Compile function Reactor_Log_Services(@Service, @Params)
/***********************************************************************************************************************

    This program is proprietary and is not to be used by or disclosed to others, nor is it to be copied without written
    permission from SRP Computer Solutions, Inc.

    Name        :   Reactor_Log_Services

    Description :   Handler program for all module related services.

    Notes       :   The generic parameters should contain all the necessary information to process the services. Often
                    this will be information like the data Record and Key ID.

    Parameters  :
        Service         [in] -- Name of the service being requested
        Param1-10   [in/out] -- Additional request parameter holders
        Response       [out] -- Response to be sent back to the Controller (MCP) or requesting procedure

    History     :   (Date, Initials, Notes)
        ??/??/??    jro     Original programmer.

***********************************************************************************************************************/
#pragma precomp SRP_PreCompiler

$Insert APP_INSERTS
$Insert SERVICE_SETUP
$Insert REACTOR_LOG_EQUATES
$Insert RLIST_EQUATES
$Insert REACT_STATE_EQUATES
$Insert REACTOR_PM_EQUATES
$Insert REACT_ITEM_EQUATES
$Insert RDS_EQUATES
$Insert REACT_SERVS_EQUATES
$Insert REACTOR_EQUATES
$Insert FEATURE_FLAGS_EQUATES

Declare function   Database_Services, Reactor_Log_Services, Obj_React_Item, Set_Status, Errmsg, Error_Services, Utility
Declare function   obj_Calendar, NextKey, SRP_JSON, Datetime, Reactor_Services, React_Servs_Services, Logging_Services
Declare function   Environment_Services, HttpClient_Services, SRP_List, Nica_Orders_Services
Declare subroutine Set_Status, RList, Errmsg, Database_Services, Error_Services, obj_React_Reads, obj_Post_Log, Delay
Declare subroutine obj_Reactor_Log, Btree.Extract, SRP_JSON, Reactor_Services, Logging_Services, Mona_Services, SRP_List
Declare subroutine Reactor_Log_Services, Nica_Orders_Services

GoToService

Return Response or ""

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Service Parameter Options
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Options BOOLEAN     = True$,False$
Options PM_TYPES    = 'ASM_HTR_TUBE_CHANGE','ASM_HTR_ANNUAL_PM','ASM_HTR_SEMIANNUAL_PM','ASM_HTR_FIVE_AND_TEN_YEAR_PM'

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SERVICES
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Service Create()
    
end service


Service UpdateReactorLog(ReactorLogID, ReactorLogRec)
    
    ErrorMsg = ''
    If ( RowExists('REACTOR_LOG', ReactorLogID) and (ReactorLogRec NE '') ) then
        Database_Services('WriteDataRow', 'REACTOR_LOG', ReactorLogID, ReactorLogRec)
        If Error_Services('HasError') then ErrorMsg = Error_Services('GetMessage')
    end else
        ErrorMsg = 'Error in ':Service:' service. REACTOR_LOG record "':ReactorLogID:'" does not exist!'
    end
    
    If ErrorMsg EQ '' then
        Response = True$
    end else
        Error_Services('Add', ErrorMsg)
        Response = False$
    end
    
    
end service


Service SignReactorLog(ReactorLogID, UserID)
    
    Flag     = ''
    ErrCode  = ''
    ErrorMsg = ''
    If RowExists('REACTOR_LOG', ReactorLogID) then
        If Error_Services('NoError') then 
            If RowExists('LSL_USERS', UserID) then
                ReactorLogRec = Database_Services('ReadDataRow', 'REACTOR_LOG', ReactorLogID)
                If Error_Services('NoError') then
                    // Verify NICA checklists are complete
                    ActiveRlNicaOrders = Nica_Orders_Services('GetActiveOrders', 'REACTOR_LOG', ReactorLogID)
                    If ActiveRLNicaOrders EQ '' then 
                        // Verify reactor number is populated
                        ReactorNo = ReactorLogRec<REACTOR_LOG_REACTOR$>
                        If ReactorNo NE '' then
                            // Verify wafer count is populated
                            WaferCount = ReactorLogRec<REACTOR_LOG_REACT_WFR_CNT_START$>
                            If WaferCount NE '' then								
                                //Check if any of the services chosen require a reactor item
                                CurrServices = Xlate('REACTOR_LOG', ReactorLogID, REACTOR_LOG_REACT_SERV_ID$, 'X')
                                CurrItems    = Xlate('REACTOR_LOG', ReactorLogID, REACTOR_LOG_REACT_ITEM_IDS$, 'X')
                                If CurrServices NE '' then
                                    for each ServiceID in CurrServices using @VM setting sPos
                                        If RowExists('REACT_SERVS', ServiceID) then
                                            ServiceRec = Database_Services('ReadDataRow', 'REACT_SERVS', ServiceID)
                                            If Error_Services('NoError') then
                                                ItemReqd = ServiceRec<REACT_SERVS_GRAPHITE_OR_TUBE$>
                                                If ItemReqd NE '' then
                                                    If CurrItems<1, sPos> NE '' then
                                                        CurrItemID   = CurrItems<1, sPos>
                                                        If RowExists('REACT_ITEM', CurrItemID) then
                                                            CurrReactItemType = XLATE('REACT_ITEM', CurrItemID, REACT_ITEM_RI_TYPE$, 'X')
                                                            If CurrReactItemType NE ItemReqd then
                                                                ErrorMsg = 'React Item ' : CurrItemID : " doesn't match the required react item type!"
                                                            end
                                                        end else
                                                            ErrorMsg = 'React Item ' : CurrItemID : " doesn't exist!"
                                                        end
                                                    end else
                                                        ErrorMsg = 'Service  ' : ServiceID : ' requires an item to be selected and none was selected.' 
                                                    end
                                                end
                                            end else
                                                ErrorMsg = 'Error reading service record for service ID: ' : ServiceID
                                            end
                                        end else
                                            ErrorMsg = 'Invalid service selected! Service ID: ' : ServiceID  
                                        end
                                    Until ErrorMsg NE ''
                                    Next ServiceID
                                end
                                
                                // Check if any react items are missing disposition codes
                                If ErrorMsg EQ '' then
                                    RemRINos   = Xlate('REACTOR_LOG', ReactorLogID, 'REM_RI_NO', 'X')
                                    If RemRINos NE '' then
                                        RemRIDispCDs = Xlate('REACTOR_LOG', ReactorLogID, 'REM_DISP_CD', 'X')
                                        For each RemRINo in RemRINos using @VM setting vPos
                                            If RemRIDispCDs<0, vPos> EQ '' then
                                                ErrorMsg = 'Error in ':Service:' service. Disposition for REACT_ITEM ':RemRINo:' being removed has not been completed.'
                                            end
                                        Until ErrorMsg NE ''
                                        Next RemRINo
                                    end
                                    AddedRINos = Xlate('REACTOR_LOG', ReactorLogID, 'REACT_ITEM_IDS', 'X')
                                    If AddedRINos NE '' then
                                        for each AddedRINo in AddedRINos using @VM
                                            RIRec = Database_Services('ReadDataRow', 'REACT_ITEM', AddedRINo)
                                            If RIRec<REACT_ITEM_RETIRE_DT$> NE '' then
                                                ErrorMsg = 'Error in ':Service:' service. REACT_ITEM ':AddedRINo:' cannot be added because it is RETIRED.'
                                            end
                                        Until ErrorMsg NE ''
                                        Next AddedRINo
                                    end
                                end
                                
                                If ErrorMsg EQ '' then
                                    // Check if we need to "post" any items that are being installed
                                    InstRINo = ReactorLogRec<REACTOR_LOG_INST_RI_NO$>
                                    If InstRINo NE '' then
                                        RIPostBy = ReactorLogRec<REACTOR_LOG_RI_POST_BY$>
                                        If RIPostBy EQ '' then
                                            obj_Reactor_Log('PostReactItems',ReactorLogID:@RM:UserID)
                                            // Pull in a fresh copy of the record with the POST_BY signature set
                                            ReactorLogRec = Database_Services('ReadDataRow', 'REACTOR_LOG', ReactorLogID)
                                            If Get_Status(ErrCode) then
                                                ErrorMsg = 'Error in ':Service:' service. Error calling obj_Reactor_Log("PostReactItems"). Error code: ':ErrCode:'.'
                                            end
                                        end
                                    end
                                    If ErrorMsg EQ '' then
                                        // Check if we need to create a REACT_READS record
                                        ReactWfrCntEnd = ReactorLogRec<REACTOR_LOG_REACT_WFR_CNT_END$>
                                        If ReactWfrCntEnd EQ 0 then
                                            CurrDTM = obj_Calendar('CurrDTM')
                                            obj_React_Reads('Create',ReactorNo:@RM:UserID:@RM:CurrDTM:@RM:'0')
                                            If Get_Status(ErrCode) then
                                                ErrorMsg = 'Error in ':Service:' service. Error calling obj_React_Reads("Create"). Error code: ':ErrCode:'.'
                                            end
                                        end
                                        If ErrorMsg EQ '' then
                                            // Check reactor prevent maintenance records
                                            CurServices = ReactorLogRec<REACTOR_LOG_REACT_SERV_ID$>
                                            Loop
                                                TestChar = CurServices[-1,1]
                                            Until TestChar NE @VM or CurServices = ''
                                                CurServices[-1,1] = ''
                                            Repeat
                                            CCnt = Count(CurServices,@VM) + (CurServices NE '')
                                            If (CCnt GT 0) then
                                                IntrMaintFlowCodes = React_Servs_Services('GetIntrMaintFlowIds', CurServices)
                                                If IntrMaintFlowCodes NE '' then
                                                    ReactorType  = Xlate('REACTOR', ReactorNo, REACTOR_REACT_TYPE$, 'X')
                                                    ChecklistIds = Nica_Orders_Services('GetFlowChecklistIds', IntrMaintFlowCodes, 'INTRUSIVE_MAINT', ReactorType)
                                                    If ChecklistIds NE '' then
                                                        LogFlows             = IntrMaintFlowCodes
                                                        Convert @VM to ', ' in LogFlows
                                                        Reactor_Log_Services('AddComment', ReactorNo, 'Intrusive Maintenance initiated for flow(s) ':LogFlows:'.', UserID)															
                                                        IntrMaintFeatureFlag = Xlate('FEATURE_FLAGS', 'NICA_INTRUSIVE_MAINTENANCE', FEATURE_FLAGS.ENABLED$, 'X')
                                                        If (IntrMaintFeatureFlag EQ True$) then
                                                            Nica_Orders_Services('CreateNewOrder', 'REACTOR', ReactorNo, 'INTRUSIVE_MAINT', IntrMaintFlowCodes, '', ChecklistIds)
                                                        end
                                                        If Error_Services('HasError') then ErrorMsg = Error_Services('GetMessage') 
                                                    end
                                                end
                                            end
                                            If ErrorMsg EQ '' then 
                                                For ReactServsIndex = 1 to CCnt
                                                    CurService = CurServices<1,ReactServsIndex>
                                                    Open 'REACTOR_PM' to ReactorPMTable then
                                                        Open 'DICT.REACTOR_PM' to DictReactorPMTable then
                                                            
                                                            SearchStr	 = 'REACT_SERV_ID':@VM:CurService:@FM
                                                            SearchStr 	:= 'REACTOR':@VM:ReactorNo:@FM
                                                            SearchStr	:= 'COMPLETE_DATE':@VM:'':@FM
                                                            
                                                            Btree.Extract(SearchStr, 'REACTOR_PM', DictReactorPMTable, OpenPMKeys, '', Flag)
                                                            
                                                            If Flag EQ 0 then
                                                                EndDate = Date()
                                                                * Add Maintenance metric reset
                                                                AssocMetrics = ''
                                                                AssocMetrics = React_Servs_Services('GetAssociatedMetrics', CurService)
                                                                If AssocMetrics NE '' then
                                                                    MetricCount = Dcount(AssocMetrics, @VM)
                                                                    For MetricIndex = 1 to MetricCount
                                                                        ThisMetric = AssocMetrics<1,MetricIndex>
                                                                        Reactor_Services('ResetWfrMetric', ReactorNo, ThisMetric) 
                                                                    Next MetricIndex
                                                                End
                                                                If OpenPMKeys NE '' then
                                                                    * If more than one, which should not happen then close all
                                                                    KCnt = COUNT( OpenPMKeys, @VM ) + (OpenPMKeys NE '')
                                                                    PMResched      = False$
                                                                    For I = 1 to KCnt
                                                                        ThisOpenPMKey  = OpenPMKeys<1,I>
                                                                        
                                                                        otlParms       = 'REACTOR_PM':@RM
                                                                        otlParms      := ThisOpenPMKey:@RM
                                                                        otlParms      := REACTOR_PM_COMPLETE_DATE$:@VM:REACTOR_PM_COMP_RL_NO$:@RM
                                                                        otlParms      := EndDate:@VM:ReactorLogID:@RM
                                                                        If ThisOpenPMKey NE '' then
                                                                            obj_Post_Log('Create',otlParms)		;* Closes previous PM record
                                                                            If Not(Get_Status(ErrCode)) then
                                                                                * Schedule next PM 
                                                                                PMDays = XLATE( 'REACT_SERVS', CurService, REACT_SERVS_PM_DAYS$, 'X' )
                                                                                IF PMDays NE '' THEN
                                                                                    If PMResched EQ False$ then
                                                                                        PMNo = NextKey('REACTOR_PM')
                                                                                        If Error_Services('NoError') then
                                                                                            NewPMRec                              = ''
                                                                                            NewPMRec<REACTOR_PM_ENTRY_ID$>        = UserID
                                                                                            NewPMRec<REACTOR_PM_ENTRY_DATE$>      = Date()
                                                                                            NewPMRec<REACTOR_PM_REACTOR$>         = ReactorNo
                                                                                            NewPMRec<REACTOR_PM_PREV_PM_COMP_DT$> = EndDate
                                                                                            NewPMRec<REACTOR_PM_DUE_DT$>          = EndDate + PMDays
                                                                                            NewPMRec<REACTOR_PM_REACT_SERV_ID$>   = CurService
                                                                                            NewPMRec<REACTOR_PM_ENTRY_RL_NO$>     = ReactorLogID
                                                                                            
                                                                                            Database_Services('WriteDataRow', 'REACTOR_PM', PMNo, NewPMRec)
                                                                                            If Error_Services('NoError') then
                                                                                                PMResched = True$
                                                                                            end else
                                                                                                ErrorMsg = Error_Services('GetMessage') 
                                                                                            end
                                                                                        end else
                                                                                            ErrorMsg = 'Error in ':Service:' service. Error calling NextKey("REACTOR_PM").'
                                                                                        end
                                                                                    end
                                                                                end
                                                                            end else
                                                                                ErrorMsg = 'Error in ':Service:' service. Error calling obj_Post_Log("Create"). Error code: ':ErrCode
                                                                            end
                                                                        end
                                                                    Next I
                                                                end
                                                            end else
                                                                ErrorMsg = 'Error in ':Service:' serivce. Error calling Btree.Extract. Error code: ':Flag
                                                            end
                                                        end	else
                                                            ErrorMsg = 'Error in ':Service:' service. Error opening DICT.REACTOR_PM table.'
                                                        end
                                                    end else
                                                        ErrorMsg = 'Error in ':Service:' service. Error opening REACTOR_PM table.'
                                                    end
                                                Next ReactServsIndex
                                            end else
                                                ErrorMsg = 'Error in ':Service:' service. Error creating INTRUSIVE_MAINT NICA order.'
                                            end
                                            
                                        end
                                    end
                                end
                            end else
                                ErrorMsg = 'Error in ':Service:' service. Wafer count is missing.'
                            end
                        end else
                            ErrorMsg = 'Error in ':Service:' service. Reactor number is missing.'
                        end
                    end else
                        ActiveChecklistTypes  = Xlate('NICA_ORDERS', ActiveRlNicaOrders, 'ORDER_TYPE', 'X')
                        Swap @VM with ',' in ActiveChecklistTypes
                        ErrorMsg              = 'Error in ':Service:' service. NICA order(s) ':ActiveChecklistTypes
                        ErrorMsg             := ' must be completed prior to signing reactor log.'
                    end
                end else
                    ErrorMsg = Error_Services('GetMessage')
                end
            end else
                ErrorMsg = 'Error in ':Service:' service. LSL_USERS record "':UserID:'" does not exist.'
            end
        end else
            ErrorMsg = Error_Services('GetMessage')
        end
    end else
        ErrorMsg = 'Error in ':Service:' service. REACTOR_LOG record "':ReactorLogID:'" does not exist.'
    end
    
    If ErrorMsg EQ '' then
        // Pull in a fresh copy of the record in case comments were added above
        ReactorLogRec = Database_Services('ReadDataRow', 'REACTOR_LOG', ReactorLogID)
        // Set signature, end date, and end time
        ReactorLogRec<REACTOR_LOG_TECH_SIG$> = UserID
        ReactorLogRec<REACTOR_LOG_END_DATE$> = Date()
        ReactorLogRec<REACTOR_LOG_END_TIME$> = Time()
        Database_Services('WriteDataRow', 'REACTOR_LOG', ReactorLogID, ReactorLogRec)
        If Error_Services('HasError') then ErrorMsg = Error_Services('GetMessage')
    end
    
    If ErrorMsg EQ '' then
        Response = True$
    end else
        Error_Services('Add', ErrorMsg)
        Response = False$
    end
    
end service


Service ClearSignature(RLKey)
    
    If RLKey NE '' then
        RLRec = Database_Services('ReadDataRow', 'REACTOR_LOG', RLKey)
        If Error_Services('NoError') then
            RLRec<REACTOR_LOG_TECH_SIG$>            = ''
            RLRec<REACTOR_LOG_END_DATE$>            = ''
            RLRec<REACTOR_LOG_END_TIME$>            = ''
            RLRec<REACTOR_LOG_LO_REVIEWED$>         = ''
            RLRec<REACTOR_LOG_LO_NA$>               = ''
            RLRec<REACTOR_LOG_REACT_WFR_CNT_START$> = ''
            Database_Services('WriteDataRow', 'REACTOR_LOG', RLKey, RLRec, True$, False$, False$)
            If Error_Services('NoError') then
                // Cancel active Intrusive Maintenance NICA orders in the event the maintenance user set an
                // invalid service id or a difference service was required.
                ReactorNo        = RLRec<REACTOR_LOG_REACTOR$>
                CurrActiveOrders = Nica_Orders_Services('GetActiveOrders', 'REACTOR', ReactorNo, 'INTRUSIVE_MAINT') 
                If CurrActiveOrders NE '' then
                    For each ActiveIntrMaintOrderId in CurrActiveOrders using @VM
                        Nica_Orders_Services('CancelOrder', ActiveIntrMaintOrderId)
                    Next ActiveIntrMaintOrderId
                end				
            end
        end
    end
    
end service


Service SaveReactorLogRecord(RLKey, RLRec)
    
    If ( (RLKey NE '') and (RLRec NE '') ) then
        
        ReactNo         = RLRec<REACTOR_LOG_REACTOR$>
        RawReactItemIds = RLRec<REACTOR_LOG_REACT_ITEM_IDS$>
        rawCnt          = COUNT(RawReactItemIds,@VM) + (RawReactItemIds NE '')
        
        InstRINos = ''
        
        FOR I = 1 TO rawCnt
            IF RawReactItemIds<1,I> NE '' THEN
                InstRINos<1,-1> = obj_React_Item('Serial_RINo',RawReactItemIds<1,I>)
            END
        NEXT I
        
        RLRec<REACTOR_LOG_INST_RI_NO$> = InstRINos
        
        * Remove Calculation
        
        PostedBy = RLRec<REACTOR_LOG_RI_POST_BY$>
        
        IF PostedBy = '' THEN
            
            NewRITypes	= XLATE('REACT_ITEM',InstRINos,REACT_ITEM_RI_TYPE$,'X')
            
            CurrRINos   = Xlate('REACTOR_LOG', RLKey, 'CURR_RI_NO', 'X')
            CurrRITypes = Xlate('REACTOR_LOG', RLKey, 'CURR_RI_TYPE', 'X')
            CurrRIDTMs  = Xlate('REACTOR_LOG', RLKey, 'CURR_RI_DTM', 'X')
            
            nRICnt = COUNT(NewRITypes,@VM) + (NewRITypes NE '')
            cRICnt = COUNT(CurrRITypes,@VM) + (CurrRITypes NE '')
            
            RemRINos    = ''
            RemHistKeys = ''
            
            FOR J = 1 TO nRICnt
                NewRIType = NewRITypes<1,J>
                FOR K = 1 TO cRICnt
                    CurrRIType = CurrRITypes<1,K>
                    IF CurrRIType[1,1] = NewRIType[1,1] THEN
                        RemNo      = CurrRINos<0, K>
                        RemInstDTM = CurrRIDTMs<0, K>
                        RemHistKey = ReactNo:'*':RemNo:'*':RemInstDTM
                        
                        LOCATE RemNo IN RemRINos USING @VM SETTING Pos ELSE
                            RemRINos = INSERT(RemRINos,1,Pos,0,RemNo)
                            RemHistKeys = INSERT(RemHistKeys,1,Pos,0,RemHistKey)
                        END
                    END
                NEXT K	;* End of Curr Loop
            NEXT J	;* End of New Loop
            
            RLRec<REACTOR_LOG_REM_RIH_KEY$> = RemHistKeys
            
        END	;* End of check for NOT Posted
        
        Database_Services('WriteDataRow', 'REACTOR_LOG', RLKey, RLRec)
        
    end
    
end service


Service IsSigned(ReactorLogID)
    
    Response = 0
    If ReactorLogID EQ '' then
        Response = 'Error, null parameter passed for ReactorLogID'
        return;
    end
    
    //Read record
    ReactorLogRec = Database_Services('ReadDataRow', 'REACTOR_LOG', ReactorLogID)
    
    ReactorLogTechSig = ReactorLogRec<REACTOR_LOG_TECH_SIG$>
    If ReactorLogTechSig then
        Response = 1
    end else
        Response = 0
    end
    
End Service


Service IsMaint(ReactorLogID)
    
    Response = 0
    If ReactorLogID EQ '' then
        Response = 'Error, null parameter passed for ReactorLogID'
        return;
    end
    
    //Read record
    ReactorLogRec = Database_Services('ReadDataRow', 'REACTOR_LOG', ReactorLogID)
    
    ReactorLogCategory = ReactorLogRec<REACTOR_LOG_CATEGORY$>
    If ReactorLogCategory EQ 'M' then
        Response = 1
    end else
        Response = 0
    end
    
End Service


Service GetLogsByReactor(ReactNo)
    
    ReactLogList = ''
    SelectSent  = 'SELECT REACTOR_LOG WITH REACTOR EQ ': ReactNo : ' AND WITH START_DATE GT ' : Date() - 5475 : ' BY-DSND START_DATE'
    
    Set_Status(0)
    RList(SelectSent, TARGET_ACTIVELIST$, "", "", "")
    IF Get_Status(errCode) THEN
        ErrMsg(errCode)
        Response = 0
        RETURN
    END
    IF @RecCount then
        EoF = 0
        NumKeys = @RecCount
        Cnt = 0
        
        Loop
            ReadNext log Else EoF = 1
        until EoF
            ReactLogList := log : @FM
        Repeat
        
    end
    //to here
    GoSub ClearCursors
    ClearSelect TARGET_ACTIVELIST$
    Response = ReactLogList
    
end service


Service GetLogsByReactorAndServID(ReactNo, ServID)
    
    ServicesPerformed = ''
    
    ServiceList = Reactor_Log_Services('GetLogsByReactor', ReactNo)
    for each rlKey in ServiceList using @FM
        ServiceIDs = XLATE('REACTOR_LOG', rlKey, 18, 'X')
        
        for each ServiceID in ServiceIDs using @VM
            If ServiceID EQ ServID then
                Date = XLATE('REACTOR_LOG', rlKey, 'END_DTM', 'X')
                ServiceDesc = XLATE('REACT_SERVS', ServiceID, 1, 'X')
                ReactItemID = ''
                RLServIDs = XLATE('REACTOR_LOG', rlKey, 18, 'X')
                RLSerialNos = XLATE('REACTOR_LOG', rlKey, 15, 'X')
                RLReactItemIDs = obj_React_Item('Serial_RINo',RLSerialNos)
                Locate ServiceID in RLServIDs using @VM setting ServPos then
                    ReactItemID = RLReactItemIDs<1,ServPos>
                end
                ServicesPerformed := ServiceID : @VM : ServiceDesc : @VM: OCONV(Date, 'D4/') : @VM : rlKey : @VM : ReactItemID : @FM
            end 
        Next ServiceID
    Next rlKey
    response = ServicesPerformed
    
end service


Service GetLatestReactorLogsByReactor(ReactNo)
    
    ServicesPerformed = ''
    
    ServiceList = Reactor_Log_Services('GetLogsByReactor', ReactNo)
    //FoundResults = ''
    
    for each rlKey in ServiceList using @FM
        ServiceIDs = XLATE('REACTOR_LOG', rlKey, 18, 'X')
        
        for each ServiceID in ServiceIDs using @VM
            Date = XLATE('REACTOR_LOG', rlKey, 'END_DTM', 'X')
            ServiceDesc = XLATE('REACT_SERVS', ServiceID, 1, 'X')
            ReactItemID = ''
            RLServIDs = XLATE('REACTOR_LOG', rlKey, 18, 'X')
            RLSerialNos = XLATE('REACTOR_LOG', rlKey, 15, 'X')
            RLReactItemIDs = obj_React_Item('Serial_RINo',RLSerialNos)
            Locate ServiceID in RLServIDs using @VM setting ServPos then
                ReactItemID = RLReactItemIDs<1,ServPos>
            end
            ReactItemSN = XLATE('REACT_ITEM', ReactItemID, 10, 'X')
            ServicesPerformed := ServiceID : @VM : rlKey : @VM : ServiceDesc : @VM: OCONV(Date, 'D4/') : @VM: ReactItemID : @FM
        Next ServiceID
    Next rlKey
    //remove duplicates
    sortIndex = ''
    existingServIDs = ''
    SortedArray = ''
    for ServiceIndex = 1 to DCOUNT(ServicesPerformed, @FM)
        LOCATE ServicesPerformed<ServiceIndex, 1> IN existingServIDs using @FM setting DUMMY else
            SortedArray := ServicesPerformed<ServiceIndex> : @FM
            existingServIDs := ServicesPerformed<ServiceIndex, 1> : @FM
        end
    Next ServiceIndex
    
    response = SortedArray
    
end service


Service GetAllServIDs()
    
    ReactServsList = ''
    SelectSent  = 'SELECT REACT_SERVS BY SERV_ID'
    
    Set_Status(0)
    RList(SelectSent, TARGET_ACTIVELIST$, "", "", "")
    IF @RecCount then
        EoF = 0
        NumKeys = @RecCount
        Cnt = 0
        
        Loop
            ReadNext ReactServID Else EoF = 1
        until EoF
            Description = XLATE('REACT_SERVS', ReactServID, 1, 'X')
            ReactServsList := ReactServID : @VM : Description : @FM
        Repeat
        
    end
    //to here
    GoSub ClearCursors
    ClearSelect TARGET_ACTIVELIST$
    Response = ReactServsList
    
end service


Service ConvertRecordToJSON(KeyID, Record, itemURL)
    
    jsonRecord    = ''
    
    If KeyID NE '' then
        
        If Record EQ '' then Record = Database_Services('ReadDataRow', 'REACTOR_LOG', KeyID)
        If Error_Services('NoError') then
            @DICT   = Database_Services('GetTableHandle', 'DICT.REACTOR_LOG')
            @ID     = KeyID
            @RECORD = Record
            objJSON = ''
            If SRP_JSON(objJSON, 'New', 'Object') then
                If SRP_JSON(objReactorLog, 'New', 'Object') then 
                    SRP_JSON(objReactorLog, 'SetValue', 'keyId', @ID)
                    SRP_JSON(objReactorLog, 'SetValue', 'reactor', {REACTOR})
                    SRP_JSON(objReactorLog, 'SetValue', 'reactType', {REACT_TYPE})
                    SRP_JSON(objReactorLog, 'SetValue', 'reactTypeDesc', {REACT_TYPE_DESC})
                    SRP_JSON(objReactorLog, 'SetValue', 'reactProbId', {REACT_PROB_ID})
                    SRP_JSON(objReactorLog, 'SetValue', 'category', {CATEGORY})
                    
                    // Create an array of service info objects
                    If SRP_JSON(objServInfoArray, 'New', 'Array') then
                        ReactProbCatIDs = {REACT_PROB_CAT_ID}
                        For each ReactProbCatID in ReactProbCatIDs using @VM setting vPos
                            objServInfo = ''
                            If SRP_JSON(objServInfo, 'New', 'Object') then
                                SRP_JSON(objServInfo, 'SetValue', 'reactProbCatId', ReactProbCatID)
                                SRP_JSON(objServInfo, 'SetValue', 'reactProbCatDesc', {REACT_PROB_CAT_DESC}<0, vPos>)
                                SRP_JSON(objServInfo, 'SetValue', 'reactServId', {REACT_SERV_ID}<0, vPos>)
                                SRP_JSON(objServInfo, 'SetValue', 'reactServDesc', {REACT_SERV_DESC}<0, vPos>)
                                If {SCHEDULED}<0, vPos> EQ '' then
                                    SRP_JSON(objServInfo, 'SetValue', 'scheduled', {SCHEDULED}<0, vPos>, 'Null')
                                end else
                                    SRP_JSON(objServInfo, 'SetValue', 'scheduled', {SCHEDULED}<0, vPos>, 'Boolean')
                                end
                                SRP_JSON(objServInfo, 'SetValue', 'reactServSnType', {REACT_SERV_SN_TYPE}<0, vPos>)
                                SRP_JSON(objServInfo, 'SetValue', 'reactItemId', {REACT_ITEM_IDS}<0, vPos>)
                                SRP_JSON(objServInfo, 'SetValue', 'reactItemRiNo', {REACT_ITEM_RI_NO}<0, vPos>)
                                SRP_JSON(objServInfo, 'SetValue', 'reactItemMfrPartNo', {RI_MFR_PART_NO}<0, vPos>)
                                SRP_JSON(objServInfo, 'SetValue', 'reactItemMfrPartRev', {RI_MFR_PART_REV}<0, vPos>)
                                SRP_JSON(objServInfo, 'SetValue', 'reactItemMfrSerialNo', {RI_MFR_SERIAL_NO}<0, vPos>)
                                
                                SRP_JSON(objServInfo, 'SetValue', 'remReactItemId', Field({REM_RIH_KEY}<0, vPos>, '*', 2))
                                SRP_JSON(objServInfo, 'SetValue', 'remReactItemDispCd', {REM_DISP_CD}<0, vPos>)
                                
                                
                                SRP_JSON(objServInfoArray, 'Add', objServInfo)
                                SRP_JSON(objServInfo, 'Release')
                            end
                        Next ReactProbCatID
                        SRP_JSON(objReactorLog, 'Set', 'servInfo', objServInfoArray)
                        SRP_JSON(objServInfoArray, 'Release')
                    end
                    SRP_JSON(objReactorLog, 'SetValue', 'reactUtilId', {REACT_UTIL_ID})
                    objWaferCount = ''
                    If SRP_JSON(objWaferCount, 'New', 'Object') then
                        SRP_JSON(objWaferCount, 'SetValue', 'startCount', {REACT_WFR_CNT_START})
                        StartDTM = OConv({START_DATE}, 'D4/') :' ': OConv({START_TIME}, 'MTH')
                        SRP_JSON(objWaferCount, 'SetValue', 'startDtm', StartDTM)
                        SRP_JSON(objWaferCount, 'SetValue', 'endCount', {REACT_WFR_CNT_END})
                        SRP_JSON(objReactorLog, 'Set', 'waferCount', objWaferCount)
                        SRP_JSON(objWaferCount, 'Release')
                    end
                    SRP_JSON(objReactorLog, 'SetValue', 'entryId', {ENTRY_ID})
                    SRP_JSON(objReactorLog, 'SetValue', 'entryDate', OConv({ENTRY_DATE}, 'D4/'))
                    SRP_JSON(objReactorLog, 'SetValue', 'techSig', {TECH_SIG})
                    EndDTM = OConv({END_DATE}, 'D4/') :' ': OConv({END_TIME}, 'MTH')
                    SRP_JSON(objReactorLog, 'SetValue', 'endDtm', Trim(EndDTM))
                    SRP_JSON(objReactorLog, 'SetValue', 'elapsedHours', {ELAPSED_HOURS})
                    If {LO_NA} EQ '' then
                        SRP_JSON(objReactorLog, 'SetValue', 'lockOutTagOutNA', {LO_NA}, 'Null')
                    end else
                        SRP_JSON(objReactorLog, 'SetValue', 'lockOutTagOutNA', {LO_NA}, 'Boolean')
                    end
                    If {LO_REVIEWED} EQ '' then
                        SRP_JSON(objReactorLog, 'SetValue', 'lockOutTagOutReviewed', {LO_REVIEWED}, 'Null')
                    end else
                        SRP_JSON(objReactorLog, 'SetValue', 'lockOutTagOutReviewed', {LO_REVIEWED}, 'Boolean')
                    end
                    If {ROTR} EQ '' then
                        SRP_JSON(objReactorLog, 'SetValue', 'ROTR', {ROTR}, 'Null')
                    end else
                        SRP_JSON(objReactorLog, 'SetValue', 'ROTR', {ROTR}, 'Boolean')
                    end
                    
                    Notes      = {NOTES}
                    NotesDTMs  = OConv({NOTES_DTMS}, 'DT2/^H')
                    NotesUsers = OConv({NOTES_USERS}, '[CONV_XLATE,LSL_USERS*FIRST_LAST]')
                    
                    If SRP_JSON(objNotesArray, 'New', 'Array') then
                        If Notes NE '' then
                            objNote = ''
                            For each Note in Notes using @VM setting vPos
                                If SRP_JSON(objNote, 'New', 'Object') then
                                    SRP_JSON(objNote, 'SetValue', 'datetime', NotesDTMs<0, vPos>)
                                    SRP_JSON(objNote, 'SetValue', 'user', NotesUsers<0, vPos>)
                                    SRP_JSON(objNote, 'SetValue', 'comment', Notes<0, vPos>)
                                    SRP_JSON(objNotesArray, 'Add', objNote)
                                    SRP_JSON(objNote, 'Release')
                                end
                            Next Note
                        end
                        SRP_JSON(objReactorLog, 'Set', 'comments', objNotesArray)
                        SRP_JSON(objNotesArray, 'Release')
                    end
                    
                    objInjSettings = ''
                    If SRP_JSON(objInjSettings, 'New', 'Object') then
                        For InjIndex = 1 to 5
                            SRP_JSON(objInjSettings, 'SetValue', InjIndex, {CURR_INJ_SETTINGS}<0, InjIndex>)
                        Next InjIndex
                        SRP_JSON(objReactorLog, 'Set', 'currInjSettings', objInjSettings)
                        SRP_JSON(objInjSettings, 'Release')
                    end
                    
                    If {WAFERS_REMOVED} EQ '' then
                        SRP_JSON(objReactorLog, 'SetValue', 'wafersRemoved', {WAFERS_REMOVED}, 'Null')
                    end else
                        SRP_JSON(objReactorLog, 'SetValue', 'wafersRemoved', {WAFERS_REMOVED}, 'Boolean')
                    end
                    
                    // Active NICA Orders
                    RlChecklistActive = {CHECKLIST_ACTIVE}
                    SRP_JSON(objReactorLog, 'SetValue', 'reactorLogChecklistActive', RlChecklistActive, 'Boolean')
                    If RlChecklistActive then
                        RlChecklistTypes    = {CHECKLIST_TYPE}
                        RlChecklistOrderIds = {CHECKLIST_ORDER_ID}
                        objRlChecklistArray = ''
                        If SRP_JSON(objRlChecklistArray, 'New', 'Array') then
                            objChecklist = ''
                            For each RlChecklistType in RlChecklistTypes using @VM setting vPos
                                If SRP_JSON(objChecklist, 'New', 'Object') then
                                    SRP_JSON(objChecklist, 'SetValue', 'reactorLogChecklistType', RlChecklistType)
                                    RlChecklistOrderId = RlChecklistOrderIds<0, vPos>
                                    SRP_JSON(objChecklist, 'SetValue', 'reactorLogChecklistOrderId', RlChecklistOrderId)
                                    SRP_JSON(objRlChecklistArray, 'Add', objChecklist)
                                    SRP_JSON(objChecklist, 'Release')
                                end
                            Next RlChecklistType
                            SRP_JSON(objReactorLog, 'Set', 'reactorLogChecklists', objRlChecklistArray)
                            SRP_JSON(objRlChecklistArray, 'Release')
                        end
                    end					
                    
                    loadedRds      = Reactor_Services('GetLoadedRds', {REACTOR})
                    loadedRdsArray = ''
                    If SRP_JSON(loadedRdsArray, 'New', 'Array') then
                        objLoadedRds = ''
                        For idx = 1 To 2
                            If SRP_JSON(objLoadedRds, 'New', 'Object') then
                                loadLockSide = Xlate('RDS', loadedRds<idx>, RDS_LOAD_LOCK_SIDE$, 'X')
                                SRP_JSON(objLoadedRds, 'SetValue', 'loadLockSide', loadLockSide)
                                currentRds = loadedRds<idx>
                                SRP_JSON(objLoadedRds, 'SetValue', 'rds', currentRds)
                            end
                            SRP_JSON(loadedRdsArray, 'Add', objLoadedRds)
                            SRP_JSON(objLoadedRds, 'Release')
                        Next idx
                        SRP_JSON(objReactorLog, 'Set', 'loadedRds', loadedRdsArray, @FM)
                        SRP_JSON(loadedRdsArray, 'Release')
                    end
                    
                    SRP_JSON(objJSON, 'Set', 'reactorLog', objReactorLog)
                    SRP_JSON(objReactorLog, 'Release')
                end
                
                If itemURL NE '' then
                    // The itemURL was passed in so add HAL+JSON properties.
                    
                    // Create the _links property and then all link objects needed for this resource.
                    objLinks = ''
                    If SRP_JSON(objLinks, 'New', 'Object') then
                        // Create a self link.
                        objLink = ''
                        If SRP_JSON(objLink, 'New', 'Object') then
                            SRP_JSON(objLink, 'SetValue', 'href', ItemURL, 'String')
                            SRP_JSON(objLink, 'SetValue', 'title', 'Self', 'String')
                            SRP_JSON(objLinks, 'Set', 'self', objLink)
                            SRP_JSON(objLink, 'Release')
                        end
                        SRP_JSON(objJSON, 'Set', '_links', objLinks)
                        SRP_JSON(objLinks, 'Release')
                    end
                    
                    // Create the _class property for this resource.
                    SRP_JSON(objJSON, 'SetValue', '_class', 'resource')
                end
                jsonRecord = SRP_JSON(objJSON, 'Stringify', 'Styled')
                SRP_JSON(objJSON, 'Release')
            end else
                Error_Services('Add', 'Unable to create JSON representation in the ' : Service : ' service.')
            end
        end
    end else
        Error_Services('Add', 'KeyID argument was missing in the ' : Service : ' service.')
    end
    
    Response    = jsonRecord
    
end service


Service ConvertJSONToRecord(JSON)
    
    If JSON NE '' then
        If SRP_JSON(objJSON, 'Parse', JSON) EQ '' then
            objReactorLog = SRP_JSON(objJSON, 'Get', 'reactorLog')
            @ID           = SRP_JSON(objReactorLog, 'GetValue', 'keyId')
            If @ID NE '' then
                @Record = Database_Services('ReadDataRow', 'REACTOR_LOG', @ID)
                If Error_Services('NoError') then
                    @Dict               = Database_Services('GetTableHandle', 'DICT.REACTOR_LOG')
                    {REACT_PROB_ID}     = SRP_JSON(objReactorLog, 'GetValue', 'reactProbID', '')
                    objServInfoArray    = SRP_JSON(objReactorLog, 'Get', 'servInfo')
                    NumObjects          = SRP_JSON(objServInfoArray, 'GetCount')
                    ReactProbCatIds     = ''
                    ReactServIds        = ''
                    Scheduled           = ''
                    ReactItemIds        = ''
                    RemReactItemIds     = ''
                    RemReactItemDispCds = ''
                    For ArrayIndex = 1 to NumObjects
                        ReactProbCatIds<0, ArrayIndex>     = SRP_JSON(objServInfoArray, 'GetValue', '[':ArrayIndex:'].reactProbCatId', '')
                        ReactServIds<0, ArrayIndex>        = SRP_JSON(objServInfoArray, 'GetValue', '[':ArrayIndex:'].reactServId', '')
                        Scheduled<0, ArrayIndex>           = SRP_JSON(objServInfoArray, 'GetValue', '[':ArrayIndex:'].scheduled', '')
                        ReactItemIds<0, ArrayIndex>        = SRP_JSON(objServInfoArray, 'GetValue', '[':ArrayIndex:'].reactItemId', '')
                        RemReactItemIds<0, ArrayIndex>     = SRP_JSON(objServInfoArray, 'GetValue', '[':ArrayIndex:'].remReactItemId', '')
                        RemReactItemDispCds<0, ArrayIndex> = SRP_JSON(objServInfoArray, 'GetValue', '[':ArrayIndex:'].remReactItemDispCd', '')
                    Next ArrayIndex
                    SRP_JSON(objServInfoArray, 'Release')
                    Notes         = ''
                    NotesDTMs     = ''
                    NotesUsers    = ''
                    objNotesArray = SRP_JSON(objReactorLog, 'Get', 'comments')
                    NumNotes      = SRP_JSON(objNotesArray, 'GetCount')
                    TempID        = @ID
                    TempRec       = @Record
                    TempDict      = @Dict
                    For ArrayIndex = 1 to NumNotes
                        Notes<0, ArrayIndex>     = SRP_JSON(objNotesArray, 'GetValue', '[':ArrayIndex:'].comment', '')
                        NotesDTMs<0, ArrayIndex> = IConv(SRP_JSON(objNotesArray, 'GetValue', '[':ArrayIndex:'].datetime', ''), 'DT')
                        User                     = SRP_JSON(objNotesArray, 'GetValue', '[':ArrayIndex:'].user', '')
                        If User NE '' then
                            Query                     = 'SELECT LSL_USERS WITH FIRST_LAST EQ ':Quote(User)
                            RList(Query, TARGET_ACTIVELIST$, '', '', '')
                            ReadNext User else Null
                            GoSub ClearCursors
                        end
                        NotesUsers<0, ArrayIndex> = User
                    Next ArrayIndex
                    SRP_JSON(objNotesArray, 'Release')
                    @ID     = TempID
                    @Record = TempRec
                    @Dict   = TempDict
                    {NOTES}                 = Notes
                    {NOTES_DTMS}            = NotesDTMs
                    {NOTES_USERS}           = NotesUsers
                    {REACT_PROB_CAT_ID}     = ReactProbCatIds
                    {REACT_SERV_ID}         = ReactServIds
                    {SCHEDULED}             = Scheduled
                    {REACT_ITEM_IDS}        = ReactItemIds
                    {REM_DISP_CD}           = RemReactItemDispCds
                    {REACT_UTIL_ID}         = SRP_JSON(objReactorLog, 'GetValue', 'reactUtilId', '')
                    {REACT_WFR_CNT_START}   = SRP_JSON(objReactorLog, 'GetValue', 'waferCount.startCount', '')
                    {TECH_SIG}              = SRP_JSON(objReactorLog, 'GetValue', 'techSig', '')
                    {LO_NA}                 = SRP_JSON(objReactorLog, 'GetValue', 'lockOutTagOutNA', '')
                    {LO_REVIEWED}           = SRP_JSON(objReactorLog, 'GetValue', 'lockOutTagOutReviewed', '')
                    {ROTR}                  = SRP_JSON(objReactorLog, 'GetValue', 'ROTR', '')
                    
                    {WAFERS_REMOVED} = SRP_JSON(objReactorLog, 'GetValue', 'wafersRemoved', '')
                    objWafersRemovedRdsArray = SRP_JSON(objReactorLog, 'Get', 'wafersRemovedRds')
                    wafersRemovedRdsCount = SRP_JSON(objWafersRemovedRdsArray, 'GetCount')
                    wafersRemovedRds = ''
                    For idx = 1 to wafersRemovedRdsCount
                        If (idx GT 1) then wafersRemovedRds := @VM
                        rds = SRP_JSON(objWafersRemovedRdsArray, 'GetValue', '[':idx:']', '')
                        wafersRemovedRds := rds
                    Next idx
                    {WAFERS_REMOVED_RDS} = wafersRemovedRds
                    SRP_Json(objWafersRemovedRdsArray, 'Release')
                    
                    {WAFERS_REMOVED} = SRP_JSON(objReactorLog, 'GetValue', 'wafersRemoved', '')
                    objWafersRemovedRdsArray = SRP_JSON(objReactorLog, 'Get', 'wafersRemovedRds')
                    wafersRemovedRdsCount = SRP_JSON(objWafersRemovedRdsArray, 'GetCount')
                    wafersRemovedRds = ''
                    For idx = 1 to wafersRemovedRdsCount
                        If (idx GT 1) then wafersRemovedRds := @VM
                        rds = SRP_JSON(objWafersRemovedRdsArray, 'GetValue', '[':idx:']', '')
                        wafersRemovedRds := rds
                    Next idx
                    {WAFERS_REMOVED_RDS} = wafersRemovedRds
                    SRP_Json(objWafersRemovedRdsArray, 'Release')
                end
            end else
                Error_Services('Add', 'Error in ':Service:' service. Null value for reactorLog.keyID.')
            end
            SRP_JSON(objReactorLog, 'Release')
            SRP_JSON(objJSON, 'Release')
        end else
            Error_Services('Add', 'Error in ':Service:' service. Unable to parse JSON payload.')
        end
    end else
        Error_Services('Add', 'Error in ':Service:' service. Null JSON passed in.')
    end
    
    Response = @Record
    
end service


Service GetRlChecklistActive(RLKey)
    
    If RLKey NE '' then
        OrderTypes            = 'ASM_HTR_TUBE_CHANGE' : @VM : 'ASM_HTR_ANNUAL_PM' : @VM : 'ASM_HTR_SEMIANNUAL_PM' : @VM : 'ASM_HTR_FIVE_AND_TEN_YEAR_PM'
        ActiveRlOrderIds      = Nica_Orders_Services('GetActiveOrders', 'REACTOR_LOG', RLKey, OrderTypes)
        Response              = ( ActiveRlOrderIds NE '' )
    end else
        Error_Services('Add', 'Error in ':Service:' service. Null ReactNo passed into service.')
    end
    
end service


Service AddComment(Reactor, NewNote, User)
    
    ReactModeNGKey = Xlate('REACTOR_CHILD_KEY_IDS_NG', Reactor, 'REACT_MODE_KEY_IDS', 'X')
    RLKey          = Xlate('REACT_MODE_NG', ReactModeNGKey, 'START_RL_ID', 'X')
    If RLKey NE '' then
        RLRec = Database_Services('ReadDataRow', 'REACTOR_LOG', RLKey)
        If Error_Services('NoError') then
            Notes                                         = RLRec<REACTOR_LOG_NOTES$>
            NumNotes                                      = DCount(Notes, @VM)
            RLRec<REACTOR_LOG_NOTES$, NumNotes + 1>       = NewNote
            RLRec<REACTOR_LOG_NOTES_DTMS$, NumNotes + 1>  = Datetime()
            RLRec<REACTOR_LOG_NOTES_USERS$, NumNotes + 1> = User
            Database_Services('WriteDataRow', 'REACTOR_LOG', RLKey, RLRec)
        end
    end else
        Error_Services('Add', 'Error in ':Service:' service. Error locating reactor log key for reactor ':Reactor:'.')
    end
    
end service


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Internal GoSubs
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

ClearCursors:
    
    For counter = 0 to 8
        ClearSelect counter
    Next counter
    
return

