diff --git a/LSL2/STPROC/WO_MAT_ACTIONS.txt b/LSL2/STPROC/WO_MAT_ACTIONS.txt index 5a164dc..7fb1669 100644 --- a/LSL2/STPROC/WO_MAT_ACTIONS.txt +++ b/LSL2/STPROC/WO_MAT_ACTIONS.txt @@ -266,321 +266,371 @@ return WRITE_RECORD_PRE: - WOMatKeyID = Name - OrigRDSNo = OrigRecord - NewRDSNo = Record + WOMatKeyID = Name + OrigRDSNo = OrigRecord + NewRDSNo = Record + OrigLotNo = OrigRecord + NewLotNo = Record + OrigWfrQty = OrigRecord + NewWfrQty = Record + OrigCustPartNo = OrigRecord + NewCustPartNo = Record + OrigSubPartNo = OrigRecord + NewSubPartNo = Record + OrigInvActions = OrigRecord + OrigNumActions = DCount(OrigInvActions, @VM) + NewInvActions = Record + NewNumActions = DCount(NewInvActions, @VM) + OrigSlotNos = OrigRecord + OrigNumSlotNos = DCount(OrigSlotNos, @VM) + NewSlotNos = Record + NewNumSlotNos = DCount(NewSlotNos, @VM) + OrigRxDtm = OrigRecord + NewRxDtm = Record + OrigRxBy = OrigRecord + NewRxBy = Record + OrigRelDtm = OrigRecord + NewRelDtm = Record + OrigRelBy = OrigRecord + NewRelBy = Record + OrigSubVendCd = OrigRecord + NewSubVendCd = Record + OrigCassShipQty = OrigRecord + NewCassShipQty = Record + OrigShipShort = OrigRecord + NewShipShort = Record + OrigMuWaferFlag = OrigRecord + NewMuWaferFlag = Record - If OrigRDSNo NE '' and NewRDSNo EQ '' and Not(MemberOf(@User4, 'OI_ADMIN')) then - - Record = OrigRDSNo - SaveRecord = Record - LogData = '' - LogData<1> = LoggingDTM - LogData<2> = @USER4 - LogData<3> = OrigRDSNo - LogData<4> = WOMatKeyID - If OrigRDSNo NE '' then - LogData<5> = Xlate('RDS', OrigRDSNo, 'WO_MAT_KEY', 'X') - end else - LogData<5> = '' - end - LogData<6> = 'RDS number cannot be removed. Setting RDS number back.' - Machine = Environment_Services('GetServer') - Logging_Services('AppendLog', ObjLog3, LogData, @RM, @FM, False$) + If ( ( (OrigRDSNo NE '') and (NewRDSNo EQ '') ) or ( (OrigLotNo NE '') and (NewLotNo EQ '') ) | + or ( (OrigWfrQty NE '') and (NewWfrQty EQ '') ) or ( (OrigCustPartNo NE '') and (NewCustPartNo EQ '') ) | + or ( (OrigSubPartNo NE '') and (NewSubPartNo EQ '') ) or (OrigNumActions GT NewNumActions) | + or (OrigNumSlotNos GT NewNumSlotNos) or ( (OrigRxDtm NE '') and (NewRxDtm EQ '') ) | + or ( (OrigRxBy NE '') and (NewRxBy EQ '') ) or ( (OrigRelDtm NE '') and (NewRelDtm EQ '') ) | + or ( (OrigRelBy NE '') and (NewRelBy EQ '') ) or ( (OrigSubVendCd NE '') and (NewSubVendCd EQ '') ) | + or ( (OrigCassShipQty NE '') and (NewCassShipQty EQ '') ) or ( (OrigShipShort NE '') and (NewShipShort EQ '') ) | + or ( (OrigMuWaferFlag NE '') and (NewMuWaferFlag EQ '') ) ) then + + Stack = Error_Services('GetStackTrace') + Recipients = '' + SentFrom = 'SYSTEM' + Subject = 'WO_MAT_ACTIONS WRITE_PRE Blocked' + Message = OConv(Datetime(), 'DT2/^H') + Message<2> = 'Computer: ':@Station + Message<3> = 'User: ':@User4 + Message<4> = 'WO_MAT key: ':Name + Message<5> = 'Message: Write operation failed due to readonly field being cleared.' + Message<6> = Stack + Swap @FM with \0D0A\ in Message + Swap @VM with ',' in Message + AttachWindow = 'WO_MAT' + AttachKey = Name + SendToGroup = 'OI_SYSADMIN' - end + Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup + obj_Notes('Create',Parms) + + OrigFileError = 104:': Write operation failed due to readonly field being cleared.' + Status = 0 + Record = '' + ActionFlow = ACTION_STOP$ + + end else - WaferQty = Record - If ( (WaferQty LT 0) or (WaferQty GT 25) ) then - // Erroneous wafer quantity save attempt. Fallback to default wafer quantity of 25. - Record = 25 - SaveRecord = Record - end - - If ({REACTOR_TYPE} EQ 'GAN') and ({FQA_DTM} NE {CASS_FINAL_SIG_DTM}) then - // Copy FQA date and datetime - DTM = {CASS_FINAL_SIG_DTM} - {FQA_DTM} = DTM - Date = {CASS_FINAL_SIG_DTM}[1, 'F.'] - {FQA_DT} = Date - SaveRecord = @Record - end - - // Sync up NCR signatures - NewNCRList = Record - OrigNCRList = OrigRecord - NewNCRSigs = Record - NewNCRSigDTMs = Record + WaferQty = Record + If ( (WaferQty LT 0) or (WaferQty GT 25) ) then + // Erroneous wafer quantity save attempt. Fallback to default wafer quantity of 25. + Record = 25 + SaveRecord = Record + end + + If ({REACTOR_TYPE} EQ 'GAN') and ({FQA_DTM} NE {CASS_FINAL_SIG_DTM}) then + // Copy FQA date and datetime + DTM = {CASS_FINAL_SIG_DTM} + {FQA_DTM} = DTM + Date = {CASS_FINAL_SIG_DTM}[1, 'F.'] + {FQA_DT} = Date + SaveRecord = @Record + end + + // Sync up NCR signatures + NewNCRList = Record + OrigNCRList = OrigRecord + NewNCRSigs = Record + NewNCRSigDTMs = Record - // Check for deleted NCRs to remove final NCR signatures as needed. - For each OrigNCRNo in OrigNCRList using @VM setting vPos - NewNCRNo = NewNCRList<0, vPos> - If NewNCRNo EQ '' then - // An NCR has been deleted so we need to remove any final NCR signatures associate with it. - NewNCRSigs<0, vPos> = '' - NewNCRSigDTMs<0, vPos> = '' - end - Next OrigNCRNo - - // Check for new NCRs to copy their final signature to the WO_MAT record. - For each NewNCRNo in NewNCRList using @VM setting vPos - // This is a new NCR, so copy the signature. - NewNCRSigs<0, vPos> = Xlate('NCR', NewNCRNo, 'AUTH_SHIP_SIG', 'X') - NewNCRSigDTMs<0, vPos> = Xlate('NCR', NewNCRNo, 'AUTH_SHIP_SIG_DTM', 'X') - Next NewNCRNo - - // Trim trailing @VMs to avoid WO_MAT CURR_STATUS from erroneously calculating an open NCR is present. - NewNCRSigs = SRP_Array('Clean', NewNCRSigs, 'Trim', @VM) - NewNCRSigDTMs = SRP_Array('Clean', NewNCRSigDTMs, 'Trim', @VM) - Record = NewNCRSigs - Record = NewNCRSigDTMs - SaveRecord = Record - - WONo = Field(Name, '*', 1) - ReactType = Xlate('WO_LOG', WONo, 'REACT_TYPE', 'X') - GaN = (ReactType EQ 'GAN') - If GaN then - // Sync QA signature with WO_MAT signature profile. - OrigCassFinalSig = OrigRecord - OrigCassFinalSigDTM = OrigRecord - CassFinalSig = Record - CassFinalSigDTM = Record - - If ( (OrigCassFinalSig NE CassFinalSig) or (OrigCassFinalSigDTM NE CassFinalSigDTM) ) then - WOMatStage = '1G_FQA' - SigProf = Record - Sigs = Record - SigDTMs = Record - Locate WOMatStage in SigProf using @VM setting vPos then - Sigs<0, vPos> = CassFinalSig - SigDTMs<0, vPos> = CassFinalSigDTM - Record = Sigs - Record = SigDTMs - SaveRecord = Record - end - end - end - - Begin Case - Case {REACTOR_TYPE} EQ 'EPP' - // EpiPro Silicon - Populate OUT_SLOT_NCR column in WO_MAT record - NCRKeyChange = (OrigRecord NE Record) - NCRSlotChange = (OrigRecord NE Record) - WOMatSlotNCRs = {EPOS_NCR} - NCRKeys = {NCR_KEYS} - ChangeDetected = (NCRKeyChange or NCRSlotChange) - If ChangeDetected then - For each NCRKey in NCRKeys using @VM setting vPos - OutSlotNos = Xlate('NCR', NCRKey, 'OUT_SLOT_NO', 'X') - If OutSlotNos NE '' then - For each SlotNo in OutSlotNos using @VM setting sPos - WOMatSlotNCRs<0, SlotNo> = NCRKey - Next SlotNo - end - Next NCRKey - // Pad value marks if necessary - NumSlots = DCount(WOMatSlotNCRs, @VM) - If NumSlots LT 25 then WOMatSlotNCRs<0, 25> = '' - Record = WOMatSlotNCRs - SaveRecord = Record - end - Case {REACTOR_TYPE} EQ 'GAN' - // Galiumn Nitride - Currently no issues with NCR keys getting erased, so nothing to do here. - Null - Case Otherwise$ - // Non-EpiPro Silicon - Populate SLOT_NCR column in WO_MAT record - NCRKeyChange = (OrigRecord NE Record) - NCRSlotChange = (OrigRecord NE Record) - ChangeDetected = (NCRKeyChange or NCRSlotChange) - If ChangeDetected then - SlotNCRs = {SLOT_NCR} - NCRKeys = {NCR_KEYS} - For each NCRKey in NCRKeys using @VM setting vPos - NCRSlotNos = Xlate('NCR', NCRKey, 'SLOT_NO', 'X') - If NCRSlotNos NE '' then - For each SlotNo in NCRSlotNos using @VM setting Dummy - SlotNCRs<0, SlotNo> = NCRKey - Next SlotNo - end - Next NCRKey - Record = SlotNCRs - SaveRecord = Record - end - NewMUFlag = Record - OrigMUFlag = OrigRecord - UnloadCheck = Signature_Services('GetStageSummary', WOMatKeyID, 'UNLOAD')<2> - If (NewMUFlag EQ True$) AND (OrigMUFlag NE True$) then - If UnloadCheck NE True$ then - OrigFileError = 104:': Cassette ineligible to be converted to makeup wafer until unload is signed.' - Status = 0 - Record = '' - ActionFlow = ACTION_STOP$ - end - end - - End Case - - TWChangeDetected = (OrigRecord NE Record) - If TWChangeDetected then - Begin Case - Case {REACTOR_TYPE} EQ 'EPP' - // EpiPro silicon -> build list of RDS_TEST keys and select those with TW_USE key(s). - RDSNos = Xlate('WM_IN', {WMI_KEY}, 'RDS_NO', 'X') - RDSNos = SRP_Array('Clean', RDSNos, 'TrimAndMakeUnique', @VM) - If RDSNos NE '' then - Query = 'SELECT RDS_TEST ' - For each RDSNo in RDSNos using @VM setting vPos - If vPos EQ 1 then - Query := 'WITH RDS_NO EQ ':RDSNo:' ' - end else - Query := 'OR WITH RDS_NO EQ ':RDSNo:' ' - end - Next RDSNo - EOF = False$ - RecordCopy = Record - RList(Query, TARGET_LATENTLIST$, '', '', '') - Query = 'SELECT RDS_TEST WITH TW_USE_ID NE ""' - RList(Query, TARGET_LATENTLIST$, '', '', '') - RDSTestKeys = '' - Loop - ReadNext KeyID else EOF = True$ - Until EOF - RDSTestKeys<0, -1> = KeyID - Repeat - TWUseKeys = Xlate('RDS_TEST', RDSTestKeys, 'TW_USE_ID', 'X') - WaferIDs = Xlate('TW_USE', TWUseKeys, 'WAFER_ID', 'X') - SlotMetNos = '' - For each WaferID in WaferIDs using @VM setting vPos - SlotNo = Field(WaferID, '*', 3) - SlotMetNos<0, SlotNo> = TWUseKeys<0, vPos> - Next WaferID - Done = False$ - NumVMs = DCount(SlotMetNos, @VM) - // Pad column with @VMs - If NumVMs LT 25 then SlotMetNos<0, 25> = '' - Record = RecordCopy - Record = SlotMetNos - SaveRecord = Record - end - Case {REACTOR_TYPE} EQ 'GAN' - // Gallium nitride -> TW_USE records do not apply, so nothing to do. - Null - Case Otherwise$ - - // Non-EpiPro silicon -> lookup RDS_TEST record and interrogate it for TW_USE key(s). - RDSNo = Record - If RDSNo NE '' then - Query = 'SELECT RDS_TEST WITH RDS_NO EQ ':RDSNo - EOF = False$ - RecordCopy = Record - RList(Query, TARGET_LATENTLIST$, '', '', '') - Query = 'SELECT RDS_TEST WITH TW_USE_ID NE ""' - RList(Query, TARGET_LATENTLIST$, '', '', '') - RDSTestKeys = '' - Loop - ReadNext KeyID else EOF = True$ - Until EOF - RDSTestKeys<0, -1> = KeyID - Repeat - TWUseKeys = Xlate('RDS_TEST', RDSTestKeys, 'TW_USE_ID', 'X') - // Rebuild list - SlotMetNos = '' - For each TWUseKey in TWUseKeys using @VM setting tPos - WaferIDs = Xlate('TW_USE', TWUseKey, 'WAFER_ID', 'X') - For each WaferID in WaferIDs using @VM setting vPos - SlotNo = Field(WaferID, '*', 3) - SlotMetNos<0, SlotNo> = TWUseKey - Next WaferID - Next TWUseKey - NumVMs = DCount(SlotMetNos, @VM) - // Pad column with @VMs - If NumVMs LT 25 then SlotMetNos<0, 25> = '' - Record = RecordCopy - Record = SlotMetNos - SaveRecord = Record - end - - End Case - end - - // Verify slot list does not exceed 25 - NewSlotList = Record - NumSlots = DCount(NewSlotList, @VM) - LastSlot = NewSlotList[-1, 'B':@VM] - If ( (NumSlots GT 25) or (LastSlot GT 25) ) then - - LogCount = Max(NumSlots, LastSlot) - // Correct the slot column - NewSlotList = '' - For Slot = 1 to 25 - NewSlotList<0, Slot> = Slot - Next Slot - Record = NewSlotList - SaveRecord = Record - - // Log the error - Stack = RetStack() - Swap @FM with CRLF$ in Stack - LogData = '' - LogData<1> = LoggingDTM - LogData<2> = @User4 - LogData<3> = Name - LogData<4> = LogCount - LogData<5> = CRLF$:Stack - Logging_Services('AppendLog', objSlotLog, LogData, @RM, @FM) - - // Send internal LSL message to OI admins - Recipients = XLATE('SEC_GROUPS', 'OI_ADMIN', 'USER', 'X') - SentFrom = @USER4 - Subject = 'Slot count exceeds 25!' - Message = 'WO_MAT key ':Name - AttachWindow = 'WO_MAT' - AttachKey = Name - SendToGroup = '' - Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup - obj_Notes('Create',Parms) - end - - If {REACTOR_TYPE} EQ 'EPP' then - WMKey = Field(Name, '*', 1):'*1*':Field(Name, '*', 2) - // Only set fields if the records exist, otherwise WO_MAT curr status can be calculated incorrectly. - If RowExists('WM_IN', WMKey) then Record = WMKey - If RowExists('WM_OUT', WMKey) then Record = WMKey - SaveRecord = Record - end - - SigProf = Record - Sigs = Record - SigDtms = Record - NumSteps = DCount(SigProf, @VM) - Record = Field(Sigs, @VM, 1, NumSteps) - Record = Field(SigDtms, @VM, 1, NumSteps) - SaveRecord = Record - - NewMUFlag = Record - OrigMUFlag = OrigRecord - If NewMUFlag NE OrigMUFlag then - SAPBatchNo = Record - SAPTXDtm = Record - AwaitingBatchNo = ( (SAPTXDtm NE '') and (SAPBatchNo EQ '') ) - FullBoxReject = (SAPBatchNo[-1, 1] = 'R') + // Check for deleted NCRs to remove final NCR signatures as needed. + For each OrigNCRNo in OrigNCRList using @VM setting vPos + NewNCRNo = NewNCRList<0, vPos> + If NewNCRNo EQ '' then + // An NCR has been deleted so we need to remove any final NCR signatures associate with it. + NewNCRSigs<0, vPos> = '' + NewNCRSigDTMs<0, vPos> = '' + end + Next OrigNCRNo + + // Check for new NCRs to copy their final signature to the WO_MAT record. + For each NewNCRNo in NewNCRList using @VM setting vPos + // This is a new NCR, so copy the signature. + NewNCRSigs<0, vPos> = Xlate('NCR', NewNCRNo, 'AUTH_SHIP_SIG', 'X') + NewNCRSigDTMs<0, vPos> = Xlate('NCR', NewNCRNo, 'AUTH_SHIP_SIG_DTM', 'X') + Next NewNCRNo + + // Trim trailing @VMs to avoid WO_MAT CURR_STATUS from erroneously calculating an open NCR is present. + NewNCRSigs = SRP_Array('Clean', NewNCRSigs, 'Trim', @VM) + NewNCRSigDTMs = SRP_Array('Clean', NewNCRSigDTMs, 'Trim', @VM) + Record = NewNCRSigs + Record = NewNCRSigDTMs + SaveRecord = Record + + WONo = Field(Name, '*', 1) + ReactType = Xlate('WO_LOG', WONo, 'REACT_TYPE', 'X') + GaN = (ReactType EQ 'GAN') + If GaN then + // Sync QA signature with WO_MAT signature profile. + OrigCassFinalSig = OrigRecord + OrigCassFinalSigDTM = OrigRecord + CassFinalSig = Record + CassFinalSigDTM = Record + + If ( (OrigCassFinalSig NE CassFinalSig) or (OrigCassFinalSigDTM NE CassFinalSigDTM) ) then + WOMatStage = '1G_FQA' + SigProf = Record + Sigs = Record + SigDTMs = Record + Locate WOMatStage in SigProf using @VM setting vPos then + Sigs<0, vPos> = CassFinalSig + SigDTMs<0, vPos> = CassFinalSigDTM + Record = Sigs + Record = SigDTMs + SaveRecord = Record + end + end + end + Begin Case - Case AwaitingBatchNo - Error_Services('Add', 'Cassette ineligible to be converted as it is awaiting a batch number from SAP.') - OrigFileError = 104:': Cassette ineligible to be converted as it is awaiting a batch number from SAP.' - Status = 0 - Record = '' - ActionFlow = ACTION_STOP$ - Case FullBoxReject - Error_Services('Add', 'Cassette ineligible to be converted as it is a full box reject.') - OrigFileError = 104:': Cassette ineligible to be converted as it is a full box reject.' - Status = 0 - Record = '' - ActionFlow = ACTION_STOP$ - Case Otherwise$ + Case {REACTOR_TYPE} EQ 'EPP' + // EpiPro Silicon - Populate OUT_SLOT_NCR column in WO_MAT record + NCRKeyChange = (OrigRecord NE Record) + NCRSlotChange = (OrigRecord NE Record) + WOMatSlotNCRs = {EPOS_NCR} + NCRKeys = {NCR_KEYS} + ChangeDetected = (NCRKeyChange or NCRSlotChange) + If ChangeDetected then + For each NCRKey in NCRKeys using @VM setting vPos + OutSlotNos = Xlate('NCR', NCRKey, 'OUT_SLOT_NO', 'X') + If OutSlotNos NE '' then + For each SlotNo in OutSlotNos using @VM setting sPos + WOMatSlotNCRs<0, SlotNo> = NCRKey + Next SlotNo + end + Next NCRKey + // Pad value marks if necessary + NumSlots = DCount(WOMatSlotNCRs, @VM) + If NumSlots LT 25 then WOMatSlotNCRs<0, 25> = '' + Record = WOMatSlotNCRs + SaveRecord = Record + end + Case {REACTOR_TYPE} EQ 'GAN' + // Galiumn Nitride - Currently no issues with NCR keys getting erased, so nothing to do here. Null + Case Otherwise$ + // Non-EpiPro Silicon - Populate SLOT_NCR column in WO_MAT record + NCRKeyChange = (OrigRecord NE Record) + NCRSlotChange = (OrigRecord NE Record) + ChangeDetected = (NCRKeyChange or NCRSlotChange) + If ChangeDetected then + SlotNCRs = {SLOT_NCR} + NCRKeys = {NCR_KEYS} + For each NCRKey in NCRKeys using @VM setting vPos + NCRSlotNos = Xlate('NCR', NCRKey, 'SLOT_NO', 'X') + If NCRSlotNos NE '' then + For each SlotNo in NCRSlotNos using @VM setting Dummy + SlotNCRs<0, SlotNo> = NCRKey + Next SlotNo + end + Next NCRKey + Record = SlotNCRs + SaveRecord = Record + end + NewMUFlag = Record + OrigMUFlag = OrigRecord + UnloadCheck = Signature_Services('GetStageSummary', WOMatKeyID, 'UNLOAD')<2> + If (NewMUFlag EQ True$) AND (OrigMUFlag NE True$) then + If UnloadCheck NE True$ then + OrigFileError = 104:': Cassette ineligible to be converted to makeup wafer until unload is signed.' + Status = 0 + Record = '' + ActionFlow = ACTION_STOP$ + end + end + End Case + + TWChangeDetected = (OrigRecord NE Record) + If TWChangeDetected then + Begin Case + Case {REACTOR_TYPE} EQ 'EPP' + // EpiPro silicon -> build list of RDS_TEST keys and select those with TW_USE key(s). + RDSNos = Xlate('WM_IN', {WMI_KEY}, 'RDS_NO', 'X') + RDSNos = SRP_Array('Clean', RDSNos, 'TrimAndMakeUnique', @VM) + If RDSNos NE '' then + Query = 'SELECT RDS_TEST ' + For each RDSNo in RDSNos using @VM setting vPos + If vPos EQ 1 then + Query := 'WITH RDS_NO EQ ':RDSNo:' ' + end else + Query := 'OR WITH RDS_NO EQ ':RDSNo:' ' + end + Next RDSNo + EOF = False$ + RecordCopy = Record + RList(Query, TARGET_LATENTLIST$, '', '', '') + Query = 'SELECT RDS_TEST WITH TW_USE_ID NE ""' + RList(Query, TARGET_LATENTLIST$, '', '', '') + RDSTestKeys = '' + Loop + ReadNext KeyID else EOF = True$ + Until EOF + RDSTestKeys<0, -1> = KeyID + Repeat + TWUseKeys = Xlate('RDS_TEST', RDSTestKeys, 'TW_USE_ID', 'X') + WaferIDs = Xlate('TW_USE', TWUseKeys, 'WAFER_ID', 'X') + SlotMetNos = '' + For each WaferID in WaferIDs using @VM setting vPos + SlotNo = Field(WaferID, '*', 3) + SlotMetNos<0, SlotNo> = TWUseKeys<0, vPos> + Next WaferID + Done = False$ + NumVMs = DCount(SlotMetNos, @VM) + // Pad column with @VMs + If NumVMs LT 25 then SlotMetNos<0, 25> = '' + Record = RecordCopy + Record = SlotMetNos + SaveRecord = Record + end + Case {REACTOR_TYPE} EQ 'GAN' + // Gallium nitride -> TW_USE records do not apply, so nothing to do. + Null + Case Otherwise$ + + // Non-EpiPro silicon -> lookup RDS_TEST record and interrogate it for TW_USE key(s). + RDSNo = Record + If RDSNo NE '' then + Query = 'SELECT RDS_TEST WITH RDS_NO EQ ':RDSNo + EOF = False$ + RecordCopy = Record + RList(Query, TARGET_LATENTLIST$, '', '', '') + Query = 'SELECT RDS_TEST WITH TW_USE_ID NE ""' + RList(Query, TARGET_LATENTLIST$, '', '', '') + RDSTestKeys = '' + Loop + ReadNext KeyID else EOF = True$ + Until EOF + RDSTestKeys<0, -1> = KeyID + Repeat + TWUseKeys = Xlate('RDS_TEST', RDSTestKeys, 'TW_USE_ID', 'X') + // Rebuild list + SlotMetNos = '' + For each TWUseKey in TWUseKeys using @VM setting tPos + WaferIDs = Xlate('TW_USE', TWUseKey, 'WAFER_ID', 'X') + For each WaferID in WaferIDs using @VM setting vPos + SlotNo = Field(WaferID, '*', 3) + SlotMetNos<0, SlotNo> = TWUseKey + Next WaferID + Next TWUseKey + NumVMs = DCount(SlotMetNos, @VM) + // Pad column with @VMs + If NumVMs LT 25 then SlotMetNos<0, 25> = '' + Record = RecordCopy + Record = SlotMetNos + SaveRecord = Record + end + + End Case + end + + // Verify slot list does not exceed 25 + NewSlotList = Record + NumSlots = DCount(NewSlotList, @VM) + LastSlot = NewSlotList[-1, 'B':@VM] + If ( (NumSlots GT 25) or (LastSlot GT 25) ) then + + LogCount = Max(NumSlots, LastSlot) + // Correct the slot column + NewSlotList = '' + For Slot = 1 to 25 + NewSlotList<0, Slot> = Slot + Next Slot + Record = NewSlotList + SaveRecord = Record + + // Log the error + Stack = RetStack() + Swap @FM with CRLF$ in Stack + LogData = '' + LogData<1> = LoggingDTM + LogData<2> = @User4 + LogData<3> = Name + LogData<4> = LogCount + LogData<5> = CRLF$:Stack + Logging_Services('AppendLog', objSlotLog, LogData, @RM, @FM) + + // Send internal LSL message to OI admins + Recipients = XLATE('SEC_GROUPS', 'OI_ADMIN', 'USER', 'X') + SentFrom = @USER4 + Subject = 'Slot count exceeds 25!' + Message = 'WO_MAT key ':Name + AttachWindow = 'WO_MAT' + AttachKey = Name + SendToGroup = '' + Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup + obj_Notes('Create',Parms) + end + + If {REACTOR_TYPE} EQ 'EPP' then + WMKey = Field(Name, '*', 1):'*1*':Field(Name, '*', 2) + // Only set fields if the records exist, otherwise WO_MAT curr status can be calculated incorrectly. + If RowExists('WM_IN', WMKey) then Record = WMKey + If RowExists('WM_OUT', WMKey) then Record = WMKey + SaveRecord = Record + end + + SigProf = Record + Sigs = Record + SigDtms = Record + NumSteps = DCount(SigProf, @VM) + Record = Field(Sigs, @VM, 1, NumSteps) + Record = Field(SigDtms, @VM, 1, NumSteps) + SaveRecord = Record + + NewMUFlag = Record + OrigMUFlag = OrigRecord + If NewMUFlag NE OrigMUFlag then + SAPBatchNo = Record + SAPTXDtm = Record + AwaitingBatchNo = ( (SAPTXDtm NE '') and (SAPBatchNo EQ '') ) + FullBoxReject = (SAPBatchNo[-1, 1] = 'R') + Begin Case + Case AwaitingBatchNo + Error_Services('Add', 'Cassette ineligible to be converted as it is awaiting a batch number from SAP.') + OrigFileError = 104:': Cassette ineligible to be converted as it is awaiting a batch number from SAP.' + Status = 0 + Record = '' + ActionFlow = ACTION_STOP$ + Case FullBoxReject + Error_Services('Add', 'Cassette ineligible to be converted as it is a full box reject.') + OrigFileError = 104:': Cassette ineligible to be converted as it is a full box reject.' + Status = 0 + Record = '' + ActionFlow = ACTION_STOP$ + Case Otherwise$ + Null + End Case + end + end + return @@ -902,3 +952,4 @@ Restore_System_Variables: return +