open-insight/LSL2/STPROC/REPORT_SERVICES.txt
2025-01-30 23:22:05 +01:00

2355 lines
92 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
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, '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 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 WO_NO'
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'
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.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
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_TRACK', 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'
end else
SelectSent = 'SELECT SCHED_DET_NG WITH STOP_DTM GE "':OCONV(Today, 'DT'):'" BY REACT_NO'
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
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 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