fixed bug in mu auto hold system

This commit is contained in:
Infineon\StieberD 2025-02-13 12:50:12 -07:00
parent 3ba7ffe782
commit 30bd03049a
2 changed files with 251 additions and 246 deletions

View File

@ -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) 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 #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 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. permission from Infineon.
Name : Makeup_Wafers_Actions Name : Makeup_Wafers_Actions
Description : Handles calculated columns and MFS calls for the current table. 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. 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. If called from outside of a calculated column these will need to be set and restored.
Parameters : Parameters :
Action [in] -- Name of the action to be taken 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 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. 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 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 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. 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 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 entire handle structure that the Basic+ Open statement would provide. Normally set by a
calling MFS. calling MFS.
Name [in] -- The name (key) of the record or file being accessed. 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. 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 Record [in] -- The entire record (for record-oriented functions) or a newly-created handle (for
"get handle" functions). Normally set by a calling MFS. "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 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. 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 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 automatically being assigned by the WRITE_RECORD and DELETE_RECORD actions within
BASE_MFS. BASE_MFS.
Param1-10 [in/out] -- Additional request parameter holders Param1-10 [in/out] -- Additional request parameter holders
ActionFlow [out] -- Used to control the action chain (see the ACTION_SETUP insert for more information.) 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 Can also be used to return a special value, such as the results of the CalcField
method. method.
History : (Date, Initials, Notes) History : (Date, Initials, Notes)
07/09/24 djs Original programmer. 07/09/24 djs Original programmer.
***********************************************************************************************************************/ ***********************************************************************************************************************/
$insert APP_INSERTS $insert APP_INSERTS
$insert FILE.SYSTEM.EQUATES $insert FILE.SYSTEM.EQUATES
$insert ACTION_SETUP $insert ACTION_SETUP
$insert MAKEUP_WAFERS_EQUATES $insert MAKEUP_WAFERS_EQUATES
Declare function SRP_Date Declare function SRP_Date
If KeyID then GoSub Initialize_System_Variables If KeyID then GoSub Initialize_System_Variables
Begin Case Begin Case
Case Action _EQC 'CalculateColumn' ; GoSub CalculateColumn Case Action _EQC 'CalculateColumn' ; GoSub CalculateColumn
Case Action _EQC 'READ_RECORD_PRE' ; GoSub READ_RECORD_PRE Case Action _EQC 'READ_RECORD_PRE' ; GoSub READ_RECORD_PRE
Case Action _EQC 'READ_RECORD' ; GoSub READ_RECORD Case Action _EQC 'READ_RECORD' ; GoSub READ_RECORD
Case Action _EQC 'READONLY_RECORD_PRE' ; GoSub READONLY_RECORD_PRE Case Action _EQC 'READONLY_RECORD_PRE' ; GoSub READONLY_RECORD_PRE
Case Action _EQC 'READONLY_RECORD' ; GoSub READONLY_RECORD Case Action _EQC 'READONLY_RECORD' ; GoSub READONLY_RECORD
Case Action _EQC 'WRITE_RECORD_PRE' ; GoSub WRITE_RECORD_PRE Case Action _EQC 'WRITE_RECORD_PRE' ; GoSub WRITE_RECORD_PRE
Case Action _EQC 'WRITE_RECORD' ; GoSub WRITE_RECORD Case Action _EQC 'WRITE_RECORD' ; GoSub WRITE_RECORD
Case Action _EQC 'DELETE_RECORD_PRE' ; GoSub DELETE_RECORD_PRE Case Action _EQC 'DELETE_RECORD_PRE' ; GoSub DELETE_RECORD_PRE
Case Action _EQC 'DELETE_RECORD' ; GoSub DELETE_RECORD Case Action _EQC 'DELETE_RECORD' ; GoSub DELETE_RECORD
Case Otherwise$ ; Status = 'Invalid Action' Case Otherwise$ ; Status = 'Invalid Action'
End Case End Case
If KeyID then GoSub Restore_System_Variables If KeyID then GoSub Restore_System_Variables
If Assigned(ActionFlow) else ActionFlow = ACTION_CONTINUE$ If Assigned(ActionFlow) else ActionFlow = ACTION_CONTINUE$
Return ActionFlow Return ActionFlow
// ----- Calculated Columns -------------------------------------------------------------------------------------------- // ----- Calculated Columns --------------------------------------------------------------------------------------------
// //
// The typical structure of a calculated column will look like this: // The typical structure of a calculated column will look like this:
// //
// Declare function TableName_Actions // Declare function TableName_Actions
// //
// A = {COL1} ; * Reference as many data columns in this way to ensure the dictionary dependency is generated. // A = {COL1} ; * Reference as many data columns in this way to ensure the dictionary dependency is generated.
// //
// @ANS = TableName_Actions('CalcField', 'CalcColName') // @ANS = TableName_Actions('CalcField', 'CalcColName')
// //
// --------------------------------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------------------------------
CalculateColumn: CalculateColumn:
// Make sure the ActionFlow return variable is cleared in case nothing is calculated. // Make sure the ActionFlow return variable is cleared in case nothing is calculated.
ActionFlow = '' ActionFlow = ''
Begin Case Begin Case
Case CalcColName EQ 'EXAMPLE' ; GoSub EXAMPLE Case CalcColName EQ 'EXAMPLE' ; GoSub EXAMPLE
End Case End Case
return return
EXAMPLE: EXAMPLE:
ActionFlow = '' ActionFlow = ''
return return
// ----- MFS calls ----------------------------------------------------------------------------------------------------- // ----- MFS calls -----------------------------------------------------------------------------------------------------
READ_RECORD_PRE: READ_RECORD_PRE:
// In order to stop a record from being read in this action these lines of code must be used: // In order to stop a record from being read in this action these lines of code must be used:
// //
// OrigFileError = 100 : @FM : KeyID // OrigFileError = 100 : @FM : KeyID
// Status = 0 // Status = 0
// Record = '' // Record = ''
// ActionFlow = ACTION_STOP$ // ActionFlow = ACTION_STOP$
return return
READ_RECORD: READ_RECORD:
// In order to stop a record from being read in this action these lines of code must be used: // In order to stop a record from being read in this action these lines of code must be used:
// //
// OrigFileError = 100 : @FM : KeyID // OrigFileError = 100 : @FM : KeyID
// Status = 0 // Status = 0
// Record = '' // Record = ''
return return
READONLY_RECORD_PRE: READONLY_RECORD_PRE:
// In order to stop a record from being read in this action these lines of code must be used: // In order to stop a record from being read in this action these lines of code must be used:
// //
// OrigFileError = 100 : @FM : KeyID // OrigFileError = 100 : @FM : KeyID
// Status = 0 // Status = 0
// Record = '' // Record = ''
// ActionFlow = ACTION_STOP$ // ActionFlow = ACTION_STOP$
return return
READONLY_RECORD: READONLY_RECORD:
// In order to stop a record from being read in this action these lines of code must be used: // In order to stop a record from being read in this action these lines of code must be used:
// //
// OrigFileError = 100 : @FM : KeyID // OrigFileError = 100 : @FM : KeyID
// Status = 0 // Status = 0
// Record = '' // Record = ''
return return
WRITE_RECORD_PRE: WRITE_RECORD_PRE:
return
SaveRecord<MAKEUP_WAFERS.EXPIRED$> = ( {UNLOAD_DTM} LT SRP_Date('AddYears', Date(), -3) )
WRITE_RECORD:
return return
WRITE_RECORD: DELETE_RECORD_PRE:
return return
DELETE_RECORD_PRE: DELETE_RECORD:
return return
DELETE_RECORD:
return // ----- Internal Methods ----------------------------------------------------------------------------------------------
Initialize_System_Variables:
// ----- Internal Methods ---------------------------------------------------------------------------------------------- // Save these for restoration later
SaveDict = @DICT
Initialize_System_Variables: SaveID = @ID
// Save these for restoration later SaveRecord = @RECORD
SaveDict = @DICT OrigFileError = @FILE.ERROR
SaveID = @ID
SaveRecord = @RECORD // Now make sure @DICT, ID, and @RECORD are populated
OrigFileError = @FILE.ERROR CurrentDictName = ''
If @DICT then
// Now make sure @DICT, ID, and @RECORD are populated DictHandle = @DICT<1, 2>
CurrentDictName = '' Locate DictHandle in @TABLES(5) Using @FM Setting fPos then
If @DICT then CurrentDictName = Field(@TABLES(0), @FM, fPos, 1)
DictHandle = @DICT<1, 2> end
Locate DictHandle in @TABLES(5) Using @FM Setting fPos then end
CurrentDictName = Field(@TABLES(0), @FM, fPos, 1)
end If CurrentDictName NE DictName then
end Open DictName to @DICT else Status = 'Unable to initialize @DICT'
end
If CurrentDictName NE DictName then
Open DictName to @DICT else Status = 'Unable to initialize @DICT' @ID = KeyID
end If Record else
// Record might not have been passed in. Read the record from the database table just to make sure.
@ID = KeyID @FILE.ERROR = ''
If Record else Open TableName to hTable then
// Record might not have been passed in. Read the record from the database table just to make sure. FullFSList = hTable[1, 'F' : @VM]
@FILE.ERROR = '' BFS = FullFSList[-1, 'B' : @SVM]
Open TableName to hTable then LastHandle = hTable[-1, 'B' : \0D\]
FullFSList = hTable[1, 'F' : @VM] FileHandle = \0D\ : LastHandle[1, @VM]
BFS = FullFSList[-1, 'B' : @SVM]
LastHandle = hTable[-1, 'B' : \0D\] Call @BFS(READO.RECORD, BFS, FileHandle, KeyID, FMC, Record, ReadOStatus)
FileHandle = \0D\ : LastHandle[1, @VM] end
end
Call @BFS(READO.RECORD, BFS, FileHandle, KeyID, FMC, Record, ReadOStatus) @RECORD = Record
end return
end
@RECORD = Record Restore_System_Variables:
return Transfer SaveDict to @DICT
Transfer SaveID to @ID
Restore_System_Variables: Transfer SaveRecord to @RECORD
Transfer SaveDict to @DICT @FILE.ERROR = OrigFileError
Transfer SaveID to @ID return
Transfer SaveRecord to @RECORD
@FILE.ERROR = OrigFileError
return

View File

@ -262,7 +262,7 @@ End Service
// looks for MakeUp wafers older than 3 years old and then puts them on hold and sends notification. // looks for MakeUp wafers older than 3 years old and then puts them on hold and sends notification.
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------
Service ProcessAutoHold() Service ProcessAutoHold()
hSysLists = Database_Services('GetTableHandle', 'SYSLISTS') hSysLists = Database_Services('GetTableHandle', 'SYSLISTS')
Lock hSysLists, ServiceKeyID then Lock hSysLists, ServiceKeyID then
@ -271,10 +271,12 @@ Service ProcessAutoHold()
LogData<2> = 'Begin ':Service LogData<2> = 'Begin ':Service
Logging_Services('AppendLog', objLog, LogData, @RM, @FM) Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
HoldList = '' HoldList = ''
FailedHoldList = '' FailedHoldList = ''
CutoffDate = SRP_Date('AddYears', Date(), -3) HoldEntityIds = ''
Query = 'SELECT MAKEUP_WAFERS WITH UNLOAD_DTM LT ':Quote(OConv(CutoffDate, 'DT2/^H'): ' AND WITH EXPIRED NE ':True$)
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 = '' Flag = ''
RList(Query, TARGET_ACTIVELIST$, '', '', Flag) RList(Query, TARGET_ACTIVELIST$, '', '', Flag)
@ -363,36 +365,48 @@ Service ProcessAutoHold()
end end
If ErrorMsg EQ '' then If ErrorMsg EQ '' then
// Now mark cassette as expired // Now mark cassette as expired
MWRec = Database_Services('ReadDataRow', 'MAKEUP_WAFERS', WOMatKey)
ExpiredFlag = MWRec<MAKEUP_WAFERS.EXPIRED$>
LogData = '' LogData = ''
LogData<1> = OConv(Datetime(), 'DT2/^H') LogData<1> = OConv(Datetime(), 'DT2/^H')
LogData<2> = 'Attempting to mark lot "':WOMatKey:'" as expired.' LogData<2> = 'Checking expiry state of "':WOMatKey:'". Expired flag = ':ExpiredFlag:'.'
Logging_Services('AppendLog', objLog, LogData, @RM, @FM) Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
If ExpiredFlag NE True$ then
Material_Services('MarkMUCassExpired', WOMatKey) LogData = ''
If Error_Services('NoError') then LogData<1> = OConv(Datetime(), 'DT2/^H')
MWRec = Database_Services('ReadDataRow', 'MAKEUP_WAFERS', WOMatKey) 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 If Error_Services('NoError') then
ExpiredFlag = MWRec<MAKEUP_WAFERS.EXPIRED$> MWRec = Database_Services('ReadDataRow', 'MAKEUP_WAFERS', WOMatKey)
LogData = '' If Error_Services('NoError') then
LogData<1> = OConv(Datetime(), 'DT2/^H') ExpiredFlag = MWRec<MAKEUP_WAFERS.EXPIRED$>
LogData<2> = 'Successfully marked lot "':WOMatKey:'" as expired. Expired flag = ':ExpiredFlag:'.' LogData = ''
Logging_Services('AppendLog', objLog, LogData, @RM, @FM) 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 end else
ErrorMsg = Error_Services('GetMessage') 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 LogMsg := 'Error message: ':ErrorMsg
LogData = '' LogData = ''
LogData<1> = OConv(Datetime(), 'DT2/^H') LogData<1> = OConv(Datetime(), 'DT2/^H')
LogData<2> = LogMsg LogData<2> = LogMsg
Logging_Services('AppendLog', objLog, LogData, @RM, @FM) Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
end end
end else end else
ErrorMsg = Error_Services('GetMessage') LogData = ''
LogMsg = 'Failed to mark lot "':WOMatKey:'" as expired.' LogData<1> = OConv(Datetime(), 'DT2/^H')
LogMsg := 'Error message: ':ErrorMsg LogData<2> = 'Lot "':WOMatKey:'" already marked as expired. Expired flag = ':ExpiredFlag:'.'
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
end else end else
@ -415,9 +429,10 @@ Service ProcessAutoHold()
end end
If (ErrorMsg EQ '') then If (ErrorMsg EQ '') then
HoldList<-1> = ReactType:TAB$:HoldEntityID HoldList<-1> = ReactType:TAB$:HoldEntityID
HoldEntityIds<-1> = WOMatKey
end else end else
FailedHoldList<-1> = ReactType:TAB$:HoldEntityID FailedHoldList<-1> = ReactType:TAB$:HoldEntityID
end end
Repeat Repeat
@ -425,7 +440,7 @@ Service ProcessAutoHold()
NotifyDtm = Datetime() NotifyDtm = Datetime()
// Send initial notification of successful lots and failed lots // Send initial notification of successful lots and failed lots
If (HoldList NE '') then If (HoldEntityIds NE '') then
Recipients = '' Recipients = ''
SentFrom = 'SYSTEM' SentFrom = 'SYSTEM'
Subject = 'Makeup Wafer Auto-Hold Report' 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 Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup
obj_Notes('Create',Parms) obj_Notes('Create',Parms)
For each WOMatKey in HoldList using @FM For each HoldEntityId in HoldEntityIds using @FM
WOMatKey = HoldEntityId
WONo = Field(WOMatKey, '*', 1) MUWfrRec = Database_Services('ReadDataRow', 'MAKEUP_WAFERS', WOMatKey)
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)
If Error_Services('NoError') then If Error_Services('NoError') then
HaveLock = Database_Services('GetKeyIDLock', 'MAKEUP_WAFERS', WOMatKey, True$) HaveLock = Database_Services('GetKeyIDLock', 'MAKEUP_WAFERS', WOMatKey, True$)
If HaveLock then If HaveLock then
@ -488,7 +495,7 @@ Service ProcessAutoHold()
LogData<2> = LogMsg LogData<2> = LogMsg
Logging_Services('AppendLog', objLog, LogData, @RM, @FM) Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
end end
Next WOMatKey Next HoldEntityId
end end
If (FailedHoldList NE '') then If (FailedHoldList NE '') then
@ -612,7 +619,7 @@ end service
Service GetAvailableMakeupWafers(WorkOrderNo, KeysOnly=BOOLEAN) Service GetAvailableMakeupWafers(WorkOrderNo, KeysOnly=BOOLEAN)
AvailableMakeupWafers = '' AvailableMakeupWafers = ''
If WorkOrderNo NE '' then If WorkOrderNo NE '' then
WorkOrderNo = WorkOrderNo[1, '*'] ; // This might be formatted as a WO_MAT Key ID, so strip off the Cassette No. 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) WOLogRow = Database_Services('ReadDataRow', 'WO_LOG', WorkOrderNo)