COMPILE FUNCTION Comm_RDS(Method, Parm1, Parm2)
#pragma precomp SRP_PreCompiler

/*
	Commuter module for existing RDS... windows.
	Used for added functionality in the RDS Mess.
	
	09/17/2004 - John C. Henry, J.C. Henry & Co., Inc.
	
	06/13/2024	djm		Add new stage-specific supplement system.
*/

DECLARE SUBROUTINE Set_Property, End_Dialog, Send_Event, Set_Status, ErrMsg, Security_Err_Msg, Popup, Print_Cass_Labels
DECLARE SUBROUTINE Print_Prod_Labels, obj_WO_Mat_Log, obj_Post_Log, obj_Tables, obj_React_Run, Post_Event, Hold_Services
DECLARE SUBROUTINE obj_Appwindow, Start_Window, Btree.Extract, Msg, Start_Window,Print_Cleanroom_Labels_Thermal, Error_Services
DECLARE SUBROUTINE obj_RDS_Test, obj_Notes, Print_Control_Plan, obj_WO_Mat, Send_Event, Print_RDS_Instruction, obj_RDS
DECLARE SUBROUTINE Start_Window, Development_Services, Dialog_Box, SAP_Services, End_Window, Logging_Services, Rds_Services
Declare subroutine Labeling_Services

DECLARE FUNCTION Get_Property, Get_Status, Dialog_Box, Utility, Send_Message, Popup, obj_RDS_Makeup, Msg, obj_RDS
DECLARE FUNCTION obj_Tables, obj_Clean_Insp, obj_WO_Mat_QA, obj_RDS_Test, obj_WO_Mat, Signature_Services
DECLARE FUNCTION obj_WO_Step, Security_Check, obj_RDS_Audit, obj_WM_In, Create_Dialog, obj_NCR, obj_WO_Mat, MemberOf
DECLARE FUNCTION Start_Window, Database_Services, Development_Services, RDS_Services, RTI_Lock_Owner, Logging_Services
DECLARE FUNCTION Environment_Services, Wafer_Counter_Services, Error_Services, Hold_Services, Datetime

EQU CRLF$	TO \0D0A\

$INSERT LOGICAL
$INSERT APPCOLORS
$INSERT MSG_EQUATES
$INSERT POPUP_EQUATES
$INSERT RDS_EQUATES
$INSERT WO_STEP_EQU
$INSERT WO_LOG_EQUATES
$INSERT SECURITY_RIGHTS_EQU
$INSERT SEC_GROUPS_EQU
$INSERT DICT_EQUATES
$INSERT NOTIFICATION_EQU
$INSERT RDS_EPILOAD					;* Equates for data coming back from the EpiPRO Load/Unload dialog boxes
$INSERT LSL_USERS_EQU
$INSERT PROD_SPEC_EQU
$INSERT WO_MAT_EQUATES
$INSERT REACTOR_EQUATES
$INSERT CLEAN_INSP_EQUATES
$INSERT TOOL_CLASS_EQUATES
$INSERT QUOTE_SIGS_EQU
$INSERT COMPANY_EQUATES
$INSERT PRS_STAGE_EQUATES
$INSERT WO_MAT_QA_EQUATES
$INSERT WAFER_COUNTER_EQUATES

EQU COL$LOG_FILE		TO 1		;* obj_WO_Mat_Log method parameter equates
EQU COL$LOG_DTM 		TO 2
EQU COL$WO_MAT_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 FONT_FACE_NAME$			TO 1
EQU FONT_HEIGHT$			TO 2
EQU FONT_WEIGHT$			TO 3
EQU FONT_ITALIC$			TO 4
EQU FONT_UNDERLINE$			TO 5
EQU FONT_WIDTH$				TO 6
EQU FONT_CHAR_SET$			TO 7
EQU FONT_PITCH_AND_FAMILY$	TO 8
EQU FONT_STRIKE_OUT$		TO 9
EQU FONT_OUT_PRECISION$		TO 10
EQU FONT_CLIP_PRECISION$	TO 11
EQU FONT_QUALITY$			TO 12

EQU COL$LSID			TO 1
EQU COL$RECIPE			TO 2
EQU COL$RECIPE_NAME		TO 3
EQU COL$PARAMS			TO 4
EQU COL$PARMS_OUT		TO 5
EQU COL$BLANK_COL		TO 6
EQU COL$MET_NO			TO 7
EQU COL$THICK_AVG		TO 8
EQU COL$RRHO_AVG		TO 9
EQU COL$MET_NO_Z1		TO 10
EQU COL$THICK_AVG_Z1	TO 11
EQU COL$RRHO_AVG_Z1		TO 12
EQU COL$MET_NO_Z2		TO 13
EQU COL$THICK_AVG_Z2	TO 14
EQU COL$RRHO_AVG_Z2		TO 15
EQU COL$MET_OUT			TO 16
EQU COL$MET_OUT_Z1		TO 17
EQU COL$MET_OUT_Z2		TO 18
EQU COL$MET_TWSIG		TO 19
EQU COL$MET_TWSIG_Z1	TO 20
EQU COL$MET_TWSIG_Z2	TO 21

EQU COL$POCKET			TO 1
EQU COL$USE				TO 2
EQU COL$ZONE			TO 3
EQU COL$IN_CASS			TO 4
EQU COL$IN_SLOT			TO 5
EQU COL$CHAR			TO 6
EQU COL$OUT_CASS		TO 7
EQU COL$OUT_SLOT		TO 8
EQU COL$NCR				TO 9		;* Dead?

EQU COL$MET_TEST		TO 1		;* QA Metrology control RDS_POST_EPI window
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

EQU COL$UL_MET_TEST		    TO 1		;* QA Metrology control on RDS_UNLOAD window
EQU COL$UL_MET_TEST_DESC	TO 2
EQU COL$UL_MET_RECIPE       TO 3
EQU COL$UL_MET_SLOT		    TO 4
EQU COL$UL_MET_SLOT_DESC	TO 5
EQU COL$UL_MET_WFR_QTY		TO 6
EQU COL$UL_MET_MIN			TO 7
EQU COL$UL_MET_MAX			TO 8
EQU COL$UL_MET_RESULT		TO 9
EQU COL$UL_MET_PHASE_MIN    TO 10
EQU COL$UL_MET_PHASE_RESULT TO 11
EQU COL$UL_MET_SIG			TO 12
EQU COL$UL_MET_SIG_DTM		TO 13

EQU COL$HOLD_START_DTM		TO 1
EQU COL$HOLD_START_USER		TO 2
EQU COL$HOLD_START_REASON	TO 3
EQU COL$HOLD_STOP_DTM		TO 4
EQU COL$HOLD_STOP_USER		TO 5
EQU COL$HOLD_STOP_REASON	TO 6

EQU COL$ACTION           TO 1
EQU COL$SPEC_CLEAN_TOOL  TO 2
EQU COL$SPEC_EDGE        TO 3
EQU COL$SPEC_MICROSCOPE  TO 4
EQU COL$SPEC_BRIGHTLIGHT TO 5
EQU COL$SURFSCAN_RECIPE  TO 6
EQU COL$TOOL             TO 7
EQU COL$SIG              TO 8
EQU COL$SIG_DTM          TO 9

LogDate      = Oconv(Date(), 'D4/')
LogTime      = Oconv(Time(), 'MTS')
LogPath      = Environment_Services('GetApplicationRootPath') : '\LogFiles\RDS'
LogFileName  = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' WAFERS_IN.csv'
Headers      = 'Logging DTM' : @FM : 'RDS Key ID' : @FM : 'WAFERS_IN'
objWafersLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ',', Headers, '', False$, False$)
LoggingDTM   = LogDate : ' ' : LogTime   ; // Logging DTM

ErrTitle = 'Error in Comm_RDS'
ErrorMsg = ''

Result = ''

BEGIN CASE
    CASE Method = 'Clear'				; GOSUB Clear
    CASE Method = 'Refresh'				; GOSUB Refresh
    CASE Method = 'GotFocus'			; GOSUB GotFocus
    CASE Method = 'RdsLF'				; GOSUB RdsLF
    CASE Method = 'MUWafers'			; GOSUB MUWafers
    CASE Method = 'ProdWfrLF'			; GOSUB ProdWfrLF
    CASE Method = 'WafersInLF'			; GOSUB WafersInLF
    CASE Method = 'Update'				; GOSUB Update
    CASE Method = 'FirstRead'			; GOSUB FirstRead
    CASE Method = 'FirstRefresh'		; GOSUB FirstRefresh
    CASE Method = 'NewNCR'				; GOSUB NewNCR
    CASE Method = 'NCRKeysDC'			; GOSUB NCRKeysDC
    CASE Method = 'PrintLabels'			; GOSUB PrintLabels
    CASE Method = 'ViewAudit'			; GOSUB ViewAudit
    CASE Method = 'LSIdDC'				; GOSUB LSIdDC
    CASE Method = 'LoadEpiPro'			; GOSUB LoadEpiPro
    CASE Method = 'UnloadEpiPro'		; GOSUB UnloadEpiPro
    CASE Method = 'ClearEpiUnload'		; GOSUB ClearEpiUnload
    CASE Method = 'AddZoneMet'			; GOSUB AddZoneMet
    CASE Method = 'MoveMetToZone'		; GOSUB MoveMetToZone
    CASE Method = 'RemZoneMet'          ; GOSUB RemoveZoneMet
    CASE Method = 'HoldClick'			; GOSUB HoldClick
    CASE Method = 'HoldDC'				; GOSUB HoldDC
    CASE Method = 'CtrlPlanClick'		; GOSUB CtrlPlanClick
    CASE Method = 'Override'			; GOSUB Override
    CASE Method = 'PrintInstruction'	; GOSUB PrintInstruction
    CASE Method = 'ViewWOMat'			; GOSUB ViewWOMat
    CASE Method = 'NextStepQty'			; GOSUB NextStepQty
    CASE Method = 'CIClick'				; GOSUB CIClick
    CASE Method = 'SAPSign'				; GOSUB SAPSign
    CASE Method = 'SAPReject'			; GOSUB SAPReject
    CASE Method = 'MetTestDC'			; GOSUB MetTestDC
    CASE Method = 'LUPostCode'			; GOSUB LUPostCode
    CASE Method = 'SigProfile'			; GOSUB SigProfile
    CASE Method = 'ReactProfile'		; GOSUB ReactProfile
    CASE Method = 'OverrideLog'			; GOSUB OverrideLog
    CASE Method = 'AddComment'			; GOSUB AddComment
    CASE Method = 'ViewComments'		; GOSUB ViewComments
	CASE Method = 'ViewLotHistory'      ; GOSUB ViewLotHistory
    CASE Method = 'Close'               ; GOSUB Close
    CASE 1
        ErrMsg(ErrTitle:@SVM:'Unknown method ':QUOTE(Method):' passed to routine.')
        
END CASE


RETURN Result



* * * * * * * 
RdsLF:
* * * * * * *

    RDSNo = Get_Property(@WINDOW:'.RDS_NO','DEFPROP')
    IF RDSNo NE '' THEN
        IF RowExists('RDS',RDSNo) ELSE
            Msg(@WINDOW,'','INVALID_RDS_NO')
        END
    END	;* End of check for null RDSNo
    
RETURN


* * * * * * *
Clear:
* * * * * * *
    
    
* * * * * * *
Refresh:
* * * * * * *

    **** Added 4/9/2014 JCH * * * * * * 
    
    WONo = Get_Property(@WINDOW:'.WO','DEFPROP')
    
    IF WONo NE ''  THEN
        PriDisp = XLATE('WO_LOG',WONo,'PRI_DISPLAY','X')
        
        Set_Property(@WINDOW:'.PRI_DISPLAY_TEXT','TEXT',PriDisp)
        
        CurrFontProp = Get_Property(@WINDOW:'.PRI_DISPLAY_TEXT','FONT')
        
        NewFontProp = FIELD(CurrFontProp,@SVM,1,12)
        
        IF PriDisp[1,2] = 'P1' THEN
            Set_Property(@WINDOW:'.PRI_DISPLAY_TEXT','DEFPROP','P1 - High')
            NewFontProp<1,1,FONT_WEIGHT$> = 700
            NewFontProp<1,1,FONT_ITALIC$> = 255
            NewFontProp<1,1,FONT_WIDTH$> = 7
            ForeColor = BRED$
            
        END
        
        IF PriDisp[1,2] = 'P2' THEN
            Set_Property(@WINDOW:'.PRI_DISPLAY_TEXT','DEFPROP','P2 - Medium')
            NewFontProp<1,1,FONT_WEIGHT$> = 400
            NewFontProp<1,1,FONT_ITALIC$> = 255
            NewFontProp<1,1,FONT_WIDTH$> = 6
            ForeColor = BYELLOW$
        END	
        
        IF PriDisp[1,2] = 'P3' THEN
            Set_Property(@WINDOW:'.PRI_DISPLAY_TEXT','DEFPROP','P3 - Low')
            NewFontProp<1,1,FONT_WEIGHT$> = 400
            NewFontProp<1,1,FONT_ITALIC$> = 0
            NewFontProp<1,1,FONT_WIDTH$> = 6
            ForeColor = FONTGREEN$
            
        END
        
        Set_Property(@WINDOW:'.PRI_DISPLAY_TEXT','FONT', NewFontProp)
        Set_Property(@WINDOW:'.PRI_DISPLAY_TEXT','FORECOLOR',ForeColor)
    END	;* End of check for window
    
    PSNo = Get_Property(@WINDOW:'.PSN','TEXT')
    PSStatus = XLATE('PROD_SPEC',PSNo,9,'X')
    
    IF PSStatus[1,1] = 'I' THEN
        Set_Property(@WINDOW:'.PSN','BACKCOLOR',RED$)
    END ELSE
        Set_Property(@WINDOW:'.PSN','BACKCOLOR',GREEN$)
    END
    
    IF MemberOf(@USER4,'TESTING') THEN
        
        BEGIN CASE
            CASE @WINDOW = 'RDS_PRE_EPI'
                Set_Property(@WINDOW:'.PRE_CI_NO','VISIBLE',1)
            CASE @WINDOW = 'RDS'
                Set_Property(@WINDOW:'.FWI_CI_NO','VISIBLE',1)
            CASE @WINDOW = 'RDS_UNLOAD'
                Set_Property(@WINDOW:'.LWI_CI_NO','VISIBLE',1)
            CASE @WINDOW = 'RDS_POST_EPI'
                Set_Property(@WINDOW:'.POST_CI_NO','VISIBLE',1)
        END CASE
    END
    
    * Modification History Button
    
    ProdMgr = XLATE( 'CONFIG', 'QUOTE_SIGS', ProdMgr$, 'X' )
    TrainSpec = XLATE( 'CONFIG', 'QUOTE_SIGS', TrainSpec$, 'X' )
    
    IF (Memberof( @USER4, 'MASTER' )) OR ( @USER4 = ProdMgr ) OR ( @USER4 = TrainSpec ) THEN
        Set_Property( @WINDOW:'.VIEW_MOD_HIST', 'VISIBLE', 1 )
    END
    
    RDSNo     = Get_Property(@Window:'.RDS_NO', 'TEXT')
	WOMatKey  = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X', '')
    HoldCheck = Hold_Services('CheckForHold', WOMatKey, '')
	IF HoldCheck THEN
    	Set_Property(@WINDOW:'.HOLD_BUTTON2','TEXT','Remove Hold')
    	Set_Property(@Window:'.MENU.PRINT.REPRINT_HOLD_LABEL', 'ENABLED', True$)
   END ELSE
        Set_Property(@WINDOW:'.HOLD_BUTTON2','TEXT','Place on Hold')
        Set_Property(@Window:'.MENU.PRINT.REPRINT_HOLD_LABEL', 'ENABLED', False$)
   END
    
    
    * Wafers Accounting and update section
    
    UseMUWafers		= Get_Property(@WINDOW:'.MU_WAFERS_FLAG','CHECK')
    MakeupBox		= Get_Property(@WINDOW:'.MAKEUP_BOX','CHECK')
    WafersIn		= Get_Property(@WINDOW:'.WAFERS_IN','INVALUE')
    WafersOut		= Get_Property(@WINDOW:'.WAFERS_OUT','INVALUE')
    WafersScheduled = Get_Property(@WINDOW:'.WAFERS_SCHEDULED','INVALUE')
    WafersVerify	= Get_Property(@WINDOW:'.VERIFY_QTY','INVALUE')
    WafersProdTest	= Get_Property(@WINDOW:'.TW_PROD','INVALUE')
    WafersTotRej	= Get_Property(@WINDOW:'.TOT_REJ','INVALUE')
    WafersSRPBill	= Get_Property(@WINDOW:'.RESEARCH_SRP_BILLABLE','INVALUE')
    RunOrderNo		= Get_Property(@WINDOW:'.RUN_ORDER_NUM','INVALUE')
    MUWfrsRemoved	= Get_Property(@WINDOW:'.MU_WFRS_REMOVED','INVALUE')
    MUWfrsAdded		= Get_Property(@WINDOW:'.MU_WFRS_ADDED','INVALUE')
    WONo			= Get_Property(@WINDOW:'.WO','INVALUE')
    CassNo			= Get_Property(@WINDOW:'.CASS_NO','INVALUE')
    CassSchedShip   = Get_Property(@WINDOW:'.CASS_SHIP_QTY', 'INVALUE')
    
    CassShipQty     = XLATE('WO_MAT',WONo:'*':CassNo,WO_MAT_CASS_SHIP_QTY$,'X')
    MinCassShipQty  = XLATE('WO_MAT',WONo:'*':CassNo,WO_MAT_MIN_CASS_SHIP_QTY$,'X')
    
    IF CassShipQty NE '' AND CassShipQty > 0 THEN
        FullBoxQty = CassShipQty
    END ELSE
        FullBoxQty = WafersIn
    END
    
    EnableLoadButton = 1
    EnableQASignButton = 1
    EnableUnloadButton = 1
    
    QASignReason = ''
    
    IF UseMUWafers THEN
        Set_Property(@WINDOW:'.MU_WAFER_BUTTON','VISIBLE',0)
        IF (WafersIn NE '' AND WafersOut NE ''  AND WafersOut < FullBoxQty) THEN
            IF RunOrderNo = 1 THEN
                IF MUWfrsRemoved NE '' THEN
                    Set_Property(@WINDOW:'.MU_WAFER_BUTTON','ENABLED',0)	;* Rejects, needs makeup wafers** was 1 jch
                END ELSE
                    Set_Property(@WINDOW:'.MU_WAFER_BUTTON','ENABLED',0)	;* was 1 jch
                END
            END ELSE
                Set_Property(@WINDOW:'.MU_WAFER_BUTTON','ENABLED',0)		;* was 1 jch
            END
        END ELSE
            IF MUWfrsRemoved NE '' OR MUWfrsAdded NE '' THEN
                Set_Property(@WINDOW:'.MU_WAFER_BUTTON','ENABLED',0)		;* was 1 jch
            END ELSE
                Set_Property(@WINDOW:'.MU_WAFER_BUTTON','ENABLED',0)	;* No rejects, doesn't need makeup wafers
            END
        END
    END ELSE
        Set_Property(@WINDOW:'.MU_WAFER_BUTTON','VISIBLE',0)
    END
    
    BoxType = Get_Property(@WINDOW:'.BOX_TYPE','TEXT')
    
    IF BoxType = 'Merged Lots' THEN
        Set_Property(@WINDOW:'.MU_WAFERS_ADDED','ENABLED',1)
        Set_Property(@WINDOW:'.MU_ADDED_LABEL','ENABLED',1)
    END ELSE
        Set_Property(@WINDOW:'.MU_WAFERS_ADDED','ENABLED',0)
        Set_Property(@WINDOW:'.MU_ADDED_LABEL','ENABLED',0)
    END
    
    IF BoxType = 'Makeup Box' THEN
        Set_Property(@WINDOW:'.MU_WAFERS_REMOVED','ENABLED',1)
        Set_Property(@WINDOW:'.MU_REMOVED_LABEL','ENABLED',1)
    END ELSE
        Set_Property(@WINDOW:'.MU_WAFERS_REMOVED','ENABLED',0)
        Set_Property(@WINDOW:'.MU_REMOVED_LABEL','ENABLED',0)
    END
    
    IF (WafersIn NE WafersScheduled) OR (WafersVerify NE WafersScheduled) THEN
        EnableQASignButton	= 0
        IF QASignReason = '' THEN QASignReason = 'Wafers In or Wafers Verified is not equal to Wafers Scheduled'
    END
    
    IF Get_Property(@WINDOW:'.HOT_LOT','CHECK') THEN
        Set_Property(@WINDOW:'.HOT_LOT_LABEL','VISIBLE',1)
    END ELSE
        Set_Property(@WINDOW:'.HOT_LOT_LABEL','VISIBLE',0)
    END
    
    IF Get_Property(@WINDOW:'.HGCV_TEST_CHECK','CHECK') THEN
        Set_Property(@WINDOW:'.HGCV_TEST','VISIBLE',1)
    END ELSE
        Set_Property(@WINDOW:'.HGCV_TEST','VISIBLE',0)
    END
    
    * * * * Pre Epi window
    
    IF @WINDOW = 'RDS_PRE_EPI' THEN
        VerifyQty = Get_Property(@WINDOW:'.VERIFY_QTY','INVALUE')
        RDSNo     = Get_Property(@Window:'.RDS_NO', 'TEXT')
        LoadSig   = Xlate('RDS', RDSNo, 'OPERATOR_IN', 'X')
        If LoadSig NE '' then Set_Property(@Window:'.VERIFY_QTY', 'ENABLED', False$)
        
        IF VerifyQty NE WafersScheduled THEN
            Ctrls = @WINDOW:'.VERIFY_QTY'
            Props = 'BACKCOLOR'
            Vals = RED$
        END ELSE
            Ctrls = @WINDOW:'.VERIFY_QTY'
            Props = 'BACKCOLOR'
            If LoadSig NE '' then
                Vals = READONLY_GREEN$
            end else
                Vals = WHITE$
            end
        END
        Set_Property(Ctrls,Props,Vals)
        
        IF Get_Property(@WINDOW:'.HOLD_CHECKBOX','CHECK') THEN
            Set_Property(@WINDOW:'.HOLD_BUTTON','TEXT','Remove Hold')
        END ELSE
            Set_Property(@WINDOW:'.HOLD_BUTTON','TEXT','Place on Hold')
        END
        
        IF MemberOf(@USER4, 'OI_ADMIN') THEN
            Set_Property(@WINDOW:'.FIX_SIG_PROFILE','VISIBLE',1)
        END ELSE
            Set_Property(@WINDOW:'.FIX_SIG_PROFILE','VISIBLE',0)
        END 
    END
    
    * * * * * Load / Wafer Inspection window
    
    IF @WINDOW = 'RDS' THEN
        PSNo			= Get_Property(@WINDOW:'.PSN','TEXT')
        FirstWfrSig		= Get_Property(@WINDOW:'.FW_SIG','DEFPROP')
        WinBackColor	= Get_Property(@WINDOW,'BACKCOLOR')			;* default background color
        
        FirstOrLast = XLATE('PROD_SPEC',PSNo,PROD_SPEC_POST_FWI_LWI$,'X')
        IF FirstOrLast NE '' THEN
            IF FirstOrLast = 'FWI' THEN
                Set_Property(@WINDOW:'.GROUP_10','TEXT','FWI Surface Inspection Signature')
                Set_Property(@WINDOW:'.SURFACE_Q_BUTTON','TEXT','FWI Surface Inspection')
            END
            IF FirstOrLast = 'LWI' THEN
                Set_Property(@WINDOW:'.GROUP_10','TEXT','LWI Surface Inspection Signature')
                Set_Property(@WINDOW:'.SURFACE_Q_BUTTON','TEXT','LWI Surface Inspection')
            END
            IF FirstWfrSig = '' THEN
                Set_Property(@WINDOW:'.GROUP_10','BACKCOLOR',YELLOW$)
            END ELSE
                Set_Property(@WINDOW:'.GROUP_10','BACKCOLOR',WinBackColor)
            END
        END
        
    END
    
    * * * * * Unload Window
    
    IF @WINDOW = 'RDS_UNLOAD' THEN
        
        Reactor = Get_Property(@WINDOW:'.REACTOR','DEFPROP')
        ReactorType = XLATE('REACTOR',Reactor,1,'X')
        IF ReactorType = 'EPP' THEN
            Set_Property(@WINDOW:'.NCR_MU_BUTTON','VISIBLE',0)
        END ELSE
            Set_Property(@WINDOW:'.NCR_MU_BUTTON','VISIBLE',1)
        END
        
        CtrlName = @WINDOW:'.NCR_KEYS'
        NCRList = Get_Property(CtrlName,'LIST')
        
        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$
                    EnableQASignButton	= 0
                    IF QASignReason = '' THEN QASignReason = 'Open NCR'
                    
                CASE Status = 'Verified'
                    Color = YELLOW$
                    
                CASE 1
                    Color = WHITE$
                    
            END CASE
            stat = Send_Message(CtrlName,'COLOR_BY_POS',0,Line,Color)
            
        NEXT Line
        
        UnloadSig = Get_Property(@Window:'.OP_OUT', 'TEXT')
        If UnloadSig NE '' then
            Set_Property(@Window:'.PUB_SIGN', 'TEXT', 'Unsign')
        end else
            Set_Property(@Window:'.PUB_SIGN', 'TEXT', 'Sign')
        end
        
    END
    
    ****************************************************************************************************************************************
    // RDS and RDS_POST_EPI
    If @WINDOW = 'RDS' or @WINDOW = 'RDS_POST_EPI' THEN
    
        CtrlName    = @WINDOW:'.MET_TEST'
        MetList     = Get_Property(CtrlName,'LIST')
        MetListtest = XLATE('RDS', @ID, 'MET_TEST_QA', 'X')
        MLCnt       = COUNT(MetList,@FM) + (MetList NE '')
        FOR Line = 1 TO MLCnt
        	//MetResult = ICONV(MetList<Line,COL$MET_RESULT>, "MD1")
            IF MetList<Line,COL$MET_TEST> NE '' THEN
                BEGIN CASE
                    CASE MetList<Line,COL$MET_RESULT> = '' 
                        Color = YELLOW$
                    CASE MetList<Line,COL$MET_RESULT> < MetList<Line,COL$MET_MIN> OR MetList<Line,COL$MET_RESULT> > MetList<Line,COL$MET_MAX>
                    //CASE MetResult < MetList<Line,COL$MET_MIN> OR MetResult > MetList<Line,COL$MET_MAX>
                        Color = RED$
                    CASE 1
                        Color = GREEN$
                END CASE
                
            END	ELSE
                Color = GREEN$
            END;* End of check for Met Test on the current line
            
            stat = Send_Message(CtrlName,'COLOR_BY_POS',0,Line,Color)
        NEXT Line
        
        IF @WINDOW = 'RDS_POST_EPI' AND (Color = RED$ OR Color = YELLOW$) Then
            WOMatKey = WONo:'*':CassNo
            RDSNo = Xlate('WO_MAT', WOMatKey, 'RDS_NO', 'X')
            WOStep = Xlate('RDS', RDSNo, 'WO_STEP', 'X')
            QAResults = obj_WO_Mat_QA('QAResults',WONo:@RM:WOStep:@RM:CassNo)
            If QAResults NE '' THEN
                EnableQASignButton	= 0
                IF QASignReason = '' THEN QASignReason = QAResults
            END
        END
        
        If @WINDOW EQ 'RDS' then
            LoadSig = Get_Property(@Window:'.OP_IN', 'TEXT')
            PUBText = Get_Property(@Window:'.PUB_SIGN', 'TEXT')
            If LoadSig NE '' then
                Set_Property(@Window:'.PUB_SIGN', 'TEXT', 'Unsign')
            end else
                Set_Property(@Window:'.PUB_SIGN', 'TEXT', 'Sign')
            end
        end
        
    END	
    
    ****************************************************************************************************************************************
    // RDS_UNLOAD
    
    If @WINDOW EQ 'RDS_UNLOAD' then
            
		CtrlName       = @WINDOW:'.EDT_QA_MET'
		Set_Property(@Window : '.MET_TEST', 'VISIBLE', False$)
		Set_Property(CtrlName, 'VISIBLE', True$)
		MetList        = Get_Property(CtrlName,'LIST')
		ThickOutOfSpec = False$
		CresOutOfSpec  = False$
		MLCnt          = COUNT(MetList,@FM) + (MetList NE '')
		FOR Line = 1 TO MLCnt
			IF MetList<Line,COL$UL_MET_TEST> NE '' THEN
				MetResult        = MetList<Line,COL$UL_MET_RESULT>
				MetMin           = MetList<Line,COL$UL_MET_MIN>
				MetMax           = MetList<Line,COL$UL_MET_MAX>
				PhaseMin         = MetList<Line,COL$UL_MET_PHASE_MIN>
				PhaseResult      = MetList<Line,COL$UL_MET_PHASE_RESULT>
				ScanRecipe       = MetList<Line,COL$UL_MET_RECIPE>
				PSN              = Get_Property(@Window : '.PSN', 'TEXT')
				PRSStageKey      = PSN:'*UNLOAD'
				MetTest          = MetList<Line,COL$UL_MET_TEST>
				PRSStageRec      = Database_Services('ReadDataRow', 'PRS_STAGE', PRSStageKey)
				SpecTests        = PRSStageRec<PRS_STAGE_MET_TEST$>
				SpecRecipe       = ''
				RDSNo            = Get_Property(@Window:'.RDS_NO', 'TEXT')
				QAMetKey         = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X')
				WOMatQARec       = Database_Services('ReadDataRow', 'WO_MAT_QA', QAMetKey)
				DataPoints       = WOMatQARec<WO_MAT_QA_DATA_POINTS$, Line>
				Begin Case
					Case MetTest EQ 'THICK_ONLY'
						// Check each point to see if any are out of spec
						For each DataPoint in DataPoints using @SVM setting ThickIndex
						Until DataPoint EQ ''
							Begin Case
								Case ThickIndex GT 10
									Null
								Case (DataPoint EQ '')
									ThickOutOfSpec = True$
								Case (DataPoint GT MetMax) OR (DataPoint LT MetMin)
									ThickOutOfSpec = True$
							End Case
						Next DataPoint
						
					Case MetTest EQ 'CRES'
						// Check critical points to see if any are out of spec (both HgCV and Phase)
						CriticalPoints = '1,2,5,6,9'
						For each DataPoint in DataPoints using @SVM setting CresIndex
						Until DataPoint EQ ''
							HgCVDataPoint  = DataPoint[1, 'F':@TM]
							PhaseDataPoint = DataPoint[-1, 'B':@TM]
							CriticalPoint  = Index(CriticalPoints, CresIndex, 1)
							Begin Case
								Case (HgCVDataPoint EQ '') and CriticalPoint
									CresOutOfSpec = True$
								Case (PhaseDataPoint EQ '') and CriticalPoint
									CresOutOfSpec = True$
								Case (HgCVDataPoint GT MetMax) OR (HgCVDataPoint LT MetMin) and CriticalPoint
									CresOutOfSpec = True$
								Case (PhaseDataPoint LT PhaseMin) and CriticalPoint
									CresOutOfSpec = True$
							End Case
						Next DataPoint
				End Case
				QAMetOutofSpec = (ThickOutOfSpec or CresOutOfSpec)
				Locate MetTest in SpecTests using @VM setting vPos then
					SpecRecipe = PRSStageRec<PRS_STAGE_MET_RECIPE$, vPos>
				end                
				NoError = True$

				If (MetList<Line,COL$UL_MET_RESULT> EQ '') then
					Color = YELLOW$
					stat = Send_Message(CtrlName, 'COLOR_BY_POS', COL$UL_MET_RESULT, Line, Color)
					NoError = False$
				end
				
				If QAMetOutofSpec EQ True$ then
					Color   = BYELLOW$:@FM:BLACK$:@FM:BYELLOW$:@FM:BLACK$
					stat    = Send_Message(CtrlName, 'COLOR_BY_POS', COL$UL_MET_RESULT, Line, Color)
					NoError = False$
				end
				
				If (MetResult LT MetMin) then
					Color = RED$:@FM:'':@FM:BRED$:@FM:''
					stat = Send_Message(CtrlName, 'COLOR_BY_POS', COL$UL_MET_RESULT, Line, Color)
					NoError = False$
				end
				
				If (MetResult GT MetMax) then
					Color = RED$:@FM:'':@FM:BRED$:@FM:''
					stat = Send_Message(CtrlName, 'COLOR_BY_POS', COL$UL_MET_RESULT, Line, Color)
					NoError = False$
				end
				
				If (PhaseResult LT PhaseMin) then
					Color = RED$:@FM:'':@FM:BRED$:@FM:''
					stat = Send_Message(CtrlName, 'COLOR_BY_POS', COL$UL_MET_PHASE_RESULT, Line, Color)
					NoError = False$
				end
				
				QAFailReason = WOMatQARec<WO_MAT_QA_FAIL_REASON$, Line>
				DetectedFail = Index(QAFailReason, 'Number of data points is less than the required amount', 1)
				If (ScanRecipe NE SpecRecipe) OR (DetectedFail) then
					Color = RED$:@FM:'':@FM:BRED$:@FM:''
					stat = Send_Message(CtrlName, 'COLOR_BY_POS', COL$UL_MET_RECIPE, Line, Color)
					NoError = False$
				end
				
				If (NoError EQ True$) then
					Color = GREEN$
					stat = Send_Message(CtrlName,'COLOR_BY_POS',0,Line,Color)
				end
				
			END	ELSE
				Color = GREEN$
				stat = Send_Message(CtrlName,'COLOR_BY_POS',0,Line,Color)
			END
			
		NEXT Line
		
		Set_Property(@WINDOW:'.BUTTON_11','ENABLED',EnableUnloadButton)
		
		IF MemberOf(@USER4, 'OI_ADMIN') THEN
			Set_Property(@WINDOW:'.CLEAR_EPI_UNLOAD','VISIBLE',1)
		END ELSE
			Set_Property(@WINDOW:'.CLEAR_EPI_UNLOAD','VISIBLE',0)
		END
	end
    * End of check for Unload OR Post_Epi windows
    
    ****************************************************************************************************************************************
    
    
    IF @WINDOW = 'RDS_POST_EPI' THEN
        
        If WafersScheduled NE WafersOut then
            BackColor = RED$
        end else
            BackColor = GREEN$
        end
        
        Set_Property(@Window:'.WAFERS_SCHEDULED','BACKCOLOR',BackColor)
        Set_Property(@Window:'.WAFERS_OUT','BACKCOLOR',BackColor)
        
        IF MemberOf(@USER4, 'SAP_ADMIN') THEN
            Set_Property(@WINDOW:'.SAP_SIGN','VISIBLE',1)
            Set_Property(@WINDOW:'.SAP_REJECT','VISIBLE',1)
        END ELSE
            Set_Property(@WINDOW:'.SAP_SIGN','VISIBLE',0)
            Set_Property(@WINDOW:'.SAP_REJECT','VISIBLE',0)
        END
        
        ROTRAction      = Get_Property(@WINDOW:'.ROTR_ACTION','TEXT')  
        BEGIN CASE
            CASE ROTRAction[1,1] = 'P'
                BackColor = GREEN$
            CASE ROTRAction[1,1] = 'F'
                BackColor = RED$
            CASE ROTRAction[1,1] = 'W'
                BackColor = YELLOW$
            CASE ROTRAction[1,1] = 'A'
                BackColor = ORANGE$
            CASE 1
                BackColor = Get_Property(@WINDOW,'BACKCOLOR')
        END CASE
        Set_Property(@WINDOW:'.ROTR_ACTION','BACKCOLOR',BackColor)
        
        GoSub RefreshWaferCounterData

    end
    
    * * * * * Layer Set edit table control in Load and Post Epi windows

    IF @WINDOW = 'RDS' OR @WINDOW = 'RDS_POST_EPI' THEN
        
        IF Get_Property(@WINDOW:'.INV_FAB_COMP','CHECK') = 1 THEN
            Set_Property(@WINDOW:'.INV_FAB_HRS','BACKCOLOR',GREEN$)
        END ELSE
            Set_Property(@WINDOW:'.INV_FAB_HRS','BACKCOLOR',YELLOW$)
        END
        
        CtrlID = @WINDOW:'.RDS_LS_ID'
        
        LayerList = Get_Property(CtrlID,'LIST')
        
        FOR I = 1 TO COUNT(LayerList,@FM) + (LayerList NE '')
            
            * Layer Set Parameters
            
            IF ICONV(LayerList<I,COL$PARMS_OUT>,'B') = 1 THEN
                ParmColor = RED$
            END ELSE
                IF ICONV(LayerList<I,COL$PARAMS>,'B') = 0 THEN
                    ParmColor = YELLOW$
                    EnableQASignButton	= 0
                    IF QASignReason = '' THEN QASignReason ='Recipe Parameters incomplete'
                    
                END ELSE
                    ParmColor = GREEN$
                END
            END
            
            FOR Col = COL$LSID TO COL$PARMS_OUT
                stat = Send_Message(CtrlID,'COLOR_BY_POS',Col,I,ParmColor)
            NEXT Col
            
            * ASM Metrology
            
            IF LayerList<I,COL$MET_NO> NE '' THEN
                MetNo 	= LayerList<I,COL$MET_NO>
                MetRec 	= XLATE('RDS_TEST',MetNo,'','X')
                
                TWSigned 	= obj_RDS_Test('TWSignedOff',MetNo:@RM:MetRec)
                TestComp 	= obj_RDS_Test('TestComplete',MetNo:@RM:MetRec)
                OutOfSpec	= obj_RDS_Test('OutOfSpec',MetNo:@RM:MetRec)
                
                IF NOT(obj_RDS_Test('TWSignedOff',MetNo:@RM:MetRec)) THEN
                    MetColor = ORANGE$
                    EnableLoadButton = 0
                END
                
                IF NOT(obj_RDS_Test('TestComplete',MetNo:@RM:MetRec)) THEN
                    MetColor = ORANGE$
                    EnableQASignButton	= 0
                    IF QASignReason = '' THEN QASignReason = 'Metrology not signed off for Met No: ':MetNo
                END ELSE
                    
                    IF obj_RDS_Test('OutOfSpec',MetNo:@RM:MetRec) = 1 THEN
                        MetColor = RED$
                        EnableQASignButton	= 0
                        IF QASignReason = '' THEN QASignReason = 'Metrology ':MetNo:' is out of spec'
                        
                    END ELSE
                        IF LayerList<I,COL$THICK_AVG> = '' AND LayerList<I,COL$RRHO_AVG> = '' AND LayerList<I,COL$MET_NO> NE '' THEN
                            MetColor = YELLOW$
                            EnableQASignButton	= 0
                            IF QASignReason = '' THEN QASignReason = 'Metrology incomplete'
                        END ELSE
                            MetColor = GREEN$
                        END
                    END
                END
            END
            
            FOR Col = COL$MET_NO TO COL$RRHO_AVG
                stat = Send_Message(CtrlID,'COLOR_BY_POS',Col,I,MetColor)
            NEXT Col
            
            * Zone 1 EpiPRO Metrology
            
            IF LayerList<I,COL$MET_NO_Z1> NE '' THEN
                MetNo 	= LayerList<I,COL$MET_NO_Z1>
                MetRec 	= XLATE('RDS_TEST',MetNo,'','X')
                
                TWSigned 	= obj_RDS_Test('TWSignedOff',MetNo:@RM:MetRec)
                TestComp 	= obj_RDS_Test('TestComplete',MetNo:@RM:MetRec)
                OutOfSpec	= obj_RDS_Test('OutOfSpec',MetNo:@RM:MetRec)
                
                IF NOT(obj_RDS_Test('TWSignedOff',MetNo:@RM:MetRec)) THEN
                    MetColorZ1 = ORANGE$
                    EnableLoadButton = 0
                END
                
                IF NOT(obj_RDS_Test('TestComplete',MetNo:@RM:MetRec)) THEN
                    MetColorZ1	 = ORANGE$
                    EnableQASignButton	= 0
                    IF QASignReason = '' THEN QASignReason ='Zone 1 Metrology is Incomplete'
                END ELSE
                    
                    IF obj_RDS_Test('OutOfSpec',MetNo:@RM:MetRec) = 1 THEN
                        MetColorZ1 = RED$
                        EnableQASignButton = 0
                        IF QASignReason = '' THEN QASignReason ='Zone 1 Metrology is Out of Spec'
                        
                    END ELSE
                        IF LayerList<I,COL$THICK_AVG_Z1> = '' AND LayerList<I,COL$RRHO_AVG_Z1> = '' AND LayerList<I,COL$MET_NO_Z1> NE '' THEN
                            MetColorZ1 = YELLOW$
                            EnableQASignButton	= 0
                            IF QASignReason = '' THEN QASignReason = 'Zone 1 Metrology is Incomplete'
                        END ELSE
                            MetColorZ1 = PRE_BLUE$
                        END
                    END
                END
            END
            
            FOR Col = COL$MET_NO_Z1 TO COL$RRHO_AVG_Z1
                stat = Send_Message(CtrlID,'COLOR_BY_POS',Col,I,MetColorZ1)
            NEXT Col
            
            * Zone 2 EpiPRO Metrology
            
            IF LayerList<I,COL$MET_NO_Z2> NE '' THEN
                MetNo 	= LayerList<I,COL$MET_NO_Z2>
                MetRec 	= XLATE('RDS_TEST',MetNo,'','X')
                TWSigned 	= obj_RDS_Test('TWSignedOff',MetNo:@RM:MetRec)
                TestComp 	= obj_RDS_Test('TestComplete',MetNo:@RM:MetRec)
                OutOfSpec	= obj_RDS_Test('OutOfSpec',MetNo:@RM:MetRec)

*                IF NOT(obj_RDS_Test('TWSignedOff',MetNo:@RM:MetRec)) THEN
                If TWSigned EQ False$ then 
                    MetColorZ2 = ORANGE$
                    EnableLoadButton = 0
                END
                
*                IF NOT(obj_RDS_Test('TestComplete',MetNo:@RM:MetRec)) THEN
                If TestComp EQ False$ then 
                    MetColorZ2 = ORANGE$
                    EnableQASignButton = 0
                    IF QASignReason = '' THEN QASignReason = 'Zone 2 Metrology is Incomplete'
                END ELSE
                    
                    IF obj_RDS_Test('OutOfSpec',MetNo:@RM:MetRec) = 1 THEN
                        MetColorZ2 = RED$
                        EnableQASignButton = 0
                        IF QASignReason = '' THEN QASignReason = 'Zone 2 Metrology is Out of Spec'
                    END ELSE
                        IF LayerList<I,COL$THICK_AVG_Z2> = '' AND LayerList<I,COL$RRHO_AVG_Z2> = '' AND LayerList<I,COL$MET_NO_Z2> NE '' THEN
                            MetColorZ2 = YELLOW$
                            EnableQASignButton	= 0
                            IF QASignReason = '' THEN QASignReason = 'Zone 2 Metrology is Incomplete'
                        END ELSE
                            MetColorZ2 = INP_BLUE$
                        END
                    END
                END
            END
            
            FOR Col = COL$MET_NO_Z2 TO COL$RRHO_AVG_Z2
                stat = Send_Message(CtrlID,'COLOR_BY_POS',Col,I,MetColorZ2)
            NEXT Col
            
        NEXT I
        
        LoadLockVal = Get_Property(@WINDOW:'.LOAD_LOCK_SIDE_HIDDEN','TEXT')
        IF LoadLockVal = '' THEN
            CurrSaveWarn = Get_Property(@WINDOW,'SAVEWARN')
            Set_Property(@WINDOW:'.LOAD_LOCK_SIDE','DEFPROP','')
            IF NOT(CurrSaveWarn) THEN
                Set_Property(@WINDOW,'SAVEWARN',0)
            END
        END
        
        Reactor = Get_Property(@WINDOW:'.REACTOR','DEFPROP')				;* Changed to PickPlaceFlag on 12/6/2011 JCH
        
        PickPlaceFlag = XLATE('REACTOR',Reactor,REACTOR_PICK_PLACE$,'X')
 
        WafersIn = Get_Property(@WINDOW:'.WAFERS_IN','DEFPROP')
        IF WafersIn = '' THEN
            Set_Property(@WINDOW:'.BUTTON_11','ENABLED',0)			;* Load button disabled 
        END ELSE
            IF EnableLoadButton = 1 OR MemberOf(@USER4, 'OI_ADMIN') THEN
                Set_Property(@WINDOW:'.BUTTON_11','ENABLED',1)		;* Load button Added flag on 11/14/2007 JCH
            END
        END
    END
    
    * Clean Inspection table
    
    CtrlName = ''
    
    IF @WINDOW = 'RDS_PRE_EPI' THEN CtrlName	= @WINDOW:'.PRE_CI_ACTION'
    IF @WINDOW = 'RDS' THEN CtrlName			= @WINDOW:'.FWI_CI_ACTION'
    IF @WINDOW = 'RDS_UNLOAD' THEN CtrlName		= @WINDOW:'.LWI_CI_ACTION'
    IF @WINDOW = 'RDS_POST_EPI' THEN CtrlName	= @WINDOW:'.POST_CI_ACTION'
    
    IF CtrlName NE '' THEN
        CIList		= Get_Property(CtrlName,'LIST')
        CICnt		= COUNT(CIList,@FM) + (CIList NE '')
        
        FOR Line = 1 TO CICnt
            IF CIList<Line,COL$ACTION> NE '' THEN
                BEGIN CASE
                    CASE @WINDOW = 'RDS_PRE_EPI'
                        CICtrl = @WINDOW:'.PRE_CI_NO'
                        
                    CASE @WINDOW = 'RDS'
                        CICtrl = @WINDOW:'.FWI_CI_NO'
                        
                    CASE @WINDOW = 'RDS_UNLOAD'
                        CICtrl = @WINDOW:'.LWI_CI_NO'
                        
                    CASE @WINDOW = 'RDS_POST_EPI'
                        CICtrl = @WINDOW:'.POST_CI_NO'
                        
                    CASE 1	; RETURN
                        
                END CASE
                
                CINo     = Get_Property(CICtrl,'DEFPROP')
                CIStatus = Xlate('CLEAN_INSP', CINo,CLEAN_INSP_ROTR_ACTION$, 'X')
                Begin Case
                    Case CIList<Line, COL$ACTION> EQ 'Clean'
                        SigReq = Xlate('CLEAN_INSP', CINo, CLEAN_INSP_SPEC_CLEAN_REQ$, 'X')
                    Case CIList<Line, COL$ACTION> EQ 'Inspection'
                        SigReq = Xlate('CLEAN_INSP', CINo, CLEAN_INSP_SPEC_INSP_REQ$, 'X')
                    Case CIList<Line, COL$ACTION> EQ 'SurfScan'
                        SigReq = Xlate('CLEAN_INSP', CINo, CLEAN_INSP_SPEC_SURFSCAN_REQ$, 'X')
                    Case Otherwise$
                        SigReq = False$
                End Case
                
                
                BEGIN CASE
                    
                    Case SigReq NE True$
                        Color = GREEN$
                    
                    CASE CIList<Line,COL$TOOL> = '' 
                        Color = YELLOW$
                        EnableUnloadButton	= 0											;* 1/9/2013 JCH
                        EnableQASignButton	= 0
                        IF QASignReason = '' THEN QASignReason = 'Clean Inspection Steps Required'
                        
                    CASE CIList<Line,COL$TOOL> NE '' AND CIList<Line,COL$SIG> = '' AND CIStatus NE 'P'
                        Color = RED$
                        EnableUnloadButton	= 0
                        EnableQASignButton	= 0
                        IF QASignReason = '' THEN QASignReason = 'Clean Inspection Steps not Signed'
                    CASE CIStatus NE 'P' AND CIList<Line,COL$ACTION> EQ 'SurfScan'
                        ROTRSignature = Xlate('CLEAN_INSP', CINo, CLEAN_INSP_SIGN_ROTR_SIGNATURE$, 'X')
                        IF ROTRSignature NE '' then
                            Color = ORANGE$
                        end else
                            Color = RED$
                        end 
                    CASE Otherwise$
                        Color = GREEN$
                        
                END CASE
                
            END	ELSE
                Color = GREEN$
            END;* End of check for Clean Insp complete on the current line
            
            stat = Send_Message(CtrlName,'COLOR_BY_POS',0,Line,Color)
            IF QASignReason = '' THEN
                Set_Property(@WINDOW:'.STATUS_LINE','TEXT','')
            END ELSE
                Set_Property(@WINDOW:'.STATUS_LINE','TEXT',QASignReason)
            END
        NEXT Line
    END	;* End of check for CtrlName
    
    
    IF @WINDOW = 'RDS_POST_EPI' THEN
        
        NCRList = Get_Property(@WINDOW:'.NCR_KEYS','LIST')
        
        FOR Line = 1 TO COUNT(NCRList,@FM) + (NCRList NE '')
            Status = NCRList<Line,2>
            
            IF Status NE '' AND Status NE 'Closed' THEN
                EnableQASignButton = 0
                QASignReason 	= 'Open NCR'
            END
        NEXT Line
        
        IF UseMUWafers THEN
            IF (WafersOut NE '' AND WafersScheduled NE '') THEN
                // A full box is now defined by have equal to or more wafers required. This allows certain customer's parts
                // to have a box with less that 25 wafers be allowed to ship. - 08/04/2017
                *			IF WafersOut NE FullBoxQty  AND NOT(MakeupBox) THEN
                IF WafersOut LT MinCassShipQty AND NOT(MakeupBox) THEN
                    EnableQASignButton = 0
                    QASignReason	= 'Wafer Out is not equal to Specified Full Box Quantity'
                END
            END
        END
        
        ** Added 11/1/2013 JCH... another AFUD
        
        RotrAction = Get_Property(@WINDOW:'.ROTR_ACTION','TEXT')
        
        IF RotrAction[1,1] = 'F' Then
            EnableQASignButton = 0
            QASignReason	= 'Failed ROTR test'
            
        END
        
        If MemberOf(@USER4, 'OI_ADMIN') then
            EnableQASignButton = 1
        end
        
        Set_Property(@WINDOW:'.SIGN_BUTTON','ENABLED',EnableQASignButton)
        
        IF QASignReason = '' THEN
            Set_Property(@WINDOW:'.STATUS_LINE','TEXT','')
            Set_Property(@WINDOW:'.STATUS_LINE','BACKCOLOR',LTGREY$)
            
        END ELSE
            Set_Property(@WINDOW:'.STATUS_LINE','TEXT',QASignReason)
            Set_Property(@WINDOW:'.STATUS_LINE','BACKCOLOR',YELLOW$)
        END
        
    END
    
    IF @WINDOW = 'RDS' OR @WINDOW = 'RDS_UNLOAD' THEN
        Reactor = Get_Property(@WINDOW:'.REACTOR','DEFPROP')
        ReactorType = XLATE('REACTOR',Reactor,1,'X')
        IF ReactorType = 'EPP' THEN
            Set_Property(@WINDOW:'.LOAD_EPI_PRO','VISIBLE',1)
            Set_Property(@WINDOW:'.UNLOAD_EPI_PRO','VISIBLE',1)
            Set_Property(@WINDOW:'.POCKET','VISIBLE',1)
            Set_Property(@WINDOW:'.MOVE_MET','VISIBLE',1)
            Set_Property(@WINDOW:'.ADD_ZONE','VISIBLE',1)
            Set_Property(@WINDOW:'.REM_ZONE','VISIBLE',1)
        END ELSE
            Set_Property(@WINDOW:'.LOAD_EPI_PRO','VISIBLE',0)
            Set_Property(@WINDOW:'.UNLOAD_EPI_PRO','VISIBLE',0)
            Set_Property(@WINDOW:'.POCKET','VISIBLE',0)
            Set_Property(@WINDOW:'.MOVE_MET','VISIBLE',0)
            Set_Property(@WINDOW:'.ADD_ZONE','VISIBLE',0)
            Set_Property(@WINDOW:'.REM_ZONE','VISIBLE',0)
        END
    END
    
    * * * * * Hide Signature Profile Button if Non-EpiPro * * * * *
    RDSNo       = Get_Property(@Window:'.RDS_NO', 'TEXT')
    ReactorType = Xlate('RDS', RDSNo, 'REACTOR_TYPE', 'X')
    
*    If ( (ReactorType EQ 'EPP') or (ReactorType EQ 'P') ) then
*        Set_Property(@Window:'.SIG_PROFILE', 'VISIBLE', False$)
*    end else
*        Set_Property(@Window:'.SIG_PROFILE', 'VISIBLE', True$)
*    end
    
    QBFList = Get_Property(@Window, "QBFLIST")

    NumRDS = DCount(QBFList, @FM)
    QBFEnabled = (NumRDS GT 1)
    Set_Property(@Window:'.PHX_QBF_FIRST', 'VISIBLE', QBFEnabled)
    Set_Property(@Window:'.PHX_QBF_PREV', 'VISIBLE', QBFEnabled)
    Set_Property(@Window:'.PHX_QBF_NEXT', 'VISIBLE', QBFEnabled)
    Set_Property(@Window:'.PHX_QBF_LAST', 'VISIBLE', QBFEnabled)
    
    
    RDSNo = Get_Property(@WINDOW:'.RDS_NO','TEXT')
    RecordLocked = Database_Services('IsKeyIDLocked', 'RDS', RDSNo)
    SelfLocked   = Database_Services('IsKeyIDSelfLocked', 'RDS', RDSNo)
    Open 'RDS' to hRDS then
        If SelfLocked then
            Set_Property(@Window:'.LOAD_EPI_PRO', 'ENABLED', True$)
            Set_Property(@Window:'.UNLOAD_EPI_PRO', 'ENABLED', True$)
            Set_Property(@Window:'.CLEAR_EPI_UNLOAD', 'ENABLED', True$)
            Set_Property(@Window:'.PUB_SIGN', 'ENABLED', True$)
        end
        If RecordLocked and Not(SelfLocked) then
            Set_Property(@Window:'.LOAD_EPI_PRO', 'ENABLED', False$)
            Set_Property(@Window:'.UNLOAD_EPI_PRO', 'ENABLED', False$)
            Set_Property(@Window:'.CLEAR_EPI_UNLOAD', 'ENABLED', False$)
            Set_Property(@Window:'.PUB_SIGN', 'ENABLED', False$)
        end
    end    

    
RETURN


* * * * * * *
GotFocus:
* * * * * * *
    
    
RETURN


* * * * * * *
MUWafers:
* * * * * * *
    
    RDSNo = Get_Property(@WINDOW,'ID')
    IF RDSNo = '' THEN RETURN
    
    IF Get_Property(@WINDOW,'SAVEWARN') THEN
        Send_Event(@WINDOW,'WRITE')
    END
    
    obj_AppWindow('ViewRelated','RDS_MAKEUP':@RM:RDSNo)
    
RETURN


* * * * * * * 
ProdWfrLF:
* * * * * * *
RETURN


* * * * * * *
Update:
* * * * * * *
    
    RDSNo = Get_Property(@WINDOW:'.RDS_NO','TEXT')
    
    IF RDSNo NE '' THEN
        Send_Event(@WINDOW,'WRITE')
        Set_Property(@WINDOW:'.RDS_NO','TEXT',RDSNo)
        Send_Event(@WINDOW,'READ')
    END
    
RETURN


* * * * * * *
WafersInLF:
* * * * * * *
    
    WafersIn	= Get_Property(@WINDOW:'.WAFERS_IN','TEXT')
    RDSNo		= Get_Property(@WINDOW,'ID')
    
    IF WafersIn = '' THEN RETURN
    
    ScheduledWafers = XLATE('RDS',RDSNo,'WAFERS_SCHEDULED','X')

    If Not(Num(WafersIn)) then
        // Log the WafersIn value
        LogData    = ''
        LogData<1> = LoggingDTM
        LogData<2> = RDSNo
        LogData<3> = WafersIn
        Logging_Services('AppendLog', objWafersLog, LogData, @RM, @FM)
        WafersIn   = WafersIn<1, 1, 1>
    end
    
    IF WafersIn NE ScheduledWafers THEN
        UserInput = Msg(@window, '','WAFERS_IN_VERIFY')
        OrigWafersIn = Xlate('RDS', RDSNo, 'WAFERS_IN', 'X')
        
        If Not(Num(OrigWafersIn)) then
            // Log the WafersIn value
            LogData      = ''
            LogData<1>   = LoggingDTM
            LogData<2>   = RDSNo
            LogData<3>   = OrigWafersIn
            Logging_Services('AppendLog', objWafersLog, LogData, @RM, @FM)
            OrigWafersIn = OrigWafersIn<1, 1, 1>
        end
        
        Set_Property(@WINDOW:'.WAFERS_IN','TEXT',OrigWafersIn)
        Set_Property(@WINDOW:'.WAFERS_IN','FOCUS',1)
    END
    
    GOSUB Refresh
    
RETURN


* * * * * * *
FirstRead:
* * * * * * *
    * Hooked from RDS (first wafer) screen
    
	RDSNo     = Get_Property(@Window:'.RDS_NO', 'TEXT')
	WOMatKey  = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X', '')
	HoldCheck = Hold_Services('CheckForHold', WOMatKey, '')
	IF HoldCheck THEN
    	Set_Property(@WINDOW:'.HOLD_BUTTON2','TEXT','Remove Hold')
   END ELSE
        Set_Property(@WINDOW:'.HOLD_BUTTON2','TEXT','Place on Hold')
   END
    
* * * * * * *
FirstRefresh:
* * * * * * *

    RDSNo = Get_Property(@WINDOW:'.RDS_NO','TEXT')
    
    OverGrowRequired = Get_Property(@WINDOW:'.OVERGROW_REQ','CHECK')
    
    IF OverGrowRequired THEN
        Set_Property(@WINDOW:'.THICK_OVR_GROWTH_AVG','VISIBLE',1)
        Set_Property(@WINDOW:'.THICK_OVER_LABEL','VISIBLE',1)
    END ELSE
        Set_Property(@WINDOW:'.THICK_OVR_GROWTH_AVG','VISIBLE',0)
        Set_Property(@WINDOW:'.THICK_OVER_LABEL','VISIBLE',0)
    END
    
    GOSUB Refresh
    
RETURN


* * * * * * *
NewNCR:
* * * * * * *
    
    RDSNo = Get_Property(@WINDOW:'.RDS_NO','TEXT')
    Reactor = Get_Property(@WINDOW:'.REACTOR','TEXT')
    
    WOStepKey = XLATE('RDS',RDSNo,RDS_WO_STEP_KEY$,'X')
    
    WONo = WOStepKey[1,'*']
    WOStep = WOStepKey[COL2()+1,'*']
    
    CassNo = XLATE('RDS',RDSNo,'RUN_ORDER_NUM','X')
    
    
    IF 1 = 1 THEN	;* This was a test for non-test users
        
        ************* This is the production code ********************
        
        NewNCRNo = obj_NCR('Create',WONo:@RM:WOStep:@RM:CassNo:@RM:RDSNo:@RM:Reactor)
        errCode  = ''
        IF Get_Status(errCode) THEN
            ErrMsg(errCode)
            RETURN
        END
        
        CtrlEntID = @WINDOW:'.NCR_KEYS'
        
        NCRNos = Get_Property(CtrlEntID,'ARRAY')<1>
        
        SWAP @VM:@VM WITH '' IN NCRNos
        IF NCRNos[-1,1] = @VM THEN NCRNos[-1,1] = ''
        
        LastNCRNo = COUNT(NCRNos,@VM) + (NCRNos NE '')
        
        Send_Event(@WINDOW,'WRITE')
        
        DetWindow	= 'NCR'
        DetKeys		= NewNCRNo
        DefaultRec	= ''
        RetKey		= RDSNo
        RetWin		= @WINDOW
        RetPage		= 1
        RetCtrl		= CtrlEntID
        RetPos		= 1:@FM:LastNCRNo + 1
        
        obj_Appwindow('ViewNewDetail',DetWindow:@RM:DetKeys:@RM:DefaultRec:@RM:RetKey:@RM:RetPage:@RM:RetCtrl:@RM:RetPos)
        
    END ELSE
        
        ************* This is the test code ********************
        
        CtrlEntID = @WINDOW:'.NCR_KEYS'
        
        NCRNos = Get_Property(CtrlEntID,'ARRAY')<1>
        
        SWAP @VM:@VM WITH '' IN NCRNos
        IF NCRNos[-1,1] = @VM THEN NCRNos[-1,1] = ''
        
        LastNCRNo = COUNT(NCRNos,@VM) + (NCRNos NE '')
        
        Send_Event(@WINDOW,'WRITE')
        
        CreateParms  = WONo:@FM
        CreateParms := CassNo:@FM
        CreateParms := RDSNo:@FM
        CreateParms := Reactor:@FM
        CreateParms := WOStep:@FM
        CreateParms := '1':@FM					;* Return Page
        CreateParms := '.NCR_KEYS':@FM			;* Return Ctrl
        CreateParms := '1,1'
        
        
        thisFormWindowUp = Get_Property('WO_MAT_WFR','VISIBLE')	;* Returns 0 = hidden, 1 = visible, 2 = minimized, 3 = maximized 
        
        IF thisFormWindowUp = ''	THEN
            Start_Window('WO_MAT_WFR',@WINDOW,CreateParms)
        END ELSE
            
            IF thisFormWindowUp = 2		THEN Set_Property('WO_MAT_WFR','VISIBLE',9)	;* Restore the window if minimized
            
            IF Get_Property('WO_MAT_WFR','SAVEWARN') THEN
                Set_Property('WO_MAT_WFR','@SKIP_CARD_RETURN',1)	;* This stops the Return behavior
                Send_Event('WO_MAT_WFR','CLEAR')					;* Clear anything existing (prompts for save first)
            END
            
            * Load Key Controls with Key Parts
            
            Ctrls  = 'WO_MAT_WFR':@RM				; Props  = '@RETURN_KEY':@RM		; Vals  = RDSNo:@RM
            Ctrls := 'WO_MAT_WFR':@RM				; Props := '@RETURN_PAGE':@RM		; Vals := '':@RM
            Ctrls := 'WO_MAT_WFR':@RM				; Props := '@RETURN_CONTROL':@RM	; Vals := 'RDS_UNLOAD.NCR_KEYS':@RM
            Ctrls := 'WO_MAT_WFR':@RM				; Props := '@RETURN_POS':@RM		; Vals := 1:@FM:1:@RM
            
            Ctrls := 'WO_MAT_WFR.WO_NO':@RM			; Props := 'DEFPROP':@RM			; Vals := WONo:@RM
            Ctrls := 'WO_MAT_WFR.CASS_NO':@RM		; Props := 'DEFPROP':@RM			; Vals := CassNo:@RM
            Ctrls := 'WO_MAT_WFR.RDS_NO':@RM		; Props := 'DEFPROP':@RM			; Vals := RDSNo:@RM
            Ctrls := 'WO_MAT_WFR.REACTOR':@RM		; Props := 'DEFPROP':@RM			; Vals := Reactor:@RM
            Ctrls := 'WO_MAT_WFR.WO_STEP_NO'		; Props := 'DEFPROP'				; Vals := WOStep
            
            Set_Property(Ctrls,Props,Vals)
            
            Send_Event('WO_MAT_WFR.CASS_NO','LOSTFOCUS')
            
        END
        
    END	;* End of section with new test code 
    
RETURN


* * * * * * *
NCRKeysDC:
* * * * * * *
    
    RDSNo = Get_Property(@WINDOW:'.RDS_NO','TEXT')
    CtrlEntID = @WINDOW:'.NCR_KEYS'
    
    CurrPos = Get_Property(CtrlEntID,'SELPOS')
    CurrCol = CurrPos<1>
    CurrRow = CurrPos<2>
    
    NCRKey = Get_Property(CtrlEntID,'CELLPOS',1:@FM:CurrRow)
    
    IF NCRKey = '' THEN RETURN
    
    Send_Event(@WINDOW,'WRITE')
    
    DetWindow	= 'NCR'
    DetKeys		= NCRKey
    DefaultRec	= ''
    RetKey		= RDSNo
    RetWin		= @WINDOW
    RetPage		= 1
    RetCtrl		= CtrlEntID
    RetPos		= CurrPos
    
    obj_Appwindow('ViewNewDetail',DetWindow:@RM:DetKeys:@RM:DefaultRec:@RM:RetKey:@RM:RetPage:@RM:RetCtrl:@RM:RetPos)
    
RETURN


* * * * * * *
PrintLabels:
* * * * * * *
    
    RDSNo = Get_Property(@WINDOW,'ID')
    
    IF RDSNo = '' THEN RETURN
    
    IF Security_Check( 'RDS', Print$ ) ELSE
        Security_Err_Msg( 'RDS', Print$ )
        RETURN
    END
    
    Send_Event(@WINDOW,'WRITE')
    
    WOStepKey	= XLATE('RDS',RDSNo,RDS_WO_STEP_KEY$,'X')
    WONo		= WOStepKey[1,'*']
    WOStep		= WOStepKey[-1,'*']
    WOSteps		= XLATE('WO_LOG',WONo,WO_LOG_WO_STEP_KEY$,'X')
    
    IF INDEX(WOSteps,@VM,1) THEN
        MultiStepFlag = 1
    END ELSE
        MultiStepFlag = 0
    END
    
    IF WOStep > 1 THEN
        RDSNos = obj_WO_Step('AdjStepRDSQtys', WOStep:@RM:WOSteps)		;* Returns RDSNos for nth step that have completed step n-1
        IF Get_Status(errCode) THEN ErrMsg(errCode)
        IF RDSNos = '' THEN
            ErrMsg('No cassettes have completed Step ':WOStep - 1)
            GOTO SkipIt
        END
    END ELSE
        RetVal = Msg(@WINDOW,'','SELECT_CASS_LABEL')
        IF RetVal = 1 THEN
            RDSNos = RDSNo
        END ELSE
            RDSNos = XLATE('WO_STEP',WOSteps<1,1>,WO_STEP_RDS_KEY$,'X')
        END
    END
    
    IF Get_Status(errCode) THEN
        ErrMsg(errCode)
        RETURN
    END
    
    IF INDEX(RDSNos,@VM,1) THEN
        TypeOver = ''
        TypeOver<PDISPLAY$> = RDSNos
        TypeOver<PFIELD$>	= 2
        TypeOver<PTYPE$>	= 'K'
        
        RDSKeys = Popup(@WINDOW,TypeOver,'WO_LOG_RTS')
        
    END ELSE
        RDSKeys = RDSNos
    END
    
    IF RDSKeys = '' THEN RETURN
    
    CONVERT @VM TO @FM IN RDSKeys
    
    Def = ""
    Def<MTEXT$> = "Printing Cassette Labels..."
    Def<MTYPE$> = "U"
    
    MsgUp = Msg(@window, Def)
    
    Print_Cass_Labels(RDSKeys,MultiStepFlag)				;* Updated labels with Akrion Bar Codes
    
    Msg(@window, MsgUp)
    
    
    * * * *
SkipIt:
* * * *
    
    Set_Property(@WINDOW:'.RDS_NO','TEXT',RDSNo)
    Send_Event(@WINDOW,'READ')
    
RETURN


* * * * * * *
ViewAudit:
* * * * * * *
    
    RDSNo = Get_Property(@WINDOW:'.RDS_NO','DEFPROP')
    
    IF RDSNo = '' THEN RETURN
    
    AuditData	= obj_RDS_Audit('Display',RDSNo:@RM:'')	;* Returns all audit columns 
    
    DispText 	= AuditData[1,@RM]
    UserNames	= AuditData[COL2()+1,@RM]
    LastDTMS	= AuditData[COL2()+1,@RM]
    Windows		= AuditData[COL2()+1,@RM]
    
    PopupDisplay = ''
    
    FOR I = 1 TO COUNT(DispText,@FM) + (DispText NE '')
        PopupDisplay<1,I> = DispText<I>:@TM:OCONV(UserNames<I>,'[XLATE_CONV,LSL_USERS*FIRST_LAST]' ):@TM:LastDTMs<I>:@TM:Windows<I>
    NEXT I
    
    OverRide = ''
    OverRide<PDISPLAY$> = PopupDisplay
    
    PopUp(@WINDOW, OverRide, 'RDS_MOD_HIST_VIEW' )
    
RETURN


* * * * * * *
LSIdDC:
* * * * * * *
    
    CtrlEntID	= @WINDOW:'.RDS_LS_ID'
    RDSNo		= Get_Property(@WINDOW,'ID')
    ReactNo		= Get_Property(@WINDOW:'.REACTOR','DEFPROP')
    
    IF Get_Property(@WINDOW,'SAVEWARN') THEN
        Set_Property(@WINDOW,'@SKIP_SAVEWARN',0)
    END ELSE
        Set_Property(@WINDOW,'@SKIP_SAVEWARN',1)
    END
    
    CurrPos = Get_Property(CtrlEntID,'SELPOS')
    CurrCol = CurrPos<1>
    CurrRow = CurrPos<2>
    
    
    IF CurrCol LT COL$MET_NO THEN
        LSId = Get_Property(CtrlEntID,'CELLPOS',COL$LSID:@FM:CurrRow)
        
        IF RDSNo NE '' AND LSId NE '' THEN
            
            // Do not clear on WRITE
            PrevIOOptions = Get_Property(@Window, 'IOOPTIONS')
            IOOptions = PrevIOOptions
            IOOptions<6> = True$
            Set_Property(@Window, 'IOOPTIONS', IOOptions)
            Send_Event(@Window, 'WRITE')
            Set_Property(@Window, 'IOOPTIONS', PrevIOOptions)
            
            RdsLSID = RDSNo:'*':LSId
            Dialog_Box('RDS_LAYER', @Window, RdsLSID)

        END
    END
    
    IF CurrCol = COL$MET_NO OR CurrCol = COL$MET_NO_Z1 OR CurrCol = COL$MET_NO_Z2 THEN
        MetNo = Get_Property(CtrlEntID,'CELLPOS',CurrCol:@FM:CurrRow)
        
        IF MetNo NE '' THEN
            
            Send_Event(@WINDOW,'WRITE')
            Send_Event(@WINDOW,'CLEAR') ; // 12/21/2017 - DMB - Although WRITE normally clears the form, QBF mode will prevent the clear so do this explicitly so the lock is removed from the RDS record.
            
            DetWindow	= 'RDS_TEST'
            DetKeys		= MetNo
            DefaultRec	= ''
            RetKey		= RDSNo
            RetWin		= 'RDS'
            RetPage		= 1
            RetCtrl		= CtrlEntID
            RetPos		= CurrPos
            
            obj_Appwindow('ViewNewDetail',DetWindow:@RM:DetKeys:@RM:DefaultRec:@RM:RetKey:@RM:RetPage:@RM:RetCtrl:@RM:RetPos)
            
        END
    END
    
    
RETURN


* * * * * * *
LoadEpiPro:
* * * * * * * 
    
    RDSNo		= Get_Property(@WINDOW:'.RDS_NO','DEFPROP')
    CurrentLoad = Get_Property(@WINDOW:'.POCKET','DEFPROP')
    
    IF RDSNo = '' THEN RETURN
    
    OutCassettes = CurrentLoad<COL$OUT_CASS>
    
    CONVERT @VM TO '' IN OutCassettes
    
    IF OutCassettes NE '' THEN
        ErrMsg('Wafers have already been unloaded from the reactor.')
        RETURN
    END
    
    
    Reactor = Get_Property(@WINDOW:'.REACTOR','TEXT')
    ReactorType = XLATE('REACTOR',Reactor,1,'X')
    
    IF ReactorType NE 'EPP' THEN
        ErrMsg('Reactor ':Reactor:' is not an EpiPro tool.')
        RETURN
    END
    
    Send_Event(@WINDOW,'WRITE')
    
    
    MatlLoadInfo = Create_Dialog('DIALOG_LOAD_EPI_PRO', @WINDOW, 0, RDSNo:@FM:CurrentLoad)
    
    
RETURN


* * * * * * *
UnloadEpiPro:
* * * * * * * 
    
    RDSNo		= Get_Property(@WINDOW:'.RDS_NO','DEFPROP')
    CurrentLoad = Get_Property(@WINDOW:'.POCKET','DEFPROP')
    
    IF RDSNo = '' THEN RETURN
    
    Reactor = Get_Property(@WINDOW:'.REACTOR','TEXT')
    
    ReactorType = XLATE('REACTOR',Reactor,1,'X')
    
    IF ReactorType NE 'EPP' THEN
        ErrMsg('Reactor ':Reactor:' is not an EpiPro tool.')
        RETURN
    END
    
    ProdLoadCnt = 0
    ProdUnloadCnt = 0
    
    FOR I = 1 TO COUNT(CurrentLoad<1>,@VM) + (CurrentLoad<1> NE '')
        
        Usage	= CurrentLoad<COL$USE,I>
        WfrType	= CurrentLoad<COL$CHAR,I>
        OutCass	= CurrentLoad<COL$OUT_CASS,I>
        
        IF WfrType = 'PROD' AND Usage = '' AND OutCass = '' THEN
            ProdLoadCnt += 1											;* Product wafers to be unloaded
        END
        
        IF OutCass NE '' THEN
            ProdUnloadCnt += 1
        END
        
    NEXT I
    
    IF ProdLoadCnt = 0 AND ProdUnloadCnt = 0 THEN
        ErrMsg('No production wafers loaded in reactor.')		;* Not yet loaded
        RETURN
    END
    
    Send_Event(@WINDOW,'WRITE')
    
    MatlUnloadInfo = Create_Dialog('DIALOG_UNLOAD_EPI_PRO', @WINDOW, 0, RDSNo:@FM:CurrentLoad)
    
RETURN


* * * * * * * *
ClearEpiUnload:
* * * * * * * *
    
    RDSNo		= Get_Property(@WINDOW:'.RDS_NO','DEFPROP')
    CurrentLoad = Get_Property(@WINDOW:'.POCKET','DEFPROP')
    
    IF RDSNo = '' THEN RETURN
    
    Reactor = Get_Property(@WINDOW:'.REACTOR','TEXT')
    
    ReactorType = XLATE('REACTOR',Reactor,1,'X')
    
    IF ReactorType NE 'EPP' THEN
        ErrMsg('Reactor ':Reactor:' is not an EpiPro tool.')
        RETURN
    END
    
    ProdLoadCnt = 0
    ProdUnloadCnt = 0
    
    FOR I = 1 TO COUNT(CurrentLoad<1>,@VM) + (CurrentLoad<1> NE '')
        
        Usage	= CurrentLoad<COL$USE,I>
        WfrType	= CurrentLoad<COL$CHAR,I>
        OutCass	= CurrentLoad<COL$OUT_CASS,I>
        
        IF WfrType = 'PROD' AND Usage = '' AND OutCass = '' THEN
            ProdLoadCnt += 1											;* Product wafers to be unloaded
        END
        
        IF OutCass NE '' THEN
            ProdUnloadCnt += 1
        END
        
    NEXT I
    
    IF ProdLoadCnt = 0 AND ProdUnloadCnt = 0 THEN
        ErrMsg('No production wafers loaded in reactor.')		;* Not yet loaded
        RETURN
    END
    
    Send_Event(@WINDOW,'WRITE')
    
    
    Set_Status(0)
    obj_RDS('ClearEpiUnload',RDSNo) ; // Note: This routine does not exist in OBJ_RDS
    
    IF Get_Status(errCode) THEN
        ErrMsg(errCode)
    END
    
    Set_Property(@WINDOW:'.RDS_NO','DEFPROP',RDSNo)
    Send_Event(@WINDOW,'READ')
    
RETURN



* * * * * * *
AddZoneMet:
* * * * * * *
    
    CtrlEntID = @WINDOW:'.RDS_LS_ID'
    
    RDSNo	= Get_Property(@WINDOW,'ID')
    PSNo	= Get_Property(@WINDOW:'.PSN','DEFPROP')
    LSArray = Get_Property(CtrlEntID,'DEFPROP')
    
    LSIDs		= LSArray<COL$LSID>
    MetNos		= LSArray<COL$MET_NO>
    MetNosZ1	= LSArray<COL$MET_NO_Z1>
    MetNosZ2	= LSArray<COL$MET_NO_Z2>
    
    MetTest	= MetNos
    Z1Test	= MetNosZ1
    Z2Test	= MetNosZ2
    
    CONVERT @VM TO '' IN MetTest
    CONVERT @VM TO '' IN Z1Test
    CONVERT @VM TO '' IN Z2Test
    
    IF MetTest = '' THEN
        BEGIN CASE
            CASE Z1Test = '' AND Z2Test = ''
                * Ask for z1 or z2
                TypeOver = ''
                TypeOver<MTYPE$>	= 'B&1,&2,&Cancel'
                TypeOver<MCAPTION$>	= 'Add Reactor Zone Metrology'
                TypeOver<MICON$>	= '?'
                TypeOver<MDEFBTN$>	= '3'
                TypeOver<MTEXT$>	= 'Add Metrology for Zone:'
                
                NewZone = Msg(@WINDOW,TypeOver,'')
                
                IF NewZone = 3 THEN RETURN
                
                
            CASE Z1Test = '' AND Z2Test NE ''
                NewZone = 1
                
            CASE Z1Test NE '' AND Z2Test = ''
                NewZone = 2
                
            CASE 1
                ErrMsg('No open Zone to move to.')
                RETURN
                
        END CASE
        
        Send_Event(@WINDOW,'WRITE')
        
        FOR I = 1 TO COUNT(LSIDs,@VM) + (LSIDs NE '')
            IF LSIDs<1,I> NE '' THEN
                LSID = LSIDs<1,I>
                
                oRTParms  = RDSNo:@RM
                oRTParms := LSID:@RM
                oRTParms := PSNo:@RM
                oRTParms := NewZone
                
                obj_RDS_Test('Create',oRTPARms)
            END
        NEXT I
        
        Set_Property(@WINDOW:'.RDS_NO','DEFPROP',RDSNo)
        Send_Event(@WINDOW,'READ')
        
    END 
    
RETURN


* * * * * * *
RemoveZoneMet:
* * * * * * *
    
    CtrlEntID = @WINDOW:'.RDS_LS_ID'
    
    RDSNo	= Get_Property(@WINDOW,'ID')
    PSNo	= Get_Property(@WINDOW:'.PSN','DEFPROP')
    LSArray = Get_Property(CtrlEntID,'DEFPROP')
    
    LSIDs		= LSArray<COL$LSID>
    MetNos		= LSArray<COL$MET_NO>
    MetNosZ1	= LSArray<COL$MET_NO_Z1>
    MetNosZ2	= LSArray<COL$MET_NO_Z2>
    
    MetTest	= MetNos
    Z1Test	= MetNosZ1
    Z2Test	= MetNosZ2
    
    CONVERT @VM TO '' IN MetTest
    CONVERT @VM TO '' IN Z1Test
    CONVERT @VM TO '' IN Z2Test
    
    IF MetTest NE '' or Z1Test NE '' or Z2Test NE '' THEN
        BEGIN CASE
            CASE Z1Test NE '' AND Z2Test NE ''
                * Ask for z1 or z2
                TypeOver            = ''
                TypeOver<MTYPE$>	= 'B&1,&2,&Cancel'
                TypeOver<MCAPTION$>	= 'Which zone metrology would you like to remove?'
                TypeOver<MICON$>	= '?'
                TypeOver<MDEFBTN$>	= '3'
                TypeOver<MTEXT$>	= 'Remove Metrology for Zone:'
                
                DeleteZone = Msg(@WINDOW,TypeOver,'')
                
                IF DeleteZone = 3 THEN RETURN

            CASE Otherwise$
                ErrMsg('At least one zone must have metrology.')
                RETURN
                
        END CASE
        
        Send_Event(@WINDOW,'WRITE')
        
        NumMet = DCount(MetNos, @VM)
        
        FOR I = 1 TO NumMet
            
            Begin Case               
                Case DeleteZone EQ 1
                    // Operator wants to delete metrology from zone 1.
                    IF MetNosZ1<1,I> NE '' THEN
                        MetNo = MetNosZ1<1,I>
                        
                        oRTParms  = MetNo:@RM
                        
                        obj_RDS_Test('Delete',oRTParms)
                    END
                Case DeleteZone EQ 2
                    
                    // Operator wants to delete metrology from zone 2.
                    IF MetNosZ2<1,I> NE '' THEN
                        MetNo = MetNosZ2<1,I>
                        
                        oRTParms  = MetNo:@RM
                        
                        obj_RDS_Test('Delete',oRTParms)
                    END

                Case Otherwise$
                    Null
                    
            End Case

        NEXT I
        
        Set_Property(@WINDOW:'.RDS_NO','DEFPROP',RDSNo)
        Send_Event(@WINDOW,'READ')
        
    END 

return


* * * * * * *
MoveMetToZone:
* * * * * * *
    
    CtrlEntID = @WINDOW:'.RDS_LS_ID'
    RDSNo = Get_Property(@WINDOW,'ID')
    
    LSArray = Get_Property(CtrlEntID,'DEFPROP')
    
    MetNos		= LSArray<COL$MET_NO>
    MetNosZ1	= LSArray<COL$MET_NO_Z1>
    MetNosZ2	= LSArray<COL$MET_NO_Z2>
    
    MetTest	= MetNos
    Z1Test	= MetNosZ1
    Z2Test	= MetNosZ2
    
    CONVERT @VM TO '' IN MetTest
    CONVERT @VM TO '' IN Z1Test
    CONVERT @VM TO '' IN Z2Test
    
    IF MetTest NE '' or Z1Test NE '' or Z2Test NE '' THEN
        BEGIN CASE
            CASE Z1Test = '' AND Z2Test = ''
                * Ask for z1 or z2
                TypeOver            = ''
                TypeOver<MTYPE$>	= 'B&1,&2,&Cancel'
                TypeOver<MCAPTION$>	= 'Move Metrology to Reactor Zone'
                TypeOver<MICON$>	= '?'
                TypeOver<MDEFBTN$>	= '3'
                TypeOver<MTEXT$>	= 'Move Metrology to Zone:'
                
                DestZone = Msg(@WINDOW,TypeOver,'')
                
                IF DestZone = 3 THEN RETURN
                
                
            CASE Z1Test = '' AND Z2Test NE ''
                DestZone = 1
                
            CASE Z1Test NE '' AND Z2Test = ''
                DestZone = 2
                
            CASE 1
                ErrMsg('No open Zone to move to.')
                RETURN
                
        END CASE
        
        Send_Event(@WINDOW,'WRITE')
        NumMet = DCount(MetNos, @VM)
        
        FOR I = 1 TO NumMet
            Begin Case
                Case Z1Test EQ '' and Z2Test EQ ''
                    // Metrology has not yet been assigned to a zone.
                    IF MetNos<1,I> NE '' THEN
                        MetNo = MetNos<1,I>
                        
                        oRTParms  = MetNo:@RM
                        oRTParms := DestZone
                        
                        obj_RDS_Test('SetZone',oRTPARms)
                    END
                Case Z1Test EQ '' and Z2Test NE ''
                    // Operator wants to move metrology from zone 2 to zone 1.
                    IF MetNosZ2<1,I> NE '' THEN
                        MetNo = MetNosZ2<1,I>
                        
                        oRTParms  = MetNo:@RM
                        oRTParms := DestZone
                        
                        obj_RDS_Test('SetZone',oRTPARms)
                    END
                Case Z1Test NE '' and Z2Test EQ ''
                    // Operator wants to move metrology from zone 1 to zone 2.
                    IF MetNosZ1<1,I> NE '' THEN
                        MetNo = MetNosZ1<1,I>
                        
                        oRTParms  = MetNo:@RM
                        oRTParms := DestZone
                        
                        obj_RDS_Test('SetZone',oRTPARms)
                    END
                
                Case Otherwise$
                    // Swap zones?
                    Null
                    
            End Case

        NEXT I
        
        Set_Property(@WINDOW:'.RDS_NO','DEFPROP',RDSNo)
        Send_Event(@WINDOW,'READ')
        
    END 
    
    
RETURN


* * * * * * *
HoldClick:
* * * * * * *
    
    RDSNo		= Get_Property(@WINDOW:'.RDS_NO','DEFPROP')
    CtrlEnt		= Get_Property(@WINDOW,'FOCUS')
    PSN         = Get_Property(@WINDOW:'.PSN','TEXT')
    ReactorType = Get_Property(@WINDOW:'.REACTOR_TYPE','TEXT')
    
    If ReactorType = 'EPP' then
        Reactor = 'EPP'
    end else
        Reactor = Get_Property(@WINDOW:'.REACTOR','TEXT')
    end
    
    Send_Event(@WINDOW,'WRITE')
    Send_Event(@WINDOW,'CLEAR') ; // 12/21/2017 - DMB - Although WRITE normally clears the form, QBF mode will prevent the clear so do this explicitly so the lock is removed from the RDS record.
    IF RDSNo NE '' then
		HoldEntity		= 'RDS'
		HoldEntityID	= RDSNo
		WOMatKey = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X', '')
		//obj_WO_Mat('ToggleHold',WOMatKey:@RM:HoldEntity:@RM:HoldEntityID:@RM:CtrlEnt)
		Transition = Hold_Services('CheckForHold', WOMatKey, CtrlEnt)
		Stage = Xlate('WO_MAT', WOMatKey, WO_MAT_HOLD_STAGE$, 'X')
		Interrupted = Xlate('WO_MAT', WOMatKey, WO_MAT_HOLD_INTERRUPTED$, 'X')
		HoldType   = 'HOLD'
		HoldData   = ''
		HoldData   = Dialog_Box('DIALOG_HOLD',@WINDOW,Transition:@FM:@FM:HoldType:@FM:Stage:@FM:Interrupted)
		
		If HoldData NE 'Cancel' then
			Hold_Services('ToggleHold', WOMatKey, HoldEntity, HoldEntityID, CtrlEnt, '', HoldData, '')
			IF Error_Services("HasError") THEN
				ErrCode = Error_Services("GetMessage")
				ErrMsg(errCode)
			end else
			    If Transition EQ False$ then
                    MsgInfo = ''
                    MsgInfo<MTYPE$> = 'BNY'
                    MsgInfo<MTEXT$> = 'Hold Successful. Would you like to print label(s)?'
                    MsgInfo<MICON$> = '!'
                    PrintLabel = Msg(@WINDOW,MsgInfo,'')
                    HoldBy = HoldData<1>
                    Reason = HoldData<2>
                    Stage = HoldData<4>
                    Interrupted = HoldData<5>
                    DTM = Datetime()
                    If PrintLabel EQ True$ then 
                        Labeling_Services('PrintHoldLabel', HoldEntity, HoldEntityID, Stage, Reason, HoldBy, DTM, PSN, Reactor, Interrupted)
                    end
                end
			end
		end
	end
    
    obj_AppWindow('LoadFormKeys',@WINDOW:@RM:RDSNo)
    
RETURN


* * * * * * *
HoldDC:
* * * * * * *
    
    CtrlEntID = @WINDOW:'.HOLD_HISTORY'
    RecordID = Get_Property(@WINDOW:'.RDS_NO','DEFPROP')
    
    WOMatKey	= Get_Property(@WINDOW:'.WO_MAT_KEY','DEFPROP')
    
    HoldHistory = Get_Property(CtrlEntID,'LIST')
    
    CurrPos = Get_Property(CtrlEntID,'SELPOS')
    CurrCol = CurrPos<1>
    CurrRow = CurrPos<2>
    
    HistoryCols	= Get_Property(CtrlEntID, "COLUMN")
    ColName		= HistoryCols<1,1,CurrCol>
    
    WOMatRec = Database_Services("ReadDataRow", "WO_MAT", WOMatKey, "", "", FALSE$)

	IF INDEX(ColName,'START',1)  THEN
		HoldStartReason = WOMatRec<WO_MAT_HOLD_START_REASON$,CurrRow>
		UpdatedText     = Dialog_Box('DIALOG_TEXT',@WINDOW,'Hold Start Reason':@FM:HoldStartReason)
	END ELSE
		IF INDEX(ColName,'STOP',1)  THEN
			HoldStopReason = WOMatRec<WO_MAT_HOLD_STOP_REASON$,CurrRow>
			UpdatedText    = Dialog_Box('DIALOG_TEXT',@WINDOW,'Hold Stop Reason':@FM:HoldStopReason)
		END
	END
    
    If UpdatedText NE 'Cancel' then 
		Hold_Services("EditHoldReason",WOMatKey, ColName, CurrRow, UpdatedText)
	End
    IF Error_Services("NoError") NE TRUE$ THEN
    	ErrMsg(Error_Services("GetMessage"))
    end
    Send_Event(CtrlEntID,'CALCULATE',CurrCol)
    
RETURN



* * * * * * * 
CtrlPlanClick:
* * * * * * *

    PSNo = Get_Property(@WINDOW:'.PSN','DEFPROP')
    WONo = Get_Property(@WINDOW:'.WO','DEFPROP')
    
    IF PSNo NE '' THEN	
        Print_Control_Plan(PSNo,WONo)
    END
    
RETURN


* * * * * * *
Override:
* * * * * * *
    
    UserRec = XLATE('LSL_USERS',@USER4,'','X')
    
    RDSMasterFlag	= UserRec<LSL_USERS_RDS_MASTER$>
    UserGroups		= UserRec<LSL_USERS_GROUPS$>
    
    IF NOT(RDSMasterFlag) THEN
        ErrMsg('You do not have security rights to override Run Data Sheet information.')
        RETURN
    END
    
    IF NOT(Dialog_Box( 'PWD_ENTRY', @WINDOW, '' )) THEN RETURN
    
    EpiOvrControls = Get_Property( @WINDOW, '@EpiOvrControls' )  
    Set_Property( EpiOvrControls, 'ENABLED', 1 )
    
    LOCATE 'MASTER_SCHED' IN UserGroups USING @VM SETTING Dummy ELSE
        Set_Property(@WINDOW:'.STATUS.CANCELLED','ENABLED',0)				;* Disable the CANCELLED button in the button group
    END
    
    
RETURN


* * * * * * *
PrintInstruction:
* * * * * * *
    
    RDSNo = Get_Property(@WINDOW:'.RDS_NO','TEXT')
    
    IF RDSNo NE '' THEN
        Print_RDS_Instruction(RDSNo)
    END
    
RETURN



* * * * * * *
ViewWOMat:
* * * * * * *

    Ctrls  = @WINDOW:'.WO':@RM				; Props  = 'DEFPROP':@RM
    Ctrls := @WINDOW:'.RUN_ORDER_NUM':@RM	; Props := 'DEFPROP':@RM
    Ctrls := @WINDOW:'.RDS_NO':@RM			; Props := 'DEFPROP':@RM
    Ctrls := @WINDOW:'.REACTOR':@RM			; Props := 'DEFPROP':@RM
    Ctrls := @WINDOW:'.WO_STEP':@RM			; Props := 'DEFPROP':@RM
    Ctrls := @WINDOW:'.REACTOR_TYPE'		; Props := 'DEFPROP'
    
    Vals = Get_Property(Ctrls,Props)
    
    WONo		= Vals[1,@RM]
    CassNo		= Vals[COL2()+1,@RM]
    RDSNo		= Vals[COL2()+1,@RM]
    Reactor		= Vals[COL2()+1,@RM]
    WOStep		= Vals[COL2()+1,@RM]
    ReactorType	= Vals[COL2()+1,@RM]
    
    IF ReactorType = 'P' OR ReactorType = 'EPP' THEN RETURN
    
    Send_Event(@WINDOW,'WRITE')
    Send_Event(@WINDOW,'CLEAR') ; // 12/21/2017 - DMB - Although WRITE normally clears the form, QBF mode will prevent the clear so do this explicitly so the lock is removed from the RDS record.
    
    thisFormWindowUp = Get_Property('WO_MAT_WFR','VISIBLE')	;* Returns 0 = hidden, 1 = visible, 2 = minimized, 3 = maximized 
    
    IF thisFormWindowUp = ''	THEN
        Start_Window('WO_MAT_WFR',@WINDOW,'')
    END ELSE
        
        IF thisFormWindowUp = 2		THEN Set_Property('WO_MAT_WFR','VISIBLE',9)	;* Restore the window if minimized
        
        IF Get_Property('WO_MAT_WFR','SAVEWARN') THEN
            Set_Property('WO_MAT_WFR','@SKIP_CARD_RETURN',1)	;* This stops the Return behavior
            Send_Event('WO_MAT_WFR','CLEAR')					;* Clear anything existing (prompts for save first)
        END
    END
    
    * Load Key Controls with Key Parts
    Set_Property('WO_MAT_WFR', 'VISIBLE', 1)	
    Ctrls  = 'WO_MAT_WFR':@RM				; Props  = '@RETURN_KEY':@RM		; Vals  = RDSNo:@RM
    Ctrls := 'WO_MAT_WFR':@RM				; Props := '@RETURN_PAGE':@RM		; Vals := '':@RM
    Ctrls := 'WO_MAT_WFR':@RM				; Props := '@RETURN_CONTROL':@RM	; Vals := '':@RM
    Ctrls := 'WO_MAT_WFR':@RM				; Props := '@RETURN_POS':@RM		; Vals := '':@RM
    Ctrls := 'WO_MAT_WFR':@RM				; Props := '@RDS_NO':@RM			; Vals := RDSNo:@RM
    Ctrls := 'WO_MAT_WFR':@RM				; Props := '@REACTOR':@RM			; Vals := Reactor:@RM
    Ctrls := 'WO_MAT_WFR':@RM				; Props := '@WO_STEP_NO':@RM		; Vals := WOStep:@RM
    
    Ctrls := 'WO_MAT_WFR.WO_NO':@RM			; Props := 'DEFPROP':@RM			; Vals := WONo:@RM
    Ctrls := 'WO_MAT_WFR.CASS_NO'			; Props := 'DEFPROP'				; Vals := CassNo
    
    Set_Property(Ctrls,Props,Vals)
    
    Send_Event('WO_MAT_WFR.CASS_NO','LOSTFOCUS')
    
RETURN



* * * * * * *
NextStepQty:
* * * * * * *
    
    Ctrls  = @WINDOW:'.RDS_NO':@RM		; Props  = 'DEFPROP':@RM
    Ctrls := @WINDOW:'.WO':@RM			; Props := 'DEFPROP':@RM
    Ctrls := @WINDOW:'.WO_STEP':@RM		; Props := 'DEFPROP':@RM
    Ctrls := @WINDOW:'.CASS_NO'			; Props := 'DEFPROP'
    
    Vals = Get_Property(Ctrls,Props)
    
    CurRDSNo	= Vals[1,@RM]
    WONo		= Vals[COL2()+1,@RM]
    WOStep		= Vals[COL2()+1,@RM]
    CassNo		= Vals[COL2()+1,@RM]
    
    
    WOMatKey = WONo:'*':CassNo
    WOMatRec = XLATE('WO_MAT',WOMatKey,'','X')
    WMRDSNos = WOMatRec<WO_MAT_RDS_NO$>
    
    LOCATE CurRdsNo IN WMRDSNos USING @VM SETTING Pos THEN
        NextRDSNo = WMRDSNos<1,Pos+1>
        IF NextRDSNo NE '' THEN
            CurrWfrQty = obj_WO_Mat('CurrWaferCnt',WOMatKey:@RM:WOMatRec)
            Set_Status(0)
            obj_RDS('SetSchedWfrQty',NextRDSNo:@RM:CurrWfrQty)
            IF Get_Status(errCode) THEN ErrMsg(errCode)
        END
    END ELSE
        ErrMsg('Not a multi step process')
    END
    
RETURN


* * * * * * *
CIClick:
* * * * * * *
    
    CurrCtrl = Parm1
    
    BEGIN CASE
        CASE @WINDOW = 'RDS_PRE_EPI'
            Stage = 'PRE'
            CICtrl = @WINDOW:'.PRE_CI_NO'
            
        CASE @WINDOW = 'RDS'
            Stage = 'FWI'
            CICtrl = @WINDOW:'.FWI_CI_NO'
            
        CASE @WINDOW = 'RDS_UNLOAD'
            Stage = 'LWI'
            CICtrl = @WINDOW:'.LWI_CI_NO'
            
        CASE @WINDOW = 'RDS_POST_EPI'
            Stage = 'POST'
            CICtrl = @WINDOW:'.POST_CI_NO'
            
        CASE 1	; RETURN
            
    END CASE
    
    Ctrls  = @WINDOW:'.RDS_NO':@RM		; Props  = 'DEFPROP':@RM
    Ctrls := @WINDOW:'.WO':@RM			; Props := 'DEFPROP':@RM
    Ctrls := @WINDOW:'.WO_STEP':@RM		; Props := 'DEFPROP':@RM
    Ctrls := @WINDOW:'.CASS_NO':@RM		; Props := 'DEFPROP':@RM
    Ctrls := @WINDOW:'.PSN':@RM			; Props := 'DEFPROP':@RM
    Ctrls := CICtrl						; Props := 'DEFPROP'
    
    Vals = Get_Property(Ctrls,Props)
    
    RDSNo	= Vals[1,@RM]
    WONo	= Vals[COL2()+1,@RM]
    WOStep	= Vals[COL2()+1,@RM]
    CassNo	= Vals[COL2()+1,@RM]
    PSNo	= Vals[COL2()+1,@RM]
    CINo	= Vals[COL2()+1,@RM]
    
    IF RDSNo = '' THEN RETURN
    
    IF CINo = '' THEN
        
        MsgHead	= 'Create Clean_Insp Record'
        MsgText	= 'Are you sure you wish to create a Clean_Insp record for this stage?'
        
        OK = Msg(@WINDOW,'','YESNO','',MsgHead:@FM:MsgText)
        
        IF NOT(OK) THEN RETURN
        
        oCIParms  = WONo:@RM
        oCIParms := WOStep:@RM
        oCIParms := CassNo:@RM
        oCIParms := Stage:@RM
        oCIParms := RDSNo:@RM
        oCIParms := PSNo:@RM
        oCIParms := ''			;* PSRec passed as null
        
        CINo = obj_Clean_Insp('Create',oCIParms)
        
        IF Get_Status(errCode) THEN
            ErrMsg(errCode)
            RETURN
        END
        
        obj_React_Run('AddCI',RDSNo:@RM:Stage:@RM:CINo)
        
    END
    
    IF CINo NE '' THEN
        CurrQBFPos = Get_Property (@WINDOW, "QBFPOS"); // 4/14/2025 - JRO - CLEAR event below is advancing the QBF position. Buffer the current position before that happens
        Send_Event(@WINDOW,'WRITE')
        
        Send_Event(@WINDOW,'CLEAR') ; // 12/22/2017 - DMB - Although WRITE normally clears the form, QBF mode will prevent the clear so do this explicitly so the lock is removed from the RDS record.
        
        Set_Property (@WINDOW, "QBFPOS", CurrQBFPos); // - JRO - 4/14/2025 CLEAR event above is advancing the QBF position. apply the buffered position value
        DetWindow	= 'CLEAN_INSP'
        DetKeys		= CINo
        DefaultRec	= ''
        RetKey		= RDSNo
        RetWin		= @WINDOW
        RetPage		= 1
        RetCtrl		= CurrCtrl
        RetPos		= ''
        
        obj_Appwindow('ViewNewDetail',DetWindow:@RM:DetKeys:@RM:DefaultRec:@RM:RetKey:@RM:RetPage:@RM:RetCtrl:@RM:RetPos)
        
    END
    
RETURN


* * * * * * *
SAPSign:
* * * * * * * 
    * Used to auto-sign all steps for Admin purposes.
    
    RDSNo		= Get_Property(@WINDOW:'.RDS_NO','DEFPROP')
    WONo		= Get_Property(@WINDOW:'.WO','DEFPROP')
    WOStepNo	= Get_Property(@WINDOW:'.WO_STEP','DEFPROP')
    CassNo		= Get_Property(@WINDOW:'.CASS_NO','DEFPROP')
    SchedQty	= Get_Property(@WINDOW:'.WAFERS_SCHEDULED','DEFPROP')
    
    ProdVerNo = XLATE('WO_LOG',WONo,WO_LOG_PROD_VER_NO$,'X')
    
    IF ProdVerNo = '' THEN
        ErrMsg('No Prod_Ver number on Work Order -> Not generated by SAP.')
        RETURN
    END
    
    CurrDt = Date()
    CurrTm = Time()
    
    Set_Property(@WINDOW:'.SHIFT','DEFPROP', 'A')
    
    Send_Event(@WINDOW,'WRITE')
    
    otParms = 'RDS':@RM:RdsNo
    RDSRec = obj_Tables('ReadRec',otParms)	;* Reads and sets lock
    
    IF Get_Status(errCode) THEN RETURN			;* Problems getting the lock
    
    If MemberOf(@USER4, 'OI_ADMIN') then
        Sig = @USER4
    end
    
    AllSigProfKeys = XLATE('WO_MAT',WONo:'*':CassNo,WO_MAT_SIG_PROFILE$,'X')
    
    SigCnt = COUNT(AllSigProfKeys,@VM) + (AllSigProfKeys NE '')
    
    SigDTM = OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTHS')
    
    SigProfKeys = ''
    Sigs = ''
    SigDTMs = ''
    
    SigProfKeys = AllSigProfKeys
    
    FOR I = 1 TO SigCnt - 1
        Sigs<1,I> = Sig
        SigDTMs<1,I> = SigDTM
    NEXT I
    
    RDSRec<RDS_PRE_EPI_SIG$>		= Sig
    RDSRec<RDS_PRE_EPI_SIG_DATE$>	= CurrDt
    RDSRec<RDS_PRE_EPI_SIG_TIME$>	= CurrTm - 250
    
    RDSRec<RDS_OPERATOR_IN$>		= Sig
    RDSRec<RDS_DATE_IN$>			= CurrDt
    RDSRec<RDS_TIME_IN$>			= CurrTm - 200
    
    RDSRec<RDS_FIRST_WAF_SIG$>		= Sig
    RDSRec<RDS_FIRST_WAF_SIG_DATE$>	= CurrDt
    RDSRec<RDS_FIRST_WAF_SIG_TIME$> = CurrTm - 150
    
    RDSRec<RDS_OPERATOR_OUT$>		= Sig
    RDSRec<RDS_DATE_OUT$>			= CurrDt
    RDSRec<RDS_TIME_OUT$>			= CurrTm - 100
    
    RDSRec<RDS_POST_EPI_SIG$>		= Sig
    RDSRec<RDS_POST_EPI_SIG_DATE$>	= CurrDt
    RDSRec<RDS_POST_EPI_SIG_TIME$>	= CurrTm - 50
    
    RDSRec<RDS_STATUS$>	= 'T'
    
    RDSRec<RDS_VERIFY_QTY$>	= SchedQty
    RDSRec<RDS_WAFERS_IN$>	= SchedQty
    RDSRec<RDS_WAFERS_OUT$>	= SchedQty      
    
    
    otParms = FIELDSTORE(otParms,@RM,4,0,RDSRec)
    obj_Tables('WriteRec',otParms)
    
    
    IF Get_Status(errCode) THEN
        obj_Tables('UnlockRec',otParms)
    END

    IF Get_Status(errCode) THEN
        ErrMsg(errCode)
    END
    
    
    LogFile = 'WO_MAT'
    Action = 'Place'
    WhCd	= '1K'		;* Class 1000 room
    LocCd	= 'PTI'		;* Passthrough Inbound
    WONos	= WONo
    CassNos = CassNo
    UserID  = Sig
    CassIDs	= RDSNo
    
    obj_WO_Mat_Log('Create',LogFile:@RM:SigDTM:@RM:Action:@RM:WhCd:@RM:LocCd:@RM:WONos:@RM:CassNos:@RM:UserID:@RM:CassIDs)
    
    IF Get_Status(errCode) THEN
        ErrMsg(errCode)
    END
    
    Set_Property(@WINDOW:'.RDS_NO','DEFPROP',RDSNo)
    Send_Event(@WINDOW:'.RDS_NO','LOSTFOCUS')
    
RETURN


* * * * * * *
SAPReject:
* * * * * * *

    * Rejected cassettes do not close automatically.  This is the manual step triggered by the 
    * SAP "Reject" button on the RDS_POST_EPI window.  Admin reviews and then closes and data is sent
    * to SAP and Fab-Time.
    
    * Following copied from Sign Final QA click event on the RDS_POST_EPI window.
    
    * Development in process 10/23/2014 JC
    
    SigDt			= OCONV( Date(), 'D2/' )
    SigTm 			= Time()
    SigTmPlusOne	= OCONV(SigTm + 1, 'MTS' )
    SigTmPlusTwo	= OCONV(SigTm + 2, 'MTS' )
    SigTm			= OCONV(SigTm,'MTS')
    
    SigBy = @USER4
    
    Ctrls  = @WINDOW:'.REACTOR_TYPE':@RM	; Props  = 'DEFPROP':@RM
    Ctrls := @WINDOW:'.RDS_NO':@RM			; Props := 'DEFPROP':@RM
    Ctrls := @WINDOW:'.WO':@RM				; Props := 'DEFPROP':@RM
    Ctrls := @WINDOW:'.WO_STEP':@RM			; Props := 'DEFPROP':@RM
    Ctrls := @WINDOW:'.CASS_NO':@RM			; Props := 'DEFPROP':@RM
    Ctrls := @WINDOW:'.MAKEUP_BOX'			; Props := 'CHECK'
    
    Vals = Get_Property(Ctrls,Props)
    
    ReactorType = Vals[1,@RM]
    CurRDSNo	= Vals[COL2()+1,@RM]
    WONo		= Vals[COL2()+1,@RM]
    WOStep		= Vals[COL2()+1,@RM]
    CassNo		= Vals[COL2()+1,@RM]
    MakeupBox	= Vals[COL2()+1,@RM]
    WOMatKey    = WONo:'*':CassNo
    EventParms = ''
    EventCnt   = 1
    
    IF ReactorType NE 'EPP' THEN
        
        ToolID		= ''
        WHCd		= 'CR'
        LocCD		= 'QA'
        Tag			= ''
        
        owmParms = WONo:@RM:CassNo:@RM:WOStep:@RM:'QA':@RM:@USER4:@RM:SigDt:' ':SigTm:@RM:ToolID:@RM:WHCd:@RM:LocCd:@RM:Tag			;* 4/30/2013 JCH added parms for merging of two methods	
        
        IF Get_Status(errCode) THEN
            CALL ErrMsg(ErrCode)
            RETURN 0					;* Added 4/4/2013 JCH
        END
        
        EventParms<COL$LOG_FILE>		= 'WO_MAT'
        EventParms<COL$LOG_DTM>			= SigDt:' ':SigTm
        EventParms<COL$WO_MAT_ACTION>	= WOStep:'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 * * * * *
        
        IF Get_Status(errCode) THEN
            CALL ErrMsg(ErrCode)
            RETURN 0
        END
        
        IF MakeupBox = 1 THEN
            
            EventParms<COL$LOG_FILE>		= 'WO_MAT'
            EventParms<COL$LOG_DTM>			= SigDt:' ':SigTmPlusTwo
            EventParms<COL$WO_MAT_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)
                RETURN 0
            END
            
        END
        
    END	;* End of check for non EpiPRO reactor
    
    * Update Final QA signature fields in the window *
    
    Ctrls  = @WINDOW:'.POST_EPI_SUP_SIG':@RM		; Props  = 'TEXT':@RM		; Vals  = @USER4:@RM
    Ctrls := @WINDOW:'.POST_EPI_SUP_SIG_NAME':@RM	; Props := 'TEXT':@RM		; Vals := OCONV( @USER4, '[XLATE_CONV,LSL_USERS*FIRST_LAST]' ):@RM
    Ctrls := @WINDOW:'.POST_EPI_SUP_SIG_DATE':@RM	; Props := 'TEXT':@RM		; Vals := SigDt:@RM
    Ctrls := @WINDOW:'.POST_EPI_SUP_SIG_TIME'		; Props := 'TEXT'			; Vals := SigTmPlusOne
    
    Set_Property(Ctrls,Props,Vals)
    
    // Send SAP "CASS_COMP" transaction
    Sap_Services('AddCassCompTransaction', WOMatKey)
    
    * Check for multiple Reactor Runs on this cassette and update Sched Wafer Qty as required *
    
    //WOMatKey = WONo:'*':CassNo
    WOMatRec = XLATE('WO_MAT',WOMatKey,'','X')
    WMRDSNos = WOMatRec<WO_MAT_RDS_NO$>
    
    LOCATE CurRdsNo IN WMRDSNos USING @VM SETTING Pos THEN
        NextRDSNo = WMRDSNos<1,Pos+1>
        
        IF NextRDSNo NE '' THEN
            CurrWfrQty = obj_WO_Mat('CurrWaferCnt',WOMatKey:@RM:WOMatRec)
            Set_Status(0)
            obj_RDS('SetSchedWfrQty',NextRDSNo:@RM:CurrWfrQty)
            IF Get_Status(errCode) THEN ErrMsg(errCode)
        END
    END
    
    WOMatKey	= WONo:'*':CassNo
    OrgMUPart	= XLATE('WO_MAT',WOMatKey,'MU_PART_NO','X')
    
    Send_Event(@WINDOW,'WRITE')
    
    * Generate index transaction to keep the MU_PART_NO index updated in the WO_MAT table *
    
    NewMUPart = XLATE('WO_MAT',WOMatKey,'MU_PART_NO','X')
    
    IF NewMUPart NE OrgMUPart THEN
        
        IndexTransactionRow = 'MU_PART_NO':@FM:WOMatKey:@FM:OrgMUPart:@FM:NewMUPart:@FM
        
        OPEN "!WO_MAT" TO BangTable THEN
            
            LOCK BangTable, 0 THEN
                
                READ PendingTrans FROM BangTable, 0 ELSE PendingTrans = '0':@FM
                
                PendingTrans := IndexTransactionRow
                
                WRITE PendingTrans ON BangTable, 0 ELSE
                    ErrMsg('Unable to write index transaction to !WO_MAT. ':WOMatKey)
                END
                UNLOCK BangTable, 0 ELSE ErrMsg('Unable to Open !WO_MAT to add index transaction. ':WOMatKey)
            END ELSE
                ErrMsg('Unable to Lock !WO_MAT to add index transaction. ':WOMatKey)
            END
        END ELSE
            ErrMsg('Unable to Open !WO_MAT to add index transaction. ':WOMatKey)
        END
    END	;* End of check for changed index value
    
    * Redisplay the updated RDS record in the window *
    
    obj_AppWindow('LoadFormKeys',@WINDOW:@RM:CurRdsNo)
    
    
RETURN


* * * * * * *
MetTestDC:
* * * * * * *
    
    Ctrls  = @WINDOW:'.RDS_NO':@RM		; Props  = 'DEFPROP':@RM
    Ctrls := @WINDOW:'.WO':@RM			; Props := 'DEFPROP':@RM
    Ctrls := @WINDOW:'.WO_STEP':@RM		; Props := 'DEFPROP':@RM
    Ctrls := @WINDOW:'.CASS_NO':@RM		; Props := 'DEFPROP':@RM
    
    CurrPos	  = Get_Property(@WINDOW:'.MET_TEST', 'SELPOS')
    CurrCol   = CurrPos<1>
    CurrRow   = CurrPos<2>
    Lines	  = Get_Property(@WINDOW:'.MET_TEST', 'LIST')
    TestLine  = Lines<CurrRow>
    LWRHOTest = Indexc(TestLine, 'LW_RHO', 1)
    
    If (@Window EQ 'RDS_UNLOAD') and (LWRHOTest EQ False$)  then
        Ctrls := @WINDOW:'.EDT_QA_MET':@RM	; Props := 'SELPOS':@RM
        Ctrls := @WINDOW:'.EDT_QA_MET'		; Props := 'LIST'
    end else
        Ctrls := @WINDOW:'.MET_TEST':@RM	; Props := 'SELPOS':@RM
        Ctrls := @WINDOW:'.MET_TEST'		; Props := 'LIST'
    end
    
    Vals = Get_Property(Ctrls,Props)
    
    RDSNo	= Vals[1,@RM]
    WONo	= Vals[COL2()+1,@RM]
    WOStep	= Vals[COL2()+1,@RM]
    CassNo	= Vals[COL2()+1,@RM]
    CurrPos	= Vals[COL2()+1,@RM]
    Lines	= Vals[COL2()+1,@RM]
    
    CurrCol = CurrPos<1>
    CurrRow = CurrPos<2>
    
    TestLine = Lines<CurrRow>
    
    CurrCtrl = Get_Property(@WINDOW,'FOCUS')
    
    RunStep = ''
    If CurrCtrl[1,'.'] = 'RDS' Then RunStep = 'FWI'
    IF CurrCtrl[1,'.'] = 'RDS_UNLOAD' THEN RunStep = 'UNLOAD'
    IF CurrCtrl[1,'.'] = 'RDS_POST_EPI' THEN RunStep = 'QA'
    
    IF RunStep = '' THEN RETURN
    
    CassID = WONo:'*':WOStep:'*':CassNo:'*':RDSNo:'*':RunStep
    
    MetTest = TestLine<0, 1>
    BEGIN CASE
        CASE MetTest EQ ''
            Null
        CASE (@WINDOW = 'RDS_UNLOAD') and (LWRHOTest EQ False$)
            ReturnVal = Dialog_Box('NDW_QA_MET_RESULT', @WINDOW, CassID)
            Send_Event(@Window, "READ")
        CASE Otherwise$
            ReturnVal = Dialog_Box('QA_MET_RESULT', @WINDOW, CassID:@FM:TestLine)
            Send_Event(@Window, "READ");
    END CASE
    
    GOSUB Refresh
    
RETURN


* * * * * * * *
LUPostCode:
* * * * * * * *
    
    ToolKeys		= XLATE('TOOL_CLASS','AKRION',TOOL_CLASS_TOOL$,'X')
    ToolKeys<1,-1>	= XLATE('TOOL_CLASS','WET BENCH',TOOL_CLASS_TOOL$,'X')
    
    TypeOver = ''
    TypeOver<PMODE$> = 'K'
    TypeOver<PDISPLAY$> = ToolKeys
    
    ToolID = Popup(@WINDOW,TypeOver,'TOOLS')
    
    IF ToolID = '' THEN RETURN
    
    obj_Appwindow('LUValReturn',ToolID:@RM:@WINDOW:'.POST_CODE')
    
    
RETURN


* * * * * * *
SigProfile:
* * * * * * *
    
    RDSNo  = Get_Property(@WINDOW:'.RDS_NO','TEXT')
    WOMatKey = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X')
    
    If WOMatKey NE '' or RDSNo NE '' then
        SigData = Signature_Services('GetSigProfile', WOMatKey, False$, RDSNo)
        Display = ''
        RowCnt = COUNT(SigData<1>,@VM) + (SigData<1> NE '')
        
        FOR I = 1 TO RowCnt
            Display<1,I,1> = SigData<1,I>
            Display<1,I,2> = SigData<2,I>
            Display<1,I,3> = SigData<3,I>
            Display<1,I,4> = SigData<4,I>
        NEXT I
        
        TypeOver = ''
        TypeOver<PDISPLAY$> = Display
        
        void = Popup(@WINDOW,TypeOver,'SIG_PROFILE')   
    end
    
RETURN


* * * * * * *
ReactProfile:
* * * * * * *
    
    ReactNo = Get_Property(@WINDOW:'.REACTOR','DEFPROP')
    
    IF ReactNo NE '' THEN
        obj_AppWindow('ViewRelated','REACT_STATE':@RM:ReactNo)
    END
    
RETURN


* * * * * * * *
ConversionLoad:
* * * * * * * *
    
    * Routine to create/update RDS_LAYER and RDS_TEST records until conversion is complete
    * dead stub
    
RETURN


* * * * * * * *
Overridelog:
* * * * * * * *

	RDSNo  = Get_Property(@WINDOW:'.RDS_NO','TEXT')
	orKeys = XLATE('RDS',RDSNo, 295, 'X')

	Display = ''
	overriderec = ''
	i = 1
	For Each orKey in orKeys using @VM
		overriderec = Xlate('OVERRIDE_LOG', orKey, '', 'X')
		Display<1,I,1> = overriderec<3>
		Display<1,I,2> = overriderec<4>
		Display<1,I,3> = overriderec<5>
		Display<1,I,4> = overriderec<6>
		i = i + 1
	Next orKey

	TypeOver            = ''
	TypeOver<PDISPLAY$> = Display
	void                = Popup(@WINDOW,TypeOver,'OVERRIDES') 

RETURN


* * * * * * * *
AddComment:
* * * * * * * *
	
    RDSNo  = Get_Property(@WINDOW:'.RDS_NO','TEXT')
    If RDSNo NE '' then
		Response = Dialog_Box('NDW_ADD_RDS_COMMENT', @Window)
		If Response NE '' then Rds_Services('AddComment', RDSNo, Response)
    end

return


* * * * * * * *
ViewComments:
* * * * * * * *

    RDSNo  = Get_Property(@WINDOW:'.RDS_NO','TEXT')
    If RDSNo NE '' then Response = Dialog_Box('NDW_RDS_COMMENT_VIEWER', @Window, RDSNo)

return


* * * * * * * *
ViewLotHistory:
* * * * * * * *

    RDSNo  = Get_Property(@WINDOW:'.RDS_NO','TEXT')
    If RDSNo NE '' then Response = Dialog_Box('NDW_LOT_HISTORY_VIEWER', @Window, RDSNo)

return


* * * * * * * *
Close:
* * * * * * * *


return


RefreshWaferCounterData:

	Set_Property(@Window:'.LBL_WAFER_COUNTER_QTY', 'VISIBLE', True$)
	Set_Property(@Window:'.EDL_WAFER_COUNTER_QTY', 'VISIBLE', True$)            
	QtyBackColor = GREEN$
	RDSNo        = Get_Property(@Window : '.RDS_NO','DEFPROP')
	If RDSNo NE '' then 
		FqaWcRec        = Wafer_Counter_Services('GetLastScan', RDSNo, 'QA')
		WaferCounterQty = FqaWcRec<WAFER_COUNTER.SCAN_QTY$>
		Set_Property(@Window, '@ORIG_WFR_CTR_QTY', WaferCounterQty)
		WafersOut       = Get_Property(@WINDOW:'.WAFERS_OUT','TEXT')
		Set_Property(@WINDOW:'.EDL_WAFER_COUNTER_QTY','DEFPROP', WaferCounterQty)

		*****************************************
		* WaferCounter - Wafers Quantity Section *
		*****************************************
		If (WaferCounterQty NE '') then
			If (WaferCounterQty NE WafersOut) then QtyBackColor = RED$
		end else
			QtyBackColor = ORANGE$
		end			
		
		WaferSize = Xlate('RDS', RDSNo, 'WAFER_SIZE', 'X')
		WaferSize = Field(WaferSize, ' ', 3, 1)
		If ( (WaferSize EQ 6) or (WaferSize EQ 8) ) then
			WCToolId = Wafer_Counter_Services('GetWaferCounterToolID', WaferSize:'INCH', 'QA')
			If Error_Services('NoError') then 
				WCCurrMode = ''
				If RowExists('TOOL', WCToolID) then
					WCCurrModeKey = Xlate('TOOL', WCToolID, 'CURR_MODE_KEY', 'X')
					WCCurrMode    = Xlate('TOOL_LOG', WCCurrModeKey, 'TOOL_MODE', 'X')
					Set_Property(@WINDOW:'.EDL_WAFER_COUNTER_QTY', 'ENABLED', (WCCurrMode NE 'PROD'))
				end else
					ErrMsg('Verify wafer count error. Invalid wafer counter tool ID "':WCToolID:'".')
				end
			end else
				ErrMsg(Error_Services('GetMessage'))
			end
		end else
			ErrMsg('Verify wafer count error. Invalid wafer size "':WaferSize:'" returned for RDS "':RDSNo:'".')
		end			
	end
	Set_Property(@WINDOW:'.EDL_WAFER_COUNTER_QTY','BACKCOLOR', QtyBackColor)
    
return

