Files
open-insight/LSL2/STPROC/LOT_SERVICES.txt
Infineon\StieberD 5ca3778719 VNAV bug fix
2025-07-02 09:54:16 -07:00

1521 lines
65 KiB
Plaintext

Compile function Lot_Services(@Service, @Params)
/***********************************************************************************************************************
Name : Lot_Services
Description : Handler program for all LOT 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)
07/01/25 djs Corrected error throwing.
***********************************************************************************************************************/
#pragma precomp SRP_PreCompiler
$Insert SERVICE_SETUP
$Insert APP_INSERTS
$Insert LOT_EQUATES
$Insert TEST_WAFER_PROD_EQUATES
$Insert LOT_OPERATION_EQUATES
$Insert PRODUCT_OPERATION_EQUATES
$Insert LOT_EVENT_EQUATES
$Insert NOTIFICATION_EQUATES
$Insert VOIDED_LOT_EQUATES
Declare function TEST_WAFER_PROD_SERVICES, SRP_Datetime, Datetime, Database_Services, Lot_Services, Error_Services, RTI_CREATEGUID
Declare function SRP_Array, SRP_Json, Environment_Services, Logging_Services, MemberOf, Lot_Event_Services, GetTickCount
Declare subroutine Database_Services, Btree.Extract, Lot_Services, Error_Services, Labeling_Services, SRP_Json, Logging_Services
Declare subroutine SRP_Run_Command, Service_Services, obj_notes, Lot_Event_Services, Mona_Services
LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\Lot'
LogDate = Oconv(Date(), 'D4/')
LogTime = Oconv(Time(), 'MTS')
LoggingDTM = LogDate : ' ' : LogTime ; // Logging DTM
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' TestWaferLotCreation.csv'
Headers = 'Logging DTM' : @FM : 'Product Name' : @FM : 'Username' : @FM : 'Message'
objTWCreationLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ',', Headers, '', False$, False$)
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' LotStart.csv'
Headers = 'Logging DTM' : @FM : 'Lot Id' : @FM : 'Username' : @FM : 'Message'
objLotStartLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ',', Headers, '', False$, False$)
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' LotRun.csv'
Headers = 'Logging DTM' : @FM : 'Lot Id' : @FM : 'Username' : @FM : 'Tool Id' : @FM : 'Message'
objRunLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ',', Headers, '', False$, False$)
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' LotMove.csv'
Headers = 'Logging DTM' : @FM : 'Lot Id' : @FM : 'Username' : @FM : 'Message'
objLotMoveLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ',', Headers, '', False$, False$)
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' LotEvent.csv'
Headers = 'Logging DTM' : @FM : 'Lot Id' : @FM : 'Event Type' : @FM : 'Operator' : @FM : 'Begin Wafer Qty' : @FM : 'End Wafer Qty' : @FM : 'Bonus Wafer Qty' : @FM : 'Reduce Wafer Qty' : @FM : 'Message'
objLotEventLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ',', Headers, '', False$, False$)
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' TWLotClosure.csv'
Headers = 'Logging DTM' : @FM : 'Lot Id' : @FM : 'Operator' : @FM : 'Message'
objLotClosureLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ',', Headers, '', False$, False$)
Options EVENT_TYPES = 'MOVE_IN', 'MOVE_OUT', 'HOLD_ON', 'HOLD_OFF', 'REDUCE_WAFER_QTY', 'BONUS_WAFER_QTY', 'COMMENT', 'LOCATION', 'LOAD', 'UNSIGN_LOAD', 'TW_USE', 'CLOSE', 'SIGN_FQA', 'UNSIGN_FQA'
Options LOT_TYPES = 'TW', 'RDS', 'WM_OUT', 'WM_IN', 'WO_MAT', 'LOT'
IsProd = Environment_Services('IsProd')
If IsProd EQ True$ then
MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_LOTSERVICES'
end else
MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_DEV_LOTSERVICES'
end
GoToService
Return Response or ""
//----------------------------------------------------------------------------------------------------------------------
// Services
//----------------------------------------------------------------------------------------------------------------------
Service GenerateNewLotId(LotType)
NewLotID = ''
RightNow = Datetime()
If LotType NE '' then
ValidLotNum = False$
GeneratedLotID = ''
Begin Case
Case LotType EQ 'TW'
Loop
Until ValidLotNum EQ True$
LotPrefix = 'TW'
LotYear = SRP_Datetime('Year', RightNow)
LotMonth = SRP_Datetime('Month', RightNow)
LotDay = SRP_Datetime('Day', RightNow)
LotTime = SRP_Datetime('Time', RightNow)
GeneratedLotId = LotPrefix : LotYear : LotMonth : LotDay : LotTime
If Not(RowExists('LOT', GeneratedLotId)) then
ValidLotNum = True$
end else
ValidLotNum = False$
RightNow = Datetime()
end
Repeat
Case LotType EQ 'RDS' OR LotType EQ 'WM_IN' OR LotType EQ 'WM_OUT' OR LotType EQ 'WO_MAT'
Loop
Until ValidLotNum EQ True$
LotPrefix = ''
Begin Case
Case LotType EQ 'RDS'
LotPrefix = 'R'
Case LotType EQ 'WM_IN'
LotPrefix = 'I'
Case LotType EQ 'WM_OUT'
LotPrefix = 'O'
Case LotType EQ 'WO_MAT'
LotPrefix = 'M'
End Case
HaveLockLotIdSequence = Database_Services('GetKeyIDLock', 'CONFIG', 'LOT_KEY_SEQUENCE_PROD')
If HaveLockLotIdSequence then
CurrLotSequence = Database_Services('ReadDataRow', 'CONFIG', 'LOT_KEY_SEQUENCE_PROD', True$, 0, False$)
NextLotSequence = CurrLotSequence + 1
Database_Services('WriteDataRow', 'CONFIG', 'LOT_KEY_SEQUENCE_PROD', NextLotSequence, True$, False$, False$)
Database_Services('ReleaseKeyIDLock', 'CONFIG', 'LOT_KEY_SEQUENCE_PROD')
GeneratedLotId = LotPrefix : CurrLotSequence
If Not(RowExists('LOT', GeneratedLotId)) AND CurrLotSequence NE '' then
ValidLotNum = True$
end else
ValidLotNum = False$
end
end
Repeat
Case Otherwise$
Null
End Case
If GeneratedLotID NE '' AND ValidLotNum then
// Write the new lot id now so it's reserved
Database_Services('WriteDataRow', 'LOT', GeneratedLotID, '')
If RowExists('LOT', GeneratedLotID) then
NewLotID = GeneratedLotID
end
end
end
Response = NewLotID
end service
Service GetLotIdByLegacyLotIdAndType(LegacyLotId, LegacyLotType)
StartTick = GetTickCount()
MetricName = 'GetLotIdByLegacyLotIdAndType'
ErrorMsg = ''
Open 'DICT.LOT' to DictLot then
SearchString = ''
SearchString := 'LEGACY_LOT_ID':@VM:LegacyLotId:@FM
SearchString := 'TYPE':@VM:LegacyLotType:@FM
LotIdKeys = ''
Btree.Extract(SearchString, 'LOT', DictLot, LotIdKeys, '', '')
ErrCode = ''
IF Get_Status(ErrCode) then
ErrorMsg = 'Error in ':Service:' service. Error calling Btree.Extract. Error code ':ErrCode:'.'
end else
Response = LotIdKeys<1,1>
end
end else
ErrorMsg = 'Error in ':Service:' service. Error opening LOT dictionary.'
end
EndTick = GetTickCount()
Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick)
If ErrorMsg NE '' then Error_Services('Add', ErrorMsg)
end service
Service CreateNewLot(LotType, ProdName, LotQty, VendorPartNo, VendorLotNo, VendorCode, Username, PrinterID, LotId)
StartTick = GetTickCount()
MetricName = 'CreateNewLot'
CreatedLotNumber = ''
ErrorMessage = ''
Begin Case
Case LotType EQ 'RDS' OR LotType EQ 'WM_IN' OR LotType EQ 'WM_OUT' OR LotType EQ 'WO_MAT'
// Case statement for legacy lot entity types
NewLotId = Lot_Services('GenerateNewLotId', LotType)
If NewLotId NE '' then
If RowExists('LOT', NewLotId) NE False$ then
LotRec = ''
LotRec<LOT_TYPE$> = LotType
LotRec<LOT_PROD_ID$> = ''
LotRec<LOT_ORIG_WAFER_QTY$> = LotQty
LotRec<LOT_WAFER_QTY$> = LotQty
LotRec<LOT_VENDOR_PART_NO$> = VendorPartNo
LotRec<LOT_VENDOR_LOT_NO$> = VendorLotNo
LotRec<LOT_VENDOR_CODE$> = VendorCode
LotRec<LOT_LEGACY_LOT_ID$> = LotId
Database_Services('WriteDataRow', 'LOT', NewLotId, LotRec)
If Error_Services('HasError') then
ErrorMessage = 'Error in ':Service:' service. ':Error_Services('GetMessage')
end else
CreatedLotNumber = NewLotId
end
end else
ErrorMessage = 'Error in ':Service:' service. LOT record "':NewLotId:'" already exists.'
end
end else
ErrorMessage = 'Error in ':Service:' service. No lot ID passed in.'
end
Case LotType EQ 'TW'
If ProdName NE '' then
TWProdID = Test_Wafer_Prod_Services('GetTestWaferProdIDsByPartName', ProdName)
If TWProdID NE '' then
If DCount(TWProdID, @VM) EQ 1 then
NewLotId = Lot_Services('GenerateNewLotId', 'TW');//Don't use this
If NewLotId NE '' then
If RowExists('LOT', NewLotId) then
LotRec = Database_Services('ReadDataRow', 'LOT', NewLotId)
// Ensure the lot record is empty
If LotRec<LOT_TYPE$> EQ '' AND LotRec<LOT_PROD_ID$> EQ '' AND LotRec<LOT_ORIG_WAFER_QTY$> EQ '' AND LotRec<LOT_WAFER_QTY$> EQ '' then
LotRec<LOT_TYPE$> = LotType
LotRec<LOT_PROD_ID$> = TWProdID
LotRec<LOT_ORIG_WAFER_QTY$> = LotQty
LotRec<LOT_WAFER_QTY$> = LotQty
LotRec<LOT_VENDOR_PART_NO$> = VendorPartNo
LotRec<LOT_VENDOR_LOT_NO$> = VendorLotNo
LotRec<LOT_VENDOR_CODE$> = VendorCode
Database_Services('WriteDataRow', 'LOT', NewLotId, LotRec)
// Now Ensure that the written lot matches what was just written
LotRecCheck = Database_Services('ReadDataRow', 'LOT', NewLotId)
If LotRecCheck EQ LotRec then
// Lot Created successfully
CreatedLotNumber = NewLotId
If RowExists('LOT', CreatedLotNumber) then
Lot_Services('CreateInitialLotOperationRecords', CreatedLotNumber)
If Error_Services('NoError') then
// Check in at first operation
// Get Curr Operation(Should be first one in sequence)
ThisLotCurrOpId = Lot_Services('GetLotCurrOperationId', CreatedLotNumber)
If ThisLotCurrOpId NE '' then
// Set lot to open
Lot_Services('OpenLot', CreatedLotNumber)
if Error_Services('NoError') then
// Move lot in
Lot_Services('MoveInLot', CreatedLotNumber, Username)
if Error_Services('NoError') then
If PrinterID NE 'WEB' then
// If PrinterID is set to WEB this means the request comes from OI_Wizard and the client is going to handle printing.
Labeling_Services('PrintTestWaferLotLabel', CreatedLotNumber, Username, PrinterID)
If Error_Services('HasError') then
ErrorMessage = 'Error in Create New Test Wafer Lot Process, lot id: ' : CreatedLotNumber : ' , ' : Error_Services('GetMessage')
end
end
Lot_Services('MoveOutLot', NewLotId, Username)
If Error_Services('NoError') then
Lot_Services('MoveInLot', NewLotId, Username)
If Error_Services('HasError') then
ErrorMessage = 'Error in Create New Test Wafer Lot Process, lot id: ' : NewLotId : ' , ' : Error_Services('GetMessage')
end
end else
ErrorMessage = 'Error in Create New Test Wafer Lot Process, lot id: ' : NewLotId : ' , ' : Error_Services('GetMessage')
end
end else
ErrorMessage = 'Error in Create New Test Wafer Lot Process, lot id: ' : NewLotId : ' , ' : Error_Services('GetMessage')
end
end else
// Close LOT record as there was an error
Lot_Services('CloseLot', NewLotId)
ErrorMessage = 'Error in Create New Test Wafer Lot Process, lot id: ' : NewLotId : ' , ' : Error_Services('GetMessage')
end
end else
// Close LOT record as there was an error
Lot_Services('CloseLot', NewLotId)
ErrorMessage = 'Error in Create New Test Wafer Lot Process, error getting current operation for lot: ' : NewLotId
end
end else
// Close LOT record as there was an error
// Database_Services('DeleteDataRow', 'LOT', NewLotId, True$, False$)
Lot_Services('CloseLot', NewLotId)
ErrorMessage = 'Error in Create New Test Wafer Lot Process, lot id: ' : NewLotId : ' , ' : Error_Services('GetMessage')
end
end
end else
ErrorMessage = 'Error in Create New Test Wafer Lot Process, Lot attributes did not write correctly for lot: ' : NewLotId
end
end else
ErrorMessage = 'Error in Create New Test Wafer Lot Process, Lot already had data, lot: ' : NewLotId
end
end else
ErrorMessage = 'Error in Create New Test Wafer Lot Process, Created lot: ' : NewLotId : ' not found in LOT table.'
end
end else
ErrorMessage = 'Error in Create New Test Wafer Lot Process, no lot id returned.'
end
end else
ErrorMessage = 'Error in Create New Test Wafer Lot Process, ambiguous product passed to routine OR no matching products found.'
end
end else
ErrorMessage = 'Error in Create New Test Wafer Lot Process, product(':ProdName:') passed to routine not found.'
end
end else
ErrorMessage = 'Null value passed in for ProdID'
end
Case Otherwise$
ErrorMessage = 'Error in ':Service:' service. Lot Type "':LotType:'" is not currently supported.'
End Case
EndTick = GetTickCount()
Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick)
If ErrorMessage EQ '' then
LogData = ''
LogData<1> = LoggingDTM
LogData<2> = ProdName
LogData<3> = Username
LogData<4> = 'Successfully created lot id ' : CreatedLotNumber : ' of product type ' : ProdName '.'
Logging_Services('AppendLog', objTWCreationLog, LogData, @RM, @FM, False$)
end else
LogData = ''
LogData<1> = LoggingDTM
LogData<2> = ProdName
LogData<3> = Username
LogData<4> = ErrorMessage
Logging_Services('AppendLog', objTWCreationLog, LogData, @RM, @FM, False$)
Error_Services('Add', ErrorMessage)
end
Response = CreatedLotNumber
End Service
Service CreateNewTestWaferLot(LotType, ProdName, LotQty, VendorPartNo, VendorLotNo, VendorCode, Username, PrinterID)
CreatedLotNumber = ''
ErrorMessage = ''
If LotType EQ 'TW' then
If ProdName NE '' then
TWProdID = Test_Wafer_Prod_Services('GetTestWaferProdIDsByPartName', ProdName)
If TWProdID NE '' then
If DCount(TWProdID, @VM) EQ 1 then
NewLotId = Lot_Services('GenerateNewLotId', 'TW')
If NewLotId NE '' then
If RowExists('LOT', NewLotId) then
LotRec = Database_Services('ReadDataRow', 'LOT', NewLotId)
// Ensure the lot record is empty
If LotRec<LOT_TYPE$> EQ '' AND LotRec<LOT_PROD_ID$> EQ '' AND LotRec<LOT_ORIG_WAFER_QTY$> EQ '' AND LotRec<LOT_WAFER_QTY$> EQ '' then
LotRec<LOT_TYPE$> = LotType
LotRec<LOT_PROD_ID$> = TWProdID
LotRec<LOT_ORIG_WAFER_QTY$> = LotQty
LotRec<LOT_WAFER_QTY$> = LotQty
LotRec<LOT_VENDOR_PART_NO$> = VendorPartNo
LotRec<LOT_VENDOR_LOT_NO$> = VendorLotNo
LotRec<LOT_VENDOR_CODE$> = VendorCode
Database_Services('WriteDataRow', 'LOT', NewLotId, LotRec)
// Now Ensure that the written lot matches what was just written
LotRecCheck = Database_Services('ReadDataRow', 'LOT', NewLotId)
If LotRecCheck EQ LotRec then
// Lot Created successfully
CreatedLotNumber = NewLotId
If RowExists('LOT', CreatedLotNumber) then
Lot_Services('CreateInitialLotOperationRecords', CreatedLotNumber)
If Error_Services('NoError') then
// Check in at first operation
// Get Curr Operation(Should be first one in sequence)
ThisLotCurrOpId = Lot_Services('GetLotCurrOperationId', CreatedLotNumber)
If ThisLotCurrOpId NE '' then
Lot_Services('MoveInLot', NewLotId, Username)
if Error_Services('NoError') then
// Set lot to open
Lot_Services('OpenLot', CreatedLotNumber)
if Error_Services('NoError') then
If PrinterID NE 'WEB' then
// If PrinterID is set to WEB this means the request comes from OI_Wizard and the client is going to handle printing.
Labeling_Services('PrintTestWaferLotLabel', CreatedLotNumber, Username, PrinterID)
If Error_Services('HasError') then
ErrorMessage = 'Error in Create New Test Wafer Lot Process, lot id: ' : CreatedLotNumber : ' , ' : Error_Services('GetMessage')
end
end
Lot_Services('MoveOutLot', NewLotId, Username)
If Error_Services('NoError') then
Lot_Services('MoveInLot', NewLotId, Username)
If Error_Services('HasError') then
ErrorMessage = 'Error in Create New Test Wafer Lot Process, lot id: ' : NewLotId : ' , ' : Error_Services('GetMessage')
end
end else
ErrorMessage = 'Error in Create New Test Wafer Lot Process, lot id: ' : NewLotId : ' , ' : Error_Services('GetMessage')
end
end else
ErrorMessage = 'Error in Create New Test Wafer Lot Process, lot id: ' : NewLotId : ' , ' : Error_Services('GetMessage')
end
end else
ErrorMessage = 'Error in Create New Test Wafer Lot Process, lot id: ' : NewLotId : ' , ' : Error_Services('GetMessage')
end
end else
ErrorMessage = 'Error in Create New Test Wafer Lot Process, error getting current operation for lot: ' : NewLotId
end
end else
ErrorMessage = 'Error in Create New Test Wafer Lot Process, lot id: ' : NewLotId : ' , ' : Error_Services('GetMessage')
end
end
end else
ErrorMessage = 'Error in Create New Test Wafer Lot Process, Lot attributes did not write correctly for lot: ' : NewLotId
end
end else
ErrorMessage = 'Error in Create New Test Wafer Lot Process, Lot already had data, lot: ' : NewLotId
end
end else
ErrorMessage = 'Error in Create New Test Wafer Lot Process, Created lot: ' : NewLotId : ' not found in LOT table.'
end
end else
ErrorMessage = 'Error in Create New Test Wafer Lot Process, no lot id returned.'
end
end else
ErrorMessage = 'Error in Create New Test Wafer Lot Process, ambiguous product passed to routine OR no matching products found.'
end
end else
ErrorMessage = 'Error in Create New Test Wafer Lot Process, product(':ProdName:') passed to routine not found.'
end
end else
ErrorMessage = 'Null value passed in for ProdID'
end
end else
ErrorMessage = 'Lot type was not test wafer'
end
If ErrorMessage EQ '' then
LogData = ''
LogData<1> = LoggingDTM
LogData<2> = ProdName
LogData<3> = Username
LogData<4> = 'Successfully created lot id ' : CreatedLotNumber : ' of product type ' : ProdName '.'
Logging_Services('AppendLog', objTWCreationLog, LogData, @RM, @FM, False$)
end else
LogData = ''
LogData<1> = LoggingDTM
LogData<2> = ProdName
LogData<3> = Username
LogData<4> = ErrorMessage
Logging_Services('AppendLog', objTWCreationLog, LogData, @RM, @FM, False$)
Error_Services('Add', ErrorMessage)
end
Response = CreatedLotNumber
End Service
Service GenerateInitialLotOperationRecords(LotId)
ErrorMessage = ''
If LotID NE '' then
if RowExists('LOT', LotId) then
LotRec = Database_Services('ReadDataRow', 'LOT', LotId)
ProdID = LotRec<LOT_PROD_ID$>
If ProdID NE '' then
// Get product operations
ThisLotOperations = Lot_Services('GetPrescribedOperationsByProdId', ProdId)
If ThisLotOperations NE '' then
for each ProdOperationKey in ThisLotOperations using @FM
OperationRec = Database_Services('ReadDataRow', 'PRODUCT_OPERATION', ProdOperationKey)
Next operation
end else
ErrorMessage = 'No Operations found for ' : ProdId
end
end else
ErrorMessage = 'Prod ID not specified'
end
// ID will be LotNum + OperationID
// Get product operations
end else
ErrorMessage = 'Lot ID does not exist.'
end
end else
ErrorMessage = 'Lot ID was null'
end
If ErrorMessage NE '' then Error_Services('Add', ErrorMessage)
end service
Service GetPrescribedOperationsByProdId(ProdId, ProdType)
ErrorMsg = ''
ProdOperationKeys = ''
If ProdId NE '' then
Begin Case
Case ProdType = 'TW'
ProdRec = Database_Services('ReadDataRow', 'TEST_WAFER_PROD', ProdId)
ProdOperationKeys = ProdRec<TEST_WAFER_PROD_PRODUCT_OPERATIONS$>
Case Otherwise$
ErrorMsg = 'Error in ':Service:' service. No matching prod type.'
End Case
end else
ErrorMsg = 'Error in ':Service:' service. Null ProdId passed into service.'
end
If ErrorMsg EQ '' then
Response = ProdOperationKeys
end else
Error_Services('Add', ErrorMsg)
end
end service
Service CreateInitialLotOperationRecords(LotId)
ErrorMessage = ''
If LotId NE '' then
LotRec = Database_Services('ReadDataRow', 'LOT', LotId)
LotType = LotRec<LOT_TYPE$>
ProdId = LotRec<LOT_PROD_ID$>
ThisInitialProdOperations = Lot_Services('GetPrescribedOperationsByProdId', ProdId, LotType)
If Error_Services('NoError') AND ThisInitialProdOperations NE '' then
For each ProdOperation in ThisInitialProdOperations using @VM
ProdOperationRec = Database_Services('ReadDataRow', 'PRODUCT_OPERATION', ProdOperation)
OperationID = ProdOperationRec<PRODUCT_OPERATION_OPERATION_ID$>
OperationSequence = ProdOperationRec<PRODUCT_OPERATION_OPERATION_SEQUENCE$>
LotOperationRecID = Rti_Createguid()
If Not(RowExists('LOT_OPERATION', LotOperationRecID)) then
LotOperationRec = ''
LotOperationRec<LOT_OPERATION_LOT_ID$> = LotId
LotOperationRec<LOT_OPERATION_OPERATION_ID$> = OperationID
LotOperationRec<LOT_OPERATION_OPERATION_SEQUENCE$> = OperationSequence
LotOperationRec<LOT_OPERATION_REWORK$> = False$
Database_Services('WriteDataRow', 'LOT_OPERATION', LotOperationRecId, LotOperationRec)
TestRec = Database_Services('ReadDataRow', 'LOT', LotId)
end else
ErrorMessage = 'Error in ':Service:' service. Lot Operation already existed, cannot overwrite.'
end
Next Operation
end else
ErrorMessage = 'Error in ':Service:' service. Error getting prescribed operations for lot# ' : LotId
end
end else
ErrorMessage = 'Error in ':Service:' service. Null LotID passed into service.'
end
If ErrorMessage NE '' then Error_Services('Add', ErrorMessage)
end service
// Returns a @FM delimited list of operations in sequence
Service GetLotOperationSequence(LotId)
StartTick = GetTickCount()
MetricName = 'GetLotOperationSequence'
ErrorMsg = ''
LotOperationsInSequence = ''
If LotID NE '' then
// Get Operations
LotOperations = Xlate('LOT', LotId, LOT_LOT_OPERATIONS$, 'X')
for each LotOperation in LotOperations using @VM
ThisLotOperationSequence = Xlate('LOT_OPERATION', LotOperation, LOT_OPERATION_OPERATION_SEQUENCE$, 'X')
LotOperationsInSequence<ThisLotOperationSequence> = LotOperation
Next LotOperation
end else
ErrorMsg = 'Error in ':Service:' service. Null LotID passed into service.'
end
EndTick = GetTickCount()
Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick)
If ErrorMsg EQ '' then
Response = LotOperationsInSequence
end else
Error_Services('Add', ErrorMsg)
end
end service
Service GetLotCurrOperationId(LotId)
StartTick = GetTickCount()
MetricName = 'GetLotCurrOperationId'
ErrorMsg = ''
CurrOperation = ''
If LotID NE '' then
// Get them in sequence first
LotOperationsInSequence = Lot_Services('GetLotOperationSequence', LotId)
for each LotOperation in LotOperationsInSequence using @FM
ThisLotOperationStartDTM = Xlate('LOT_OPERATION', LotOperation, LOT_OPERATION_DATETIME_IN$, 'X')
ThisLotOperationEndDTM = Xlate('LOT_OPERATION', LotOperation, LOT_OPERATION_DATETIME_OUT$, 'X')
If ThisLotOperationEndDTM Eq '' then
CurrOperation = LotOperation
end
until CurrOperation
Next LotOperation
end else
ErrorMsg = 'Error in ':Service:' service. Null LotID passed into service'
end
Response = CurrOperation
EndTick = GetTickCount()
Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick)
If ErrorMsg NE '' then Error_Services('Add', ErrorMsg)
end service
Service GetLotCurrOperationName(LotId)
StartTick = GetTickCount()
MetricName = 'GetLotCurrOperationName'
ErrorMsg = ''
CurrOperationId = ''
CurrOperationName = ''
If LotID NE '' then
// Get them in sequence first
LotOperationsInSequence = Lot_Services('GetLotOperationSequence', LotId)
for each LotOperation in LotOperationsInSequence using @FM
ThisLotOperationStartDTM = Xlate('LOT_OPERATION', LotOperation, LOT_OPERATION_DATETIME_IN$, 'X')
ThisLotOperationEndDTM = Xlate('LOT_OPERATION', LotOperation, LOT_OPERATION_DATETIME_OUT$, 'X')
If ThisLotOperationEndDTM Eq '' then
CurrOperationId = LotOperation
CurrOperationName = Database_Services('ReadDataColumn', 'LOT_OPERATION', CurrOperationId, LOT_OPERATION_OPERATION_ID$, True$, 0, False$)
end
until CurrOperationName
Next LotOperation
end else
ErrorMsg = 'Error in ':Service:' service. Null LotID passed into service.'
end
EndTick = GetTickCount()
Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick)
If ErrorMsg EQ '' then
Response = CurrOperationName
end else
Error_Services('Add', ErrorMsg)
end
end service
Service AddLotOperationIntoSequence(LotId, NewOperationId, NewSequence, Rework)
ErrorMessage = ''
If LotId NE '' then
If NewSequence NE '' AND Num(NewSequence) then
// Get Current Operations in sequence
LotCurrOperation = Lot_Services('GetLotCurrOperationId', LotId)
CurrOperationSequence = Xlate('LOT_OPERATION', LotCurrOperation, LOT_OPERATION_OPERATION_SEQUENCE$, 'X')
If CurrOperationSequence LE NewSequence then
// Get Curr Operation Sequence
Done = False$
LotCurrOperationSequence = Lot_Services('GetLotOperationSequence', LotId)
for each Operation in LotCurrOperationSequence using @Fm setting OpPos
ThisOperationRec = Database_Services('ReadDataRow', 'LOT_OPERATION', Operation)
ThisOperationSequence = ThisOperationRec<LOT_OPERATION_OPERATION_SEQUENCE$>
If ThisOperationSequence GE NewSequence then
NewOperationSequence = ThisOperationSequence + 1
ThisOperationRec<LOT_OPERATION_OPERATION_SEQUENCE$> = NewOperationSequence
Database_Services('WriteDataRow', 'LOT_OPERATION', Operation, ThisOperationRec)
If Error_Services('HasError') then
Done = True$
ErrorMessage = Error_Services('GetMessage')
end
end
Until Done
Next Operation
If ErrorMessage EQ '' then
LotOperationRecID = RTI_CreateGUID()
If Not(RowExists('LOT_OPERATION', LotOperationRecID)) then
LotOperationRec = ''
LotOperationRec<LOT_OPERATION_LOT_ID$> = LotId
LotOperationRec<LOT_OPERATION_OPERATION_ID$> = NewOperationId
LotOperationRec<LOT_OPERATION_OPERATION_SEQUENCE$> = NewSequence
LotOperationRec<LOT_OPERATION_REWORK$> = Rework
Database_Services('WriteDataRow', 'LOT_OPERATION', LotOperationRecId, LotOperationRec)
end else
ErrorMessage = 'Error in ':Service:' service. Lot Operation already existed, cannot overwrite'
end
end
end else
ErrorMessage = 'Error in ':Service:' service. Not allowed to add new operations prior to current operation'
end
end else
ErrorMessage = 'Error in ':Service:' service. Null or invalid sequence passed to routine'
end
end else
ErrorMessage = 'Error in ':Service:' service. Null LotID passed into service.'
end
If ErrorMessage NE '' then Error_Services('Add', ErrorMessage)
end service
Service IsLotMovedIn(LotId)
StartTick = GetTickCount()
MetricName = 'IsLotMovedIn'
Response = ''
If RowExists('LOT', LotId) then
CurrOperId = Lot_Services('GetLotCurrOperationId', LotId)
CurrOperDtmIn = Database_Services('ReadDataColumn', 'LOT_OPERATION', CurrOperId, LOT_OPERATION_DATETIME_IN$, True$, 0, False$)
Response = ( (CurrOperDtmIn LE Datetime()) AND (CurrOperDtmIn NE '') )
end
EndTick = GetTickCount()
Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick)
end service
Service IsOperationCompleted(LotOperationId)
OperationCompleted = False$
ErrorMessage = ''
If RowExists('LOT_OPERATION', LotOperationId) then
LotOperationDateTimeOut = Database_Services('ReadDataColumn', 'LOT_OPERATION', LotOperationId, LOT_OPERATION_DATETIME_OUT$, True$, 0, False$)
If LotOperationDateTimeOut NE '' then OperationCompleted = true$
end else
ErrorMessage = 'Invalid lot operation id passed to routine.'
end
If ErrorMessage NE '' then
Error_Services('Add', 'Error in ' : Service : ' with Lot OperationId ' : LotOperationId : ' : ' : ErrorMessage)
end
Response = OperationCompleted
end service
Service StartLot(LotId, Operator)
StartTick = GetTickCount()
ErrorMessage = ''
If LotId NE '' then
If RowExists('LOT', LotId) then
Lot_Event_Services('CreateLotEvent', LotId, Datetime(), 'LOT_START', 'Lot started.', '', Operator)
If Error_Services('NoError') then
Lot_Services('MoveInLot', LotId, Operator)
If Error_Services('HasError') then ErrorMessage = Error_Services('GetMessage')
end else
ErrorMessage = Error_Services('GetMessage')
end
end else
ErrorMessage = 'Error in ':Service:' process for Lot id ' : LotId : '. Lot ID not found in LOT table.'
end
end else
ErrorMessage = 'Error in ':Service:' process. Lot id was not passed to routine.'
end
EndTick = GetTickCount()
Mona_Services('QueueLatencyAndCountMetrics', MonaResource, Service, StartTick, EndTick)
If ErrorMessage EQ '' then
LogData = ''
LogData<1> = LoggingDTM
LogData<2> = LotID
LogData<3> = Operator
LogData<4> = 'Successfully started lot.'
Logging_Services('AppendLog', objLotStartLog, LogData, @RM, @FM, False$)
end else
LogData = ''
LogData<1> = LoggingDTM
LogData<2> = LotID
LogData<3> = Operator
LogData<4> = 'Error starting lot.'
Logging_Services('AppendLog', objLotStartLog, LogData, @RM, @FM, False$)
Error_Services('Add', ErrorMessage)
end
end service
Service BeginRun(LotId, Operator, ToolId)
StartTick = GetTickCount()
ErrorMessage = ''
If ( (LotId NE '') and (Operator NE '') and (ToolId NE '') ) then
If RowExists('LOT', LotId) then
Lot_Event_Services('CreateLotEvent', LotId, Datetime(), 'BEGIN_RUN', 'Begin run', ToolId, Operator)
If Error_Services('HasError') then ErrorMessage = Error_Services('GetMessage')
end else
ErrorMessage = 'Error in ':Service:' process for Lot id ' : LotId : '. Lot ID not found in LOT table.'
end
end else
ErrorMessage = 'Error in ':Service:' process. Lot id, Operator, or ToolId was not passed to routine.'
end
EndTick = GetTickCount()
Mona_Services('QueueLatencyAndCountMetrics', MonaResource, Service, StartTick, EndTick)
If ErrorMessage EQ '' then
LogData = ''
LogData<1> = LoggingDTM
LogData<2> = LotID
LogData<3> = Operator
LogData<4> = ToolId
LogData<4> = 'Successfully began run.'
Logging_Services('AppendLog', objLotRunLog, LogData, @RM, @FM, False$)
end else
LogData = ''
LogData<1> = LoggingDTM
LogData<2> = LotID
LogData<3> = Operator
LogData<4> = ToolId
LogData<4> = 'Error beginning run.'
Logging_Services('AppendLog', objLotRunLog, LogData, @RM, @FM, False$)
Error_Services('Add', ErrorMessage)
end
end service
Service EndRun(LotId, Operator, ToolId)
StartTick = GetTickCount()
ErrorMessage = ''
If ( (LotId NE '') and (Operator NE '') and (ToolId NE '') ) then
If RowExists('LOT', LotId) then
Lot_Event_Services('CreateLotEvent', LotId, Datetime(), 'END_RUN', 'End run', ToolId, Operator)
If Error_Services('HasError') then ErrorMessage = Error_Services('GetMessage')
end else
ErrorMessage = 'Error in ':Service:' process for Lot id ' : LotId : '. Lot ID not found in LOT table.'
end
end else
ErrorMessage = 'Error in ':Service:' process. Lot id, Operator, or ToolId was not passed to routine.'
end
EndTick = GetTickCount()
Mona_Services('QueueLatencyAndCountMetrics', MonaResource, Service, StartTick, EndTick)
If ErrorMessage EQ '' then
LogData = ''
LogData<1> = LoggingDTM
LogData<2> = LotID
LogData<3> = Operator
LogData<4> = ToolId
LogData<4> = 'Successfully ended run.'
Logging_Services('AppendLog', objLotRunLog, LogData, @RM, @FM, False$)
end else
LogData = ''
LogData<1> = LoggingDTM
LogData<2> = LotID
LogData<3> = Operator
LogData<4> = ToolId
LogData<4> = 'Error ending run.'
Logging_Services('AppendLog', objLotRunLog, LogData, @RM, @FM, False$)
Error_Services('Add', ErrorMessage)
end
end service
Service MoveInLot(LotID, Operator)
StartTick = GetTickCount()
MetricName = 'MoveInLot'
ErrorMessage = ''
ThisLotCurrOperationID = ''
If LotId NE '' then
If RowExists('LOT', LotId) then
ThisLotRec = Database_Services('ReadDataRow', 'LOT', LotId)
WaferQty = ThisLotRec<LOT_WAFER_QTY$>
//Possibly Add locking here
If Error_Services('NoError') then
ThisLotCurrOperationID = Lot_Services('GetLotCurrOperationId', LotId)
If ThisLotCurrOperationID NE '' then
ThisLotCurrOperationRec = Database_Services('ReadDataRow', 'LOT_OPERATION', ThisLotCurrOperationID)
ThisLotCurrOperationRec<LOT_OPERATION_DATETIME_IN$> = Datetime()
ThisLotCurrOperationRec<LOT_OPERATION_WAFER_IN_QTY$> = WaferQty
ThisLotCurrOperationRec<LOT_OPERATION_OPERATOR_IN_ID$> = Operator
Database_Services('WriteDataRow', 'LOT_OPERATION', ThisLotCurrOperationID, ThisLotCurrOperationRec)
If Error_Services('NoError') then
LotType = XLATE('LOT', LotId, LOT_TYPE$, 'X')
CurrOperation = XLATE('LOT_OPERATION', ThisLotCurrOperationID, LOT_OPERATION_OPERATION_ID$, 'X')
If Error_Services('NoError') then
Lot_Event_Services('CreateLotEvent', LotId, Datetime(), 'MOVE_IN', 'Lot moved into operation ' : CurrOperation : '.', '', Operator)
If Error_Services('NoError') then
Lot_Event_Services('CreateLotEvent', LotId, Datetime(), 'ARRIVAL', 'Lot arrived at operation ' : CurrOperation : '.', '', Operator)
If Error_Services('HasError') then ErrorMessage = Error_Services('GetMessage')
end else
ErrorMessage = Error_Services('GetMessage')
end
end else
ErrorMessage = 'Error in Move In process for Lot id ' : LotId : '. ' : Error_Services('GetMessage')
end
end else
ErrorMessage = 'Error in Move In process for Lot id ' : LotId : '. Error writing to lot operation record. ' : Error_Services('GetMessage')
end
end else
ErrorMessage = 'Error in Move In process for Lot id ' : LotId : '. Error getting lots current operation.'
end
end else
ErrorMessage = 'Error in Move In process for Lot id ' : LotId : '. ' : Error_Services('GetMessage')
end
end else
ErrorMessage = 'Error in Move In process for Lot id ' : LotId : '. Lot ID not found in LOT table.'
end
end else
ErrorMessage = 'Error in Move In process. Lot id was not passed to routine.'
end
EndTick = GetTickCount()
Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick)
If ErrorMessage EQ '' then
LogData = ''
LogData<1> = LoggingDTM
LogData<2> = LotID
LogData<3> = Operator
LogData<4> = 'Successfully Moved Lot into operation ' : ThisLotCurrOperationID : '.'
Logging_Services('AppendLog', objLotMoveLog, LogData, @RM, @FM, False$)
end else
LogData = ''
LogData<1> = LoggingDTM
LogData<2> = LotID
LogData<3> = Operator
LogData<4> = 'Error moving Lot into operation ' : ThisLotCurrOperationID : '.'
Logging_Services('AppendLog', objLotMoveLog, LogData, @RM, @FM, False$)
Error_Services('Add', ErrorMessage)
end
end service
Service MoveOutLot(LotID, Operator)
StartTick = GetTickCount()
MetricName = 'MoveOutLot'
ErrorMessage = ''
ThisLotCurrOperationID = ''
If LotId NE '' then
If RowExists('LOT', LotId) then
ThisLotRec = Database_Services('ReadDataRow', 'LOT', LotId)
WaferQty = ThisLotRec<LOT_WAFER_QTY$>
If Error_Services('NoError') then
ThisLotCurrOperationID = Lot_Services('GetLotCurrOperationId', LotId)
If ThisLotCurrOperationID NE '' then
If Lot_Services('IsLotMovedIn', LotId) then
ThisLotCurrOperationRec = Database_Services('ReadDataRow', 'LOT_OPERATION', ThisLotCurrOperationID)
ThisLotCurrOperationRec<LOT_OPERATION_DATETIME_OUT$> = Datetime()
ThisLotCurrOperationRec<LOT_OPERATION_WAFER_OUT_QTY$> = WaferQty
ThisLotCurrOperationRec<LOT_OPERATION_OPERATOR_OUT_ID$> = Operator
Database_Services('WriteDataRow', 'LOT_OPERATION', ThisLotCurrOperationID, ThisLotCurrOperationRec)
If Error_Services('NoError') then
LotType = XLATE('LOT', LotId, LOT_TYPE$, 'X')
CurrOperation = XLATE('LOT_OPERATION', ThisLotCurrOperationID, LOT_OPERATION_OPERATION_ID$, 'X')
If Error_Services('NoError') then
Lot_Event_Services('CreateLotEvent', LotId, Datetime(), 'MOVE_OUT', 'Lot moved out of operation ' : CurrOperation : '.', '', Operator)
end else
ErrorMessage = 'Error in Move In process for Lot id ' : LotId : '. ' : Error_Services('GetMessage')
end
end else
ErrorMessage = 'Error in Move Out process for Lot id ' : LotId : '. Error writing to lot operation record. ' : Error_Services('GetMessage')
end
end else
CurrOperationName = Field(ThisLotCurrOperationID, '*', 2)
ErrorMessage = 'Error in Move Out process for Lot id ' : LotId : '. Cannot move out lot from ' :CurrOperationName: ' because it is not moved in.'
end
end else
ErrorMessage = 'Error in Move Out process for Lot id ' : LotId : '. Error getting lots current operation.'
end
end else
ErrorMessage = 'Error in Move Out process for Lot id ' : LotId : '. ' : Error_Services('GetMessage')
end
end else
ErrorMessage = 'Error in Move Out process for Lot id ' : LotId : '. Lot ID not found in LOT table.'
end
end else
ErrorMessage = 'Error in Move Out process. Lot id was not passed to routine.'
end
EndTick = GetTickCount()
Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick)
If ErrorMessage EQ '' then
LogData = ''
LogData<1> = LoggingDTM
LogData<2> = LotID
LogData<3> = Operator
LogData<4> = 'Successfully Moved Lot out of operation ' : ThisLotCurrOperationID : '.'
Logging_Services('AppendLog', objLotMoveLog, LogData, @RM, @FM, False$)
end else
LogData = ''
LogData<1> = LoggingDTM
LogData<2> = LotID
LogData<3> = Operator
LogData<4> = 'Error in Move Out process for Lot id ' : LotId : '. ' : ErrorMessage
Logging_Services('AppendLog', objLotMoveLog, LogData, @RM, @FM, False$)
Error_Services('Add', ErrorMessage)
end
end service
Service ConvertLotRecordToJson(LotId, ItemURL, CurrUser, FullObject=BOOLEAN)
ErrorMessage = ''
JsonString = ''
If FullObject EQ '' then FullObject = True$
If RowExists('LOT', LotId) then
objJSON = ''
If SRP_JSON(objJSON, 'New', 'Object') then
LotRec = Database_Services('ReadDataRow', 'LOT', LotId)
If Error_Services('NoError') then
If SRP_JSON(objLot, 'New', 'Object') then
SRP_JSON(objLot, 'SetValue', 'LotId', LotId)
SRP_JSON(objLot, 'SetValue', 'Type', LotRec<LOT_TYPE$>)
SRP_JSON(objLot, 'SetValue', 'ProdId', LotRec<LOT_PROD_ID$>)
Begin Case
Case LotRec<LOT_TYPE$> = 'TW'
ProdName = XLATE('TEST_WAFER_PROD', LotRec<LOT_PROD_ID$>, TEST_WAFER_PROD_PART_NAME$, 'X')
Case Otherwise$
ProdName = ''
End Case
SRP_JSON(objLot, 'SetValue', 'ProdName', ProdName)
SRP_JSON(objLot, 'SetValue', 'OrigWaferQty', LotRec<LOT_ORIG_WAFER_QTY$>)
SRP_JSON(objLot, 'SetValue', 'WaferQty', LotRec<LOT_WAFER_QTY$>)
SRP_JSON(objLot, 'SetValue', 'VendorPartNo', LotRec<LOT_VENDOR_PART_NO$>)
SRP_JSON(objLot, 'SetValue', 'VendorLotNo', LotRec<LOT_VENDOR_LOT_NO$>)
SRP_JSON(objLot, 'SetValue', 'Vendor', LotRec<LOT_VENDOR_CODE$>)
CurrOperation = Lot_Services('GetLotCurrOperationId', LotId)
CurrOperation = XLATE('LOT_OPERATION', CurrOperation, LOT_OPERATION_OPERATION_ID$, 'X')
SRP_JSON(objLot, 'SetValue', 'CurrOperation', CurrOperation)
MostRecentEventId = LotRec<LOT_MOST_RECENT_LOT_EVENT_ID$>
MostRecentEventDtmIConv = Xlate('LOT_EVENT', MostRecentEventId, LOT_EVENT_EVENT_DATETIME$, 'X')
MostRecentEventDtmOConv = OConv(MostRecentEventDtmIConv, 'DT')
SRP_JSON(objLot, 'SetValue', 'MostRecentEventDateTime', MostRecentEventDtmOConv)
If FullObject then
// Events Array
EventsArrayJson = ''
If SRP_Json(EventsArrayJson, 'New', 'Array') then
LotEventKeys = Lot_Event_Services('GetLotEventsInSequence', LotId)
for each LotEventKey in LotEventKeys using @FM
objEvent = ''
EventRec = Database_Services('ReadDataRow', 'LOT_EVENT', LotEventKey)
If SRP_Json(objEvent, 'New', 'Object') then
SRP_JSON(objEvent, 'SetValue', 'LotEventId', LotEventKey)
SRP_JSON(objEvent, 'SetValue', 'LotId', EventRec<LOT_EVENT_LOT_ID$>)
SRP_JSON(objEvent, 'SetValue', 'LotEventType', EventRec<LOT_EVENT_LOT_EVENT_TYPE$>)
SRP_JSON(objEvent, 'SetValue', 'EventDatetime', OConv(EventRec<LOT_EVENT_EVENT_DATETIME$>, 'DT'))
SRP_JSON(objEvent, 'SetValue', 'EventNote', EventRec<LOT_EVENT_EVENT_NOTE$>)
SRP_JSON(objEvent, 'SetValue', 'EquipmentId', EventRec<LOT_EVENT_EQUIPMENT_ID$>)
SRP_JSON(objEvent, 'SetValue', 'EventReduceWaferQty', EventRec<LOT_EVENT_EVENT_REDUCE_WAFER_QTY$>)
SRP_JSON(objEvent, 'SetValue', 'EventBonusWaferQty', EventRec<LOT_EVENT_EVENT_BONUS_WAFER_QTY$>)
SRP_JSON(objEvent, 'SetValue', 'EventBeginWaferQty', EventRec<LOT_EVENT_EVENT_BEGIN_WAFER_QTY$>)
SRP_JSON(objEvent, 'SetValue', 'EventEndWaferQty', EventRec<LOT_EVENT_EVENT_END_WAFER_QTY$>)
SRP_JSON(objEvent, 'SetValue', 'EventOperationId', EventRec<LOT_EVENT_EVENT_OPERATION_ID$>)
SRP_JSON(objEvent, 'SetValue', 'EventOperatorId', EventRec<LOT_EVENT_EVENT_OPERATOR_ID$>)
SRP_JSON(objEvent, 'SetValue', 'Sequence', EventRec<LOT_EVENT_SEQUENCE$>)
SRP_JSON(EventsArrayJson, 'Add', objEvent)
SRP_JSON(objEvent, 'Release')
end
Next LotEventKey
SRP_JSON(objLot, 'Set', 'LotEvents', EventsArrayJson)
SRP_JSON(EventsArrayJson, 'Release')
end else
ErrorMessage = 'Error Creating Events JSON Array'
end
// Operations Array
OperationsArrayJson = ''
If SRP_Json(OperationsArrayJson, 'New', 'Array') then
LotOperationKeys = Lot_Services('GetLotOperationSequence', LotId)
for each LotOperationKey in LotOperationKeys using @FM
objOperation = ''
OperationRec = Database_Services('ReadDataRow', 'LOT_OPERATION', LotOperationKey)
If SRP_Json(objOperation, 'New', 'Object') then
SRP_JSON(objOperation, 'SetValue', 'LotOperationId', LotOperationKey)
SRP_JSON(objOperation, 'SetValue', 'LotId', OperationRec<LOT_OPERATION_LOT_ID$>)
SRP_JSON(objOperation, 'SetValue', 'OperationId', OperationRec<LOT_OPERATION_OPERATION_ID$>)
SRP_JSON(objOperation, 'SetValue', 'DatetimeIn', OConv(OperationRec<LOT_OPERATION_DATETIME_IN$>, 'DT'))
SRP_JSON(objOperation, 'SetValue', 'DatetimeOut', Oconv(OperationRec<LOT_OPERATION_DATETIME_OUT$>, 'DT'))
SRP_JSON(objOperation, 'SetValue', 'EquipmentId', OperationRec<LOT_OPERATION_EQUIPMENT_ID$>)
SRP_JSON(objOperation, 'SetValue', 'WaferInQty', OperationRec<LOT_OPERATION_WAFER_IN_QTY$>)
SRP_JSON(objOperation, 'SetValue', 'WaferOutQty', OperationRec<LOT_OPERATION_WAFER_OUT_QTY$>)
SRP_JSON(objOperation, 'SetValue', 'OperatorInId', OperationRec<LOT_OPERATION_OPERATOR_IN_ID$>)
SRP_JSON(objOperation, 'SetValue', 'OperatorOutId', OperationRec<LOT_OPERATION_OPERATOR_OUT_ID$>)
SRP_JSON(objOperation, 'SetValue', 'OperationSequence', OperationRec<LOT_OPERATION_OPERATION_SEQUENCE$>)
SRP_JSON(objOperation, 'SetValue', 'Rework', OperationRec<LOT_OPERATION_REWORK$>)
SRP_JSON(objOperation, 'SetValue', 'DatetimeStart', OConv(OperationRec<LOT_OPERATION_DATETIME_START$>, 'DT'))
SRP_JSON(objOperation, 'SetValue', 'DatetimeStop', OConv(OperationRec<LOT_OPERATION_DATETIME_STOP$>, 'DT'))
SRP_JSON(OperationsArrayJson, 'Add', objOperation)
SRP_JSON(objOperation, 'Release')
end
Next LotOperationKey
SRP_JSON(objLot, 'Set', 'LotOperations', OperationsArrayJson)
SRP_JSON(OperationsArrayJson, 'Release')
end else
ErrorMessage = 'Error Creating Operations JSON Array'
end
end
SRP_JSON(objJSON, 'Set', 'Lot', objLot)
SRP_JSON(objLot, 'Release')
end else
ErrorMessage = 'Error creating new Lot Json Object'
end
end else
ErrorMessage = 'Error reading ':LotId:' from lot table.'
end
JsonString = SRP_JSON(objJSON, 'Stringify', 'Styled')
SRP_JSON(objJSON, 'Release')
end else
ErrorMessage = 'Error creating new Json Object'
end
end else
ErrorMessage = 'Invalid or null lot number passed to routine.'
end
If ErrorMessage EQ '' then
Response = JsonString
end else
Error_Services('Add', ErrorMessage)
end
end service
Service OpenLot(LotId)
StartTick = GetTickCount()
MetricName = 'OpenLot'
ErrorMessage = ''
If RowExists('LOT', LotId) then
LotRec = Database_Services('ReadDataRow', 'LOT', LotId, True$, 0, False$)
LotRec<LOT_OPEN$> = True$
Database_Services('WriteDataRow', 'LOT', LotId, LotRec, True$, False$, False$)
If Error_Services('NoError') then
Lot_Event_Services('CreateLotEvent', LotId, Datetime(), 'OPEN', 'Lot status set to Open.', '', 'SYSTEM')
end else
ErrorMessage = 'Error setting lot ' : LotId : ' to open.' : Error_Services('GetMessage')
end
end else
ErrorMessage = 'Unable to Open Lot ' : LotId : '. Lot ID was not found in LOT table.'
end
EndTick = GetTickCount()
Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick)
If ErrorMessage NE '' then Error_Services('Add', ErrorMessage)
end service
Service CloseLot(LotId)
StartTick = GetTickCount()
MetricName = 'CloseLot'
ErrorMessage = ''
If RowExists('LOT', LotId) then
LotRec = Database_Services('ReadDataRow', 'LOT', LotId, True$, 0, False$)
LotRec<LOT_OPEN$> = False$
Database_Services('WriteDataRow', 'LOT', LotId, LotRec, True$, False$, False$)
If Error_Services('NoError') then
Lot_Event_Services('CreateLotEvent', LotId, Datetime(), 'CLOSE', 'Lot status set to Closed', '', 'SYSTEM')
end else
ErrorMessage = 'Error setting lot ' : LotId : ' to closed.' : Error_Services('GetMessage')
end
end else
ErrorMessage = 'Unable to Close Lot ' : LotId : '. Lot ID was not found in LOT table.'
end
EndTick = GetTickCount()
Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick)
If ErrorMessage NE '' then Error_Services('Add', ErrorMessage)
end service
Service AutoCloseTestWaferLot(LotId, CloseUserId)
AutoCloseTime = Datetime()
ErrorMessage = ''
If MemberOf(CloseUserId, 'LEAD') OR MemberOf(CloseUserId, 'SUPERVISOR') OR CloseUserId EQ 'SYSTEM' then
LotOperations = Lot_Services('GetLotOperationSequence', LotId)
for LotOperationIndex = 1 to DCount(LotOperations, @FM)
ThisLotOperationId = LotOperations<LotOperationIndex>
ThisOperationCompleted = Lot_Services('IsOperationCompleted', ThisLotOperationId)
If Error_Services('NoError') then
if Not(ThisOperationCompleted) then
ThisLotOperationRec = Database_Services('ReadDataRow', 'LOT_OPERATION', ThisLotOperationId)
if Error_Services('NoError') then
CurrLotQty = Database_Services('ReadDataColumn', 'LOT', LotId, LOT_WAFER_QTY$, True$, 0, False$)
If ThisLotOperationRec<LOT_OPERATION_DATETIME_IN$> EQ '' then
ThisLotOperationRec<LOT_OPERATION_DATETIME_IN$> = AutoCloseTime
end
If ThisLotOperationRec<LOT_OPERATION_DATETIME_OUT$> EQ '' then
ThisLotOperationRec<LOT_OPERATION_DATETIME_OUT$> = AutoCloseTime
end
if ThisLotOperationRec<LOT_OPERATION_OPERATOR_IN_ID$> EQ '' then
ThisLotOperationRec<LOT_OPERATION_OPERATOR_IN_ID$> = CloseUserId
end
if ThisLotOperationRec<LOT_OPERATION_OPERATOR_OUT_ID$> EQ '' then
ThisLotOperationRec<LOT_OPERATION_OPERATOR_OUT_ID$> = CloseUserId
end
if ThisLotOperationRec<LOT_OPERATION_DATETIME_START$> EQ '' then
ThisLotOperationRec<LOT_OPERATION_DATETIME_START$> = AutoCloseTime
end
if ThisLotOperationRec<LOT_OPERATION_DATETIME_STOP$> EQ '' then
ThisLotOperationRec<LOT_OPERATION_DATETIME_STOP$> = AutoCloseTime
end
If ThisLotOperationRec<LOT_OPERATION_WAFER_IN_QTY$> EQ '' then
ThisLotOperationRec<LOT_OPERATION_WAFER_IN_QTY$> = CurrLotQty
end
If ThisLotOperationRec<LOT_OPERATION_WAFER_OUT_QTY$> EQ '' then
ThisLotOperationRec<LOT_OPERATION_WAFER_OUT_QTY$> = CurrLotQty
end
Database_Services('WriteDataRow', 'LOT_OPERATION', ThisLotOperationId, ThisLotOperationRec, True$, False$, False$)
If Error_Services('HasError') then
ErrorMessage = Error_Services('GetMessage')
end
end else
ErrorMessage = Error_Services('GetMessage')
end
end
end else
ErrorMessage = Error_Services('GetMessage')
end
Next LotOperationIndex
end else
ErrorMessage = CloseUserId : ' does not have permission to close this lot.'
end
If ErrorMessage EQ '' then
// Close Lot as there were no validation failures.
Lot_Services('CloseLot', LotId)
If Error_Services('NoError') then
LogData = ''
LogData<1> = LoggingDTM
LogData<2> = LotId
LogData<3> = CloseUserId
LogData<4> = 'Successfully marked lot as closed.'
Logging_Services('AppendLog', objLotClosureLog, LogData, @RM, @FM, False$)
end else
ErrorMessage = Error_Services('GetMessage')
LogData = ''
LogData<1> = LoggingDTM
LogData<2> = LotId
LogData<3> = CloseUserId
LogData<4> = 'Error marking lot as closed.' : ErrorMessage
Logging_Services('AppendLog', objLotClosureLog, LogData, @RM, @FM, False$)
// Send a message to FI
Recipients = Xlate('NOTIFICATION', 'FI_SUPPORT', NOTIFICATION_USER_ID$, 'X')
SentFrom = 'SYSTEM'
Subject = 'TEST WAFER LOT AUTO-CLOSURE FAILURE'
Message = 'Error in ' : service : ' with lot id ' : LotId : ' attempting to set CLOSE flag on lot. ' : ErrorMessage
Obj_Notes('Create',Recipients:@RM:SentFrom:@RM:Subject:@RM:Message)
Error_Services('Add', 'Error in ' : service : ' with lot ' : LotId : ':' : ErrorMessage)
end
end else
ErrorMessage = 'Error in ' : service : ' with lot ' : LotId : ':' : ErrorMessage
LogData = ''
LogData<1> = LoggingDTM
LogData<2> = LotId
LogData<3> = CloseUserId
LogData<4> = 'Error marking lot as closed.' : ErrorMessage
Logging_Services('AppendLog', objLotClosureLog, LogData, @RM, @FM, False$)
// Send a message to FI
Recipients = Xlate('NOTIFICATION', 'FI_SUPPORT', NOTIFICATION_USER_ID$, 'X')
SentFrom = 'SYSTEM'
Subject = 'TEST WAFER LOT AUTO-CLOSURE FAILURE'
Message = 'Error in ' : service : ' with lot id ' : LotId : ' attempting to Auto Close Lot. ' : ErrorMessage
Obj_Notes('Create',Recipients:@RM:SentFrom:@RM:Subject:@RM:Message)
Error_Services('Add', 'Error in ' : service : ' with lot ' : LotId : ':' : ErrorMessage)
end
end service
Service HoldLot(LotId, OperatorId)
StartTick = GetTickCount()
MetricName = 'HoldLot'
EndTick = GetTickCount()
Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick)
end service
Service UnholdLot(LotId, OperatorId)
StartTick = GetTickCount()
MetricName = 'UnholdLot'
EndTick = GetTickCount()
Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick)
end service
Service ReduceLotWaferCount(LotId, ReductionQty, OperatorId)
StartTick = GetTickCount()
MetricName = 'ReduceLotWaferCount'
ErrorMessage = ''
If RowExists('LOT', LotId) then
LotRec = Database_Services('ReadDataRow', 'LOT', LotId, True$, 0, False$)
LotType = LotRec<LOT_TYPE$>
LotHold = LotRec<LOT_HOLD$>
LotOpen = LotRec<LOT_OPEN$>
LotCurrWfrQty = LotRec<LOT_WAFER_QTY$>
LotNewWfrQty = LotCurrWfrQty - ReductionQty
If LotNewWfrQty LE 25 AND LotNewWfrQty GE 0 then
LotRec<LOT_WAFER_QTY$> = LotNewWfrQty
Database_Services('WriteDataRow', 'LOT', LotId, LotRec, True$, False$, False$)
If Error_Services('NoError') then
// Write Lot Event
Lot_Event_Services('CreateLotEvent', LotId, Datetime(), 'REDUCE_WAFER_QTY', 'Reduced wafer count by ' : ReductionQty, '', OperatorId, False$, '')
if LotNewWfrQty EQ 0 AND LotType EQ 'TW' then
ServiceParms = 'AutoCloseTestWaferLot' : @VM : LotId : @VM : 'SYSTEM'
Service_Services('PostProcedure', 'LOT_SERVICES', ServiceParms)
If Error_Services('HasError') then
Recipients = Xlate('NOTIFICATION', 'FI_SUPPORT', NOTIFICATION_USER_ID$, 'X')
SentFrom = 'SYSTEM'
Subject = 'TEST WAFER LOT AUTO-CLOSURE FAILURE'
Message = 'Error in ' : service : ' attempting to add auto lot closure for lot id ' : LotId : ' to the service queue.'
AttachWindow = ''
AttachKeys = ''
SendToGroup = ''
Obj_Notes('Create',Recipients:@RM:SentFrom:@RM:Subject:@RM:Message)
end
end
end else
ErrorMessage = 'Error in Increase Lot Wafer Count service, Error writing Lot Id ' : LotId : ' with new quantity.'
end
end else
Begin Case
Case LotNewWfrQty GT 25
ErrorMessage = 'Error in Reduce Lot Wafer Count service, Lot Id ' : LotId : ' cannot have a quantity great than 25.'
Case LotNewWfrQty LT 0
ErrorMessage = 'Error in Reduce Lot Wafer Count service, Lot Id ' : LotId : ' cannot have a quantity less than 0.'
End Case
end
end else
ErrorMessage = 'Error in Reduce Lot Wafer Count service, Lot Id ' : LotId : ' not found in lot table.'
end
EndTick = GetTickCount()
Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick)
If ErrorMessage NE '' then Error_Services('Add', ErrorMessage)
end service
Service IncreaseLotWaferCount(LotId, IncreaseQty, OperatorId)
StartTick = GetTickCount()
MetricName = 'IncreaseLotWaferCount'
ErrorMessage = ''
If RowExists('LOT', LotId) then
LotRec = Database_Services('ReadDataRow', 'LOT', LotId, True$, 0, False$)
LotHold = LotRec<LOT_HOLD$>
LotOpen = LotRec<LOT_OPEN$>
if LotOpen then
If Not(LotHold) then
LotCurrWfrQty = LotRec<LOT_WAFER_QTY$>
LotNewWfrQty = LotCurrWfrQty + IncreaseQty
If LotNewWfrQty LE 25 AND LotNewWfrQty GT 0 then
LotRec<LOT_WAFER_QTY$> = LotNewWfrQty
Database_Services('WriteDataRow', 'LOT', LotId, LotRec, True$, False$, False$)
If Error_Services('NoError') then
// Write Lot Event
Lot_Event_Services('CreateLotEvent', LotId, Datetime(), 'INCREASE_WAFER_QTY', 'Increased wafer count by ' : IncreaseQty, '', OperatorId, False$, '')
end else
ErrorMessage = 'Error in Increase Lot Wafer Count service, Error writing Lot Id ' : LotId : ' with new quantity.'
end
end else
Begin Case
Case LotNewWfrQty GT 25
ErrorMessage = 'Error in Increase Lot Wafer Count service, Lot Id ' : LotId : ' cannot have a quantity great than 25.'
Case LotNewWfrQty LT 0
ErrorMessage = 'Error in Increase Lot Wafer Count service, Lot Id ' : LotId : ' cannot have a quantity less than 0.'
End Case
end
end else
ErrorMessage = 'Error in Increase Lot Wafer Count service, Lot Id ' : LotId : ' is currently on hold.'
end
end else
ErrorMessage = 'Error in Increase Lot Wafer Count service, Lot Id ' : LotId : ' is closed.'
end
end else
ErrorMessage = 'Error in Increase Lot Wafer Count service, Lot Id ' : LotId : ' not found in lot table.'
end
EndTick = GetTickCount()
Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick)
If ErrorMessage NE '' then Error_Services('Add', ErrorMessage)
end service
Service OpenOIWizardCreateTWLotInBrowser()
Command = 'explorer https://goto.infineon.com/oiwizard/Lot/CreateTestWaferLot/'
SRP_Run_Command(Command)
end service
Service CreateNewVoidedLotRecord(LotId, LegacyLotId, LotType=LOT_TYPES, Username)
StartTick = GetTickCount()
MetricName = 'CreateNewVoidedLotRecord'
ErrorMessage = ''
If RowExists('LSL_USERS', Username) then
If LotType NE '' then
NewVoidedLotRecordId = RTI_CreateGUID()
If Not(RowExists('VOIDED_LOT', NewVoidedLotRecordId)) then
NewVoidedLotRec = ''
Begin Case
Case LotType EQ 'RDS'
WONo = XLate('RDS', LegacyLotId, RDS_WO$, 'X')
CassNo = XLATE('RDS', LotId, RDS_CASS_NO$, 'X')
WoMatKey = WONo : '*' : CassNo
If RowExists('RDS', LegacyLotId) then
WoNo = Field(LotId, '*', 1)
NewVoidedLotRec<VOIDED_LOT_WORK_ORDER_LOG_ID$> = WoNo
NewVoidedLotRec<VOIDED_LOT_ENTITY_TYPE$> = 'RDS'
NewVoidedLotRec<VOIDED_LOT_LEGACY_LOT_ID$> = LegacyLotId
end else
ErrorMessage = 'Error when creating a voided lot record for ' : LotId : ' of type ' : LotType : '. RDS record not found.'
end
Case LotType EQ 'WO_MAT'
If RowExists('WO_MAT', LegacyLotId) then
WoNo = Field(LotId, '*', 1)
NewVoidedLotRec<VOIDED_LOT_WORK_ORDER_LOG_ID$> = WoNo
NewVoidedLotRec<VOIDED_LOT_ENTITY_TYPE$> = 'WO_MAT'
NewVoidedLotRec<VOIDED_LOT_LEGACY_LOT_ID$> = LegacyLotId
end else
ErrorMessage = 'Error when creating a voided lot record for ' : LotId : ' of type ' : LotType : '. WoMat record not found.'
end
Case LotType EQ 'WM_IN'
If RowExists('WM_IN', LegacyLotId) then
WoNo = Field(LotId, '*', 1)
NewVoidedLotRec<VOIDED_LOT_WORK_ORDER_LOG_ID$> = WoNo
NewVoidedLotRec<VOIDED_LOT_ENTITY_TYPE$> = 'WM_IN'
NewVoidedLotRec<VOIDED_LOT_LEGACY_LOT_ID$> = LegacyLotId
end else
ErrorMessage = 'Error when creating a voided lot record for ' : LotId : ' of type ' : LotType : '. WM_IN record not found.'
end
Case LotType EQ 'WM_OUT'
If RowExists('WM_OUT', LegacyLotId) then
WoNo = Field(LotId, '*', 1)
NewVoidedLotRec<VOIDED_LOT_WORK_ORDER_LOG_ID$> = WoNo
NewVoidedLotRec<VOIDED_LOT_ENTITY_TYPE$> = 'WM_OUT'
NewVoidedLotRec<VOIDED_LOT_LEGACY_LOT_ID$> = LegacyLotId
end else
ErrorMessage = 'Error when creating a voided lot record for ' : LotId : ' of type ' : LotType : '. WM_OUT record not found.'
end
Case Otherwise$
ErrorMessage = 'Error when creating a voided lot record for ' : LotId : ' of type ' : LotType : '. Non supported lot type.'
End Case
If ErrorMessage EQ '' then
NewVoidedLotRec<VOIDED_LOT_VOID_BY$> = Username
NewVoidedLotRec<VOIDED_LOT_VOID_DTM$> = Datetime()
NewVoidedLotRec<VOIDED_LOT_LOT_ID$> = LotId
Database_Services('WriteDataRow', 'VOIDED_LOT', NewVoidedLotRecordId, NewVoidedLotRec)
If Error_Services('HasError') then
ErrorMessage = Error_Services('GetMessage')
end
end
end else
ErrorMessage = 'Go buy a lottery ticket, we ran into a GUID collision with an existing GUID ' : NewVoidedLotRecordId : ' when trying to create a Voided Lot record for ' : LotId
end
end else
ErrorMessage = 'Null lot type of passed to CreateVoidedLotRecord routine.'
end
end else
ErrorMessage = 'Username ' : Username : ' passed to CreateVoidedLotRecord routine does not exist.'
end
EndTick = GetTickCount()
Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick)
If ErrorMessage NE '' then Error_Services('Add', ErrorMessage)
end service
//----------------------------------------------------------------------------------------------------------------------
// Internal GoSubs
//----------------------------------------------------------------------------------------------------------------------