From 30bd03049a73546eda2bbc5c88800edf04b22839 Mon Sep 17 00:00:00 2001 From: "Infineon\\StieberD" Date: Thu, 13 Feb 2025 12:50:12 -0700 Subject: [PATCH] fixed bug in mu auto hold system --- LSL2/STPROC/MAKEUP_WAFERS_ACTIONS.txt | 410 +++++++++++++------------- LSL2/STPROC/MATERIAL_SERVICES.txt | 87 +++--- 2 files changed, 251 insertions(+), 246 deletions(-) diff --git a/LSL2/STPROC/MAKEUP_WAFERS_ACTIONS.txt b/LSL2/STPROC/MAKEUP_WAFERS_ACTIONS.txt index 67ff34a..9bfc1e7 100644 --- a/LSL2/STPROC/MAKEUP_WAFERS_ACTIONS.txt +++ b/LSL2/STPROC/MAKEUP_WAFERS_ACTIONS.txt @@ -1,206 +1,204 @@ -Function MAKEUP_WAFERS_Actions(Action, CalcColName, FSList, Handle, Name, FMC, Record, Status, OrigRecord, Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10) -#pragma precomp SRP_PreCompiler - -/*********************************************************************************************************************** - - This program is proprietary and is not to be used by or disclosed to others, nor is it to be copied without written - permission from Infineon. - - Name : Makeup_Wafers_Actions - - Description : Handles calculated columns and MFS calls for the current table. - - Notes : This function uses @ID, @RECORD, and @DICT to make sure {ColumnName} references work correctly. - If called from outside of a calculated column these will need to be set and restored. - - Parameters : - Action [in] -- Name of the action to be taken - CalcColName [in] -- Name of the calculated column that needs to be processed. Normally this should only be - populated when the CalcField action is being used. - FSList [in] -- The list of MFSs and the BFS name for the current file or volume. This is an @SVM - delimited array, with the current MFS name as the first value in the array, and the BFS - name as the last value. Normally set by a calling MFS. - Handle [in] -- The file handle of the file or media map being accessed. Note, this does contain the - entire handle structure that the Basic+ Open statement would provide. Normally set by a - calling MFS. - Name [in] -- The name (key) of the record or file being accessed. Normally set by a calling MFS. - FMC [in] -- Various functions. Normally set by a calling MFS. - Record [in] -- The entire record (for record-oriented functions) or a newly-created handle (for - "get handle" functions). Normally set by a calling MFS. - Status [in/out] -- Indicator of the success or failure of an action. Normally set by the calling MFS but - for some actions can be set by the action handler to indicate failure. - OrigRecord [in] -- Original content of the record being processed by the current action. This is - automatically being assigned by the WRITE_RECORD and DELETE_RECORD actions within - BASE_MFS. - Param1-10 [in/out] -- Additional request parameter holders - ActionFlow [out] -- Used to control the action chain (see the ACTION_SETUP insert for more information.) - Can also be used to return a special value, such as the results of the CalcField - method. - - History : (Date, Initials, Notes) - 07/09/24 djs Original programmer. - -***********************************************************************************************************************/ - -$insert APP_INSERTS -$insert FILE.SYSTEM.EQUATES -$insert ACTION_SETUP -$insert MAKEUP_WAFERS_EQUATES - -Declare function SRP_Date - -If KeyID then GoSub Initialize_System_Variables - -Begin Case - - Case Action _EQC 'CalculateColumn' ; GoSub CalculateColumn - Case Action _EQC 'READ_RECORD_PRE' ; GoSub READ_RECORD_PRE - Case Action _EQC 'READ_RECORD' ; GoSub READ_RECORD - Case Action _EQC 'READONLY_RECORD_PRE' ; GoSub READONLY_RECORD_PRE - Case Action _EQC 'READONLY_RECORD' ; GoSub READONLY_RECORD - Case Action _EQC 'WRITE_RECORD_PRE' ; GoSub WRITE_RECORD_PRE - Case Action _EQC 'WRITE_RECORD' ; GoSub WRITE_RECORD - Case Action _EQC 'DELETE_RECORD_PRE' ; GoSub DELETE_RECORD_PRE - Case Action _EQC 'DELETE_RECORD' ; GoSub DELETE_RECORD - Case Otherwise$ ; Status = 'Invalid Action' - -End Case - -If KeyID then GoSub Restore_System_Variables - -If Assigned(ActionFlow) else ActionFlow = ACTION_CONTINUE$ - -Return ActionFlow - - -// ----- Calculated Columns -------------------------------------------------------------------------------------------- -// -// The typical structure of a calculated column will look like this: -// -// Declare function TableName_Actions -// -// A = {COL1} ; * Reference as many data columns in this way to ensure the dictionary dependency is generated. -// -// @ANS = TableName_Actions('CalcField', 'CalcColName') -// -// --------------------------------------------------------------------------------------------------------------------- - -CalculateColumn: - - // Make sure the ActionFlow return variable is cleared in case nothing is calculated. - ActionFlow = '' - - Begin Case - Case CalcColName EQ 'EXAMPLE' ; GoSub EXAMPLE - End Case - -return - - -EXAMPLE: - - ActionFlow = '' - -return - - -// ----- MFS calls ----------------------------------------------------------------------------------------------------- - -READ_RECORD_PRE: - // In order to stop a record from being read in this action these lines of code must be used: - // - // OrigFileError = 100 : @FM : KeyID - // Status = 0 - // Record = '' - // ActionFlow = ACTION_STOP$ -return - - -READ_RECORD: - // In order to stop a record from being read in this action these lines of code must be used: - // - // OrigFileError = 100 : @FM : KeyID - // Status = 0 - // Record = '' -return - -READONLY_RECORD_PRE: - // In order to stop a record from being read in this action these lines of code must be used: - // - // OrigFileError = 100 : @FM : KeyID - // Status = 0 - // Record = '' - // ActionFlow = ACTION_STOP$ -return - -READONLY_RECORD: - // In order to stop a record from being read in this action these lines of code must be used: - // - // OrigFileError = 100 : @FM : KeyID - // Status = 0 - // Record = '' -return - -WRITE_RECORD_PRE: - - SaveRecord = ( {UNLOAD_DTM} LT SRP_Date('AddYears', Date(), -3) ) - -return - -WRITE_RECORD: -return - -DELETE_RECORD_PRE: -return - -DELETE_RECORD: -return - - -// ----- Internal Methods ---------------------------------------------------------------------------------------------- - -Initialize_System_Variables: - // Save these for restoration later - SaveDict = @DICT - SaveID = @ID - SaveRecord = @RECORD - OrigFileError = @FILE.ERROR - - // Now make sure @DICT, ID, and @RECORD are populated - CurrentDictName = '' - If @DICT then - DictHandle = @DICT<1, 2> - Locate DictHandle in @TABLES(5) Using @FM Setting fPos then - CurrentDictName = Field(@TABLES(0), @FM, fPos, 1) - end - end - - If CurrentDictName NE DictName then - Open DictName to @DICT else Status = 'Unable to initialize @DICT' - end - - @ID = KeyID - If Record else - // Record might not have been passed in. Read the record from the database table just to make sure. - @FILE.ERROR = '' - Open TableName to hTable then - FullFSList = hTable[1, 'F' : @VM] - BFS = FullFSList[-1, 'B' : @SVM] - LastHandle = hTable[-1, 'B' : \0D\] - FileHandle = \0D\ : LastHandle[1, @VM] - - Call @BFS(READO.RECORD, BFS, FileHandle, KeyID, FMC, Record, ReadOStatus) - end - end - @RECORD = Record -return - -Restore_System_Variables: - Transfer SaveDict to @DICT - Transfer SaveID to @ID - Transfer SaveRecord to @RECORD - @FILE.ERROR = OrigFileError -return - - - +Function MAKEUP_WAFERS_Actions(Action, CalcColName, FSList, Handle, Name, FMC, Record, Status, OrigRecord, Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10) +#pragma precomp SRP_PreCompiler + +/*********************************************************************************************************************** + + This program is proprietary and is not to be used by or disclosed to others, nor is it to be copied without written + permission from Infineon. + + Name : Makeup_Wafers_Actions + + Description : Handles calculated columns and MFS calls for the current table. + + Notes : This function uses @ID, @RECORD, and @DICT to make sure {ColumnName} references work correctly. + If called from outside of a calculated column these will need to be set and restored. + + Parameters : + Action [in] -- Name of the action to be taken + CalcColName [in] -- Name of the calculated column that needs to be processed. Normally this should only be + populated when the CalcField action is being used. + FSList [in] -- The list of MFSs and the BFS name for the current file or volume. This is an @SVM + delimited array, with the current MFS name as the first value in the array, and the BFS + name as the last value. Normally set by a calling MFS. + Handle [in] -- The file handle of the file or media map being accessed. Note, this does contain the + entire handle structure that the Basic+ Open statement would provide. Normally set by a + calling MFS. + Name [in] -- The name (key) of the record or file being accessed. Normally set by a calling MFS. + FMC [in] -- Various functions. Normally set by a calling MFS. + Record [in] -- The entire record (for record-oriented functions) or a newly-created handle (for + "get handle" functions). Normally set by a calling MFS. + Status [in/out] -- Indicator of the success or failure of an action. Normally set by the calling MFS but + for some actions can be set by the action handler to indicate failure. + OrigRecord [in] -- Original content of the record being processed by the current action. This is + automatically being assigned by the WRITE_RECORD and DELETE_RECORD actions within + BASE_MFS. + Param1-10 [in/out] -- Additional request parameter holders + ActionFlow [out] -- Used to control the action chain (see the ACTION_SETUP insert for more information.) + Can also be used to return a special value, such as the results of the CalcField + method. + + History : (Date, Initials, Notes) + 07/09/24 djs Original programmer. + +***********************************************************************************************************************/ + +$insert APP_INSERTS +$insert FILE.SYSTEM.EQUATES +$insert ACTION_SETUP +$insert MAKEUP_WAFERS_EQUATES + +Declare function SRP_Date + +If KeyID then GoSub Initialize_System_Variables + +Begin Case + + Case Action _EQC 'CalculateColumn' ; GoSub CalculateColumn + Case Action _EQC 'READ_RECORD_PRE' ; GoSub READ_RECORD_PRE + Case Action _EQC 'READ_RECORD' ; GoSub READ_RECORD + Case Action _EQC 'READONLY_RECORD_PRE' ; GoSub READONLY_RECORD_PRE + Case Action _EQC 'READONLY_RECORD' ; GoSub READONLY_RECORD + Case Action _EQC 'WRITE_RECORD_PRE' ; GoSub WRITE_RECORD_PRE + Case Action _EQC 'WRITE_RECORD' ; GoSub WRITE_RECORD + Case Action _EQC 'DELETE_RECORD_PRE' ; GoSub DELETE_RECORD_PRE + Case Action _EQC 'DELETE_RECORD' ; GoSub DELETE_RECORD + Case Otherwise$ ; Status = 'Invalid Action' + +End Case + +If KeyID then GoSub Restore_System_Variables + +If Assigned(ActionFlow) else ActionFlow = ACTION_CONTINUE$ + +Return ActionFlow + + +// ----- Calculated Columns -------------------------------------------------------------------------------------------- +// +// The typical structure of a calculated column will look like this: +// +// Declare function TableName_Actions +// +// A = {COL1} ; * Reference as many data columns in this way to ensure the dictionary dependency is generated. +// +// @ANS = TableName_Actions('CalcField', 'CalcColName') +// +// --------------------------------------------------------------------------------------------------------------------- + +CalculateColumn: + + // Make sure the ActionFlow return variable is cleared in case nothing is calculated. + ActionFlow = '' + + Begin Case + Case CalcColName EQ 'EXAMPLE' ; GoSub EXAMPLE + End Case + +return + + +EXAMPLE: + + ActionFlow = '' + +return + + +// ----- MFS calls ----------------------------------------------------------------------------------------------------- + +READ_RECORD_PRE: + // In order to stop a record from being read in this action these lines of code must be used: + // + // OrigFileError = 100 : @FM : KeyID + // Status = 0 + // Record = '' + // ActionFlow = ACTION_STOP$ +return + + +READ_RECORD: + // In order to stop a record from being read in this action these lines of code must be used: + // + // OrigFileError = 100 : @FM : KeyID + // Status = 0 + // Record = '' +return + +READONLY_RECORD_PRE: + // In order to stop a record from being read in this action these lines of code must be used: + // + // OrigFileError = 100 : @FM : KeyID + // Status = 0 + // Record = '' + // ActionFlow = ACTION_STOP$ +return + +READONLY_RECORD: + // In order to stop a record from being read in this action these lines of code must be used: + // + // OrigFileError = 100 : @FM : KeyID + // Status = 0 + // Record = '' +return + +WRITE_RECORD_PRE: +return + +WRITE_RECORD: +return + +DELETE_RECORD_PRE: +return + +DELETE_RECORD: +return + + +// ----- Internal Methods ---------------------------------------------------------------------------------------------- + +Initialize_System_Variables: + // Save these for restoration later + SaveDict = @DICT + SaveID = @ID + SaveRecord = @RECORD + OrigFileError = @FILE.ERROR + + // Now make sure @DICT, ID, and @RECORD are populated + CurrentDictName = '' + If @DICT then + DictHandle = @DICT<1, 2> + Locate DictHandle in @TABLES(5) Using @FM Setting fPos then + CurrentDictName = Field(@TABLES(0), @FM, fPos, 1) + end + end + + If CurrentDictName NE DictName then + Open DictName to @DICT else Status = 'Unable to initialize @DICT' + end + + @ID = KeyID + If Record else + // Record might not have been passed in. Read the record from the database table just to make sure. + @FILE.ERROR = '' + Open TableName to hTable then + FullFSList = hTable[1, 'F' : @VM] + BFS = FullFSList[-1, 'B' : @SVM] + LastHandle = hTable[-1, 'B' : \0D\] + FileHandle = \0D\ : LastHandle[1, @VM] + + Call @BFS(READO.RECORD, BFS, FileHandle, KeyID, FMC, Record, ReadOStatus) + end + end + @RECORD = Record +return + +Restore_System_Variables: + Transfer SaveDict to @DICT + Transfer SaveID to @ID + Transfer SaveRecord to @RECORD + @FILE.ERROR = OrigFileError +return + + + + diff --git a/LSL2/STPROC/MATERIAL_SERVICES.txt b/LSL2/STPROC/MATERIAL_SERVICES.txt index 4a52364..e9bc14a 100644 --- a/LSL2/STPROC/MATERIAL_SERVICES.txt +++ b/LSL2/STPROC/MATERIAL_SERVICES.txt @@ -262,7 +262,7 @@ End Service // looks for MakeUp wafers older than 3 years old and then puts them on hold and sends notification. //---------------------------------------------------------------------------------------------------------------------- Service ProcessAutoHold() - + hSysLists = Database_Services('GetTableHandle', 'SYSLISTS') Lock hSysLists, ServiceKeyID then @@ -271,10 +271,12 @@ Service ProcessAutoHold() LogData<2> = 'Begin ':Service Logging_Services('AppendLog', objLog, LogData, @RM, @FM) - HoldList = '' - FailedHoldList = '' - CutoffDate = SRP_Date('AddYears', Date(), -3) - Query = 'SELECT MAKEUP_WAFERS WITH UNLOAD_DTM LT ':Quote(OConv(CutoffDate, 'DT2/^H'): ' AND WITH EXPIRED NE ':True$) + HoldList = '' + FailedHoldList = '' + HoldEntityIds = '' + + CuttoffDtm = SRP_Datetime('AddYears', Datetime(), -3) + Query = 'SELECT MAKEUP_WAFERS WITH UNLOAD_DTM LT ':Quote(OConv(CuttoffDtm, 'DT2/^H')): ' AND WITH EXPIRED NE ':True$ Flag = '' RList(Query, TARGET_ACTIVELIST$, '', '', Flag) @@ -363,36 +365,48 @@ Service ProcessAutoHold() end If ErrorMsg EQ '' then // Now mark cassette as expired + MWRec = Database_Services('ReadDataRow', 'MAKEUP_WAFERS', WOMatKey) + ExpiredFlag = MWRec LogData = '' LogData<1> = OConv(Datetime(), 'DT2/^H') - LogData<2> = 'Attempting to mark lot "':WOMatKey:'" as expired.' - Logging_Services('AppendLog', objLog, LogData, @RM, @FM) - - Material_Services('MarkMUCassExpired', WOMatKey) - If Error_Services('NoError') then - MWRec = Database_Services('ReadDataRow', 'MAKEUP_WAFERS', WOMatKey) + LogData<2> = 'Checking expiry state of "':WOMatKey:'". Expired flag = ':ExpiredFlag:'.' + Logging_Services('AppendLog', objLog, LogData, @RM, @FM) + If ExpiredFlag NE True$ then + LogData = '' + LogData<1> = OConv(Datetime(), 'DT2/^H') + LogData<2> = 'Lot "':WOMatKey:'" not marked as expired. Attempting to mark lot "':WOMatKey:'" as expired.' + Logging_Services('AppendLog', objLog, LogData, @RM, @FM) + Material_Services('MarkMUCassExpired', WOMatKey) If Error_Services('NoError') then - ExpiredFlag = MWRec - LogData = '' - LogData<1> = OConv(Datetime(), 'DT2/^H') - LogData<2> = 'Successfully marked lot "':WOMatKey:'" as expired. Expired flag = ':ExpiredFlag:'.' - Logging_Services('AppendLog', objLog, LogData, @RM, @FM) + MWRec = Database_Services('ReadDataRow', 'MAKEUP_WAFERS', WOMatKey) + If Error_Services('NoError') then + ExpiredFlag = MWRec + LogData = '' + LogData<1> = OConv(Datetime(), 'DT2/^H') + LogData<2> = 'Successfully marked lot "':WOMatKey:'" as expired. Expired flag = ':ExpiredFlag:'.' + Logging_Services('AppendLog', objLog, LogData, @RM, @FM) + end else + ErrorMsg = Error_Services('GetMessage') + LogMsg = 'Failed to verify lot "':WOMatKey:'" was marked as expired.' + LogMsg := 'Error message: ':ErrorMsg + LogData = '' + LogData<1> = OConv(Datetime(), 'DT2/^H') + LogData<2> = LogMsg + Logging_Services('AppendLog', objLog, LogData, @RM, @FM) + end end else ErrorMsg = Error_Services('GetMessage') - LogMsg = 'Failed to verify lot "':WOMatKey:'" was marked as expired.' + LogMsg = 'Failed to mark lot "':WOMatKey:'" as expired.' LogMsg := 'Error message: ':ErrorMsg LogData = '' LogData<1> = OConv(Datetime(), 'DT2/^H') LogData<2> = LogMsg - Logging_Services('AppendLog', objLog, LogData, @RM, @FM) + Logging_Services('AppendLog', objLog, LogData, @RM, @FM) end end else - ErrorMsg = Error_Services('GetMessage') - LogMsg = 'Failed to mark lot "':WOMatKey:'" as expired.' - LogMsg := 'Error message: ':ErrorMsg - LogData = '' - LogData<1> = OConv(Datetime(), 'DT2/^H') - LogData<2> = LogMsg + LogData = '' + LogData<1> = OConv(Datetime(), 'DT2/^H') + LogData<2> = 'Lot "':WOMatKey:'" already marked as expired. Expired flag = ':ExpiredFlag:'.' Logging_Services('AppendLog', objLog, LogData, @RM, @FM) end end else @@ -415,9 +429,10 @@ Service ProcessAutoHold() end If (ErrorMsg EQ '') then - HoldList<-1> = ReactType:TAB$:HoldEntityID + HoldList<-1> = ReactType:TAB$:HoldEntityID + HoldEntityIds<-1> = WOMatKey end else - FailedHoldList<-1> = ReactType:TAB$:HoldEntityID + FailedHoldList<-1> = ReactType:TAB$:HoldEntityID end Repeat @@ -425,7 +440,7 @@ Service ProcessAutoHold() NotifyDtm = Datetime() // Send initial notification of successful lots and failed lots - If (HoldList NE '') then + If (HoldEntityIds NE '') then Recipients = '' SentFrom = 'SYSTEM' Subject = 'Makeup Wafer Auto-Hold Report' @@ -439,17 +454,9 @@ Service ProcessAutoHold() Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup obj_Notes('Create',Parms) - For each WOMatKey in HoldList using @FM - - WONo = Field(WOMatKey, '*', 1) - ReactType = Xlate('WO_LOG', WONo, 'REACT_TYPE', 'X') - If ReactType EQ 'EPP' then - CassNo = Field(WOMatKey, '*', 2) - HoldEntityID = WONo:'*1*':CassNo - end else - HoldEntityID = Xlate('WO_MAT', WOMatKey, 'RDS_NO', 'X') - end - MUWfrRec = Database_Services('ReadDataRow', 'MAKEUP_WAFERS', WOMatKey) + For each HoldEntityId in HoldEntityIds using @FM + WOMatKey = HoldEntityId + MUWfrRec = Database_Services('ReadDataRow', 'MAKEUP_WAFERS', WOMatKey) If Error_Services('NoError') then HaveLock = Database_Services('GetKeyIDLock', 'MAKEUP_WAFERS', WOMatKey, True$) If HaveLock then @@ -488,7 +495,7 @@ Service ProcessAutoHold() LogData<2> = LogMsg Logging_Services('AppendLog', objLog, LogData, @RM, @FM) end - Next WOMatKey + Next HoldEntityId end If (FailedHoldList NE '') then @@ -612,7 +619,7 @@ end service Service GetAvailableMakeupWafers(WorkOrderNo, KeysOnly=BOOLEAN) AvailableMakeupWafers = '' - + If WorkOrderNo NE '' then WorkOrderNo = WorkOrderNo[1, '*'] ; // This might be formatted as a WO_MAT Key ID, so strip off the Cassette No. WOLogRow = Database_Services('ReadDataRow', 'WO_LOG', WorkOrderNo)