449 lines
17 KiB
Plaintext
449 lines
17 KiB
Plaintext
Function RDS_Unload_Events(CtrlEntId, Event, @PARAMS)
|
|
/***********************************************************************************************************************
|
|
|
|
This program is proprietary and is not to be used by or disclosed to others, nor is it to be copied without written
|
|
permission from Infineon.
|
|
|
|
Name : RDS_Unload_Events
|
|
|
|
Description : This function acts as a commuter module for all events related to this window.
|
|
|
|
Notes : Commuter Modules are automatically called from the Promoted_Events function which is called by the
|
|
application-specific promoted event handler. This makes it possible to add QuickEvents that need to
|
|
execute Basic+ logic without having use the Form Designer to make the association, although this is
|
|
limited to the events which are currently promoted.
|
|
|
|
If the form needs to call the commuter module directly then the QuickEvent parameters should be
|
|
formatted like this:
|
|
|
|
'@SELF','@EVENT',['@PARAM1','@PARAMx']
|
|
|
|
Parameters :
|
|
CtrlEntId [in] -- The fully qualified name of the control calling the promoted event
|
|
Event [in] -- The event being executed. See the Notes section regarding "PRE" events
|
|
Param1-15 [in] -- Additional event parameter holders
|
|
EventFlow [out] -- Set to 1 or 0 so the calling event knows whether or not to chain forward. See comments in
|
|
EVENT_SETUP insert
|
|
|
|
History : (Date, Initials, Notes)
|
|
03/26/19 djs Created initial commuter module.
|
|
06/13/24 djm Add new stage-specific supplement system.
|
|
|
|
|
|
***********************************************************************************************************************/
|
|
|
|
#pragma precomp SRP_PreCompiler
|
|
#Window RDS_UNLOAD
|
|
|
|
$insert APP_INSERTS
|
|
$insert EVENT_SETUP
|
|
$insert MSG_EQUATES
|
|
$insert RDS_EQUATES
|
|
$insert LSL_USERS_EQUATES
|
|
$insert PROD_SPEC_EQUATES
|
|
$insert WO_MAT_EQUATES
|
|
$insert SURFACE_SCAN_EQUATES
|
|
$insert REACTOR_EQUATES
|
|
$insert PRS_STAGE_EQUATES
|
|
$insert COMPANY_EQUATES
|
|
$insert WO_MAT_QA_EQUATES
|
|
$insert REACT_STATUS_EQUATES
|
|
$insert SUPPL_INFO_ARRAY_EQU
|
|
$insert CLEAN_INSP_EQUATES
|
|
$insert REACT_STATE_EQUATES
|
|
$insert REACT_RUN_EQUATES
|
|
$insert REACT_ITEM_EQUATES
|
|
$Insert MESSAGE_BOX_EQUATES
|
|
|
|
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
|
|
|
|
Equ COL$MET_TEST to 1 ; // QA Metrology control on RDS_UNLOAD & RDS_POST_EPI windows
|
|
Equ COL$MET_TEST_DESC to 2
|
|
Equ COL$MET_SLOT to 3
|
|
Equ COL$MET_SLOT_DESC to 4
|
|
Equ COL$MET_WFR_QTY to 5
|
|
Equ COL$MET_MIN to 6
|
|
Equ COL$MET_MAX to 7
|
|
Equ COL$MET_RESULT to 8
|
|
Equ COL$MET_STD_MAX to 9
|
|
Equ COL$MET_STD_RESULT to 10
|
|
Equ COL$MET_SIG to 11
|
|
Equ COL$MET_SIG_DTM to 12
|
|
|
|
* Clean Insp Actions
|
|
|
|
Equ ACTION$ACTIONS TO 1 ;* Data structures for each action
|
|
Equ ACTION$SIGS TO 2
|
|
Equ ACTION$SIG_DTMS TO 3
|
|
Equ ACTION$TOOLS TO 4
|
|
Equ ACTION$SPEC_CLEAN_TOOL TO 5
|
|
Equ ACTION$SPEC_MICROSCOPE TO 6
|
|
Equ ACTION$SPEC_BRIGHTLIGHT TO 7
|
|
Equ ACTION$SPEC_SURFSCAN_RECIPE TO 8
|
|
|
|
Declare subroutine ErrMsg, Set_Status, obj_WO_Mat, obj_WO_Mat_Log, obj_RDS, Set_Property, Send_Event, Database_Services
|
|
Declare subroutine Dialog_Box, Msg, MemberOf, obj_WO_Mat, Get_Property, obj_React_Status, Get_Status, Override_Services
|
|
Declare subroutine record_lock, obj_React_Status, Post_Event, obj_React_State, obj_Post_Log, Qa_Services, Reactor_Services
|
|
Declare Subroutine Rds_Services, WO_MAT_Services, Message_Box, Reactor_Log_Services, Schedule_Services
|
|
|
|
Declare function dialog_box, msg, Get_Status, obj_WO_Mat, Get_Status, obj_Clean_Insp, obj_Reactor, Get_Property
|
|
Declare function QA_Services, Database_Services, Set_Property, Rds_Services, Qa_Services, Memberof, Reactor_Services
|
|
Declare function Supplement_Services, WO_MAT_Services, Message_Box, Reactor_Log_Services, Schedule_Services
|
|
|
|
SubclassInfo = Form_Services('FindSubclassControl')
|
|
Subclass = SubclassInfo<1>
|
|
|
|
// Update the arguments so that the OpenInsight OLE event will treate the ActiveX event as a native event handler.
|
|
If Event EQ 'OLE' then
|
|
Transfer Event to OIEvent
|
|
Transfer Param1 to Event
|
|
Transfer Param2 to Param1
|
|
Transfer Param3 to Param2
|
|
* Transfer Param4 to Param3
|
|
* Transfer Param5 to Param4
|
|
* Transfer Param6 to Param5
|
|
* Transfer Param7 to Param6
|
|
* Transfer Param8 to Param7
|
|
end
|
|
|
|
GoToEvent Event for CtrlEntID
|
|
|
|
Return EventFlow else EVENT_CONTINUE$
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Events
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
Event WINDOW.CREATE(CreateParam)
|
|
|
|
GoSub Setup_OLE_Controls
|
|
|
|
SRP_Show_Window(@Window, '', 'C', 'C', 1, '', False$, False$)
|
|
|
|
end event
|
|
|
|
|
|
Event WINDOW.READ()
|
|
|
|
end event
|
|
|
|
|
|
Event WINDOW.CLOSE(CancelFlag)
|
|
|
|
end event
|
|
|
|
|
|
Event WINDOW.CLEAR(bSaveKey, bSuppressWarning, bMaintainFocus, CtrlIDFocus)
|
|
|
|
end event
|
|
|
|
|
|
Event SUPPL_BUTTON.CLICK()
|
|
|
|
RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT')
|
|
Dialog_Box('NDW_RDS_SUPP_SIG', @Window, RDSNo :@FM: 'UNLOAD' :@FM: FALSE$)
|
|
|
|
end event
|
|
|
|
|
|
Event OP_OUT_DATE.LOSTFOCUS(Flag, FocusID)
|
|
|
|
UnloadDt = IConv(Get_Property(CtrlEntID, 'TEXT'), 'D')
|
|
RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT')
|
|
LoadDt = Xlate('RDS', RDSNo, 'DATE_IN', 'X')
|
|
Runtime = UnloadDt - LoadDt
|
|
Today = Date()
|
|
Error = True$
|
|
ErrorMsg = 'Invalid UNLOAD date ':OConv(UnloadDt, 'D/'):'! '
|
|
Supervisor = Memberof(@User4, 'SUPERVISOR')
|
|
Lead = Memberof(@User4, 'LEAD')
|
|
Begin Case
|
|
Case UnloadDt GT Today
|
|
ErrorMsg := 'Unload date cannot be in the future!'
|
|
|
|
Case ( (Runtime GT 2) and Not(Supervisor or Lead) )
|
|
ErrorMsg := 'Unload date must be within two days of the LOAD date ':OConv(LoadDt, 'D/'):'.'
|
|
|
|
Case ( (Runtime GT 2) and (Supervisor or Lead) )
|
|
Override_Services('SetOverride', 'RDS', RDSNo, 'UNLOAD_DTM', @User4)
|
|
Error = False$
|
|
|
|
Case UnloadDt LT LoadDt
|
|
ErrorMsg := 'Unload date cannot be less than the LOAD date ':OConv(LoadDt, 'D/'):'.'
|
|
|
|
Case Otherwise$
|
|
Error = False$
|
|
End Case
|
|
|
|
If Error then
|
|
ErrMsg(ErrorMsg)
|
|
// Return focus to control and highlight the invalid date entered.
|
|
Set_Property(CtrlEntID, 'FOCUS', True$)
|
|
Set_Property(CtrlEntID, 'SELECTION', 1:@FM:65534)
|
|
end
|
|
|
|
end event
|
|
|
|
|
|
Event PUB_SIGN.CLICK()
|
|
|
|
SignEventType = Get_Property(CtrlEntID, 'TEXT')
|
|
WONo = Get_Property(@Window:'.WO','DEFPROP')
|
|
CassNo = Get_Property(@Window:'.CASS_NO','DEFPROP')
|
|
WOStep = Get_Property(@Window:'.WO_STEP','DEFPROP')
|
|
RDSNo = Get_Property(@Window:'.RDS_NO','TEXT')
|
|
Reactor = Get_Property(@Window:'.REACTOR', 'TEXT')
|
|
|
|
Preauthenticated = FALSE$
|
|
Begin Case
|
|
Case SignEventType EQ 'Sign'
|
|
|
|
LWIInstAckReq = Xlate('RDS', RDSNo, 'LWI_INST_ACK_REQ', 'X')
|
|
If LWIInstAckReq EQ True$ then
|
|
Response = RDS_Services('RDSVerifyInst', RDSNo, 'LWI')
|
|
If Response EQ False$ then return
|
|
end
|
|
|
|
UnloadInstAckReq = Xlate('RDS', RDSNo, 'UNLOAD_INST_ACK_REQ', 'X')
|
|
If UnloadInstAckReq EQ True$ then
|
|
Response = RDS_Services('RDSVerifyInst', RDSNo, 'UNLOAD')
|
|
If Response EQ False$ then return
|
|
end
|
|
|
|
PostInstAckReq = Xlate('RDS', RDSNo, 'POST_INST_ACK_REQ', 'X')
|
|
If PostInstAckReq EQ True$ then
|
|
Response = RDS_Services('RDSVerifyInst', RDSNo, 'POST')
|
|
If Response EQ False$ then return
|
|
end
|
|
|
|
SupplAckReq = Supplement_Services('UnacknowledgedSupplementCheck', 'RDS', RDSNo, 'UNLOAD')
|
|
IF (SupplAckReq NE FALSE$) then
|
|
Response = Dialog_Box('NDW_RDS_SUPP_SIG', @Window, RDSNo :@FM: 'UNLOAD' :@FM: FALSE$)
|
|
If Response EQ False$ then
|
|
return
|
|
end else
|
|
Preauthenticated = TRUE$
|
|
end
|
|
end
|
|
|
|
Override = False$
|
|
ReadyToSign = QA_Services('UnloadSignatureReady', RDSNo, @User4, Reactor)
|
|
If Error_Services('HasError') then
|
|
ErrorMsg = Error_Services('GetMessage')
|
|
If ErrorMsg EQ 'Cassette runtime exceeds three days! An override by a LEAD or SUPERVISOR is required.' then
|
|
// Prompt for override
|
|
Response = Msg(@Window, '', 'OVERRIDE', '', ErrorMsg)
|
|
|
|
Begin Case
|
|
Case Response EQ 1
|
|
Response = True$ ; // User Clicked Override
|
|
Case Response EQ 2
|
|
Response = False$ ; // User Clicked Cancel
|
|
Case Response EQ char(27)
|
|
Response = False$ ; // User Pressed Escape Key
|
|
End Case
|
|
|
|
If Response EQ True$ then
|
|
OverrideGroups = 'LEAD' : @VM : 'SUPERVISOR'
|
|
Response = Dialog_Box('NDW_VERIFY_USER', @WINDOW, @USER4 : @FM : OverrideGroups)
|
|
Valid = Response<1>
|
|
Username = Response<2>
|
|
If Valid then
|
|
Override_Services('SetOverride', 'RDS', RDSNo, 'UNLOAD_DTM', Username)
|
|
ReadyToSign = True$
|
|
Override = True$
|
|
end
|
|
end
|
|
end
|
|
end
|
|
If (ReadyToSign EQ True$) then
|
|
If Preauthenticated EQ False$ Then
|
|
If Override EQ False$ then
|
|
Response = Dialog_Box('NDW_VERIFY_USER', @WINDOW)
|
|
Valid = Response<1>
|
|
end
|
|
end else
|
|
Valid = True$
|
|
end
|
|
If (Valid EQ True$) then
|
|
ReactorType = XLATE('RDS',RDSNo,'REACTOR_TYPE','X')
|
|
If Len(ReactorType) GE 3 and ReactorType[1, 3] _EQC 'HTR' then
|
|
WoMatKey = WONo:'*':CassNo
|
|
IsLastCassetteInWo = WO_MAT_Services('CassetteIsLastInWo', WoMatKey)
|
|
If Error_Services('NoError') then
|
|
If IsLastCassetteInWo then
|
|
NextEventScheduled = False$
|
|
NextEventHasSamePsn = True$
|
|
NextEventIsBlock = False$
|
|
|
|
NextScheduledEvent = Schedule_Services('GetNextEvent', Reactor)
|
|
If Error_Services('NoError') then
|
|
NextEventScheduled = True$
|
|
|
|
NextEventHasSamePsn = Schedule_Services('NextEventIsSamePsn', Reactor)
|
|
NextEventIsBlock = Schedule_Services('NextEventIsBlock', Reactor)
|
|
end
|
|
|
|
If NextEventScheduled EQ False$ or NextEventHasSamePsn EQ False$ or NextEventIsBlock EQ True$ then
|
|
WoMatRecord = Database_Services('ReadDataRow', 'WO_MAT', WoMatKey)
|
|
WoMatRecord<WO_MAT_LAST_CASSETTE_TEST_WAFER_ACK_REQ$> = True$
|
|
|
|
Message = ''
|
|
If NextEventScheduled EQ False$ or NextEventIsBlock EQ True$ then
|
|
Message = 'No material scheduled. Test wafer required.'
|
|
end else if NextEventHasSamePsn EQ False$ then
|
|
Message = 'Next work order is a NEW PSN number. Test wafer required.'
|
|
end
|
|
|
|
MesageAcked = Message_Box(@Window, Message, "Test Wafer Required", MSG_BTN_OK$ + MSG_ICON_EXCLAM$)
|
|
|
|
WoMatRecord<WO_MAT_LAST_CASSETTE_TEST_WAFER_ACKED$> = True$
|
|
Database_Services('WriteDataRow', 'WO_MAT', WoMatKey, WoMatRecord, True$, False$, False$)
|
|
|
|
ConfirmNote = 'Test wafer requirement acknowledged. [RDS:' : RDSNo : '], [WO:' : WONo : '], [Cassette:' : CassNo : ']'
|
|
Reactor_Log_Services('AddComment', Reactor, ConfirmNote, @User4)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
QA_Services('SignUnloadStage', RDSNo, @User4)
|
|
end
|
|
end
|
|
If Error_Services('HasError') then
|
|
ErrorMsg = Error_Services('GetMessage')
|
|
ErrMsg(ErrorMsg)
|
|
end
|
|
Set_Property(@Window, 'SAVEWARN', False$)
|
|
Send_Event(@Window, 'READ')
|
|
|
|
Case SignEventType EQ 'Unsign'
|
|
|
|
// 1. Check if on hold. If so, then block event and inform user
|
|
WOMatKey = WONo:'*':CassNo
|
|
WOMatCurrStatus = obj_WO_Mat('CurrStatus',WOMatKey)
|
|
IF WOMatCurrStatus = 'HOLD' THEN
|
|
ErrorMessage = 'Process Error':@SVM:'Cassette is on Hold and may not be signed off.':CRLF$:CRLF$
|
|
ErrMsg(ErrorMessage)
|
|
RETURN 0
|
|
END
|
|
Reactor = XLATE('RDS',RDSNo,'REACTOR','X')
|
|
// 2. Check if the reactor will have enough capacity to load this lot. If not then block the event and
|
|
// inform user.
|
|
CurrChamberCount = Reactor_Services('GetReactorAvailChamberCount', Reactor)
|
|
If CurrChamberCount LE 0 then
|
|
ErrorMessage = 'Process Error':@SVM:'Reactor ' : Reactor : ' does not have the capacity for this lot.' :CRLF$:CRLF$
|
|
ErrMsg(ErrorMessage)
|
|
RETURN 0
|
|
end
|
|
// 3.
|
|
// a. For Non-EPP - Check if LWII, LWIS, or FQA has been signed. If so, then block event and inform user
|
|
// b. For EPP - Check Clean_Insp actions to see if an inspection or surfscan has been completed
|
|
// Also check the FQA signature (MO_QA)
|
|
ReactorType = XLATE('RDS',RDSNo,'REACTOR_TYPE','X')
|
|
CISigs = Xlate('RDS', RDSNo, 'LWI_CI_SIG', 'X')
|
|
Convert @VM to '' in CISigs
|
|
IF ReactorType NE 'EPP' THEN
|
|
FQASig = Xlate('RDS', RDSNo, 'SUP_VER_SIG', 'X')
|
|
END ELSE
|
|
WMOutKey = Xlate('RDS', RDSNo, 'WM_OUT_KEY', 'X')
|
|
FQASig = Xlate('WM_OUT', WMOutKey, 'SUP_VER_SIG', 'X')
|
|
END
|
|
If (CISigs NE '') or (FQASig NE '') then
|
|
// LWII, LWIS, or FQA already signed. Block unload unsign event.
|
|
ErrorMessage = 'Process Error':@SVM:'LWII, LWIS, or FQA already signed. Cannot unsign unload event.' |
|
|
: CRLF$ : CRLF$
|
|
ErrMsg(ErrorMessage)
|
|
Return 0
|
|
end
|
|
// 3. LEAD/SUPERVISOR standard override
|
|
Response = Dialog_Box('NDW_VERIFY_USER', @WINDOW, @USER4 : @FM : 'LEAD' : @VM : 'SUPERVISOR')
|
|
Valid = Response<1>
|
|
OverrideUser = Response<2>
|
|
If Valid then
|
|
|
|
// 4. Remove RDS Unload signature, date, and time
|
|
Set_Property(@Window:'.OP_OUT', 'TEXT', '')
|
|
Set_Property(@Window:'.OP_OUT_NAME', 'TEXT', '')
|
|
Set_Property(@Window:'.OP_OUT_DATE', 'TEXT', '')
|
|
Set_Property(@Window:'.OP_OUT_TIME', 'TEXT', '')
|
|
IOOptions = Get_Property(@Window, 'IOOPTIONS')
|
|
IOOptions<6> = True$
|
|
Set_Property(@Window, 'IOOPTIONS', IOOptions)
|
|
Send_Event(@Window, 'WRITE')
|
|
IOOptions<6> = False$
|
|
Set_Property(@Window, 'IOOPTIONS', IOOptions)
|
|
|
|
// 5. Remove WO_MAT Unload signature, date, and time
|
|
WOMatRec = Database_Services('ReadDataRow', 'WO_MAT', WOMatKey)
|
|
|
|
SigProf = WOMatRec<WO_MAT_SIG_PROFILE$>
|
|
Sigs = WOMatRec<WO_MAT_SIGNATURE$>
|
|
SigDTMs = WOMatRec<WO_MAT_SIG_DTM$>
|
|
|
|
If ReactorType NE 'EPP' then
|
|
Locate '1UNLOAD' in SigProf using @VM setting vPos then
|
|
Sigs<1, vPos> = ''
|
|
SigDTMs<1, vPos> = ''
|
|
WOMatRec<WO_MAT_SIGNATURE$> = Sigs
|
|
WOMatRec<WO_MAT_SIG_DTM$> = SigDTMs
|
|
end
|
|
Reactor_Services('DecrementWfrMetrics', RDSNo)
|
|
end
|
|
|
|
// Added by JRO
|
|
obj_React_Status('HandleUnloadUnsign',Reactor:@RM:WONo:@RM:CassNo:@RM:RDSNo:@RM:OverrideUser)
|
|
Rds_Services('AddComment', RDSNo, 'Unload Stage unsigned from Reactor ' : Reactor)
|
|
// 6. Remove '1UNLOAD' material log entry (i.e. WO_MAT<INV...> columns)
|
|
InvActions = WOMatRec<WO_MAT_INV_ACTION$>
|
|
Locate '1UNLOAD' in InvActions using @VM setting vPos then
|
|
WOMatRec<WO_MAT_INV_WH$> = Delete(WOMatRec<WO_MAT_INV_WH$>, 0, vPos, 0)
|
|
WOMatRec<WO_MAT_INV_LOCATION$> = Delete(WOMatRec<WO_MAT_INV_LOCATION$>, 0, vPos, 0)
|
|
WOMatRec<WO_MAT_INV_ACTION$> = Delete(WOMatRec<WO_MAT_INV_ACTION$>, 0, vPos, 0)
|
|
WOMatRec<WO_MAT_INV_DTM$> = Delete(WOMatRec<WO_MAT_INV_DTM$>, 0, vPos, 0)
|
|
WOMatRec<WO_MAT_INV_USER$> = Delete(WOMatRec<WO_MAT_INV_USER$>, 0, vPos, 0)
|
|
WOMatRec<WO_MAT_INV_TAG$> = Delete(WOMatRec<WO_MAT_INV_TAG$>, 0, vPos, 0)
|
|
WOMatRec<WO_MAT_INV_TOOL_ID$> = Delete(WOMatRec<WO_MAT_INV_TOOL_ID$>, 0, vPos, 0)
|
|
WOMatRec<WO_MAT_INV_LOC$> = Delete(WOMatRec<WO_MAT_INV_LOC$>, 0, vPos, 0)
|
|
WOMatRec<WO_MAT_INV_SCAN_ENTRY$> = Delete(WOMatRec<WO_MAT_INV_SCAN_ENTRY$>, 0, vPos, 0)
|
|
end
|
|
Database_Services('WriteDataRow', 'WO_MAT', WOMatKey, WOMatRec, True$, False$, True$)
|
|
|
|
WoMatKey = WONo:'*':CassNo
|
|
WoMatRecord = Database_Services('ReadDataRow', 'WO_MAT', WoMatKey)
|
|
|
|
WoMatRecord<WO_MAT_LAST_CASSETTE_TEST_WAFER_ACK_REQ$> = False$
|
|
WoMatRecord<WO_MAT_LAST_CASSETTE_TEST_WAFER_ACKED$> = False$
|
|
|
|
Database_Services('WriteDataRow', 'WO_MAT', WoMatKey, WoMatRecord, True$, False$, False$)
|
|
|
|
Set_Property(@Window:'.PUB_SIGN', 'TEXT', 'Sign')
|
|
end else
|
|
Return 0
|
|
end
|
|
End Case
|
|
|
|
end event
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Internal GoSubs
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
Setup_OLE_Controls:
|
|
|
|
return
|
|
|
|
|
|
|
|
|