1521 lines
65 KiB
Plaintext
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
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
|
|
|