2438 lines
		
	
	
		
			95 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			2438 lines
		
	
	
		
			95 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| Compile function Report_Services(@Service, @Params)
 | |
| /***********************************************************************************************************************
 | |
| 
 | |
|     Name        :   Report_Services
 | |
| 
 | |
|     Description :   Handler program for all Report services.
 | |
| 
 | |
|     Notes       :   Application errors should be logged using the Error Services module. There are a few methodological
 | |
|                     assumptions built into way errors are managed which are important to understand in order to properly
 | |
|                     work with Error Services:
 | |
| 
 | |
|                     - The term 'top' refers to the originating procedure of a call stack and the term 'bottom' refers to
 | |
|                       the last routine (or the current routine) within a call stack. Within the OpenInsight Debugger
 | |
|                       this will appear backwards since the originating procedure always appears at the bottom of the
 | |
|                       list and the current routine appears at the top of the list. We are using this orientation because
 | |
|                       it is common to refer to the process of calling other procedures as 'drilling down'.
 | |
| 
 | |
|                     - The reason for defining the orientation of the call stack is because Error_Services allows for
 | |
|                       multiple error conditions to be appended to an original error. In most cases this will happen when
 | |
|                       a procedure at the bottom of the stack generates an error condition and then returns to its
 | |
|                       calling procedure. This higher level procedure can optionally add more information relevant to
 | |
|                       itself. This continues as the call stack 'bubbles' its way back to the top to where the
 | |
|                       originating procedure is waiting.
 | |
| 
 | |
|                     - Native OpenInsight commands that handle errors (e.g., Set_Status, Set_FSError, Set_EventStatus)
 | |
|                       preserve their error state until explicitly cleared. This can hinder the normal execution of code
 | |
|                       since subsequent procedures (usually SSPs) will fail if a pre-existing error condition exists.
 | |
|                       Our philosophy is that error conditions should automatically be cleared before a new procedure
 | |
|                       is executed to avoid this problem. However, the nature of Basic+ does not make this easy to
 | |
|                       automate for any given stored procedure. Therefore, if a stored procedure wants to conform to our
 | |
|                       philosophy then it should include a call into the 'Clear' service request at the top of the
 | |
|                       program. Alternatively this can be done through a common insert (see SERVICE_SETUP for example.)
 | |
| 
 | |
|                     - Service modules will use the SERVICE_SETUP insert and therefore automatically clear out any
 | |
|                       error conditions that were set before.
 | |
| 
 | |
|     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
 | |
| 
 | |
|     Metadata    :
 | |
| 
 | |
|     History     :   (Date, Initials, Notes)
 | |
|         10/30/20    djs     Original programmer.
 | |
| 														
 | |
| 
 | |
| ***********************************************************************************************************************/
 | |
| #pragma precomp SRP_PreCompiler
 | |
| 
 | |
| $Insert SERVICE_SETUP
 | |
| $Insert LOGICAL
 | |
| $Insert OIPRINT_EQUATES
 | |
| $Insert SCHED_DET_EQUATES
 | |
| $Insert WO_LOG_EQUATES
 | |
| $Insert APPCOLORS
 | |
| $Insert MSG_EQUATES
 | |
| $Insert SCHEDULE_EQU
 | |
| $Insert LOCATION_EQUATES
 | |
| $Insert RLIST_EQUATES
 | |
| $Insert DICT_EQUATES
 | |
| $Insert DAILY_METRICS_EQUATES
 | |
| $Insert RDS_EQUATES
 | |
| $Insert DAILY_PERFORMANCE_EQUATES
 | |
| $Insert DAILY_PERFORMANCE_REPORT_EQUATES
 | |
| $Insert SCHED_DET_NG_EQUATES
 | |
| $Insert MAKEUP_WAFERS_EQUATES
 | |
| $Insert REACTOR_EQUATES
 | |
| $Insert WAFER_COUNTER_EQUATES
 | |
| $Insert REACTOR_DAILY_UPTIME_EQUATES
 | |
| $Insert MATERIAL_REPORT_EQUATES
 | |
| 
 | |
| // Reduce modes (for Select statement)
 | |
| Equ NEW_EXIST$ To 0 
 | |
| Equ NEXT_CUR$  To 1
 | |
| Equ ADD_EXIST$ To 2  
 | |
| 
 | |
| Declare subroutine Utility, ErrMsg, Set_Status, Set_Printer, RList, SRP_Stopwatch, Btree.Extract, Error_Services, V119
 | |
| Declare subroutine Push.Select, Pop.Select, Database_Services, SRP_JSON, Logging_Services, Reduce, FSMsg
 | |
| Declare subroutine Report_Services, Make.List, Update_Index
 | |
| Declare function   Set_Printer, Get_Printer, Msg, Get_Status, Printer_Select, obj_Install, Dialog_Box, obj_Location
 | |
| Declare function   Schedule_Services, Error_Services, Location_Services, SRP_Array, Signature_Services, obj_RDS_Test
 | |
| Declare function   Epi_Part_Services, SRP_Math, Database_Services, SRP_JSON, Reactor_Services, SRP_Datetime
 | |
| Declare function   SRP_Array, Environment_Services, Logging_Services, Datetime, Select_Into, Wafer_Counter_Services
 | |
| Declare function    Lot_Services, Test_Run_Services, NCR_Services, Date_Services
 | |
| 
 | |
| Equ TAB   TO \09\
 | |
| 
 | |
| LogPath     = Environment_Services('GetApplicationRootPath') : '\LogFiles\RDS'
 | |
| LogDate     = Oconv(Date(), 'D4/')
 | |
| LogTime     = Oconv(Time(), 'MTS')
 | |
| LogFileName  = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' WAFERS_IN.csv'
 | |
| Headers      = 'Logging DTM' : @FM : 'RDS Key ID' : @FM : 'WAFERS_IN'
 | |
| objWafersLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ',', Headers, '', False$, False$)
 | |
| 
 | |
| LogPath       = Environment_Services('GetApplicationRootPath') : '\LogFiles\Report_Services'
 | |
| LogFileName   = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' CalcDailyPerformanceData.csv'
 | |
| Headers       = 'Logging DTM' : @FM : 'Service Step' : @FM : 'Service Notes'
 | |
| objReportsLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ',', Headers, '', False$, False$)
 | |
| 
 | |
| LoggingDTM  = LogDate : ' ' : LogTime   ; // Logging DTM
 | |
| 
 | |
| GoToService
 | |
| 
 | |
| Return Response or ""
 | |
| 
 | |
| ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | |
| // Service Parameter Options
 | |
| ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | |
| Options BOOLEAN     = True$, False$
 | |
| 
 | |
| ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | |
| // Services
 | |
| ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | |
| 
 | |
| Service GetMakeupInventoryReportJSON()
 | |
| 	
 | |
| 	clearselect
 | |
| 	Statement1 = 'LIST MAKEUP_WAFERS WO_NO CASS_NO CUST_NO CUST_PART_NO EPI_PART_NO PROD_ORD_NO PROD_VER_NO PS_NO RDS_NO REACT_TYPE SAP_BATCH_NO UNLOAD_DTM WAFER_SIZE WM_OUT_NO WFR_QTY EXPIRED BY WAFER_SIZE BY PS_NO'
 | |
| 	MUInv = Select_Into(Statement1, 'EDT')
 | |
| 	
 | |
| 	If Error_Services('NoError') then
 | |
| 		MUInvJSON = ''
 | |
| 		objJSON   = ''
 | |
| 		If SRP_JSON(objJSON, 'New', 'Object') then
 | |
| 			objReactArray = ''
 | |
| 			If SRP_JSON(objReactArray, 'New', 'Array') then
 | |
| 				For each Row in MUInv using @FM setting fPos
 | |
| 					objRow = ''
 | |
| 					If SRP_JSON(objRow, 'New', 'Object') then
 | |
| 						SRP_JSON(objRow, 'SetValue', 'workOrderNo', Row<0, 2>, 'number')
 | |
| 						SRP_JSON(objRow, 'SetValue', 'cassNo', Row<0, 3>, 'number')
 | |
| 						SRP_JSON(objRow, 'SetValue', 'custNo', Row<0, 4>, 'number')
 | |
| 						SRP_JSON(objRow, 'SetValue', 'custPartNo', Row<0, 5>)
 | |
| 						SRP_JSON(objRow, 'SetValue', 'epiPartNo', Row<0, 6>)
 | |
| 						SRP_JSON(objRow, 'SetValue', 'prodOrderNo', Row<0, 7>)
 | |
| 						SRP_JSON(objRow, 'SetValue', 'prodVerNo', Row<0, 8>, 'number')
 | |
| 						SRP_JSON(objRow, 'SetValue', 'prodSpecNo', Row<0, 9>, 'number')
 | |
| 						SRP_JSON(objRow, 'SetValue', 'rdsNo', Row<0, 10>, 'number')
 | |
| 						SRP_JSON(objRow, 'SetValue', 'reactType', Row<0, 11>)
 | |
| 						SRP_JSON(objRow, 'SetValue', 'sapBatchNo', Row<0, 12>)
 | |
| 						SRP_JSON(objRow, 'SetValue', 'unloadDtm', Row<0, 13>)
 | |
| 						SRP_JSON(objRow, 'SetValue', 'wfrSize', Row<0, 14>)
 | |
| 						SRP_JSON(objRow, 'SetValue', 'wmOutNo', Row<0, 15>)
 | |
| 						SRP_JSON(objRow, 'SetValue', 'wfrQty', Row<0, 16>, 'number')
 | |
| 						
 | |
| 						ReactType = Xlate('WO_MAT', Row<0, 2>:'*':Row<0, 3>, 'REACTOR_TYPE', 'X')
 | |
| 						If ReactType NE 'EPP' then
 | |
| 							LotID = Row<0, 10>
 | |
| 						end else
 | |
| 							LotID = Row<0, 2>:'*1*':Row<0, 3>
 | |
| 						end
 | |
| 						WcRec = Wafer_Counter_Services('GetLastScan', LotID)
 | |
| 						WcQty = WcRec<WAFER_COUNTER.SCAN_QTY$>
 | |
| 						WcDtm = WcRec<WAFER_COUNTER.SCAN_DTM$>
 | |
| 						
 | |
| 						SRP_JSON(objRow, 'SetValue', 'muWaferCounterQty', WcQty)
 | |
| 						SRP_JSON(objRow, 'SetValue', 'muWaferCounterDtm', WcDtm)
 | |
| 						
 | |
| 						SRP_JSON(objRow, 'SetValue', 'expired', IConv(Row<0, 17>, 'B'), 'Boolean')
 | |
| 						
 | |
| 						SRP_JSON(objReactArray, 'Add', objRow)
 | |
| 						SRP_JSON(objRow, 'Release')
 | |
| 					end
 | |
| 				Next Row
 | |
| 				SRP_JSON(objJSON, 'Set', 'MUInvReport', objReactArray)
 | |
| 				SRP_JSON(objReactArray, 'Release')
 | |
| 			end
 | |
| 			Response = SRP_JSON(objJSON, 'Stringify', 'Styled')
 | |
| 			SRP_JSON(objJSON, 'Release')
 | |
| 		end
 | |
| 		
 | |
| 	end
 | |
| 	
 | |
| end service
 | |
| 
 | |
| 
 | |
| Service GenerateEPPMetReport(DateFrom, DateTo, EpiPartNo, ExportDir)
 | |
| 	
 | |
| 	ReportData = ''
 | |
| 	ErrorMsg   = ''
 | |
| 	If ( (DateFrom NE '') and (EpiPartNo NE '') and (ExportDir NE '') ) then
 | |
| 		If DateTo EQ '' then
 | |
| 			DateTo = Date()
 | |
| 		end else
 | |
| 			If Not(Num(DateTo)) then DateTo = IConv(DateTo, 'D')
 | |
| 		end
 | |
| 		If Not(Num(DateFrom)) then DateFrom = IConv(DateFrom, 'D')
 | |
| 		// Select WM_OUT keys
 | |
| 		WMOList = ''
 | |
| 		Query   = 'SELECT WM_OUT WITH PART_NO EQ ':Quote(EpiPartNo)
 | |
| 		GoSub ClearCursors
 | |
| 		Set_Status(0)
 | |
| 		RList(Query, TARGET_ACTIVELIST$, '', '', '')
 | |
| 		If Get_Status(ErrCode) then
 | |
| 			ErrorMsg = 'Error in ':Service:' service. RList failed! Error code: ':ErrCode:'.'
 | |
| 		end
 | |
| 		If ErrorMsg EQ '' then
 | |
| 			Def              = ""
 | |
| 			Def<MCAPTION$>   = "Selecting WM_OUT records..."
 | |
| 			Def<MTYPE$>      = "GC"
 | |
| 			Def<MEXTENT$>    = @RecCount
 | |
| 			Def<MTEXTWIDTH$> = 600
 | |
| 			MsgUp            = Msg(@WINDOW, Def) ;* Start gas guage message
 | |
| 			Counter          = 0
 | |
| 			EOF              = False$
 | |
| 			Loop
 | |
| 				Counter += 1
 | |
| 				Running     = Msg(@WINDOW, MsgUp, Counter, MSGINSTUPDATE$) ;* Update message
 | |
| 				ReadNext WMOKey else EOF = True$
 | |
| 			Until EOF
 | |
| 				WMOList<-1> = WMOKey
 | |
| 			Repeat
 | |
| 			Msg(@WINDOW,MsgUp)
 | |
| 			
 | |
| 			// Filter on RDS {DATE_OUT}
 | |
| 			RDSList       = ''
 | |
| 			FilterWMOList = ''
 | |
| 			NumWMO        = DCount(WMOList, @FM)
 | |
| 			
 | |
| 			Def              = ""
 | |
| 			Def<MCAPTION$>   = "Filtering on dates..."
 | |
| 			Def<MTYPE$>      = "GC"
 | |
| 			Def<MEXTENT$>    = NumWMO
 | |
| 			Def<MTEXTWIDTH$> = 600
 | |
| 			MsgUp            = Msg(@WINDOW, Def) ;* Start gas guage message
 | |
| 			Counter          = 0
 | |
| 			
 | |
| 			For WMOIndex = 1 to NumWMO
 | |
| 				Running     = Msg(@WINDOW, MsgUp, WMOIndex, MSGINSTUPDATE$) ;* Update message
 | |
| 				Done        = False$
 | |
| 				WMOKey      = WMOList<WMOIndex>
 | |
| 				ThisRDSList = Xlate('WM_OUT', WMOKey, 'RDS', 'X')
 | |
| 				ThisRDSList = SRP_Array('Clean', ThisRDSList, 'TrimAndMakeUnique', @VM)
 | |
| 				For each RDSNo in ThisRDSList using @VM
 | |
| 					DateOut = Xlate('RDS', RDSNo, 'DATE_OUT', 'X')
 | |
| 					If ( (DateOut GE DateFrom) and (DateOut LE DateTo) ) then
 | |
| 						FilterWMOList<-1> = WMOKey
 | |
| 						Done              = True$
 | |
| 					end
 | |
| 				Until Done
 | |
| 				Next RDSNo
 | |
| 			Next WMOIndex
 | |
| 			Msg(@WINDOW,MsgUp)
 | |
| 			
 | |
| 			// Build the report
 | |
| 			ReportData    = ''
 | |
| 			Headers       = Database_Services('ReadDataRow', 'SYSLISTS', 'EPP_METROLOGY_HEADERS')
 | |
| 			Columns       = Xlate('EXPORTS', 'EPIPRO_METOROLGY', 'COLUMNS', 'X')
 | |
| 			Swap @FM with @VM in Headers
 | |
| 			ReportData<1> = Headers
 | |
| 			
 | |
| 			RDSFields  = Database_Services('ReadDataRow', 'DICT.RDS', '%FIELDS%')
 | |
| 			RDSColumns = RDSFields<DICT_DISPLAY$>
 | |
| 			RDSConvs   = RDSFields<DICT_GENERIC_TYPE$>
 | |
| 			NumWMO     = DCount(FilterWMOList, @FM)
 | |
| 			
 | |
| 			Def              = ""
 | |
| 			Def<MCAPTION$>   = "Building report..."
 | |
| 			Def<MTYPE$>      = "GC"
 | |
| 			Def<MEXTENT$>    = NumWMO
 | |
| 			Def<MTEXTWIDTH$> = 600
 | |
| 			MsgUp            = Msg(@WINDOW, Def) ;* Start gas guage message
 | |
| 			
 | |
| 			If NumWMO GT 0 then
 | |
| 				For each WMOKey in FilterWMOList using @FM setting fPos
 | |
| 					Running     = Msg(@WINDOW, MsgUp, fPos, MSGINSTUPDATE$) ;* Update message
 | |
| 					RowIndex    = fPos + 1
 | |
| 					ThisRDSList = Xlate('WM_OUT', WMOKey, 'RDS', 'X')
 | |
| 					Zones       = Xlate('WM_OUT', WMOKey, 'ZONE', 'X')
 | |
| 					Pockets     = Xlate('WM_OUT', WMOKey, 'POCKET', 'X')
 | |
| 					SAPBatchNo  = Xlate('WM_OUT', WMOKey, 'SAP_BATCH_NO', 'X')
 | |
| 					InCassNos   = Xlate('WM_OUT', WMOKey, 'IN_CASS_NO', 'X')
 | |
| 					WONo        = Field(WMOKey, '*', 1)
 | |
| 					PrevRDSNo   = ''
 | |
| 					For each RDSNo in ThisRDSList using @VM setting SlotNo
 | |
| 						If RDSNo NE '' then
 | |
| 							If RDSNo NE PrevRDSNo then Database_Services('ActivateRecord', 'RDS', RDSNo)
 | |
| 							ReportRow = ''
 | |
| 							For each Column in Columns using @VM setting cPos
 | |
| 								Locate Column in RDSColumns using @VM setting ConvPos then
 | |
| 									Conv = RDSConvs<0, ConvPos>
 | |
| 									Begin Case
 | |
| 										Case Column EQ 'WO'
 | |
| 											ReportRow<0, cPos> = Field(WMOKey, '*', 1)
 | |
| 										Case Column EQ 'SEQ'
 | |
| 											ReportRow<0, cPos> = RDSNo
 | |
| 										Case Column EQ 'ZONE'
 | |
| 											ReportRow<0, cPos> = Zones<0, SlotNo>
 | |
| 										Case Column EQ 'POCKET'
 | |
| 											ReportRow<0, cPos> = Pockets<0, SlotNo>
 | |
| 										Case Column EQ 'WM_OUT_KEY'
 | |
| 											ReportRow<0, cPos> = WMOKey
 | |
| 										Case Column EQ 'OUT_CASS_NO'
 | |
| 											ReportRow<0, cPos> = Field(WMOKey, '*', 3)
 | |
| 										Case Column EQ 'OUT_SLOT_NO'
 | |
| 											ReportRow<0, cPos> = SlotNo
 | |
| 										Case Column EQ 'SAP_BATCH_NO'
 | |
| 											ReportRow<0, cPos> = SAPBatchNo
 | |
| 										Case Column EQ 'LOT_NUM'
 | |
| 											ReportRow<0, cPos> = Xlate('WO_MAT', WONo:'*':InCassNos<0, SlotNo>, 'LOT_NO', 'X')
 | |
| 										Case Otherwise$
 | |
| 											If Conv EQ '' then
 | |
| 												ReportRow<0, cPos> = Calculate(Column)
 | |
| 											end else
 | |
| 												ReportRow<0, cPos> = OConv(Calculate(Column), Conv)
 | |
| 											end
 | |
| 									End Case
 | |
| 								end
 | |
| 							Next Column
 | |
| 							PrevRDSNo      = RDSNo
 | |
| 							ReportData<-1> = ReportRow
 | |
| 						end
 | |
| 					Next RDSNo
 | |
| 					
 | |
| 				Next WMOKey
 | |
| 			end
 | |
| 			Msg(@WINDOW,MsgUp)
 | |
| 			Swap @VM with ',' in ReportData
 | |
| 			Swap @FM with CRLF$ in ReportData
 | |
| 			Set_Status(0)
 | |
| 			OSWrite ReportData on ExportDir
 | |
| 			ErrCode = ''
 | |
| 			If Get_Status(ErrCode) then
 | |
| 				ErrorMsg = 'Error in ':Service:' service. OSWrite failed! Error code: ':ErrCode:'.'
 | |
| 			end
 | |
| 		end
 | |
| 	end else
 | |
| 		ErrorMsg = 'Error in ':Service:' service. Null DateFrom or EpiPartNo passed in!'
 | |
| 	end
 | |
| 	If ErrorMsg EQ '' then
 | |
| 		Response = ReportData
 | |
| 	end else
 | |
| 		Error_Services('Add', ErrorMsg)
 | |
| 	end
 | |
| 	
 | |
| end service
 | |
| 
 | |
| 
 | |
| Service UpdateDailyMetrics(ReportDate)
 | |
| 	
 | |
| 	If ReportDate NE '' then
 | |
| 		If Not(Num(ReportDate)) then ReportDate = IConv(ReportDate, 'D')
 | |
| 		// Get daily target
 | |
| 		CurrDate     = Date()
 | |
| 		DailyTarget  = 0
 | |
| 		Query        = 'SELECT FISCAL_QTR WITH FISCAL_YR EQ 2022 AND WITH START_DT LT ':Quote(OConv(ReportDate + 1, 'D4/'))
 | |
| 		Query       := ' AND WITH END_DT GT ':Quote(OConv(ReportDate - 1, 'D4/'))
 | |
| 		RList(Query, TARGET_ACTIVELIST$, '', '', '')
 | |
| 		If Not(Get_Status(ErrCode)) then
 | |
| 			ReadNext FiscalQtrKey then
 | |
| 				WorkingDays = Xlate('FISCAL_QTR', FiscalQtrKey, 'PLAN_WORKING_DAYS', 'X')
 | |
| 				Targets     = Xlate('FISCAL_QTR', FiscalQtrKey, 'THRU_TARGET', 'X')
 | |
| 				Qtys        = Xlate('FISCAL_QTR', FiscalQtrKey, 'THRU_QTY', 'X')
 | |
| 				Locate 'Yield_Outs' in Targets using @VM setting vPos then
 | |
| 					QtrTarget   = Qtys<0, vPos>
 | |
| 					DailyTarget = QtrTarget / WorkingDays
 | |
| 					DailyTarget = OConv(IConv(DailyTarget, 'MD0'), 'MD0')
 | |
| 				end
 | |
| 			end
 | |
| 		end
 | |
| 		
 | |
| 		GoSub ClearCursors
 | |
| 		
 | |
| 		// Calculate the metrics for the ReportDate
 | |
| 		OPEN 'DICT.RDS' TO @DICT then
 | |
| 			OPEN 'RDS' TO RDSTable then
 | |
| 				
 | |
| 				TotalThickness24 = 0
 | |
| 				TotalYield24     = 0
 | |
| 				
 | |
| 				
 | |
| 				Dates            = ''
 | |
| 				CurrTime         = Time()
 | |
| 				If CurrTime LT 3600 then
 | |
| 					// 3600 is 1:00 am -> update yesterday's metrics as well
 | |
| 					Dates<-1> = ReportDate - 1
 | |
| 				end
 | |
| 				Dates<-1> = ReportDate
 | |
| 				For each Date in Dates using @FM
 | |
| 					
 | |
| 					TotalThickness  = 0
 | |
| 					WafersOutTotal  = 0
 | |
| 					YieldTotal      = 0
 | |
| 					ScrapTotal      = 0
 | |
| 					ProdTestTotal   = 0
 | |
| 					ProjectedYield  = 0
 | |
| 					YieldPercent    = '0.00'
 | |
| 					ThickWaferRatio = 0
 | |
| 					
 | |
| 					SearchString   = 'DATE_OUT':@VM:OConv(Date, 'D4/')
 | |
| 					RDSKeys        = ''
 | |
| 					Option         = ''
 | |
| 					Flag           = ''
 | |
| 					Set_Status(0)
 | |
| 					Btree.Extract(SearchString, 'RDS', @DICT, RDSKeys, Option, Flag)
 | |
| 					IF Not(Get_Status(errCode)) then
 | |
| 						IF RDSKeys NE '' THEN
 | |
| 							RDSCnt  = COUNT(RDSKeys,@VM) + (RDSKeys NE '')
 | |
| 							LOOP
 | |
| 								@ID = RDSKeys[1,@VM]
 | |
| 								RDSKeys[1,COL2()] = ''
 | |
| 								READ @RECORD FROM RDSTable, @ID THEN
 | |
| 									ReactorsOut     = {WAFERS_IN}
 | |
| 									If Not(Num(ReactorsOut)) then
 | |
| 										// Log the WafersIn value
 | |
| 										LogData     = ''
 | |
| 										LogData<1>  = LoggingDTM
 | |
| 										LogData<2>  = @ID
 | |
| 										LogData<3>  = ReactorsOut
 | |
| 										Logging_Services('AppendLog', objWafersLog, LogData, @RM, @FM)
 | |
| 										ReactorsOut = ReactorsOut<1, 1, 1>
 | |
| 									end
 | |
| 									
 | |
| 									CustScrap       = {CUST_TOT_REJ}
 | |
| 									IFXEpiScrap     = {LSL_TOT_REJ}
 | |
| 									TestKeys        = XLATE('RDS_LAYER', @RECORD<RDS_RDS_LAYER_KEYS$>, 3, 'X')
 | |
| 									TWProd          = obj_RDS_Test('ProdTestCount',TestKeys)
 | |
| 									Reactor         = @RECORD<RDS_REACTOR$>
 | |
| 									ReactorType     = XLATE('REACTOR', Reactor, REACTOR_REACT_TYPE$, 'X')
 | |
| 									Scrap           = CustScrap + IFXEpiScrap
 | |
| 									Yield           = ReactorsOut - Scrap - TWProd
 | |
| 									WafersOutTotal += ReactorsOut
 | |
| 									YieldTotal     += Yield
 | |
| 									ScrapTotal     += Scrap
 | |
| 									ProdTestTotal  += TWProd
 | |
| 									ThickTarget     = OConv({THICK_TARGET_TOT}, 'MD3')
 | |
| 									TotalThickness += (ReactorsOut * ThickTarget)
 | |
| 								end
 | |
| 							UNTIL RDSKeys = ''
 | |
| 							REPEAT
 | |
| 							TotalThickness = TotalThickness[1, 'F.']
 | |
| 						end
 | |
| 					end
 | |
| 					
 | |
| 					If Date EQ CurrDate then
 | |
| 						// Calculate projected yield and projected thickness
 | |
| 						Date             = Date()
 | |
| 						CurrTime         = Time()
 | |
| 						SearchString     = 'DATE_OUT':@VM:OConv((Date - 1), 'D4/'):@FM:'TIME_OUT':@VM:'>':CurrTime
 | |
| 						YesterdayRDSKeys = ''
 | |
| 						Option           = ''
 | |
| 						Flag             = ''
 | |
| 						Set_Status(0)
 | |
| 						Btree.Extract(SearchString, 'RDS', @DICT, YesterdayRDSKeys, Option, Flag)
 | |
| 						If Not(Get_Status(errCode)) then
 | |
| 							SearchString = 'DATE_OUT':@VM:Date
 | |
| 							TodayRDSKeys = ''
 | |
| 							Option       = ''
 | |
| 							Flag         = ''
 | |
| 							Set_Status(0)
 | |
| 							Btree.Extract(SearchString, 'RDS', @DICT, TodayRDSKeys, Option, Flag)
 | |
| 							If Not(Get_Status(errCode)) then
 | |
| 								TotalRDSKeys     = SRP_Array('Join', YesterdayRDSKeys, TodayRDSKeys, 'OR', @VM)
 | |
| 								For each RDS in TotalRDSKeys using @VM
 | |
| 									Database_Services('ActivateRecord', 'RDS', RDS)
 | |
| 									ReactorsOut       = {WAFERS_IN}
 | |
| 									If Not(Num(ReactorsOut)) then
 | |
| 										// Log the WafersIn value
 | |
| 										LogData     = ''
 | |
| 										LogData<1>  = LoggingDTM
 | |
| 										LogData<2>  = RDS
 | |
| 										LogData<3>  = ReactorsOut
 | |
| 										Logging_Services('AppendLog', objWafersLog, LogData, @RM, @FM)
 | |
| 										ReactorsOut = ReactorsOut<1, 1, 1>
 | |
| 									end
 | |
| 									CustScrap         = {CUST_TOT_REJ}
 | |
| 									IFXEpiScrap       = {LSL_TOT_REJ}
 | |
| 									TestKeys          = XLATE('RDS_LAYER', @RECORD<RDS_RDS_LAYER_KEYS$>, 3, 'X')
 | |
| 									TWProd            = obj_RDS_Test('ProdTestCount',TestKeys)
 | |
| 									Reactor           = @RECORD<RDS_REACTOR$>
 | |
| 									ReactorType       = XLATE('REACTOR', Reactor, REACTOR_REACT_TYPE$, 'X')
 | |
| 									Scrap             = CustScrap + IFXEpiScrap
 | |
| 									Yield             = ReactorsOut - Scrap - TWProd
 | |
| 									TotalYield24     += Yield
 | |
| 									TargetThick       = OConv({THICK_TARGET_TOT}, 'MD3')
 | |
| 									TotalThickness24 += TargetThick * ReactorsOut
 | |
| 								Next RDS
 | |
| 								TotalThickness24 = TotalThickness24[1, 'F.']
 | |
| 							end
 | |
| 						end
 | |
| 					end
 | |
| 					
 | |
| 					If WafersOutTotal GT 0 then
 | |
| 						ThickWaferRatio = TotalThickness / WafersOutTotal
 | |
| 						// Round to one decimal 
 | |
| 						ThickWaferRatio = OConv(IConv(ThickWaferRatio, 'MD1'), 'MD1')
 | |
| 						// Round to two decimals
 | |
| 						YieldPercent    = (YieldTotal / WafersOutTotal) * 100
 | |
| 						YieldPercent    = OConv(IConv(YieldPercent, 'MD2'), 'MD2')
 | |
| 					end
 | |
| 					
 | |
| 					If WafersOutTotal   EQ 0 then WafersOutTotal   = ''
 | |
| 					If YieldTotal       EQ 0 then YieldTotal       = ''
 | |
| 					If TotalYield24     EQ 0 then TotalYield24     = ''
 | |
| 					If TotalThickness   EQ 0 then TotalThickness   = ''
 | |
| 					If TotalThickness24 EQ 0 then TotalThickness24 = ''
 | |
| 					
 | |
| 					MetricsRec                                       = ''
 | |
| 					MetricsRec<DAILY_METRICS.WAFERS_OUT$>            = WafersOutTotal
 | |
| 					MetricsRec<DAILY_METRICS.YIELD$>                 = YieldTotal
 | |
| 					MetricsRec<DAILY_METRICS.PROJECTED$>             = TotalYield24
 | |
| 					MetricsRec<DAILY_METRICS.SCRAP$>                 = ScrapTotal
 | |
| 					MetricsRec<DAILY_METRICS.PROD_TEST$>             = ProdTestTotal
 | |
| 					MetricsRec<DAILY_METRICS.TARGET$>                = DailyTarget
 | |
| 					MetricsRec<DAILY_METRICS.TOTAL_THICKNESS$>       = TotalThickness
 | |
| 					MetricsRec<DAILY_METRICS.PROJECTED_THICKNESS$>   = TotalThickness24
 | |
| 					MetricsRec<DAILY_METRICS.THICKNESS_WAFER_RATIO$> = ThickWaferRatio
 | |
| 					MetricsRec<DAILY_METRICS.YIELD_PERCENT$>         = YieldPercent
 | |
| 					Database_Services('WriteDataRow', 'DAILY_METRICS', Date, MetricsRec)
 | |
| 					
 | |
| 				Next Date
 | |
| 			end
 | |
| 		end
 | |
| 	end
 | |
| 	
 | |
| end service
 | |
| 
 | |
| 
 | |
| Service GetMetricsJSON(Date)
 | |
| 	
 | |
| 	// Get a week's worth of metrics and return them as JSON
 | |
| 	StartDate    = Date() - 6
 | |
| 	EndDate      = Date()
 | |
| 	
 | |
| 	JSON           = ''
 | |
| 	hMetricsObj    = ''
 | |
| 	hMetricsArray  = ''
 | |
| 	hDayMetricsObj = ''
 | |
| 	hStatusObj     = ''
 | |
| 	If SRP_JSON(hMetricsObj, 'NEW', 'OBJECT') then
 | |
| 		If SRP_JSON(hMetricsArray, 'NEW', 'ARRAY') then
 | |
| 			DateIndex = 1
 | |
| 			For Date = StartDate to EndDate
 | |
| 				MetricsRec = Database_Services('ReadDataRow', 'DAILY_METRICS', Date)
 | |
| 				// Create new date object
 | |
| 				SRP_JSON(hDayMetricsObj, 'NEW', 'OBJECT')
 | |
| 				// Add values
 | |
| 				SRP_JSON(hDayMetricsObj, 'SETVALUE', 'date', OConv(Date, 'D4/'))
 | |
| 				SRP_JSON(hDayMetricsObj, 'SETVALUE', 'target', MetricsRec<DAILY_METRICS.TARGET$>)
 | |
| 				SRP_JSON(hDayMetricsObj, 'SETVALUE', 'reactorOut', MetricsRec<DAILY_METRICS.WAFERS_OUT$>)
 | |
| 				SRP_JSON(hDayMetricsObj, 'SETVALUE', 'yieldOut', MetricsRec<DAILY_METRICS.YIELD$>)
 | |
| 				SRP_JSON(hDayMetricsObj, 'SETVALUE', 'projected', MetricsRec<DAILY_METRICS.PROJECTED$>)
 | |
| 				SRP_JSON(hDayMetricsObj, 'SETVALUE', 'yieldPercent', MetricsRec<DAILY_METRICS.YIELD_PERCENT$>, 'String')
 | |
| 				// Add object to metrics array
 | |
| 				SRP_JSON(hMetricsArray, 'ADD', hDayMetricsObj)
 | |
| 				SRP_JSON(hDayMetricsObj, 'RELEASE')
 | |
| 			Next Date
 | |
| 		end
 | |
| 		SRP_JSON(hMetricsObj, 'SET', 'dailyMetrics', hMetricsArray)
 | |
| 		JSON    = SRP_JSON(hMetricsObj, 'STRINGIFY', 'FAST')
 | |
| 		SRP_JSON(hMetricsArray, 'RELEASE')
 | |
| 		SRP_JSON(hStatusObj, 'RELEASE')
 | |
| 	end else
 | |
| 		Error_Services('Add', 'Error creating the metrics JSON object.')
 | |
| 	end
 | |
| 	
 | |
| 	Response = JSON
 | |
| 	
 | |
| end service
 | |
| 
 | |
| 
 | |
| Service GetThickMetricsJSON(Date)
 | |
| 	
 | |
| 	// Get a week's worth of metrics and return them as JSON
 | |
| 	StartDate    = Date() - 6
 | |
| 	EndDate      = Date()
 | |
| 	
 | |
| 	JSON           = ''
 | |
| 	hMetricsObj    = ''
 | |
| 	hMetricsArray  = ''
 | |
| 	hDayMetricsObj = ''
 | |
| 	If SRP_JSON(hMetricsObj, 'NEW', 'OBJECT') then
 | |
| 		If SRP_JSON(hMetricsArray, 'NEW', 'ARRAY') then
 | |
| 			DateIndex = 1
 | |
| 			For Date = StartDate to EndDate
 | |
| 				MetricsRec = Database_Services('ReadDataRow', 'DAILY_METRICS', Date)
 | |
| 				// Create new date object
 | |
| 				SRP_JSON(hDayMetricsObj, 'NEW', 'OBJECT')
 | |
| 				// Add values
 | |
| 				SRP_JSON(hDayMetricsObj, 'SETVALUE', 'date', OConv(Date, 'D4/'))
 | |
| 				SRP_JSON(hDayMetricsObj, 'SETVALUE', 'thickness', MetricsRec<DAILY_METRICS.TOTAL_THICKNESS$>)
 | |
| 				SRP_JSON(hDayMetricsObj, 'SETVALUE', 'projectedThickness', MetricsRec<DAILY_METRICS.PROJECTED_THICKNESS$>)
 | |
| 				SRP_JSON(hDayMetricsObj, 'SETVALUE', 'thicknessWaferRatio', MetricsRec<DAILY_METRICS.THICKNESS_WAFER_RATIO$>)
 | |
| 				// Add object to metrics array
 | |
| 				SRP_JSON(hMetricsArray, 'ADD', hDayMetricsObj)
 | |
| 				SRP_JSON(hDayMetricsObj, 'RELEASE')
 | |
| 			Next Date
 | |
| 		end
 | |
| 		SRP_JSON(hMetricsObj, 'SET', 'dailyMetrics', hMetricsArray)
 | |
| 		JSON    = SRP_JSON(hMetricsObj, 'STRINGIFY', 'FAST')
 | |
| 		SRP_JSON(hMetricsArray, 'RELEASE')
 | |
| 		SRP_JSON(hStatusObj, 'RELEASE')
 | |
| 	end else
 | |
| 		Error_Services('Add', 'Error creating the metrics JSON object.')
 | |
| 	end
 | |
| 	
 | |
| 	Response = JSON
 | |
| 	
 | |
| end service
 | |
| 
 | |
| 
 | |
| Service GetMaterialTrackJSON()
 | |
| 	
 | |
| 	ErrCode = ''
 | |
| 	KeyList = ''
 | |
| 	Query   = 'SELECT MATERIAL_REPORT BY REACT_NO BY START_DTM'
 | |
| 	RList(Query, TARGET_ACTIVELIST$, '', '', '')
 | |
| 	If Not(Get_Status(ErrCode)) then
 | |
| 		EOF = False$
 | |
| 		Loop
 | |
| 			ReadNext KeyId else EOF = True$
 | |
| 		Until EOF
 | |
| 			KeyList<-1> = KeyId
 | |
| 		Repeat
 | |
| 		If KeyList NE '' then
 | |
| 			MatRepJSON = ''
 | |
| 			If SRP_JSON(objJSON, 'New', 'Object') then
 | |
| 				If SRP_JSON(objReactArray, 'New', 'Array') then
 | |
| 					For each KeyId in KeyList using @FM setting fPos
 | |
| 						Row          = Database_Services('ReadDataRow', 'MATERIAL_REPORT', KeyId)
 | |
| 						If Error_Services('NoError') then
 | |
| 							KitRunOrder  = Row<MATERIAL_REPORT.KIT_RO$>
 | |
| 							PTIRunOrder  = Row<MATERIAL_REPORT.PTI_RO$>
 | |
| 							LoadRunOrder = Row<MATERIAL_REPORT.LOAD_RO$>
 | |
| 							If KitRunOrder NE '' or PTIRunOrder NE '' or LoadRunOrder NE '' then
 | |
| 								If SRP_JSON(objRow, 'New', 'Object') then
 | |
| 									SRP_JSON(objRow, 'SetValue', 'KeyId', KeyId)
 | |
| 									SRP_JSON(objRow, 'SetValue', 'ReactorNo', Row<MATERIAL_REPORT.REACT_NO$>)
 | |
| 									SRP_JSON(objRow, 'SetValue', 'ReactorType', Row<MATERIAL_REPORT.REACT_TYPE$>)
 | |
| 									SRP_JSON(objRow, 'SetValue', 'WorkOrderNo', Row<MATERIAL_REPORT.WO_NO$>)
 | |
| 									SRP_JSON(objRow, 'SetValue', 'SapProdNo', Row<MATERIAL_REPORT.PROD_ORD_NO$>)
 | |
| 									SRP_JSON(objRow, 'SetValue', 'SubPartNo', Row<MATERIAL_REPORT.SUB_PART_NO$>)
 | |
| 									SRP_JSON(objRow, 'SetValue', 'EpiPartNo', Row<MATERIAL_REPORT.EPI_PART_NO$>)
 | |
| 									WOQty        = Row<MATERIAL_REPORT.WO_QTY$>
 | |
| 									Swap ',' with '' in WOQty
 | |
| 									SRP_JSON(objRow, 'SetValue', 'WoQty', WOQty)
 | |
| 									RxQty        =  Row<MATERIAL_REPORT.WO_RX_QTY$>
 | |
| 									Swap ',' with '' in RxQty
 | |
| 									SRP_JSON(objRow, 'SetValue', 'RxQty', RxQty)
 | |
| 									UnRelQty     = Row<MATERIAL_REPORT.WO_UNREL_QTY$>
 | |
| 									Swap ',' with '' in UnRelQty
 | |
| 									SRP_JSON(objRow, 'SetValue', 'UnRelQty', UnRelQty)
 | |
| 									SRP_JSON(objRow, 'SetValue', 'KitLoc', Row<MATERIAL_REPORT.KIT_LOCATION$>)
 | |
| 									KitQty       = Row<MATERIAL_REPORT.KIT_QTY$>
 | |
| 									Swap ',' with '' in KitQty
 | |
| 									SRP_JSON(objRow, 'SetValue', 'KitQty', KitQty)
 | |
| 									SRP_JSON(objRow, 'SetValue', 'CassDelta', Row<MATERIAL_REPORT.CASS_DELTA$>)
 | |
| 									Swap ',' with ', ' in KitRunOrder
 | |
| 									SRP_JSON(objRow, 'SetValue', 'KitRunOrder', KitRunOrder)
 | |
| 									SRP_JSON(objRow, 'SetValue', 'KitDemand', Row<MATERIAL_REPORT.KIT_DEMAND$>)
 | |
| 									Swap ',' with ', ' in PTIRunOrder
 | |
| 									SRP_JSON(objRow, 'SetValue', 'PtiRunOrder', PTIRunOrder)
 | |
| 									Swap ',' with ', ' in LoadRunOrder
 | |
| 									SRP_JSON(objRow, 'SetValue', 'LoadRunOrder', LoadRunOrder)
 | |
| 									SRP_JSON(objRow, 'SetValue', 'Comments', Row<MATERIAL_REPORT.COMMENTS$>)
 | |
| 									SRP_JSON(objReactArray, 'Add', objRow)
 | |
| 									SRP_JSON(objRow, 'Release')
 | |
| 								end
 | |
| 							end							
 | |
| 						end
 | |
| 					Next KeyId
 | |
| 					SRP_JSON(objJSON, 'Set', 'MaterialReport', objReactArray)
 | |
| 					SRP_JSON(objReactArray, 'Release')
 | |
| 				end
 | |
| 				Response = SRP_JSON(objJSON, 'Stringify', 'Styled')
 | |
| 				SRP_JSON(objJSON, 'Release')
 | |
| 			end  		
 | |
| 		end else
 | |
| 			Error_Services('Add', 'Error in ':Service:' service. No rows returned.')
 | |
| 		end		
 | |
| 	end else
 | |
| 		Error_Services('Add', 'Error in ':Service:' service. Error calling RList. Error message: ':ErrCode)
 | |
| 	end
 | |
| 	
 | |
| end service
 | |
| 
 | |
| 
 | |
| Service CalcDailyPerformanceData(DateOut)
 | |
| 	
 | |
| 	hSysLists  = Database_Services('GetTableHandle', 'SYSLISTS')
 | |
| 	Lock hSysLists, ServiceKeyID then
 | |
| 		LogData = ''
 | |
| 		LogData<1> = LoggingDtm
 | |
| 		LogData<2> = '1'
 | |
| 		LogData<3> = 'Begin service.'
 | |
| 		Logging_Services('AppendLog', objReportsLog, LogData, @RM, @FM)
 | |
| 		
 | |
| 		Response   = ''
 | |
| 		CurrDate   = Date()
 | |
| 		CurrDTM    = Datetime()
 | |
| 		ReportDate = IConv(DateOut, 'D')
 | |
| 		ReportData = ''
 | |
| 		
 | |
| 		// Clear out previous daily_performance metrics
 | |
| 		table_name = "DAILY_PERFORMANCE"
 | |
| 		flag       = ""
 | |
| 		done       = False$
 | |
| 		CursorVar  = ""
 | |
| 		
 | |
| 		For counter = 0 To 8
 | |
| 			ClearSelect counter
 | |
| 		Next counter
 | |
| 		
 | |
| 		sort_list     = "DATE_OUT"
 | |
| 		Reduce_Script = "WITH {DATE_OUT} EQ '":OConv(ReportDate, 'D4/'):"'"
 | |
| 		mode          = NEXT_CUR$
 | |
| 		DeleteKeyList = ''
 | |
| 		LogData = ''
 | |
| 		LogData<1>    = LoggingDtm
 | |
| 		LogData<2> = '2'
 | |
| 		LogData<3> = 'Calling Reduce with query "':Reduce_Script:'" using next available cursor.'
 | |
| 		Logging_Services('AppendLog', objReportsLog, LogData, @RM, @FM)
 | |
| 		
 | |
| 		Reduce(reduce_script, sort_list, mode, table_name, Cursorvar, flag)
 | |
| 		If flag then
 | |
| 			Select table_name By sort_list Using Cursorvar then
 | |
| 				Open table_name To file_var then
 | |
| 					Loop
 | |
| 						ReadNext KeyID Using Cursorvar By AT Else done = TRUE$
 | |
| 					Until done
 | |
| 						DeleteKeyList<-1> = KeyID
 | |
| 					Repeat
 | |
| 				End
 | |
| 			end
 | |
| 		End
 | |
| 		LogData = ''
 | |
| 		LogData<1> = LoggingDtm
 | |
| 		LogData<2> = '3'
 | |
| 		LogData<3> = 'Deleting selected records.'
 | |
| 		Logging_Services('AppendLog', objReportsLog, LogData, @RM, @FM)
 | |
| 		
 | |
| 		If DeleteKeyList NE '' then
 | |
| 			For each KeyID in DeleteKeyList using @FM
 | |
| 				Database_Services('DeleteDataRow', 'DAILY_PERFORMANCE', KeyID, True$, False$)
 | |
| 			Next KeyID
 | |
| 		end
 | |
| 		
 | |
| 		// Begin by building DAILY_PERFORMANCE data from RDS table. We will need to supplement this below
 | |
| 		// for work orders / parts that do not have any cassettes unloaded yet.
 | |
| 		Query      = 'SELECT RDS WITH DATE_OUT EQ ':Quote(OConv(ReportDate, 'D4/')): ' BY REACTOR'
 | |
| 		EOF        = False$
 | |
| 		ErrCode    = ''
 | |
| 		ReportData = ''
 | |
| 		RawData    = ''
 | |
| 		
 | |
| 		// Clear cursors for good measure
 | |
| 		For counter = 0 To 8
 | |
| 			ClearSelect counter
 | |
| 		Next counter
 | |
| 		LogData = ''
 | |
| 		LogData<1> = LoggingDtm
 | |
| 		LogData<2> = '4'
 | |
| 		LogData<3> = 'Selecting RDS records using query "':Query:'".'
 | |
| 		Logging_Services('AppendLog', objReportsLog, LogData, @RM, @FM)
 | |
| 		
 | |
| 		RList(Query, TARGET_ACTIVELIST$, '', '', '')
 | |
| 		RowIndex   = 0
 | |
| 		If Not(Get_Status(ErrCode)) then
 | |
| 			Loop
 | |
| 				ReadNext KeyID else EOF = True$
 | |
| 			Until EOF
 | |
| 				RowIndex += 1
 | |
| 				Database_Services('ActivateRecord', 'RDS', KeyID)
 | |
| 				If Error_Services('NoError') then
 | |
| 					Reactor                                   = {REACTOR}
 | |
| 					PSN                                       = {PROD_SPEC_ID}
 | |
| 					DateOut                                   = {DATE_OUT}
 | |
| 					PartNo                                    = {PART_NUM}
 | |
| 					WafersOut                                 = {WAFERS_IN}
 | |
| 					DtmIn                                     = {DTM_IN}
 | |
| 					DtmOut                                    = {DTM_OUT}
 | |
| 					ReportKey                                 = DateOut:'*':Reactor:'*':PSN:'*':PartNo
 | |
| 					ReportRow                                 = Database_Services('ReadDataRow', 'DAILY_PERFORMANCE', ReportKey)
 | |
| 					RepWafersOut                              = ReportRow<DAILY_PERFORMANCE.WAFERS_OUT$>
 | |
| 					RepWafersOut                             += WafersOut
 | |
| 					ReportRow<DAILY_PERFORMANCE.WAFERS_OUT$>  = RepWafersOut
 | |
| 					Database_Services('WriteDataRow', 'DAILY_PERFORMANCE', ReportKey, ReportRow)
 | |
| 				end
 | |
| 			Repeat
 | |
| 		end
 | |
| 		
 | |
| 		Reactors = Reactor_Services('GetReactorNumbers')
 | |
| 		RowIndex = 0
 | |
| 		For each ReactorNo in Reactors using @FM setting RIndex
 | |
| 			ReactorAssign = Xlate('REACTOR', ReactorNo, 'REACT_ASSIGNMENT', 'X')
 | |
| 			// Only report reactors that are not out of service.
 | |
| 			If ReactorAssign NE 'O' then
 | |
| 				KeyList          = ''
 | |
| 				ReportRow        = ''
 | |
| 				ReportRow<0, 1>  = ReactorNo
 | |
| 				
 | |
| 				// Supplement DAILY_PERFORMANCE data for work orders / parts that do not have any cassettes unloaded yet.
 | |
| 				// Get the scheduled PSN, PartNo, and ReactType
 | |
| 				SchedWONos             = ''
 | |
| 				SchedPSNs              = ''
 | |
| 				SchedEpiParts          = ''
 | |
| 				SchedDetKeyIDs         = ''
 | |
| 				// The below EpiPro reactors are scheduled via a "sister" reactor (e.g. 44 for 46)
 | |
| 				If ( (ReactorNo EQ 42) or (ReactorNo EQ 46) or (ReactorNo EQ 50) or (ReactorNo EQ 54) ) then
 | |
| 					QueryReactorNo = ReactorNo - 2
 | |
| 				end else
 | |
| 					QueryReactorNo = ReactorNo
 | |
| 				end
 | |
| 				Query = "SELECT SCHED_DET_NG WITH REACT_NO EQ ":QueryReactorNo:" AND WITH BLOCK_OUT NE 1 AND WITH START_DTM LT '":OConv(ReportDate + 1, 'DT2/^H'):"' AND WITH STOP_DTM GT '":OConv(ReportDate, 'DT2/^H'):"'"
 | |
| 				LogData = ''
 | |
| 				LogData<1> = LoggingDtm
 | |
| 				LogData<2> = '5.':RIndex:'.1'
 | |
| 				LogData<3> = 'Selecting SCHED_DET_NG records for reactor ':ReactorNo:' using query "':Query:'".'
 | |
| 				Logging_Services('AppendLog', objReportsLog, LogData, @RM, @FM)
 | |
| 				
 | |
| 				// Clear cursors for good measure.
 | |
| 				For counter = 0 To 8
 | |
| 					ClearSelect counter
 | |
| 				Next counter
 | |
| 				
 | |
| 				RList(Query, TARGET_ACTIVELIST$, '', '', '')
 | |
| 				If Not(Get_Status(ErrCode)) then
 | |
| 					EOF = False$
 | |
| 					Loop
 | |
| 						ReadNext SchedKeyID else EOF = True$
 | |
| 					Until EOF
 | |
| 						SchedDetKeyIDs<0, -1> = SchedKeyID
 | |
| 					Repeat
 | |
| 				end
 | |
| 				LogData = ''
 | |
| 				LogData<1> = LoggingDtm
 | |
| 				LogData<2> = '5.':RIndex:'.2'
 | |
| 				LogData<3> = 'Reading SCHED_DET_NG records for reactor ':ReactorNo:'.'
 | |
| 				Logging_Services('AppendLog', objReportsLog, LogData, @RM, @FM)                
 | |
| 				
 | |
| 				If SchedDetKeyIDs NE '' then
 | |
| 					If Error_Services('NoError') then
 | |
| 						HoursUp   = ''
 | |
| 						SchedKeys = ''
 | |
| 						For Each SchedDetKeyID in SchedDetKeyIDs using @VM setting vPos
 | |
| 							SchedDetRec      = Database_Services('ReadDataRow', 'SCHED_DET_NG', SchedDetKeyID)
 | |
| 							SchedWONo        = SchedDetRec<SCHED_DET_NG.WO_NO$>
 | |
| 							SchedStartDtm    = SchedDetRec<SCHED_DET_NG.START_DTM$>
 | |
| 							SchedStopDtm     = SchedDetRec<SCHED_DET_NG.STOP_DTM$>
 | |
| 							SchedStartDt     = SchedStartDTM[1, 'F.']
 | |
| 							SchedStopDt      = SchedStopDTM[1, 'F.']
 | |
| 							Begin Case
 | |
| 								Case SchedStopDt EQ ReportDate
 | |
| 									// This scheduled part is ending
 | |
| 									If SchedStopDtm GT CurrDtm then
 | |
| 										HoursUp<0, vPos> = (CurrDtm - ReportDate) * 24
 | |
| 									end else
 | |
| 										HoursUp<0, vPos> = (SchedStopDtm - ReportDate) * 24
 | |
| 									end
 | |
| 								Case SchedStartDt EQ ReportDate
 | |
| 									// This scheduled part is starting on the day of the report
 | |
| 									Begin Case
 | |
| 										Case SchedStartDtm GT CurrDtm 
 | |
| 											TempHours = 0
 | |
| 										Case ReportDate EQ CurrDate
 | |
| 											TempHours = ( ( CurrDtm - SchedStartDtm) * 24 )
 | |
| 										Case Otherwise$
 | |
| 											TempHours = ( ( (ReportDate + 1) - SchedStartDtm) * 24 )
 | |
| 									End Case
 | |
| 									If TempHours LT 0 then TempHours = 0
 | |
| 									HoursUp<0, vPos> = TempHours
 | |
| 								Case ReportDate EQ CurrDate
 | |
| 									// Part is still running. Calculate how long it has been up today.
 | |
| 									HoursUp<0, vPos> = (CurrDtm - ReportDate) * 24
 | |
| 								Case Otherwise$
 | |
| 									HoursUp<0, vPos> = 24
 | |
| 							End Case
 | |
| 							SchedWONos<0, -1>    = SchedWONo
 | |
| 							SchedPSN             = Xlate('WO_LOG', SchedWONo, 'PS_NO', 'X')
 | |
| 							SchedPSNs<0, -1>     = SchedPSN
 | |
| 							SchedEpiParts<0, -1> = Xlate('WO_LOG', SchedWONo, 'EPI_PART_NO', 'X')
 | |
| 							
 | |
| 							SchedKeys<0, -1>     = SchedDetKeyID
 | |
| 						Next SchedDetKeyID
 | |
| 					end
 | |
| 				end
 | |
| 				LogData = ''
 | |
| 				LogData<1> = LoggingDtm
 | |
| 				LogData<2> = '5.':RIndex:'.3'
 | |
| 				LogData<3> = 'Writing new DAILY_PERFORMANCE records reactor ':ReactorNo:'.'
 | |
| 				Logging_Services('AppendLog', objReportsLog, LogData, @RM, @FM)    
 | |
| 				
 | |
| 				RepEpiParts = SRP_Array('Clean', SchedEpiParts, 'TrimAndMakeUnique', @VM)
 | |
| 				If RepEpiParts NE '' then
 | |
| 					For each SchedEpiPart in RepEpiParts using @VM setting vPos
 | |
| 						If SchedEpiPart NE '' then
 | |
| 							Locate SchedEpiPart in SchedEpiParts using @VM setting sPos then
 | |
| 								SchedPSN = SchedPSNs<0, sPos>
 | |
| 							end
 | |
| 						end else
 | |
| 							SchedPSN = ''
 | |
| 						end
 | |
| 						PSN                                           = SchedPSN
 | |
| 						PartNo                                        = SchedEpiPart
 | |
| 						PerfKey                                       = DateOut:'*':ReactorNo:'*':PSN:'*':PartNo
 | |
| 						PerfRow                                       = Database_Services('ReadDataRow', 'DAILY_PERFORMANCE', PerfKey)
 | |
| 						RepWafersOut                                  = PerfRow<DAILY_PERFORMANCE.WAFERS_OUT$>
 | |
| 						If RepWafersOut EQ '' then RepWafersOut  = 0
 | |
| 						PerfRow<DAILY_PERFORMANCE.WAFERS_OUT$>        = RepWafersOut
 | |
| 						PerfRow<DAILY_PERFORMANCE.HOURS_ON_PART$>     = OConv(IConv(HoursUp<0, vPos>, 'MD2'), 'MD2')
 | |
| 						PerfRow<DAILY_PERFORMANCE.SCHED_DET_KEY_IDS$> = SchedKeys<0, vPos>
 | |
| 						Database_Services('WriteDataRow', 'DAILY_PERFORMANCE', PerfKey, PerfRow)
 | |
| 					Next SchedEpiPart
 | |
| 				end
 | |
| 				// Merge in Changeover data and build the report row from the DAILY_PERFORMANCE data generated above.
 | |
| 				
 | |
| 				table_name = "DAILY_PERFORMANCE"
 | |
| 				flag       = ""
 | |
| 				done       = False$
 | |
| 				CursorVar  = ""
 | |
| 				
 | |
| 				* Clears all cursors
 | |
| 				For counter = 0 To 8
 | |
| 					ClearSelect counter
 | |
| 				Next counter
 | |
| 				
 | |
| 				sort_list     = "DATE_OUT"
 | |
| 				Reduce_Script = "WITH {REACTOR} EQ '":ReactorNo:"' AND WITH {DATE_OUT} EQ '":OConv(ReportDate, 'D4/'):"'"
 | |
| 				mode          = NEXT_CUR$
 | |
| 				LogData = ''
 | |
| 				LogData<1> = LoggingDtm
 | |
| 				LogData<2> = '5.':RIndex:'.4'
 | |
| 				LogData<3> = 'Selecting new DAILY_PERFORMANCE records for reactor ':ReactorNo:' using query "':Reduce_Script:'" via Reduce.'
 | |
| 				Logging_Services('AppendLog', objReportsLog, LogData, @RM, @FM) 
 | |
| 				
 | |
| 				Reduce(reduce_script, sort_list, mode, table_name, Cursorvar, flag)
 | |
| 				If flag then
 | |
| 					Select table_name By sort_list Using Cursorvar then
 | |
| 						Open table_name To file_var then
 | |
| 							Loop
 | |
| 								ReadNext KeyID Using Cursorvar By AT Else done = TRUE$
 | |
| 							Until done
 | |
| 								KeyList<-1> = KeyID
 | |
| 							Repeat
 | |
| 						End
 | |
| 					end
 | |
| 				End
 | |
| 				LogData = ''
 | |
| 				LogData<1> = LoggingDtm
 | |
| 				LogData<2> = '5.':RIndex:'.5'
 | |
| 				LogData<3> = 'Updating new DAILY_PERFORMANCE records for reactor ':ReactorNo:'.'
 | |
| 				Logging_Services('AppendLog', objReportsLog, LogData, @RM, @FM)                 
 | |
| 				
 | |
| 				If KeyList NE '' then
 | |
| 					// Build the final report row with data compiled above.
 | |
| 					For each KeyID in KeyList using @FM setting fPos
 | |
| 						WafersOut           = Xlate('DAILY_PERFORMANCE', KeyID, 'WAFERS_OUT', 'X')
 | |
| 						PSN                 = Field(KeyID, '*', 3)
 | |
| 						PartNo              = Field(KeyID, '*', 4)
 | |
| 						ReactType           = Xlate('REACTOR', ReactorNo, 'REACT_TYPE', 'X')
 | |
| 						If ReactType EQ 'EPP' then ReactType = 'EPIPRO'
 | |
| 						ReportRow<0, 2, -1> = PSN
 | |
| 						ReportRow<0, 3, -1> = PartNo
 | |
| 						HoursOnPart         = Xlate('DAILY_PERFORMANCE', KeyID, 'HOURS_ON_PART', 'X')
 | |
| 						ReportRow<0, 4, -1> = OConv(IConv(HoursOnPart, 'MD2'), 'MD2')
 | |
| 						ReportRow<0, 5, -1> = WafersOut           ; // ActualOuts
 | |
| 						ReportRow<0, 6, -1> = XLATE('DAILY_PERFORMANCE', KeyID, DAILY_PERFORMANCE.SCHED_DET_KEY_IDS$, 'X')
 | |
| 						ReportRow<0, 7>     = ReactorNo
 | |
| 					Next KeyID
 | |
| 					ReportData<-1> = ReportRow
 | |
| 				end
 | |
| 			end
 | |
| 			
 | |
| 		Next ReactorNo
 | |
| 		LogData = ''
 | |
| 		LogData<1> = LoggingDtm
 | |
| 		LogData<2> = '6'
 | |
| 		LogData<3> = 'Begin building DAILY_PERFORMANCE_REPORT rows.'
 | |
| 		Logging_Services('AppendLog', objReportsLog, LogData, @RM, @FM)         
 | |
| 		
 | |
| 		ReportKeys = ''
 | |
| 		For each Row in ReportData using @FM setting fPos
 | |
| 			LogData = ''
 | |
| 			LogData<1> = LoggingDtm
 | |
| 			LogData<2> = '6.':fPos
 | |
| 			LogData<3> = 'Building DAILY_PERFORMANCE_REPORT row ':fPos:'.'
 | |
| 			Logging_Services('AppendLog', objReportsLog, LogData, @RM, @FM) 
 | |
| 			
 | |
| 			PSNs    = Row<0, 2>
 | |
| 			NumPSNs = DCount(Row<0, 2>, @SVM)
 | |
| 			If NumPSNs GT 0 then
 | |
| 				For PSNIndex = 1 to NumPSNs
 | |
| 					KeyID             = ReportDate:'*':Row<0, 1>:'*':Row<0, 2, PSNIndex>:'*':Row<0, 3, PSNIndex>
 | |
| 					ReportKeys<0, -1> = KeyID
 | |
| 					If RowExists('DAILY_PERFORMANCE_REPORT', KeyID) then
 | |
| 						Rec = Database_Services('ReadDataRow', 'DAILY_PERFORMANCE_REPORT', KeyID)
 | |
| 					end else
 | |
| 						Rec = ''
 | |
| 					end
 | |
| 					Rec<DAILY_PERFORMANCE_REPORT.HOURS_ON_PART$> = Row<0, 4, PSNIndex>
 | |
| 					Rec<DAILY_PERFORMANCE_REPORT.ACTUAL_OUT$>    = Row<0, 5, PSNIndex>
 | |
| 					ActualStartDTM                               = ''
 | |
| 					ActualStopDTM                                = ''
 | |
| 					SchedDetRec                                  = Database_Services('ReadDataRow', 'SCHED_DET_NG', Row<0, 6, PSNIndex>)
 | |
| 					SchedDetStartDTM                             = SchedDetRec<SCHED_DET_NG.START_DTM$>
 | |
| 					SchedDetStopDTM                              = SchedDetRec<SCHED_DET_NG.STOP_DTM$>
 | |
| 					If SchedDetStartDTM LT ReportDate then
 | |
| 						ActualStartDTM = ReportDate
 | |
| 					end else
 | |
| 						ActualStartDTM = SchedDetStartDTM
 | |
| 					end
 | |
| 					If SchedDetStopDTM GT ReportDate + 1 then
 | |
| 						ActualStopDTM = ReportDate + 1
 | |
| 					end else
 | |
| 						ActualStopDTM = SchedDetStopDTM
 | |
| 					end
 | |
| 					Rec<DAILY_PERFORMANCE_REPORT.START_DTM$>     = ActualStartDTM
 | |
| 					Rec<DAILY_PERFORMANCE_REPORT.STOP_DTM$>      = ActualStopDTM
 | |
| 					
 | |
| 					//Get Mode Metric here
 | |
| 					EQU PRODUCTIVE$                                      To 1
 | |
| 					EQU UNSCHED$                                         to 2
 | |
| 					EQU SCHED$                                           to 3
 | |
| 					TotalReactorData                                      = Reactor_Services('GetReactorUptimeMetricsByTimeSpan', Row<0, 7> , ActualStartDTM, ActualStopDTM)
 | |
| 					Rec<DAILY_PERFORMANCE_REPORT.TOTAL_PROD_PERCENT$>     = TotalReactorData<1, PRODUCTIVE$>
 | |
| 					Rec<DAILY_PERFORMANCE_REPORT.TOTAL_PROD_MIN$>         = TotalReactorData<2, PRODUCTIVE$>
 | |
| 					Rec<DAILY_PERFORMANCE_REPORT.TOTAL_UNSCHED_PERCENT$>  = TotalReactorData<1, UNSCHED$>
 | |
| 					Rec<DAILY_PERFORMANCE_REPORT.TOTAL_UNSCHED_MIN$>      = TotalReactorData<2, UNSCHED$>
 | |
| 					Rec<DAILY_PERFORMANCE_REPORT.TOTAL_SCHED_MIN$>        = TotalReactorData<2, SCHED$>
 | |
| 					Rec<DAILY_PERFORMANCE_REPORT.TOTAL_SCHED_PERCENT$>    = TotalReactorData<1, SCHED$>
 | |
| 					
 | |
| 					Database_Services('WriteDataRow', 'DAILY_PERFORMANCE_REPORT', KeyID, Rec)
 | |
| 				Next PSNIndex
 | |
| 			end else
 | |
| 				// Nothing ran or is scheduled on this reactor
 | |
| 				KeyID             = ReportDate:'*':Row<0, 1>:'*':Row<0, 2, PSNIndex>:'*':Row<0, 3, PSNIndex>
 | |
| 				ReportKeys<0, -1> = KeyID
 | |
| 				If RowExists('DAILY_PERFORMANCE_REPORT', KeyID) then
 | |
| 					Rec = Database_Services('ReadDataRow', 'DAILY_PERFORMANCE_REPORT', KeyID)
 | |
| 				end else
 | |
| 					Rec = ''
 | |
| 				end
 | |
| 				Rec<DAILY_PERFORMANCE_REPORT.HOURS_ON_PART$> = 0
 | |
| 				Rec<DAILY_PERFORMANCE_REPORT.ACTUAL_OUT$>    = 0
 | |
| 				Database_Services('WriteDataRow', 'DAILY_PERFORMANCE_REPORT', KeyID, Rec)
 | |
| 			end
 | |
| 		Next Row 
 | |
| 		
 | |
| 		// Clean out any rows that weren't just generated.
 | |
| 		table_name = "DAILY_PERFORMANCE_REPORT"
 | |
| 		flag      = ""
 | |
| 		done      = False$
 | |
| 		CursorVar = ""
 | |
| 		* Clears all cursors
 | |
| 		For counter = 0 To 8
 | |
| 			ClearSelect counter
 | |
| 		Next counter
 | |
| 		sort_list     = "DATE_OUT"
 | |
| 		Reduce_Script = "WITH {DATE_OUT} EQ '":OConv(ReportDate, 'D4/'):"'"
 | |
| 		mode          = NEXT_CUR$
 | |
| 		LogData = ''
 | |
| 		LogData<1> = LoggingDtm
 | |
| 		LogData<2> = '7'
 | |
| 		LogData<3> = 'Selecing DAILY_PERFORMANCE_REPORT rows to delete using query "':Reduce_Script:'" via Reduce.'
 | |
| 		Logging_Services('AppendLog', objReportsLog, LogData, @RM, @FM) 
 | |
| 		
 | |
| 		Reduce(reduce_script, sort_list, mode, table_name, Cursorvar, flag)
 | |
| 		If flag then
 | |
| 			Select table_name By sort_list Using Cursorvar then
 | |
| 				Open table_name To file_var then
 | |
| 					Loop
 | |
| 						ReadNext KeyID Using Cursorvar By AT Else done = TRUE$
 | |
| 					Until done
 | |
| 						Locate KeyID in ReportKeys using @VM setting vPos else
 | |
| 							Database_Services('DeleteDataRow', 'DAILY_PERFORMANCE_REPORT', KeyID)
 | |
| 						end
 | |
| 					Repeat
 | |
| 				End
 | |
| 			end
 | |
| 		end
 | |
| 		LogData = ''
 | |
| 		LogData<1> = LoggingDtm
 | |
| 		LogData<2> = '8'
 | |
| 		LogData<3> = 'End service.'
 | |
| 		Logging_Services('AppendLog', objReportsLog, LogData, @RM, @FM) 
 | |
| 		
 | |
| 		Unlock hSysLists, ServiceKeyID else Null
 | |
| 	end
 | |
| 	
 | |
| end service
 | |
| 
 | |
| Service GenerateOrUpdateDailyReactorUptimeData()
 | |
| 	//Generates new or updates existing Reactor uptime data for all reactors in the current day.
 | |
| 	hSysLists  = Database_Services('GetTableHandle', 'SYSLISTS')
 | |
| 	Lock hSysLists, ServiceKeyID then
 | |
| 		Today = Date()
 | |
| 		DataArray = ''
 | |
| 		//ASM Reactors
 | |
| 		ASMRecordKey = 'ASM*': Today
 | |
| 		ASMUptimeRec = Reactor_Services('GetReactorUptimeMetricsByTypeAndTimeSpan', Today, Today + 1, 'ASM')
 | |
| 		Database_Services('WriteDataRow', 'REACTOR_DAILY_UPTIME', ASMRecordKey, ASMUptimeRec, True$, False$, True$)
 | |
| 		//HTR Reactors
 | |
| 		HTRRecordKey = 'HTR*': Today
 | |
| 		HTRUptimeRec = Reactor_Services('GetReactorUptimeMetricsByTypeAndTimeSpan', Today, Today + 1, 'HTR')
 | |
| 		Database_Services('WriteDataRow', 'REACTOR_DAILY_UPTIME', HTRRecordKey, HTRUptimeRec, True$, False$, True$)
 | |
| 		//EPP Reactors
 | |
| 		EPPRecordKey = 'EPP*': Today
 | |
| 		EPPUptimeRec = Reactor_Services('GetReactorUptimeMetricsByTypeAndTimeSpan', Today, Today + 1, 'EPP')
 | |
| 		Database_Services('WriteDataRow', 'REACTOR_DAILY_UPTIME', EPPRecordKey, EPPUptimeRec, True$, False$, True$)
 | |
| 		//All Reactors
 | |
| 		ALLRecordKey = 'ALL*': Today
 | |
| 		ALLUptimeRec = Reactor_Services('GetReactorUptimeMetricsByTypeAndTimeSpan', Today, Today + 1, 'ALL')
 | |
| 		Database_Services('WriteDataRow', 'REACTOR_DAILY_UPTIME', ALLRecordKey, ALLUptimeRec, True$, False$, True$)
 | |
| 		Unlock hSysLists, ServiceKeyID else Null
 | |
| 	end
 | |
| end service
 | |
| 
 | |
| Service GetDailyReactorUptimeDataJSON(ReportStartDt, ReportEndDt)
 | |
| 	Response = ''
 | |
| 	Begin Case
 | |
| 		Case ReportStartDt EQ ''
 | |
| 			Error_Services('Add', 'Start Date was not provided.')
 | |
| 		Case ReportEndDt EQ ''
 | |
| 			Error_Services('Add', 'End Date was not provided.')
 | |
| 	End Case
 | |
| 	ReportStartDT = IConv(ReportStartDt, 'D4/H')
 | |
| 	ReportEndDt = IConv(ReportEndDt, 'D4/H')
 | |
| 	//Calculate Days to include
 | |
| 	FirstDay = SRP_Datetime('Date', ReportStartDt)
 | |
| 	LastDay = SRP_Datetime('Date', ReportEndDt) - 1
 | |
| 	DataArray = ''
 | |
| 	ASMPeriodUptimeMinutes = 0
 | |
| 	ASMPeriodAvailMinutes = 0
 | |
| 	HTRPeriodUptimeMinutes = 0
 | |
| 	HTRPeriodAvailMinutes = 0
 | |
| 	EPPPeriodUptimeMinutes = 0
 | |
| 	EPPPeriodAvailMinutes = 0
 | |
| 	AllPeriodUptimeMinutes = 0
 | |
| 	AllPeriodAvailMinutes = 0
 | |
| 	ReactorUptimeJson = ''
 | |
| 	//Create Root Object
 | |
| 	If SRP_Json(ReactorUptimeJson, 'New') then
 | |
| 		//Create an Array of days
 | |
| 		ReactorUptimeDaysJson = ''
 | |
| 		If SRP_Json(ReactorUptimeDaysJson, 'New', 'Array') then
 | |
| 			//For each day create a daily uptime object
 | |
| 			for day = FirstDay to LastDay
 | |
| 				//Single Day Object
 | |
| 				ASMUptimeKey = 'ASM*':day
 | |
| 				HTRUptimeKey = 'HTR*':day
 | |
| 				EPPUptimeKey = 'EPP*':day
 | |
| 				AllUptimeKey = 'ALL*':day
 | |
| 				ReactorUptimeDayJson = ''
 | |
| 				If SRP_Json(ReactorUptimeDayJson, 'New') then
 | |
| 					ASMUptime = 0
 | |
| 					HTRUptime = 0
 | |
| 					EPPUptime = 0
 | |
| 					AllUptime = 0
 | |
| 					If RowExists('REACTOR_DAILY_UPTIME', ASMUptimeKey) then
 | |
| 						ASMUptimeRec = Database_Services('ReadDataRow', 'REACTOR_DAILY_UPTIME', ASMUptimeKey, True$, 0)
 | |
| 						ASMUptime = ASMUptimeRec<REACTOR_DAILY_UPTIME_TOTAL_UPTIME_PERCENTAGE$>
 | |
| 						ASMUptime = SRP_Math('ROUND', ASMUptime * 100, 2)
 | |
| 						ASMUptimeMinutes = ASMUptimeRec<REACTOR_DAILY_UPTIME_TOTAL_UPTIME_MINUTES$>
 | |
| 						ASMAvailMinutes = ASMUptimeRec<REACTOR_DAILY_UPTIME_TOTAL_AVAIL_MINUTES$>
 | |
| 						ASMPeriodUptimeMinutes += ASMUptimeMinutes
 | |
| 						ASMPeriodAvailMinutes += ASMAvailMinutes
 | |
| 					end
 | |
| 					If RowExists('REACTOR_DAILY_UPTIME', HTRUptimeKey) then
 | |
| 						HTRUptimeRec = Database_Services('ReadDataRow', 'REACTOR_DAILY_UPTIME', HTRUptimeKey, True$, 0)
 | |
| 						HTRUptime = HTRUptimeRec<REACTOR_DAILY_UPTIME_TOTAL_UPTIME_PERCENTAGE$>
 | |
| 						HTRUptime = SRP_Math('ROUND', HTRUptime * 100, 2)
 | |
| 						HTRUptimeMinutes = HTRUptimeRec<REACTOR_DAILY_UPTIME_TOTAL_UPTIME_MINUTES$>
 | |
| 						HTRAvailMinutes = HTRUptimeRec<REACTOR_DAILY_UPTIME_TOTAL_AVAIL_MINUTES$>
 | |
| 						HTRPeriodUptimeMinutes += HTRUptimeMinutes
 | |
| 						HTRPeriodAvailMinutes += HTRAvailMinutes
 | |
| 					end
 | |
| 					If RowExists('REACTOR_DAILY_UPTIME', EPPUptimeKey) then
 | |
| 						EPPUptimeRec = Database_Services('ReadDataRow', 'REACTOR_DAILY_UPTIME', EPPUptimeKey, True$, 0)
 | |
| 						EPPUptime = EPPUptimeRec<REACTOR_DAILY_UPTIME_TOTAL_UPTIME_PERCENTAGE$>
 | |
| 						EPPUptime = SRP_Math('ROUND', EPPUptime * 100, 2)
 | |
| 						EPPUptimeMinutes = EPPUptimeRec<REACTOR_DAILY_UPTIME_TOTAL_UPTIME_MINUTES$>
 | |
| 						EPPAvailMinutes = EPPUptimeRec<REACTOR_DAILY_UPTIME_TOTAL_AVAIL_MINUTES$>
 | |
| 						EPPPeriodUptimeMinutes += EPPUptimeMinutes
 | |
| 						EPPPeriodAvailMinutes +=	EPPAvailMinutes
 | |
| 					end
 | |
| 					If RowExists('REACTOR_DAILY_UPTIME', AllUptimeKey) then
 | |
| 						AllUptimeRec = Database_Services('ReadDataRow', 'REACTOR_DAILY_UPTIME', AllUptimeKey, True$, 0)
 | |
| 						AllUptime = AllUptimeRec<REACTOR_DAILY_UPTIME_TOTAL_UPTIME_PERCENTAGE$>
 | |
| 						AllUptime = SRP_Math('ROUND', AllUptime * 100, 2)
 | |
| 						AllUptimeMinutes = AllUptimeRec<REACTOR_DAILY_UPTIME_TOTAL_UPTIME_MINUTES$>
 | |
| 						AllAvailMinutes = AllUptimeRec<REACTOR_DAILY_UPTIME_TOTAL_AVAIL_MINUTES$>
 | |
| 						AllPeriodUptimeMinutes += AllUptimeMinutes
 | |
| 						AllPeriodAvailMinutes += AllAvailMinutes
 | |
| 					end
 | |
| 					SRP_Json(ReactorUptimeDayJson, "SetValue", "ReportDate", Oconv(day, 'DT4/H'))
 | |
| 					SRP_Json(ReactorUptimeDayJson, "SetValue", "ASMUptime", ASMUptime)
 | |
| 					SRP_Json(ReactorUptimeDayJson, "SetValue", "ASMUptimeMinutes", ASMUptimeMinutes)
 | |
| 					SRP_Json(ReactorUptimeDayJson, "SetValue", "ASMAvailMinutes", ASMAvailMinutes)
 | |
| 					SRP_Json(ReactorUptimeDayJson, "SetValue", "HTRUptime", HTRUptime)
 | |
| 					SRP_Json(ReactorUptimeDayJson, "SetValue", "HTRUptimeMinutes", HTRUptimeMinutes)
 | |
| 					SRP_Json(ReactorUptimeDayJson, "SetValue", "HTRAvailMinutes", HTRAvailMinutes)
 | |
| 					SRP_Json(ReactorUptimeDayJson, "SetValue", "EPPUptime", EPPUptime)
 | |
| 					SRP_Json(ReactorUptimeDayJson, "SetValue", "EPPUptimeMinutes", EPPUptimeMinutes)
 | |
| 					SRP_Json(ReactorUptimeDayJson, "SetValue", "EPPAvailMinutes", EPPAvailMinutes)
 | |
| 					SRP_Json(ReactorUptimeDayJson, "SetValue", "AllUptime", AllUptime)
 | |
| 					SRP_Json(ReactorUptimeDayJson, "SetValue", "AllUptimeMinutes", ALLUptimeMinutes)
 | |
| 					SRP_Json(ReactorUptimeDayJson, "SetValue", "AllAvailMinutes", ALLAvailMinutes)
 | |
| 					SRP_Json(ReactorUptimeDaysJson, "Add", ReactorUptimeDayJson)
 | |
| 					//Release it
 | |
| 					SRP_Json(ReactorUptimeDayJson, "Release")
 | |
| 					
 | |
| 					
 | |
| 				end
 | |
| 			Next day
 | |
| 			//Add array to root object
 | |
| 			SRP_Json(ReactorUptimeJson, 'Set', 'Days', ReactorUptimeDaysJson)
 | |
| 			//Close out array
 | |
| 			SRP_Json(ReactorUptimeDaysJson, 'Release')
 | |
| 			
 | |
| 		end
 | |
| 		ReactorUptimeWTDJson = ''
 | |
| 		If SRP_Json(ReactorUptimeWTDJson, 'New') then	
 | |
| 			If ASMPeriodAvailMinutes GT 0 then
 | |
| 				ASMWTDUptimePercent = SRP_Math('ROUND', (ASMPeriodUptimeMinutes / ASMPeriodAvailMinutes) * 100, 2)
 | |
| 			end else
 | |
| 				ASMWTDUptimePercent = 0
 | |
| 			end
 | |
| 			If HTRPeriodAvailMinutes GT 0 then
 | |
| 				HTRWTDUptimePercent = SRP_Math('ROUND', (HTRPeriodUptimeMinutes / HTRPeriodAvailMinutes) * 100, 2)
 | |
| 			end else
 | |
| 				HTRWTDUptimePercent = 0
 | |
| 			end
 | |
| 			If EPPPeriodAvailMinutes GT 0 then
 | |
| 				EPPWTDUptimePercent = SRP_Math('ROUND', (EPPPeriodUptimeMinutes / EPPPeriodAvailMinutes) * 100, 2)
 | |
| 			end else
 | |
| 				EPPWTDUptimePercent = 0
 | |
| 			end
 | |
| 			If ALLPeriodAvailMinutes GT 0 then
 | |
| 				ALLWTDUptimePercent = SRP_Math('ROUND', (ALLPeriodUptimeMinutes / ALLPeriodAvailMinutes) * 100, 2)
 | |
| 			end else
 | |
| 				ALLWTDUptimePercent = 0
 | |
| 			end
 | |
| 			SRP_Json(ReactorUptimeWTDJson, "SetValue", "ASMWtdUptimeMinutes", ASMPeriodUptimeMinutes)
 | |
| 			SRP_Json(ReactorUptimeWTDJson, "SetValue", "ASMWTDAvailMinutes", ASMPeriodAvailMinutes)
 | |
| 			SRP_Json(ReactorUptimeWTDJson, "SetValue", "ASMWTDUptimePercent", ASMWTDUptimePercent)
 | |
| 			SRP_Json(ReactorUptimeWTDJson, "SetValue", "HTRWTDUptimeMinutes", HTRPeriodUptimeMinutes)
 | |
| 			SRP_Json(ReactorUptimeWTDJson, "SetValue", "HTRWTDAvailMinutes", HTRPeriodAvailMinutes)
 | |
| 			SRP_Json(ReactorUptimeWTDJson, "SetValue", "HTRWTDUptimePercent", HTRWTDUptimePercent)
 | |
| 			SRP_Json(ReactorUptimeWTDJson, "SetValue", "EPPWTDUptimeMinutes", EPPPeriodUptimeMinutes)
 | |
| 			SRP_Json(ReactorUptimeWTDJson, "SetValue", "EPPWTDAvailMinutes", EPPPeriodAvailMinutes)
 | |
| 			SRP_Json(ReactorUptimeWTDJson, "SetValue", "EPPWTDUptimePercent", EPPWTDUptimePercent)
 | |
| 			SRP_Json(ReactorUptimeWTDJson, "SetValue", "ALLWTDUptimeMinutes", ALLPeriodUptimeMinutes)
 | |
| 			SRP_Json(ReactorUptimeWTDJson, "SetValue", "ALLWTDAvailMinutes", ALLPeriodAvailMinutes)
 | |
| 			SRP_Json(ReactorUptimeWTDJson, "SetValue", "ALLWTDUptimePercent", ALLWTDUptimePercent)
 | |
| 			SRP_Json(ReactorUptimeJson, 'Set', 'WTDMetrics', ReactorUptimeWTDJson)
 | |
| 			SRP_Json(ReactorUptimeWTDJson, 'Release')
 | |
| 		end
 | |
| 		// Now get the actual JSON
 | |
| 		ResponseJson = SRP_Json(ReactorUptimeJson, "Stringify", "STYLED")
 | |
| 		
 | |
| 		// All done with the root object
 | |
| 		SRP_Json(ReactorUptimeJson, "Release")
 | |
| 		Response = ResponseJson
 | |
| 	end
 | |
| end service
 | |
| 
 | |
| Service GetDailyPerformanceDataJSON(DateOut)
 | |
| 	
 | |
| 	Response   = ''
 | |
| 	ReportDate = IConv(DateOut, 'D')
 | |
| 	ReportData = ''
 | |
| 	
 | |
| 	Query = "SELECT DAILY_PERFORMANCE_REPORT WITH DATE_OUT EQ '":DateOut:"' BY REACTOR"
 | |
| 	RList(Query, TARGET_ACTIVELIST$, '', '', '')
 | |
| 	If Not(Get_Status(ErrCode)) then
 | |
| 		EOF = False$
 | |
| 		If SRP_JSON(objJSON, 'New', 'Object') then
 | |
| 			If SRP_JSON(objReactArray, 'New', 'Array') then
 | |
| 				Loop
 | |
| 					ReadNext KeyID else EOF = True$
 | |
| 				Until EOF
 | |
| 					Database_Services('ActivateRecord', 'DAILY_PERFORMANCE_REPORT', KeyID)
 | |
| 					If SRP_JSON(objRow, 'New', 'Object') then
 | |
| 						
 | |
| 						ReactorNo    = Field(KeyID, '*', 2)
 | |
| 						SRP_JSON(objRow, 'SetValue', 'reactorNo', ReactorNo)
 | |
| 						CurrModeKeys = Xlate('REACTOR_CHILD_KEY_IDS_NG', ReactorNo, 'REACT_MODE_KEY_IDS', 'X')
 | |
| 						CurrModeKey  = CurrModeKeys<0, 1>
 | |
| 						CurrMode     = Xlate('REACT_MODE_NG', CurrModeKey, 'MODE', 'X')
 | |
| 						SRP_JSON(objRow, 'SetValue', 'reactorType', {REACTOR_TYPE})
 | |
| 						SRP_JSON(objRow, 'SetValue', 'currMode', CurrMode)
 | |
| 						SRP_JSON(objRow, 'SetValue', 'psn', Field(KeyID, '*', 3))
 | |
| 						SRP_JSON(objRow, 'SetValue', 'partNo', Field(KeyID, '*', 4))
 | |
| 						SRP_JSON(objRow, 'SetValue', 'upHours', {HOURS_ON_PART})
 | |
| 						SRP_JSON(objRow, 'SetValue', 'uptimePercent', {PERCENT_ON_PART})
 | |
| 						SRP_JSON(objRow, 'SetValue', 'minutesPerWafer', {MIN_PER_WAFER})
 | |
| 						SRP_JSON(objRow, 'SetValue', 'wafersPerDay', {WAFERS_PER_DAY})
 | |
| 						SRP_JSON(objRow, 'SetValue', 'oee', {OEE})
 | |
| 						SRP_JSON(objRow, 'SetValue', 'projOut', {PROJECTED_OUT})
 | |
| 						SRP_JSON(objRow, 'SetValue', 'oeeCalculation', {OEE_CALCULATION})
 | |
| 						SRP_JSON(objRow, 'SetValue', 'timeAdjProjOut', {TIME_ADJ_PROJECTED_OUT})
 | |
| 						SRP_JSON(objRow, 'SetValue', 'actualOut', {ACTUAL_OUT}, 'Number')
 | |
| 						SRP_JSON(objRow, 'SetValue', 'totalDelta', {TOTAL_DELTA})
 | |
| 						SRP_JSON(objRow, 'SetValue', 'totalDeltaAlt', {TOTAL_DELTA_ALT})
 | |
| 						SRP_JSON(objRow, 'SetValue', 'comments', {COMMENTS})
 | |
| 						SRP_JSON(objRow, 'SetValue', 'projOutAlt', {PROJECTED_OUT_ALT})
 | |
| 						SRP_JSON(objRow, 'SetValue', 'toolProdPecent', SRP_MATH('ROUND',Xlate('DAILY_PERFORMANCE_REPORT', @ID, DAILY_PERFORMANCE_REPORT.TOTAL_PROD_PERCENT$, 'X'), 2))
 | |
| 						SRP_JSON(objRow, 'SetValue', 'toolUnschedPecent', SRP_MATH('ROUND',Xlate('DAILY_PERFORMANCE_REPORT', @ID, DAILY_PERFORMANCE_REPORT.TOTAL_UNSCHED_PERCENT$, 'X'), 2))
 | |
| 						SRP_JSON(objRow, 'SetValue', 'toolSchedPecent', SRP_MATH('ROUND',Xlate('DAILY_PERFORMANCE_REPORT', @ID, DAILY_PERFORMANCE_REPORT.TOTAL_SCHED_PERCENT$, 'X'), 2))
 | |
| 						SRP_JSON(objRow, 'SetValue', 'toolProdMin', SRP_MATH('ROUND',Xlate('DAILY_PERFORMANCE_REPORT', @ID, DAILY_PERFORMANCE_REPORT.TOTAL_PROD_MIN$, 'X'), 2))
 | |
| 						SRP_JSON(objRow, 'SetValue', 'toolUnschedMin', SRP_MATH('ROUND',Xlate('DAILY_PERFORMANCE_REPORT', @ID, DAILY_PERFORMANCE_REPORT.TOTAL_UNSCHED_MIN$, 'X'), 2))
 | |
| 						SRP_JSON(objRow, 'SetValue', 'toolSchedMin', SRP_MATH('ROUND',Xlate('DAILY_PERFORMANCE_REPORT', @ID, DAILY_PERFORMANCE_REPORT.TOTAL_SCHED_MIN$, 'X'), 2))
 | |
| 						SRP_JSON(objReactArray, 'Add', objRow)
 | |
| 						SRP_JSON(objRow, 'Release')
 | |
| 					end
 | |
| 				Repeat
 | |
| 				SRP_JSON(objJSON, 'Set', 'performanceReport', objReactArray)
 | |
| 				SRP_JSON(objReactArray, 'Release')
 | |
| 			end
 | |
| 		end
 | |
| 		Response = SRP_JSON(objJSON, 'Stringify', 'Styled')
 | |
| 		SRP_JSON(objJSON, 'Release')
 | |
| 	end
 | |
| 	
 | |
| end service
 | |
| 
 | |
| 
 | |
| Service UpdateDailyPerformanceData(RepDate, RepJSON)
 | |
| 	
 | |
| 	If ( (RepDate NE '') and (RepJSON NE '') ) then
 | |
| 		If (SRP_JSON(objJSON, 'Parse', RepJSON) EQ '') then
 | |
| 			objArray   = SRP_JSON(objJSON, 'Get', 'performanceReport')
 | |
| 			ArrayCount = SRP_JSON(objArray, 'GetCount')
 | |
| 			For ArrayIndex = 1 to ArrayCount
 | |
| 				objRow    = SRP_JSON(objArray, 'Get', '[':ArrayIndex:']')
 | |
| 				ReactorNo = SRP_JSON(objRow, 'GetValue', 'reactorNo')
 | |
| 				PSNo      = SRP_JSON(objRow, 'GetValue', 'psn')
 | |
| 				PartNo    = SRP_JSON(objRow, 'GetValue', 'partNo')
 | |
| 				Comments  = SRP_JSON(objRow, 'GetValue', 'comments', '')
 | |
| 				RepKey = IConv(RepDate, 'D'):'*':ReactorNo:'*':PSNo:'*':PartNo
 | |
| 				RepRec = Database_Services('ReadDataRow', 'DAILY_PERFORMANCE_REPORT', RepKey)
 | |
| 				If Error_Services('NoError') then
 | |
| 					RepRec<DAILY_PERFORMANCE_REPORT.COMMENTS$> = Comments
 | |
| 					Database_Services('WriteDataRow', 'DAILY_PERFORMANCE_REPORT', RepKey, RepRec)
 | |
| 				end
 | |
| 				SRP_JSON(objRow, 'Release')
 | |
| 			Next ArrayIndex
 | |
| 			SRP_JSON(objArray, 'Release')
 | |
| 			SRP_JSON(objJSON, 'Release')
 | |
| 		end
 | |
| 	end
 | |
| 	
 | |
| end service
 | |
| 
 | |
| 
 | |
| // Calculate the last month's worth of performance data one day at a time.
 | |
| Service CalcInProcessDailyPerformanceData()
 | |
| 	
 | |
| 	ReportDate  = Database_Services('ReadDataRow', 'APP_INFO', 'PERFORMANCE_REPORT_DATE')
 | |
| 	Report_Services('CalcDailyPerformanceData', ReportDate)
 | |
| 	ReportDate  = IConv(ReportDate, 'D')
 | |
| 	ReportDate -= 1
 | |
| 	If ReportDate LT Date() - 2 then ReportDate = Date()
 | |
| 	ReportDate  = OConv(ReportDate, 'D2/')
 | |
| 	Database_Services('WriteDataRow', 'APP_INFO', 'PERFORMANCE_REPORT_DATE', ReportDate)
 | |
| 	
 | |
| end service
 | |
| 
 | |
| 
 | |
| Service GetOpenTestWaferLotWIPReportJson()
 | |
| 	
 | |
| 	ErrorMessage    = ''
 | |
| 	JSONCollection  = ''
 | |
| 	TestWaferLots   = Test_Run_Services('GetTestWaferLots', True$)
 | |
| 	hJSONCollection = ''
 | |
| 	If SRP_JSON(hJSONCollection, 'New', 'Object') then
 | |
| 		hTWLotArray = ''
 | |
| 		If SRP_JSON(hTWLotArray, 'New', 'Array') then
 | |
| 			Abort = False$
 | |
| 			for each TestWaferLotId in TestWaferLots using @VM
 | |
| 				ThisLotJson = Lot_Services('ConvertLotRecordToJson', TestWaferLotId, '', '', False$)
 | |
| 				If Error_Services('NoError') then
 | |
| 					hTWLot = ''
 | |
| 					If (SRP_JSON(hTWLot, 'Parse', ThisLotJson) EQ '') then
 | |
| 						SRP_JSON(hTWLotArray, 'Add', hTWLot)
 | |
| 						SRP_JSON(hTWLot, 'Release')
 | |
| 					end
 | |
| 				end else
 | |
| 					Abort   = True$
 | |
| 				end
 | |
| 			Until Abort
 | |
| 			Next TestWaferLotId
 | |
| 			If Abort EQ False$ then
 | |
| 				SRP_JSON(hJSONCollection, 'Set', 'Lots', hTWLotArray)
 | |
| 			end
 | |
| 			SRP_JSON(hTWLotArray, 'Release')
 | |
| 		end else
 | |
| 			ErrorMessage = 'Error creating test wafer Json array.'
 | |
| 		end
 | |
| 		JSONCollection = SRP_JSON(hJSONCollection, 'Stringify', 'Styled')
 | |
| 		SRP_JSON(hJSONCollection, 'Release')
 | |
| 	end else
 | |
| 		ErrorMessage = 'Error creating test wafer Json Collection'
 | |
| 	end
 | |
| 	If ErrorMessage NE '' then
 | |
| 		Error_Services('Add', ErrorMessage)
 | |
| 	end
 | |
| 	Response = JSONCollection
 | |
| 	
 | |
| end service
 | |
| 
 | |
| 
 | |
| Service GenerateMaterialTrackRows()
 | |
| 
 | |
| 	hSysLists = Database_Services('GetTableHandle', 'SYSLISTS')
 | |
| 	Lock hSysLists, ServiceKeyID then
 | |
| 		
 | |
| 		Abort     = False$
 | |
| 		NoMatFlag = True$
 | |
| 		
 | |
| 		LocationFilter        = ''
 | |
| 		LocationFilter<1, 1>  = 'SR*KTR]'
 | |
| 		LocationFilter<1, 2>  = '1K*PTI'
 | |
| 		LocationFilter<1, 3>  = 'CR*BE'
 | |
| 		LocationFilter<1, 4>  = 'CR*BO'
 | |
| 		LocationFilter<1, 5>  = 'CR*TUN'
 | |
| 		LocationFilter<1, 6>  = 'CR*EPR'
 | |
| 		LocationFilter<1, 7>  = 'CR*FE'
 | |
| 		LocationFilter<1, 8>  = 'CR*FEH'
 | |
| 		LocationFilter<1, 9>  = 'CR*FO'
 | |
| 		LocationFilter<1, 10> = 'CR*FOH'
 | |
| 		
 | |
| 		// All Possible Report Columns
 | |
| 		AllRptColumns        = ''
 | |
| 		AllRptColumns<1, 1>  = 'React No'
 | |
| 		AllRptColumns<1, 2>  = 'React Type'
 | |
| 		AllRptColumns<1, 3>  = 'WO No'
 | |
| 		AllRptColumns<1, 4>  = 'SAP Prod No'
 | |
| 		AllRptColumns<1, 5>  = 'Sub Part No'
 | |
| 		AllRptColumns<1, 6>  = 'Epi Part No'
 | |
| 		AllRptColumns<1, 7>  = 'WO Qty'
 | |
| 		AllRptColumns<1, 8>  = 'RX Qty'
 | |
| 		AllRptColumns<1, 9>  = 'UnRel Qty'
 | |
| 		AllRptColumns<1, 10> = 'Kit Location'
 | |
| 		AllRptColumns<1, 11> = 'Kit Qty'
 | |
| 		AllRptColumns<1, 12> = '+/-'
 | |
| 		AllRptColumns<1, 13> = 'Kit RO'
 | |
| 		AllRptColumns<1, 14> = 'PTI RO'
 | |
| 		AllRptColumns<1, 15> = 'Load'
 | |
| 		AllRptColumns<1, 16> = 'Comments'
 | |
| 		
 | |
| 		RptColumns = AllRptColumns
 | |
| 		
 | |
| 		ErrorTitle  =  'Error in service ':Service
 | |
| 		ErrCode		= ''
 | |
| 		ErrorMsg	= ''
 | |
| 		
 | |
| 		OPEN 'SCHED_DET_NG' TO SchedDetTable then
 | |
| 			OPEN 'DICT.SCHED_DET_NG' TO @DICT then
 | |
| 				Today   = Datetime()
 | |
| 				
 | |
| 				ReactList 		= ''
 | |
| 				WOList			= ''
 | |
| 				SchedDetKeys	= ''
 | |
| 				PrevReactNo     = ''
 | |
| 				PrevWO          = ''
 | |
| 				
 | |
| 				SelectSent  = 'SELECT SCHED_DET_NG WITH STOP_DTM GE "':OCONV(Today, 'DT'):'" BY REACT_NO BY START_DTM'
 | |
| 				
 | |
| 				RList(SelectSent,TARGET_ACTIVELIST$,'','','')
 | |
| 				IF Get_Status(errCode) THEN
 | |
| 					ErrMsg(errCode)
 | |
| 					Unlock hSysLists, ServiceKeyID else Null
 | |
| 					RETURN
 | |
| 				END
 | |
| 				
 | |
| 				Done = 0
 | |
| 				@ID  = ''
 | |
| 				LOOP
 | |
| 					PrevSchedDetKey = @ID
 | |
| 					READNEXT @ID ELSE Done = 1
 | |
| 				UNTIL Done
 | |
| 					READ SchedDetRec FROM SchedDetTable,@ID THEN
 | |
| 						ReactNo = SchedDetRec<SCHED_DET_NG.REACT_NO$>
 | |
| 						WONo    = SchedDetRec<SCHED_DET_NG.WO_NO$>
 | |
| 						If ReactNo NE '' then
 | |
| 							LOCATE ReactNo IN ReactList BY 'AR' USING @FM  SETTING Pos ELSE
 | |
| 								ReactList = INSERT(ReactList,Pos,0,0,ReactNo)
 | |
| 							END
 | |
| 						END
 | |
| 						If WONo NE '' then
 | |
| 							LOCATE WONo IN WOList<Pos> USING @VM SETTING WPos ELSE	
 | |
| 								WOList 			= INSERT(WOList,Pos,-1,0,WONo)
 | |
| 								SchedDetKeys = INSERT(SchedDetKeys,-1,0,0,@ID)
 | |
| 							END
 | |
| 						END
 | |
| 					END
 | |
| 					
 | |
| 				REPEAT
 | |
| 				
 | |
| 				CALL Make.List(0,SchedDetKeys,SchedDetTable,@DICT)
 | |
| 				
 | |
| 				DateRange = 'Effective ':OCONV(Date(),'D4')
 | |
| 				
 | |
| 				RowIndex      = 0
 | |
| 				AllReportData = ''
 | |
| 				@RECCOUNT     = 0
 | |
| 				FirstPass     = 1
 | |
| 				LastRecord    = 0
 | |
| 				FirstLine     = 1
 | |
| 				fontSpacing   = 100
 | |
| 				
 | |
| 				* Zero Accumulators For Each Break
 | |
| 				
 | |
| 				Prev.ReactNo       = ''
 | |
| 				Last.ReactNo.Break = 1
 | |
| 				
 | |
| 				Loop
 | |
| 					
 | |
| 					ReactNo.Break = 0
 | |
| 					
 | |
| 					READNEXT @ID, Which.Value ELSE
 | |
| 						LastRecord    = 1
 | |
| 						ReactNo.Break = 1
 | |
| 						ReactNo       = Prev.ReactNo
 | |
| 					END
 | |
| 					
 | |
| 					S.ATID = @ID
 | |
| 					Abort  = (FirstPass and LastRecord)
 | |
| 					If Not(Abort) then
 | |
| 						
 | |
| 						If Not(LastRecord) then 
 | |
| 						
 | |
| 							READO @RECORD FROM SchedDetTable,@ID then
 | |
| 								
 | |
| 								// GOTO ReadRecord
 | |
| 								@RECCOUNT += 1
 | |
| 								
 | |
| 								* Calculate Value(s) For Column(s)
 | |
| 								
 | |
| 								S.StartDtm     = {START_DTM}
 | |
| 								S.ATID         = {@ID}
 | |
| 								I.ATID         = S.ATID
 | |
| 								S.ReactNo      = {REACT_NO}
 | |
| 								I.ReactNo      = S.ReactNo
 | |
| 								S.WoNo         = {WO_NO}
 | |
| 								I.WoNo         = S.WoNo
 | |
| 								S.SubPartNo    = XLATE('WO_LOG', S.WoNo, 'ORD_SUB_PART_NO', 'X')
 | |
| 								I.SubPartNo    = S.SubPartNo
 | |
| 								S.EpiPartNo    = XLATE('WO_LOG', S.WoNo, WO_LOG_EPI_PART_NO$, 'X')
 | |
| 								I.EpiPartNo    = S.EpiPartNo
 | |
| 								S.WO_Qty       = Xlate('WO_LOG', {WO_NO}, WO_LOG_WO_QTY$, 'X')
 | |
| 								I.WO_Qty       = S.WO_Qty
 | |
| 								S.WO_RX_Qty    = Xlate('WO_LOG', {WO_NO}, 'RX_QTY', 'X')
 | |
| 								I.WO_RX_Qty    = S.WO_RX_Qty
 | |
| 								S.WO_UnRel_QTY = Xlate('WO_LOG', {WO_NO}, 'UNREL_QTY', 'X')
 | |
| 								I.WO_UnRel_QTY = S.WO_UnRel_QTY
 | |
| 								S.REACT_TYPE   = Xlate('WO_LOG', {WO_NO}, 'REACT_TYPE', 'X')
 | |
| 								S.ProdOrdNo    = Xlate('WO_LOG', {WO_NO}, 'PROD_ORD_NO', 'X')
 | |
| 								
 | |
| 								Locate 'SR*KTR]' in LocationFilter using @VM setting vPos then
 | |
| 									KitData = Location_Services('GetLocationCassInfo', S.WONo, 'SR*KTR]')
 | |
| 									SWAP CRLF$ WITH @VM IN KitData
 | |
| 								end else
 | |
| 									KitData = ''
 | |
| 								end
 | |
| 								
 | |
| 								KitCassList = KitData<3>
 | |
| 								NewKitData  = ''
 | |
| 								
 | |
| 								Swap ',' with @VM in KitData
 | |
| 								
 | |
| 								// Filter out cassettes on hold
 | |
| 								NewKitData<1> = KitData<1>
 | |
| 								Swap @VM with ',' in KitCassList
 | |
| 								For each Cass in KitCassList using ',' setting cPos
 | |
| 									Key    = S.WONo:'*':Cass
 | |
| 									OnHold = Xlate('WO_MAT', Key, 'HOLD', 'X')
 | |
| 									If OnHold NE True$ then
 | |
| 										NewKitData<3, -1> = KitData<3, cPos>
 | |
| 									end
 | |
| 								Next Cass
 | |
| 								
 | |
| 								LocInfo    = ''
 | |
| 								LocInfo<1> = NewKitData<1>
 | |
| 								LocInfo<2> = DCount(NewKitData<3>, @VM)
 | |
| 								LocInfo<3> = NewKitData<3>
 | |
| 								Database_Services('WriteDataRow', 'WO_LOC', S.WONo:'*':'SR*KTR]', LocInfo)
 | |
| 								
 | |
| 								NewKitData<2> = DCount(NewKitData<3>, @VM) ; // Update cassette count
 | |
| 								KitData       = NewKitData
 | |
| 								
 | |
| 								Swap @VM with ',' in KitData
 | |
| 								
 | |
| 								S.KitLocation = KitData<1>
 | |
| 								I.KitLocation = S.KitLocation
 | |
| 								
 | |
| 								S.KitCassCnt	= COUNT(KitData<3>,',') + (KitData<3> NE '')
 | |
| 								I.KitCassCnt	= S.KitCassCnt
 | |
| 								
 | |
| 								KitCassList = KitData<3>
 | |
| 								S.KitQty    = 0
 | |
| 								For each CassNo in KitCassList using ','
 | |
| 									S.KitQty += Xlate('WO_MAT', S.WONo:'*':CassNo, 'WAFER_QTY', 'X')
 | |
| 								Next CassNo
 | |
| 								I.KitQty = S.KitQty
 | |
| 								
 | |
| 								Locate '1K*PTI' in LocationFilter using @VM setting vPos then
 | |
| 									PTIData = Location_Services('GetLocationCassInfo', S.WONo, '1K*PTI')
 | |
| 									SWAP CRLF$ WITH @VM IN PTIData    
 | |
| 								end else
 | |
| 									PTIData = ''
 | |
| 								end
 | |
| 								PTICassList = PTIData<3>
 | |
| 								NewPTIData  = ''
 | |
| 								
 | |
| 								Swap ',' with @VM in PTIData 
 | |
| 								// Filter out cassettes on hold
 | |
| 								NewPTIData<1> = PTIData<1>
 | |
| 								Swap @VM with ',' in PTICassList
 | |
| 								For each Cass in PTICassList using ',' setting cPos
 | |
| 									Key    = S.WONo:'*':Cass
 | |
| 									OnHold = Xlate('WO_MAT', Key, 'HOLD', 'X')
 | |
| 									If OnHold NE True$ then
 | |
| 										NewPTIData<3, -1> = PTIData<3, cPos>
 | |
| 									end
 | |
| 								Next Cass
 | |
| 								
 | |
| 								LocInfo    = ''
 | |
| 								LocInfo<1> = '1K*PTI'
 | |
| 								LocInfo<2> = DCount(NewPTIData<3>, @VM)
 | |
| 								LocInfo<3> = NewPTIData<3>
 | |
| 								Database_Services('WriteDataRow', 'WO_LOC', S.WONo:'*':'1K*PTI', LocInfo)
 | |
| 								
 | |
| 								NewPTIData<2> = DCount(NewPTIData<3>, @VM) ; // Update cassette count
 | |
| 								PTIData       = NewPTIData
 | |
| 								
 | |
| 								Swap @VM with ',' in PTIData
 | |
| 								PTICassList = PTIData<3>
 | |
| 								
 | |
| 								CRLocs        = ''
 | |
| 								CRLocs<0, -1> = 'CR*BE'
 | |
| 								CRLocs<0, -1> = 'CR*BO'
 | |
| 								CRLocs<0, -1> = 'CR*TUN'
 | |
| 								CRLocs<0, -1> = 'CR*EPR'
 | |
| 								CRLocs<0, -1> = 'CR*FE'
 | |
| 								CRLocs<0, -1> = 'CR*FEH'
 | |
| 								CRLocs<0, -1> = 'CR*FO'
 | |
| 								CRLocs<0, -1> = 'CR*FOH'
 | |
| 								
 | |
| 								LoadedData     = ''
 | |
| 								LocQueryList   = ''
 | |
| 								For each Loc in CRLocs using @VM setting crPos
 | |
| 									Locate Loc in LocationFilter using @VM setting vPos then
 | |
| 										LocQueryList<0, -1> = Loc    
 | |
| 									end
 | |
| 								Next Loc
 | |
| 								LoadedCassList = ''
 | |
| 								ReactType      = Xlate('WO_LOG', S.WONo, 'REACT_TYPE', 'X')
 | |
| 								
 | |
| 								If ReactType NE 'EPP' then
 | |
| 									If LocQueryList NE '' then
 | |
| 										For each CRLoc in LocQueryList using @VM
 | |
| 											CRLocCassList = ''
 | |
| 											LoadedData    = Location_Services('GetLocationCassInfo', S.WONo, CRLoc)
 | |
| 											Swap CRLF$ with @VM in LoadedData
 | |
| 											CassList      = LoadedData<3>
 | |
| 											Swap @VM with ',' in CassList
 | |
| 											For each CassNo in CassList using ','
 | |
| 												If ( (S.WONo NE '') and (CassNo NE '') ) then
 | |
| 													WOMatKey      = S.WONo:'*':CassNo
 | |
| 													UnloadSigComp = Signature_Services('CheckSignature', WOMatKey, 'UNLOAD')
 | |
| 													OnHold        = Xlate('WO_MAT', WOMatKey, 'HOLD', 'X')
 | |
| 													CurrStatus    = Xlate('WO_MAT', WOMatKey, 'CURR_STATUS', 'X')
 | |
| 													If Not(UnloadSigComp or OnHold or (CurrStatus EQ 'REJ') ) then
 | |
| 														CRLocCassList<0, -1>  = CassNo
 | |
| 														Locate CassNo in LoadedCassList using @VM setting vPos else
 | |
| 															LoadedCassList<0, -1> = CassNo
 | |
| 														end
 | |
| 													end
 | |
| 												end
 | |
| 											Next CassNo
 | |
| 											LocInfo    = ''
 | |
| 											LocInfo<3> = CRLocCassList
 | |
| 											Database_Services('WriteDataRow', 'WO_LOC', S.WONo:'*':CRLoc, LocInfo)
 | |
| 										Next CRLoc
 | |
| 									end
 | |
| 								end
 | |
| 								
 | |
| 								* TEST FOR CONTROL BREAK(S)
 | |
| 								
 | |
| 								IF (S.ReactNo NE Prev.ReactNo) OR ReactNo.Break THEN
 | |
| 									ReactNo			= Prev.ReactNo
 | |
| 									Prev.ReactNo	= S.ReactNo
 | |
| 									ReactNo.Break  += 1
 | |
| 								END
 | |
| 								
 | |
| 								IF FirstPass THEN FirstPass = False$
 | |
| 									
 | |
| 								* Do Conversion If Any
 | |
| 								
 | |
| 								IF S.REACTNO NE "" 		THEN S.REACTNO		= OCONV(S.REACTNO,"MD0,")
 | |
| 								IF S.WONO NE "" 		THEN S.WONO			= OCONV(S.WONO,"MD0")
 | |
| 								IF S.WO_QTY NE "" 		THEN S.WO_QTY		= OCONV(S.WO_QTY,"MD0,")
 | |
| 								IF S.WO_RX_QTY NE ""	THEN S.WO_RX_QTY	= OCONV(S.WO_RX_QTY,"MD0,")
 | |
| 								IF S.WO_UNREL_QTY NE "" THEN S.WO_UNREL_QTY	= OCONV(S.WO_UNREL_QTY,"MD0,")
 | |
| 								
 | |
| 								* PRINT DETAIL LINE
 | |
| 								
 | |
| 								COLDATA        = ''
 | |
| 								RowNumber      = 0
 | |
| 								
 | |
| 								/*  ascending sort  */
 | |
| 								Convert @VM to ',' in KitCassList
 | |
| 								Convert @VM to ',' in PTICassList
 | |
| 								Convert @VM to ',' in LoadedCassList
 | |
| 								KitCassList    = SRP_Array('SortSimpleList', KitCassList, 'AscendingNumbers', ',')
 | |
| 								PTICassList    = SRP_Array('SortSimpleList', PTICassList, 'AscendingNumbers', ',')
 | |
| 								LoadedCassList = SRP_Array('SortSimpleList', LoadedCassList, 'AscendingNumbers', ',')
 | |
| 								
 | |
| 								CassNeeded = ''
 | |
| 								EpiPartNo  = Xlate('WO_LOG', S.WONo, 'EPI_PART_NO', 'X')
 | |
| 								If EpiPartNo NE '' then
 | |
| 									WPDAdjusted = Epi_Part_Services('GetAdjustedWafersPerDayScheduler', EpiPartNo, S.React_Type)
 | |
| 									If WPDAdjusted NE '' then
 | |
| 										CPDAdjusted = SRP_Math('CEILING', (WPDAdjusted/25) )
 | |
| 										CassInCR    = DCount(KitCassList, ',') + DCount(PTICassList, ',') + DCount(LoadedCassList, ',')
 | |
| 										CassNeeded  = CassInCR - CPDAdjusted
 | |
| 									end
 | |
| 								end
 | |
| 								
 | |
| 								RowIndex                    += 1
 | |
| 								Swap '.1' with '' in S.ProdOrdNo
 | |
| 								
 | |
| 								AllReportData<RowIndex, 1>  = S.ReactNo
 | |
| 								AllReportData<RowIndex, 2>  = S.React_Type
 | |
| 								AllReportData<RowIndex, 3>  = S.WONo
 | |
| 								AllReportData<RowIndex, 4>  = S.ProdOrdNo
 | |
| 								AllReportData<RowIndex, 5>  = S.SubPartNo
 | |
| 								AllReportData<RowIndex, 6>  = S.EpiPartNo
 | |
| 								AllReportData<RowIndex, 7>  = S.WO_Qty
 | |
| 								AllReportData<RowIndex, 8>  = S.WO_RX_Qty
 | |
| 								AllReportData<RowIndex, 9>  = S.WO_UnRel_Qty
 | |
| 								AllReportData<RowIndex, 10> = S.KitLocation
 | |
| 								AllReportData<RowIndex, 11> = S.KitQty
 | |
| 								AllReportData<RowIndex, 12> = CassNeeded					
 | |
| 								AllReportData<RowIndex, 13> = KitCassList  ; // Skip field 14, it is populated by users
 | |
| 								AllReportData<RowIndex, 15> = PTICassList
 | |
| 								AllReportData<RowIndex, 16> = LoadedCassList ; // Skip field 17, it is populated by users
 | |
| 								AllReportData<RowIndex, 18> = S.StartDtm
 | |
| 						
 | |
| 							end
 | |
| 						end else
 | |
| 							// Last record -> write data
 | |
| 							
 | |
| 							Database_Services('WriteDataRow', 'SYSLISTS', 'MAT_REPORT', AllReportData)
 | |
| 							
 | |
| 							If AllReportData NE '' then
 | |
| 								KeyList = ''
 | |
| 								For each Row in AllReportData using @FM setting fPos
 | |
| 									Key            = Row<0, 1> : '*': Row<0, 3> ; // Key = ReactNo * WONo
 | |
| 									KeyList<0, -1> = Key
 | |
| 									Convert @VM to @FM in Row
 | |
| 									If RowExists('MATERIAL_REPORT', Key) then
 | |
| 										// Update it
 | |
| 										Rec = Database_Services('ReadDataRow', 'MATERIAL_REPORT', Key)
 | |
| 										If Error_Services('NoError') then
 | |
| 											// Preserve user input fields
 | |
| 											Row<MATERIAL_REPORT.KIT_DEMAND$> = Rec<MATERIAL_REPORT.KIT_DEMAND$>
 | |
| 											Row<MATERIAL_REPORT.COMMENTS$>   = Rec<MATERIAL_REPORT.COMMENTS$>
 | |
| 											Database_Services('WriteDataRow', 'MATERIAL_REPORT', Key, Row)
 | |
| 										end
 | |
| 									end else
 | |
| 										// New record -> Just write it
 | |
| 										Database_Services('WriteDataRow', 'MATERIAL_REPORT', Key, Row)
 | |
| 									end
 | |
| 								Next Row
 | |
| 								
 | |
| 								// Remove rows no longer current
 | |
| 								Open "MATERIAL_REPORT" To hTable then
 | |
| 									Select hTable
 | |
| 									EOF = False$
 | |
| 									Loop
 | |
| 										ReadNext Key else EOF = True$
 | |
| 									Until EOF
 | |
| 										If Not(InList(KeyList, Key, @VM)) then
 | |
| 											Database_Services('DeleteDataRow', 'MATERIAL_REPORT', Key, True$, False$)
 | |
| 										end
 | |
| 									Repeat
 | |
| 								End else
 | |
| 									// Open table failed
 | |
| 								end
 | |
| 							end
 | |
| 						end
 | |
| 					end else
 | |
| 						ErrorMsg = 'No records selected!'
 | |
| 					end
 | |
| 				Until (LastRecord or Abort)
 | |
| 				Repeat 
 | |
| 			end else
 | |
| 				ErrorMsg = 'Unable to open "SCHED_DET_NG" table.'
 | |
| 			end
 | |
| 		end else
 | |
| 			ErrorMsg  =  'Unable to open "SCHED_DET_NG" table.'
 | |
| 		end
 | |
| 		Unlock hSysLists, ServiceKeyID else Null
 | |
| 	end	
 | |
| 	
 | |
| end service
 | |
| 
 | |
| 
 | |
| Service UpdateMaterialTrackData(MaterialTrackJSON)
 | |
| 	
 | |
| 	If MaterialTrackJSON NE '' then
 | |
| 		If (SRP_JSON(objJSON, 'Parse', MaterialTrackJSON) EQ '') then
 | |
| 			objArray   = SRP_JSON(objJSON, 'Get', 'MaterialReport')
 | |
| 			ArrayCount = SRP_JSON(objArray, 'GetCount')
 | |
| 			For ArrayIndex = 1 to ArrayCount
 | |
| 				objRow    = SRP_JSON(objArray, 'Get', '[':ArrayIndex:']')
 | |
| 				KeyId     = SRP_JSON(objRow, 'GetValue', 'KeyId')
 | |
| 				KitDemand = SRP_JSON(objRow, 'GetValue', 'KitDemand', '')
 | |
| 				Comments  = SRP_JSON(objRow, 'GetValue', 'Comments', '')
 | |
| 				HaveLock  = Database_Services('GetKeyIDLock', 'MATERIAL_REPORT', KeyId, True$)
 | |
| 				If HaveLock then 
 | |
| 					MatRepRec = Database_Services('ReadDataRow', 'MATERIAL_REPORT', KeyId)
 | |
| 					If Error_Services('NoError') then
 | |
| 						MatRepRec<MATERIAL_REPORT.KIT_DEMAND$> = KitDemand
 | |
| 						MatRepRec<MATERIAL_REPORT.COMMENTS$>   = Comments
 | |
| 						Database_Services('WriteDataRow', 'MATERIAL_REPORT', KeyId, MatRepRec, True$, False$, False$)
 | |
| 					end
 | |
| 				end
 | |
| 				SRP_JSON(objRow, 'Release')
 | |
| 			Next ArrayIndex
 | |
| 			SRP_JSON(objArray, 'Release')
 | |
| 			SRP_JSON(objJSON, 'Release')
 | |
| 		end	else
 | |
| 			Error_Services('Add', 'Error in ':Service:' service. Error parsing MaterialTrackJSON.')
 | |
| 		end
 | |
| 	end else
 | |
| 		Error_Services('Add', 'Error in ':Service:' service. Empty MaterialTrackJSON passed into service.')
 | |
| 	end
 | |
| 	
 | |
| end service
 | |
| 
 | |
| 
 | |
| Service PrintMaterialTrackReport(RptColumns, LocationFilter, NoMatFlag, OldReport=BOOLEAN)
 | |
| 	
 | |
| 	If OldReport EQ '' then OldReport = False$
 | |
| 	Abort                = False$
 | |
|     // All Possible Report Columns
 | |
|     AllRptColumns        = ''
 | |
|     AllRptColumns<1, 1>  = 'React No'
 | |
|     AllRptColumns<1, 2>  = 'React Type'
 | |
|     AllRptColumns<1, 3>  = 'WO No'
 | |
|     AllRptColumns<1, 4>  = 'SAP Prod No'
 | |
|     AllRptColumns<1, 5>  = 'Sub Part No'
 | |
|     AllRptColumns<1, 6>  = 'Epi Part No'
 | |
|     AllRptColumns<1, 7>  = 'WO Qty'
 | |
|     AllRptColumns<1, 8>  = 'RX Qty'
 | |
|     AllRptColumns<1, 9>  = 'UnRel Qty'
 | |
|     AllRptColumns<1, 10> = 'Kit Location'
 | |
|     AllRptColumns<1, 11> = 'Kit Qty'
 | |
|     AllRptColumns<1, 12> = '+/-'
 | |
|     AllRptColumns<1, 13> = 'Kit RO'
 | |
|     AllRptColumns<1, 14> = 'PTI RO'
 | |
|     AllRptColumns<1, 15> = 'Load'
 | |
|     AllRptColumns<1, 16> = 'Comments'
 | |
|     
 | |
|     If Index(RptColumns, 'Comments', 1) then
 | |
|         AllColFmt        = ''
 | |
|         AllColFmt<1, 1>  = '+^720'
 | |
|         AllColFmt<1, 2>  = '+<720'
 | |
|         AllColFmt<1, 3>  = '+^1000'
 | |
|         AllColFmt<1, 4>  = '+^1100'
 | |
|         AllColFmt<1, 5>  = '+^1300'
 | |
|         AllColFmt<1, 6>  = '+^1200'
 | |
|         AllColFmt<1, 7>  = '+>720'
 | |
|         AllColFmt<1, 8>  = '+>720'
 | |
|         AllColFmt<1, 9>  = '+>720'
 | |
|         AllColFmt<1, 10> = '+^1260'
 | |
|         AllColFmt<1, 11> = '+^720'
 | |
|         AllColFmt<1, 12> = '+^500'
 | |
|         AllColFmt<1, 13> = '+^1300'
 | |
|         AllColFmt<1, 14> = '+^1300'
 | |
|         AllColFmt<1, 15> = '+^700'
 | |
|         AllColFmt<1, 16> = '+^1300'    
 | |
|     end else
 | |
|         AllColFmt        = ''
 | |
|         AllColFmt<1, 1>  = '+^720'
 | |
|         AllColFmt<1, 2>  = '+<720'
 | |
|         AllColFmt<1, 3>  = '+^1000'
 | |
|         AllColFmt<1, 4>  = '+^1100'
 | |
|         AllColFmt<1, 5>  = '+^1300'
 | |
|         AllColFmt<1, 6>  = '+^1200'
 | |
|         AllColFmt<1, 7>  = '+>720'
 | |
|         AllColFmt<1, 8>  = '+>720'
 | |
|         AllColFmt<1, 9>  = '+>720'
 | |
|         AllColFmt<1, 10> = '+^1260'
 | |
|         AllColFmt<1, 11> = '+^720'
 | |
|         AllColFmt<1, 12> = '+^500'
 | |
|         AllColFmt<1, 13> = '+^1800'
 | |
|         AllColFmt<1, 14> = '+^1800'
 | |
|         AllColFmt<1, 15> = '+^1100'
 | |
|         AllColFmt<1, 16> = ''
 | |
|     end
 | |
| 
 | |
|     ErrorTitle  =  'Error in service ':Service
 | |
|     ErrCode		= ''
 | |
|     ErrorMsg	= ''
 | |
| 
 | |
|     OPEN 'SCHED_DET_NG' TO SchedDetTable then
 | |
|         OPEN 'DICT.SCHED_DET_NG' TO @DICT then
 | |
|             Today   = Datetime()
 | |
| 
 | |
|             ReactList 		= ''
 | |
|             WOList			= ''
 | |
|             SchedDetKeys	= ''
 | |
|             PrevReactNo     = ''
 | |
|             PrevWO          = ''
 | |
| 
 | |
| 			If OldReport then
 | |
| 				SelectSent  = 'SELECT SCHED_DET_NG WITH STOP_DTM GE ':Today:' BY REACT_NO BY START_DTM'
 | |
| 			end else
 | |
| 				SelectSent = 'SELECT SCHED_DET_NG WITH STOP_DTM GE "':OCONV(Today, 'DT'):'" BY REACT_NO BY START_DTM'
 | |
| 			end
 | |
| 
 | |
|             RList(SelectSent,TARGET_ACTIVELIST$,'','','')
 | |
|             IF Get_Status(errCode) THEN
 | |
|                 ErrMsg(errCode)
 | |
|                 RETURN
 | |
|             END
 | |
| 
 | |
|             Done = 0
 | |
|             @ID  = ''
 | |
|             LOOP
 | |
|                 PrevSchedDetKey = @ID
 | |
|                 READNEXT @ID ELSE Done = 1
 | |
|             UNTIL Done
 | |
|                 READ SchedDetRec FROM SchedDetTable,@ID THEN
 | |
|                     ReactNo = SchedDetRec<SCHED_DET_NG.REACT_NO$>
 | |
|                     WONo    = SchedDetRec<SCHED_DET_NG.WO_NO$>
 | |
|                     If ReactNo NE '' then
 | |
|                         LOCATE ReactNo IN ReactList BY 'AR' USING @FM  SETTING Pos ELSE
 | |
|                             ReactList = INSERT(ReactList,Pos,0,0,ReactNo)
 | |
|                         END
 | |
|                     END
 | |
|                     If WONo NE '' then
 | |
|                         LOCATE WONo IN WOList<Pos> USING @VM SETTING WPos ELSE	
 | |
|                             WOList 			= INSERT(WOList,Pos,-1,0,WONo)
 | |
|                             SchedDetKeys = INSERT(SchedDetKeys,-1,0,0,@ID)
 | |
|                         END
 | |
|                     END
 | |
|                 END
 | |
|                 
 | |
|             REPEAT
 | |
|             
 | |
|             CALL Make.List(0,SchedDetKeys,SchedDetTable,@DICT)
 | |
| 
 | |
|             Header		= "'D'":@VM:obj_Install('Get_Prop','CompTitle'):' Material Tracking by Reactor':@VM:"Page  'P'"
 | |
|             MinDemand	= 0
 | |
|             Set_Status(0)
 | |
| 
 | |
|             * Start of printing process
 | |
|             FileName = 'Print Material Demand'
 | |
|             Title    = 'Printing Material Demand'
 | |
| 
 | |
|             TopMargin		= 1.0
 | |
|             BottomMargin	= 0.75
 | |
|             LeftMargin		= 0.25
 | |
|             RightMargin		= 0.25
 | |
| 
 | |
|             Margins = LeftMargin:@FM:TopMargin:@FM:RightMargin:@FM:BottomMargin
 | |
| 
 | |
|             PageSetup       = '1'		;* LandScape
 | |
|             PrintSetup      = '2'		;* Preview Normal
 | |
|             PrintSetup<1,2> = '0'	;* All buttons
 | |
|             PrintSetup<1,5> = '1'	;* Page Range
 | |
|             PrintSetup<1,6> = 7		;* full mouse and keyboard support
 | |
| 
 | |
|             PrintPath = ''
 | |
|             stat      = Set_Printer('INIT',FileName,Title,Margins,PageSetup,PrintSetup,PrintPath)
 | |
| 
 | |
|             If Stat GE 0 THEN
 | |
| 				DateRange = 'Effective ':OCONV(Date(),'D4')
 | |
| 
 | |
| 				Header<-1> = "'T'"
 | |
| 				Header<-1> = ''																;* Blank line following heading
 | |
| 
 | |
| 				font	= 'Arial'
 | |
| 				font<2>	= '10'
 | |
| 				font<4>	= '0'		;* Bold
 | |
| 
 | |
| 				stat = Set_Printer('FONTHEADFOOT',font)	
 | |
| 				If Stat GE 0 then
 | |
| 					stat   = Set_Printer('HEADER',Header)		
 | |
| 					If Stat GE 0 then
 | |
| 						Footer    = " 'D' 'T'":@VM:@VM:"Page:  'P'"
 | |
| 						stat      = Set_Printer('FOOTER',Footer)
 | |
| 						If Stat GE 0 then
 | |
| 							@RECCOUNT   = 0
 | |
| 							FirstPass	= 1
 | |
| 							LastRecord	= 0
 | |
| 							FirstLine 	= 1
 | |
| 							fontSpacing	= 100
 | |
| 
 | |
| 							* Make Column Heading
 | |
| 							ColHead = ''
 | |
| 							ColFmt  = ''
 | |
| 							
 | |
| 							For each Column in RptColumns using @VM setting rcPos
 | |
| 								Locate Column in AllRptColumns using @VM setting dataPos then
 | |
| 									ColHead<0, -1> = Column
 | |
| 									ColFmt<0, -1>  = AllColFmt<0, dataPos>
 | |
| 								end
 | |
| 							Next Column
 | |
| 
 | |
| 							* Zero Accumulators For Each Break
 | |
| 
 | |
| 							Prev.ReactNo       = ''
 | |
| 							Last.ReactNo.Break = 1
 | |
| 							
 | |
| 							Loop
 | |
| 									
 | |
| 								* Zero Break Flags To False
 | |
| 								
 | |
| 								ReactNo.Break = 0
 | |
| 								
 | |
| 								READNEXT @ID, Which.Value ELSE
 | |
| 									LastRecord    = 1
 | |
| 									ReactNo.Break = 1
 | |
| 									ReactNo       = Prev.ReactNo
 | |
| 								END
 | |
| 								
 | |
| 								S.ATID = @ID
 | |
| 								Abort  = (FirstPass AND LastRecord)
 | |
| 								IF Not(Abort) THEN
 | |
| 									
 | |
| 									IF Not(LastRecord) then
 | |
| 										READO @RECORD FROM SchedDetTable,@ID then
 | |
| 											
 | |
| 											@RECCOUNT += 1
 | |
| 											
 | |
| 											* Calculate Value(s) For Column(s)
 | |
| 											
 | |
| 											S.ATID			= {@ID}
 | |
| 											I.ATID			= S.ATID
 | |
| 											S.ReactNo		= {REACT_NO}
 | |
| 											I.ReactNo		= S.ReactNo
 | |
| 											S.WoNo			= {WO_NO}
 | |
| 											I.WoNo			= S.WoNo
 | |
| 											S.SubPartNo		= XLATE('WO_LOG', S.WoNo, 'ORD_SUB_PART_NO', 'X')
 | |
| 											I.SubPartNo		= S.SubPartNo
 | |
| 											S.EpiPartNo		= XLATE('WO_LOG', S.WoNo, WO_LOG_EPI_PART_NO$, 'X')
 | |
| 											I.EpiPartNo		= S.EpiPartNo
 | |
| 											S.WO_Qty		= Xlate('WO_LOG', {WO_NO}, WO_LOG_WO_QTY$, 'X')
 | |
| 											I.WO_Qty		= S.WO_Qty
 | |
| 											S.WO_RX_Qty 	= Xlate('WO_LOG', {WO_NO}, 'RX_QTY', 'X')
 | |
| 											I.WO_RX_Qty 	= S.WO_RX_Qty
 | |
| 											S.WO_UnRel_QTY	= Xlate('WO_LOG', {WO_NO}, 'UNREL_QTY', 'X')
 | |
| 											I.WO_UnRel_QTY	= S.WO_UnRel_QTY
 | |
| 											S.REACT_TYPE    = Xlate('WO_LOG', {WO_NO}, 'REACT_TYPE', 'X')
 | |
| 											S.ProdOrdNo		= Xlate('WO_LOG', {WO_NO}, 'PROD_ORD_NO', 'X')
 | |
| 											
 | |
| 											
 | |
| 											If OldReport then
 | |
| 												
 | |
| 												Locate 'SR*KTR]' in LocationFilter using @VM setting vPos then
 | |
| 													KitData = Location_Services('GetLocationCassInfo', S.WONo, 'SR*KTR]')    
 | |
| 													SWAP CRLF$ WITH @VM IN KitData
 | |
| 												end else
 | |
| 													KitData = ''
 | |
| 												end
 | |
| 												
 | |
| 												S.KitLocation = KitData<1>
 | |
| 												I.KitLocation = S.KitLocation
 | |
| 												
 | |
| 												S.KitQty		= OCONV(SUM(KitData<2>) * 25,'MD0,Z')
 | |
| 												I.KitQty		= S.KitQty
 | |
| 												
 | |
| 												S.KitCassCnt	= COUNT(KitData<3>,',') + (KitData<3> NE '')
 | |
| 												I.KitCassCnt	= S.KitCassCnt
 | |
| 												
 | |
| 												KitCassList = KitData<3>
 | |
| 
 | |
| 												Locate '1K*PTI' in LocationFilter using @VM setting vPos then
 | |
| 													PTIData = Location_Services('GetLocationCassInfo', S.WONo, '1K*PTI')
 | |
| 													SWAP CRLF$ WITH @VM IN PTIData    
 | |
| 												end else
 | |
| 													PTIData = ''
 | |
| 												end												
 | |
| 												
 | |
| 											end else
 | |
| 												
 | |
| 												Locate 'SR*KTR]' in LocationFilter using @VM setting vPos then
 | |
| 													KitData = Database_Services('ReadDataRow', 'WO_LOC', S.WONo:'*':'SR*KTR]')
 | |
| 												end else
 | |
| 													KitData = ''
 | |
| 												end
 | |
| 												   
 | |
| 												Swap @VM with ',' in KitData
 | |
| 												
 | |
| 												S.KitLocation = KitData<1>
 | |
| 												I.KitLocation = S.KitLocation
 | |
| 												
 | |
| 												S.KitCassCnt	= COUNT(KitData<3>,',') + (KitData<3> NE '')
 | |
| 												I.KitCassCnt	= S.KitCassCnt
 | |
| 												
 | |
| 												KitCassList = KitData<3>
 | |
| 												S.KitQty    = 0
 | |
| 												For each CassNo in KitCassList using ','
 | |
| 													S.KitQty += Xlate('WO_MAT', S.WONo:'*':CassNo, 'WAFER_QTY', 'X')
 | |
| 												Next CassNo
 | |
| 												I.KitQty = S.KitQty
 | |
| 
 | |
| 												Locate '1K*PTI' in LocationFilter using @VM setting vPos then
 | |
| 													PTIData = Database_Services('ReadDataRow', 'WO_LOC', S.WONo:'*':'1K*PTI')
 | |
| 												end else
 | |
| 													PTIData = ''
 | |
| 												end
 | |
| 												PTICassList = PTIData<3>
 | |
| 												
 | |
| 												Swap @VM with ',' in PTIData	
 | |
| 												
 | |
| 											end
 | |
| 
 | |
| 											PTICassList = PTIData<3>
 | |
| 											
 | |
| 											CRLocs        = ''
 | |
| 											CRLocs<0, -1> = 'CR*BE'
 | |
| 											CRLocs<0, -1> = 'CR*BO'
 | |
| 											CRLocs<0, -1> = 'CR*TUN'
 | |
| 											CRLocs<0, -1> = 'CR*EPR'
 | |
| 											CRLocs<0, -1> = 'CR*FE'
 | |
| 											CRLocs<0, -1> = 'CR*FEH'
 | |
| 											CRLocs<0, -1> = 'CR*FO'
 | |
| 											CRLocs<0, -1> = 'CR*FOH'
 | |
| 											
 | |
| 											LoadedData     = ''
 | |
| 											LocQueryList   = ''
 | |
| 											For each Loc in CRLocs using @VM setting crPos
 | |
| 												Locate Loc in LocationFilter using @VM setting vPos then
 | |
| 													LocQueryList<0, -1> = Loc    
 | |
| 												end
 | |
| 											Next Loc
 | |
| 											LoadedCassList = ''
 | |
| 											ReactType      = Xlate('WO_LOG', S.WONo, 'REACT_TYPE', 'X')
 | |
| 											If ReactType NE 'EPP' then
 | |
| 												If LocQueryList NE '' then
 | |
| 													If OldReport then
 | |
| 														LoadedData = Location_Services('GetLocationCassInfo', S.WONo, LocQueryList)
 | |
| 														Swap CRLF$ with @VM in LoadedData
 | |
| 														CassList   = LoadedData<3>
 | |
| 														Swap @VM with ',' in CassList
 | |
| 														For each CassNo in CassList using ','
 | |
| 															If ( (S.WONo NE '') and (CassNo NE '') ) then
 | |
| 																WOMatKey      = S.WONo:'*':CassNo
 | |
| 																UnloadSigComp = Signature_Services('CheckSignature', WOMatKey, 'UNLOAD')
 | |
| 																OnHold        = Xlate('WO_MAT', WOMatKey, 'HOLD', 'X')
 | |
| 																CurrStatus    = Xlate('WO_MAT', WOMatKey, 'CURR_STATUS', 'X')
 | |
| 																If Not(UnloadSigComp or OnHold or (CurrStatus EQ 'REJ') ) then
 | |
| 																	LoadedCassList<0, -1> = CassNo
 | |
| 																end
 | |
| 															end
 | |
| 														Next CassNo														
 | |
| 													end else
 | |
| 														For each CRLoc in LocQueryList using @VM
 | |
| 															CRLocInfo      = Database_Services('ReadDataRow', 'WO_LOC', S.WONo:'*':CRLoc)
 | |
| 															CRLocCassList  = CRLocInfo<3>
 | |
| 															LoadedCassList = SRP_Array('Join', LoadedCassList, CRLocCassList, 'OR', @VM)
 | |
| 														Next CRLoc														
 | |
| 													end
 | |
| 												end
 | |
| 											end
 | |
| 											
 | |
| 											If Not(OldReport) then LoadedCassList = SRP_Array('Clean', LoadedCassList, 'TrimAndMakeUnique', @VM)
 | |
| 											* TEST FOR CONTROL BREAK(S)
 | |
| 											
 | |
| 											IF (S.ReactNo NE Prev.ReactNo) OR ReactNo.Break THEN
 | |
| 												ReactNo			= Prev.ReactNo
 | |
| 												Prev.ReactNo	= S.ReactNo
 | |
| 												ReactNo.Break  += 1
 | |
| 											END
 | |
| 											
 | |
| 											IF ReactNo.Break THEN stat = Set_Printer('TEXT')
 | |
| 											
 | |
| 											IF FirstPass THEN FirstPass = False$
 | |
| 											
 | |
| 											* Do Conversion If Any
 | |
| 
 | |
| 											IF S.REACTNO NE "" 		THEN S.REACTNO		= OCONV(S.REACTNO,"MD0,")
 | |
| 											IF S.WONO NE "" 		THEN S.WONO			= OCONV(S.WONO,"MD0")
 | |
| 											IF S.WO_QTY NE "" 		THEN S.WO_QTY		= OCONV(S.WO_QTY,"MD0,")
 | |
| 											IF S.WO_RX_QTY NE ""	THEN S.WO_RX_QTY	= OCONV(S.WO_RX_QTY,"MD0,")
 | |
| 											IF S.WO_UNREL_QTY NE "" THEN S.WO_UNREL_QTY	= OCONV(S.WO_UNREL_QTY,"MD0,")
 | |
| 											
 | |
| 											* PRINT DETAIL LINE
 | |
| 											
 | |
| 											COLDATA        = ''
 | |
| 											RowNumber      = 0
 | |
| 
 | |
| 											/*  ascending sort  */
 | |
| 											Convert @VM to ',' in KitCassList
 | |
| 											Convert @VM to ',' in PTICassList
 | |
| 											Convert @VM to ',' in LoadedCassList
 | |
| 											KitCassList    = SRP_Array('SortSimpleList', KitCassList, 'AscendingNumbers', ',')
 | |
| 											PTICassList    = SRP_Array('SortSimpleList', PTICassList, 'AscendingNumbers', ',')
 | |
| 											LoadedCassList = SRP_Array('SortSimpleList', LoadedCassList, 'AscendingNumbers', ',')
 | |
| 											
 | |
| 											Convert ',' to @VM in KitCassList
 | |
| 											Convert ',' to @VM in PTICassList
 | |
| 											Convert ',' to @VM in LoadedCassList
 | |
| 
 | |
| 											NumKitCass = DCount(KitCassList, @VM)
 | |
| 											If NumKitCass GT 4 then
 | |
| 												For CassIndex = 4 to NumKitCass Step 4
 | |
| 													CassNo                     = KitCassList<0, CassIndex>
 | |
| 													CassNo                    := CRLF$
 | |
| 													KitCassList<0, CassIndex>  = CassNo
 | |
| 												Next CassIndex
 | |
| 											end
 | |
| 											NumPTICass = DCount(PTICassList, @VM)
 | |
| 											If NumPTICass GT 4 then
 | |
| 												For CassIndex = 4 to NumPTICass Step 4
 | |
| 													CassNo                     = PTICassList<0, CassIndex>
 | |
| 													CassNo                    := CRLF$
 | |
| 													PTICassList<0, CassIndex>  = CassNo
 | |
| 												Next CassIndex
 | |
| 											end
 | |
| 											NumLoadedCass = DCount(LoadedCassList, @VM)
 | |
| 											If NumLoadedCass GT 2 then
 | |
| 												For CassIndex = 2 to NumLoadedCass Step 2
 | |
| 													CassNo                        = LoadedCassList<0, CassIndex>
 | |
| 													CassNo                       := CRLF$
 | |
| 													LoadedCassList<0, CassIndex>  = CassNo
 | |
| 												Next CassIndex
 | |
| 											end
 | |
| 											Convert @VM to ',' in KitCassList
 | |
| 											Convert @VM to ',' in PTICassList
 | |
| 											Convert @VM to ',' in LoadedCassList
 | |
| 											
 | |
| 											CassNeeded = ''
 | |
| 											EpiPartNo  = Xlate('WO_LOG', S.WONo, 'EPI_PART_NO', 'X')
 | |
| 											If EpiPartNo NE '' then
 | |
| 												WPDAdjusted = Epi_Part_Services('GetAdjustedWafersPerDayScheduler', EpiPartNo, S.React_Type)
 | |
| 												If WPDAdjusted NE '' then
 | |
| 													CPDAdjusted = SRP_Math('CEILING', (WPDAdjusted/25) )
 | |
| 													CassInCR    = DCount(KitCassList, ',') + DCount(PTICassList, ',') + DCount(LoadedCassList, ',')
 | |
| 													CassNeeded  = CassInCR - CPDAdjusted
 | |
| 												end
 | |
| 											end
 | |
| 
 | |
| 											Swap '.1' with '' in S.ProdOrdNo
 | |
| 											AllReportData     = ''
 | |
| 											AllReportData<1>  = S.ReactNo
 | |
| 											AllReportData<2>  = S.React_Type
 | |
| 											AllReportData<3>  = S.WONo
 | |
| 											AllReportData<4>  = S.ProdOrdNo
 | |
| 											AllReportData<5>  = S.SubPartNo
 | |
| 											AllReportData<6>  = S.EpiPartNo
 | |
| 											AllReportData<7>  = S.WO_Qty
 | |
| 											AllReportData<8>  = S.WO_RX_Qty
 | |
| 											AllReportData<9>  = S.WO_UnRel_Qty
 | |
| 											AllReportData<10> = S.KitLocation
 | |
| 											AllReportData<11> = S.KitQty
 | |
| 											AllReportData<12> = CassNeeded					
 | |
| 											AllReportData<13> = KitCassList
 | |
| 											AllReportData<14> = PTICassList
 | |
| 											AllReportData<15> = LoadedCassList
 | |
| 											AllReportData<16> = ''
 | |
| 											
 | |
| 											If ( (KitCassList NE '') or (PTICassList NE '') or (LoadedCassList NE '') or (NoMatFlag EQ True$) ) then
 | |
| 												RowNumber += 1              
 | |
| 												For each RptColumn in RptColumns using @VM setting rcPos
 | |
| 													Locate RptColumn in AllRptColumns using @VM setting dataPos then
 | |
| 														COLDATA<RowNumber,rcPos> = AllReportData<dataPos>
 | |
| 													end  
 | |
| 												Next RptColumn
 | |
| 												If COLDATA NE '' then
 | |
| 													// Print the data
 | |
| 													PageHeight		= Get_Printer('PAGESIZE')<2>
 | |
| 													PrintableHeight = PageHeight - TopMargin - BottomMargin
 | |
| 													PrinterHeight   = Get_Printer('POS')<2>   
 | |
| 													stat			= Set_Printer('CALCTABLE',ColFmt:@FM:ColData)
 | |
| 													TableSize		= Get_Printer('CALCTABLE')  
 | |
| 													TableHeight		= TableSize<2>   
 | |
| 													fontSpacing     = 120
 | |
| 													
 | |
| 													IF ( TableHeight + PrinterHeight >= PrintableHeight ) OR FirstLine THEN
 | |
| 														IF NOT(FirstLine) THEN
 | |
| 															stat = Set_Printer('PAGEBREAK')
 | |
| 														END
 | |
| 														FirstLine = 0
 | |
| 														font<2> = 10
 | |
| 														font<4> = 1		;* Bold
 | |
| 														stat = Set_Printer('FONT',font,'100')       
 | |
| 														stat = Set_Printer('ADDTABLE',colFmt,colHead,'',LTGREY$,'',0,TB_ALL)                
 | |
| 														font<4> = 0
 | |
| 														stat = Set_Printer('FONT',font,fontSpacing)      
 | |
| 														stat = Set_Printer('ADDTABLE',colFmt,'',colData,LTGREY$,'',0,7)        
 | |
| 													END ELSE
 | |
| 														font<2> = 10
 | |
| 														font<4> = 0
 | |
| 														stat = Set_Printer('FONT',font,fontSpacing)
 | |
| 														stat = Set_Printer('ADDTABLE',colFmt,'',colData,LTGREY$,'',1,TB_ALL)       
 | |
| 													END													
 | |
| 												end
 | |
| 											END											
 | |
| 										end
 | |
| 									end else
 | |
| 										// Last record -> Finish printing
 | |
| 										colData = ''
 | |
| 										stat = Set_Printer('TERM',1)
 | |
| 									end								
 | |
| 								END else
 | |
| 									// No records selected -> Bail
 | |
| 									stat = Set_Printer('TERM',1)
 | |
| 								end
 | |
| 							Until (LastRecord or Abort)
 | |
| 							Repeat 
 | |
| 						end else
 | |
| 							GoSub OipiPrintError							
 | |
| 						end
 | |
| 					end else
 | |
| 						GoSub OipiPrintError						
 | |
| 					end
 | |
| 				end else
 | |
| 					GoSub OipiPrintError
 | |
| 				end
 | |
|             end else
 | |
|             	ErrorMsg = 'Stat = ' : Stat : ', PrintPath = ' : PrintPath
 | |
| 				GoSub OipiPrintError
 | |
|             end
 | |
|         end else
 | |
|             ErrorMsg = 'Unable to open "SCHED_DET_NG" table.'
 | |
|             ErrMsg(ErrorTitle:@SVM:ErrorMsg)
 | |
|         end
 | |
|     end else
 | |
|         ErrorMsg  =  'Unable to open "SCHED_DET_NG" table.'
 | |
|         ErrMsg(ErrorTitle:@SVM:ErrorMsg)       
 | |
|     end
 | |
| 	
 | |
| end service
 | |
| 
 | |
| Service GetOpenNCRReportJson()
 | |
|     ErrorMessage      = ''
 | |
|     OpenNCRReportJson = ''
 | |
|     OpenNCRKeyList    = NCR_Services('GetOpenNCRKeys')
 | |
| 	objJson           = ''
 | |
| 	If SRP_Json(objJson, 'New') then
 | |
| 	    objOpenNCRJsonArray = ''
 | |
| 	    If SRP_Json(objOpenNCRJsonArray, 'New', 'Array') then
 | |
| 	        for each NCRKey in OpenNCRKeyList using @VM
 | |
| 	            ThisNCRJsonString = NCR_Services('ConvertRecordToJson', NCRKey)
 | |
| 	            ThisNCRJsonObj    = ''
 | |
| 	            ParseResult       = SRP_Json(ThisNCRJsonObj, 'Parse', ThisNCRJsonString)
 | |
| 	            If ParseResult EQ '' then
 | |
| 	                SRP_Json(objOpenNCRJsonArray, 'Add', ThisNCRJsonObj)
 | |
| 	                SRP_Json(ThisNCRJsonObj, 'Release')
 | |
| 	            end else
 | |
| 	                SRP_Json(ThisNCRJsonObj, 'Release')
 | |
| 	            end
 | |
| 	        Next NCRKey
 | |
| 	        SRP_Json(objJson, 'Set', 'OpenNCRReport', objOpenNCRJsonArray)
 | |
| 	        SRP_Json(objOpenNCRJsonArray, 'Release')
 | |
| 	    end else
 | |
| 	       ErrorMessage = 'Error creating Open NCR JSON Array.' 
 | |
| 	    end
 | |
| 	    OpenNCRReportJson = SRP_JSON(objJSON, 'Stringify', 'Styled')
 | |
|         SRP_JSON(objJSON, 'Release')
 | |
| 	end else
 | |
| 	    ErrorMessage = 'Error creating root JSON object.'
 | |
| 	end
 | |
| 	If ErrorMessage NE '' then
 | |
| 	    Error_Services('Add', ErrorMessage)
 | |
| 	end
 | |
| 	Response = OpenNCRReportJson
 | |
| end service
 | |
| 
 | |
| 
 | |
| /* * * * * *
 | |
| Called from Reporting Services
 | |
| 
 | |
| * * * * * */
 | |
| Service GetSLLReportJson(FromDt, ToDt)
 | |
|     
 | |
|     FromDt = IConv(FromDt, 'D')
 | |
|     ToDt = IConv(ToDt, 'D')
 | |
|     ErrorMessage = ''
 | |
|     SLLReportJson = ''
 | |
|     objSLLReportJson = ''
 | |
|     If FromDt NE '' OR ToDt NE '' then
 | |
|         If SRP_Json(objSLLReportJson, 'New', 'Array') then
 | |
|             For StartDt = FromDt to ToDt
 | |
|                 ThisDate = Date_Services('ConvertDateTimeToISO8601', StartDt)
 | |
|                 ThisDtASMDownLL = Reactor_Services('GetReactorsWithDownLLByDtm', StartDt + 1, 'ASM')
 | |
|                 ThisDtASMPlusDownLL = Reactor_Services('GetReactorsWithDownLLByDtm', StartDt + 1, 'ASM+')
 | |
|                 ThisDtHTRDownLL = Reactor_Services('GetReactorsWithDownLLByDtm', StartDt + 1, 'HTR')
 | |
|                 ThisDtASMDownLLCount = DCount(ThisDtASMDownLL, @VM) + DCount(ThisDtASMPlusDownLL, @VM)
 | |
|                 ThisDtHTRDownLLCount = DCount(ThisDtHTRDownLL, @VM)
 | |
|                 objSLLDay = ''
 | |
|                 If SRP_Json(objSLLDay, 'New', 'Object') then
 | |
|                     SRP_Json(objSLLDay, 'SetValue', 'Date', ThisDate)
 | |
|                     SRP_Json(objSLLDay, 'SetValue', 'ASM', ThisDtASMDownLLCount)
 | |
|                     SRP_Json(objSLLDay, 'SetValue', 'HTR', ThisDtHTRDownLLCount)
 | |
|                     SRP_Json(objSLLReportJson, 'Add', objSLLDay)
 | |
|                     SRP_Json(objSLLDay, 'Release')
 | |
|                 end
 | |
|             Next StartDt
 | |
|             SLLReportJson = SRP_Json(objSLLReportJson, 'Stringify', 'Fast')
 | |
|             SRP_Json(objSLLReportJson, 'Release')
 | |
|         end else
 | |
|             ErrorMessage = 'Error creating the root JSON for the report.'
 | |
|         end
 | |
|     end else
 | |
|         ErrorMessage = 'From Date or To Date was null.'
 | |
|     end
 | |
|     
 | |
|     If ErrorMessage NE '' then
 | |
|         Error_Services('Add', ErrorMessage)
 | |
|     end
 | |
|     
 | |
|     Response = SLLReportJson
 | |
|     
 | |
| end service
 | |
| 
 | |
| ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | |
| // Internal GoSubs
 | |
| ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | |
| 
 | |
| ClearCursors:
 | |
| 	
 | |
| 	For counter = 0 to 8
 | |
| 		ClearSelect counter
 | |
| 	Next counter
 | |
| 	
 | |
| return
 | |
| 
 | |
| 
 | |
| OipiPrintError:
 | |
| 	
 | |
| 	ErrMsg(ErrorTitle:@SVM:ErrorMsg)
 | |
| 	ErrMsg(ErrorTitle:@SVM:'Set_Printer returned errorcode ':stat)
 | |
| 	stat = Set_Printer('TERM',1)		
 | |
| 	
 | |
| return
 | |
| 
 |