Initial commit. Create FQASignatureReady service in QA_SERVICES. Create SignFQA service in SIGNATURE_SERVICES. Commit remaining portion of project. Implement changes requested in review meeting. Fix typo. Add new MU logic to final entry point. Restrict logic to only apply to 'THICK' inspections. Bypass new logic if Biorad 4 and 5 are down.
1238 lines
43 KiB
Plaintext
1238 lines
43 KiB
Plaintext
COMPILE FUNCTION Comm_WO_Mat_Wfr(Instruction, Parm1,Parm2)
|
|
#pragma precomp SRP_PreCompiler
|
|
|
|
/*
|
|
Commuter module for WO_MAT_WFR (Work Order Material Wafer) window
|
|
|
|
01/25/2008 - John C. Henry, J.C. Henry & Co., Inc.
|
|
11/12/2018 - djs - Updated VerifyFullBoxReject subroutine to set the SAP Batch No. as a rejected cassette.
|
|
Previously this was being done prematurely in OBJ_WO_MAT('SignNCR').
|
|
01/04/2019 - djs - Fixed an issue within the "Refresh" subroutine, which was preventing the "SLOT_NO" edit table
|
|
from being colored correctly. The coloring code was moved to be executed after the section of
|
|
code responsible for coloring edit tables with symbolic fields.
|
|
02/27/2025 - DJM - Added prompt to remove hold when creating NCR in 'RejMat'
|
|
*/
|
|
|
|
DECLARE SUBROUTINE Set_Property, Set_Status, ErrMsg, Set_Property, obj_AppWindow, Send_Message, Logging_Services
|
|
DECLARE SUBROUTINE Btree.Extract, Send_Event, Security_Err_Msg, Forward_Event, End_Window, Start_Window
|
|
DECLARE SUBROUTINE EditCell, obj_NCR, obj_Notes, Post_Event, obj_WO_Mat, obj_WO_Mat_Log, obj_WO_Wfr, obj_Tables
|
|
DECLARE SUBROUTINE SRP_Stopwatch, Update_Index, Database_Services, obj_RDS, Create_Dialog, Dialog_Box
|
|
DECLARE SUBROUTINE Sleepery, Wo_Mat_Services
|
|
DECLARE FUNCTION Get_Property, Get_Status, Popup, Send_Message, Msg, Security_Check, Dialog_Box, RowExists
|
|
DECLARE FUNCTION Dialog_Box, obj_WO_Log, obj_NCR, Check_Notes, obj_MUWafers, obj_WO_Mat, Signature_Services
|
|
DECLARE FUNCTION MemberOf, obj_Tables, obj_RDS, Environment_Services, Logging_Services, Material_Services
|
|
DECLARE FUNCTION Database_Services, RetStack, Datetime, Error_Services, Rds_Services
|
|
|
|
$INSERT POPUP_EQUATES
|
|
$INSERT LOGICAL
|
|
$INSERT MSG_EQUATES
|
|
$INSERT APPCOLORS
|
|
$INSERT WM_IN_EQUATES
|
|
$INSERT WO_LOG_EQU
|
|
$INSERT WO_STEP_EQU
|
|
$INSERT WO_MAT_EQUATES
|
|
$INSERT ORDER_EQU
|
|
$INSERT RDS_EQUATES
|
|
$INSERT PROD_SPEC_EQU
|
|
$INSERT NOTIFICATION_EQU
|
|
$INSERT LSL_USERS_EQU
|
|
$INSERT SECURITY_RIGHTS_EQU
|
|
$INSERT WM_OUT_EQUATES
|
|
|
|
EQU CRLF$ TO \0D0A\
|
|
|
|
EQU COL$SLOT TO 1
|
|
EQU COL$WAFER_ID TO 2
|
|
EQU COL$SLOT_NCR TO 3
|
|
EQU COL$MET_NO$ TO 4
|
|
EQU COL$MOVED_TO_SLOT TO 5
|
|
EQU COL$MU_WAFER_ID TO 6
|
|
EQU COL$MOVED_FROM_SLOT TO 7
|
|
EQU COL$REPLACED_BY TO 8
|
|
EQU COL$MU_ADD_DATE TO 9
|
|
EQU COL$MU_REM_DATE TO 10
|
|
|
|
EQU COL$NCR_NO TO 1
|
|
EQU COL$NCR_STATUS TO 2
|
|
EQU COL$NCR_REJ_QTY TO 3
|
|
EQU COL$NCR_RESP TO 4
|
|
EQU COL$NCR_STAGE TO 5
|
|
EQU COL$NCR_LOSS_DESC TO 6
|
|
EQU COL$NCR_LOSS_COMM TO 7
|
|
EQU COL$NCR_FIN_SIG TO 8
|
|
EQU COL$NCR_FIN_SIG_DTM TO 9
|
|
|
|
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
|
|
|
|
LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\WO_Mat'
|
|
LogDate = Oconv(Date(), 'D4/')
|
|
LogTime = Oconv(Time(), 'MTS')
|
|
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' RDS Erase Attempt.csv'
|
|
Headers = 'Logging DTM' : @FM : 'User' : @FM : 'WOMatKeyID' : @FM : 'Record' : @FM : 'Stack'
|
|
objLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, Comma$, Headers, '', False$, False$)
|
|
LoggingDTM = LogDate : ' ' : LogTime ; // Logging DTM
|
|
|
|
ErrTitle = 'Error in Comm_WO_MAT_WFR'
|
|
ErrorMsg = ''
|
|
ErrCode = ''
|
|
|
|
Result = ''
|
|
|
|
BEGIN CASE
|
|
CASE Instruction = 'Create' ; GOSUB Create
|
|
CASE Instruction = 'Refresh' ; GOSUB Refresh
|
|
CASE Instruction = 'Read' ; GOSUB Read
|
|
CASE Instruction = 'Write' ; GOSUB Write
|
|
CASE Instruction = 'Clear' ; GOSUB Clear
|
|
CASE Instruction = 'Delete' ; GOSUB Delete
|
|
CASE Instruction = 'Close' ; GOSUB Close
|
|
CASE Instruction = 'RejMat' ; GOSUB RejMat
|
|
CASE Instruction = 'RecallMat' ; GOSUB RecallMat
|
|
CASE Instruction = 'NCRKeysDC' ; GOSUB NCRKeysDC
|
|
CASE Instruction = 'AddMakeup' ; GOSUB AddMakeup
|
|
CASE Instruction = 'RemMakeup' ; GOSUB RemMakeup
|
|
CASE Instruction = 'MakeUpLot' ; GOSUB MakeUpLot
|
|
CASE Instruction = 'WOStepRdsDC' ; GOSUB WOStepRdsDC
|
|
|
|
CASE 1
|
|
ErrorMsg = 'Unknown Instruction passed to routine'
|
|
END CASE
|
|
|
|
RETURN Result
|
|
|
|
|
|
* * * * * * *
|
|
Create:
|
|
* * * * * * *
|
|
|
|
Start_Window('WO_MAT_WFR', '')
|
|
|
|
IOOptions = Get_Property(@WINDOW, "IOOPTIONS")
|
|
IOOptions<2> = 2 ; // Do not lock
|
|
IOOptions<6> = 1 ; // Do not clear on write
|
|
Set_Property(@WINDOW, "IOOPTIONS", IOOptions)
|
|
|
|
* Provides compatibility with the existing messaging attachment system
|
|
|
|
IF Parm1 NE '' THEN
|
|
PassedKeys = FIELD(Parm1,'*',1)
|
|
obj_Appwindow('ViewRelated','WO_MAT_WFR':@RM:PassedKeys)
|
|
END
|
|
|
|
IF (MemberOf(@USER4,'OI_ADMIN')) THEN
|
|
Set_Property(@WINDOW:'.WO_STEP_RDS_NO','VISIBLE',1)
|
|
END
|
|
|
|
GOSUB Refresh
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
Read:
|
|
* * * * * * *
|
|
|
|
WONo = Get_Property(@WINDOW:'.WO_NO','DEFPROP')
|
|
CassNo = Get_Property(@WINDOW:'.CASS_NO','DEFPROP')
|
|
|
|
IF RowExists('WO_MAT',WONo:'*':CassNo) THEN
|
|
IF NOT(Security_Check('RDS',READ$)) THEN
|
|
Send_Event(@WINDOW,'CLEAR')
|
|
Security_Err_Msg('Work Order Mat',READ$)
|
|
RETURN
|
|
END
|
|
|
|
IF NOT(Security_Check('RDS',EDIT$)) THEN
|
|
obj_Appwindow('ReadOnly',@WINDOW) ;*Set to Read Only
|
|
END
|
|
|
|
END ELSE
|
|
ErrMsg('Work Order Mat entries are only created by the program.')
|
|
Send_Event(@WINDOW,'CLEAR')
|
|
RETURN
|
|
END
|
|
|
|
|
|
IF Get_Property(@WINDOW,'PARENT') = 'RDS_UNLOAD' THEN
|
|
Set_Property(@WINDOW:'.RDS_NO','DEFPROP',Get_Property(@WINDOW,'@RDS_NO'))
|
|
Set_Property(@WINDOW:'.REACTOR','DEFPROP',Get_Property(@WINDOW,'@REACTOR'))
|
|
Set_Property(@WINDOW:'.WO_STEP_NO','DEFPROP',Get_Property(@WINDOW,'@WO_STEP_NO'))
|
|
END
|
|
|
|
GOSUB Refresh
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
Write:
|
|
* * * * * * *
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
Clear:
|
|
* * * * * * *
|
|
|
|
IF Get_Property(@WINDOW,'PARENT') = 'RDS_UNLOAD' THEN
|
|
Set_Property(@WINDOW:'.RDS_NO','DEFPROP','')
|
|
Set_Property(@WINDOW:'.REACTOR','DEFPROP','')
|
|
Set_Property(@WINDOW:'.WO_STEP_NO','DEFPROP','')
|
|
END
|
|
|
|
GOTO Refresh
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
Delete:
|
|
* * * * * * *
|
|
|
|
ErrMsg('Records may not be modified or deleted.')
|
|
|
|
Result = 0 ;* No Deletes
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
Close:
|
|
* * * * * * *
|
|
|
|
obj_Appwindow('DetailReturn')
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
Refresh:
|
|
* * * * * * *
|
|
|
|
Ctrls = @WINDOW:@RM ; Props = '@RDS_NO':@RM
|
|
Ctrls := @WINDOW:@RM ; Props := '@REACTOR':@RM
|
|
Ctrls := @WINDOW ; Props := '@WO_STEP_NO'
|
|
|
|
Vals = Get_Property(Ctrls,Props)
|
|
|
|
Ctrls = @WINDOW:'.RDS_NO':@RM ; Props = 'DEFPROP':@RM
|
|
Ctrls := @WINDOW:'.REACTOR':@RM ; Props := 'DEFPROP':@RM
|
|
Ctrls := @WINDOW:'.WO_STEP_NO' ; Props := 'DEFPROP'
|
|
|
|
Set_Property(Ctrls,Props,Vals)
|
|
|
|
Ctrls = @WINDOW:'.MAKEUP_BOX':@RM:@WINDOW:'.HOLD':@RM:@WINDOW:'.HOTLOT':@RM:@WINDOW:'.MU_WAFER_FLAG'
|
|
Props = 'CHECK':@RM:'CHECK':@RM:'CHECK':@RM:'CHECK'
|
|
|
|
Vals = Get_Property(Ctrls,Props)
|
|
|
|
MakeupBox = Vals[1,@RM]
|
|
Hold = Vals[COL2()+1,@RM]
|
|
HotLot = Vals[COL2()+1,@RM]
|
|
UseMUWafers = Vals[COL2()+1,@RM]
|
|
|
|
IF NOT(MakeupBox) AND UseMUWafers THEN
|
|
Set_Property(@WINDOW:'.MU_BOX_LABEL','VISIBLE',0)
|
|
END ELSE
|
|
IF MakeupBox = 1 THEN
|
|
Set_Property(@WINDOW:'.MU_BOX_LABEL','VISIBLE',1)
|
|
END ELSE
|
|
Set_Property(@WINDOW:'.MU_BOX_LABEL','VISIBLE',0)
|
|
END
|
|
END
|
|
|
|
IF HotLot THEN
|
|
Set_Property(@WINDOW:'.HOT_LOT_LABEL','VISIBLE',1)
|
|
END ELSE
|
|
Set_Property(@WINDOW:'.HOT_LOT_LABEL','VISIBLE',0)
|
|
END
|
|
|
|
Ctrls = 'WO_MAT_WFR.QBF_FIRST_FIX':@RM ; Props = 'ENABLED':@RM
|
|
Ctrls := 'WO_MAT_WFR.QBF_PREV_FIX':@RM ; Props := 'ENABLED':@RM
|
|
Ctrls := 'WO_MAT_WFR.QBF_ABS_FIX':@RM ; Props := 'ENABLED':@RM
|
|
Ctrls := 'WO_MAT_WFR.QBF_NEXT_FIX':@RM ; Props := 'ENABLED':@RM
|
|
Ctrls := 'WO_MAT_WFR.QBF_LAST_FIX':@RM ; Props := 'ENABLED':@RM
|
|
Ctrls := 'WO_MAT_WFR.QBF_STOP_FIX' ; Props := 'ENABLED'
|
|
|
|
IF Get_Property('WO_MAT_WFR','QBFLIST') = '' THEN
|
|
Vals = 0:@RM:0:@RM:0:@RM:0:@RM:0:@RM:0
|
|
END ELSE
|
|
Vals = 1:@RM:1:@RM:1:@RM:1:@RM:1:@RM:1
|
|
END
|
|
|
|
Set_Property(Ctrls,Props,Vals)
|
|
|
|
* Turn edit table symbolic column backgrounds to green
|
|
|
|
ETSymbolics = Get_Property('WO_MAT_WFR','@ET_SYMBOLICS') ;* Loaded during 'Create' in obj_Appwindow
|
|
|
|
ETCtrls = ETSymbolics<1>
|
|
ETCols = ETSymbolics<2>
|
|
|
|
FOR I = 1 TO COUNT(ETCtrls,@VM) + (ETCtrls NE '')
|
|
ETCtrl = ETCtrls<1,I>
|
|
IF ETCtrl NE 'WO_MAT_WFR.SLOT_NO' THEN
|
|
ETList = Get_Property(ETCtrl,'LIST')
|
|
FOR Line = 1 TO COUNT(ETList,@FM) + (ETList NE '')
|
|
IF ETList<Line,1> NE '' THEN
|
|
FOR N = 1 TO COUNT(ETCols<1,I>,@SVM) + (ETCols<1,I> NE '')
|
|
stat = Send_Message(ETCtrl,'COLOR_BY_POS',ETCols<1,I,N>,Line,GREEN$)
|
|
NEXT N
|
|
END
|
|
NEXT Line
|
|
END
|
|
NEXT I
|
|
|
|
CtrlName = 'WO_MAT_WFR.NCR_KEYS'
|
|
NCRList = Get_Property(CtrlName,'LIST')
|
|
|
|
ColCount = COUNT(NCRList<1>,@VM) + (NCRList<1> NE '')
|
|
FOR Line = 1 TO COUNT(NCRList,@FM) + (NCRList NE '')
|
|
|
|
Status = NCRList<Line,2>
|
|
|
|
BEGIN CASE
|
|
CASE Status = '' ; Color = WHITE$
|
|
CASE Status = 'Closed' ; Color = GREEN$
|
|
CASE Status = 'Open' ; Color = RED$
|
|
CASE Status = 'Verified' ; Color = YELLOW$
|
|
|
|
CASE 1 ; Color = WHITE$
|
|
|
|
END CASE
|
|
FOR Col = 1 TO ColCount
|
|
stat = Send_Message(CtrlName,'COLOR_BY_POS',Col,Line,Color)
|
|
NEXT Col
|
|
|
|
NEXT Line
|
|
|
|
|
|
// Fill MU Rem Date and MU Add Date columns of the SLOT_NO edit table
|
|
|
|
WONo = Get_Property(@Window : '.WO_NO', 'TEXT')
|
|
CassNo = Get_Property(@Window : '.CASS_NO', 'TEXT')
|
|
WOMatKey = WONo : '*' : CassNo
|
|
WOMatRec = Database_Services('ReadDataRow', 'WO_MAT', WOMatKey)
|
|
MUAddDTMS = WOMatRec<WO_MAT_MU_WAFER_ADDED_DTM$>
|
|
MURemDTMS = WOMatRec<WO_MAT_MU_WAFER_REMOVED_DTM$>
|
|
List = Get_Property(@Window : '.SLOT_NO', 'LIST')
|
|
NumRows = DCount(List, @FM)
|
|
For fPos = 1 to NumRows
|
|
Row = List<fPos>
|
|
Row<1, COL$MU_REM_DATE> = OConv(MURemDTMS<1, fPos, 1>, 'DT2/^H') ; // Grab only the most recent datetime to display
|
|
Row<1, COL$MU_ADD_DATE> = OConv(MUAddDTMS<1, fPos, 1>, 'DT2/^H')
|
|
List<fPos> = Row
|
|
Next fPos
|
|
Set_Property(@Window : '.SLOT_NO', 'LIST', List)
|
|
|
|
CtrlEntID = @WINDOW:'.SLOT_NO'
|
|
|
|
SlotList = Get_Property(CtrlEntID,'LIST')
|
|
SlotListCnt = COUNT(SlotList,@FM) + (SlotList NE '')
|
|
FailedWfrs = WOMatRec<WO_MAT_FAILED_WAFERS$>
|
|
|
|
FOR Line = 1 TO SlotListCnt
|
|
WaferID = SlotList<Line,COL$WAFER_ID>
|
|
* RepBy = SlotList<Line,COL$REPLACED_BY>
|
|
NCRNo = SlotList<Line,COL$SLOT_NCR>
|
|
WfrFailed = FailedWfrs<0, Line>
|
|
BEGIN CASE
|
|
CASE SlotList<Line,COL$SLOT> = ''
|
|
LineColor = GREY$
|
|
CASE WaferID EQ '' AND (NOT(UseMUWafers) OR (MakeupBox))
|
|
LineColor = LTGREY$
|
|
CASE WaferID EQ '' AND NOT(MakeupBox) AND UseMUWafers
|
|
LineColor = YELLOW$
|
|
Case WaferID NE '' AND WfrFailed AND NCRNo EQ ''
|
|
LineColor = RED$
|
|
CASE WaferID NE '' AND NCRNo NE ''
|
|
LineColor = GREEN$
|
|
CASE WaferID NE '' AND NCRNo EQ ''
|
|
LineColor = WHITE$
|
|
CASE Otherwise$
|
|
LineColor = WHITE$
|
|
END CASE
|
|
|
|
FOR Col = 1 TO 10
|
|
stat = Send_Message(CtrlEntID,'COLOR_BY_POS',Col,Line,LineColor)
|
|
NEXT COL
|
|
NEXT Line
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
RejMat:
|
|
* * * * * * *
|
|
|
|
// Ensure cassette is not on hold
|
|
WONo = Get_Property(@Window:'.WO_NO', 'TEXT')
|
|
CassNo = Get_Property(@Window:'.CASS_NO', 'TEXT')
|
|
RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT')
|
|
WOMatKey = WONo:'*':CassNo
|
|
OnHold = Xlate('WO_MAT', WOMatKey, 'HOLD', 'X')
|
|
Result = ''
|
|
|
|
SlotList = Get_Property('WO_MAT_WFR.SLOT_NO','LIST')
|
|
SlotSelection = Get_Property('WO_MAT_WFR.SLOT_NO','SELPOS')
|
|
SelectedRows = SlotSelection<2>
|
|
CONVERT @VM TO @FM in SelectedRows
|
|
|
|
SelCnt = DCount(SelectedRows, @FM)
|
|
IF SelCnt = 0 THEN
|
|
ErrMsg('You must select at least one row in order to create an NCR.')
|
|
RETURN
|
|
END
|
|
|
|
GoSub FQAVerify
|
|
If Not(Authorized) then Return 0
|
|
|
|
If OnHold EQ True$ then
|
|
Result = Dialog_Box('NDW_HOLD_REMOVAL_PROMPT',@WINDOW,'RDS':@VM:RDSNo:@VM:WOMatKey)
|
|
If Result NE True$ then
|
|
Return 0
|
|
end else
|
|
Send_Event(@Window, 'READ')
|
|
end
|
|
end
|
|
If (OnHold NE True$) OR (Result = True$) then
|
|
OffHoldDTMs = Xlate('WO_MAT', WOMatKey, 'HOLD_STOP_DTM', 'X')
|
|
SAPBatchNo = Xlate('WO_MAT', WOMatKey, WO_MAT_SAP_BATCH_NO$, 'X')
|
|
If OffHoldDTMs NE '' then
|
|
// Ensure at least a minute has elapsed since the cassette was last taken off hold.
|
|
LastDTM = OffHoldDTMs[-1, 'B':@VM]
|
|
TimeElapsed = Datetime() - LastDTM
|
|
// .000694 is the equivalent to 60 seconds in datetime format
|
|
If (TimeElapsed LT '.000694') AND (SAPBatchNo NE '') then
|
|
Def = ""
|
|
Def<MTEXT$> = "Please wait for SAP to process off hold transaction..."
|
|
Def<MTYPE$> = "U"
|
|
MsgUp = Msg(@window, Def) ;* display the processing message
|
|
WaitTime = '.000694' - TimeElapsed
|
|
WaitSeconds = WaitTime * 86400 ;* 86400 = 60 seconds * 60 minutes * 24 hours
|
|
WaitMilliSec = WaitSeconds * 1000
|
|
Sleepery(WaitMilliSec)
|
|
Msg(@window, MsgUp) ;* take down the processing message
|
|
end
|
|
end
|
|
|
|
IneligibleSlots = ''
|
|
AllSlotsPermitted = True$ ; // Assume that all slots are permitted to be NCR'd for now.
|
|
For I = 1 TO SelCnt
|
|
SlotNo = SlotList<SelectedRows<I>, COL$SLOT>
|
|
MetNo = SlotList<SelectedRows<I>, COL$MET_NO$>
|
|
WfrID = SlotList<SelectedRows<I>, COL$WAFER_ID>
|
|
PrevNCR = SlotList<SelectedRows<I>, COL$SLOT_NCR>
|
|
MUWfrID = SlotList<SelectedRows<I>, COL$MU_WAFER_ID>
|
|
If ( (MetNo NE '') or (WfrID EQ '') or (PrevNCR NE '' and MUWfrID EQ '') ) then
|
|
AllSlotsPermitted = False$
|
|
IneligibleSlots<0, -1> = SlotNo
|
|
end
|
|
Next I
|
|
|
|
If AllSlotsPermitted EQ False$ then
|
|
Swap @VM with ',' in IneligibleSlots
|
|
ErrMsg('Selected slot(s) ' : IneligibleSlots : ' are not eligible for NCR.')
|
|
return
|
|
end
|
|
|
|
Ctrls = 'WO_MAT_WFR.WO_NO':@RM ; Props = 'DEFPROP':@RM
|
|
Ctrls := 'WO_MAT_WFR.CASS_NO':@RM ; Props := 'DEFPROP':@RM
|
|
Ctrls := 'WO_MAT_WFR.RDS_NO':@RM ; Props := 'DEFPROP':@RM
|
|
Ctrls := 'WO_MAT_WFR.WO_STEP_NO':@RM ; Props := 'DEFPROP':@RM
|
|
Ctrls := 'WO_MAT_WFR.REACTOR':@RM ; Props := 'DEFPROP':@RM
|
|
Ctrls := 'WO_MAT_WFR.NCR_KEYS':@RM ; Props := 'DEFPROP':@RM
|
|
Ctrls := 'WO_MAT_WFR.SAP_BATCH_NO' ; Props := 'DEFPROP'
|
|
|
|
Vals = Get_Property(Ctrls,Props)
|
|
|
|
WONo = Vals[1,@RM]
|
|
CassNo = Vals[COL2()+1,@RM]
|
|
RDSNo = Vals[COL2()+1,@RM]
|
|
WOStepNo = Vals[COL2()+1,@RM]
|
|
Reactor = Vals[COL2()+1,@RM]
|
|
NCRArray = Vals[COL2()+1,@RM]
|
|
|
|
WOMatKey = WONo:'*':CassNo
|
|
|
|
RejWaferIDs = ''
|
|
PrevNCRNos = ''
|
|
SlotNos = ''
|
|
|
|
GoodLines = 0
|
|
FOR I = 1 TO SelCnt
|
|
IF SlotList<SelectedRows<I>,COL$WAFER_ID> NE '' Then
|
|
GoodLines += 1
|
|
RejWaferIDs<1,GoodLines> = SlotList<SelectedRows<I>,COL$WAFER_ID>
|
|
PrevNCRNos<1,GoodLines> = SlotList<SelectedRows<I>,COL$SLOT_NCR>
|
|
SlotNos<1,GoodLines> = SlotList<SelectedRows<I>,COL$SLOT>
|
|
END
|
|
NEXT I
|
|
|
|
ncrParms = WONo:@RM
|
|
ncrParms := WOStepNo:@RM
|
|
ncrParms := CassNo:@RM ;* Place holder for WO_MAT_CASS_NO
|
|
ncrParms := RDSNo:@RM ;* Single RDS field
|
|
ncrParms := Reactor:@RM ;* Reactor No
|
|
ncrParms := '':@RM ;* Stage
|
|
ncrParms := '':@RM ;* InCassNos
|
|
ncrParms := SlotNos:@RM ;* InSlotNos
|
|
ncrParms := '':@RM ;* PockeNots
|
|
ncrParms := '':@RM ;* Zones
|
|
ncrParms := '':@RM ;* OutCassNos
|
|
ncrParms := '':@RM ;* OutSlotNos
|
|
ncrParms := '':@RM ;* Multiple RDSNos (EpiPro)
|
|
ncrParms := RejWaferIDs:@RM ;* Rejected Wafer ID's
|
|
ncrParms := PrevNCRNos ;* Previous NCR No's
|
|
|
|
BarcodeVerified = Dialog_Box('NDW_VERIFY_BARCODE', @Window, RDSNo, @User4)
|
|
If BarcodeVerified EQ TRUE$ then
|
|
Set_Status(0)
|
|
|
|
NCRNo = obj_NCR('Create',ncrParms) ;* Create new NCR for this wafer/group of wafers
|
|
SAPBatchNo = Get_Property(@WINDOW:'.SAP_BATCH_NO','DEFPROP')
|
|
MUFlag = XLATE('WO_MAT', WOMatKey, 'MakeupBox', 'X')
|
|
|
|
IF Get_Status(errCode) THEN
|
|
ErrMsg(errCode)
|
|
END ELSE
|
|
IF SAPBatchNo NE '' THEN
|
|
IF SAPBatchNo[-1,1] NE 'R' THEN
|
|
MUFlag = Xlate('NCR', NCRNo, 'MAKEUP_BOX', 'X')
|
|
MUFlag = OCONV(MUFlag ,'BYes,')
|
|
PartNoID = Xlate('NCR', NCRNo, 'WO_MAT_PART_NO', 'X')
|
|
RejCnt = Xlate('NCR', NCRNo, 'REJ_CNT', 'X')
|
|
Recipients = XLATE('NOTIFICATION', 'NCR_AFTER_GR', NOTIFICATION_USER_ID$, 'X')
|
|
SentFrom = @USER4
|
|
Subject = 'SAP Post - GR Scrap Qty - NCR Reported' ;* Modified subject line - dkk 7/17/14
|
|
Message = "NCR: ":NCRNo:CRLF$:"Batch_No: ":SAPBatchNo:CRLF$:"MU Box: ":MUFlag:CRLF$:"Epi PN: ":PartNoID:CRLF$:"Qty: ":RejCnt ;* Added Epi PN on the end - dkk 7/17/14
|
|
AttachWindow = 'NCR'
|
|
AttachKey = NCRNo
|
|
SendToGroup = ''
|
|
Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup
|
|
obj_Notes('Create',Parms)
|
|
END
|
|
END
|
|
|
|
RejDTM = OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTS')
|
|
|
|
RejWfrIDs = ''
|
|
CurrSlotIDs = ''
|
|
|
|
sCnt = COUNT(SlotNos,@VM) + (SlotNos NE '')
|
|
FOR N = 1 TO sCnt
|
|
* * * * Added 3/23/2016 JCH - wafer history * * * *
|
|
|
|
RejWfrID = RejWaferIDs<1,N>
|
|
CurrSlotID = WONo:'*':CassNo:'*':SlotNos<1,N>
|
|
|
|
Convert '.' To '*' In RejWfrID
|
|
|
|
RejWfrIDs<1,-1> = RejWfrID
|
|
CurrSlotIDs<1,-1> = CurrSlotID
|
|
|
|
Parms = RejWfrID:@RM ;* WfrID
|
|
Parms := RejDTM:@RM ;* EventDtm
|
|
Parms := @USER4:@RM ;* EventBy
|
|
Parms := 'NCR':@RM ;* Event
|
|
Parms := '':@RM ;* NewSlotID
|
|
Parms := '':@RM ;* RunLoc
|
|
Parms := NCRNo:@RM ;* NCRNo
|
|
Parms := '':@RM ;* TWUse
|
|
Parms := CurrSlotID:@RM ;* CurrSlotID
|
|
Parms := '':@RM ;* NewToolID
|
|
Parms := '':@RM ;* CurrToolID
|
|
Parms := '':@RM ;* NewInvLoc
|
|
Parms := '':@RM ;* CurrInvLoc
|
|
Parms := 'O' ;* Wfr Side
|
|
|
|
obj_WO_Wfr('AddEvent',Parms)
|
|
* * * * * * * * *
|
|
LineNo = SlotNos<1,N>
|
|
NEXT N
|
|
END
|
|
|
|
Set_Property(@WINDOW:'.SLOT','SELPOS',SlotSelection) ;* Toggle WM_IN select off
|
|
Set_Property(@WINDOW, 'SAVEWARN', False$)
|
|
rv = Dialog_Box('NCR', @WINDOW, NCRNo)
|
|
Send_Event(@WINDOW, 'READ')
|
|
end
|
|
end
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * *
|
|
RecallMat:
|
|
* * * * * *
|
|
|
|
Ctrls = 'WO_MAT_WFR.SLOT_NO':@RM:'WO_MAT_WFR.NCR_KEYS':@RM:'WO_MAT_WFR.WO_NO':@RM:'WO_MAT.CASS_NO'
|
|
Props = 'LIST':@RM:'ARRAY':@RM:'DEFPROP':@RM:'DEFPROP'
|
|
|
|
Vals = Get_Property(Ctrls,Props)
|
|
|
|
SlotList = Vals[1,@RM]
|
|
NCRArray = Vals[COL2()+1,@RM]
|
|
WONo = Vals[COL2()+1,@RM]
|
|
CassNo = Vals[COL2()+1,@RM]
|
|
|
|
NCRKeys = NCRArray<1>
|
|
NCRStatuses = NCRArray<2>
|
|
|
|
SlotSelection = Get_Property('WO_MAT_WFR.SLOT_NO','SELPOS')
|
|
SelectedRows = SlotSelection<2>
|
|
|
|
CONVERT @VM TO @FM in SelectedRows
|
|
|
|
SelCnt = COUNT(SelectedRows,@FM) + (SelectedRows NE '')
|
|
IF SelCnt = 0 THEN RETURN
|
|
|
|
Ctrls = 'WO_MAT_WFR.WO_NO':@RM ; Props = 'DEFPROP':@RM
|
|
Ctrls := 'WO_MAT_WFR.CASS_NO' ; Props := 'DEFPROP'
|
|
|
|
Vals = Get_Property(Ctrls,Props)
|
|
|
|
WONo = Vals[1,@RM]
|
|
CassNo = Vals[COL2()+1,@RM]
|
|
|
|
WOMatKey = WONo:'*':CassNo
|
|
|
|
RecallNCRNos = ''
|
|
RecallSlotNos = ''
|
|
|
|
;*******************************************************************************
|
|
|
|
RecallNCRCnt = 0
|
|
FOR I = 1 TO SelCnt
|
|
IF SlotList<SelectedRows<I>,COL$WAFER_ID> = '' AND SlotList<SelectedRows<I>,COL$SLOT_NCR> NE '' THEN
|
|
SlotNCRNo = SlotList<SelectedRows<I>,COL$SLOT_NCR>
|
|
LOCATE SlotNCRNo IN NCRKeys USING @VM SETTING Pos THEN
|
|
NCRStatus = NCRStatuses<1,Pos>
|
|
* Rem'd for testing P U T T H I S B A C K ! ! ! ! ! !
|
|
LOCATE SLotNCRNo IN RecallNCRNos USING @FM SETTING RPos THEN
|
|
RecallSlotNos<RPos,-1> = SlotList<SelectedRows<I>,COL$SLOT>
|
|
END ELSE
|
|
RecallNCRCnt += 1
|
|
RecallNCRNos = INSERT(RecallNCRNos,RPos,0,0,SlotList<SelectedRows<I>,COL$SLOT_NCR>)
|
|
RecallSlotNos = INSERT(RecallSlotNos,RPos,1,0,SlotList<SelectedRows<I>,COL$SLOT>)
|
|
END
|
|
END
|
|
END
|
|
NEXT I
|
|
|
|
FOR I = 1 TO RecallNCRCnt
|
|
RecallNCRNo = RecallNCRNos<I>
|
|
RecallSlot = RecallSlotNos<I>
|
|
SlotInfo = '' ; // Initializing variable here to prevent compilation warning. This code looks unfinished...
|
|
SlotCnt = COUNT(SlotInfo<1>, @VM) + (SlotInfo<1> NE '')
|
|
FOR N = 1 TO SlotCnt
|
|
SlotNo = SlotInfo<1,N>
|
|
PrevWaferID = SlotInfo<2,N>
|
|
PrevNCR = SlotInfo<3,N>
|
|
|
|
IF FIELD(PrevWaferID,'*',1,2) = WONo:'.':CassNo THEN
|
|
* MakeupWafer
|
|
END ELSE
|
|
* Original Wafer
|
|
END
|
|
|
|
NEXT N
|
|
NEXT I
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
NCRKeysDC:
|
|
* * * * * * *
|
|
|
|
WMId = Get_Property('WO_MAT_WFR','ID')
|
|
|
|
CtrlEntID = 'WO_MAT_WFR.NCR_KEYS'
|
|
|
|
CurrPos = Get_Property(CtrlEntID,'SELPOS')
|
|
CurrCol = CurrPos<1>
|
|
CurrRow = CurrPos<2>
|
|
|
|
NCRKey = Get_Property(CtrlEntID,'CELLPOS',1:@FM:CurrRow)
|
|
|
|
Send_Event('WO_MAT_WFR','WRITE')
|
|
|
|
Dialog_Box('NCR', @WINDOW, NCRKey)
|
|
|
|
Send_Event(@WINDOW, 'READ')
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
AddMakeup:
|
|
* * * * * * *
|
|
|
|
// Ensure cassette is not on hold
|
|
WONo = Get_Property(@Window:'.WO_NO', 'TEXT')
|
|
CassNo = Get_Property(@Window:'.CASS_NO', 'TEXT')
|
|
WOMatKey = WONo:'*':CassNo
|
|
OnHold = Xlate('WO_MAT', WOMatKey, 'HOLD', 'X')
|
|
|
|
If OnHold NE True$ then
|
|
|
|
GoSub FQAVerify
|
|
If Not(Authorized) then Return 0
|
|
|
|
* Build popup of available makeup wafers based on following priority:
|
|
|
|
Ctrls = @WINDOW:'.WO_NO':@RM:@WINDOW:'.CASS_NO':@RM:@WINDOW:'.SLOT_NO'
|
|
Props = 'DEFPROP':@RM:'DEFPROP':@RM:'LIST'
|
|
|
|
Vals = Get_Property(Ctrls,Props)
|
|
|
|
WONo = Vals[1,@RM]
|
|
CassNo = Vals[COL2()+1,@RM]
|
|
SlotList = Vals[COL2()+1,@RM]
|
|
|
|
WOMatKey = WONo:'*':CassNo
|
|
|
|
SlotSelection = Get_Property(@WINDOW:'.SLOT_NO','SELPOS')
|
|
SelectedRows = SlotSelection<2>
|
|
|
|
* This section added 11/5/2009 JCH
|
|
|
|
CassShipQty = Get_Property(@WINDOW:'.CASS_SHIP_QTY','DEFPROP')
|
|
|
|
IF CassShipQty NE '' AND CassShipQty > 0 THEN
|
|
|
|
SlotSelection = Get_Property(@WINDOW:'.SLOT_NO','SELPOS')
|
|
SelectedRows = SlotSelection<2>
|
|
BadRows = ''
|
|
|
|
SelCnt = COUNT(SelectedRows,@VM) + (SelectedRows NE '')
|
|
|
|
FOR I = 1 TO SelCnt
|
|
IF SelectedRows<1,I> > CassShipQty THEN
|
|
BadRows<1,-1> = SelectedRows<1,I>
|
|
END
|
|
NEXT I
|
|
|
|
IF BadRows NE '' THEN
|
|
ClearSelection = ''
|
|
ClearSelection<1> = SlotSelection<1>
|
|
ClearSelection<2> = BadRows
|
|
Set_Property(@WINDOW:'.SLOT_NO','SELPOS',ClearSelection)
|
|
ErrMsg('Only slots included in the shipping cassette may be selected for Makeup Wafers.')
|
|
RETURN
|
|
END
|
|
END
|
|
|
|
CONVERT @VM TO @FM in SelectedRows
|
|
|
|
SelCnt = COUNT(SelectedRows,@FM) + (SelectedRows NE '')
|
|
IF SelCnt = 0 THEN RETURN
|
|
|
|
EmptySlots = SelectedRows
|
|
CONVERT @FM TO @VM IN EmptySlots
|
|
|
|
IF EmptySlots = '' THEN
|
|
ErrMsg('No slots selected for makeup!')
|
|
RETURN
|
|
END
|
|
|
|
FOR I = 1 TO COUNT(EmptySlots,@VM) + (EmptySlots NE '')
|
|
EmptySlot = EmptySlots<1,I>
|
|
|
|
IF SlotList<EmptySlot,COL$WAFER_ID> NE '' THEN
|
|
ErrMsg('Slot ':EmptySlot:" isn't empty.")
|
|
RETURN
|
|
END
|
|
NEXT I
|
|
|
|
Parms = WONo:@RM ;*
|
|
Parms := @RM ;* WOLogRec
|
|
Parms := 1:@RM ;* ReturnKeys Flag
|
|
Parms := 1 ;* Use Reactor Run Table Flag
|
|
|
|
Response = Dialog_Box('NDW_MAKEUP_WAFERS', @Window, WOMatKey)
|
|
Begin Case
|
|
Case Response EQ True$
|
|
// User requested to convert the current cassette into a makeup box.
|
|
WOMatRec = Database_Services("ReadDataRow", 'WO_MAT', WOMatKey)
|
|
If Error_Services('NoError') then
|
|
SAPBatchNo = WOMatRec<WO_MAT_SAP_BATCH_NO$>
|
|
SAPTXDtm = WOMatRec<WO_MAT_SAP_TX_DTM$>
|
|
AwaitingBatchNo = ( (SAPTXDtm NE '') and (SAPBatchNo EQ '') )
|
|
HasBatchNo = (SAPBatchNo NE '')
|
|
FullBoxReject = (SAPBatchNo[-1, 1] = 'R')
|
|
Begin Case
|
|
Case AwaitingBatchNo
|
|
InvalidRequest = True$
|
|
ErrMsg('WARNING: Cassette ineligible to be converted as it is awaiting a batch number from SAP.')
|
|
Return
|
|
Case FullBoxReject
|
|
InvalidRequest = True$
|
|
ErrMsg('WARNING: Cassette ineligible to be converted as it is a full box reject.')
|
|
Return
|
|
Case HasBatchNo
|
|
// Operation limited to LEAD and SUPERVISOR groups
|
|
OverrideMsg = "Cassette has a batch number. SUPERVISOR or LEAD must override."
|
|
Response = Msg(@Window, '', 'OVERRIDE', '', OverrideMsg)
|
|
|
|
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
|
|
Response = Dialog_Box('NDW_VERIFY_USER', @WINDOW, @USER4:@FM:'LEAD':@VM:'SUPERVISOR')
|
|
Authorized = Response<1>
|
|
end else
|
|
Authorized = False$
|
|
end
|
|
If Not(Authorized) then Return
|
|
Case Otherwise$
|
|
Null
|
|
End Case
|
|
|
|
AvailMU_WOMatKeys = ''
|
|
UserResp = Response
|
|
MakeupBox = ''
|
|
|
|
// User requested to convert the current cassette into a makeup box.
|
|
// Verify the quantity before proceeding.
|
|
RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT')
|
|
If RDSNo NE '' then
|
|
Parms = ''
|
|
Parms<1> = RDSNo ; // Cassette to verify wafer count of.
|
|
Parms<2> = 0 ; // Wafer count adjustment - 0 because converting box.
|
|
Parms<3> = 'MU' ; // Wafer counter tool location
|
|
Proceed = Dialog_Box('NDW_WAFER_COUNTER', @Window, Parms)
|
|
If Proceed NE True$ then return
|
|
end else
|
|
ErrMsg('Error starting wafer counter check. RDS No is missing.')
|
|
end
|
|
|
|
RDSNo = Get_Property(@Window : '.RDS_NO', 'TEXT') ; // Get the RDS No now before the WRITE in case it is needed to toggle the index.
|
|
|
|
Send_Event(@WINDOW,'WRITE')
|
|
|
|
FieldNo = WO_MAT_MAKEUP_BOX$
|
|
CheckValue = 1
|
|
EpiCheck = Rds_Services('IsEpiPro', RDSNo)
|
|
|
|
obj_WO_Mat('ChangeFlag',WOMatKey:@RM:FieldNo:@RM:CheckValue)
|
|
|
|
If EpiCheck EQ False$ then
|
|
IF Get_Status(errCode) THEN
|
|
ErrMsg('Unable to set makeup flag until Unload stage is signed.')
|
|
Return
|
|
END else
|
|
Wo_Mat_Services('MakeupFlagOn', RDSNo)
|
|
end
|
|
end
|
|
|
|
SlotWaferIDs = Xlate('WO_MAT', WOMatKey, 'SLOT_WAFER_ID', 'X')
|
|
Convert @VM to '' in SlotWaferIDs
|
|
|
|
// Flush/update pending index transactions.
|
|
Update_Index('WO_MAT', 'MU_PART_NO', False$, True$)
|
|
Update_Index('WO_MAT', 'CURR_STATUS', False$, True$)
|
|
|
|
IF Get_Status(errCode) THEN
|
|
ErrMsg(errCode)
|
|
end
|
|
|
|
CurrStatus = obj_WO_Mat('CurrStatus',WOMatKey)
|
|
CurrDTM = OCONV(Date(),'D2/'):' ':OCONV(Time(),'MTS')
|
|
|
|
IF CurrStatus = 'RTU' THEN
|
|
EventParms = ''
|
|
EventParms<COL$LOG_FILE> = 'WO_MAT'
|
|
EventParms<COL$LOG_DTM> = CurrDTM
|
|
EventParms<COL$ACTION> = 'RTU'
|
|
EventParms<COL$WH_CD> = 'CR'
|
|
EventParms<COL$LOC_CD> = 'MU'
|
|
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 * * * * *
|
|
|
|
IF Get_Status(errCode) THEN
|
|
CALL ErrMsg(ErrCode)
|
|
END
|
|
|
|
END
|
|
|
|
obj_AppWindow('LoadFormKeys',@WINDOW:@RM:WOMatKey)
|
|
|
|
Post_Event(@Window, 'READ')
|
|
RETURN
|
|
|
|
end else
|
|
ErrMsg('WARNING: Error reading WO_MAT record.')
|
|
Return
|
|
end
|
|
|
|
Case Response EQ ''
|
|
// User has cancelled this process.
|
|
Return
|
|
|
|
Case Otherwise$
|
|
// User has selected a makeup box to use and backfill.
|
|
AvailMU_WOMatKeys = Response
|
|
MakeupBox = Response
|
|
MuWfrsNeeded = SelCnt
|
|
If AvailMU_WOMatKeys NE '' then
|
|
// Wafer counter check - Account for the possibility of selecting more than one makeup box.
|
|
For each MuWoMatKey in AvailMU_WOMatKeys using @FM
|
|
MuRdsNo = Xlate('WO_MAT', MuWoMatKey, 'RDS_NO', 'X')
|
|
QtyAdj = MuWfrsNeeded
|
|
CurrMuWfrCnt = obj_WO_Mat('CurrWaferCnt', MuWoMatKey)
|
|
If MuWfrsNeeded GT CurrMuWfrCnt then
|
|
QtyAdj = CurrMuWfrCnt
|
|
MuWfrsNeeded -= CurrMuWfrCnt
|
|
end
|
|
Parms = ''
|
|
Parms<1> = MuRdsNo ; // Cassette to verify wafer count of.
|
|
Parms<2> = QtyAdj ; // Wafer count adjustment - Number of makeup wafers being used.
|
|
Parms<3> = 'MU' ; // Wafer counter tool location
|
|
Proceed = Dialog_Box('NDW_WAFER_COUNTER', @Window, Parms)
|
|
If Proceed NE True$ then return
|
|
Next MuWoMatKey
|
|
end
|
|
|
|
IF NOT(MemberOf(@USER4,'OI_ADMIN')) THEN
|
|
IF MakeupBox NE AvailMU_WOMatKeys<1,1> THEN
|
|
ErrMsg('Only the first available cassette can be used for makeup.')
|
|
MakeupBox = ''
|
|
return
|
|
END
|
|
END
|
|
|
|
Valid = Dialog_Box('NDW_VERIFY_USER', @Window, @User4)
|
|
IF NOT(Valid) THEN RETURN ;* User is not worthy or can't type
|
|
Send_Event(@WINDOW,'WRITE')
|
|
obj_WO_Mat('AddMakeupWafers',WOMatKey:@RM:EmptySlots:@RM:MakeupBox)
|
|
Send_Event(@WINDOW,'READ')
|
|
|
|
End Case
|
|
|
|
end else
|
|
// Cassette is on hold so makeup wafers cannot be added.
|
|
ErrorMessage = 'Add makeup wafer(s) denied!. The cassette must be taken off hold before adding makeup wafer(s).'
|
|
Msg(@Window, '', 'OK', '', 'Error':@FM:ErrorMessage)
|
|
end
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
RemMakeup:
|
|
* * * * * * *
|
|
|
|
// Ensure cassette is not on hold
|
|
WONo = Get_Property(@Window:'.WO_NO', 'TEXT')
|
|
CassNo = Get_Property(@Window:'.CASS_NO', 'TEXT')
|
|
WOMatKey = WONo:'*':CassNo
|
|
OnHold = Xlate('WO_MAT', WOMatKey, 'HOLD', 'X')
|
|
|
|
If OnHold NE True$ then
|
|
|
|
GoSub FQAVerify
|
|
If Not(Authorized) then Return 0
|
|
|
|
Ctrls = @WINDOW:'.WO_NO':@RM:@WINDOW:'.CASS_NO':@RM:@WINDOW:'.SLOT_NO'
|
|
Props = 'DEFPROP':@RM:'DEFPROP':@RM:'LIST'
|
|
|
|
Vals = Get_Property(Ctrls,Props)
|
|
|
|
WONo = Vals[1,@RM]
|
|
CassNo = Vals[COL2()+1,@RM]
|
|
SlotList = Vals[COL2()+1,@RM]
|
|
|
|
WOMatKey = WONo:'*':CassNo
|
|
|
|
SlotSelection = Get_Property(@WINDOW:'.SLOT_NO','SELPOS')
|
|
SelectedRows = SlotSelection<2>
|
|
|
|
CONVERT @VM TO @FM in SelectedRows
|
|
|
|
SelCnt = COUNT(SelectedRows,@FM) + (SelectedRows NE '')
|
|
IF SelCnt = 0 THEN RETURN
|
|
|
|
MadeupSlots = SelectedRows
|
|
CONVERT @FM TO @VM IN MadeupSlots
|
|
|
|
IF MadeupSlots = '' THEN
|
|
ErrMsg('No madeup slots selected for removing makeup wafers!')
|
|
RETURN
|
|
END
|
|
|
|
FOR I = 1 TO COUNT(MadeupSlots,@VM) + (MadeupSlots NE '')
|
|
MadeupSlot = MadeupSlots<1,I>
|
|
|
|
IF SlotList<MadeupSlot,COL$MU_WAFER_ID> = '' THEN
|
|
ErrMsg('Slot ':MadeupSlot:" does not contain a makeup wafer.")
|
|
RETURN
|
|
END
|
|
NEXT I
|
|
|
|
Send_Event(@WINDOW,'WRITE')
|
|
|
|
|
|
MUWaferData = obj_WO_Mat('SubMakeupWafers',WOMatKey:@RM:MadeupSlots) ;* This needs to return the waferIDs (4/7/2008 JCH)
|
|
|
|
IF Get_Status(errCode) THEN
|
|
ErrMsg(errCode)
|
|
END
|
|
|
|
|
|
IF MUWaferData NE '' THEN
|
|
obj_WO_Mat('RepMakeupWafers',WOMatKey:@RM:MUWaferData)
|
|
IF Get_Status(errCode) THEN
|
|
ErrMsg(errCode)
|
|
END
|
|
END
|
|
|
|
obj_Appwindow('LoadFormKeys',@WINDOW:@RM:WOMatKey)
|
|
|
|
end else
|
|
// Cassette is on hold so makeup wafer(s) cannot be removed.
|
|
ErrorMessage = 'Remove makeup wafer(s) denied!. The cassette must be taken off hold removing makeup wafer(s).'
|
|
Msg(@Window, '', 'OK', '', 'Error':@FM:ErrorMessage)
|
|
end
|
|
|
|
RETURN
|
|
|
|
|
|
**********
|
|
MakeUpLot:
|
|
**********
|
|
|
|
Ctrls = @WINDOW:'.WO_NO':@RM:@WINDOW:'.CASS_NO':@RM:@WINDOW:'.SLOT_NO'
|
|
Props = 'DEFPROP':@RM:'DEFPROP':@RM:'LIST'
|
|
Vals = Get_Property(Ctrls,Props)
|
|
WONo = Vals[1,@RM]
|
|
CassNo = Vals[COL2()+1,@RM]
|
|
SlotList = Vals[COL2()+1,@RM]
|
|
CtrlEnt = Get_Property(@WINDOW,'FOCUS')
|
|
FieldNo = Get_Property(CtrlEnt,'POS')
|
|
Send_Event(CtrlEnt,'GOTFOCUS')
|
|
CheckValue = Get_Property(CtrlEnt,'DEFPROP')
|
|
InvalidRequest = False$
|
|
|
|
IF ((WONo NE '') AND (CassNo NE '')) THEN
|
|
WOMatKey = WONo:'*':CassNo
|
|
OnHold = Xlate('WO_MAT', WOMatKey, 'HOLD', 'X')
|
|
If OnHold NE True$ then
|
|
IF (MemberOf(@USER4,'MASTER_SCHED')) |
|
|
OR (MemberOf(@USER4,'SUPERVISOR')) |
|
|
OR (MemberOf(@USER4,'ENGINEERING')) |
|
|
OR (MemberOf(@USER4,'LEAD')) |
|
|
OR (MemberOf(@USER4,'OI_ADMIN')) THEN
|
|
|
|
WOMatRec = Database_Services("ReadDataRow", 'WO_MAT', WOMatKey)
|
|
If Error_Services('NoError') then
|
|
SAPBatchNo = WOMatRec<WO_MAT_SAP_BATCH_NO$>
|
|
SAPTXDtm = WOMatRec<WO_MAT_SAP_TX_DTM$>
|
|
AwaitingBatchNo = ( (SAPTXDtm NE '') and (SAPBatchNo EQ '') )
|
|
FullBoxReject = (SAPBatchNo[-1, 1] = 'R')
|
|
Begin Case
|
|
Case AwaitingBatchNo
|
|
InvalidRequest = True$
|
|
ErrMsg('WARNING: Cassette ineligible to be converted as it is awaiting a batch number from SAP.')
|
|
Case FullBoxReject
|
|
InvalidRequest = True$
|
|
ErrMsg('WARNING: Cassette ineligible to be converted as it is a full box reject.')
|
|
Case Otherwise$
|
|
Null
|
|
End Case
|
|
|
|
If Not(InvalidRequest) then
|
|
RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT')
|
|
EpiCheck = Rds_Services('IsEpiPro', RDSNo)
|
|
If RDSNo NE '' then
|
|
Parms = ''
|
|
Parms<1> = RDSNo ; // Cassette to verify wafer count of.
|
|
Parms<2> = 0 ; // Wafer count adjustment - 0 because converting box.
|
|
Parms<3> = 'MU' ; // Wafer counter tool location
|
|
Proceed = Dialog_Box('NDW_WAFER_COUNTER', @Window, Parms)
|
|
If Proceed EQ True$ then
|
|
obj_WO_Mat('ChangeFlag',WOMatKey:@RM:FieldNo:@RM:CheckValue)
|
|
If EpiCheck EQ False$ then
|
|
IF Get_Status(errCode) THEN
|
|
ErrMsg('Unable to set makeup flag until Unload stage is signed.')
|
|
InvalidRequest = True$
|
|
END else
|
|
Set_Property(@WINDOW,'SAVEWARN', False$)
|
|
Send_Event(@WINDOW,'CLEAR')
|
|
If (CheckValue EQ True$) then
|
|
Wo_Mat_Services('MakeupFlagOn', RDSNo)
|
|
end
|
|
end
|
|
end else
|
|
Set_Property(@WINDOW,'SAVEWARN', False$)
|
|
Send_Event(@WINDOW,'CLEAR')
|
|
end
|
|
end else
|
|
InvalidRequest = True$
|
|
end
|
|
end else
|
|
InvalidRequest = True$
|
|
ErrMsg('WARNING: Error starting wafer counter check. RDS No is missing.')
|
|
end
|
|
end
|
|
end else
|
|
InvalidRequest = True$
|
|
ErrMsg('ERROR: Error reading WO_MAT record.')
|
|
end
|
|
END ELSE
|
|
InvalidRequest = True$
|
|
ErrMsg('INFO: This function is limited to members of MASTER_SCHED, SUPERVISOR, ENGINEERING, or LEAD security groups.')
|
|
END
|
|
end else
|
|
InvalidRequest = True$
|
|
ErrMsg('WARNING: Cannot modify lot while it is on hold.')
|
|
end
|
|
END ELSE
|
|
InvalidRequest = True$
|
|
ErrMsg('WARNING: Work Order/Cassette information is missing.')
|
|
END
|
|
|
|
IF (InvalidRequest EQ True$) then
|
|
/* Toggle back the checkbox flag */
|
|
If (CheckValue EQ False$) then
|
|
Set_Property(CtrlEnt, 'DEFPROP', True$)
|
|
end else
|
|
Set_Property(CtrlEnt, 'DEFPROP', False$)
|
|
end
|
|
end
|
|
|
|
obj_AppWindow('LoadFormKeys',@WINDOW:@RM:WOMatKey)
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
WOStepRdsDC:
|
|
* * * * * * *
|
|
|
|
****************** This is a temporary hook to the old RDS_MAKEUP window for conversion JCH 4/8/2008
|
|
|
|
CtrlEntId = @WINDOW:'.WO_STEP_RDS_NO'
|
|
|
|
CurrPos = Get_Property(CtrlEntId,'SELPOS')
|
|
RowData = Get_Property(CtrlEntId,'ROWDATA')
|
|
ColData = Get_Property(CtrlEntId,'ARRAY')
|
|
|
|
CurrCol = CurrPos<1>
|
|
CurrRow = CurrPos<2>
|
|
|
|
IF CurrCol = 1 AND RowData<CurrCol> NE '' THEN
|
|
RDSNo = RowData<CurrCol>
|
|
END ELSE
|
|
RDSNo = ''
|
|
END
|
|
|
|
IF RDSNo = '' THEN RETURN
|
|
|
|
IF Get_Property(@WINDOW,'SAVEWARN') THEN
|
|
Send_Event(@WINDOW,'WRITE')
|
|
END
|
|
|
|
obj_AppWindow('ViewRelated','RDS_MAKEUP':@RM:RDSNo)
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * *
|
|
FQAVerify:
|
|
* * * * * *
|
|
|
|
// Check if FQA'd. If so, prompt for override.
|
|
Authorized = False$
|
|
WorkOrdNo = Get_Property(@Window : '.WO_NO', 'TEXT')
|
|
CassNo = Get_Property(@Window : '.CASS_NO', 'TEXT')
|
|
WoMatKey = WorkOrdNo:'*':CassNo
|
|
WoMatRec = Database_Services('ReadDataRow', 'WO_MAT', WoMatKey)
|
|
|
|
FQASig = ''
|
|
FQADate = ''
|
|
ReactorType = XLATE('WO_LOG', WorkOrdNo, 'REACT_TYPE', 'X')
|
|
SigArray = Signature_Services('GetSigProfile', WOMatKey)
|
|
SigProfile = SigArray<1>
|
|
Signatures = SigArray<2>
|
|
SigDTMS = SigArray<3>
|
|
|
|
IF (ReactorType = 'EPP') OR (ReactorType = 'EpiPro') THEN
|
|
StatusStage = 'MO_QA'
|
|
END ELSE
|
|
StatusStage = 'QA'
|
|
END
|
|
|
|
LOCATE StatusStage IN SigProfile USING @VM SETTING Pos THEN
|
|
FQASig = Signatures<1, Pos>
|
|
FQADate = SigDTMS<1, Pos>
|
|
end
|
|
|
|
If (FQASig NE '') and (FQADate NE '') then
|
|
// Cassette FQA'd
|
|
OverrideMsg = "Cassette already FQA'd. SUPERVISOR, LEAD OR ENG. TECH must override."
|
|
Response = Msg(@Window, '', 'OVERRIDE', '', OverrideMsg)
|
|
|
|
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
|
|
Response = Dialog_Box('NDW_VERIFY_USER', @WINDOW, @USER4:@FM:'LEAD':@VM:'SUPERVISOR':@VM:'ENG_TECH')
|
|
Authorized = Response<1>
|
|
end else
|
|
Authorized = False$
|
|
end
|
|
end else
|
|
Authorized = True$
|
|
end
|
|
|
|
return
|
|
|
|
|
|
LogRecord:
|
|
|
|
WOMatRecCopy = WOMatRec
|
|
Swap @FM with CRLF$ in WOMatRecCopy
|
|
LogData = ''
|
|
LogData<1> = LoggingDTM
|
|
LogData<2> = @USER4
|
|
LogData<3> = WOMatKey
|
|
LogData<4> = WOMatRecCopy
|
|
LogData<5> = RetStack()
|
|
Logging_Services('AppendLog', ObjLog, LogData, @RM, @FM, False$)
|
|
|
|
return
|
|
|
|
|
|
|