open-insight/LSL2/STPROC/AUTOMATED_WORKFLOW_SERVICES.txt

416 lines
18 KiB
Plaintext

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<WO_LOG_EPI_PART_NO$>
If EpiPartNo NE '' then
AllProdVerNos = XLATE('EPI_PART',EpiPartNo,EPI_PART_PROD_VER_NO$,'X')
TypeOver = ''
TypeOver<PDISPLAY$> = AllProdVerNos
TypeOver<PSELECT$> = 1
TypeOver<PMODE$> = '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<WO_LOG_WO_MAT_KEY$, -1> = 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<COL$LOG_FILE> = 'WO_MAT'
EventParms<COL$LOG_DTM> = SigDt:' ':SigTm
EventParms<COL$ACTION> = 1:'QA'
EventParms<COL$WH_CD> = 'CR'
EventParms<COL$LOC_CD> = 'QA'
EventParms<COL$WO_NOS> = WONo
EventParms<COL$CASS_NOS> = CassNo
EventParms<COL$USER_ID> = @USER4
EventParms<COL$TAGS> = ''
EventParms<COL$TOOL_ID> = ''
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<RDS_LAYER_EPI_TIME_MIN$> NE '' AND RDSLayerRec<RDS_LAYER_EPI_TIME_MAX$> NE '' then
//Epi Deposit Time
RDSLayerRec<RDS_LAYER_EPI_TIME$> = ((RDSLayerRec<RDS_LAYER_EPI_TIME_MAX$> - RDSLayerRec<RDS_LAYER_EPI_TIME_MIN$>) / 2) + RDSLayerRec<RDS_LAYER_EPI_TIME_MIN$>
end
If RDSLayerRec<RDS_LAYER_DILUENT_MIN$> NE '' AND RDSLayerRec<RDS_LAYER_DILUENT_MAX$> NE '' then
//Diluent
RDSLayerRec<RDS_LAYER_DILUENT_ADJ_PARAM$> = ((RDSLayerRec<RDS_LAYER_DILUENT_MAX$> - RDSLayerRec<RDS_LAYER_DILUENT_MIN$>) / 2) + RDSLayerRec<RDS_LAYER_DILUENT_MIN$>
end
If RDSLayerRec<RDS_LAYER_DOPANT_FLOW_MIN$> NE '' AND RDSLayerRec<RDS_LAYER_DOPANT_FLOW_MAX$> NE '' then
//Dopant Flow
RDSLayerRec<RDS_LAYER_DOPANT_FLOW$> = ((RDSLayerRec<RDS_LAYER_DOPANT_FLOW_MAX$> - RDSLayerRec<RDS_LAYER_DOPANT_FLOW_MIN$>) / 2) + RDSLayerRec<RDS_LAYER_DOPANT_FLOW_MIN$>
end
If RDSLayerRec<RDS_LAYER_HCL_FLOW_MIN$> NE '' AND RDSLayerRec<RDS_LAYER_HCL_FLOW_MAX$> NE '' then
//HCL Flow
RDSLayerRec<RDS_LAYER_HCL_FLOW$> = ((RDSLayerRec<RDS_LAYER_HCL_FLOW_MAX$> - RDSLayerRec<RDS_LAYER_HCL_FLOW_MIN$>) / 2) + RDSLayerRec<RDS_LAYER_HCL_FLOW_MIN$>
end
If RDSLayerRec<RDS_LAYER_BAKE_TIME_MIN$> NE '' AND RDSLayerRec<RDS_LAYER_BAKE_TIME_MAX$> NE '' then
//Bake Time
RDSLayerRec<RDS_LAYER_BAKE_TIME$> = ((RDSLayerRec<RDS_LAYER_BAKE_TIME_MAX$> - RDSLayerRec<RDS_LAYER_BAKE_TIME_MIN$>) / 2) + RDSLayerRec<RDS_LAYER_BAKE_TIME_MIN$>
end
If RDSLayerRec<RDS_LAYER_EPI_H2_FLOW_MIN$> NE '' AND RDSLayerRec<RDS_LAYER_EPI_H2_FLOW_MAX$> NE '' then
//H2 Flow
RDSLayerRec<RDS_LAYER_EPI_H2_FLOW$> = ((RDSLayerRec<RDS_LAYER_EPI_H2_FLOW_MAX$> - RDSLayerRec<RDS_LAYER_EPI_H2_FLOW_MIN$>) / 2) + RDSLayerRec<RDS_LAYER_EPI_H2_FLOW_MIN$>
end
If RDSLayerRec<RDS_LAYER_TCS_FLOW_MIN$> NE '' AND RDSLayerRec<RDS_LAYER_TCS_FLOW_MAX$> NE '' then
//TCS Flow
RDSLayerRec<RDS_LAYER_TCS_FLOW$> = ((RDSLayerRec<RDS_LAYER_TCS_FLOW_MAX$> - RDSLayerRec<RDS_LAYER_TCS_FLOW_MIN$>) / 2) + RDSLayerRec<RDS_LAYER_TCS_FLOW_MIN$>
end
If RDSLayerRec<RDS_LAYER_DCS_FLOW_MIN$> NE '' AND RDSLayerRec<RDS_LAYER_DCS_FLOW_MAX$> NE '' then
//DCS Flow
RDSLayerRec<RDS_LAYER_DCS_FLOW$> = ((RDSLayerRec<RDS_LAYER_DCS_FLOW_MAX$> - RDSLayerRec<RDS_LAYER_DCS_FLOW_MIN$>) / 2) + RDSLayerRec<RDS_LAYER_DCS_FLOW_MIN$>
end
If RDSLayerRec<RDS_LAYER_AUX1_MIN$> NE '' AND RDSLayerRec<RDS_LAYER_AUX1_MAX$> NE '' then
//AUX 1
RDSLayerRec<RDS_LAYER_AUX1$> = ((RDSLayerRec<RDS_LAYER_AUX1_MAX$> - RDSLayerRec<RDS_LAYER_AUX1_MIN$>) / 2) + RDSLayerRec<RDS_LAYER_AUX1_MIN$>
end
If RDSLayerRec<RDS_LAYER_AUX2_MIN$> NE '' AND RDSLayerRec<RDS_LAYER_AUX2_MAX$> NE '' then
//AUX2
RDSLayerRec<RDS_LAYER_AUX2$> = ((RDSLayerRec<RDS_LAYER_AUX2_MAX$> - RDSLayerRec<RDS_LAYER_AUX2_MIN$>) / 2) + RDSLayerRec<RDS_LAYER_AUX2_MIN$>
end
If RDSLayerRec<RDS_LAYER_F_OFFSET_MIN$> NE '' AND RDSLayerRec<RDS_LAYER_F_OFFSET_MAX$> NE '' then
//F_OFFSET
RDSLayerRec<RDS_LAYER_F_OFFSET$> = ((RDSLayerRec<RDS_LAYER_F_OFFSET_MAX$> - RDSLayerRec<RDS_LAYER_F_OFFSET_MIN$>) / 2) + RDSLayerRec<RDS_LAYER_F_OFFSET_MIN$>
end
If RDSLayerRec<RDS_LAYER_S_OFFSET_MIN$> NE '' AND RDSLayerRec<RDS_LAYER_S_OFFSET_MAX$> NE '' then
//S_OFFSET
RDSLayerRec<RDS_LAYER_S_OFFSET$> = ((RDSLayerRec<RDS_LAYER_S_OFFSET_MAX$> - RDSLayerRec<RDS_LAYER_S_OFFSET_MIN$>) / 2) + RDSLayerRec<RDS_LAYER_S_OFFSET_MIN$>
end
If RDSLayerRec<RDS_LAYER_R_OFFSET_MIN$> NE '' AND RDSLayerRec<RDS_LAYER_R_OFFSET_MAX$> NE '' then
//R OFFSET
RDSLayerRec<RDS_LAYER_R_OFFSET$> = ((RDSLayerRec<RDS_LAYER_R_OFFSET_MAX$> - RDSLayerRec<RDS_LAYER_R_OFFSET_MIN$>) / 2) + RDSLayerRec<RDS_LAYER_R_OFFSET_MIN$>
end
If RDSLayerRec<RDS_LAYER_ETCH1_MIN$> NE '' AND RDSLayerRec<RDS_LAYER_ETCH1_MAX$> NE '' then
//ETCH 1
RDSLayerRec<RDS_LAYER_ETCH1$> = ((RDSLayerRec<RDS_LAYER_ETCH1_MAX$> - RDSLayerRec<RDS_LAYER_ETCH1_MIN$>) / 2) + RDSLayerRec<RDS_LAYER_ETCH1_MIN$>
end
If RDSLayerRec<RDS_LAYER_ETCH2_MIN$> NE '' AND RDSLayerRec<RDS_LAYER_ETCH2_MAX$> NE '' then
//ETCH 2
RDSLayerRec<RDS_LAYER_ETCH2$> = ((RDSLayerRec<RDS_LAYER_ETCH2_MAX$> - RDSLayerRec<RDS_LAYER_ETCH2_MIN$>) / 2) + RDSLayerRec<RDS_LAYER_ETCH2_MIN$>
end
If RDSLayerRec<RDS_LAYER_ETCH3_MIN$> NE '' AND RDSLayerRec<RDS_LAYER_ETCH3_MAX$> NE '' then
//ETCH 3
RDSLayerRec<RDS_LAYER_ETCH3$> = ((RDSLayerRec<RDS_LAYER_ETCH3_MAX$> - RDSLayerRec<RDS_LAYER_ETCH3_MIN$>) / 2) + RDSLayerRec<RDS_LAYER_ETCH3_MIN$>
end
If RDSLayerRec<RDS_LAYER_UL_TEMP_MIN$> NE '' AND RDSLayerRec<RDS_LAYER_UL_TEMP_MAX$> NE '' then
//UL_TEMP
RDSLayerRec<RDS_LAYER_UL_TEMP$> = ((RDSLayerRec<RDS_LAYER_UL_TEMP_MAX$> - RDSLayerRec<RDS_LAYER_UL_TEMP_MIN$>) / 2) + RDSLayerRec<RDS_LAYER_UL_TEMP_MIN$>
end
If RDSLayerRec<RDS_LAYER_SUSC_ETCH_MIN$> NE '' AND RDSLayerRec<RDS_LAYER_SUSC_ETCH_MAX$> NE '' then
//Susceptor Etch
RDSLayerRec<RDS_LAYER_SUSC_ETCH$> = ((RDSLayerRec<RDS_LAYER_SUSC_ETCH_MAX$> - RDSLayerRec<RDS_LAYER_SUSC_ETCH_MIN$>) / 2) + RDSLayerRec<RDS_LAYER_SUSC_ETCH_MIN$>
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<RDS_RDS_LAYER_ACK$> = 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