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 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 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 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 = 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 = 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 = TestWaferProdID NewTestWaferProdDispoRec = 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 AllTWProdsSorted = Test_Run_Services('GetAllTWProdKeysUnformatted') //Get rid of all zero value sort orders i = 1 LOOP UNTIL AllTWProdsSorted = '' currSortOrder = Xlate('TEST_WAFER_PROD', AllTWProdsSorted, 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 = '' If i NE NewOrder AND AllTWProdsSorted 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 = 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 = SortOrder Database_Services('WriteDataRow', 'TEST_WAFER_PROD', TWProd, TWProdRecToWrite, 1, 0, 1) Next TWProd end service Service 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 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) 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 = RunDTM TWRunRec = RunTypeID TWRunRec = EqpID TWRunRec = EqpType TWRunRec = PSNo TWRunRec = UserID TWRunRec = 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 IsThisLotOpen = LotRec IsThisLotATWLot = LotRec EQ 'TW' ThisLotCurrQty = LotRec ThisLotPartId = LotRec // 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('CreateLotEvent', TWLotId, 'TW', Datetime(), 'MOVE_IN', 'Move into TW_IN_USE', '', 0, 0, '', 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('CreateLotEvent', TWLotId, 'TW', Datetime(), 'MOVE_IN', 'Move into TW_READY_TO_USE', '', 0, 0, '', UserID) end else Lot_Services('CreateLotEvent', TWLotId, 'TW', Datetime(), 'MOVE_OUT', 'Move out of TW_READY_TO_USE', '', 0, 0, '', 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('CreateLotEvent', TWLotId, 'TW', Datetime(), 'REDUCE_WAFER_QTY', ThisUsageQty : ' wafers consumed from lot.', EqpID, ThisUsageQty, 0, '', 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 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) ErrorMessage = '' If TestRunID NE '' AND TWPartID NE '' then If RowExists('TEST_RUN', TestRunID) then //Legacy Code: Pre LOT usage TRWaferRec = '' TRWaferRec = TestRunID TRWaferRec = TWPartID TRWaferRec = TWUsageTypeID TRWaferRec = 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 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('CreateLotEvent', LotId, 'TW', Datetime(), 'REDUCE_WAFER_QTY', 'Consumed test wafer.', '', UsageQty, 0, '', 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 = TWProdRec + 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 = TestRunID TestRunObj = OConv(TestRunRec, 'DT') TestRunObj = Xlate('TEST_RUN_TYPE', TestRunRec, TEST_RUN_TYPE_RUN_TYPE$, 'X') TestRunObj = TestRunRec EqpType = TestRunRec Begin Case Case EqpType EQ 'R' TestRunObj = 'Reactor' Case EqpType EQ 'T' TestRunObj = 'Non-Reactor' End Case TestRunObj = TestRunRec TestRunObj = TestRunRec TestRunObj = TestRunRec TWKeys = TestRunRec TWUsageProds = '' TWUsageQtys = '' for each TWKey in TWKeys using @VM setting tPos TRWRec = Test_Run_Services('GetTestRunWaferByID', TWKey) TestWaferProdName = XLATE('TEST_WAFER_PROD', TRWRec, 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 = TWUsageProds TestRunObj = 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 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, 'DT') TWLine<1, TEST_RUN_OBJ_RUN_TYPE$> = XLATE('TEST_RUN_TYPE', TestRunRec, 'RUN_TYPE', 'X') TWLine<1, TEST_RUN_OBJ_EQUIPMENT_ID$> = TestRunRec TWLine<1, TEST_RUN_OBJ_EQUIPMENT_TYPE$> = TestRunRec TWLine<1, TEST_RUN_OBJ_PROD_SPEC_ID$> = TestRunRec TWLine<1, TEST_RUN_OBJ_LSL_USER_ID$> = TestRunRec TWLine<1, TEST_RUN_OBJ_RDS_ID$> = TestRunRec 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) 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 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