open-insight/LSL2/STPROC/REPORT_SERVICES.txt
Infineon\StieberD 7762b129af pre cutover push
2024-09-04 20:33:41 -07:00

1848 lines
86 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
// 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
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
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 ""
//-----------------------------------------------------------------------------
// 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, 'MU')
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 GetMaterialTrackReport(RptColumns, LocationFilter)
// 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' TO SchedDetTable then
OPEN 'DICT.SCHED_DET' TO @DICT then
Today = OCONV(Date(),'D4/')
EndDate = OCONV(Date()+13,'D4/')
ReactList = ''
WOList = ''
SchedDetKeys = ''
PrevReactNo = ''
PrevWO = ''
SelectSent = 'SELECT SCHED_DET WITH SCHED_DT GE ':QUOTE(Today):' BY REACT_NO'
* Push.Select(f1, f2, f3, f4)
RList(SelectSent,TARGET_ACTIVELIST$,'','','')
* Pop.Select(f1, f2, f3, f4)
IF Get_Status(errCode) THEN
ErrMsg(errCode)
RETURN
END
Done = 0
@ID = ''
LOOP
PrevSchedDetKey = @ID
READNEXT @ID ELSE Done = 1
UNTIL Done
ReactNo = @ID[1,'*']
SchedDt = @ID[COL2()+1,'*']
SeqNo = @ID[COL2()+1,'*']
READ SchedDetRec FROM SchedDetTable,@ID THEN
WONo = SchedDetRec<SCHED_DET_WO_NO$>
LOCATE ReactNo IN ReactList BY 'AR' USING @FM SETTING Pos ELSE
ReactList = INSERT(ReactList,Pos,0,0,ReactNo)
END
PrevReactNo = Field(PrevSchedDetKey, '*', 1)
PrevSchedDt = Field(PrevSchedDetKey, '*', 2)
LOCATE WONo IN WOList<Pos> USING @VM SETTING WPos ELSE
WOList = INSERT(WOList,Pos,-1,0,WONo)
// Patch added on 10/24/18 to resolve scheduling conflicts on the same day for
// the material track report. - djs
If (PrevReactNo EQ ReactNo) and (PrevSchedDt EQ SchedDt) then
PrevSeqNo = Field(PrevSchedDetKey, '*', 3)
NumWO = DCount(WOList<Pos>, @VM)
PrevWONo = WOList<Pos, NumWO - 1>
SchedEvents = Schedule_Services('GetScheduleEventSummary', ReactNo, WONo, SchedDt, SeqNo, True$)
StartDt = IConv(SchedEvents<SCHEDULE_ENTRY_DATE$>, 'D')
PrevSchedEvents = Schedule_Services('GetScheduleEventSummary', ReactNo, PrevWONo, PrevSchedDt, PrevSeqNo, True$)
PrevStartDt = IConv(PrevSchedEvents<SCHEDULE_ENTRY_DATE$>, 'D')
If StartDt GT PrevStartDt then
// This is the common case
SchedDetKeys = INSERT(SchedDetKeys,-1,0,0,@ID)
end else
// Scheduling irregularity - Insert this key in the second to last position.
NumKeys = DCount(SchedDetKeys, @FM)
InsertPos = NumKeys
SchedDetKeys = INSERT(SchedDetKeys,InsertPos,0,0,@ID)
end
end else
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 < 0 THEN
ErrorMsg = 'Stat = ' : Stat : ', PrintPath = ' : PrintPath
GOTO OIPrintErr
end
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 < 0 THEN GOTO OIPrintErr
stat = Set_Printer('HEADER',Header) ; IF stat < 0 THEN GOTO OIPrintErr
Footer = " 'D' 'T'":@VM:@VM:"Page: 'P'"
stat = Set_Printer('FOOTER',Footer) ; IF stat < 0 THEN GOTO OIPrintErr
@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
GoTo ReadRecord
end else
ErrorMsg = 'Unable to open "SCHED_DET" table.'
ErrMsg(ErrorTitle:@SVM:ErrorMsg)
end
end else
ErrorMsg = 'Unable to open "SCHED_DET" table.'
ErrMsg(ErrorTitle:@SVM: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()
MatRep = Database_Services('ReadDataRow', 'SYSLISTS', 'MAT_REPORT')
If Error_Services('NoError') then
MatRepJSON = ''
If SRP_JSON(objJSON, 'New', 'Object') then
If SRP_JSON(objReactArray, 'New', 'Array') then
For each Row in MatRep using @FM setting fPos
KitRunOrder = Row<0, 13>
PTIRunOrder = Row<0, 14>
LoadRunOrder = Row<0, 15>
If KitRunOrder NE '' or PTIRunOrder NE '' or LoadRunOrder NE '' then
If SRP_JSON(objRow, 'New', 'Object') then
SRP_JSON(objRow, 'SetValue', 'reactorNo', Row<0, 1>)
SRP_JSON(objRow, 'SetValue', 'reactorType', Row<0, 2>)
SRP_JSON(objRow, 'SetValue', 'workOrderNo', Row<0, 3>)
SRP_JSON(objRow, 'SetValue', 'sapProdNo', Row<0, 4>)
SRP_JSON(objRow, 'SetValue', 'subPartNo', Row<0, 5>)
SRP_JSON(objRow, 'SetValue', 'epiPartNo', Row<0, 6>)
WOQty = Row<0, 7>
Swap ',' with '' in WOQty
SRP_JSON(objRow, 'SetValue', 'woQty', WOQty)
RxQty = Row<0, 8>
Swap ',' with '' in RxQty
SRP_JSON(objRow, 'SetValue', 'rxQty', RxQty)
UnRelQty = Row<0, 9>
Swap ',' with '' in UnRelQty
SRP_JSON(objRow, 'SetValue', 'unRelQty', UnRelQty)
SRP_JSON(objRow, 'SetValue', 'kitLoc', Row<0, 10>)
KitQty = Row<0, 11>
Swap ',' with '' in KitQty
SRP_JSON(objRow, 'SetValue', 'kitQty', KitQty)
SRP_JSON(objRow, 'SetValue', 'cassDelta', Row<0, 12>)
Swap ',' with ', ' in KitRunOrder
SRP_JSON(objRow, 'SetValue', 'kitRunOrder', KitRunOrder)
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<0, 16>)
SRP_JSON(objReactArray, 'Add', objRow)
SRP_JSON(objRow, 'Release')
end
end
Next Row
SRP_JSON(objJSON, 'Set', 'matReport', objReactArray)
SRP_JSON(objReactArray, 'Release')
end
Response = SRP_JSON(objJSON, 'Stringify', 'Styled')
SRP_JSON(objJSON, 'Release')
end
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
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Internal GoSubs
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ReadRecord:
* 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
IF FirstPass AND LastRecord THEN
GOTO Bail
END
IF LastRecord THEN GOTO BREAKS
READO @RECORD FROM SchedDetTable,@ID ELSE
GOTO ReadRecord
END
@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 = {WO_QTY}
I.WO_Qty = S.WO_Qty
S.WO_RX_Qty = {WO_RX_QTY}
I.WO_RX_Qty = S.WO_RX_Qty
S.WO_UnRel_QTY = {WO_UNREL_QTY}
I.WO_UnRel_QTY = S.WO_UnRel_QTY
S.Sched_DT = {SCHED_DT}
I.Sched_DT = S.Sched_DT
S.REACT_TYPE = {REACTOR_TYPE}
S.ProdOrdNo = {PROD_ORD_NO}
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
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
LoadedData = Location_Services('GetLocationCassInfo', S.WONo, LocQueryList)
Swap CRLF$ with @VM in LoadedData
CassList = LoadedData<3>
For each CassNo in CassList using ','
If ( (S.WONo NE '') and (CassNo NE '') ) then
WOMatKey = S.WONo:'*':CassNo
UnloadSigComp = Signature_Services('CheckSignature', WOMatKey, 'UNLOAD')
If UnloadSigComp then
// Add this cassette to the PTI list instead of the Load list
* PTICassList<0, -1> = CassNo
end else
LoadedCassList<0, -1> = CassNo
end
end
Next CassNo
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=0
GOTO DETAIL
END
BREAKS:
* Print Break Total(s) And Accumulate Total(s)
IF ReactNo.Break THEN stat = Set_Printer('TEXT')
* Perform Last Record Output If Done
IF LastRecord THEN
colData = ''
GOTO Bail
END
DETAIL:
* 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,")
IF S.SCHED_DT NE "" THEN S.SCHED_DT = OCONV(S.SCHED_DT,"D4/")
* 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 '') ) 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 GoSub PrintTable
END
GOTO ReadRecord
Bail:
stat = Set_Printer('TERM',1)
RETURN
OIPrintErr:
ErrMsg(ErrorTitle:@SVM:ErrorMsg)
ErrMsg(ErrorTitle:@SVM:'Set_Printer returned errorcode ':stat)
stat = Set_Printer('TERM',1)
RETURN
PrintTable:
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
RETURN
ClearCursors:
For counter = 0 to 8
ClearSelect counter
Next counter
return