Compile function Nica_Orders_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 Infineon Technologies.

    Name        :   Nica_Orders_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)
        12/05/24    djs     Original programmer.

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

$Insert APP_INSERTS
$Insert SERVICE_SETUP
$Insert REACTOR_EQUATES
$Insert REACTOR_LOG_EQUATES
$Insert NICA_ORDERS_EQUATES
$Insert NICA_CHECKLISTS_EQUATES
$Insert NICA_ORDERS_CHECKLISTS_EQUATES
$Insert RLIST_EQUATES
$Insert TIME_INSERTS

Declare function   Environment_Services, Database_Services, Error_Services, Logging_Services, Nica_Orders_Services
Declare function   Httpclient_Services, SRP_JSON, Reactor_Services, Reactor_Log_Services, SRP_Array, Datetime
Declare subroutine Error_Services, Btree.Extract, Database_Services, Logging_Services, Nica_Orders_Services, Delay
Declare subroutine Httpclient_Services, SRP_JSON, Mona_Services, Service_Services, Extract_SI_Keys

Machine     = Environment_Services('GetServer')
LogDate     = Oconv(Date(), 'D4/')
LogTime     = Oconv(Time(), 'MTS')
LoggingDTM  = LogDate : ' ' : LogTime   ; // Logging DTM

IsProd = Environment_Services('IsProd')
If IsProd EQ True$ then
	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_NICAINTEGRATIONSERVICE'
end else
	MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_DEV_NICAINTEGRATIONSERVICE_DEV'
end

GoToService

Return Response or ""

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Service Parameter Options
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Options BOOLEAN                  = True$, False$
Options ENTITY_TYPES             = 'REACTOR','REACTOR_LOG'
Options ORDER_TYPES              = 'INTRUSIVE_MAINT','CHANGEOVER','INITIATE_IDLE','IDLE','ASM_HTR_TUBE_CHANGE','ASM_HTR_ANNUAL_PM','ASM_HTR_SEMIANNUAL_PM','ASM_HTR_FIVE_AND_TEN_YEAR_PM','IQS_HGCV_ALARM','ABORT_ALARM'
Options ORDER_STATUSES           = 'new','in-edit','creating','not-started','in-progress','cancelled','done'
Options REACTOR_TYPES            = 'ASM','ASM+','HTR','EPP'
Options ORDER_CHECKLIST_STATUSES = 'not-started','in-progress','paused','done'
Options NICA_CHECKLISTS          = 'PROCESS_INTERRUPTION_FLOW_C_PRE','PROCESS_INTERRUPTION_FLOW_A_PRE','PROCESS_INTERRUPTION_FLOW_B_PRE','PROCESS_INTERRUPTION_LAST_KNOWN_PRODUCT_THICKNESS_SHEETRHO','PROCESS_INTERRUPTION_LAST_KNOWN_PRODUCT_VISUAL_INSPECTION','PROCESS_INTERRUPTION_TEST_WAFER','PROCESS_INTERRUPTION_ASM_PARTICLE_QUAL_VISUAL_INSPECTION','PROCESS_INTERRUPTION_HTR_PARTICLE_QUAL_VISUAL_INSPECTION','SUSCEPTOR_PREP','1_PCRC','2_PCRC','BD','INTRINSIC','SPV-FE','CLEANUP','TEST_WAFER_VERIFICATION','PARTICLE_QUAL_ASM','PARTICLE_QUAL_HTR','FIRST_PRODUCT_RUN_HGCV','FIRST_PRODUCT_RUN_THICK','PROCESS_INTERRUPTION_FLOW_B_POST'

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

Service GetOrderIds(EntityType=ENTITY_TYPES, EntityID, OrderTypes=ORDER_TYPES, OrderStatus=ORDER_STATUSES, IsComplete=BOOLEAN)

	OrderKeys = ''
	ErrorMsg  = ''
	If ( (EntityType NE '') or (EntityID NE '') or (OrderTypes NE '') or (OrderStatus NE '') or (IsComplete NE '') ) then 
		Open 'DICT.NICA_ORDERS' to hDict then
			Query   = ''
			Table   = 'NICA_ORDERS'
			Option  = 'E'
			Flag    = ''
			If EntityType   NE '' then Query := 'ENTITY_TYPE'  : @VM : EntityType  : @FM
			If EntityID 	NE '' then Query := 'ENTITY_ID'    : @VM : EntityID    : @FM
			If OrderTypes   NE '' then
				Query := 'ORDER_TYPE'
				For each OrderType in OrderTypes using @VM
					Query := @VM : OrderType
				Next OrderType
				Query := @FM
			end
			If OrderStatus  NE '' then Query := 'ORDER_STATUS' : @VM : OrderStatus : @FM
			If IsComplete NE '' then
				Query := 'IS_COMPLETE'
				For each Val in IsComplete using @VM
					Query := @VM : Val
				Next Val
				Query := @FM
			end
			Btree.Extract(Query, Table, hDict, OrderKeys, Option, Flag)
			If Flag NE 0 then
				ErrorMsg = 'Error in ':Service:' service. Btree.Extract call failed.'
			end
		end else
			ErrorMsg = 'Error in ':Service:' service. Failed to open DICT.NICA_ORDERS.'
		end
	end else
		ErrorMsg = 'Error in ':Service:' service. At least one search parameter must be provided.'
	end
	
	If ErrorMsg EQ '' then
		Response = OrderKeys
	end else
		Error_Services('Add', ErrorMsg)
	end
	
End Service


Service GetOrderChecklistIds(NicaOrdersIds, NicaChecklistIds=NICA_CHECKLISTS, IsComplete=BOOLEAN, ChecklistOrderStates=ORDER_CHECKLIST_STATUSES)
    
	OrderChecklistIds = ''
	ErrorMsg          = ''
	If ( (NicaOrdersIds NE '') or (IsComplete NE '') or (ChecklistOrderStates NE '') ) then 
		Open 'DICT.NICA_ORDERS_CHECKLISTS' to hDict then
			Query   = ''
			Table   = 'NICA_ORDERS_CHECKLISTS'
			Option  = 'E'
			Flag    = ''
			If (NicaOrdersIds NE '') then
				Query := 'NICA_ORDERS_ID'
				For each NicaOrderId in NicaOrdersIds using @VM
					Query := @VM : NicaOrderId
				Next NicaOrderId
				Query := @FM
			end
			If (NicaChecklistIds NE '') then
			    Query := 'NICA_CHECKLISTS_ID'
			    For each NicaChecklistId in NicaChecklistIds using @VM
			        Query := @VM : NicaChecklistId
			    Next NicaChecklistId
			    Query := @FM
			end
			If (IsComplete NE '') then
				Query := 'IS_COMPLETE'
				For each Val in IsComplete using @VM
					Query := @VM : Val
				Next Val
				Query := @FM
			end
			If (ChecklistOrderStates NE '') then
			    Query := 'STATE'
			    For each ChecklistOrderState in ChecklistOrderStates using @VM
			        Query := @VM : ChecklistOrderState
			    Next ChecklistOrderState
			    Query := @FM
			end
			Btree.Extract(Query, Table, hDict, OrderChecklistIds, Option, Flag)
			If Flag NE 0 then
				ErrorMsg = 'Error in ':Service:' service. Btree.Extract call failed.'
			end
		end else
			ErrorMsg = 'Error in ':Service:' service. Failed to open DICT.NICA_ORDERS_CHECKLISTS.'
		end
	end else
		ErrorMsg = 'Error in ':Service:' service. At least one search parameter must be provided.'
	end
	
	If ErrorMsg EQ '' then
		Response = OrderChecklistIds
	end else
		Error_Services('Add', ErrorMsg)
	end
    
end service


Service GetOrderUpdates()

	hSysLists   = Database_Services('GetTableHandle', 'SYSLISTS')
	Lock hSysLists, ServiceKeyID then
		Nica_Orders_Services('UpdateNicaChecklistBaseInstructionIds')
		ActiveOrderIds = Nica_Orders_Services('GetActiveOrders')
		For each OrderId in ActiveOrderIds using @VM
			Nica_Orders_Services('GetOrderStatusUpdate', OrderId)
		Next OrderId
		Unlock hSysLists, ServiceKeyID else Null
		Nica_Orders_Services('UpdateNicaFlags')
	end
	
end service


Service UpdateNicaFlags()
	
	ErrCode  = ''
	ReactNos = Reactor_Services('GetReactorNumbers')
	Open 'REACTOR' to hReactor then
		Open 'REACTOR_LOG' to hReactorLog then 
			For each ReactNo in ReactNos using @FM
				ProveInActive             = Reactor_Services('GetProveInActive', ReactNo)
				HgCVChecklistActive       = (Nica_Orders_Services('GetActiveOrders', 'REACTOR', ReactNo, 'IQS_HGCV_ALARM') NE '')
				IntrMaintChecklistActive  = (Nica_Orders_Services('GetActiveOrders', 'REACTOR', ReactNo, 'INTRUSIVE_MAINT') NE '')
				AbortAlarmChecklistActive = (Nica_Orders_Services('GetActiveOrders', 'REACTOR', ReactNo, 'ABORT_ALARM') NE '')
				Open 'REACTOR' to hReactor then
					ReadV CacheProveInActive from hReactor, ReactNo, REACTOR_PROVE_IN_ACTIVE$ then
						If CacheProveInActive NE ProveInActive then
							Lock hReactor, ReactNo then
								WriteV ProveInActive on hReactor, ReactNo, REACTOR_PROVE_IN_ACTIVE$ else Null
								Unlock hReactor, ReactNo else Null
							end
						end
					end
					ReadV CacheHgCVChecklistActive from hReactor, ReactNo, REACTOR_HGCV_CHECKLIST_ACTIVE$ then
						If CacheHgCVChecklistActive NE HgCVChecklistActive then
							Lock hReactor, ReactNo then
								WriteV HgCVChecklistActive on hReactor, ReactNo, REACTOR_HGCV_CHECKLIST_ACTIVE$ else Null
								Unlock hReactor, ReactNo else Null
							end
						end
					end
					ReadV CacheIntrMaintChecklistActive from hReactor, ReactNo, REACTOR_INTRUSIVE_MAINT_CHECKLIST_ACTIVE$ then
						If CacheIntrMaintChecklistActive NE IntrMaintChecklistActive then
							Lock hReactor, ReactNo then
								WriteV IntrMaintChecklistActive on hReactor, ReactNo, REACTOR_INTRUSIVE_MAINT_CHECKLIST_ACTIVE$ else Null
								Unlock hReactor, ReactNo else Null
							end
						end
					end
					ReadV CacheAbortAlarmChecklistActive from hReactor, ReactNo, REACTOR_ABORT_ALARM_CHECKLIST_ACTIVE$ then
						If CacheAbortAlarmChecklistActive NE AbortAlarmChecklistActive then
							Lock hReactor, ReactNo then
								WriteV AbortAlarmChecklistActive on hReactor, ReactNo, REACTOR_ABORT_ALARM_CHECKLIST_ACTIVE$ else Null
								Unlock hReactor, ReactNo else Null
							end
						end
					end					
				end
				CurrModeKey       = Xlate('REACTOR_CHILD_KEY_IDS_NG', ReactNo, 'REACT_MODE_KEY_IDS', 'X')
				CurrModeKey       = CurrModeKey[-1, 'B':@VM]
				CurrRLKey         = Xlate('REACT_MODE_NG', CurrModeKey, 'START_RL_ID', 'X')			
				RLChecklistActive = Reactor_Log_Services('GetRlChecklistActive', CurrRlKey)
				Open 'REACTOR_LOG' to hReactorLog then 
					ReadV CacheRlChecklistActive from hReactorLog, CurrRlKey, REACTOR_LOG_CHECKLIST_ACTIVE$ then
						If CacheRlChecklistActive NE RLChecklistActive then
							Lock hReactorLog, CurrRlKey then
								WriteV RlChecklistActive on hReactorLog, CurrRlKey, REACTOR_LOG_CHECKLIST_ACTIVE$ else Null	
								Unlock hReactorLog, CurrRlKey else Null	
							end
						end
					end
				end
			Next ReactNo		
		end
	end

end service


Service GetActiveOrders(EntityType=ENTITY_TYPES, EntityId, OrderTypes=ORDER_TYPES)

	Response = Nica_Orders_Services('GetOrderIds', EntityType, EntityID, OrderTypes, '#cancelled', False$:@VM:'') 
	
end service


Service CreateNewOrder(EntityType=ENTITY_TYPES, EntityID, OrderType=ORDER_TYPES, OrderFlows, OrderResponseLevel, ChecklistIds, Intrusive=BOOLEAN)

    If Intrusive NE True$ then Intrusive = False$

	ErrorMsg     = ''
	EntityTypes  = 'REACTOR,REACTOR_LOG'
	OrderTypes   = 'INTRUSIVE_MAINT,CHANGEOVER,INITIATE_IDLE,IDLE,ASM_HTR_TUBE_CHANGE,ASM_HTR_ANNUAL_PM,'
	OrderTypes  := 'ASM_HTR_SEMIANNUAL_PM,ASM_HTR_FIVE_AND_TEN_YEAR_PM,IQS_HGCV_ALARM,ABORT_ALARM'	
	
	Machine        = Environment_Services('GetServer')
	Headers        = 'Logging DTM' : @FM : 'Machine' : @FM : 'Log'
	ColumnWidths   = 20 : @FM : 15 : @FM : 300
	LogPath        = Environment_Services('GetApplicationRootPath') : '\LogFiles\NicaOrders'
	makeDirSuccess = Utility("MAKEDIR", LogPath)
	LogFileName    = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : '_CreateNicaOrder.csv'
	objLog         = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ' ', Headers, ColumnWidths, False$, False$)
	
	Prod             = Environment_Services('IsProd')
	IgnoreCertErrors = Not(Prod)
	
	If ( (EntityType NE '') and (EntityID NE '') and (OrderType NE '') ) then
		
		Begin Case
			Case Not(InList(EntityTypes, EntityType, ','))
				ErrorMsg = 'Error in ':Service:' service. Unsupported entity type'
			Case Not(InList(OrderTypes, OrderType, ','))
				ErrorMsg = 'Error in ':Service:' service. Unsupported order type'
		End Case
		
		If ErrorMsg EQ '' then 
			
			LogData    = ''
			LogData<1> = Oconv(Date(), 'D4/') : ' ' : Oconv(Time(), 'MTS') ; // Logging DTM
			LogData<2> = Machine
			LogData<3> = 'Attempting to create NICA order for entity ':EntityType:' ' :EntityID:' of type ':OrderType
			Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$)			
			
			Begin Case
			    
			    Case OrderType _EQC 'ABORT_ALARM'
			        
			        OrderTypes            = OrderType:@VM:'INTRUSIVE_MAINT'
			        CurrActiveOrders      = Nica_Orders_Services('GetActiveOrders', EntityType, EntityID, OrderTypes)
			        If CurrActiveOrders NE '' then
			            // If any active ABORT_ALARM orders are marked as intrusive (i.e., they were merged 
			            // with an INTRUSIVE_MAINT order then mark the new order as intrusive).
			            ActiveOrdersIntrusive = Sum(Xlate('NICA_ORDERS', CurrActiveOrders, 'INTRUSIVE', 'X'))
			            If ActiveOrdersIntrusive then Intrusive = True$
			        end
			        
			    Case OrderType _EQC 'INTRUSIVE_MAINT'
			        
			        Intrusive                  = True$
			        CurrActiveOrders           = Nica_Orders_Services('GetActiveOrders', EntityType, EntityID, OrderType)
			        CurrActiveAbortAlarmOrders = Nica_Orders_Services('GetActiveOrders', EntityType, EntityID, 'ABORT_ALARM')
			        If CurrActiveAbortAlarmOrders NE '' then
			            CurrActiveOrders<-1> = CurrActiveAbortAlarmOrders
			            // Merge INTRUSIVE_MAINT and ABORT_ALARM orders into one ABORT_ALARM order.
			            // Preserve ABORT_ALARM order flow ids for Reactor mode change logic that relies on these
			            // to determine whether or not to trigger a new ABORT/ALARM order when changing ABORT/ALARM sub modes.
			            OrderType            = 'ABORT_ALARM'
			            OrderFlows           = Xlate('NICA_ORDERS', CurrActiveAbortAlarmOrders, 'ORDER_FLOW_IDS', 'X')
			            OrderFlows           = SRP_Array('Clean', OrderFlows, 'TrimAndMakeUnique', @VM)
			        end
			        
			    Case Otherwise$
			        CurrActiveOrders = Nica_Orders_Services('GetActiveOrders', EntityType, EntityID, OrderType)
			        
			End Case
			
			OrderTypeAlreadyActive = (CurrActiveOrders NE '')
			
			If ( (OrderTypeAlreadyActive EQ False$) or (OrderType EQ 'INTRUSIVE_MAINT') or (OrderType EQ 'ABORT_ALARM') ) then
				
				Begin Case
					Case EntityType EQ 'REACTOR'
						ReactNo = EntityID
						
					Case EntityType EQ 'REACTOR_LOG'
						ReactNo = Xlate(EntityType, EntityID, REACTOR_LOG_REACTOR$, 'X')
				End Case
				
				// Build request
				Body                  = ''
				NewSortedChecklistIds = ''
				If ( (OrderType NE 'INTRUSIVE_MAINT') and (OrderType NE 'ABORT_ALARM') ) then
					// Original API endpoint just uses query params, no body.
					NicaURL  = Environment_Services("GetProveInApiUrl"):'/checklists?'
					NicaURL := 'checklistType=':OrderType					
					NicaURL := '&reactorNumber=':ReactNo
				end else
					// New API endpoint uses JSON body instead of query params.
					NicaURL             = Environment_Services("GetProveInApiUrl"):'/order'
					If OrderFlows NE '' then
						If ChecklistIds NE '' then
							NewChecklistIds = ChecklistIds
							If CurrActiveOrders NE '' then
								IncompleteChecklistIds = ''
								CompleteChecklistIds   = ''
								Open 'DICT.NICA_ORDERS_CHECKLISTS' to hDict then
									For each ActiveNicaOrdersId in CurrActiveOrders using @VM
										// Get incomplete checklists so we can add them to the new order
										IncompleteOrderChecklistIds  = ''
										Flag                         = ''
										Query                        = 'NICA_ORDERS_ID':@VM:ActiveNicaOrdersId:@FM
										Query                       := 'IS_COMPLETE':@VM:False$:@FM
										Btree.Extract(Query, 'NICA_ORDERS_CHECKLISTS', hDict, IncompleteOrderChecklistIds, 'E', Flag)
										If Flag EQ 0 then
											IncompleteOrderChecklistIdsRot = SRP_Array('Rotate', IncompleteOrderChecklistIds, @VM, '*')
											PrevChecklistIds               = IncompleteOrderChecklistIdsRot<0, 2>
											Swap '*' with @VM in PrevChecklistIds
											IncompleteChecklistIds<0, -1>  = PrevChecklistIds
										end
										
										// Build a list of completed checklists which should not be prescribed again in the replacement NICA order
										CompleteOrderChecklistIds  = ''
										Flag                       = ''
										Query                      = 'NICA_ORDERS_ID':@VM:ActiveNicaOrdersId:@FM
										Query                     := 'IS_COMPLETE':@VM:True$:@FM
										Btree.Extract(Query, 'NICA_ORDERS_CHECKLISTS', hDict, CompleteOrderChecklistIds, 'E', Flag)
										If Flag EQ 0 then
											CompleteOrderChecklistIdsRot     = SRP_Array('Rotate', CompleteOrderChecklistIds, @VM, '*')
											CompChecklistIds                 = CompleteOrderChecklistIdsRot<0, 2>
											Swap '*' with @VM in CompChecklistIds
										end
										For each CompChecklistId in CompChecklistIds using @VM
											RemoveIfComp = Xlate('NICA_CHECKLISTS', CompChecklistId, NICA_CHECKLISTS.REMOVE_IF_COMPLETE$, 'X')
											If RemoveIfComp then
												Locate CompChecklistId in NewChecklistIds using @VM setting vPos then
													NewChecklistIds = Delete(NewChecklistIds, 0, vPos, 0)
												end
											end
										Next CompChecklistId
										
									Next ActiveNicaOrdersId								
								end
								NewChecklistIds<0, -1> = IncompleteChecklistIds
							end
							
							NewChecklistIds        = SRP_Array('Clean', NewChecklistIds, 'TrimAndMakeUnique', @VM)
							If Intrusive then
							    // Remove checklist ids with REMOVE_IF_INRUSIVE flag set to True$
							    ChecklistIdsToRemove = Nica_Orders_Services('GetChecklistIds', '', '', '', '', '', '', True$)
							    If ChecklistIdsToRemove NE '' then
							        For each ChecklistIdToRemove in ChecklistIdsToRemove using @VM
							            Locate ChecklistIdToRemove in NewChecklistIds using @VM setting vPos then
							                NewChecklistIds = Delete(NewChecklistIds, 0, vPos, 0)
							            end
							        Next ChecklistIdToRemove
							    end
							end
							NewChecklistPriorities = Xlate('NICA_CHECKLISTS', NewChecklistIds, 'PRIORITY', 'X')
							ChecklistArray         = NewChecklistIds:@FM:NewChecklistPriorities
							ChecklistArray         = SRP_Array('SortRows', ChecklistArray, 'AR2', 'ARRAY', @FM, @VM)
							NewSortedChecklistIds  = ChecklistArray<1>
							JsonRequest = ''
							objJson     = ''
							If SRP_JSON(objJson, 'New', 'Object') then
								SRP_JSON(objJson, 'SetValue', 'orderType', OrderType)
								SRP_JSON(objJson, 'SetValue', 'reactorNumber', ReactNo)
								NewChecklistInstIds = Xlate('NICA_CHECKLISTS', NewSortedChecklistIds, 'NICA_BASE_INSTRUCTION_ID', 'X')
								SRP_JSON(objJson, 'SetValueArray', 'baseInstructionIds', NewChecklistInstIds, @VM)
								Body                = SRP_JSON(objJson, 'Stringify', 'Fast')
								Convert @FM to '' in Body
								SRP_JSON(objJson, 'Release')
							end else
								ErrorMsg = 'Error in ':Service:' service. Failed to initialize JSON object for request body.'
							end
						end else
							ErrorMsg = 'Error in ':Service:' service. Null ChecklistIds variable passed in.'
						end
					end else
						ErrorMsg = 'Error in ':Service:' service. Null Orderflows variable passed in.'
					end
				end
				
				// Send the request
				IsSuccessful   = False$
				If ErrorMsg EQ '' then 
				
				    AttemptNo      = 0
					Retries        = 3
					BackoffSeconds = 1
					OrderId        = ''
					
					Loop					    
					while (IsSuccessful EQ False$ and Retries GT 0)
						WaitSeconds = (3 - retries) * BackoffSeconds
						Delay(WaitSeconds)
						
						Retries          = Retries - 1
						If Body NE '' then
							Headers = 'Content-Type':@VM:'application/json':@FM:'Accept':@VM:'*/*'
						end else
							Headers = 'Accept':@VM:'*/*'
						end
						
                        LogData<1>        = Oconv(Date(), 'D4/') : ' ' : Oconv(Time(), 'MTS') ; // Logging DTM
                        LogData<2>        = Machine
                        AttemptNo        += 1
                        LogData<3>        = 'Attempt number ':AttemptNo:' to send HTTP POST request to ':NicaURL
                        Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$)
                        
                        // Write directly to the log file to avoid mangling the JSON
                        OSRead LogBytes from LogPath:'\':LogFileName then
                            LogBytes := CRLF$:Body
                            OSWrite LogBytes to LogPath:'\':LogFileName
                        end

						HttpResponseJson = Httpclient_Services('SendHTTPRequest', 'POST', NicaURL, Headers, Body, '', '', False$, False$, '', IgnoreCertErrors)
						
                        LogData<1> = Oconv(Date(), 'D4/') : ' ' : Oconv(Time(), 'MTS') ; // Logging DTM
                        LogData<2> = Machine
                        LogData<3> = 'Attempt number ':AttemptNo:' HttpResponse from ':NicaURL:':'
                        Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$)
                        
                        // Write directly to the log file to avoid mangling the JSON
                        OSRead LogBytes from LogPath:'\':LogFileName then
                            LogBytes := CRLF$:HttpResponseJson
                            OSWrite LogBytes to LogPath:'\':LogFileName
                        end                        
                        
						If HttpResponseJson NE '' then
							ObjResponseJson = ''
							If SRP_JSON(ObjResponseJson, 'Parse', HttpResponseJson) EQ '' then
								OrderId = SRP_JSON(ObjResponseJson, 'GetValue', 'id')
								If OrderId NE '' then
									Convert @Lower.Case to @Upper.Case in OrderId
									ReqDtm                                  = SRP_JSON(ObjResponseJson, 'GetValue', 'requestedDate')
									ReqDate                                 = IConv(ReqDtm[1, 'FT'], 'DJ')
									ReqTime                                 = IConv(ReqDtm[Col2() + 1, 'F.'], 'MT')
									CreatedDtm                              = ReqDate + (ReqTime/SECONDS_IN_DAY$)
									NicaOrderRec                            = ''
									NicaOrderRec<NICA_ORDERS.ORDER_TYPE$>   = OrderType
									NicaOrderRec<NICA_ORDERS.ORDER_STATUS$> = SRP_JSON(ObjResponseJson, 'GetValue', 'state')
									NicaOrderRec<NICA_ORDERS.ENTITY_TYPE$>  = EntityType
									NicaOrderRec<NICA_ORDERS.ENTITY_ID$>    = EntityID
									NicaOrderRec<NICA_ORDERS.IS_COMPLETE$>  = SRP_JSON(ObjResponseJson, 'GetValue', 'isComplete')
									NicaOrderRec<NICA_ORDERS.CREATED_DTM$>  = CreatedDtm
									If NicaOrderRec<NICA_ORDERS.IS_COMPLETE$> EQ False$ then
										NicaOrderRec<NICA_ORDERS.PROGRESS_PERCENTAGE$>  = SRP_JSON(ObjResponseJson, 'GetValue', 'progressPercentage')
									end else
										NicaOrderRec<NICA_ORDERS.PROGRESS_PERCENTAGE$>  = 100
									end
									NicaOrderRec<NICA_ORDERS.ORDER_FLOW_IDS$>       = OrderFlows
									NicaOrderRec<NICA_ORDERS.ORDER_RESPONSE_LEVEL$> = OrderResponseLevel
									NicaOrderRec<NICA_ORDERS.INTRUSIVE$>            = Intrusive
									LogNicaOrderRec                                 = NicaOrderRec
									Swap @FM with ',' in LogNicaOrderRec
									LogData                                         = ''
									LogData<1>                                      = Oconv(Date(), 'D4/') : ' ' : Oconv(Time(), 'MTS') ; // Logging DTM
									LogData<2>                                      = Machine
									LogData<3>                                      = 'Nica order record to write: ':LogNicaOrderRec
									Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$)
									
									Database_Services('WriteDataRow', 'NICA_ORDERS', OrderId, NicaOrderRec, True$, False$, False$)
									If Error_Services('NoError') then
										If ( (OrderType _EQC 'INITIATE_IDLE') and (EntityType _EQC 'REACTOR') ) then
											Open 'REACTOR' to hReactor then
												WriteV True$ to hReactor, ReactNo, REACTOR_IDLE_STARTUP_REQUIRED$ else
													ErrorMsg = 'Error in ':Service:' service. Error setting IDLE_STARTUP_REQUIRED flag in REACTOR record.'		
												end
											end
										end										
										If ( (OrderType _EQC 'INTRUSIVE_MAINT') or (OrderType _EQC 'ABORT_ALARM') ) then
											// Create NICA_ORDERS_CHECKLISTS child records for each checklist
											If NewSortedChecklistIds NE '' then
												For each ChecklistId in NewSortedChecklistIds using @VM
													Key                                                          = OrderId:'*':ChecklistId
													NicaOrdersChecklistsRec                                      = ''
													NicaOrdersChecklistsRec<NICA_ORDERS_CHECKLISTS.IS_COMPLETE$> = False$
													Database_Services('WriteDataRow', 'NICA_ORDERS_CHECKLISTS', Key, NicaOrdersChecklistsRec, True$, False$, True$)
													If Error_Services('HasError') then ErrorMsg = Error_Services('GetMessage')
												Until (ErrorMsg NE '')
												Next ChecklistId
											end else
												ErrorMsg = 'Error in ':Service:' service. failed to create NICA_ORDERS_CHECKLIST records due to empty checklist array.'
											end
										end
										If ErrorMsg EQ '' then
											For each OrderId in CurrActiveOrders using @VM
												Nica_Orders_Services('CancelOrder', Orderid)
											Next OrderId
											IsSuccessful = True$
											Response     = OrderId
										end
									end else
										ErrorMsg = Error_Services('GetMessage')
									end
								end else
									ErrorMsg = 'Error in ':Service:' service. Null OrderId returned from MesaProveInAPI.'
								end
								SRP_JSON(ObjResponseJson, 'Release')
							end else
								ErrorMsg = 'Error in ':Service:' service. Error parsing JSON response from MesaProveInAPI.'
							end
						end else
							ErrorMsg = 'Error in ':Service:' service. Null JSON response returned from MesaProveInAPI.'
						end
					Repeat				
				end
				
				// Send MonA status
				StatusName   = 'CreateNicaOrder'
				If IsSuccessful then
					LogData     = ''
					LogData<1>  = Oconv(Date(), 'D4/') : ' ' : Oconv(Time(), 'MTS') ; // Logging DTM
					LogData<2>  = Machine
					LogData<3>  = 'Successfully created Nica order for entity ':EntityType:' ':EntityID:' of type ':OrderType
					Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$) 
					Mona_Services('PostStatus', MonaResource, StatusName, 'Ok')
				end else
					ErrorMsg   = 'Error encountered when attempting to create Nica in order for reactor ':ReactNo:' of type ':OrderType
					Mona_Services('PostStatus', MonaResource, StatusName, 'Critical')
				end
			end
		end else
			ErrorMsg   = 'Error encountered when attempting to create Nica order for entity ':EntityType:' ' :EntityID:' of type ':OrderType:'. Active order already exists.'
		end
	end else
		ErrorMsg = 'Error in ':Service:' service. Null EntityType, EntityID, or OrderType passed in.'
	end
	
	If ErrorMsg NE '' then
		LogData    = ''
		LogData<1> = Oconv(Date(), 'D4/') : ' ' : Oconv(Time(), 'MTS') ; // Logging DTM
		LogData<2> = Machine
		LogData<3> = ErrorMsg
		Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$) 		
		Error_Services('Add', ErrorMsg)
		Response = 'error'
	end
	
end service


Service CancelOrder(OrderId)
	
	ErrorMsg       = ''
	Machine        = Environment_Services('GetServer')
	Headers        = 'Logging DTM' : @FM : 'Machine' : @FM : 'Log'
	ColumnWidths   = 20 : @FM : 15 : @FM : 300
	LogPath        = Environment_Services('GetApplicationRootPath') : '\LogFiles\NicaOrders'
	makeDirSuccess = Utility("MAKEDIR", LogPath)
	LogFileName    = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : '_CancelNicaOrder.csv'
	objLog         = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ' ', Headers, ColumnWidths, False$, False$)
	
	LogData    = ''
	LogData<1> = Oconv(Date(), 'D4/') : ' ' : Oconv(Time(), 'MTS') ; // Logging DTM
	LogData<2> = Machine
	LogData<3> = 'Attempting to cancel Nica order ' : OrderId :'.'
	Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$)
	
	Prod             = Environment_Services('IsProd')
	IgnoreCertErrors = Not(Prod)	
	
	If OrderId NE '' then
		LockRetries        = 3
		LockBackoffSeconds = 1
		HaveLock           = False$
		Loop
		While (HaveLock EQ False$ and LockRetries GT 0)
			WaitSeconds = (3 - LockRetries) * LockBackoffSeconds
			Delay(WaitSeconds)
			LockRetries = LockRetries - 1		
			HaveLock    = Database_Services('GetKeyIDLock', 'NICA_ORDERS', OrderId, True$)
		Repeat	
		
		If HaveLock then
			NicaOrderRec = Database_Services('ReadDataRow', 'NICA_ORDERS', OrderId)
			If Error_Services('NoError') then 
				EntityType = NicaOrderRec<NICA_ORDERS.ENTITY_TYPE$>
				EntityId   = NicaOrderRec<NICA_ORDERS.ENTITY_ID$>
				Begin Case
					Case EntityType EQ 'REACTOR'
						ReactNo = EntityId
						
					Case EntityType EQ 'REACTOR_LOG'
						ReactNo = Xlate(EntityType, EntityId, REACTOR_LOG_REACTOR$, 'X')
						
					Case Otherwise$
						ErrorMsg = 'Error in ':Service:' service. Unsupported entity type.'
				End Case	
				
				If ErrorMsg EQ '' then 
					
					LogData     = ''
					LogData<1>  = Oconv(Date(), 'D4/') : ' ' : Oconv(Time(), 'MTS') ; // Logging DTM
					LogData<2>  = Machine
					LogData<3>  = 'Sending cancel request for Nica order ' : OrderId : ' for reactor ' : ReactNo
					Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$)
					
					Response       = False$
					BaseProveInUrl = Environment_Services("GetProveInApiUrl"):'/checklists?'
					UrlOrderId     = OrderId
					Convert @Upper.Case to @Lower.Case in UrlOrderId
					ProveInUrl     = BaseProveInUrl:'checklistOrderId=':UrlOrderId					
					ProveInUrl     = ProveInUrl:'&checklistState=cancelled'
					
					Retries        = 3
					BackoffSeconds = 1
					IsSuccessful   = False$
					
					Loop
					while (IsSuccessful EQ False$ and Retries GT 0)
						WaitSeconds = (3 - Retries) * BackoffSeconds
						Delay(WaitSeconds)
						Retries = Retries - 1
						HttpResponseJson = Httpclient_Services('SendHTTPRequest', 'PUT', ProveInUrl, 'Accept':@VM:'*/*', '', '', '', False$, False$, '', IgnoreCertErrors)
						If HttpResponseJson NE '' then
							ObjResponseJson = ''
							If SRP_JSON(ObjResponseJson, 'Parse', HttpResponseJson) EQ '' then
								IsComplete                              = SRP_JSON(ObjResponseJson, 'GetValue', 'isComplete')
								NicaOrderRec<NICA_ORDERS.ORDER_STATUS$> = 'cancelled'
								NicaOrderRec<NICA_ORDERS.IS_COMPLETE$>  = IsComplete
								CloseDtm                                = Datetime()
								NicaOrderRec<NICA_ORDERS.CLOSED_DTM$>   = CloseDtm								
								If IsComplete EQ False$ then
								    NicaOrderRec<NICA_ORDERS.PROGRESS_PERCENTAGE$>  = SRP_JSON(ObjResponseJson, 'GetValue', 'progressPercentage')
								end else
								    NicaOrderRec<NICA_ORDERS.PROGRESS_PERCENTAGE$>  = 100
								end
								Database_Services('WriteDataRow', 'NICA_ORDERS', OrderId, NicaOrderRec, True$, False$, False$)						
								If Error_Services('NoError') then
									OrderType = NicaOrderRec<NICA_ORDERS.ORDER_TYPE$>
									If ( (OrderType _EQC 'IDLE') and (EntityType EQ 'REACTOR') ) then
										Open 'REACTOR' to hReactor then
											WriteV False$ on hReactor, ReactNo, REACTOR_IDLE_STARTUP_REQUIRED$ else
												ErrorMsg = 'Error in ':Service:' service. Error setting IDLE_STARTUP_REQUIRED flag in REACTOR record.'
											end
										end
									end
									If (OrderType EQ 'ABORT_ALARM') then
										ActiveAbortAlarmOrders = Nica_Orders_Services('GetActiveOrders', 'REACTOR', ReactNo, 'ABORT_ALARM')
										AbortAlarmOrderActive  = (ActiveAbortAlarmOrders NE '')
										If (AbortAlarmOrderActive EQ False$) then 
											Open 'REACTOR' to hReactor then
												WriteV True$ on hReactor, ReactNo, REACTOR_ABORT_ALARM_COMPLETE$ else
													ErrorMsg = 'Error in ':Service:' service. Error setting ABORT_ALARM_COMPLETE flag in REACTOR record.'
												end
											end
										end
									end									
									If ( (Response EQ True$) or (Response EQ False$) ) then IsSuccessful = True$
								end else
									ErrorMsg = Error_Services('GetMessage')
								end
								If IsComplete EQ True$ then
									Response = True$
								end else
									Response = False$
								end
							end
						end
						SRP_JSON(ObjResponseJson, 'Release')
					Repeat
					
					StatusName   = 'CancelNicaOrder'
					If ( (IsSuccessful EQ True$) and (Response NE 'error') and (ErrorMsg EQ '') ) then		
						LogData     = ''
						LogData<1>  = Oconv(Date(), 'D4/') : ' ' : Oconv(Time(), 'MTS') ; // Logging DTM
						LogData<2>  = Machine
						LogData<3>  = 'Successfully cancelled Nica order ' : OrderId : ' for reactor ' : ReactNo
						Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$)
						Mona_Services('PostStatus', MonaResource, StatusName, 'Ok')
					end else
						ErrorMsg   = 'Error encountered cancelling Nica order ' : OrderId : ' for reactor ' : ReactNo
						Mona_Services('PostStatus', MonaResource, StatusName, 'Critical')
					end
				end else
					ErrorMsg = Error_Services('GetMessage')
					Database_Services('ReleaseKeyIDLock', 'NICA_ORDERS', OrderId)
				end			
			end else
				ErrorMsg = 'Error in ':Service:' service. Failed to lock NICA_ORDERS ':OrderId:' for cancellation.'
			end
		end else
			ErrorMsg = 'Error in ':Service:' service. Null OrderID passed in.'
		end
	end else
		ErrorMsg = Error_Services('GetMessage')
	end
	
	If ErrorMsg NE '' then
		LogData    = ''
		LogData<1> = Oconv(Date(), 'D4/') : ' ' : Oconv(Time(), 'MTS') ; // Logging DTM
		LogData<2> = Machine
		LogData<3> = ErrorMsg
		Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$) 		
		Error_Services('Add', ErrorMsg)
		Response = 'error'
	end
	
end service


Service GetOrderStatus(OrderId)
	
	If OrderId NE '' then
		If RowExists('NICA_ORDERS', OrderId) then
			Response = Xlate('NICA_ORDERS', OrderId, 'ORDER_STATUS', 'X')
		end else
			Error_Services('Add', 'Error in ':Service:' service. Nica order ':OrderId:' does not exist.')
		end
	end else
		Error_Services('Add', 'Error in ':Service:' service. Null OrderId passed in.')
	end
	
end service


Service GetOrderStatusUpdate(OrderId)
	
	ErrorMsg       = ''
	Headers        = 'Logging DTM' : @FM : 'Machine' : @FM : 'Log'
	ColumnWidths   = 20 : @FM : 15 : @FM : 300
	LogPath        = Environment_Services('GetApplicationRootPath') : '\LogFiles\NicaOrders'
	makeDirSuccess = Utility("MAKEDIR", LogPath)
	LogFileName    = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : '_GetOrderStatusUpdate.csv'
	objLog         = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ' ', Headers, ColumnWidths, False$, False$)
	
	LogData    = ''
	LogData<1> = Oconv(Date(), 'D4/') : ' ' : Oconv(Time(), 'MTS') ; // Logging DTM
	LogData<2> = Machine
	LogData<3> = 'Attempting to update Nica order ' : OrderId :'.'
	Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$)
	
	Prod             = Environment_Services('IsProd')
	IgnoreCertErrors = Not(Prod)
	
	If OrderId NE '' then 
		HaveLock = Database_Services('GetKeyIDLock', 'NICA_ORDERS', OrderId, True$)
		If HaveLock then
			NicaOrderRec = Database_Services('ReadDataRow', 'NICA_ORDERS', OrderId)
			If Error_Services('NoError') then 
				EntityType = NicaOrderRec<NICA_ORDERS.ENTITY_TYPE$>
				EntityId   = NicaOrderRec<NICA_ORDERS.ENTITY_ID$>
				Begin Case
					Case EntityType EQ 'REACTOR'
						ReactNo = EntityId
						
					Case EntityType EQ 'REACTOR_LOG'
						ReactNo = Xlate(EntityType, EntityId, REACTOR_LOG_REACTOR$, 'X')
						
					Case Otherwise$
						ErrorMsg = 'Error in ':Service:' service. Unsupported entity type.'
				End Case	
				
				If ErrorMsg EQ '' then 	
					
					LogData    = ''
					LogData<1> = Oconv(Date(), 'D4/') : ' ' : Oconv(Time(), 'MTS') ; // Logging DTM
					LogData<2> = Machine
					LogData<3> = 'Attempting to fetch Nica order ':OrderId:' for reactor ':ReactNo
					Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$)
					
					Response       = True$
					IsSuccessful   = True$
					BaseProveInUrl = Environment_Services("GetProveInApiUrl"):'/checklists?'
					UrlOrderId     = OrderId
					Convert @Upper.Case to @Lower.Case in UrlOrderId
					ProveInUrl     = BaseProveInUrl:'checklistOrderId=':UrlOrderId
					
					Retries        = 3
					BackoffSeconds = 1
					IsSuccessful   = False$
					
					Loop
					while (IsSuccessful EQ False$ and Retries GT 0)
						WaitSeconds = (3 - Retries) * BackoffSeconds
						Delay(WaitSeconds)
						Retries          = Retries - 1
						HttpResponseJson = Httpclient_Services('SendHTTPRequest', 'GET', ProveInUrl, 'Accept':@VM:'*/*', '', '', '', False$, False$, '', IgnoreCertErrors)
						
						If HttpResponseJson NE '' then
							ObjResponseJson = ''
							If SRP_JSON(ObjResponseJson, 'Parse', HttpResponseJson) EQ '' then
								IsComplete                              = SRP_JSON(ObjResponseJson, 'GetValue', 'isComplete')
								State                                   = SRP_JSON(ObjResponseJson, 'GetValue', 'state')
								NicaOrderRec<NICA_ORDERS.ORDER_STATUS$> = State
								NicaOrderRec<NICA_ORDERS.IS_COMPLETE$>  = IsComplete
								CloseDtm                                = NicaOrderRec<NICA_ORDERS.CLOSED_DTM$>
								If ( (CloseDtm EQ '' ) and ( (State _EQC 'done') or (State _EQC 'cancelled') ) ) then
									CloseDtm                              = Datetime()
									NicaOrderRec<NICA_ORDERS.CLOSED_DTM$> = CloseDtm
								end
								If IsComplete EQ False$ then
								    NicaOrderRec<NICA_ORDERS.PROGRESS_PERCENTAGE$>  = SRP_JSON(ObjResponseJson, 'GetValue', 'progressPercentage')
								end else
								    NicaOrderRec<NICA_ORDERS.PROGRESS_PERCENTAGE$>  = 100
								end
								Database_Services('WriteDataRow', 'NICA_ORDERS', OrderId, NicaOrderRec, True$, False$, False$)
								If Error_Services('NoError') then
									OrderType = NicaOrderRec<NICA_ORDERS.ORDER_TYPE$>
									If ( (OrderType _EQC 'INTRUSIVE_MAINT') or (OrderType _EQC 'ABORT_ALARM') ) then
										// Update NICA_ORDERS_CHECKLISTS records (documents)
										Open 'NICA_ORDERS_CHECKLISTS' to hNicaOrdersChecklists then 
											// Parse documents array for their isComplete flag
											ObjDocumentArray = SRP_JSON(ObjResponseJson, 'get', 'progresses')
											If ObjDocumentArray NE 0 then
												NumDocs      = SRP_JSON(objDocumentArray, 'GetCount')
												For DocIndex = 1 to NumDocs
													DocumentId   = SRP_JSON(ObjDocumentArray, 'GetValue', '[':DocIndex:'].baseInstructionId', '')
													If DocumentId NE '' then 
														State       = SRP_JSON(ObjDocumentArray, 'GetValue', '[':DocIndex:'].state', False$)
														IsComplete  = (State _EQC 'done')
														ChecklistId = ''
														Extract_SI_Keys('NICA_CHECKLISTS', 'NICA_BASE_INSTRUCTION_ID', DocumentId, ChecklistId)
														ErrorCode   = ''
														If Not(Get_Status(ErrorCode)) then
															If ChecklistId NE '' then
																NicaOrdersChecklistsKey = OrderId:'*':ChecklistId
																HaveOrderChecklistLock  = Database_Services('GetKeyIDLock', 'NICA_ORDERS_CHECKLISTS', NicaOrdersChecklistsKey)
																If HaveOrderChecklistLock then 
																	NicaOrdersChecklistsRec = Database_Services('ReadDataRow', 'NICA_ORDERS_CHECKLISTS', NicaOrdersChecklistsKey)
																	If Error_Services('NoError') then
																		NicaOrdersChecklistsRec<NICA_ORDERS_CHECKLISTS.IS_COMPLETE$> = IsComplete
																		NicaOrdersChecklistsRec<NICA_ORDERS_CHECKLISTS.STATE$>       = State
																		Database_Services('WriteDataRow', 'NICA_ORDERS_CHECKLISTS', NicaOrdersChecklistsKey, NicaOrdersChecklistsRec, True$, False$, False$)
																		If Error_Services('HasError') then
																			Database_Services('ReleaseKeyIDLock', 'NICA_ORDERS_CHECKLISTS', NicaOrdersChecklistsKey)
																		end
																	end
																end
															end else
																ErrorMsg = 'Error in ':Service:' service. No NICA_CHECKLISTS record found for documentId ':DocumentId:'.'
															end
														end else
															ErrorMsg = 'Error in ':Service:' service. Error calling Extract_SI_Keys on NICA_CHECKLISTS table. Error code: ':ErrorCode:'.'
														end
													end else
														ErrorMsg = 'Error in ':Service:' service. Null documentId return from Json response.'
													end
												Next DocIndex
												SRP_JSON(ObjDocumentArray, 'Release')
											end else
												ErrorMsg = 'Error in ':Service:' service. Error retrieving documents array from Json response.'
											end
										end else
											ErrorMsg = 'Error in ':Service:' service. Error opening NICA_ORDERS_CHECKLISTS table.'
										end
									end									
									If ( (OrderType _EQC 'ABORT_ALARM') and ( (State _EQC 'done') or (State _EQC 'cancelled') ) ) then
										ActiveAbortAlarmOrders = Nica_Orders_Services('GetActiveOrders', 'REACTOR', ReactNo, 'ABORT_ALARM')
										AbortAlarmOrderActive  = (ActiveAbortAlarmOrders NE '')
										If (AbortAlarmOrderActive EQ False$) then 										
											Open 'REACTOR' to hReactor then
												WriteV True$ on hReactor, ReactNo, REACTOR_ABORT_ALARM_COMPLETE$ else
													ErrorMsg = 'Error in ':Service:' service. Error setting ABORT_ALARM_COMPLETE flag in REACTOR record.'
												end
											end
										end
									end
									If IsComplete EQ True$ then
										If ( (OrderType _EQC 'IDLE') and (EntityType _EQC 'REACTOR') ) then
											Open 'REACTOR' to hReactor then
												WriteV False$ on hReactor, ReactNo, REACTOR_IDLE_STARTUP_REQUIRED$ else
													ErrorMsg = 'Error in ':Service:' service. Error setting IDLE_STARTUP_REQUIRED flag in REACTOR record.'
												end
											end
										end
										If ErrorMsg EQ '' then Response = True$
									end else
										Response = False$
									end									
									If ( (Response EQ True$) or (Response EQ False$) ) then IsSuccessful = True$
								end else
									ErrorMsg = Error_Services('GetMessage')
								end
							end
							SRP_JSON(ObjResponseJson, 'Release')
						end
					Repeat
					
					StatusName   = 'GetNicaOrderUpdate'
					If IsSuccessful and Response NE 'error' then
						LogData     = ''
						LogData<1>  = Oconv(Date(), 'D4/') : ' ' : Oconv(Time(), 'MTS') ; // Logging DTM
						LogData<2>  = Machine
						LogData<3>  = 'Successfully updated Nica order ':OrderId:' for reactor ':ReactNo:'.'
						Mona_Services('PostStatus', MonaResource, StatusName, 'Ok')
						Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$)
					end else
						Database_Services('ReleaseKeyIDLock', 'NICA_ORDERS', OrderId)
						ErrorMsg   = 'Error encountered updating Nica order ':OrderId:' for reactor ':ReactNo:'.'
						Mona_Services('PostStatus', MonaResource, StatusName, 'Critical')
					end					
				end
			end else
				ErrorMsg = Error_Services('GetMessage')
			end
		end else
			ErrorMsg = 'Error in ':Service:' service. Failed to lock NICA_ORDERS ':OrderId:'.'
		end
	end else
		ErrorMsg = 'Error in ':Service:' service. Null OrderId passed in.'
	end
		
	If ErrorMsg NE '' then
		LogData    = ''
		LogData<1> = Oconv(Date(), 'D4/') : ' ' : Oconv(Time(), 'MTS') ; // Logging DTM
		LogData<2> = Machine
		LogData<3> = ErrorMsg
		Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$)
		Error_Services('Add', ErrorMsg)
		Response = 'error'		
	end
		
end service


Service GetFlowChecklistIds(NicaOrderFlowIds, NicaOrderFlowType=ORDER_TYPES, ReactorTypes=REACTOR_TYPES)

	ErrorMsg         = ''
	FlowChecklistIds = ''
	If ( (NicaOrderFlowIds NE '') and (NicaOrderFlowType NE '') and (ReactorTypes NE '') ) then
		Query = 'SELECT NICA_CHECKLISTS '
		For each NicaOrderFlowId in NicaOrderFlowIds using @VM setting vPos
			If vPos GT 1 then Query := 'OR '
			Query := 'WITH NICA_ORDER_FLOW_IDS EQ ':Quote(NicaOrderFlowId):' '
		Next NicaOrderFlowId
		Query := 'AND WITH NICA_ORDER_FLOW_TYPE EQ ':Quote(NicaOrderFlowType):' '
		For each ReactorType in ReactorTypes using @VM setting vPos
			If vPos EQ 1 then
				Query := 'AND '
			end else
				Query := 'OR '
			end
			Query := 'WITH REACTOR_TYPES EQ ':Quote(ReactorType):' '
		Next ReactorType
		Query   := 'BY PRIORITY'
		RList(Query, TARGET_ACTIVELIST$, '', '', '')
		ErrCode  = ''
		If Not(Get_Status(ErrCode)) then
			EOF = False$
			Loop
				Readnext KeyId else EOF = True$
			Until EOF
				FlowChecklistIds<0, -1> = KeyId
			Repeat
		end else
			ErrorMsg = 'Error in ':Service:' service. Error calling RList. Error code: ':ErrCode:'.'
		end
	end else
		ErrorMsg = 'Error in ':Service:' service. Null NicaOrderFlowIds, NicaOrderFlowType, or ReactorTypes Passed in.'
	end
	If ErrorMsg NE '' then
		Error_Services('Add', ErrorMsg)
	end else
		Response = FlowChecklistIds
	end

end service


Service GetAvailableFlowIds(NicaOrderType=ORDER_TYPES)
	
	If NicaOrderType NE '' then
		ChecklistIds = ''
		Extract_SI_Keys('NICA_CHECKLISTS', 'NICA_ORDER_FLOW_TYPE', NicaOrderType, ChecklistIds)
		If ChecklistIds NE '' then
			FlowIds = Xlate('NICA_CHECKLISTS', ChecklistIds, 'NICA_ORDER_FLOW_IDS', 'X')
			If FlowIds NE '' then
				FlowIds  = SRP_Array('Clean', FlowIds, 'TrimAndMakeUnique', @VM)
				FlowIds  = SRP_Array('SortSimpleList', FlowIds, 'AscendingText', @VM)
				Response = FlowIds
			end
		end
	end else
		ErrorMsg = 'Error in ':Service:' service. Null NicaOrderType passed in.'
		Error_Services('Add', ErrorMsg)
	end
	
end service


Service AbortAlarmFromIntrusiveMaintRequired(ReactNo)
    
    ErrorMsg                             = ''
    AbortAlarmFromIntrusiveMaintRequired = ''
    If ReactNo NE '' then
        If RowExists('REACTOR', ReactNo) then
            ActiveIntrusiveMaintOrderIds = Nica_Orders_Services('GetActiveOrders', 'REACTOR', ReactNo, 'INTRUSIVE_MAINT')
            IntrusiveMaintOrderActive    = (ActiveIntrusiveMaintOrderIds NE '')
            If IntrusiveMaintOrderActive then
                // If any FIRST_PRODUCT_RUN_THICK or FIRST_PRODUCT_RUN_HGCV associated with active INTRUSIVE_MAINT
                // orders have been started or completed, then an ABORT/ALARM order should be triggerd.
                ChecklistIdsToSearch                 = 'FIRST_PRODUCT_RUN_THICK':@VM:'FIRST_PRODUCT_RUN_HGCV'
                InProcessOrCompleteOrderChecklistIds = Nica_Orders_Services('GetOrderChecklistIds', ActiveIntrusiveMaintOrderIds, ChecklistIdsToSearch, '', '#not-started')
                AbortAlarmFromIntrusiveMaintRequired = (InProcessOrCompleteOrderChecklistIds NE '')
            end else
                AbortAlarmFromIntrusiveMaintRequired = False$
            end
        end else
            ErrorMsg = 'Error in ':Service:' service. REACTOR ':ReactNo:' does not exist.'
        end
    end else
        ErrorMsg = 'Error in ':Service:' service. Null ReactNo passed into service.'
    end
    
    If ErrorMsg EQ '' then
        Response = AbortAlarmFromIntrusiveMaintRequired
    end else
        Error_Services('Add', ErrorMsg)
    end
    
end service


Service GetChecklistIds(Priorities, NicaBaseInstructionIds, NicaOrderFlowIds, NicaOrderFlowTypes, ReactorTypes, RemoveIfComplete=BOOLEAN, RemoveIfIntrusive=BOOLEAN)
    
	ChecklistIds = ''
	ErrorMsg     = ''
	If ( (Priorities NE '') or (NicaBaseInstructionIds NE '') or (NicaOrderFlowIds NE '') or (NicaOrderFlowTypes NE '') |
	    or (ReactorTypes NE '') or (RemoveIfComplete NE '') or (RemoveIfIntrusive NE '') ) then 
		Open 'DICT.NICA_CHECKLISTS' to hDict then
			Query   = ''
			Table   = 'NICA_CHECKLISTS'
			Option  = 'E'
			Flag    = ''
			If (Priorities NE '') then
				Query := 'PRIORITY'
				For each Priority in Priorities using @VM
					Query := @VM : Priority
				Next Priority
				Query := @FM
			end
			If (NicaBaseInstructionIds NE '') then
			    Query := 'NICA_BASE_INSTRUCTION_ID'
			    For each NicaBaseInstructionId in NicaBaseInstructionIds using @VM
			        Query := @VM : NicaBaseInstructionId
			    Next NicaBaseInstructionId
			    Query := @FM
			end
			If (NicaOrderFlowIds NE '') then
				Query := 'NICA_ORDER_FLOW_IDS'
				For each NicaOrderFlowId in NicaOrderFlowIds using @VM
					Query := @VM : NicaOrderFlowId
				Next NicaOrderFlowId
				Query := @FM
			end
			If (NicaOrderFlowTypes NE '') then
			    Query := 'NICA_ORDER_FLOW_TYPE'
			    For each NicaOrderFlowType in NicaOrderFlowTypes using @VM
			        Query := @VM : NicaOrderFlowType
			    Next NicaOrderFlowTypes
			    Query := @FM
			end
			If (ReactorTypes NE '') then
			    Query := 'REACTOR_TYPES'
			    For each NicaOrderFlowType in NicaOrderFlowTypes using @VM
			        Query := @VM : NicaOrderFlowType
			    Next NicaOrderFlowTypes
			    Query := @FM
			end
			If (RemoveIfComplete NE '') then
			    Query := 'REMOVE_IF_COMPLETE'
			    For each Val in RemoveIfComplete using @VM
			        Query := @VM : Val
			    Next RemoveIfComplete
			    Query := @FM
			end
			If (RemoveIfIntrusive NE '') then
			    Query := 'REMOVE_IF_INTRUSIVE'
			    For each Val in RemoveIfIntrusive using @VM
			        Query := @VM : Val
			    Next Val
			    Query := @FM
			end			
			Btree.Extract(Query, Table, hDict, ChecklistIds, Option, Flag)
			If Flag NE 0 then
				ErrorMsg = 'Error in ':Service:' service. Btree.Extract call failed.'
			end
		end else
			ErrorMsg = 'Error in ':Service:' service. Failed to open DICT.NICA_CHECKLISTS.'
		end
	end else
		ErrorMsg = 'Error in ':Service:' service. At least one search parameter must be provided.'
	end
	
	If ErrorMsg EQ '' then
		Response = ChecklistIds
	end else
		Error_Services('Add', ErrorMsg)
	end    
    
end service


Service UpdateNicaChecklistBaseInstructionIds()
	
	StatusName     = Service
	StatusState    = 'OK'
	Machine        = Environment_Services('GetServer')
	Headers        = 'Logging DTM' : @FM : 'Machine' : @FM : 'Log'
	ColumnWidths   = 20 : @FM : 15 : @FM : 300
	LogPath        = Environment_Services('GetApplicationRootPath') : '\LogFiles\NicaOrders'
	makeDirSuccess = Utility("MAKEDIR", LogPath)
	LogFileName    = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : '_UpdateBaseInstructionIds.csv'
	objLog         = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ' ', Headers, ColumnWidths, False$, False$)
	
	LogData    = ''
	LogData<1> = OConv(Datetime(), 'DT/^S')
	LogData<2> = Machine
	LogData<3> = 'Begin ':Service
	Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
	
	ErrorMsg = ''
	BaseNicaIntegrationServiceApiUrl = Environment_Services('GetProveInApiUrl')
	If BaseNicaIntegrationServiceApiUrl NE '' then
		Prod              = Environment_Services('IsProd')
		IgnoreCertErrors  = Not(Prod)		
		AllChecklistsUrl  = BaseNicaIntegrationServiceApiUrl:'/checklists/all'
		AllChecklistsJson = Httpclient_Services('SendHTTPRequest', 'GET', AllChecklistsUrl, '', '', '', '', '', '', '', IgnoreCertErrors)
		If Error_Services('NoError') then
			If AllChecklistsJson NE '' then
				objAllChecklistsJsonArray = ''
				If (SRP_Json(objAllChecklistsJsonArray, 'Parse', AllChecklistsJson) EQ '') then
					NumJsonChecklists = SRP_Json(objAllChecklistsJsonArray, 'GetCount')
					Open 'NICA_CHECKLISTS' to hNicaChecklists then
						EOF = False$
						Select hNicaChecklists
						Loop
							ReadNext NicaChecklistId else EOF = True$
						Until EOF
							Lock hNicaChecklists, NicaChecklistId then
								LogData<1> = OConv(Datetime(), 'DT/^S')
								LogData<2> = Machine
								LogData<3> = 'Successfully locked NICA_CHECKLISTS ':NicaChecklistId:' for update.'
								Logging_Services('AppendLog', objLog, LogData, @RM, @FM)								
								Read NicaChecklistRec from hNicaChecklists, NicaChecklistId then
									InstructionNameKey = NicaChecklistRec<NICA_CHECKLISTS.INTRUCTION_NAME_KEY$>
									If InstructionNameKey NE '' then
										Done = False$
										For InstructionIndex = 1 to NumJsonChecklists
											InstructionName = SRP_Json(objAllChecklistsJsonArray, 'GetValue', '[':InstructionIndex:'].name')
											If (IndexC(InstructionName, InstructionNameKey, 1) GT 0) then
												// Found matching json object
												BaseInstructionId = SRP_Json(objAllChecklistsJsonArray, 'GetValue', '[':InstructionIndex:'].baseInstructionId')
												WriteV BaseInstructionId on hNicaChecklists, NicaChecklistId, NICA_CHECKLISTS.NICA_BASE_INSTRUCTION_ID$ then
													LogData<1> = OConv(Datetime(), 'DT/^S')
													LogData<2> = Machine
													LogData<3> = 'Successfully updated NICA_BASE_INSTRUCTION_ID ':BaseInstructionId:' on NICA_CHECKLISTS ':NicaChecklistId:'.'
													Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
													Done       = True$
												end else
													ErrorMsg    = 'Error in ':Service:' service. Error updating NICA_CHECKLISTS record ':NicaChecklistId:'.'
													LogData<1>  = OConv(Datetime(), 'DT/^S')
													LogData<2>  = Machine
													LogData<3>  = 'Failed to write NICA_BASE_INSTRUCTION_ID ':BaseInstructionId:' on NICA_CHECKLISTS ':NicaChecklistId:'.'
													Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
													StatusState = 'CRITICAL'
												end
											end
										Until Done
										Next InstructionIndex
									end else
										LogData<1>  = OConv(Datetime(), 'DT/^S')
										LogData<2>  = Machine
										LogData<3>  = 'Failed to update NICA_BASE_INSTRUCTION_ID. Null INSTRUCTION_NAME_KEY in NICA_CHECKLISTS ':NicaChecklistId:'.'
										Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
										StatusState = 'CRITICAL'
									end
								end else
									LogData<1>  = OConv(Datetime(), 'DT/^S')
									LogData<2>  = Machine
									LogData<3>  = 'Failed to update NICA_BASE_INSTRUCTION_ID. Error reading NICA_CHECKLISTS ':NicaChecklistId:'.'
									Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
									StatusState = 'CRITICAL'
								end
								Unlock hNicaChecklists, NicaChecklistId then
									LogData<1> = OConv(Datetime(), 'DT/^S')
									LogData<2> = Machine
									LogData<3> = 'Successfully unlocked NICA_CHECKLISTS ':NicaChecklistId:'.'
									Logging_Services('AppendLog', objLog, LogData, @RM, @FM)	
								end else
									LogData<1>  = OConv(Datetime(), 'DT/^S')
									LogData<2>  = Machine
									LogData<3>  = 'Failed to unlock NICA_CHECKLISTS ':NicaChecklistId:'.'
									Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
									StatusState = 'CRITICAL'
								end
							end else
								LogData<1> = OConv(Datetime(), 'DT/^S')
								LogData<2> = Machine
								LogData<3> = 'Failed to lock NICA_CHECKLISTS ':NicaChecklistId:' for update.'
								Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
							end
						Repeat
					end else
						ErrorMsg = 'Error in ':Service:' service. Error opening NICA_CHECKLISTS table.'
					end
				end else
					ErrorMsg = 'Error in ':Service:' service. Error parsing Checklist JSON returned from NicaIntegrationServiceApi.'
				end
			end else
				ErrorMsg = 'Error in ':Service:' service. Null Checklist JSON returned from NicaIntegrationServiceApi.'
			end
		end else
			ErrorMsg = 'Error in ':Service:' service. Error getting Checklist JSON from NicaIntegrationServiceApi.'
		end
	end else
		ErrorMsg = 'Error in ':Service:' service. Null BaseNicaIntegrationServiceApiUrl.'
	end
	
	If ErrorMsg NE '' then
		LogData<1>  = OConv(Datetime(), 'DT/^S')
		LogData<2>  = Machine
		LogData<3>  = ErrorMsg
		Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
		StatusState = 'CRITICAL'		
	end
	
	Mona_Services('PostStatus', MonaResource, StatusName, StatusState)
	
	LogData<1> = OConv(Datetime(), 'DT/^S')
	LogData<2> = Machine
	LogData<3> = 'End ':Service
	Logging_Services('AppendLog', objLog, LogData, @RM, @FM)	
	
	If ErrorMsg NE '' then Error_Services('Add', ErrorMsg)
	
end service

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

