Compile function DBW_RDS_OVERVIEW_NEPP_EVENTS(CtrlEntId, Event, @PARAMS)
/***********************************************************************************************************************

    This program is proprietary and is not to be used by or disclosed to others, nor is it to be copied without written
    permission from Infineon.

    Name        :   NDW_RDS_Proc_Stat_Nepp_Events

    Description :   This function acts as a commuter module for all events related to this window.

    Notes       :   Commuter Modules are automatically called from the Promoted_Events function which is called by the
                    application-specific promoted event handler. This makes it possible to add QuickEvents that need to
                    execute Basic+ logic without having use the Form Designer to make the association, although this is
                    limited to the events which are currently promoted.

                    If the form needs to call the commuter module directly then the QuickEvent parameters should be
                    formatted like this:

                        '@SELF','@EVENT',['@PARAM1','@PARAMx']

    Parameters  :
        CtrlEntId   [in] -- The fully qualified name of the control calling the promoted event
        Event       [in] -- The event being executed. See the Notes section regarding "PRE" events
        Param1-15   [in] -- Additional event parameter holders
        EventFlow  [out] -- Set to 1 or 0 so the calling event knows whether or not to chain forward. See comments in
                            EVENT_SETUP insert                 

    History     :   (Date, Initials, Notes)
        09/29/21    djs     Created initial commuter module.                                           

***********************************************************************************************************************/
#pragma precomp SRP_PreCompiler
#window DBW_RDS_OVERVIEW_NEPP

$Insert EVENT_SETUP
$Insert ACTION_SETUP
$Insert APPCOLORS
$Insert MSG_EQUATES
$Insert WO_MAT_QA_EQUATES
$Insert WO_MAT_EQUATES
$Insert RDS_EQUATES
$Insert POPUP_EQUATES
$INSERT LOGICAL
$INSERT LSL_USERS_EQU
$INSERT SECURITY_RIGHTS_EQU
$Insert REACT_RUN_EQUATES
$Insert WM_IN_EQUATES
$Insert WM_OUT_EQUATES
$Insert WO_LOG_EQUATES
$Insert NOTIFICATION_EQUATES

Equ COL$LOG_FILE        to 1
Equ COL$LOG_DTM         to 2
Equ COL$ACTION          to 3
Equ COL$WH_CD           to 4
Equ COL$LOC_CD          to 5
Equ COL$WO_NOS          to 6
Equ COL$CASS_NOS        to 7
Equ COL$USER_ID         to 8
Equ COL$TAGS            to 9
Equ COL$TOOL_ID         to 10

Equ COL.MET_TEST$       To 1
Equ COL.TEST_DESC$      To 2
Equ COL.SLOT$           To 3
Equ COL.SLOT_DESC$      To 4
Equ COL.WFR_QTY$        To 5
Equ COL.MET_MIN$        To 6
Equ COL.MET_MAX$        To 7
Equ COL.MET_RESULT$     To 8
Equ COL.STD_DEV_MAX$    To 9
Equ COL.STD_DEV_RESULT$ To 10
Equ COL.SIG$            To 11
Equ COL.SIG_DTM$        To 12

Equ COL$MET_TEST        to 1    ; // QA Metrology control on RDS_UNLOAD & RDS_POST_EPI windows
Equ COL$MET_TEST_DESC   to 2
Equ COL$MET_SLOT        to 3
Equ COL$MET_SLOT_DESC   to 4
Equ COL$MET_WFR_QTY     to 5
Equ COL$MET_MIN         to 6
Equ COL$MET_MAX         to 7
Equ COL$MET_RESULT      to 8
Equ COL$MET_STD_MAX     to 9
Equ COL$MET_STD_RESULT  to 10
Equ COL$MET_SIG         to 11
Equ COL$MET_SIG_DTM     to 12

EQU COL$TOP_LABEL		TO 1
EQU COL$BOTTOM_LABEL	TO 2
EQU COL$LOT_NO			TO 3
EQU COL$IFX_LABEL		TO 4
EQU COL$RESULT			TO 5
EQU COL$WOLOGKEY		TO 6

Equ CRLF$		to \0D0A\

Equ SS_STAGE$ To 1
Equ SS_PASS$  To 2
Equ SS_SIG$   To 3
Equ SS_DATA$  To 4
Equ SS_NA$    To 5

Declare subroutine  SRP_Show_Window, Set_Property, Send_Message, ErrMsg, Msg, Start_Window, QA_Services, Post_Event
Declare subroutine  obj_Appwindow, Popup, Signature_Services, Set_Status, obj_WO_Mat, obj_WO_Mat_Log, Send_Event
Declare subroutine  obj_RDS, obj_Notes
Declare function    Database_Services, Form_Services, Signature_Services, Msg, SRP_Array, QA_Services, obj_Popup
Declare function    Error_Services, Popup_Services, Dialog_Box, MemberOf, obj_WO_Mat, obj_RDS, Send_Message, Utility

SubclassInfo    = Form_Services('FindSubclassControl')
Subclass        = SubclassInfo<1>

// Update the arguments so that the OpenInsight OLE event will treate the ActiveX event as a native event handler.
If Event EQ 'OLE' then
    Transfer Event to OIEvent
    Transfer Param1 to Event
    Transfer Param2 to Param1
    Transfer Param3 to Param2
    Transfer Param4 to Param3
    Transfer Param5 to Param4
    Transfer Param6 to Param5
    Transfer Param7 to Param6
    Transfer Param8 to Param7
end

GoToEvent Event for CtrlEntID

Return EventFlow else EVENT_CONTINUE$

//-----------------------------------------------------------------------------
// EVENT HANDLERS
//-----------------------------------------------------------------------------

Event WINDOW.CREATE(CreateParam)
    
    GoSub SetupOLEControls
    If RowExists('RDS', CreateParam) then
        Set_Property(@Window:'.EDL_RDS_NO', 'TEXT', CreateParam)
        GoSub RefreshForm
    end
    GoSub EnableRefreshButton
    FormSize = '' 
    SRP_Show_Window(@Window, '', 'C', 'C', 1, '', False$, False$, FormSize)
    
End Event


Event WINDOW.CLEAR(bSaveKey, bSuppressWarning, bMaintainFocus, CtrlIDFocus)
    
    GoSub ClearForm
    
end event


Event OLE_BTN_REFRESH.OnClick(Point, Button, Shift, Ctrl)

    GoSub RefreshForm
    
end event


Event EDL_RDS_NO.LOSTFOCUS(Flag, FocusID)
    
    GoSub EnableRefreshButton
    GoSub RefreshForm
    
end event


Event OLE_EDT_STAGES.OnButtonClick(Cell, Point, Button, Shift, Ctrl)

    // Open related form so the user can sign the stage/metrology test/NCR/etc...
    RDSNo    = Get_Property(@Window:'.EDL_RDS_NO', 'TEXT')
    ErrorMsg = ''
    If RDSNo NE '' then
        StageIndex = Field(Cell, ';', 2)
        StageIDs   = Get_Property(@Window, '@STAGE_ID_LIST')
        StageID    = StageIDs<StageIndex>
        Begin Case
            Case StageID EQ 'VER'
                Start_Window('RDS_PRE_EPI', @Window, RDSNo)
            Case StageID EQ 'SUPP'
                Start_Window('RDS', @Window, RDSNo)
            Case StageID EQ 'LOAD'
                Start_Window('RDS', @Window, RDSNo)
            Case StageID EQ 'UNLOAD'
                Start_Window('RDS_UNLOAD', @Window, RDSNo)
            Case StageID EQ 'POST'
                Start_Window('RDS_POST_EPI', @Window, RDSNo)
            Case StageID EQ 'QA'
                Start_Window('RDS_POST_EPI', @Window, RDSNo)
            Case StageID EQ 'RDS_TEST'
                MetKeys = Xlate('RDS', RDSNo, 'MET_KEYS', 'X')
                NumKeys = DCount(MetKeys, @VM)
                Begin Case
                    Case NumKeys EQ 1
                        Start_Window('RDS_TEST', @Window, MetKeys)
                    Case NumKeys GT 1
                        // Just display the Post-Epi RDS form so that users can select which RDS_TEST record
                        // they would like to view.
                        Start_Window('RDS_POST_EPI', @Window, RDSNo)
                    Case NumKeys EQ 0
                        ErrorMsg = 'RDS_TEST record for RDS ':RDSNo:' does not exist!'
                End Case
            Case ( (StageID EQ 'PREI') or (StageID EQ 'PREC') or (StageID EQ 'PRES') )
                CINo = Xlate('RDS', RDSNo, 'PRE_CI_NO', 'X')
                If RowExists('CLEAN_INSP', CINo) then
                    GoSub OpenCleanInsp
                end else
                    ErrorMsg = 'PRE CLEAN_INSP record for RDS ':RDSNo:' does not exist!'
                end
            Case ( (StageID EQ 'FWII') or (StageID EQ 'FWIC') or (StageID EQ 'FWIS') )
                CINo = Xlate('RDS', RDSNo, 'FWI_CI_NO', 'X')
                If RowExists('CLEAN_INSP', CINo) then
                    GoSub OpenCleanInsp
                end else
                    ErrorMsg = 'FWI CLEAN_INSP record for RDS ':RDSNo:' does not exist!'
                end
            Case StageID EQ 'LOAD_QA_MET'
                WOMatQAKey = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X')
                If RowExists('WO_MAT_QA', WOMatQAKey) then
                    WOMatQAStages = Xlate('WO_MAT_QA', WOMatQAKey, 'STAGE', 'X')
                    Locate 'FWI' in WOMatQAStages using @VM setting vPos then                    
                        WONo       = Field(WOMatQAKey, '*', 1)
                        WOStep     = 1
                        CassNo     = Field(WOMatQAKey, '*', 2)
                        RunStep    = 'FWI'
                        CassID     = WONo:'*':WOStep:'*':CassNo:'*':RDSNo:'*':RunStep
                        Start_Window('QA_MET_RESULT', @Window, CassID)
                    end else
                        ErrorMsg = 'LOAD/FWI QA metrology is not prescribed for RDS ':RDSNo:'!'
                    end
                end else
                    ErrorMsg = 'WO_MAT_QA record for RDS ':RDSNo:' does not exist!'
                end
            Case ( (StageID EQ 'LWII') or (StageID EQ 'LWIC') or (StageID EQ 'LWIS') or (StageID EQ 'ROTR') )
                CINo = Xlate('RDS', RDSNo, 'LWI_CI_NO', 'X')
                If RowExists('CLEAN_INSP', CINo) then
                    GoSub OpenCleanInsp    
                end else
                    ErrorMsg = 'LWI CLEAN_INSP record for RDS ':RDSNo:' does not exist!'
                end
            Case StageID EQ 'UNLOAD_QA_MET'
                WOMatQAKey = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X')
                If RowExists('WO_MAT_QA', WOMatQAKey) then
                    WONo       = Field(WOMatQAKey, '*', 1)
                    WOStep     = 1
                    CassNo     = Field(WOMatQAKey, '*', 2)
                    RunStep    = 'UNLOAD'
                    CassID     = WONo:'*':WOStep:'*':CassNo:'*':RDSNo:'*':RunStep
                    Start_Window('NDW_QA_MET_RESULT', @Window, CassID)
                end else
                    ErrorMsg = 'WO_MAT_QA record for RDS ':RDSNo:' does not exist!'
                end
            Case ( (StageID EQ 'PSTI') or (StageID EQ 'PSTC') or (StageID EQ 'PSTS') )
                CINo = Xlate('RDS', RDSNo, 'POST_CI_NO', 'X')
                If RowExists('CLEAN_INSP', CINo) then
                    GoSub OpenCleanInsp
                end else
                    ErrorMsg = 'POST CLEAN_INSP record for RDS ':RDSNo:' does not exist!'
                end
            Case StageID EQ 'POST_QA_MET'
                WOMatQAKey = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X')
                If RowExists('WO_MAT_QA', WOMatQAKey) then
                    MetSlot    = ''
                    WONo       = Field(WOMatQAKey, '*', 1)
                    WOStep     = 1
                    CassNo     = Field(WOMatQAKey, '*', 2)
                    RunStep    = 'QA'
                    CassID     = WONo:'*':WOStep:'*':CassNo:'*':RDSNo:'*':RunStep
                    TestStages = Xlate('WO_MAT_QA', WOMatQAKey, 'STAGE', 'X')
                    NumTests   = Count(TestStages, 'QA')
                    If NumTests GT 1 then
                        AllSlots = Xlate('WO_MAT_QA', WOMatQAKey, 'SLOT', 'X')
                        QASlots  = ''
                        For each Stage in TestStages using @VM setting vPos
                            If Stage EQ 'QA' then QASlots<0, -1> = AllSlots<0, vPos>
                        Next Stage
                        MetSlot  = Popup_Services('DisplayPopupLiteral', 'Select QA Met Slot', 'Slot', QASlots, 1)
                    end else
                        For each Stage in TestStages using @VM setting vPos
                            If Stage EQ 'QA' then MetSlot = AllSlots<0, vPos>
                        Next Stage
                    end
                    If MetSlot NE '' then
                        WOMatQARec = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatQAKey)
                        Done       = False$
                        For each Stage in TestStages using @VM setting vPos
                            ThisSlot = AllSlots<0, vPos>
                            If ( (Stage EQ 'QA') and (ThisSlot EQ MetSlot) ) then Done = True$
                        Until Done EQ True$
                        Next Stage
                        MetTest                          = WOMatQARec<WO_MAT_QA_PROFILE$, vPos>
                        TestLine                         = ''
                        TestLine<0, COL.MET_TEST$>       = MetTest
                        TestLine<0, COL.TEST_DESC$>      = obj_Popup('CodeDesc', 'QA_MET_TEST':@RM:MetTest)
                        TestLine<0, COL.SLOT$>           = MetSlot
                        TestLine<0, COL.SLOT_DESC$>      = obj_Popup('CodeDesc','TEST_SLOTS':@RM:MetSlot)
                        TestLine<0, COL.WFR_QTY$>        = WOMatQARec<WO_MAT_QA_WFR_QTY$, vPos>
                        TestLine<0, COL.MET_MIN$>        = WOMatQARec<WO_MAT_QA_MIN$, vPos>
                        TestLine<0, COL.MET_MAX$>        = WOMatQARec<WO_MAT_QA_MAX$, vPos>
                        TestLine<0, COL.MET_RESULT$>     = WOMatQARec<WO_MAT_QA_RESULT$, vPos>
                        TestLine<0, COL.STD_DEV_MAX$>    = WOMatQARec<WO_MAT_QA_STD_MAX$, vPos>
                        TestLine<0, COL.STD_DEV_RESULT$> = WOMatQARec<WO_MAT_QA_STD_RESULT$, vPos>
                        TestLine<0, COL.SIG$>            = WOMatQARec<WO_MAT_QA_SIG$, vPos>
                        TestLine<0, COL.SIG_DTM$>        = WOMatQARec<WO_MAT_QA_SIG_DTM$, vPos>
                        Start_Window('QA_MET_RESULT', @Window, CassID:@FM:TestLine)
                    end
                end else
                    ErrorMsg = 'WO_MAT_QA record for RDS ':RDSNo:' does not exist!'
                end
            Case StageID EQ 'LBLCHK'
                Start_Window('DIALOG_QA_LABEL_CHECK')
            Case StageID EQ 'NCR'
                WOMatKey = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X')
                NCRKeys  = Xlate('WO_MAT', WOMatKey, 'NCR_KEYS', 'X')
                If NCRKeys NE '' then
                    NumKeys = DCount(NCRKeys, @VM)
                    If NumKeys GT 1 then
                        NCRKey = Popup_Services('DisplayPopupLiteral', 'Select NCR', 'NCR No', NCRKeys, 1)
                    end else
                        NCRKey = NCRKeys
                    end
                    If NCRKey NE '' then Start_Window('NCR', @Window, NCRKey)
                end else
                    ErrorMsg = 'No NCR records on file for RDS ':RDSNo:'!'
                end
            Case StageID EQ 'SAP_BATCH_ID'
                WOMatKey = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X')
                WONo     = Field(WOMatKey, '*', 1)
                CassNo   = Field(WOMatKey, '*', 2)
                Start_Window('WO_MAT', @Window, WOMatKey)
                Set_Property('WO_MAT.WO_NO', 'TEXT', WONo)
                Set_Property('WO_MAT.CASS_NO', 'TEXT', CassNo)
                Post_Event('WO_MAT', 'READ')
        End Case
    end
    
    If ErrorMsg NE '' then ErrMsg(ErrorMsg)
    
end event


Event OLE_EDT_STAGES.OnCheckChanged(Cell, OldValue, NewValue)

    GoSub EnableAutoSignButton
    
end event


Event PUB_AUTO_SIGN.CLICK()
    
    If (Not(MemberOf(@User4, 'LEAD')) or Not(MemberOf(@User4, 'SUPERVISOR') ) ) then
        Response = Dialog_Box('NDW_VERIFY_USER', @WINDOW, @USER4:@FM:'LEAD':@VM:'SUPERVISOR')
        Valid    = Response<1>
    end else
        Valid = True$
    end
    If Valid then
        
        ErrorMsgs = ''
        RDSNo     = Get_Property(@Window:'.EDL_RDS_NO', 'TEXT')
        WOMatKey  = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X')
        // Check all locks first
        RDSLock   = Database_Services('IsKeyIDLocked', 'RDS', RDSNo)
        If RDSLock then
            ErrorMsgs<-1> = 'RDS record ':RDSNo:' is locked!'
        end
        WOMatLock   = Database_Services('IsKeyIDLocked', 'WO_MAT', WOMatKey)
        If WOMatLock then
            ErrorMsgs<-1> = 'WO_MAT record ':WOMatKey:' is locked!'
        end
        WOMatQALock = Database_Services('IsKeyIDLocked', 'WO_MAT_QA', WOMatKey)
        If WOMatQALock then
            ErrorMsgs<-1> = 'WO_MAT_QA record ':WOMatKey:' is locked!'
        end
        NCRLock     = False$
        NCRKeys     = Xlate('WO_MAT', WOMatKey, 'NCR_KEYS', 'X')
        If NCRKeys NE '' then
            For each NCRKey in NCRKeys using @VM setting vPos
                Locked = Database_Services('IsKeyIDLocked', 'NCR', NCRKey)
                If Locked then NCRLock = True$
            Until Locked
            Next NCRKey
            If NCRLock then
                ErrorMsgs<-1> = 'NCR record ':NCRKey:' is locked!'
            end
        end
        PreCILock = Database_Services('IsKeyIDLocked', 'CLEAN_INSP', Xlate('RDS', RDSNo, 'PRE_CI_NO', 'X') )
        If PreCILock then
            ErrorMsgs<-1> = 'PRE CLEAN_INSP record is locked!'
        end
        FWICILock = Database_Services('IsKeyIDLocked', 'CLEAN_INSP', Xlate('RDS', RDSNo, 'FWI_CI_NO', 'X') )
        If FWICILock then
            ErrorMsgs<-1> = 'FWI CLEAN_INSP record is locked!'
        end
        LWICILock = Database_Services('IsKeyIDLocked', 'CLEAN_INSP', Xlate('RDS', RDSNo, 'LWI_CI_NO', 'X') )
        If LWICILock then
            ErrorMsgs<-1> = 'LWI CLEAN_INSP record is locked!'
        end
        QACILock  = Database_Services('IsKeyIDLocked', 'CLEAN_INSP', Xlate('RDS', RDSNo, 'POST_CI_NO', 'X') )
        If QACILock then
            ErrorMsgs<-1> = 'POST CLEAN_INSP record is locked!'
        end
        
        If ErrorMsgs EQ '' then
            If @User4 EQ 'DANIEL_ST' then Send_Event(@Window, 'WRITE')
            Def         = ""
            Def<MTEXT$> = "Auto-signing stages. Please wait..."
            Def<MTYPE$> = "U"
            MsgUp       = Msg(@Window, Def)   ;* display the processing message
            
            // Procedurally sign all stages that have a checkmark
            ChkBoxList = Get_Property(@Window:'.OLE_EDT_STAGES', "OLE.CellCheck[4; All]")
            Swap @RM with @FM in ChkBoxList
            StageIDs   = Get_Property(@Window, '@STAGE_ID_LIST')
            NumRows    = DCount(ChkBoxList, @FM)
            For RowIndex = 1 to NumRows
                ChkVal = ChkBoxList<RowIndex>
                If ChkVal EQ True$ then
                    StageID = StageIDs<RowIndex>
                    Begin Case
                        Case StageID EQ 'VER'
                            WaferQty = Xlate('RDS', RDSNo, 'VERIFY_QTY', 'X')
                            Reactor  = Xlate('RDS', RDSNo, 'REACTOR', 'X')
                            SigReady = QA_Services('PreEpiSignatureReady', RDSNo, @User4, WaferQty, Reactor)
                            If SigReady then
                                QA_Services('SignPreEpiStage', RDSNo, @User4, WaferQty, Reactor, False$)
                                If Error_Services('NoError') then
                                    ChkBoxList<RowIndex> = False$
                                end else
                                    ErrorMsgs<-1> = Error_Services('GetMessage')
                                end
                            end else
                                ErrorMsgs<-1> = Error_Services('GetMessage')
                            end
                        Case StageID EQ 'SUPP'
                            Signature_Services('SignSupplement', RDSNo, @User4)
                            If Error_Services('HasError') then
                                ErrorMsgs<-1> = Error_Services('GetMessage')
                            end
                        Case StageID EQ 'LOAD'
                            WafersIn = Xlate('RDS', RDSNo, 'WAFERS_IN', 'X')
                            Reactor  = Xlate('RDS', RDSNo, 'REACTOR', 'X')
                            LLSide   = Xlate('RDS', RDSNo, 'LOAD_LOCK_SIDE', 'X')
                            SigReady = QA_Services('LoadSignatureReady', RDSNo, @User4, WafersIn, LLSide, False$)
                            If SigReady then
                                QA_Services('SignLoadStage', RDSNo, @User4, WaferQty, LLSide, False$)
                                If Error_Services('NoError') then
                                    ChkBoxList<RowIndex> = False$
                                end else
                                    ErrorMsgs<-1> = Error_Services('GetMessage')
                                end
                            end else
                                ErrorMsgs<-1> = Error_Services('GetMessage')
                            end
                        Case StageID EQ 'UNLOAD'
                            Reactor  = Xlate('RDS', RDSNo, 'REACTOR', 'X')
                            SigReady = QA_Services('UnloadSignatureReady', RDSNo, @User4, Reactor)
                            If SigReady then
                                QA_Services('SignUnloadStage', RDSNo, @User4, False$)
                                If Error_Services('NoError') then
                                    ChkBoxList<RowIndex> = False$
                                end else
                                    ErrorMsgs<-1> = Error_Services('GetMessage')
                                end
                            end else
                                ErrorMsgs<-1> = Error_Services('GetMessage')
                            end
                        Case StageID EQ 'POST'
                            PSNo                 = Xlate('RDS', RDSNo, 'PROD_SPEC_ID', 'X')
                            VerInst              = XLATE('PRS_STAGE', PSNo:'*POST', 'INST', 'X')
                            InstructionsVerified = True$
                            If VerInst NE '' then InstructionsVerified = Dialog_Box('RDS_VER', @Window, VerInst)
                            If InstructionsVerified then
                                SigReady = Signature_Services('PostEpiSigReady', RDSNo)
                                If SigReady then
                                    Signature_Services('SignPostEpiStage', RDSNo, @User4)
                                    If Error_Services('NoError') then
                                        ChkBoxList<RowIndex> = False$
                                    end else
                                        ErrorMsgs<-1> = Error_Services('GetMessage')
                                    end
                                end else
                                    ErrorMsgs<-1> = Error_Services('GetMessage')
                                end
                            end else
                                ErrorMsgs<-1> = 'You must acknowledge RDS_VER instructions in order to sign POST-EPI stage.'
                            end
                        Case StageID EQ 'QA'
                            SigReady = Signature_Services('QASigReady', RDSNo)
                            If SigReady then
                                Signature_Services('SignQAStage', RDSNo, @User4)
                                If Error_Services('NoError') then
                                    ChkBoxList<RowIndex> = False$
                                end else
                                    ErrorMsgs<-1> = Error_Services('GetMessage')
                                end
                            end else
                                ErrorMsgs<-1> = Error_Services('GetMessage')
                            end
                        Case StageID EQ 'RDS_TEST'
                            // No signature for RDS_TEST records
                            Null
                        Case ( (StageID EQ 'PREI') or (StageID EQ 'PREC') or (StageID EQ 'PRES') or (StageID EQ 'FWII') |
                            or (StageID EQ 'FWIC') or (StageID EQ 'FWIS') or (StageID EQ 'LWII') or (StageID EQ 'LWIC') |
                            or (StageID EQ 'LWIS') or (StageID EQ 'PSTI') or (StageID EQ 'PSTC') or (StageID EQ 'PSTS') )
                            SigReady = Signature_Services('CleanInspSigReady', RDSNo, StageID)
                            If SigReady then
                                Signature_Services('SignCleanInsp', RDSNo, StageID, @User4)
                                If Error_Services('NoError') then
                                    ChkBoxList<RowIndex> = False$
                                end else
                                    ErrorMsgs<-1> = Error_Services('GetMessage')
                                end
                            end else
                                ErrorMsgs<-1> = Error_Services('GetMessage')
                            end
                        Case ( (StageID EQ 'LOAD_QA_MET') or (StageID EQ 'UNLOAD_QA_MET') or (StageID EQ 'POST_QA_MET') )
                            Begin Case
                                Case StageID EQ 'LOAD_QA_MET'
                                    QAStage = 'LOAD'
                                Case StageID EQ 'UNLOAD_QA_MET'
                                    QAStage = 'UNLOAD'
                                Case StageID EQ 'POST_QA_MET'
                                    QAStage = 'QA'
                            End Case
                            WOMatQARec = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatKey)
                            TestStages = WOMatQARec<WO_MAT_QA_STAGE$>
                            TestSlots  = WOMatQARec<WO_MAT_QA_SLOT$>
                            For each TestStage in TestStages using @VM setting vPos
                                If TestStage EQ QAStage then
                                    TestSlot = TestSlots<0, vPos>
                                    SigReady   = Signature_Services('QAMetSigReady', RDSNo, QAStage, TestSlot)
                                    If SigReady then
                                        Signature_Services('SignQAMet', RDSNo, QAStage, @User4, TestSlot)
                                        If Error_Services('HasError') then
                                            ErrorMsgs<-1> = Error_Services('GetMessage')
                                        end
                                    end else
                                        ErrorMsgs<-1> = Error_Services('GetMessage')
                                    end
                                end
                            Next TestStage
                            If ErrorMsgs EQ '' then ChkBoxList<RowIndex> = False$
                        Case StageID EQ 'ROTR'
                            SigReady = Signature_Services('ROTRSigReady', RDSNo)
                            If SigReady then
                                // Collect ROTR reason from user
                                MsgParms = 'ROTR Acceptance' : @FM : 'ROTR Acceptance Reason' : @FM : ''
                                Reason   = Msg(@Window, '', 'MESSAGE_INPUT', '', MsgParms)
                                If Reason NE '' then
                                    Signature_Services('SignROTR', RDSNo, @User4, Reason)
                                    If Error_Services('NoError') then
                                        ChkBoxList<RowIndex> = False$
                                    end else
                                        ErrorMsgs<-1> = Error_Services('GetMessage')
                                    end
                                end else
                                    ErrorMsgs<-1> = 'An ROTR acceptance reason must be provided in order to sign ROTR'
                                end
                            end else
                                ErrorMsgs<-1> = Error_Services('GetMessage')
                            end
                        Case StageID EQ 'LBLCHK'
                            // No signature for LBLCHK. Users must use the UI and barcode scanner.
                            Null
                        Case StageID EQ 'NCR'
                            SigReady = Signature_Services('NCRSigReady', RDSNo)
                            If SigReady then
                                Signature_Services('SignNCRs', RDSNo, @User4)
                                If Error_Services('NoError') then
                                    ChkBoxList<RowIndex> = False$
                                end else
                                    ErrorMsgs<-1> = Error_Services('GetMessage')
                                end
                            end else
                                ErrorMsgs<-1> = Error_Services('GetMessage')
                            end
                        Case Otherwise$
                            
                    End Case
                end
            Next RowIndex
            
            Msg(@Window, MsgUp)      ;* Take message down
            Set_Property(@Window, '@CHK_BOX_LIST', ChkBoxList)
            GoSub RefreshForm
        end
    end else
        ErrorMsgs<-1> = 'Only a LEAD or SUPERVISOR may auto-sign.'
    end
    
    If ErrorMsgs NE '' then
        Swap @FM with CRLF$ in ErrorMsgs
        ErrMsg(ErrorMsgs)
    end
    
end event


Event SIGN_BUTTON.CLICK()

    Valid       = ''    
    RDSNo       = Get_Property(@WINDOW:'.EDL_RDS_NO', 'DEFPROP')
    WONo        = Xlate('RDS', RDSNo, 'WO', 'X')
    CassNo      = Xlate('RDS', RDSNo, 'CASS_NO', 'X')
    WOStep      = Xlate('RDS', RDSNo, 'WO_STEP', 'X')
    ReactorType = Xlate('RDS', RDSNo, 'REACTOR_TYPE', 'X')
    PSNo        = Xlate('RDS', RDSNo, 'PROD_SPEC_ID', 'X')
    ******************************************
    * Update the form with signature, if any *
    ******************************************
    CurrSig     = ''
    CurrDTM     = ''
    CurrDate    = ''
    CurrTime    = ''

    *********************************************
    * Verify if the FQA has already been signed *
    *********************************************
    IF Not(MemberOf(@USER4,'BYPASS')) THEN
        IF (CurrSig NE '') THEN
                ErrMsg('Supervisor Verification for this material has already been signed.')
            RETURN
        END
    END

    ******************************************
    * Verify if the Post-EPI has been signed *
    ******************************************
    PostEpiSig = Xlate('RDS', RDSNo, 'POST_EPI_SIG', 'X')
    IF (PostEpiSig = '') THEN
        ErrorMesg = 'Process Error':@SVM:'Technician Signature Required before Final QA Verification.'
        ErrMsg(ErrorMesg)
        RETURN
    END

    **************************************************************************
    
    **************************************************************************
    IF Not(MemberOf(@USER4,'BYPASS')) THEN        ;* Bypass requirement for a different signer for post-epi and FQA -dkk 10/9/14
        IF (PostEpiSig = @USER4) THEN
            ErrorMesg  = 'Process Error':@SVM:'User ':QUOTE(PostEpiSig):' has signed this RDS for Post-Epi.':CRLF$:CRLF$
            ErrorMesg := 'Another qualified user must sign FQA verification'
            ErrMsg(ErrorMesg)
            RETURN
        END
    END

    ***************************************
    * Verify Metrology has been completed *
    ***************************************
    Set_Status(0)
    obj_WO_Mat('MQAComp',WONo:'*':CassNo:@RM:WOStep:@RM:'QA')
    errCode = ''
    IF Get_Status(errCode) THEN
        ErrMsg(errCode)
        RETURN
    END
    
    ***********************************************
    * Verify RDS_TEST record has measurement data *
    ***********************************************
    ThickAvg = Xlate('RDS', RDSNo, 'TTHICK_AVG_ALL', 'X')
    If ThickAvg EQ '' then
        ErrMsg('RDS metrology measurement data is missing. FQA cannot be signed.')
        Return
    end
    ResAvg = Xlate('RDS', RDSNo, 'TRES_AVG_ALL', 'X')
    If ResAvg EQ '' then
        ErrMsg('RDS Resistivity measurement data is missing. FQA cannot be signed.')
        Recipients     =  XLATE('SEC_GROUPS', 'OI_ADMIN', 'USER', 'X')
        SentFrom       = 'OI Admin'
        Subject        = 'Missing Resistivity Avg data'
        Message        = RDSNo: ' failed FQA due to missing resistivity average data.'
        AttachWindow   = ''
        AttachKey      = ''   
        SendToGroup    = ''   
        Parms          = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup
        obj_Notes('Create',Parms) 
        Return
    end
    
    ************************************************
    * Verify Signatures Profile has been fulfilled *
    ************************************************
        
    WOMatKey = WONo:'*':CassNo
    Signature_Services('CheckSigOrder', WOMatKey, 'QA')
    If Error_Services('HasError') then            
        ErrMsg(Error_Services('GetMessage'))
        return 0
    end

    Signature_Services('FQAReady', WOMatKey)
    If Error_Services('HasError') then
        ErrMsg(Error_Services('GetMessage'))
        Return 0
    end   

    *************************
    * Verify Wafer Quantity *
    *************************

    CassSchedWafers = Get_Property(@Window : '.WAFERS_SCHEDULED', 'TEXT')
    WafersOut       = Get_Property(@Window : '.WAFERS_OUT', 'TEXT')
    
    If CassSchedWafers NE WafersOut then

        Message     = 'Unable to sign FQA because the Scheduled' : CRLF$ : 'Qty does not equal the '
        Message     := 'Wafers Out Qty.' : CRLF$ : 'Lead or supervisor must override.'
        LeadMessage = 'Scheduled Wafers Quantity does not equal the Wafers Out Quantity.'
        
        If NOT( MemberOf(@USER4, 'LEAD') OR MemberOf(@USER4, 'SUPERVISOR') ) then
            Response = Msg(@Window, '', 'POST_EPI_WAFER_OUT', '', Message)
        end else
            Response = Msg(@Window, '', 'POST_EPI_WAFER_OUT', '', LeadMessage)
        end

        Begin Case
            Case Response EQ 1
                Response = True$        ; // User Clicked Override
            Case Response EQ 2
                Response = False$       ; // User Clicked Cancel
            Case Response EQ char(27)
                Response = False$       ; // User Pressed Escape Key
        End Case            
        
        If Response EQ True$ then
            Response    = Dialog_Box('NDW_VERIFY_USER', @WINDOW, @USER4 : @FM : 'LEAD' : @VM : 'SUPERVISOR')
            Valid       = Response<1>
            Username    = Response<2>
            If NOT(Valid) then
                Return
            end else
                Set_Property(@Window : '.FINAL_QA_WAFER_OUT_SIG', 'DEFPROP', Username)
                Set_Property(@Window : '.FINAL_QA_WAFER_OUT_NAME', 'TEXT', OConv(Username, '[XLATE_CONV,LSL_USERS*FIRST_LAST]'))
                Set_Property(@Window : '.FINAL_QA_WAFER_OUT_DATE', 'DEFPROP', Oconv(Date(), 'D2/'))
                Set_Property(@Window : '.FINAL_QA_WAFER_OUT_TIME', 'DEFPROP', Oconv(Time(), 'MTS'))                
            end
        end else
            Return
        end
                
    end
    

    *********************************
    * Verify NCR total >= USL Fails *
    *********************************

    ReactorNo   = Xlate('RDS', RDSNo, 'REACTOR', 'X')
    ROTREnabled = Xlate('REACTOR', ReactorNo, 'ENABLE_ROTR', 'X')
    If (ROTREnabled EQ True$) then
        LWICIKey          = Xlate('RDS', RDSNo, 'LWI_CI_NO', 'X')
        NumUSLFailValues  = Xlate('CLEAN_INSP', LWICIKey, 'NUM_FAILED_WAFERS', 'X')
        NumUSLFailCount   = COUNT(NumUSLFailValues,@VM) + (NumUSLFailValues NE '')
        NumUSLFail        = NumUSLFailValues<1,NumUSLFailCount>
        If NumUSLFail EQ '' then NumUSLFail = 0
        TotalNCR    = Xlate('RDS', RDSNo, 'TOT_REJ', 'X')
        If TotalNCR EQ '' then TotalNCR = 0
      
        If NumUSLFail GT TotalNCR then
            Message     = 'Unable to sign FQA because the total quantity of NCR wafers':CRLF$:'is less than the '|
                        : 'number of wafers above the USL threshold.' : CRLF$ : 'A lead or supervisor must override.'
            LeadMessage = 'Total quantity of NCR wafers is less than the number of wafers above the USL threshold.'
            
            If NOT( MemberOf(@USER4, 'LEAD') OR MemberOf(@USER4, 'SUPERVISOR') ) then
                Response = Msg(@Window, '', 'POST_EPI_WAFER_OUT', '', Message)
            end else
                Response = Msg(@Window, '', 'POST_EPI_WAFER_OUT', '', LeadMessage)
            end

            Begin Case
                Case Response EQ 1
                    Response = True$        ; // User Clicked Override
                Case Response EQ 2
                    Response = False$       ; // User Clicked Cancel
                Case Response EQ char(27)
                    Response = False$       ; // User Pressed Escape Key
            End Case            
            
            If Response EQ True$ then
                Response    = Dialog_Box('NDW_VERIFY_USER', @WINDOW, @USER4:@FM:'LEAD':@VM:'SUPERVISOR':@VM:'ENGINEER')
                Valid       = Response<1>
                If NOT(Valid) then Return
            end else
                Return
            end
        end
    end
    
    
    ********************************************
    * Verify NCR wafer qty >= Failed wafer qty *
    ********************************************

    NCRReq = QA_Services('GetNCRRequired', WOMatKey)
    If NCRReq then
        Message     = 'Unable to sign FQA because the total quantity of NCR wafers':CRLF$:'is less than the '|
                    : 'number of wafers that failed surfscan.' : CRLF$ : 'A lead or supervisor must override.'
        LeadMessage = 'Total quantity of NCR wafers is less than the number of wafers that failed surfscan.'
        
        If NOT( MemberOf(@USER4, 'LEAD') OR MemberOf(@USER4, 'SUPERVISOR') ) then
            Response = Msg(@Window, '', 'POST_EPI_WAFER_OUT', '', Message)
        end else
            Response = Msg(@Window, '', 'POST_EPI_WAFER_OUT', '', LeadMessage)
        end

        Begin Case
            Case Response EQ 1
                Response = True$        ; // User Clicked Override
            Case Response EQ 2
                Response = False$       ; // User Clicked Cancel
            Case Response EQ char(27)
                Response = False$       ; // User Pressed Escape Key
        End Case            
        
        If Response EQ True$ then
            Response    = Dialog_Box('NDW_VERIFY_USER', @WINDOW, @USER4:@FM:'LEAD':@VM:'SUPERVISOR':@VM:'ENGINEER')
            Valid       = Response<1>
            If NOT(Valid) then Return 0
        end else
            Return
        end
    end
        

    *************************
    * Verify if Shift exist *
    *************************
    Shift = Xlate('RDS', RDSNo, 'SHIFT', 'X')
    IF (Shift EQ '') THEN
        ErrMsg('Process Error':@SVM:'Shift is required before signing.')
        RETURN
    END

    ****************************
    * Verify if lot is on Hold *
    ****************************
    WOMatCurrStatus = obj_WO_Mat('CurrStatus',WONo:'*':CassNo)
    IF WOMatCurrStatus = 'HOLD' THEN
        ErrMsg('Process Error':@SVM:'Cassette is on Hold and may not be signed off.':CRLF$:CRLF$)
        RETURN
    END

    **********************
    * Check ROTR Failure *
    **********************
    ROTRAction  = Get_Property(@Window : '.ROTR_ACTION', 'INVALUE')
    If (ROTRAction NE 'Passed') AND (ROTRAction NE 'Accepted') AND (ROTRAction NE '') then
        ErrMsg('Process Error':@SVM:'ROTR does not meet all requirements.':CRLF$:CRLF$)
        return
    end

    ***************************************
    * Verify Metrology has been completed *
    ***************************************
    CtrlName = @WINDOW:'.MET_TEST'
    MetList = Get_Property(CtrlName,'LIST')
    MLCnt = COUNT(MetList,@FM) + (MetList NE '')
    FOR Line = 1 TO MLCnt
        IF MetList<Line,COL$MET_TEST> NE '' THEN
            BEGIN CASE
                CASE ((MetList<Line,COL$MET_MIN> = '') AND (MetList<Line,COL$MET_MAX> = ''))
                    NULL
                CASE (MetList<Line,COL$MET_RESULT> = '')
                    ErrMsg('Process Error':@SVM:'Required QA Metrology results have not been entered.')
                    RETURN
                CASE ((MetList<Line,COL$MET_RESULT> < MetList<Line,COL$MET_MIN>) OR (MetList<Line,COL$MET_RESULT> > MetList<Line,COL$MET_MAX>))
                    ErrMsg('Process Error':@SVM:'One or more QA Metrology results is out of specification.')
                    RETURN
                CASE ((MetList<Line,COL$MET_RESULT> NE '') AND (MetList<Line,COL$MET_SIG> = ''))
                    ErrMsg('Process Error':@SVM:'One or more QA Metrology results are not signed off.')
                    RETURN
            END CASE
        END    ;* End of check for a test requirement on the line
    NEXT Line
    
    ******************************************
    * Verify Unload Stage QA Metrology Tests *
    ******************************************
	WOMatQAKey  = WONo : '*' : CassNo
	WOMatQARec  = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatQAKey)
	OutOfSpec   = WOMatQARec<WO_MAT_QA_OUT_OF_SPEC$>
	OutOfSpec   = Sum(OutOfSpec)
	If OutOfSpec GT 0 then
		FailReasons = WOMatQARec<WO_MAT_QA_FAIL_REASON$>
		ErrorMsg = 'Process Error':@SVM
		For each FailReason in FailReasons using @VM
			ErrorMsg := FailReason:CRLF$
		Next FailReason
		ErrMsg(ErrorMsg)
		Return
	end

    *******************************************
    * Verify if all steps have been completed *
    *******************************************
    WOMatRec  = XLATE('WO_MAT',WONo:'*':CassNo,'','X')
    RDSNos    = WOMatRec<WO_MAT_RDS_NO$>
    MakeupBox = WOMatRec<WO_MAT_MAKEUP_BOX$>

    LOCATE RDSNo IN RDSNos USING @VM SETTING Pos THEN
        NextRDS = RDSNos<1,Pos+1>
    END ELSE
        NextRDS = ''
    END
            
    IF (WOMatCurrStatus NE 'QA' AND WOMatCurrStatus NE 'PSTI' AND WOMatCurrStatus NE 'COMP') AND (NextRDS NE '' AND WOMatCurrStatus NE 'VER') THEN
        ErrorMessage  = 'Process Error':@SVM:'Run is not ready for final QA.':CRLF$:CRLF$
        ErrorMessage := 'The ':OCONV(WOMatCurrStatus,'[WO_MAT_CURR_STATUS_CONV]'):' step is not complete.'
        ErrMsg(ErrorMessage)
        RETURN
    END
        
    IF NOT(MemberOF( @USER4, 'SUPERVISOR' ) OR MemberOf( @user4, 'LEAD' ) OR MemberOf( @USER4, 'FINAL_QA' ) ) THEN
        ErrMsg('Process Error':@SVM:'You must be a supervisor to verify this RDS.')
        RETURN
    END
        
    ************************************************************************
    * Prompt user to validate the Process Specification Stage Instructions *
    ************************************************************************
    VerInst = XLATE('PRS_STAGE',PSNo:'*QA',PRS_STAGE_INST$,'X')
    VerInst = TRIM(VerInst)
    IF LEN(VerInst) > 5 THEN
        Yes = Dialog_Box( 'RDS_VER', @WINDOW, VerInst )
        IF NOT(Yes) THEN
            RETURN
        END
    END

    **************************
    * Verify user's password *
    **************************
    
    // Check if user has already been verified above to avoid prompting for password twice
  
    If Valid EQ '' Then
        Response    = Dialog_Box('NDW_VERIFY_USER', @WINDOW)
        Valid       = Response<1>                  
    end       

    IF (Valid) THEN
                                   
        SigDt         = OCONV( Date(), 'D2/' )
        SigTm         = Time()
        SigTmPlusOne  = OCONV(SigTm + 1, 'MTS' )
        SigTmPlusTwo  = OCONV(SigTm + 2, 'MTS' )
        SigTmPlusFive = OCONV(SigTm + 5, 'MTS' )
        SigTmPlusTen  = OCONV(SigTm + 10, 'MTS' )
        SigTm         = OCONV(SigTm,'MTS')
        SigBy         = @USER4
        EventParms    = ''
        EventCnt      = 1
                          
        IF ReactorType NE 'EPP' THEN
        
            ToolID = ''
            WHCd   = 'CR'
            LocCD  = 'QA'
            Tag    = ''

            EventParms<COL$LOG_FILE> = 'WO_MAT'
            EventParms<COL$LOG_DTM>  = SigDt:' ':SigTm
            EventParms<COL$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
            END
            
            IF MakeupBox = 1 THEN
                
                EventParms<COL$LOG_FILE> = 'WO_MAT'
                EventParms<COL$LOG_DTM>  = SigDt:' ':SigTmPlusTwo
                EventParms<COL$ACTION>   = 'RTU'
                EventParms<COL$WH_CD>    = 'CR'
                EventParms<COL$LOC_CD>   = 'MU'
                EventParms<COL$WO_NOS>   = WONo
                EventParms<COL$CASS_NOS> = CassNo
                EventParms<COL$USER_ID>  = @USER4
                EventParms<COL$TAGS>     = ''
                EventParms<COL$TOOL_ID>  = ''
                
                CONVERT @FM TO @RM IN EventParms
                
                obj_WO_Mat_Log('Create',EventParms)        ;* * * * * INV EVENT LOG * * * * *
                
                IF Get_Status(errCode) THEN
                    CALL ErrMsg(ErrCode)
                    RETURN
                END
            END
        END    ;* End of check for non EpiPRO reactor

        Set_Property(@Window : '.POST_EPI_SUP_SIG', 'TEXT', @User4)
        Set_Property(@Window : '.POST_EPI_SUP_SIG_NAME', 'TEXT', OConv(@User4, '[XLATE_CONV,LSL_USERS*FIRST_LAST]'))
        Set_Property(@Window : '.POST_EPI_SUP_SIG_DATE', 'TEXT', SigDt)
        Set_Property(@Window : '.POST_EPI_SUP_SIG_TIME', 'TEXT', SigTmPlusOne)
        
        /* Sync up the RDS record with WO_MAT */
        IOOptions = Get_Property(@Window, 'IOOPTIONS')
        IOOptions<6> = True$
        Set_Property(@Window, 'IOOPTIONS', IOOptions)
        Send_Event(@Window, 'WRITE')
        IOOptions<6> = False$
        Set_Property(@Window, 'IOOPTIONS', IOOptions)
        
        WOMatKey = WONo:'*':CassNo
        WOMatRec = XLATE('WO_MAT',WOMatKey,'','X')
        WMRDSNos = WOMatRec<WO_MAT_RDS_NO$>
                        
        LOCATE RDSNo 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
            
        * Added 08/05/2013 JCH
        
        WOMatKey    = WONo:'*':CassNo
        OrgMUPart    = XLATE('WO_MAT',WOMatKey,'MU_PART_NO','X')
        
        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
        
    END    ;* End of check for valid signature

end event


Event SIG_PROFILE.CLICK()

    RDSNo    = Get_Property(@WINDOW:'.EDL_RDS_NO','TEXT')
    WOMatKey = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X')
    
    If WOMatKey NE '' then
        SigData = Signature_Services('GetSigProfile', WOMatKey)
        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
    
end event


Event CASS_IDS.POSCHANGED(NextColumn, NextRow)

    CtrlEntID = @WINDOW:'.CASS_IDS'
    
    PrevSelPos	= Get_Property(CtrlEntId,"PREVSELPOS")
    PrevCol 	= PrevSelPos<1>
    PrevRow 	= PrevSelPos<2>
    
    CurrPos = Get_Property(CtrlEntId,"SELPOS")
    CurrCol = CurrPos<1>
    CurrRow = CurrPos<2>
    
    ListData	= Get_Property(CtrlEntId,'LIST')
    ArrayData	= Get_Property(CtrlEntId,'ARRAY')
    
    MismatchDetected = False$ /* No mismatch */
    
    CellValue = TRIM(Send_Message(CtrlEntID, "TEXT_BY_POS", CurrCol, CurrRow))
    IF (CellValue = '') THEN
        
        ColPointer = CurrCol
        LinePointer = CurrRow
        ColCnt = 5
        
        /* Find the first non-empty cell */
        LOOP
            Test = TRIM(Send_Message(CtrlEntID, "TEXT_BY_POS", ColPointer, LinePointer))
        UNTIL Test NE '' OR (LinePointer = 0 AND ColPointer = 1)
            ColPointer = ColPointer - 1
            IF ColPointer = 0 THEN
                ColPointer = ColCnt
                LinePointer = LinePointer - 1
            END
        REPEAT
        
        /* Move to the next empty cell */
        BEGIN CASE
            CASE LinePointer = 0 
                * Empty Table
                LinePointer = 1
                ColPointer = 1
                
            CASE ColPointer = ColCnt
                LinePointer = LinePointer + 1
                ColPointer = 1
                
            CASE 1
                ColPointer = ColPointer + 1
        END CASE
        
        Set_Property("SYSTEM", "BLOCK_EVENTS", True$)
        Set_Property(CtrlEntId, "SELPOS", ColPointer:@FM:LinePointer)
        Set_Property("SYSTEM", "BLOCK_EVENTS", False$)
    END
    
    *****************************
    * Post Prompt for Top Label *
    *****************************
    
    TopLabel = TRIM(Send_Message(CtrlEntID, "TEXT_BY_POS", COL$TOP_LABEL, PrevRow))
    
    IF TopLabel[1,2] = '1T' THEN
        TopLabel = TopLabel[3,99]
        Set_Property(CtrlEntId,"CELLPOS",TopLabel,PrevSelPos)
    END
    
    IF ((TopLabel NE '') AND (PrevCol = COL$TOP_LABEL)) THEN
        
        Set_Property(@WINDOW,'@EPIPRO_FLAG',0)
        
        BEGIN CASE
            CASE TopLabel[1,1] = 'I'
                * WM_IN table
                TopLabel = TopLabel[2,99]
                WOMatKey = FIELD(TopLabel,'.',1):'*':FIELD(TopLabel,'.',3)
                Set_Property(CtrlEntID, "CELLPOS", TopLabel, PrevSelPos)
                Set_Property(@WINDOW,'@EPIPRO_FLAG',1)
                
            CASE TopLabel[1,1] = 'O'
                * EpiPro Silicon or GaN
                TopLabel = TopLabel[2,99]
                WONo     = TopLabel[1, 'F.']
                CassNo   = TopLabel[-1, 'B.']
                WOMatKey = WONo:'*':CassNo
                Set_Property(CtrlEntID, "CELLPOS", TopLabel, PrevSelPos)
                If (Count(TopLabel, '.') EQ 2) then
                    // EpiPro
                    Set_Property(@WINDOW,'@EPIPRO_FLAG',1)
                end else
                    // GaN
                    Set_Property(@WINDOW,'@GAN_FLAG',1)
                end
                
            CASE INDEX(TopLabel,'.',1) AND NOT(INDEX(TopLabel,'.',2))
                * This is a WO_MAT format label
                WOMatKey = TopLabel
                Convert '.' To '*' In WOMatKey
                
            CASE INDEX(TopLabel,'.',2)
                * EpiPRO material indeterminate direction
                WOMatKey = FIELD(TopLabel,'.',1):'*':Field(TopLabel,'.',3)
                Set_Property(@WINDOW,'@EPIPRO_FLAG',1)
                
            CASE 1
                ReactRunRec	= XLATE('REACT_RUN', TopLabel, '', 'X')
                IF ReactRunRec = '' THEN
                    RDSRec = XLATE('RDS',TopLabel,'','X')
                    TestWO = RDSRec<RDS_WO$>
                    CassNo = RDSRec<RDS_CASS_NO$>
                END ELSE
                    TestWO = ReactRunRec<REACT_RUN_WO_NO$>
                    CassNo = ReactRunRec<REACT_RUN_CASS_NO$>
                End
                WOMatKey = TestWO:'*':CassNo
        END CASE
        
        WOMatRec = XLATE('WO_MAT', WOMatKey, '', 'X')
        
        IF (WOMatRec = '') THEN
            Set_Property(CtrlEntID, "CELLPOS", '', PrevSelPos)		;* No corresponding data record found for label scanned bad read or wrong thing scanned
            Set_Property("SYSTEM", "BLOCK_EVENTS", True$)
            Set_Property(CtrlEntID, "SELPOS", PrevSelPos)
            Set_Property("SYSTEM", "BLOCK_EVENTS", False$)
            RETURN
            
        END ELSE
            Set_Property(CtrlEntID, "CELLPOS", FIELD(WOMatKey,'*',1), COL$WOLOGKEY:@FM:PrevRow)
            
            * *  Check for FQA signature completed   * *
            FQASigned = ''
            WorkOrdNo = Field(WOMatKey, '*', 1)
            ReactorType = XLATE('WO_LOG', WorkOrdNo, 'REACT_TYPE', 'X')
            QAStage   = ''
            
            Begin Case
                Case ReactorType EQ 'EPP'
                    QAStage = 'MO_QA'
                Case ReactorType EQ 'GAN'
                    QAStage = 'G_FQA'
                Case Otherwise$
                    QAStage = 'QA'
            End Case

            FQASigned = Signature_Services('CheckSignature', WOMatKey, QAStage)
            
            IF NOT(FQASigned) THEN
                Msg(@WINDOW, '', 'UNSIGNED_CASSETTE')
                Set_Property(CtrlEntID, "CELLPOS", '', PrevSelPos)		;* No corresponding data record found for label scanned bad read or wrong thing scanned
                Set_Property("SYSTEM", "BLOCK_EVENTS", True$)
                Set_Property(CtrlEntID, "SELPOS", PrevSelPos)
                Set_Property("SYSTEM", "BLOCK_EVENTS", False$)
                RETURN
            END
            
            Set_Property(@WINDOW,'@WO_MAT_KEY',WOMatKey)
            Set_Property(@WINDOW,'@WO_MAT_LOT',WOMatRec<WO_MAT_LOT_NO$>)
        END
    END
    
    ********************************
    * Post Prompt for Bottom Label *
    ********************************
    
    TopLabel	= TRIM(Send_Message(CtrlEntID, "TEXT_BY_POS", COL$TOP_LABEL, PrevRow))
    BottomLabel = TRIM(Send_Message(CtrlEntID, "TEXT_BY_POS", COL$BOTTOM_LABEL, PrevRow))
    
    IF BottomLabel[1,2] = '1T' THEN
        BottomLabel = BottomLabel[3,99]
        Set_Property(CtrlEntId,"CELLPOS",BottomLabel,PrevSelPos)
    END
    
    IF ((BottomLabel NE '') AND (PrevCol = COL$BOTTOM_LABEL)) Then
        
        BEGIN CASE
            CASE BottomLabel[1,1] = 'I'
                * WM_IN table
                BottomLabel = BottomLabel[2,99]
                Set_Property(CtrlEntID, "CELLPOS", BottomLabel, PrevSelPos)
                
            CASE BottomLabel[1,1] = 'O'
                * WM_OUT table
                BottomLabel = BottomLabel[2,99]
                Set_Property(CtrlEntID, "CELLPOS", BottomLabel, PrevSelPos)
                
            CASE INDEX(BottomLabel,'.',1) AND NOT(INDEX(BottomLabel,'.',2))
                * This is a WO_MAT format label
                NULL
                
            CASE INDEX(BottomLabel,'.',2)
                * EpiPRO material indeterminate direction
                NULL
                
            CASE 1
                NULL
        END CASE
        
        ************************************
        * Validate the Top & Bottom Labels *
        ************************************
        
        IF (TopLabel NE BottomLabel) THEN
            
            MismatchDetected = True$ /* Mismatch Detected */
            
            void = Utility('BEEP')
            Set_Property(CtrlEntID, "CELLPOS", 'Mismatch', COL$RESULT:@FM:PrevRow)	/* Load Current Location */
            stat = Send_Message(CtrlEntID, 'COLOR_BY_POS', 0, PrevRow, RED$)
            Set_Property("SYSTEM", "BLOCK_EVENTS", True$)
            Set_Property(CtrlEntID, "SELPOS", COL$TOP_LABEL:@FM:PrevRow+1)		/* Move to the next line ready to scan */
            Set_Property("SYSTEM", "BLOCK_EVENTS", False$)
            InsertedPosition = Send_Message(CtrlEntID, "INSERT", -1, '')
            
            TypeOver = ''
            TypeOver<MCAPTION$> = 'FQA Label Mismatch'
            TypeOver<MTEXT$> = CRLF$:'Label ID Mismatch!':CRLF$
            
            OK = Msg(@WINDOW,TypeOver,'LABEL_MISMATCH')
            
            * Inform Quality Insurance that a mismatch has occurred *
            
            Recipients = ''
            OtherRecipients	= XLATE('NOTIFICATION','LABEL_CHECK_FQA',NOTIFICATION_USER_ID$,'X')		;* Added 10/03/2005 JCH - J.C. Henry & Co., Inc  Changed from LABEL_MISMATCH by dkk 11/6/15
            
            FOR N = 1 TO COUNT(OtherRecipients,@VM) + (OtherRecipients NE '')
                OtherRecip = OtherRecipients<1,N>
                LOCATE OtherRecip IN Recipients USING @VM SETTING Pos ELSE
                    Recipients = INSERT(Recipients,1,Pos,0,OtherRecip)
                END
            NEXT N
            
            SentFrom		= @USER4
            Subject			= 'Final QA Label Check Mismatch'
            Message			= 'Cassette Top ID ':QUOTE(TopLabel):' has mismatched Bottom ID ':QUOTE(BottomLabel)'.'
            AttachWindow	= ''
            AttachKey		= ''
            SendToGroup		= ''
            
            Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup
            obj_Notes('Create',Parms)

            
            If Count(TopLabel, '.') then
                // EpiPro Silicon or GaN
                IF TopLabel[1,1] = 'O' THEN TopLabel[1,1] = ''
                IF TopLabel[1,1] = 'I' THEN TopLabel[1,1] = ''
                WONo   = TopLabel[1, 'F.']
                StepNo = 1
                CassNo = TopLabel[-1, 'B.']
                RDSNo  = ''
            end else
                // Non-EpiPro Silicon
                RDSNo = TopLabel
                ReactRunRec = XLATE('REACT_RUN', RDSNo, '', 'X')
                WONo	= ReactRunRec<REACT_RUN_WO_NO$>
                StepNo	= ReactRunRec<REACT_RUN_WO_STEP$>
                CassNo	= ReactRunRec<REACT_RUN_CASS_NO$>
            end
            
            * Setup parameters to WO_Mat_Log method *
            CurrDTM = OCONV(Date(),'D2/'):' ':OCONV(Time(),'MTS')
            UserID = @USER4
            
            LogFile	= 'WO_MAT'		;* Changed so all scans are logged in the WO_MAT table 12/3/2006
            Action	= 'LBLCHK'		;* Final label check for same top and bottom and correct Lot Number on WO_MAT record
            WHCd	= 'CR'			;* Clean room @ final QA
            LocCd	= 'QA'			;* MisMatch - keep the cassette location at Final QA
            
            Set_Status(0)
            obj_WO_Mat_Log('Create',LogFile:@RM:CurrDTM:@RM:Action:@RM:WhCd:@RM:LocCd:@RM:WONo:@RM:CassNo:@RM:UserID:@RM:'Mismatch')
            
            IF Get_Status(errCode) THEN 
                Errmsg(errCode)
            END
        END /* End of check for top & bottom labels check */
    END /* End of check for bottom label available */
    
    **********************
    * Process Lot Number *
    **********************
   
    IF (MismatchDetected = False$) THEN
        
        LotNumber = TRIM(Send_Message(CtrlEntID, "TEXT_BY_POS", COL$LOT_NO, PrevRow))
        
        IF ((TopLabel NE '') AND (BottomLabel NE '') AND (LotNumber = '')) THEN
            
            EpiProFlag = Get_Property(@WINDOW, '@EPIPRO_FLAG')
            GaNFlag    = Get_Property(@WINDOW, '@GAN_FLAG')
            Begin Case
                Case EpiProFlag EQ True$
                    LotNumber = 'EpiPRO'
                    Set_Property(CtrlEntID, "CELLPOS", LotNumber, COL$LOT_NO:@FM:PrevRow)
                Case GaNFlag EQ True$
                    LotNumber = 'GaN'
                    Set_Property(CtrlEntID, "CELLPOS", LotNumber, COL$LOT_NO:@FM:PrevRow)
            End Case
        END
        
        IF ((LotNumber NE '') AND (PrevCol = COL$LOT_NO)) THEN
            
            ***************************
            * Validate the Lot Number *
            ***************************
            
            IF (LotNumber NE 'EpiPRO' and LotNumber NE 'GaN') THEN
                
                IF ((LotNumber[1,2] = '1T') OR (LotNumber[1,2] = '2T')) THEN
                    /* Trim off field identifiers (1T) or (2T) if present - changed by dkk 12/13/16 */
                    LotNumber[1,2] = ''
                    Set_Property(CtrlEntID, "CELLPOS", LotNumber, COL$LOT_NO:@FM:PrevRow)
                END
                
                WOMatKey = Get_Property(@WINDOW,'@WO_MAT_KEY')
                WONo	= WOMatKey[1,'*']
                CassNo	= WOMatKey[COL2()+1,'*']
                
                WOMatLot = Get_Property(@WINDOW,'@WO_MAT_LOT')
                
                * * *   Check for Wales added suffix "-BB" on implant wafers coming back    * * * 
                
                IF (WOMatLot[-3,1] = '-') AND (WOMatLot[-2,1] = WOMatLot[-1,1]) And WOMatLot[-2,2] Matches "2A" THEN
                    IF LotNumber = WOMatLot[1,Len(WOMatLot) - 3] THEN
                        LotNumber := WOMatLot[-3,3]						
                    END
                END ;* End of check for "-AA" type lot suffix added by Wales
                
                IF (LotNumber NE WOMatLot) THEN
                    
                    MismatchDetected = True$ /* Mismatch Detected */
                    
                    void = Utility('BEEP')
                    Set_Property(CtrlEntID, "CELLPOS", 'Mismatch',COL$RESULT:@FM:PrevRow)	/* Load Current Location */
                    stat = Send_Message(CtrlEntID, 'COLOR_BY_POS', 0, PrevRow,RED$)
                    Set_Property("SYSTEM", "BLOCK_EVENTS", True$)
                    Set_Property(CtrlEntID, "SELPOS", COL$TOP_LABEL:@FM:PrevRow+1)		/* Move to the next line ready to scan */
                    Set_Property("SYSTEM", "BLOCK_EVENTS", False$)
                    InsertedPosition = Send_Message(CtrlEntID, "INSERT", -1, '')
                    
                    TypeOver = ''
                    TypeOver<MCAPTION$> = 'FQA Label Mismatch'
                    TypeOver<MTEXT$> = CRLF$:'Lot No. Mismatch!':CRLF$
                    
                    OK = Msg(@WINDOW,TypeOver,'LABEL_MISMATCH')
                    
                    /* Inform Quality Insurance that a mismatch has occurred */
                    
                    Recipients		= ''
                    OtherRecipients	= XLATE('NOTIFICATION','LABEL_CHECK_FQA',NOTIFICATION_USER_ID$,'X')		;* Added 10/03/2005 JCH - J.C. Henry & Co., Inc  Changed from LABEL_MISMATCH by dkk 11/6/15
                    
                    FOR N = 1 TO COUNT(OtherRecipients,@VM) + (OtherRecipients NE '')
                        OtherRecip = OtherRecipients<1,N>
                        LOCATE OtherRecip IN Recipients USING @VM SETTING Pos ELSE
                            Recipients = INSERT(Recipients,1,Pos,0,OtherRecip)
                        END
                    NEXT N
                    
                    SentFrom		= @USER4
                    Subject			= 'Final QA Label Check Mismatch'
                    Message			= 'Cassette ':QUOTE(TopLabel):' has incorrect Lot No ':QUOTE(LotNumber)'.'
                    AttachWindow	= ''
                    AttachKey		= ''
                    SendToGroup		= ''
                    
                    Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup
                    obj_Notes('Create',Parms)
                    
                    CurrDTM = OCONV(Date(),'D2/'):' ':OCONV(Time(),'MTS')
                    UserID = @USER4
                    
                    LogFile	= 'WO_MAT'		;* Changed so all scans are logged in the WO_MAT table 12/3/2006
                    Action	= 'LBLCHK'		;* Final label check for same top and bottom and correct Lot Number on WO_MAT record
                    WHCd	= 'CR'			;* Clean room @ final QA
                    LocCd	= 'QA'			;* MisMatch - keep the cassette location at Final QA
                    
                    Set_Status(0)
                    obj_WO_Mat_Log('Create',LogFile:@RM:CurrDTM:@RM:Action:@RM:WhCd:@RM:LocCd:@RM:WONo:@RM:CassNo:@RM:UserID:@RM:'Mismatch')
                    
                    IF Get_Status(errCode) THEN 
                        Errmsg(errCode)
                    END
                    
                END ELSE
                    NULL
                END /* End of check for LotNumber and WOMatLot matching */
                
            END ELSE
                NULL
            END /* End of check for EpiPro lot */
            
        END /* End of check for lot number validation */
        
    END
    
    ********************************
    * Validate Scanned Information *
    ********************************
    
    IF (MismatchDetected = False$) THEN
        
        /* Read scanned information from edit table */
        TopLabel    = TRIM(Send_Message(CtrlEntID, "TEXT_BY_POS", COL$TOP_LABEL, PrevRow))
        BottomLabel = TRIM(Send_Message(CtrlEntID, "TEXT_BY_POS", COL$BOTTOM_LABEL, PrevRow))
        LotNumber   = TRIM(Send_Message(CtrlEntID, "TEXT_BY_POS", COL$LOT_NO, PrevRow))
        //IFXLabel	= TRIM(Send_Message(CtrlEntID, "TEXT_BY_POS", COL$IFX_LABEL, PrevRow))
        
        IF ((TopLabel NE '') AND (BottomLabel NE '') AND (LotNumber NE '')) THEN ;//AND (IFXValid = 1) AND (IFXLabel NE '')) THEN
            
            ********************************
            * FQA Labels Validation = GOOD *
            ********************************
            
            Set_Property(CtrlEntID, "CELLPOS", 'OK', COL$RESULT:@FM:PrevRow)
            stat = Send_Message(CtrlEntID, "COLOR_BY_POS", 0, PrevRow,GREEN$)
            Set_Property("SYSTEM", "BLOCK_EVENTS", True$)
            Set_Property(CtrlEntID, "SELPOS", COL$TOP_LABEL:@FM:PrevRow+1)		/* Move to the next line ready to scan */
            Set_Property("SYSTEM", "BLOCK_EVENTS", False$)
            InsertedPosition = Send_Message(CtrlEntID, "INSERT", -1, '')
            
            * Add transaction to Posting system to time-stamp WO_MAT record
            ! 10/28/2019 - DJS & Dan Crisp
            ! This transaction is moving to Packaging_Services and is triggered by
            ! the NDW_PACKAGING form upon a successful scan sequence.
            
            IF Count(TopLabel, '.') THEN
                IF TopLabel[1,1] = 'O' THEN TopLabel[1,1] = ''
                IF TopLabel[1,1] = 'I' THEN TopLabel[1,1] = ''
                WONo       = TopLabel[1, 'F.']
                StepNo     = 1
                CassNo     = TopLabel[-1, 'B.']
                RDSNo      = ''
            end else
                RDSNo = TopLabel
                ReactRunRec = XLATE('REACT_RUN',RDSNo,'','X')
                WONo	= ReactRunRec<REACT_RUN_WO_NO$>
                StepNo	= ReactRunRec<REACT_RUN_WO_STEP$>
                CassNo	= ReactRunRec<REACT_RUN_CASS_NO$>
            END
            
            CurrDTM = OCONV(Date(),'D2/'):' ':OCONV(Time(),'MTS')
            UserID = @USER4
            
            LogFile	= 'WO_MAT'		;* Changed so all scans are logged in the WO_MAT table 12/3/2006
            Action	= 'LBLCHK'		;* Final label check for same top and bottom and correct Lot Number on WO_MAT record
            WHCd	= 'CR'			;* Clean room @ final QA
            LocCd	= 'PKO'			;* QA wants this to "place" the cassette into the outbound passthrough
            
            Set_Status(0)
            obj_WO_Mat_Log('Create',LogFile:@RM:CurrDTM:@RM:Action:@RM:WhCd:@RM:LocCd:@RM:WONo:@RM:CassNo:@RM:UserID:@RM:'Match')
            
            IF Get_Status(errCode) THEN 
                Errmsg(errCode)
            END
            
        END /* End of check for all information available to be checked*/
        
    END

    If NextRow EQ 2 then GoSub RefreshForm
    
end event


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Internal GoSubs
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

SetupOLEControls:
    
    NumCols          = 4
    NumRows          = 26
    StageIDs         = Database_Services('ReadDataRow', 'APP_INFO', 'SILICON_STAGE_LIST')
    CtrlList         = Xlate('STAGE', StageIDs, 'DESC', 'X')
    StageCtrl        = @Window:'.OLE_EDT_STAGES'
    HeaderFontArray  = 'Segoe UI':@SVM:8:@SVM:700
    HeaderColArray   = 40:@FM:False$:@FM:False$:@FM:False$
    HeaderAlignArray = 'Center':@FM:'Center':@FM:'Center'
    DimArray         = NumCols:@FM:NumRows
    HeaderTitles     = 'Stage':@VM:'Data':@VM:'Signature':@VM:'Sign'
    DataColArray     = 120:@FM:True$:@FM:True$:@FM:True$:@FM:False$
    
    Set_Property(StageCtrl, "OLE.CellFont[All; All]", 'Segoe UI':@SVM:8)
    Set_Property(StageCtrl, "OLE.Dimension", DimArray)
    Set_Property(StageCtrl, "OLE.CellFont[1;All]", HeaderFontArray)
    Set_Property(StageCtrl, "OLE.LIST", CtrlList)
    Set_Property(StageCtrl, "OLE.HeaderFont[All; 1]", HeaderFontArray)
    Set_Property(StageCtrl, "OLE.HeaderFont[1; All]", HeaderFontArray)
    Set_Property(StageCtrl, "OLE.TitleList", HeaderTitles)
    Set_Property(StageCtrl, "OLE.AllowDeletions", False$)
    Set_Property(StageCtrl, "OLE.AllowInserts", False$)
    Set_Property(StageCtrl, "OLE.HeaderColumn[1]", HeaderColArray)
    Set_Property(StageCtrl, "OLE.HeaderAlignment[All; 1]", HeaderAlignArray)
    Set_Property(StageCtrl, "OLE.DataColumn[1]", DataColArray)
    DataColArray<1> = 60
    DataColArray<4> = False$
    Set_Property(StageCtrl, "OLE.DataColumn[2-4]", DataColArray)
    CellAlignArray  = 'Center':@FM:'Center':@FM:'Center'
    Set_Property(StageCtrl, "OLE.CellAlignment[4; All]", CellAlignArray)
    
    // Qualify OLE events that we want to intercept
    Qualifier = ''
    Qualifier<1> = 1
    Qualifier<4> = 0 ; * process synchronously (i.e. immediately)
    Send_Message(StageCtrl,  'QUALIFY_EVENT', 'OLE.OnButtonClick', Qualifier)
    Send_Message(StageCtrl,  'QUALIFY_EVENT', 'OLE.OnCheckChanged', Qualifier)
    Send_Message(@Window:'.OLE_BTN_REFRESH', 'QUALIFY_EVENT', 'OLE.OnClick', Qualifier)
    
    // Stage cell button style setup
    ButtonTypeArray       = ''
    ButtonTypeArray<1>    = 'Push Button'
    ButtonTypeArray<2>    = ''
    ButtonTypeArray<2, 1> = False$
    ButtonTypeArray<2, 2> = True$
    ButtonTypeArray<2, 3> = True$
    ButtonTypeArray<3>    = 'None'
    ButtonTypeArray<4>    = "Vertical(Gradient(":OI_HOT_BLUE$:", ":OI_HOT_BLUE$:"), Border(":OI_BLUE$:"))"
    ButtonTypeArray<5>    = "Vertical(Gradient(":OI_CLICK_BLUE$:", ":OI_CLICK_BLUE$:"), Border(":OI_BLUE$:"))"
    ButtonTypeArray<6>    = 'OD'
    ButtonTypeArray<7>    = 'None'
    Set_Property(StageCtrl, "OLE.CellType[1; All]", ButtonTypeArray)
    
return


EnableRefreshButton:
    
    RDSNo   = Get_Property(@Window:'.EDL_RDS_NO', 'TEXT')
    If RDSNo[1, 2] EQ '1T' then
        RDSNo = RDSNo[3, 999]
        Set_Property(@Window:'.EDL_RDS_NO', 'TEXT', RDSNo)
    end
    If RDSNo NE '' then
        Enabled = RowExists('RDS', RDSNo)
    end else
        Enabled = False$
    end
    Set_Property(@Window:'.OLE_BTN_REFRESH', 'ENABLED', Enabled)
    
return


EnableAutoSignButton:
    
    ChkVals    = Get_Property(@Window:'.OLE_EDT_STAGES', "OLE.CellCheck[4; All]")
    Enabled    = Sum(ChkVals)
    Set_Property(@Window:'.PUB_AUTO_SIGN', 'ENABLED', Enabled)
    
return


EnableOtherButtons:
    
    RDSNo   = Get_Property(@Window:'.EDL_RDS_NO', 'TEXT')
    Enabled = (RDSNo NE '')
    Set_Property(@Window:'.CTRL_PLAN', 'ENABLED', Enabled)
    Set_Property(@Window:'.PUB_SAVE', 'ENABLED', Enabled)
    Set_Property(@Window:'.PUB_CLEAR_FORM', 'ENABLED', Enabled)
    
return


RefreshForm:
    
    RDSNo = Get_Property(@Window:'.EDL_RDS_NO', 'TEXT')
    If RDSNo NE '' then
        If RDSNo[1,2] EQ '1T' then RDSNo[1,2] = ''
        Set_Property(@Window:'.EDL_RDS_NO', 'TEXT', RDSNo)
        ReactorType = Xlate('RDS', RDSNo, 'REACTOR_TYPE', 'X')
        Begin Case
            Case ReactorType EQ 'EPP'
                ErrMsg('EpiPro runs are not supported by this form at this time!')
                Set_Property(@Window:'.EDL_RDS_NO', 'FOCUS', True$)
                Set_Property(@Window:'.EDL_RDS_NO', 'SELECTION', 1:@FM:999)
            Case ReactorType EQ 'GAN'
                ErrMsg('GaN runs are not supported by this form!')
                Set_Property(@Window:'.EDL_RDS_NO', 'FOCUS', True$)
                Set_Property(@Window:'.EDL_RDS_NO', 'SELECTION', 1:@FM:999)
            Case RowExists('RDS', RDSNo)
                GoSub ClearLblChkEDT
                Def              = ""
                Def<MTEXT$>      = "Loading stage data. Please wait..."
                Def<MTYPE$>      = "U"
                MsgUp            = Msg(@Window, Def)   ;* display the processing message
                WOMatKey         = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X')
                CassSummary      = Signature_Services('GetCassSummary', WOMatKey)
                CassSummaryPrime = SRP_Array('Rotate', CassSummary, @FM, @VM)
                ArrayData        = Get_Property(@Window:'.OLE_EDT_STAGES', 'OLE.ARRAY')
                StageIDs         = Database_Services('ReadDataRow', 'APP_INFO', 'SILICON_STAGE_LIST')
                StageDescs       = Xlate('STAGE', StageIDs, 'DESC', 'X')
                ColorArray       = ''
                DataList         = ''
                ChkBoxList       = ''
                
                Set_Property(@Window, '@STAGE_ID_LIST', StageIDs)
                Set_Property(@Window, '@STAGE_DESC_LIST', StageDescs)
                
                For each Row in CassSummary using @FM setting fPos
                    StageID       = Row<0, SS_STAGE$>
                    StageDesc     = StageDescs<0, fPos>
                    StagePass     = Row<0, SS_PASS$>
                    StageSigComp  = Row<0, SS_SIG$>
                    StageDataComp = Row<0, SS_DATA$>
                    StageNA       = Row<0, SS_NA$>
                    
                    ChkBoxList<fPos> = False$
                    Begin Case
                        Case StagePass
                            ColorArray<fPos, 1> = GREEN$
                            ColorArray<fPos, 2> = BGREEN$
                        Case StageDataComp and Not(StageSigComp)
                            ColorArray<fPos, 1> = YELLOW$
                            ColorArray<fPos, 2> = BYELLOW$
                            ChkBoxList<fPos>    = True$
                        Case Not(StagePass) and Not(StageNA)
                            ColorArray<fPos, 1> = RED$
                            ColorArray<fPos, 2> = BRED$
                        Case Otherwise$
                            ColorArray<fPos, 1> = GREY$
                            ColorArray<fPos, 2> = LTGREY$
                    End Case
                    Begin Case
                        Case StageDataComp
                            DataList<fPos, 2>   = 'Complete'
                            ColorArray<fPos, 3> = GREEN$
                        Case Not(StageDataComp) and Not(StageNA)
                            DataList<fPos, 2>   = 'Missing'
                            ColorArray<fPos, 3> = YELLOW$
                        Case Otherwise$
                            DataList<fPos, 2>   = 'N/A'
                            ColorArray<fPos, 3> = 'None'
                    End Case
                    Begin Case
                        Case StageSigComp
                            DataList<fPos, 3>   = 'Complete'
                            ColorArray<fPos, 4> = GREEN$
                        Case Not(StageSigComp) and Not(StageNA)
                            DataList<fPos, 3>   = 'Missing'
                            ColorArray<fPos, 4> = YELLOW$
                        Case Otherwise$
                            DataList<fPos, 3>   = 'N/A'
                            ColorArray<fPos, 4> = 'None'
                    End Case
                Next Row
                Set_Property(@Window:'.OLE_EDT_STAGES', "OLE.CellCheck[4; All]", False$)
                Set_Property(@Window, '@CHK_BOX_LIST', ChkBoxList)
                Set_Property(@Window, '@DATA_LIST', DataList)
                Set_Property(@Window, '@COLOR_ARRAY', ColorArray)
                GoSub PopulateCells
                GoSub ColorCells
                GoSub EnableChkBoxes
                GoSub EnableAutoSignButton
                GoSub EnableOtherButtons
                GoSub UpdateHoldLabel
                GoSub ColorControls
                Send_Event(@Window, 'READ')
                Msg(@Window, MsgUp)      ;* Take message down
            Case Otherwise$
                ErrMsg('RDS ':RDSNo:' does not exist!.')
                Set_Property(@Window:'.EDL_RDS_NO', 'FOCUS', True$)
                Set_Property(@Window:'.EDL_RDS_NO', 'SELECTION', 1:@FM:999)
        End Case
    end
    
return


ColorCells:
    
    ColorArray = Get_Property(@Window, '@COLOR_ARRAY')
    If ColorArray NE '' then
        StageCtrl = @Window:'.OLE_EDT_STAGES'
        For each Row in ColorArray using @FM setting fPos
            // Column 1 - Stage Name
            BackColor        = Row<0, 1>
            If BackColor EQ '' then BackColor = 'None'
            HotBackColor     = Row<0, 2>
            If HotBackColor EQ '' then HotBackColor = 'None'
            CellTypeArray    = Get_Property(StageCtrl, 'OLE.CellType[1;':fPos:']')
            CellTypeArray<3> = BackColor
            CellTypeArray<4> = HotBackColor
            Set_Property(StageCtrl, 'OLE.CellType[1;':fPos:']', CellTypeArray)
            For Col = 2 to 3
                BackColor         = Row<0, Col + 1>
                CellColorArray    = Get_Property(StageCtrl, 'OLE.CellColors[':Col:';':fPos:']')
                CellColorArray<2> = BackColor
                Set_Property(StageCtrl, 'OLE.CellColors[':Col:';':fPos:']', CellColorArray)
            Next Col
        Next Row
    end
    
return


ColorControls:

    WafersOut       = Get_Property(@Window:'.WAFERS_OUT', 'TEXT')
    WafersScheduled = Get_Property(@Window:'.WAFERS_SCHEDULED', 'TEXT')
    
    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)
    
    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)
    
return


PopulateCells:
    
    DataList = Get_Property(@Window, '@DATA_LIST')
    If DataList NE '' then
        StageCtrl = @Window:'.OLE_EDT_STAGES'
        For each Row in DataList using @FM setting fPos
            For Col = 2 to 3
                CellText = DataList<fPos, Col>
                Set_Property(StageCtrl, 'OLE.CellText[':Col:';':fPos:']', CellText)
            Next Col
        Next Row
    end
    
return


EnableChkBoxes:
    
    ChkBoxList = Get_Property(@Window, '@CHK_BOX_LIST')
    If ChkBoxList NE '' then
        StageCtrl = @Window:'.OLE_EDT_STAGES'
        For each Row in ChkBoxList using @FM setting fPos
            ChkBoxEnabled = Row<0, 1>
            If ChkBoxEnabled then
                CellColorArray    = Get_Property(StageCtrl, 'OLE.CellColors[4;':fPos:']')
                CellColorArray<2> = 'None'
                Set_Property(StageCtrl, 'OLE.CellColors[4;':fPos:']', CellColorArray)
                CellTypeArray     = 'CHB':@FM:True$
                Set_Property(StageCtrl, "OLE.CellType[4;":fPos:"]", CellTypeArray)
                Set_Property(StageCtrl, "OLE.CellProtection[4;":fPos:"]", 'None')
            end else
                CellColorArray    = Get_Property(StageCtrl, 'OLE.CellColors[4;':fPos:']')
                CellColorArray<2> = GREY$
                Set_Property(StageCtrl, 'OLE.CellColors[4;':fPos:']', CellColorArray)
                Set_Property(StageCtrl, "OLE.CellType[4;":fPos:"]", 'TEXT')
                Set_Property(StageCtrl, "OLE.CellProtection[4;":fPos:"]", 'Full')
            end
        Next Row
    end
    
return


UpdateHoldLabel:
    
    Ctrl   = @Window:'.LBL_HOLD'
    RDSNo  = Get_Property(@Window:'.EDL_RDS_NO', 'TEXT')
    OnHold = Xlate('RDS', RDSNo, 'HOLD', 'X')
    If OnHold then
        // Set label to "On Hold" and set text color to red
        Set_Property(Ctrl, 'TEXT', 'On Hold')
        Set_Property(Ctrl, 'FORECOLOR', BRED$)
    end else
        // Set label to "Off Hold" and set text color to green
        Set_Property(Ctrl, 'TEXT', 'Off Hold')
        Set_Property(Ctrl, 'FORECOLOR', BGREEN$)
    end
    
return


OpenCleanInsp:
    
    DetWindow  = 'CLEAN_INSP'
    DetKeys    = CINo
    DefaultRec = ''
    RetKey     = RDSNo
    RetWin     = CtrlEntID
    RetPage    = 1
    RetCtrl    = 'OLE_EDT_STAGES'
    RetPos     = ''
    obj_Appwindow('ViewNewDetail',DetWindow:@RM:DetKeys:@RM:DefaultRec:@RM:RetKey:@RM:RetPage:@RM:RetCtrl:@RM:RetPos)
    Set_Property(DetWindow, '@SKIP_RETURN', True$)
    
return


OpenWOMatWfr:
    
    DetWindow  = 'WO_MAT_WFR'
    DetKeys    = WOMatKey
    DefaultRec = ''
    RetKey     = RDSNo
    RetWin     = ''
    RetPage    = 1
    RetCtrl    = ''
    RetPos     = ''
    obj_Appwindow('ViewNewDetail',DetWindow:@RM:DetKeys:@RM:DefaultRec:@RM:RetKey:@RM:RetPage:@RM:RetCtrl:@RM:RetPos)
    Set_Property(DetWindow, '@SKIP_RETURN', True$)
    Set_Property(DetWindow, 'VISIBLE', True$)
    
return


ClearLblChkEDT:
    
    List       = ''
    List<3, 4> = ''
    Set_Property(@Window:'.CASS_IDS', 'LIST', List)
    
return


ClearForm:

    NumCols  = 4
    NumRows  = 26
    DataList = ''
    For Row = 1 to NumRows
        DataList<Row, NumCols> = ''
    Next Row
    ColorList = ''
    For Row = 1 to NumRows
        For Col = 1 to NumCols
            ColorList<Row, Col> = 'None'
        Next Col
    Next Row
    ChkList = ''
    For Row = 1 to NumRows
        For Col = 1 to NumCols
            ChkList<Row, Col> = False$
        Next Col
    Next Row
    Set_Property(@Window:'.OLE_EDT_STAGES', "OLE.CellCheck[4; All]", False$)
    Set_Property(@Window, '@CHK_BOX_LIST', ChkList)
    Set_Property(@Window, '@DATA_LIST', DataList)
    Set_Property(@Window, '@COLOR_ARRAY', ColorList)
    GoSub PopulateCells
    GoSub ColorCells
    GoSub EnableChkBoxes
    GoSub EnableAutoSignButton
    GoSub UpdateHoldLabel
    GoSub ColorControls
    GoSub ClearLblChkEDT
    GoSub EnableRefreshButton
    GoSub EnableOtherButtons
    
return

