Compile function Automated_Workflow_Services(@Service, @Params) /* Initial Author: Jonathan Ouellette This service module has a catalogued list of functions to quickly and easily perform certain functions related to lot processing. 1. CreateAWO - Imitates the process of getting data from SAP and processing the WO start in OI. 2. RouteWO - Imitates routing of a WO, AKA selecting a ProdVer and Assigning the WO to a reactor Type 3. PrescribeWafers - Imitates creating the child lots for a WO, AKA creating WO_MAT records 4. ReleaseCassettes - Assigns raw substrates to the WO_MAT records. RDS for non-epipro is created at this point. 5. PerformPTI - Imitates Receiving operator moving the lot into the fab. 6. Perform1VER - Performs the 1VER operation for an RDS. 7. PerformLoad - Performs the load operation for an RDS. 8. PerformUnload - Performs the unload operation for a non-epipro RDS. 9. EnterRecipeParms - Used in conjunction with PerformLoad. Used to enter the parameters for the Reactor Recipe upon load typically this is the first load of a Work Order. 10. VerifyRecipeParms - Used in conjunction with PerformLoad. Used to verify the current recipe setpoints for an RDS load. */ #pragma precomp SRP_PreCompiler Declare function Gan_Services, Obj_Notes_Sent, msg, Check_Notes, Jonathan_Services, Database_Services, SRP_Datetime Declare function Lsl_Users_Services, SRP_Time, RList, Error_Services, Obj_Wo_Mat, Pm_Services, Date_Services, Test_Run_Services Declare function Reactor_Services, Reactor_Log_Services, obj_react_item, Utility, Environment_Services, obj_wo_log, Qa_Services Declare subroutine Start_Window, RList, Set_Status, Database_Services, Obj_Sap, Sap_Services, Btree.Extract, Qa_Services Declare subroutine Reactor_Services, Obj_Wo_Log, obj_wo_mat, Work_Order_Services, Material_Movement_Services, Automated_Workflow_Services Declare subroutine Override_Services, Obj_Wo_Mat_Log, obj_post_log, Obj_Sap $insert LOGICAL $insert NOTE_PTRS_EQU $insert MSG_EQUATES $Insert APP_INSERTS $Insert RLIST_EQUATES $Insert WO_LOG_EQUATES $Insert RDS_EQUATES $Insert WO_STEP_EQUATES $Insert WO_MAT_QA_EQUATES $Insert REACT_RUN_EQUATES $Insert RDS_LAYER_EQUATES $Insert RDS_TEST_EQUATES $Insert PM_EQUATES $Insert PM_SPEC_EQUATES $Insert WO_MAT_EQUATES $Insert WM_OUT_EQUATES $Insert TEST_RUN_EQUATES $Insert TEST_RUN_WAFER_EQUATES $Insert TEST_WAFER_PROD_EQUATES $Insert TEST_RUN_TYPE_EQUATES $Insert EPI_PART_EQUATES $Insert POPUP_EQUATES $Insert REACTOR_EQUATES GoToService Return Response or "" //----------------------------------------------------------------------------- // SERVICES //----------------------------------------------------------------------------- Service CreatAWO() //Step 1: Start a WO WOLogFileIn variable emulates what an SAP file would have /* ProdOrdNo = FileIn<1,1> CustPONo = FileIn<1,2> PromiseShipDt = FileIn<1,3> EpiPartNo = FileIn<1,4> SubPartNo = FileIn<1,5> SubRevNo = FileIn<1,6> WOQty = FileIn<1,7> VendCd = FileIn<1,8> */ WOLogFileIn = 'M124567.1':@VM:'NA':@VM:'02/29/2024':@VM:'400149S':@VM:'827906':@VM:'1.0':@VM:'150':@VM:'NA' RetVal = obj_WO_LOG('SAPCreate',WOLogFileIn) Response = RetVal end service Service RouteWO(WO_No) //Step 2: Route a WO with a Product Version WOLogRec = Database_Services('ReadDataRow', 'WO_LOG', WO_No) EpiPartNo = WOLogRec If EpiPartNo NE '' then AllProdVerNos = XLATE('EPI_PART',EpiPartNo,EPI_PART_PROD_VER_NO$,'X') TypeOver = '' TypeOver = AllProdVerNos TypeOver = 1 TypeOver = 'K' SelectedProdVerNo = Popup(@WINDOW,TypeOver,'PROD_VER') If SelectedProdVerNo NE '' then obj_WO_Log('Route',WO_No:@RM:SelectedProdVerNo) end end end service Service PrescribeWafers(WONo, AmountToRX) //Step 3: prescribe wafers. This is the same as assigning lot numbers to individual lots of raw material. AKA creating WO_MAT records /* a. User clicks the PUB_RX button on the WO_LOG form. b. Opens WO Receipt form c. Users clicks on WO's Due in d. User selects or enters a WO. e. User clicks scan codes, opens */ debug ProdVerNo = XLATE('WO_LOG', WONo, 'PROD_VER_NO', 'X') ReactType = XLATE('WO_LOG', WONo, 'REACT_TYPE', 'X') CassLotNo = '123456789' CustPartNo = XLATE('WO_LOG', WONo, 'CUST_PART_NO', 'X') CassQty = 25 NumCassToRX = AmountToRX / 25 ExistingWOMatList = XLATE('WO_LOG', WONo, 'WO_MAT_KEY', 'X') LastCassNo = 0 for each cass in ExistingWOMatList using @VM setting iPos thisCassNo = FIELD(cass, '*', 2) if thisCassNo GT LastCassNo then LastCassNo = thisCassNo Next cass for i = 1 to NumCassToRX NextCassNo = LastCassNo + 1 LastCassNo = nextCassNo Parms = WONo:@RM Parms := NextCassNo:@RM Parms := ProdVerNo:@RM Parms := CassLotNo:@RM Parms := CassQty:@RM Parms := CustPartNo:@RM ;* This is the CUSTOMER part No Parms := 1:@RM Parms := ReactType:@RM ;* 3 character Reactor Type Code Parms := '':@RM Parms := 'SR':@RM ;* Warehouse = 'SR' - Shipping/Receiving Area Parms := 'RB':@RM ;* Location = 'RB' - Receiving Bench Parms := OCONV(SRP_Datetime('Now'), 'DT/4'):@RM Parms := 'JONATHAN_O':@RM Parms := '':@RM Parms := '':@RM Parms := '':@RM ;* Added 8/18/2009 JCH Parms := '':@RM ;* Added 12/16/2009 JCH Parms := 25:@RM ;* Added 11/4/2009 JCH Parms := 0:@RM ;* Added 05/14/2010 JCH Parms := '':@RM ;* Added 07/14/2011 for SAP Project JCH Parms := 25 ; // Added 02/01/2018 dmb obj_WO_Mat('Create',Parms) If Error_Services('NoError') then WOLogRec = Database_Services('ReadDataRow', 'WO_LOG', WONo) WOLogRec = WONo : '*' : LastCassNo Database_Services('WriteDataRow', 'WO_LOG', WONo, WOLogRec, 1, 0, 1) end Next i Work_Order_Services('UpdateReceivedQty', WONo) end service Service ReleaseCassettes(WONo) //Step 4: User clicks release cassettes(PUB_RELEASE) from WO_LOG form Work_Order_Services('ReleaseCassettes', WONo) //Can get RDS number at this point end service Service PerformPTI(CassID) //Step 5: User performs a PTI scan to tag lot into the fab. Warehouse = '1K' Location = 'PTI' Material_Movement_Services('SaveRecord', CassID, Warehouse, Location, @USER4) end service * Service BatchProcessLotList() * RDSList = '' * * RDSList<1> = 627134 * RDSList<2> = 627135 * RDSList<3> = 627136 * RDSList<4> = 627132 * RDSList<5> = 627133 * * for each rds in RDSList using @FM * //Automated_Workflow_Services('Perform1VER', rds, 63, 25) * Automated_Workflow_Services('PerformUnload', rds) * Next rds * end service Service Perform1VER(CassID, ReactorID, WfrQty) //Step 6 If RowExists('RDS', CassID) AND ReactorID NE '' then ReadyToSign = QA_Services('PreEpiSignatureReady', CassID, @User4, WfrQty, ReactorID) If (ReadyToSign EQ True$) then QA_Services('SignPreEpiStage', CassID, @USER4, WfrQty, ReactorID) end end end service Service PerformLoad(CassID, WfrInQty, LorRLL) //Step 7 If RowExists('RDS', CassID) then ReadyToSign = Qa_Services('LoadSignatureReady', CassID, @User4, WfrInQty, LorRLL, 0) If ReadyToSign then Qa_Services('SignLoadStage', CassID, @User4, WfrInQty, LorRLL, 0) end else ErrorReason = Error_Services('GetMessage') Begin Case Case ErrorReason EQ 'Process Error: Recipe parameters have not been entered.' //Get the expected parameters and enter them. This is in the RDS_Layer Record //First lets get limits from the RDS Layer Record(s) RDSLayerKeys = XLATE('RDS', CassID, RDS_RDS_LAYER_KEYS$, 'X') for each RDSLayerKey in RDSLayerKeys using @VM setting rlPos Automated_Workflow_Services('EnterRecipeParams', RDSLayerKey) If Error_Services('NoError') then Automated_Workflow_Services('PerformLoad', CassID, WfrInQty, LorRLL) end else //Die Return end Next RDSLayerKey Case ErrorReason EQ 'RDS layer parameters must be reviewed for accuracy and acknowledged before the load operation can be signed.' Automated_Workflow_Services('VerifyRecipeParams', CassID) If Error_Services('NoError') then Automated_Workflow_Services('PerformLoad', CassID, WfrInQty, LorRLL) end else //Die Return end End Case end end end service Service PerformUnload(RDSNo) //Step 8 If RDSNo NE '' then Reactor = XLATE('RDS', RDSNo, 'REACTOR', 'X') If Reactor NE '' then ReadyToSign = QA_Services('UnloadSignatureReady', RDSNo, @User4, Reactor) If Error_Services('HasError') then If ErrorMsg EQ 'Cassette runtime exceeds three days! An override by a LEAD or SUPERVISOR is required.' then Override_Services('SetOverride', 'RDS', RDSNo, 'UNLOAD_DTM', @USER4) ReadyToSign = True$ end end If ReadyToSign then QA_Services('SignUnloadStage', RDSNo, @User4) end end else Error_Services('Add', 'No Reactor assigned to RDS!') end end else Error_Services('Add', 'No RDS No. Supplied!') end end service Service PerformFQA(RDSNo) ToolID = '' WHCd = 'CR' LocCD = 'QA' Tag = '' SigDt = Date() SigTm = Time() WONo = XLATE('RDS', RDSNo, RDS_WO$, 'X') CassNo = XLATE('RDS', RDSNo, RDS_CASS_NO$, 'X') Equ COL$LOG_FILE to 1 Equ COL$LOG_DTM to 2 Equ COL$ACTION to 3 Equ COL$WH_CD to 4 Equ COL$LOC_CD to 5 Equ COL$WO_NOS to 6 Equ COL$CASS_NOS to 7 Equ COL$USER_ID to 8 Equ COL$TAGS to 9 Equ COL$TOOL_ID to 10 EventParms = '' EventParms = 'WO_MAT' EventParms = SigDt:' ':SigTm EventParms = 1:'QA' EventParms = 'CR' EventParms = 'QA' EventParms = WONo EventParms = CassNo EventParms = @USER4 EventParms = '' EventParms = '' CONVERT @FM TO @RM IN EventParms obj_WO_Mat_Log('Create',EventParms) ;* * * * * INV EVENT LOG * * * * * Obj_Post_Log('POST') Qa_Services('SignFQAStage', RDSNo, @USER4) end service Service EnterRecipeParams(RDSLayerKey) RDSLayerRec = Database_Services('ReadDataRow', 'RDS_LAYER', RDSLayerKey) If RDSLayerRec NE '' then If RDSLayerRec NE '' AND RDSLayerRec NE '' then //Epi Deposit Time RDSLayerRec = ((RDSLayerRec - RDSLayerRec) / 2) + RDSLayerRec end If RDSLayerRec NE '' AND RDSLayerRec NE '' then //Diluent RDSLayerRec = ((RDSLayerRec - RDSLayerRec) / 2) + RDSLayerRec end If RDSLayerRec NE '' AND RDSLayerRec NE '' then //Dopant Flow RDSLayerRec = ((RDSLayerRec - RDSLayerRec) / 2) + RDSLayerRec end If RDSLayerRec NE '' AND RDSLayerRec NE '' then //HCL Flow RDSLayerRec = ((RDSLayerRec - RDSLayerRec) / 2) + RDSLayerRec end If RDSLayerRec NE '' AND RDSLayerRec NE '' then //Bake Time RDSLayerRec = ((RDSLayerRec - RDSLayerRec) / 2) + RDSLayerRec end If RDSLayerRec NE '' AND RDSLayerRec NE '' then //H2 Flow RDSLayerRec = ((RDSLayerRec - RDSLayerRec) / 2) + RDSLayerRec end If RDSLayerRec NE '' AND RDSLayerRec NE '' then //TCS Flow RDSLayerRec = ((RDSLayerRec - RDSLayerRec) / 2) + RDSLayerRec end If RDSLayerRec NE '' AND RDSLayerRec NE '' then //DCS Flow RDSLayerRec = ((RDSLayerRec - RDSLayerRec) / 2) + RDSLayerRec end If RDSLayerRec NE '' AND RDSLayerRec NE '' then //AUX 1 RDSLayerRec = ((RDSLayerRec - RDSLayerRec) / 2) + RDSLayerRec end If RDSLayerRec NE '' AND RDSLayerRec NE '' then //AUX2 RDSLayerRec = ((RDSLayerRec - RDSLayerRec) / 2) + RDSLayerRec end If RDSLayerRec NE '' AND RDSLayerRec NE '' then //F_OFFSET RDSLayerRec = ((RDSLayerRec - RDSLayerRec) / 2) + RDSLayerRec end If RDSLayerRec NE '' AND RDSLayerRec NE '' then //S_OFFSET RDSLayerRec = ((RDSLayerRec - RDSLayerRec) / 2) + RDSLayerRec end If RDSLayerRec NE '' AND RDSLayerRec NE '' then //R OFFSET RDSLayerRec = ((RDSLayerRec - RDSLayerRec) / 2) + RDSLayerRec end If RDSLayerRec NE '' AND RDSLayerRec NE '' then //ETCH 1 RDSLayerRec = ((RDSLayerRec - RDSLayerRec) / 2) + RDSLayerRec end If RDSLayerRec NE '' AND RDSLayerRec NE '' then //ETCH 2 RDSLayerRec = ((RDSLayerRec - RDSLayerRec) / 2) + RDSLayerRec end If RDSLayerRec NE '' AND RDSLayerRec NE '' then //ETCH 3 RDSLayerRec = ((RDSLayerRec - RDSLayerRec) / 2) + RDSLayerRec end If RDSLayerRec NE '' AND RDSLayerRec NE '' then //UL_TEMP RDSLayerRec = ((RDSLayerRec - RDSLayerRec) / 2) + RDSLayerRec end If RDSLayerRec NE '' AND RDSLayerRec NE '' then //Susceptor Etch RDSLayerRec = ((RDSLayerRec - RDSLayerRec) / 2) + RDSLayerRec end Database_Services('WriteDataRow', 'RDS_LAYER', RDSLayerKey, RDSLayerRec, True$, False$, True$) end end service Service VerifyRecipeParams(RDSNo) //Used to verify exisiting recipe params. This is if they are already set. IF RDSNo NE '' then RDSRec = Database_Services('ReadDataRow', 'RDS', RDSNo) RDSRec = True$ Database_Services('WriteDataRow', 'RDS', RDSNo, RDSRec, True$, False$, True$) end else Error_Services('Add', 'RDS No was blank!!!') end end service Service SendCassComp(WoMatKey) Sap_Services('RetransmitCassComp', WoMatKey) obj_sap('SendOutbound') end service