Moved call to MonA Metric setting above the local service error setting as the call to that MonA service was clearing out errors and preventing them from making their way back to the GUI.
841 lines
38 KiB
Plaintext
841 lines
38 KiB
Plaintext
Compile function TEST_RUN_Services(@Service, @Params)
|
|
#pragma precomp SRP_PreCompiler
|
|
$insert LOGICAL
|
|
$Insert APP_INSERTS
|
|
$Insert TEST_WAFER_PROD_EQUATES
|
|
$Insert TEST_WAFER_TYPES_DISPO_OPTIONS_EQUATES
|
|
$Insert TEST_RUN_EQUATES
|
|
$Insert TEST_RUN_WAFER_EQUATES
|
|
$Insert TEST_RUN_OBJ_EQUATES
|
|
$Insert LOT_EQUATES
|
|
$Insert LOT_OPERATION_EQUATES
|
|
|
|
Declare function Nextkey, Error_Services, Environment_Services, OConv, Logging_Services, SRP_Hashtable, Lot_Services, GetTickCount
|
|
Declare function SRP_Datetime, Database_Services, Test_Run_Services, File_Services, Status, delete, Insert, Datetime, SRP_Json, MemberOf
|
|
Declare subroutine Database_Services, Btree.Extract, Error_Services, Logging_Services, Rlist, Test_Run_Services, Lot_Services, SRP_Json
|
|
Declare subroutine Mona_Services
|
|
|
|
LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\TEST_RUN_SERVICES\TestWaferProduct'
|
|
LogDate = Oconv(Date(), 'D4/')
|
|
LogTime = Oconv(Time(), 'MTS')
|
|
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' Material Log.csv'
|
|
Headers = 'Logging DTM' : @FM : 'User' : @FM : 'Notes'
|
|
objLogTWP = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, Comma$, Headers, '', False$, False$)
|
|
|
|
LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\TEST_RUN_SERVICES\TestRun'
|
|
LogDate = Oconv(Date(), 'D4/')
|
|
LogTime = Oconv(Time(), 'MTS')
|
|
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' Material Log.csv'
|
|
Headers = 'Logging DTM' : @FM : 'User' : @FM : 'Notes'
|
|
objLogTR = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, Comma$, Headers, '', False$, False$)
|
|
|
|
LoggingDTM = LogDate : ' ' : LogTime ; // Logging DTM
|
|
|
|
IsProd = Environment_Services('IsProd')
|
|
If IsProd EQ True$ then
|
|
MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_TESTRUNSERVICES'
|
|
end else
|
|
MonaResource = 'GRP_OPENINSIGHT_MES_OP_FE_DEV_TESTRUNSERVICES'
|
|
end
|
|
|
|
GoToService
|
|
|
|
Return Response or ""
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// SERVICES
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
//Test Wafer Product Methods - related to TEST_WAFER_PROD table
|
|
|
|
/*
|
|
Create New Test Wafer Product
|
|
Creates a new entry in the TEST_WAFER_PROD table.
|
|
*/
|
|
Service CreateNewTestWaferProduct(ProductName)
|
|
If ProductName NE '' then
|
|
//Check for existing
|
|
table = 'TEST_WAFER_PROD'
|
|
Open "DICT ":table To @DICT Else
|
|
Error_Services('Add', 'Error opening Test wafer product table')
|
|
Return
|
|
End
|
|
Column = "PART_NAME"
|
|
Value = ProductName
|
|
search_criteria = Column:@VM:Value:@FM
|
|
keylist = ""
|
|
option = ""
|
|
flag = ""
|
|
Btree.Extract(search_criteria, table, @DICT, keylist, option, flag)
|
|
IF keylist EQ '' then
|
|
NewTestWaferProdRec = ''
|
|
NewTestWaferProdRec<TEST_WAFER_PROD_PART_NAME$> = ProductName
|
|
NewTestWaferProdKey = Nextkey('TEST_WAFER_PROD')
|
|
Database_Services('WriteDataRow', table, NewTestWaferProdKey, NewTestWaferProdRec)
|
|
If Error_Services('NoError') then
|
|
LogData = ''
|
|
LogData<1, 1> = LoggingDTM
|
|
LogData<1, 2> = @User4
|
|
LogData<1, 3> = 'Successfully created new product type with ID of ' : NewTestWaferProdKey
|
|
Logging_Services('AppendLog', objLogTWP, LogData, @FM, @VM)
|
|
Response = NewTestWaferProdKey
|
|
end else
|
|
//Todo Add Logging for failure
|
|
LogData = ''
|
|
|
|
LogData<1, 1> = LoggingDTM
|
|
LogData<1, 2> = @User4
|
|
LogData<1, 3> = 'Error Creating new test wafer product. ' : Error_Services('GetMessage')
|
|
Logging_Services('AppendLog', objLogTWP, LogData, @FM, @VM)
|
|
Response = ''
|
|
end
|
|
end else
|
|
|
|
LogData = ''
|
|
LogData<1, 1> = LoggingDTM
|
|
LogData<1, 2> = @User4
|
|
LogData<1, 3> = 'Error Creating new test wafer product. Product already exists!'
|
|
Logging_Services('AppendLog', objLogTWP, LogData, @FM, @VM)
|
|
Error_Services('Add', 'Product already exists!')
|
|
Response = ''
|
|
end
|
|
end else
|
|
//Todo Add logging for failure
|
|
LogData = ''
|
|
LogData<1, 1> = LoggingDTM
|
|
LogData<1, 2> = @User4
|
|
LogData<1, 3> = 'Product name was missing'
|
|
Logging_Services('AppendLog', objLogTWP, LogData, @FM, @VM)
|
|
Error_Services('Add', 'Product name was missing')
|
|
Response = ''
|
|
end
|
|
end service
|
|
|
|
Service DisableTWProd(TWProdKey)
|
|
If TWProdKey NE '' then
|
|
TWProdRec = Database_Services('ReadDataRow', 'TEST_WAFER_PROD', TWProdKey)
|
|
TWProdRec<TEST_WAFER_PROD_SORT_ORDER$> = 0
|
|
Database_Services('WriteDataRow', 'TEST_WAFER_PROD', TWProdKey, TWProdRec)
|
|
end else
|
|
Error_Services('Add', 'Error in TEST_RUN_SERVICES -> DisableTWProd: No TWProdKeySupplied')
|
|
end
|
|
end service
|
|
|
|
/*
|
|
Add disposition option to a test wafer product
|
|
Creates a new disposition entry in the TEST_WAFER_TYPES_DISPO_OPTION table, related to a TEST_WAFER_PROD record
|
|
*/
|
|
Service AddTestWaferProductDispo(TestWaferProdID, DispoName)
|
|
If TestWaferProdID NE '' then
|
|
IF DispoName NE '' then
|
|
MatchingIDs = False$
|
|
CurrentDispoIDs = XLATE('TEST_WAFER_PROD', TestWaferProdID, TEST_WAFER_PROD_WAFER_DISPO_IDS$, 'X')
|
|
For i = 1 to DCount(CurrentDispoIDs, @VM)
|
|
DispoID = CurrentDispoIDs<1, i>
|
|
DispoDescription = Xlate('TEST_WAFER_TYPES_DISPO_OPTIONS', DispoID, TEST_WAFER_TYPES_DISPO_OPTIONS_DISPO_DESCRIPTION$, 'X')
|
|
if DispoName EQ DispoDescription then MatchingIDs = true$
|
|
Until MatchingIDs
|
|
Next i
|
|
if NOT(MatchingIDs) then
|
|
NewTestWaferProdDispoRec = ''
|
|
NewTestWaferProdDispoRec<TEST_WAFER_TYPES_DISPO_OPTIONS_TEST_WAFER_PROD_ID$> = TestWaferProdID
|
|
NewTestWaferProdDispoRec<TEST_WAFER_TYPES_DISPO_OPTIONS_DISPO_DESCRIPTION$> = DispoName
|
|
NewTestWaferProdDispoKey = Nextkey('TEST_WAFER_TYPES_DISPO_OPTIONS')
|
|
Database_Services('WriteDataRow', 'TEST_WAFER_TYPES_DISPO_OPTIONS', NewTestWaferProdDispoKey, NewTestWaferProdDispoRec)
|
|
If Error_Services('NoError') then
|
|
LogData = ''
|
|
LogData<1, 1> = LoggingDTM
|
|
LogData<1, 2> = @User4
|
|
LogData<1, 3> = 'Dispo added to ' : TestWaferProdID : '. The dispo key is ' : NewTestWaferProdDispoKey
|
|
Logging_Services('AppendLog', objLogTWP, LogData, @FM, @VM)
|
|
end else
|
|
LogData = ''
|
|
LogData<1, 1> = LoggingDTM
|
|
LogData<1, 2> = @User4
|
|
LogData<1, 3> = 'Error adding dispo to TW Prod, ' : Error_Services('GetMessage')
|
|
Logging_Services('AppendLog', objLogTWP, LogData, @FM, @VM)
|
|
end
|
|
end else
|
|
LogData = ''
|
|
LogData<1, 1> = LoggingDTM
|
|
LogData<1, 2> = @User4
|
|
LogData<1, 3> = 'Error adding dispo to TW Prod. dispo option already existed.'
|
|
Logging_Services('AppendLog', objLogTWP, LogData, @FM, @VM)
|
|
Error_Services('Add', 'Error adding dispo to TW Prod. dispo option already existed.')
|
|
end
|
|
end else
|
|
LogData = ''
|
|
LogData<1, 1> = LoggingDTM
|
|
LogData<1, 2> = @User4
|
|
LogData<1, 3> = 'Error adding dispo to TW Prod. The dispo name was missing'
|
|
Logging_Services('AppendLog', objLogTWP, LogData, @FM, @VM)
|
|
end
|
|
end else
|
|
LogData = ''
|
|
LogData<1, 1> = LoggingDTM
|
|
LogData<1, 2> = @User4
|
|
LogData<1, 3> = 'Error adding dispo to TW Prod. The product name was missing'
|
|
Logging_Services('AppendLog', objLogTWP, LogData, @FM, @VM)
|
|
end
|
|
end service
|
|
|
|
Service DeleteTestWaferProductDispo(DispoID)
|
|
If DispoID NE '' then
|
|
If RowExists('TEST_WAFER_TYPES_DISPO_OPTIONS', DispoID) then
|
|
Database_Services('DeleteDataRow', 'TEST_WAFER_TYPES_DISPO_OPTIONS', DispoID, True$, False$)
|
|
end else
|
|
errorMessage = 'Error deleting dispo to TW Prod. The dispo id was not found.'
|
|
LogData = ''
|
|
LogData<1, 1> = LoggingDTM
|
|
LogData<1, 2> = @User4
|
|
LogData<1, 3> = errorMessage
|
|
Logging_Services('AppendLog', objLogTWP, LogData, @FM, @VM)
|
|
Error_Services('Add', errorMessage)
|
|
end
|
|
end else
|
|
errorMessage = 'Error deleting dispo to TW Prod. The dispo id was missing'
|
|
LogData = ''
|
|
LogData<1, 1> = LoggingDTM
|
|
LogData<1, 2> = @User4
|
|
LogData<1, 3> = errorMessage
|
|
Logging_Services('AppendLog', objLogTWP, LogData, @FM, @VM)
|
|
Error_Services('Add', errorMessage)
|
|
end
|
|
end service
|
|
|
|
Service GetAllTWProdKeysUnformatted()
|
|
keylist = ''
|
|
RList("SELECT TEST_WAFER_PROD WITH SORT_ORDER NE '' BY SORT_ORDER", 5, '', '', '')
|
|
Done = False$
|
|
Loop
|
|
Readnext TWProdKey else Done = True$
|
|
Until Done
|
|
keylist<-1> = TWProdKey
|
|
Repeat
|
|
|
|
Response = keylist
|
|
end service
|
|
|
|
Service GetAllTWProdKeys(ShowSorted)
|
|
keylist = ''
|
|
ProdList = ''
|
|
If ShowSorted then
|
|
RList("SELECT TEST_WAFER_PROD WITH SORT_ORDER NE 0 AND WITH SORT_ORDER NE '' BY SORT_ORDER", 5, '', '', '')
|
|
end else
|
|
RList("SELECT TEST_WAFER_PROD BY SORT_ORDER", 5, '', '', '')
|
|
end
|
|
|
|
Done = False$
|
|
Loop
|
|
Readnext TWProdKey else Done = True$
|
|
Until Done
|
|
keylist<1, -1> = TWProdKey
|
|
Repeat
|
|
for each ProdKey in keylist using @VM setting pPos
|
|
ProdName = Xlate('TEST_WAFER_PROD', ProdKey, TEST_WAFER_PROD_PART_NAME$, 'X')
|
|
if ProdName NE '' then
|
|
ProdList<1, pPos> = ProdKey
|
|
ProdList<2, pPos> = ProdName
|
|
end
|
|
Next ProdKey
|
|
Response = ProdList
|
|
end service
|
|
|
|
Service UpdateTWProdSortOrder(TWProdKey, NewOrder)
|
|
//First get current sort order
|
|
TWProdRec = Database_Services('ReadDataRow', 'TEST_WAFER_PROD', TWProdKey)
|
|
OldSortOrder = TWProdRec<TEST_WAFER_PROD_SORT_ORDER$>
|
|
AllTWProdsSorted = Test_Run_Services('GetAllTWProdKeysUnformatted')
|
|
//Get rid of all zero value sort orders
|
|
i = 1
|
|
LOOP
|
|
UNTIL AllTWProdsSorted<i> = ''
|
|
currSortOrder = Xlate('TEST_WAFER_PROD', AllTWProdsSorted<i>, TEST_WAFER_PROD_SORT_ORDER$, 'X')
|
|
If currSortOrder EQ 0 then
|
|
//Remove it from the list of TWProds with Sorting enabled. The zero's will screw up the next part.
|
|
AllTWProdsSorted = delete(AllTWProdsSorted, i, 0, 0)
|
|
end
|
|
i = i + 1
|
|
REPEAT
|
|
If NewOrder GT 0 then
|
|
AllTWProdsSorted = Insert(AllTWProdsSorted, NewOrder, 0, 0, TWProdKey)
|
|
//Locate the old order and remove it
|
|
i = 1
|
|
LOOP
|
|
UNTIL AllTWProdsSorted<i> = ''
|
|
If i NE NewOrder AND AllTWProdsSorted<i> EQ TWProdKey then
|
|
//Remove it from the list of TWProds with Sorting enabled. The zero's will screw up the next part.
|
|
AllTWProdsSorted = delete(AllTWProdsSorted, i, 0, 0)
|
|
end
|
|
i = i + 1
|
|
REPEAT
|
|
end else
|
|
//Disabling
|
|
Locate TWProdKey in AllTWProdsSorted using @FM setting tPos then
|
|
AllTWProdsSorted = delete(AllTWProdsSorted, tPos, 0, 0)
|
|
end
|
|
TWProdRecToWrite = Database_Services('ReadDataRow', 'TEST_WAFER_PROD', TWProdKey)
|
|
TWProdRecToWrite<TEST_WAFER_PROD_SORT_ORDER$> = 0
|
|
Database_Services('WriteDataRow', 'TEST_WAFER_PROD', TWProdKey, TWProdRecToWrite, 1, 0, 1)
|
|
end
|
|
//Rewrite the entire sort order for all prods
|
|
For each TWProd in AllTWProdsSorted using @FM setting SortOrder
|
|
TWProdRecToWrite = Database_Services('ReadDataRow', 'TEST_WAFER_PROD', TWProd)
|
|
TWProdRecToWrite<TEST_WAFER_PROD_SORT_ORDER$> = SortOrder
|
|
Database_Services('WriteDataRow', 'TEST_WAFER_PROD', TWProd, TWProdRecToWrite, 1, 0, 1)
|
|
Next TWProd
|
|
end service
|
|
|
|
Service GetAllTestRunTypes()
|
|
StartTick = GetTickCount()
|
|
MetricName = 'GetAllTestRunTypes'
|
|
|
|
keylist = ''
|
|
rtList = ''
|
|
RList('SELECT TEST_RUN_TYPE BY RUN_TYPE', 5, '', '', '')
|
|
Done = False$
|
|
Loop
|
|
Readnext RunTypeKey else Done = True$
|
|
Until Done
|
|
keylist<1, -1> = RunTypeKey
|
|
Repeat
|
|
for each RTKey in keylist using @VM setting rPos
|
|
RunTypeName = Xlate('TEST_RUN_TYPE', RTKey, TEST_RUN_TYPE_RUN_TYPE$, 'X')
|
|
if RunTypeName NE '' then
|
|
rtList<1, rPos> = RTKey
|
|
rtList<2, rPos> = RunTypeName
|
|
end
|
|
Next ProdKey
|
|
Response = rtList
|
|
|
|
EndTick = GetTickCount()
|
|
Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick)
|
|
end service
|
|
|
|
Service GetTestWaferLots(ShowOnlyOpenLots)
|
|
ErrorMessage = ''
|
|
TestWaferLotKeys = ''
|
|
SearchString = 'TYPE':@VM:'TW':@FM
|
|
If ShowOnlyOpenLots then
|
|
SearchString := 'OPEN':@VM:True$:@FM
|
|
end
|
|
Open 'DICT.LOT' to @DICT then
|
|
Btree.Extract(SearchString, 'LOT', @DICT, TestWaferLotKeys, '', '')
|
|
end else
|
|
ErrorMessage = 'Error opening LOT dictionary.'
|
|
end
|
|
If ErrorMessage NE '' then
|
|
Error_Services('Add', ErrorMessage)
|
|
end
|
|
Response = TestWaferLotKeys
|
|
end service
|
|
|
|
Service CreateTestRunRecord(RunTypeID, EqpType, EqpID, PSNo, RDSNo, UserID, TWLotIds, TWLotQtys)
|
|
StartTick = GetTickCount()
|
|
MetricName = 'CreateTestRunRecord'
|
|
|
|
TWRunKey = ''
|
|
Response = ''
|
|
ErrorMessage = ''
|
|
TWTrackingSystemActive = Database_Services('ReadDataColumn', 'APP_INFO', 'NEW_TW_SYSTEM_ACTIVE_SWITCH', 1, True$, 0, False$)
|
|
//Pre-Checks.
|
|
If TWTrackingSystemActive then
|
|
If TWLotIds NE '' then
|
|
for each TWLotId in TWLotIds using @VM setting twLotPos
|
|
ThisTWLotCurrQty = Database_Services('ReadDataColumn', 'LOT', TWLotId, LOT_WAFER_QTY$, True$, 0, False$)
|
|
If ThisTWLotCurrQty then
|
|
ThisTWLotUsageQty = TWLotQtys<1, twLotPos>
|
|
If ThisTWLotCurrQty LT ThisTWLotUsageQty then
|
|
ErrorMessage = 'Error in Create Test Run Record routine. Lot # ' : TWLotId : ' does not have enough wafers. Please choose ' : ThisTWLotCurrQty : ' wafers or less.'
|
|
end
|
|
end else
|
|
ErrorMessage = 'Error in Create Test Run Record routine. Lot # ' : TWLotId : ' has a zero wafer quantity.'
|
|
end
|
|
Until ErrorMessage NE ''
|
|
Next TWLotId
|
|
end else
|
|
ErrorMessage = 'Error in Create Test Run Record routine. No test wafer lots entered.'
|
|
end
|
|
end
|
|
If ErrorMessage EQ '' then
|
|
If RunTypeID NE '' AND EqpType NE '' AND EqpID NE '' AND UserID NE '' then
|
|
RunDTM = SRP_Datetime('Now')
|
|
TWRunRec = ''
|
|
TWRunRec<TEST_RUN_RUN_DTM$> = RunDTM
|
|
TWRunRec<TEST_RUN_RUN_TYPE_ID$> = RunTypeID
|
|
TWRunRec<TEST_RUN_EQUIPMENT_ID$> = EqpID
|
|
TWRunRec<TEST_RUN_EQUIPMENT_TYPE$> = EqpType
|
|
TWRunRec<TEST_RUN_PROD_SPEC_ID$> = PSNo
|
|
TWRunRec<TEST_RUN_LSL_USER_ID$> = UserID
|
|
TWRunRec<TEST_RUN_RDS_ID$> = RDSNo
|
|
TWRunKey = nextkey('TEST_RUN')
|
|
Database_Services('WriteDataRow', 'TEST_RUN', TWRunKey, TWRunRec)
|
|
If Error_Services('NoError') then
|
|
If RowExists('TEST_RUN', TWRunKey) then
|
|
LogData = ''
|
|
LogData<1, 1> = LoggingDTM
|
|
LogData<1, 2> = UserID
|
|
LogData<1, 3> = 'Successfully created new TEST_RUN record with ID of ' : TWRunKey
|
|
Logging_Services('AppendLog', objLogTR, LogData, @FM, @VM)
|
|
//Now create the test wafer usages
|
|
Success = False$
|
|
If TWLotIds NE '' then
|
|
//Supports new logging methods.
|
|
for each TWLotId in TWLotIds using @VM setting twlPos
|
|
LotRec = Database_Services('ReadDataRow', 'LOT', TWLotId, True$, 0, False$)
|
|
IsThisLotOnHold = LotRec<LOT_HOLD$>
|
|
IsThisLotOpen = LotRec<LOT_OPEN$>
|
|
IsThisLotATWLot = LotRec<LOT_TYPE$> EQ 'TW'
|
|
ThisLotCurrQty = LotRec<LOT_WAFER_QTY$>
|
|
ThisLotPartId = LotRec<LOT_PROD_ID$>
|
|
|
|
//
|
|
ThisUsageQty = TWLotQtys<1, twlPos>
|
|
|
|
If IsThisLotOpen then
|
|
If Not(IsThisLotOnHold) then
|
|
If IsThisLotATWLot then
|
|
InAtTWInUse = False$
|
|
Loop
|
|
LotMovedIn = Lot_Services('IsLotMovedIn', TWLotId)
|
|
ThisLotCurrOperationId = Lot_Services('GetLotCurrOperationId', TWLotId)
|
|
ThisLotCurrOperation = Database_Services('ReadDataColumn', 'LOT_OPERATION', ThisLotCurrOperationId, LOT_OPERATION_OPERATION_ID$, True$, 0, False$)
|
|
Begin Case
|
|
Case ThisLotCurrOperation EQ 'TW_IN_USE'
|
|
|
|
If Not(LotMovedIn) then
|
|
Lot_Services('MoveInLot', TWLotId, UserId)
|
|
If Error_Services('HasError') then
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
end else
|
|
InAtTWInUse = True$
|
|
end
|
|
|
|
Case ThisLotCurrOperation EQ 'TW_READY_TO_USE'
|
|
|
|
If Not(LotMovedIn) then
|
|
Lot_Services('MoveInLot', TWLotId, UserId)
|
|
end else
|
|
Lot_Services('MoveOutLot', TWLotId, UserId)
|
|
end
|
|
If Error_Services('HasError') then
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
Case Otherwise$
|
|
ErrorMessage = 'Error: Lot ':TWLotId:' is currently at ' : ThisLotCurrOperation : '. It cannot be used at this time.'
|
|
End Case
|
|
Until ErrorMessage NE '' Or InAtTWInUse
|
|
Repeat
|
|
If InAtTWInUse then
|
|
if Num(ThisUsageQty) then
|
|
If ThisUsageQty GT 0 then
|
|
//Now check that the usage QTY can be consumed from the TW Lot
|
|
ThisLotCurrQty = Database_Services('ReadDataColumn', 'LOT', TWLotId, LOT_WAFER_QTY$, True$, 0, False$)
|
|
If ThisUsageQty LE ThisLotCurrQty then
|
|
|
|
Abort = false$
|
|
for i = 1 to ThisUsageQty
|
|
Test_Run_Services('CreateTestRunWaferRecord',TWRunKey, ThisLotPartId, RunTypeID, TWLotId, UserID)
|
|
If Error_Services('HasError') then
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
until ErrorMessage NE ''
|
|
Next i
|
|
If ErrorMessage EQ '' then
|
|
Lot_Services('ReduceLotWaferCount', TWLotId, ThisUsageQty, UserID)
|
|
end
|
|
end else
|
|
ErrorMessage = 'Error in Create Test Run Record routine, ' : TWLotId : ' does not have enough wafers.'
|
|
end
|
|
end
|
|
end else
|
|
ErrorMessage = 'Error in Create Test Run Record routine, Invalid qty for lot ' : TWLotId : ' passed to routine.'
|
|
end
|
|
end
|
|
|
|
end else
|
|
//Lot is not classified as a test wafer lot.
|
|
end
|
|
end else
|
|
//Lot is on hold
|
|
end
|
|
end else
|
|
//Lot is not open
|
|
end
|
|
until ErrorMessage NE ''
|
|
Next TWLotId
|
|
If ErrorMessage EQ '' then
|
|
//commit everything
|
|
end else
|
|
//commit nothing, there was an error.
|
|
end
|
|
end else
|
|
//Supports legacy TW logging
|
|
Response = TWRunKey
|
|
end
|
|
end else
|
|
ErrorMessage = 'Error in Create Test Run Record routine, Generated Test Run Key did not exist in TEST Run table.'
|
|
end
|
|
|
|
Response = TWRunKey
|
|
end else
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
end
|
|
end else
|
|
If RunTypeID EQ '' then
|
|
ErrorMessage := 'Run Type ID Missing. '
|
|
end
|
|
If EqpType EQ '' then
|
|
ErrorMessage := 'Equipment Type ID Missing. '
|
|
end
|
|
If EqpID EQ '' then
|
|
ErrorMessage := 'Equipment ID Missing. '
|
|
end
|
|
If UserID EQ '' then
|
|
ErrorMessage := 'User ID Missing. '
|
|
end
|
|
end
|
|
end
|
|
|
|
EndTick = GetTickCount()
|
|
Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick)
|
|
|
|
If ErrorMessage NE '' then
|
|
LogData = ''
|
|
LogData<1, 1> = LoggingDTM
|
|
LogData<1, 2> = @User4
|
|
LogData<1, 3> = 'Error writing TEST_RUN Record ' : TWRunKey : ': ' : ErrorMessage
|
|
Logging_Services('AppendLog', objLogTR, LogData, @FM, @VM)
|
|
Error_Services('Add', ErrorMessage)
|
|
Response = ''
|
|
end
|
|
|
|
|
|
end service
|
|
|
|
Service CreateTestRunWaferRecord(TestRunID, TWPartID, TWUsageTypeID, SourceLotId, Username)
|
|
StartTick = GetTickCount()
|
|
MetricName = 'CreateTestRunWaferRecord'
|
|
|
|
ErrorMessage = ''
|
|
If TestRunID NE '' AND TWPartID NE '' then
|
|
If RowExists('TEST_RUN', TestRunID) then
|
|
//Legacy Code: Pre LOT usage
|
|
TRWaferRec = ''
|
|
TRWaferRec<TEST_RUN_WAFER_TEST_RUN_ID$> = TestRunID
|
|
TRWaferRec<TEST_RUN_WAFER_TEST_WAFER_PROD_ID$> = TWPartID
|
|
TRWaferRec<TEST_RUN_WAFER_TEST_USAGE_TYPE_ID$> = TWUsageTypeID
|
|
TRWaferRec<TEST_RUN_WAFER_SOURCE_LOT_ID$> = SourceLotID
|
|
TRWaferKey = Nextkey('TEST_RUN_WAFER')
|
|
Database_Services('WriteDataRow', 'TEST_RUN_WAFER', TRWaferKey, TRWaferRec)
|
|
If Error_Services('NoError') AND RowExists('TEST_RUN_WAFER', TRWaferKey) then
|
|
LogData = ''
|
|
LogData<1, 1> = LoggingDTM
|
|
LogData<1, 2> = @User4
|
|
LogData<1, 3> = 'Successfully wrote ' : TRWaferKey : ' to the TEST_RUN_WAFER table.'
|
|
Logging_Services('AppendLog', objLogTR, LogData, @FM, @VM)
|
|
//Increment Usage in TEST_WAFER_PROD Record
|
|
If ErrorMessage = '' then
|
|
Test_Run_Services('IncrementTWProdUsage', TWPartID)
|
|
Response = TRWaferKey
|
|
end
|
|
end else
|
|
ErrorMessage := 'Error writing TEST_RUN_WAFER record with key of ' : TRWaferKey '. '
|
|
end
|
|
end else
|
|
ErrorMessage := 'Unable to find parent TEST_RUN record. '
|
|
end
|
|
end else
|
|
If TestRunID EQ '' then
|
|
ErrorMessage := 'TestRunID parameter was not passed to CreateTestRunWaferRecord method. '
|
|
end
|
|
If TWPartID EQ '' then
|
|
ErrorMessage := 'TWPartID parameter was not passed to CreateTestRunWaferRecord method. '
|
|
end
|
|
end
|
|
|
|
EndTick = GetTickCount()
|
|
Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick)
|
|
|
|
If ErrorMessage NE '' then
|
|
LogData = ''
|
|
LogData<1, 1> = LoggingDTM
|
|
LogData<1, 2> = @User4
|
|
LogData<1, 3> = 'Error Writing to the TEST_RUN_WAFER table. ' : ErrorMessage
|
|
Logging_Services('AppendLog', objLogTR, LogData, @FM, @VM)
|
|
Error_Services('Add', 'Error creating new test run record: ' : ErrorMessage)
|
|
end
|
|
|
|
end service
|
|
|
|
Service UseTWFromLot(LotId, UsageQty, Username)
|
|
ErrorMessage = ''
|
|
If RowExists('LOT', LotId) then
|
|
Lot_Services('ReduceLotWaferCount', LotId, UsageQty, Username)
|
|
end else
|
|
ErrorMessage = 'Error logging wafer consumption from Lot # ' : LotId : '. Lot does not exist in LOT table.'
|
|
end
|
|
If ErrorMessage EQ '' then
|
|
|
|
end else
|
|
//Log Error
|
|
end
|
|
end service
|
|
|
|
Service GetTestRunById(TestRunID)
|
|
If TestRunID NE '' then
|
|
If RowExists('TEST_RUN', TestRunID) then
|
|
TRRec = Database_Services('ReadDataRow', 'TEST_RUN', TestRunID)
|
|
Response = TRRec
|
|
end else
|
|
Error_Services('Add', 'Test Run ID does not exist in TEST_RUN table')
|
|
end
|
|
end else
|
|
Error_Services('Add', 'Test Run ID parameter was not passed to routine.')
|
|
end
|
|
end service
|
|
|
|
Service IncrementTWProdUsage(TWProdKey)
|
|
If TWProdKey NE '' then
|
|
TWProdRec = Database_Services('ReadDataRow', 'TEST_WAFER_PROD', TWProdKey)
|
|
TWProdRec<TEST_WAFER_PROD_USAGE$> = TWProdRec<TEST_WAFER_PROD_USAGE$> + 1
|
|
Database_Services('WriteDataRow', 'TEST_WAFER_PROD', TWProdKey, TWProdRec)
|
|
end
|
|
end service
|
|
|
|
Service GetTestRunObj(TestRunID)
|
|
TestRunObj = ''
|
|
TestRunRec = Test_Run_Services('GetTestRunById', TestRunID)
|
|
//Start getting translated values for object
|
|
TestRunObj<TEST_RUN_OBJ_TEST_RUN_ID$> = TestRunID
|
|
TestRunObj<TEST_RUN_OBJ_RUN_DTM$> = OConv(TestRunRec<TEST_RUN_RUN_DTM$>, 'DT')
|
|
TestRunObj<TEST_RUN_OBJ_RUN_TYPE$> = Xlate('TEST_RUN_TYPE', TestRunRec<TEST_RUN_RUN_TYPE_ID$>, TEST_RUN_TYPE_RUN_TYPE$, 'X')
|
|
TestRunObj<TEST_RUN_OBJ_EQUIPMENT_ID$> = TestRunRec<TEST_RUN_EQUIPMENT_ID$>
|
|
EqpType = TestRunRec<TEST_RUN_EQUIPMENT_TYPE$>
|
|
Begin Case
|
|
Case EqpType EQ 'R'
|
|
TestRunObj<TEST_RUN_OBJ_EQUIPMENT_TYPE$> = 'Reactor'
|
|
Case EqpType EQ 'T'
|
|
TestRunObj<TEST_RUN_OBJ_EQUIPMENT_TYPE$> = 'Non-Reactor'
|
|
End Case
|
|
TestRunObj<TEST_RUN_OBJ_PROD_SPEC_ID$> = TestRunRec<TEST_RUN_PROD_SPEC_ID$>
|
|
TestRunObj<TEST_RUN_OBJ_LSL_USER_ID$> = TestRunRec<TEST_RUN_LSL_USER_ID$>
|
|
TestRunObj<TEST_RUN_OBJ_RDS_ID$> = TestRunRec<TEST_RUN_RDS_ID$>
|
|
|
|
TWKeys = TestRunRec<TEST_RUN_TEST_RUN_WAFER_IDS$>
|
|
TWUsageProds = ''
|
|
TWUsageQtys = ''
|
|
for each TWKey in TWKeys using @VM setting tPos
|
|
TRWRec = Test_Run_Services('GetTestRunWaferByID', TWKey)
|
|
TestWaferProdName = XLATE('TEST_WAFER_PROD', TRWRec<TEST_RUN_WAFER_TEST_WAFER_PROD_ID$>, TEST_WAFER_PROD_PART_NAME$, 'X')
|
|
Locate TestWaferProdName in TWUsageProds setting iPos then
|
|
TWUsageProds<1,iPos> = TestWaferProdName
|
|
TWUsageQtys<1,iPos> = TWUsageQtys<1,iPos> + 1
|
|
end else
|
|
TWUsageProds<1,-1> = TestWaferProdName
|
|
TWUsageQtys<1,-1> = 1
|
|
end
|
|
Next TWKey
|
|
TestRunObj<TEST_RUN_OBJ_TEST_RUN_WAFER_PRODS$> = TWUsageProds
|
|
TestRunObj<TEST_RUN_OBJ_TEST_RUN_WAFER_PRODS_QTYS$> = TWUsageQtys
|
|
|
|
Response = TestRunObj
|
|
end service
|
|
|
|
Service GetTestWaferUsageByDateSpan(StartDtm, StopDtm)
|
|
|
|
TestWaferData = ''
|
|
if StopDTM EQ '' then
|
|
StopDTM = SRP_Datetime('Now')
|
|
end
|
|
If StartDTM EQ '' then
|
|
StartDTM = SRP_Datetime('AddDays', StopDtm, -30)
|
|
end
|
|
//Get a list of Test Run keys
|
|
TestRunKeys = Test_Run_Services('GetTestRunKeysByDateSpan', StartDtm, StopDtm)
|
|
|
|
For each TestRunKey in TestRunKeys using @VM setting tPos
|
|
//Get all Product usages and their quantities
|
|
TestRunRec = Database_Services('ReadDataRow', 'TEST_RUN', TestRunKey)
|
|
TWUsageKeys = TestRunRec<TEST_RUN_TEST_RUN_WAFER_IDS$>
|
|
TWUsageData = ''
|
|
for each TWUsageKey in TWUsageKeys using @VM setting twPos
|
|
TWProdTypeKey = Xlate('TEST_RUN_WAFER', TWUsageKey, TEST_RUN_WAFER_TEST_WAFER_PROD_ID$, 'X')
|
|
TWProdType = Xlate('TEST_WAFER_PROD', TWProdTypeKey, TEST_WAFER_PROD_PART_NAME$, 'X')
|
|
Locate TWProdType in TWUsageData<1> using @VM setting twuPos then
|
|
TWUsageData<2, twuPos> = TWUsageData<2, twuPos> + 1
|
|
end else
|
|
TWUsageData<1, -1> = TWProdType
|
|
TWUsageData<2, -1> = 1
|
|
end
|
|
|
|
|
|
Next TWUsageKey
|
|
|
|
For each TWUsage in TWUsageData<1> using @VM setting aPos
|
|
TWLine = ''
|
|
TWLine<1, TEST_RUN_OBJ_TEST_RUN_ID$> = TestRunKey
|
|
TWLine<1, TEST_RUN_OBJ_RUN_DTM$> = OConv(TestRunRec<TEST_RUN_RUN_DTM$>, 'DT')
|
|
TWLine<1, TEST_RUN_OBJ_RUN_TYPE$> = XLATE('TEST_RUN_TYPE', TestRunRec<TEST_RUN_RUN_TYPE_ID$>, 'RUN_TYPE', 'X')
|
|
TWLine<1, TEST_RUN_OBJ_EQUIPMENT_ID$> = TestRunRec<TEST_RUN_EQUIPMENT_ID$>
|
|
TWLine<1, TEST_RUN_OBJ_EQUIPMENT_TYPE$> = TestRunRec<TEST_RUN_EQUIPMENT_TYPE$>
|
|
TWLine<1, TEST_RUN_OBJ_PROD_SPEC_ID$> = TestRunRec<TEST_RUN_PROD_SPEC_ID$>
|
|
TWLine<1, TEST_RUN_OBJ_LSL_USER_ID$> = TestRunRec<TEST_RUN_LSL_USER_ID$>
|
|
TWLine<1, TEST_RUN_OBJ_RDS_ID$> = TestRunRec<TEST_RUN_RDS_ID$>
|
|
TWLine<1, TEST_RUN_OBJ_TEST_RUN_WAFER_PRODS$> = TWUsage
|
|
TWLine<1, TEST_RUN_OBJ_TEST_RUN_WAFER_PRODS_QTYS$> = TWUsageData<2, aPos>
|
|
TestWaferData<-1> = TWLine
|
|
Next TWUsage
|
|
Next TestRunKey
|
|
|
|
Response = TestWaferData
|
|
end service
|
|
|
|
Service GetTestRunKeysByDateSpan(StartDtm, StopDtm)
|
|
Begin Case
|
|
Case StartDTM EQ '' AND StopDTM EQ ''
|
|
//Set search date for last 24 hour period
|
|
StopDTM = SRP_Datetime('Now')
|
|
StartDTM = SRP_Datetime('AddHours', StopDTM, -24)
|
|
Case StartDTM EQ '' AND StopDTM NE ''
|
|
//Set search start date 24 hours prior to stopDTM
|
|
StartDTM = SRP_Datetime('AddHours', StopDTM, -24)
|
|
Case StartDTM NE '' AND StopDTM EQ ''
|
|
//Set search start date to current dtm
|
|
StopDTM = SRP_Datetime('Now')
|
|
End Case
|
|
|
|
table = "TEST_RUN"
|
|
Open "DICT ":table To @DICT Else
|
|
Error_Services('Add', 'Error opening TEST_RUN dictionary')
|
|
End
|
|
If Error_Services('NoError') then
|
|
srch_strng = "RUN_DTM":@VM:StartDTM:'~':StopDTM:@FM
|
|
keylist = ""
|
|
option = ""
|
|
flag = ""
|
|
Btree.Extract(srch_strng, table, @DICT, keylist, option, flag)
|
|
Response = keylist
|
|
end
|
|
|
|
|
|
|
|
end service
|
|
|
|
Service GetTestRunKeysByEqp(EquipType, EquipID)
|
|
|
|
end service
|
|
|
|
Service GetTestRunKeysByEqpType(EqpType)
|
|
|
|
end service
|
|
|
|
Service GetTestRunKeysByPSN(PSNo)
|
|
|
|
end service
|
|
|
|
Service GetTestRunKeysByRDS(RDSNo)
|
|
StartTick = GetTickCount()
|
|
MetricName = 'GetTestRunKeysByRDS'
|
|
|
|
table = "TEST_RUN"
|
|
Open "DICT ":table To @DICT Else
|
|
Error_Services('Add', 'Error opening TEST_RUN dictionary')
|
|
End
|
|
If Error_Services('NoError') then
|
|
srch_strng = "RDS_ID":@VM:RDSNo:@FM
|
|
keylist = ""
|
|
option = ""
|
|
flag = ""
|
|
Btree.Extract(srch_strng, table, @DICT, keylist, option, flag)
|
|
Response = keylist
|
|
end
|
|
|
|
EndTick = GetTickCount()
|
|
Mona_Services('QueueLatencyAndCountMetrics', MonaResource, MetricName, StartTick, EndTick)
|
|
end service
|
|
|
|
Service GetTestRunWaferByID(TRWaferID)
|
|
If TRWaferID NE '' then
|
|
If RowExists('TEST_RUN_WAFER', TRWaferID) then
|
|
Response = Database_Services('ReadDataRow', 'TEST_RUN_WAFER', TRWaferID)
|
|
If Error_Services('HasError') then
|
|
Response = ''
|
|
Error_Services('Add', 'Error reading TEST_RUN_WAFER record with ID ' : TRWaferID)
|
|
end
|
|
end else
|
|
Error_Services('Add', 'No TEST_RUN_WAFER record found that matches key value.')
|
|
end
|
|
end else
|
|
Error_Services('Add', 'TRWaferID was null')
|
|
end
|
|
end service
|
|
|
|
Service GetTestRunWaferKeysByProdID(ProdID)
|
|
|
|
end service
|
|
|
|
Service GenerateTWCSVReport(StartDTM, StopDTM, SavePath)
|
|
If SavePath NE '' then
|
|
CSVData = 'ID' : @VM : 'Run Time' : @VM : 'Test Run Type' : @VM : 'Equipment ID' : @VM : 'Equipment Type' : @VM : 'PSN' : @VM : 'User' : @VM : 'RDS' : @VM : 'Test Wafer Type' : @VM : 'Wfr Qty' : @FM
|
|
CSVData := Test_Run_Services('GetTestWaferUsageByDateSpan', StartDTM, StopDTM)
|
|
swap @VM with ',' in CSVData
|
|
swap @FM with CRLF$ in CSVData
|
|
If Not(File_Services('CheckFileExtension', SavePath, 'csv')) then
|
|
SavePath = SavePath : '.csv'
|
|
end
|
|
OSWrite CSVData To SavePath
|
|
WriteFailure = Status()
|
|
If WriteFailure then
|
|
Begin Case
|
|
Case WriteFailure EQ 1
|
|
Error_Services('Add', 'Error in TEST_RUN_SERVICES -> GenerateTWCSVReport, Bad OS filename.')
|
|
Case WriteFailure EQ 2
|
|
Error_Services('Add', 'Error in TEST_RUN_SERVICES -> GenerateTWCSVReport, Access denied by operating system.')
|
|
Case WriteFailure EQ 3
|
|
Error_Services('Add', 'Error in TEST_RUN_SERVICES -> GenerateTWCSVReport, Disk or directory full.')
|
|
Case WriteFailure EQ 4
|
|
Error_Services('Add', 'Error in TEST_RUN_SERVICES -> GenerateTWCSVReport, File does not exist.')
|
|
Case WriteFailure EQ 5
|
|
Error_Services('Add', 'Error in TEST_RUN_SERVICES -> GenerateTWCSVReport, Unknown error.')
|
|
Case WriteFailure EQ 6
|
|
Error_Services('Add', 'Error in TEST_RUN_SERVICES -> GenerateTWCSVReport, Attempt to write to a read-only file.')
|
|
End Case
|
|
end
|
|
end else
|
|
Error_Services('Add', 'Error in TEST_RUN_SERVICES -> GenerateTWCSVReport, No SavePath provided.')
|
|
end
|
|
|
|
end service
|
|
|
|
Service IsNewTWSystemActive(UserId)
|
|
IsTWSystemActive = False$
|
|
If UserId EQ '' then
|
|
UserId = @USER4
|
|
end
|
|
TWTrackingSystemActive = Database_Services('ReadDataColumn', 'APP_INFO', 'NEW_TW_SYSTEM_ACTIVE_SWITCH', 1, True$, 0, False$)
|
|
If TWTrackingSystemActive EQ True$ then
|
|
IsTWSystemActive = True$
|
|
end else
|
|
If MemberOf(UserId, 'TW_TRACKING_TEST') then
|
|
IsTWSystemActive = True$
|
|
end
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|