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

    Name        :   NDW_WO_LOG_Events

    Description :   Commuter module for the NDW_WO_LOG form.

    Notes       :   Application errors should be logged using the Error Services module. There are a few methodological
                    assumptions built into way errors are managed which are important to understand in order to properly
                    work with Error Services:

                    - The term 'top' refers to the originating procedure of a call stack and the term 'bottom' refers to
                      the last routine (or the current routine) within a call stack. Within the OpenInsight Debugger
                      this will appear backwards since the originating procedure always appears at the bottom of the
                      list and the current routine appears at the top of the list. We are using this orientation because
                      it is common to refer to the process of calling other procedures as 'drilling down'.

                    - The reason for defining the orientation of the call stack is because Error_Services allows for
                      multiple error conditions to be appended to an original error. In most cases this will happen when
                      a procedure at the bottom of the stack generates an error condition and then returns to its
                      calling procedure. This higher level procedure can optionally add more information relevant to
                      itself. This continues as the call stack 'bubbles' its way back to the top to where the
                      originating procedure is waiting.

                    - Native OpenInsight commands that handle errors (e.g., Set_Status, Set_FSError, Set_EventStatus)
                      preserve their error state until explicitly cleared. This can hinder the normal execution of code
                      since subsequent procedures (usually SSPs) will fail if a pre-existing error condition exists.
                      Our philosophy is that error conditions should automatically be cleared before a new procedure
                      is executed to avoid this problem. However, the nature of Basic+ does not make this easy to
                      automate for any given stored procedure. Therefore, if a stored procedure wants to conform to our
                      philosophy then it should include a call into the 'Clear' service request at the top of the
                      program. Alternatively this can be done through a common insert (see SERVICE_SETUP for example.)

                    - Service modules will use the SERVICE_SETUP insert and therefore automatically clear out any
                      error conditions that were set before.

    Parameters  :
        Service         [in] -- Name of the service being requested
        Param1-10   [in/out] -- Additional request parameter holders
        Response       [out] -- Response to be sent back to the Controller (MCP) or requesting procedure

    Metadata    :

    History     :   (Date, Initials, Notes)
        05/17/2021    djs     Original programmer.

***********************************************************************************************************************/
#pragma precomp SRP_PreCompiler
#window NDW_WO_LOG

$Insert EVENT_SETUP
$Insert APP_INSERTS
$Insert MSG_EQUATES
$Insert POPUP_EQUATES
$Insert DICT_EQUATES
$Insert NOTIFICATION_EQUATES
$Insert WO_LOG_EQUATES
$Insert PROD_VER_EQUATES
$Insert CUST_EPI_PART_EQUATES
$Insert WM_IN_EQUATES
$Insert WO_MAT_EQUATES
$Insert SECURITY_RIGHTS_EQU
$Insert COMPANY_EQUATES
$Insert EPI_PART_EQUATES
$Insert LSL_USERS_EQU
$Insert PROD_SPEC_EQU
$Insert QUOTE_EQU
$Insert QUOTE_DET_EQU
$Insert QUOTE_SIGS_EQU
$Insert REACT_RUN_EQUATES
$Insert WM_OUT_EQUATES
$Insert ORDER_EQU
$Insert ORDER_DET_EQU
$Insert RLIST_EQUATES
$Insert WO_STEP_EQUATES
$Insert RDS_EQUATES
$Insert IFX_EQUATES

EQU COL$QUOTE_DESC		TO 1
EQU COL$SETUP_CHG		TO 4
EQU COL$SRP_CHG			TO 5
EQU COL$WAFER_PRICE		TO 6

EQU COL$ADD_DESC			TO 1
EQU COL$ADD_AMT				TO 2

EQU COL$CASS_NO				TO 1
EQU COL$LOT_NO				TO 2
EQU COL$QTY					TO 3
EQU COL$SUB_PART_NO			TO 4
EQU COL$VEND_CD				TO 5
EQU COL$EPI_PART_NO			TO 6
EQU COL$RX_DTM				TO 7
EQU COL$REL_DTM				TO 8
EQU COL$CURR_STATUS			TO 9
EQU COL$SAP_TX_DTM			TO 10
EQU COL$SAP_BATCH_NO		TO 11
EQU COL$CASS_ID_SAP			TO 12
EQU COL$SAP_YIELD			TO 13
EQU COL$SAP_CONFIRM_SCRAP	TO 14
EQU COL$SAP_GR_QTY			TO 15
EQU COL$SAP_RAW_SCRAP_QTY	TO 16
EQU COL$SAP_PROD_TEST_QTY	TO 17
EQU COL$SAP_MU_QTY			TO 18

EQU COL$STEP			TO 1
EQU COL$PSN				TO 2
EQU COL$DOPANT			TO 3
EQU COL$THICK			TO 4
EQU COL$THICK_UNITS		TO 5
EQU COL$RESIST			TO 6
EQU COL$RESIST_UNITS	TO 7
EQU COL$DESC			TO 8
EQU COL$STEP_STATUS		TO 9
EQU COL$STEP_SCHED		TO 10
EQU COL$STEP_SCHED_DTM	TO 11

EQU COMMA$ to ','

Declare subroutine Errmsg, Btree.Extract, Set_Status, Logging_Services, Work_Order_Services, Start_Window, obj_WO_Log
Declare subroutine obj_Notes, Comm_Customer_Epi, Print_WO, obj_WO_Mat, obj_WM_In, obj_WO_Mat, obj_RDS, Msg, PlaceDialog
Declare subroutine Security_Err_Msg, obj_WM_Out, Database_Services, End_Window, Print_Shelf_Label, Signature_Services
Declare Subroutine  Service_Services
Declare function   obj_WO_Log, Work_Order_Services, Environment_Services, Logging_Services, Memberof, NextKey
Declare function   Database_Services, Unassigned, obj_WO_Mat, obj_RDS, Security_Check, obj_WM_Out, Error_Services

LogPath       = Environment_Services('GetApplicationRootPath') : '\LogFiles\WO_LOG'
LogDate       = Oconv(Date(), 'D4/')
LogTime       = Oconv(Time(), 'MTS')
LogFileName   = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' Release Log.csv'
Headers       = 'Logging DTM' : @FM : 'User' : @FM : 'Notes'
objReleaseLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, COMMA$, Headers, '', False$, False$)
LoggingDTM    = LogDate : ' ' : LogTime   ; // Logging DTM

// 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 else
    // Event not implemented
end

Return EventFlow or 1

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


Event WINDOW.CREATE(CreateParam)

    If RowExists('WO_LOG', CreateParam) then
        Set_Property(@Window:'.EDL_WO_NO', 'TEXT', CreateParam)
        Post_Event(@Window, 'READ')
    end
    PlaceDialog(-2, -2)
    
End Event


Event WINDOW.READ()
    
    WONo = Get_Property(@Window:'.EDL_WO_NO','TEXT')
    Set_Property(@Window, '@WO_NO', WONo)
    IF RowExists('WO_LOG',WONo) THEN
        IF Security_Check('WO Log',READ$) THEN
        
            IF NOT(Security_Check('WO Log',EDIT$)) THEN Set_Property(@Window, '@READ_ONLY', True$)
            GoSub PopulateControls
            
        end else
            Send_Event(@Window,'CLEAR')
            Security_Err_Msg('Work Order',READ$)
        END

    END ELSE
        ErrMsg('Work Order Log entries may only be created from the ORDER window.')
        Send_Event(@Window,'CLEAR')
    END

end event


Event WINDOW.WRITE()

    ReadOnly = Get_Property(@Window, '@READ_ONLY')
    If ReadOnly NE True$ then
        ErrorMsg = ''
        Ctrls    = @WINDOW:'.EDL_COMMIT_DT':@RM			; Props  = 'DEFPROP':@RM
        Ctrls   := @WINDOW:'.EDL_WO_NO':@RM				; Props := 'DEFPROP':@RM
        Ctrls   := @WINDOW:'.EDL_ORDER_NO':@RM			; Props := 'DEFPROP':@RM
        Ctrls   := @WINDOW:'.EDL_PROD_ORD_NO':@RM		; Props := 'DEFPROP':@RM
        Ctrls   := @WINDOW:'.EDL_CUST_PART_NO':@RM		; Props := 'DEFPROP':@RM
        Ctrls   := @WINDOW:'.CHB_CUST_CAPTIVE':@RM		; Props := 'CHECK':@RM
        Ctrls   := @WINDOW:'.EDL_CLOSE_DT':@RM			; Props := 'DEFPROP':@RM
        Ctrls   := @WINDOW:'.EDL_WO_STOP_DTM':@RM		; Props := 'DEFPROP':@RM
        Ctrls   := @WINDOW:'.EDL_PROD_VER_NO'			; Props := 'DEFPROP'
        
        Vals = Get_Property(Ctrls,Props)
        
        PromiseDt	= Vals[1,@RM]
        WONo		= Vals[COL2()+1,@RM]
        OrderNo		= Vals[COL2()+1,@RM]
        ProdOrdNo	= Vals[COL2()+1,@RM]
        CustPartNo	= Vals[COL2()+1,@RM]
        CustCaptive	= Vals[COL2()+1,@RM]
        CloseDt		= Vals[COL2()+1,@RM]
        WOStopDTM	= Vals[COL2()+1,@RM]
        ProdVerNo	= Vals[COL2()+1,@RM]
        
        IF WOStopDTM = '' AND CloseDt NE '' THEN
            CurrDTM = OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTH')
            Set_Property(@WINDOW:'.EDL_WO_STOP_DTM','TEXT',CurrDTM)
        END
        
        IF ProdOrdNo[1,1] NE 'M' AND CustPartNo = '' AND ProdVerNo NE '' THEN
            ErrorMsg = 'Part No in Non SAP Group is required.'
            ErrMsg(ErrorMsg)
            Set_Property(@WINDOW:'.EDL_CUST_PART_NO','BACKCOLOR',RED$)
        END
        
        If ErrorMsg EQ '' then
        
            IF ( (PromiseDt NE '') AND (WONo NE '') AND (OrderNo NE '')	AND (ProdOrdNo = '') ) THEN 
                
                VisionOrderNo = XLATE('ORDER',OrderNo,ORDER_VISION_ORDER_NO$,'X')
                IF VisionOrderNo = '' THEN
                    Result = 1
                    RETURN
                END
                OrgWOLogRec = XLATE('WO_LOG',WONo,'','X')
                
                PrevPromiseDt = OCONV(OrgWOLogRec<WO_LOG_COMMIT_DATE$>,'D4/')
                PrevCycleTime = OrgWOLogRec<WO_LOG_CYCLE_TIME$>
                
                IF PromiseDt NE PrevPromiseDt THEN
                    
                    Reason = Msg(@WINDOW,'','PROMISE_DT_REASON')
                    
                    IF Reason = CHAR(27) THEN
                        Set_Property(@WINDOW:'.COMMIT_DT','DEFPROP',PrevPromiseDt)
                        Set_Property(@WINDOW:'.CYCLE_TIME','VALUE',PrevCycleTime)
                        Msg('Promise Date will not be changed.')
                    END ELSE
                        
                        VisionOrderNo = XLATE('ORDER',OrderNo,ORDER_VISION_ORDER_NO$,'X')
                        
                        OrderItems = Get_Property(@WINDOW:'.ORDER_ITEMS','DEFPROP')<1>
                        
                        LOOP
                            TestLine = OrderItems[-1,'B':@VM]
                        UNTIL TestLine NE '' OR OrderItems = ''
                            OrderItems[COL1(),COL2()] = ''
                        REPEAT
                        
                        Def = ""
                        Def<MTEXT$> = "Updating Promise Ship Date on RDS records..."
                        Def<MTYPE$> = "U"
                        
                        MsgUp = Msg(@window, Def)
                        
                        obj_WO_Log('SetPromiseDt',OrderNo:@RM:OrderItems:@RM:WONo:@RM:PromiseDt:@RM:Reason)
                        
                        Msg(@window, MsgUp)
                    END ;* End of prompt for change reason
                    
                END	;* End of check for changed Promise Date
                
            END	;* End of check for fields required to update Promise Date
            
            GoSub SaveData
        end
        
    end else
        Security_Err_Msg('Work Order', Write$)
    end
    
end event


Event WINDOW.CLEAR(bSaveKey, bSuppressWarning, bMaintainFocus, CtrlIDFocus)
    
    Set_Property(@WINDOW:'.EDL_CUST_PART_NO','BACKCOLOR',WHITE$)
    Set_Property(@WINDOW:'.TAB_MAIN','VALUE',1)
    Send_Event(@WINDOW,'PAGE',1)
    Set_Property(@Window, '@READ_ONLY', False$)
    Set_Property(@Window, '@WO_NO', '')
    GoSub ClearControls
    
end event


Event WINDOW.DELETE()
    
    IF NOT(Security_Check('WO Log',Delete$)) THEN
        Security_Err_Msg('WO Log',Delete$)
        RETURN
    END
    
    WONo = Get_Property(@WINDOW:'.EDL_WO_NO','TEXT')
    IF WONo NE '' THEN
        
        obj_WO_Log('Delete',WONo)						;* Removes WO_LOG record from system
        errCode = ''
        IF Get_Status(errCode) THEN
            ErrMsg(errCode)
            RETURN
        END
    END
    
    Post_Event(@WINDOW,'CLEAR')
    
    Set_Property(@Window, '@READ_ONLY', False$)
    
end event


Event WINDOW.CLOSE(CancelFlag)

    SaveFlag   = False$
    SaveWarn   = Get_Property(@Window, '@SAVEWARN')
    If SaveWarn EQ True$ then
        Response = MSG(@Window, '', 'SAVEWARN')
        Begin Case
            Case Response EQ 1
                // Yes
                SaveFlag = True$
            Case Response EQ 2
                // No
                Null
            Case Response EQ 3
                // Cancel
                CancelFlag = True$
        End Case
    end
    If SaveFlag then GoSub SaveData
    If CancelFlag NE True$ then End_Window(@Window)
    
end event


Event EDL_WO_QTY.CHANGED(NewData)

    If NewData NE '' then
        Swap ',' with '' in NewData
        NewQty   = NewData
        CtrlName = Field(CtrlEntID,'.',2)
        Set_Property(@Window:'.':CtrlName:'_1', 'TEXT', NewData)
        WONo        = Get_Property(@Window:'.EDL_WO_NO', 'TEXT')
        If WONo NE '' then
            OrigWOQty   = Xlate('WO_LOG', WONo, 'WO_QTY', 'X')
            Diff        = OrigWOQty - NewQty
            RefreshCtrl = @Window:'.EDL_UNREL_QTY'
            UnrelQty    = Xlate('WO_LOG', WONo, 'UNREL_QTY', 'X')
            If Diff NE 0 then
                Swap ',' with '' in UnrelQty
                NewUnrelQty = UnrelQty - Diff
                Set_Property(RefreshCtrl, 'TEXT', NewUnrelQty)
                Set_Property(@Window, '@SAVEWARN', True$)
            end else
                Set_Property(RefreshCtrl, 'TEXT',UnrelQty)
                Set_Property(@Window, '@SAVEWARN', False$)
            end
        end
    end

end event


Event EDL_CLOSE_DATE.CHANGED(NewData)

    If NewData NE '' then
        NewCloseDate = NewData
        CtrlName     = Field(CtrlEntID,'.',2)
        WONo         = Get_Property(@Window:'.EDL_WO_NO', 'TEXT')
        If WONo NE '' then
            OrigCloseDate = Xlate('WO_LOG', WONo, 'CLOSE_DATE', 'X')
            RefreshCtrl   = @Window:'.EDL_CLOSE_DATE'
            If NewCloseDate NE OrigCloseDate then
                Set_Property(@Window, '@SAVEWARN', True$)
            end else
                Set_Property(@Window, '@SAVEWARN', False$)
            end
        end
    end

end event


Event EDL_WO_NO.LOSTFOCUS(Flag, FocusID)
  
    PrevWONo  = Get_Property(@Window, '@WO_NO')
    DataValue = Get_Property(CtrlEntID, 'TEXT')
    If DataValue NE PrevWONo then
        CtrlMap   = ''
        If DataValue NE '' then

            If Index(DataValue,'.',1)  then
                * Try a BTREE lookup on PROD_ORD_NO
                
                Open 'DICT.WO_LOG' to DictVar then
                    
                    SearchString  = 'PROD_ORD_NO':@VM:DataValue:@FM
                    WONos = ''
                    Flag = ''
                    Btree.Extract(SearchString, 'WO_LOG', DictVar, WONos, '', Flag)
                    
                    Begin Case
                        Case Get_Status(errCode)
                            ErrMsg(errCode)
                            
                        Case WONos EQ ''
                            ErrMsg('Value Entered "':DataValue:'" is not found.')
                            
                        Case Index(WONos,@VM,1)
                            ErrMsg('Multiple Work Orders ':QUOTE(DataValue):' for Prod Order entered.')
                            
                        Case RowExists('WO_LOG', WONos)
                            Set_Property(CtrlEntID,'DEFPROP',WONos)
                            Post_Event(@Window, 'READ')
                            
                        Case Otherwise$
                            ErrMsg(Quote(DataValue):' is not a valid work order.')
                            
                    End Case
                end else
                    ErrMsg('Unable to open "DICT.WO_LOG" for index lookup in COMM_SHIPMENT routine.')
                end
            end else
                If RowExists('WO_LOG', DataValue) then
                    Post_Event(@Window, 'READ')
                end else
                    ErrMsg(Quote(DataValue):' is not a valid work order.')
                end
            end
        end
    end
    
end event


Event PUB_RX.CLICK()
    
    WONo = Get_Property(@Window:'.EDL_WO_NO', 'TEXT')
    If WONo NE '' then
        Response = Dialog_Box('WO_REC', @Window, WONo)
        GoSub PopulateControls
    end
    
end event


Event PUB_LABELS.CLICK()

    WONo = Get_Property(@Window:'.EDL_WO_NO', 'TEXT')
    If WONo NE '' then
        Work_Order_Services('PrintLabels', WONo)
        If Error_Services('HasError') then
            ErrorMsg = Error_Services('GetMessage')
            ErrMsg(ErrorMsg)
        end
    end
    
end event


Event PUB_LU_WO.CLICK()
    
    Set_Status(0)
    WOKeys = obj_WO_Log('Find')	
    
    IF Get_Status(errCode) THEN ErrMsg(ErrCode)
    
    IF WOKeys NE '' THEN
        TypeOver = ''
        TypeOver<PDISPLAY$> = WOKeys
        TypeOver<PMODE$> = 'K'
        
        WOKeys = Popup(@WINDOW,TypeOver,'WO_LOG_QUERY')
        IF Get_Status(errCode) THEN
            ErrMsg(errCode)
        END
        
        IF WOKeys NE '' THEN
            Set_Property(@Window:'.EDL_WO_NO', 'TEXT', WOKeys)
            GoSub PopulateControls
        end
    END
    
end event


Event PUB_NEW_GAN.CLICK()
    
    IF MemberOf(@USER4, 'CONFIG_LIMITED' ) THEN     
        WONo    = Get_Property(@WINDOW:'.EDL_WO_NO', 'DEFPROP')        
        IF WONo = '' THEN WONo = NextKey('WO_LOG')       
        Start_Window('WO_LOG_GAN',@WINDOW,WONo)
    end
    
end event


Event PUB_DUE_IN_WO.CLICK()
    
    OPEN 'DICT.WO_LOG' TO DictWOLogTable then
        
        MsgUp           = Msg(@WINDOW,'','SELECT_OPEN_WO')
        WOKeys          = ''
        SelectStatement = 'CURR_STATUS_STATIC':@VM:'ASN':@VM:'AWM':@VM:'RTP':@FM

        Btree.Extract(SelectStatement, 'WO_LOG', DictWOLogTable, WOKeys, '', '')

        If Get_Status(errCode) then
            ErrMsg(errCode)
            Msg(@WINDOW,MsgUp)
        end else
            Msg(@WINDOW,MsgUp)
            TypeOver            = ''
            TypeOver<PDISPLAY$> = WOKeys
            DueInWONo           = Popup(@WINDOW, TypeOver, 'DUE_IN_WORK_ORDERS')
            Set_Property(@Window:'.EDL_WO_NO', 'TEXT', DueInWONo)
            GoSub PopulateControls
        end
    end
    
end event


Event TAB_MAIN.CLICK()
    
    TabIndex = Get_Property(@WINDOW:'.TAB_MAIN', 'VALUE')
    Set_Property(@WINDOW, 'VPOSITION', TabIndex)
    
end event


Event PUB_SAVE.CLICK()
    
    Post_Event(@Window, 'WRITE')
    
end event


Event PUB_CLEAR.CLICK()
    
    Post_Event(@Window, 'CLEAR')
    
end event


Event PUB_CLOSE.CLICK()
    
    Post_Event(@Window, 'CLOSE')
    
end event


Event PUB_DELETE.CLICK()
    
    Post_Event(@Window, 'DELETE')
    
end event


Event PUB_VIEW_QUOTE.CLICK()
    
    QuoteNo = Get_Property(@WINDOW:'.EDL_QUOTE_NO','TEXT')
    
    IF QuoteNo NE '' then
        Start_Window('QUOTE2', @Window, QuoteNo)
    end
    
end event


Event PUB_LU_QUOTE.CLICK()
    
    CustNo    = Get_Property(@WINDOW:'.EDL_CUST_NO','DEFPROP')
    ProdVerNo = Get_Property(@WINDOW:'.EDL_PROD_VER_NO','DEFPROP')
    
    OPEN 'DICT.QUOTE' TO DictVar THEN
        SearchString  = 'CUST_NO':@VM:CustNo:@FM
        SearchString := 'STATUS':@VM:'=O':@FM
        SearchString := 'PROD_VER_NO':@VM:ProdVerNo:@FM
        
        Btree.Extract(SearchString, 'QUOTE', DictVar, QuoteKeys, '', Flag)
        IF Get_Status(errCode) THEN
            Msg(@window, MsgUp)
            ErrMsg(errCode)
            RETURN
        END
        
        IF QuoteKeys = '' THEN
            ErrMsg('No Quotes on file for customer ':CustNo)
            RETURN
        END
        
        IF INDEX(QuoteKeys,@VM,1) THEN
            
            QuoteKeys := @VM
            CONVERT @VM TO @RM IN QuoteKeys
            CALL V119('S','','D','R',QuoteKeys,'')
            CONVERT @RM TO @VM IN QuoteKeys
            QuoteKeys[-1,1] = ''					;* Strip trailing delimiter	
            
            TypeOver = ''
            TypeOver<PDISPLAY$> = QuoteKeys
            TypeOver<PSELECT$>	= 1				;* Single value select
            TypeOver<PTITLE$>	= 'Open Quotes for ':OCONV(CustNo,'[XLATE_CONV,COMPANY*CO_NAME]')
            
            QuoteKey = Popup(@WINDOW,TypeOver,'QUOTE')
            
        END ELSE
            QuoteKey = QuoteKeys
        END
        
        QuoteRec = XLATE('QUOTE',QuoteKey,'','X')
        PSNo = QuoteRec<7>
        
        QuoteNo = QuoteKey
        
    END	;* End of DICT.QUOTE open
    
    If QuoteNo NE '' then
        Set_Property(@Window:'.EDL_QUOTE_NO', 'DEFPROP', QuoteNo)
    end

end event


Event PUB_LU_PROD_VER_NO.CLICK()
    
    WONo 		= Get_Property(@WINDOW:'.EDL_WO_NO','DEFPROP')
    EpiPartNo	= Get_Property(@WINDOW:'.EDL_EPI_PART_NO','DEFPROP')
    SubPartNo	= Get_Property(@WINDOW:'.EDL_ORD_SUB_PART_NO','DEFPROP')
    ProdVerNo	= Get_Property(@WINDOW:'.EDL_PROD_VER_NO','DEFPROP')
    
    IF ProdVerNo NE '' THEN
        ErrMsg('ProdVer Numbers may not be changed.')
        RETURN
    END
    
    AllProdVerNos = XLATE('EPI_PART',EpiPartNo,EPI_PART_PROD_VER_NO$,'X')
    SubPartNos    = XLATE('PROD_VER',AllProdVerNos,PROD_VER_SUB_PART_NO$,'X')
    
    ProdVerCnt = COUNT(AllProdVerNos,@VM) + (AllProdVerNos NE '')
    
    DisplayKeys = ''
    
    FOR I = 1 TO ProdVerCnt
        IF SubPartNos<1,I> = SubPartNo THEN
            DisplayKeys<1,-1> = AllProdVerNos<1,I>
        END
    NEXT I
    
    IF DisplayKeys = '' THEN
        DisplayKeys = AllProdVerNos
    END
    
    TypeOver = ''
    TypeOver<PDISPLAY$> = DisplayKeys
    TypeOver<PSELECT$> = 1
    TypeOver<PMODE$> = 'K'
    
    ProdVerNo = Popup(@WINDOW,TypeOver,'PROD_VER')
    IF ProdVerNo = '' THEN RETURN

    IF NOT(MemberOf(@USER4,'RELEASE_ALL')) THEN
        IF MemberOf(@USER4,'RELEASE') THEN
            
            ProdVerRec 	= XLATE('PROD_VER',ProdVerNo,'','X')
            Captive		= XLATE('COMPANY', ProdVerRec<PROD_VER_CUST_NO$>,COMPANY_CAPTIVE$,'X')
            SpecType	= XLATE('PROD_SPEC', ProdVerRec<PROD_VER_PROC_STEP_PSN$,1> ,'SPEC_TYPE', 'X')
            
            IF NOT(Captive) THEN
                ErrMsg('This is a merchant order')
                RETURN
            END
            
            If SpecType = 'Q' Then								;* Added to prevent routing by S&R for qual runs. -dkk 4/14/14
                ErrMsg('The Prod Spec for this Captive order is Engineeing.')
                RETURN
            END
            
        END	ELSE
            RETURN
        END
    END
    
    obj_WO_Log('Route',WONo:@RM:ProdVerNo)
    
    IF Get_Status(errCode) THEN
        ErrMsg(errCode)
    END else
        GoSub PopulateControls
    end
    
end event


Event PUB_UNROUTED.CLICK()
    
    UnroutedWONos = Popup(@WINDOW,'','WO_LOG_UNROUTED')
    
    If UnroutedWONos = '' then
        ErrMsg('No Unrouted Work Orders on file.')
    end else
        FirstWONo = UnroutedWONos<0, 1>
        Set_Property(@Window:'.EDL_WO_NO', 'TEXT', FirstWoNo)
        GoSub PopulateControls
    end

end event


Event PUB_OPEN_WO.CLICK()
    
    OpenWONo = obj_WO_Log('OpenWONos','')
    
    If OpenWONo NE '' then
        Set_Property(@Window:'.EDL_WO_NO', 'TEXT', OpenWONo)
        GoSub PopulateControls
    end
    
end event


Event PUB_CHANGE_LOT_NO.CLICK()
    
    WONo	= Get_Property(@WINDOW:'.EDL_WO_NO','TEXT')
    IF WONo NE '' then
    
        Result = Dialog_Box('DIALOG_LOT_NO_CHANGE', @WINDOW, WONo)
        
        If Result NE 'Cancel' then
        
            OrgLotNo	= Result<1>
            NewLotNo	= Result<2>
            Reason		= Result<3>
            CassNos		= Result<4>
            
            obj_WO_Log('ChangeLotNo',WONo:@RM:OrgLotNo:@RM:NewLotNo:@RM:Reason:@RM:CassNos)
            
            IF Get_Status(errCode) THEN
                ErrMsg(errCode)
            END ELSE
                
                Recipients = XLATE('NOTIFICATION','WO_ENTRY',NOTIFICATION_USER_ID$,'X')
                SentFrom   = @USER4
                Subject    = 'Lot No Changed in WO ':WONo
                Message    = 'Lot No Change in WO.'
                NewForm    = Xlate('APP_INFO', 'NEW_WO_FORM', '', 'X')
                If NewForm then
                    AttachWindow	= 'NDW_WO_LOG'
                end else
                    AttachWindow	= 'WO_LOG2'
                end
                AttachKey		= WONo
                SendToGroup		= ''   
                
                Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup
                obj_Notes('Create',Parms)
                
                IF Get_Status(errCode) THEN ErrMsg(errCode)
                
                // Set CtrlMap variable to the control(s) that need to be updated
                CtrlMap = 'EDT_CASS_NO'
                GoSub PopulateControls
            END
        end
    end
    
end event


Event PUB_CHANGE_CASS_QTY.CLICK()
    
    WONo = Get_Property(@WINDOW:'.EDL_WO_NO','TEXT')
    IF WONo NE '' then

        CassList = Get_Property(@WINDOW:'.EDT_CASS_NO','LIST')
        
        LOOP
            LastLine = CassList[-1,'B':@FM]
        UNTIL LastLine<1,1> NE '' OR LastLine = ''
            CassList[COL1(),COL2()] = ''
        REPEAT
        
        CassettesList = XLATE('WO_LOG',WONo,WO_LOG_WO_MAT_KEY$,'X')
        
        CassCnt = COUNT(CassList,@VM) + (CassList NE '')
        
        Result = Dialog_Box('DIALOG_CASS_QTY_CHANGE',@WINDOW,WONo:@FM:CassettesList)

        IF Result NE 'Cancel' then
        
            CassNo		= Result[1,@FM]
            Reason		= Result[COL2()+1,@FM]
            OrgCassQty	= Result[COL2()+1,@FM]
            NewCassQty	= Result[COL2()+1,@FM]
            
            obj_WO_Log('ChangeCassQty',WONo:@RM:CassNo:@RM:NewCassQty:@RM:Reason)
            
            IF Get_Status(errCode) THEN
                ErrMsg(errCode)
            END ELSE
                
                Recipients		= XLATE('NOTIFICATION','WO_ENTRY',NOTIFICATION_USER_ID$,'X')
                SentFrom		= @USER4
                Subject			= 'Cassette Quantity Change ':WONo:'*':CassNo
                Message			= 'Cassette Quantity Change. WOMatNo: ':WONo:'*':CassNo
                AttachWindow	= 'WO_MAT'
                AttachKey		= WONo:'*':CassNo
                SendToGroup		= ''   
                Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup
                obj_Notes('Create',Parms)
                
                IF Get_Status(errCode) THEN ErrMsg(errCode)
                
                // Set CtrlMap variable to the control(s) that need to be updated
                CtrlMap    = ''
                CtrlMap<1> = @Window:'.EDL_WO_QTY'
                CtrlMap<2> = @Window:'.EDL_RX_QTY'
                CtrlMap<3> = @Window:'.EDL_REL_QTY'
                CtrlMap<4> = @Window:'.EDL_UNREL_QTY'
                CtrlMap<5> = @Window:'.EDL_SAP_CONFIRM_SCRAP_QTY'
                CtrlMap<6> = @Window:'.EDL_SAP_YIELD_QTY'
                CtrlMap<7> = @Window:'.EDL_SHIP_QTY'
                CtrlMap<8> = @Window:'.EDT_CASS_NO'
                GoSub PopulateControls
                
            END
        end
    end
    
end event


Event PUB_VIEW_CUST.CLICK()
    
    CustNo = Get_Property(@WINDOW:'.EDL_CUST_NO','TEXT')
    
    IF CustNo NE '' THEN
        Start_Window('CUSTOMER_EPI', @Window, 'Create')
        Set_Property('CUSTOMER_EPI.CO_NO', 'TEXT', CustNo)
        Post_Event('CUSTOMER_EPI', 'READ')
    END
    
end event


Event PUB_VIEW_PROD_VER.CLICK()
    
    ProdVerNo = Get_Property(@WINDOW:'.EDL_PROD_VER_NO','DEFPROP')
    
    IF ProdVerNo NE '' THEN
        Start_Window('PROD_VER', @Window, 'Create')
        Set_Property('PROD_VER.PROD_VER_NO', 'TEXT', ProdVerNo)
        Post_Event('PROD_VER', 'READ')
    END
    
end event


Event PUB_LU_CUST_PART_NO.CLICK()

    EpiPN = Get_Property(@WINDOW:'.EDL_EPI_PART_NO','DEFPROP')
    CustNo = Get_Property(@WINDOW:'.EDL_CUST_NO','DEFPROP')
    
    IF EpiPN = '' THEN
        ErrMsg('Missing Epi Part No.')
        RETURN
    END
    
    IF CustNo = '' THEN
        ErrMsg('Missing Cust No.')
        RETURN
    END
    
    CustEPRec = XLATE('CUST_EPI_PART',CustNo:'*':EpiPN,'','X')
    
    CustPNs			= CustEPRec<CUST_EPI_PART_CUST_PART_NO$>
    CustPNRevs 		= CustEPRec<CUST_EPI_PART_CUST_PART_REV$>
    CustPNInbounds	= CustEPRec<CUST_EPI_PART_CUST_PART_NO_INBOUND$>
    CustPNDescs		= CustEPRec<CUST_EPI_PART_CUST_PART_DESC$>
    
    CustPNCnt = COUNT(CustPNs,@VM) + (CustPNs NE '')
    
    IF CustPNCnt = 1 THEN
        CustPN			= CustPNs
        CustPNInbound	= CustPNInbounds
    END ELSE
        
        Display = ''
        
        FOR I = 1 TO CustPNCnt
            Display<1,I,1> = CustPNs<1,I>
            Display<1,I,2> = CustPNRevs<1,I>
            Display<1,I,3> = CustPNDescs<1,I>
            Display<1,I,4> = CustPNInbounds<1,I>
        NEXT I
        
        TypeOver = ''
        TypeOver<PDISPLAY$>	= Display
        
        CustPNLine = Popup(@WINDOW,TypeOver,'CUST_EPI_PART_PART_NOS')
        CustPN 			= CustPNLine<1,1>
        CustPNInbound	= CustPNLine<1,3>
        
    END
    
    IF CustPN NE '' THEN
        Set_Property(@WINDOW:'.EDL_CUST_PART_NO','DEFPROP',CustPN)
        Set_Property(@WINDOW:'.EDLICUST_PART_INBOUND','DEFPROP',CustPNInbound)
    END
    
end event


Event PUB_LU_CUST_SUB_NO.CLICK()
    
    EpiPN  = Get_Property(@WINDOW:'.EDL_EPI_PART_NO','DEFPROP')
    CustNo = Get_Property(@WINDOW:'.EDL_CUST_NO','DEFPROP')
    
    IF EpiPN = '' THEN
        ErrMsg('Missing Epi Part No.')
        RETURN
    END
    
    IF CustNo = '' THEN
        ErrMsg('Missing Cust No.')
        RETURN
    END
    
    CustEPIRec = XLATE('CUST_EPI_PART',CustNo:'*':EpiPN,'','X')
    
    SubPartNos = CustEPIRec<CUST_EPI_PART_SUBSTRATE_PART_NO$>
    SubPartMfrs = CustEPIRec<CUST_EPI_PART_SUBSTRATE_MFR$>
    
    SubPartCnt = COUNT(SubPartNos,@VM) + (SubPartNos NE '')
    
    IF SubPartCnt = 1 THEN
        SubPartNo = SubPartNos
        SubPartMfr = SubPartMfrs
    END ELSE
        
        Display = ''
        
        FOR I = 1 TO SubPartCnt
            Display<1,I,1> = SubPartNos<1,I>
            Display<1,I,2> = SubPartMfrs<1,I>
        NEXT I
        
        TypeOver = ''
        TypeOver<PDISPLAY$> = Display
        
        SubPNLine = Popup(@WINDOW,TypeOver,'CUST_EPI_SUB_PART_NOS')
        
        SubPartNo = SubPNLine<1,1>
        SubPartMfr = SubPNLine<1,2>
    END
    
    IF SubPartNo NE '' THEN
        Set_Property(@WINDOW:'.EDL_CUST_SUB_PART_NO','DEFPROP',SubPartNo)
        Set_Property(@WINDOW:'.EDL_CUST_SUB_MFR','DEFPROP',SubPartMfr)
    END
    
end event


Event PUB_CUST_EPI_PART.CLICK()
    
    CustEpiPartKey = Get_Property(@WINDOW:'.EDL_CUST_EPI_PART_KEY','DEFPROP')
    
    IF CustEpiPartKey NE '' then
    
        WONo = Get_Property(@WINDOW:'.EDL_WO_NO','DEFPROP')
        
        IF WONo NE '' then
            Start_Window('CUST_EPI_PART', @Window)
            Set_Property('CUST_EPI_PART.CUST_NO', 'TEXT', CustEpiPartKey)
            Post_Event('CUST_EPI_PART', 'READ')
        end
    end
    
end event


Event PUB_PRINT_WO.CLICK()
    
    WONo = Get_Property(@WINDOW:'.EDL_WO_NO','DEFPROP')
    
    IF WONo NE '' then
    
        Confirmation = ''
        Print_WO(WONo, Confirmation)
        Set_Property('SYSTEM','FOCUS','VSPRINTER')
        
    end
    
end event


Event PUB_PRINT_CONFIRMATION.CLICK()
    
    WONo = Get_Property(@WINDOW:'.EDL_WO_NO','DEFPROP')
    
    IF WONo NE '' then
    
        Confirmation = True$
        Print_WO(WONo, Confirmation)
        Set_Property('SYSTEM','FOCUS','VSPRINTER')
        
    end
    
end event


Event PUB_MU_WAFER_DETAIL.CLICK()
    
    WONo = Get_Property(@WINDOW:'.EDL_WO_NO','DEFPROP')
    
    IF WONo NE '' then
    
        Utility('CURSOR', 'H')
        Response    = Dialog_Box('NDW_MAKEUP_WAFERS', @Window, WONo)
        Utility('CURSOR', 'A')
    end
    
end event


Event PUB_UNROUTE_WO.CLICK()
    
        
    WONo      = Get_Property(@WINDOW:'.EDL_WO_NO','DEFPROP')
    ProdVerNo = Get_Property(@WINDOW:'.EDL_PROD_VER_NO','DEFPROP')
    
    If ( (WONo NE '') and (ProdVerNo NE '') ) then
    
        obj_WO_Log('Unroute',WONo)
        
        IF Get_Status(errCode) THEN
            ErrMsg(errCode)
        end else
            Gosub PopulateControls
        end
        
    end
    
end event


Event PUB_CHANGE_CUST_PART_NO.CLICK()
    
    Ctrls  = @WINDOW:'.EDL_WO_NO':@RM			; Props  = 'DEFPROP':@RM
    Ctrls := @WINDOW:'.EDL_CUST_PART_NO':@RM	; Props := 'DEFPROP'
    
    Vals = Get_Property(Ctrls,Props)
    
    WONo 		= Vals[1,@RM]
    CustPartNo	= Vals[COL2()+1,@RM]
    WOMatKeys	= Xlate('WO_LOG', WONo, 'WO_MAT_KEY', 'X')
    
    LOOP
        TestChar = WOMatKeys[-1,1]
    UNTIL TestChar NE @VM OR WOMatKeys = ''
        WOMatKeys[-1,1] = ''
    REPEAT
    
    IF WONo			= '' THEN RETURN
    IF CustPartNo	= '' THEN RETURN
    IF WOMatKeys 	= '' THEN RETURN
    
    If ( (WONo NE '') and (CustPartNo NE '') and (WOMatKeys NE '') ) then
    
        obj_WO_Mat('SetPartNo',WOMatKeys:@RM:CustPartNo)
        
        IF Get_Status(errCode) THEN
            ErrMsg(errCode)
        END ELSE
            
            Recipients		= XLATE('NOTIFICATION','WO_ENTRY',NOTIFICATION_USER_ID$,'X')
            SentFrom		= @USER4
            Subject			= 'Customer Part No Changed ':WONo
            Message			= 'Customer Part No Changed on WONo ':WONo
            AttachWindow	= 'WO_No'
            AttachKey		= WONo
            SendToGroup		= ''   
            
            Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup
            obj_Notes('Create',Parms)
            GoSub PopulateControls
        END
        
        IF Get_Status(errCode) THEN
            ErrMsg(errCode)
        END
        
    end
    
end event


Event PUB_CHANGE_PO_NO.CLICK()
    
    WONo = Get_Property(@WINDOW:'.EDL_WO_NO','TEXT')
    IF WONo NE '' then
        
        Result = Dialog_Box('DIALOG_PO_NO_CHANGE', @Window, WONo)
        
        IF Get_Status(errCode) THEN
            ErrMsg(errCode)
            
        END ELSE
            IF (Result = 'PO Number Changed') THEN
                Recipients = XLATE('NOTIFICATION','WO_ENTRY',NOTIFICATION_USER_ID$,'X')
                SentFrom   = @USER4
                Subject    = 'PO Number Changed in WO ':WONo
                Message    = 'PO Number Change in WO.'
                NewForm    = Xlate('APP_INFO', 'NEW_WO_FORM', '', 'X')
                If NewForm then
                    AttachWindow	= 'NDW_WO_LOG'
                end else
                    AttachWindow	= 'WO_LOG2'
                end
                AttachKey		= WONo
                SendToGroup		= ''   
                Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup
                obj_Notes('Create',Parms)
                GoSub PopulateControls
            END
        END
        
        IF Get_Status(errCode) THEN
            ErrMsg(errCode)
        END
        
    end
    
end event


Event PUB_REFRESH_SIG_PROFILE.CLICK()
    
    WONo = Get_Property(@WINDOW:'.EDL_WO_NO','TEXT')
    IF WONo NE '' then
    
        Set_Status(0)
        
        obj_WO_Log('RefreshSigProfile',WONo)
        
        IF Get_Status(errCode) THEN ErrMsg(errCode)
        
        GoSub PopulateControls
    end
    
end event

Event PUB_REM_CASS.CLICK()

    ErrorMessage = ''
    WONo = Get_Property(@WINDOW:'.EDL_WO_NO','TEXT')
    
    IF WONo NE '' then
        WOReactType = Xlate('WO_LOG', WONo, WO_LOG_REACT_TYPE$, 'X')
        Begin Case
            Case WOReactType EQ 'EPP'
                CassList = Work_Order_Services('GetEligiblePeelOffLotsByWOAndEntityType', WONo, 'WM_IN')
            Case WOReactType EQ 'ASM' OR WOReactType EQ 'HTR' OR WOReactType EQ 'ASM+'
                CassList = Work_Order_Services('GetEligiblePeelOffLotsByWOAndEntityType', WONo, 'RDS')
            Case Otherwise$
                ErrorMessage = 'Unsupported or null reactor type for this work order.'
        End Case
        If ErrorMessage EQ '' then
            If CassList NE '' then
                Display = ''
                DispLine = 1
                For each Cass in CassList using @VM
                    Begin Case
                        Case WOReactType EQ 'EPP'
                            WOMatKey = Field(Cass, '*', 1) : '*' : Field(Cass, '*', 3)
                        Case WOReactType EQ 'ASM' OR WOReactType EQ 'HTR' OR WOReactType EQ 'ASM+'
                            WOMatKey = Cass
                    End Case
                    WOMatRec = Database_Services('ReadDataRow', 'WO_MAT', WOMatKey, True$, 0, False$)
                    If WOReactType EQ 'EPP' then
                        CassNo = Field(Cass, '*', 3)
                        CassId = Cass
                        UnConvCurrStatus = XLATE('WM_IN',CassId,'CURR_STATUS','X')
                        CassCurrStatus = OCONV(UnConvCurrStatus,'[WM_IN_CURR_STATUS_CONV]')
                    end else
                        CassNo = Field(Cass, '*', 2)
                        CassId = WOMatRec<WO_MAT_RDS_NO$>
                        UnConvCurrStatus = obj_WO_Mat('CurrStatus',CassId:@RM:WOMatRec)
                        CassCurrStatus = OConv(UnConvCurrStatus, '[WO_MAT_CURR_STATUS_CONV]')
                    end
                    Display<1,DispLine,1>  = CassNo
                    Display<1,DispLine,2>  = WOMatRec<WO_MAT_LOT_NO$>
                    Display<1,DispLine,3>  = WOMatRec<WO_MAT_WAFER_QTY$>
                    Display<1,DispLine,4>  = CassId
                    Display<1,DispLine,5>  = CassCurrStatus
                    DispLine              += 1
                Next Cass
                CassettesToVoid = ''
                TypeOver = ''
                TypeOver<PDISPLAY$> = Display
                If WOReactType EQ 'EPP' then
                    CassettesToVoid = Popup(@WINDOW,TypeOver,'UNUSED_WM_IN')
                    If CassettesToVoid NE '' then
                        WmInKeys = ''
                        for each CassetteToVoid in CassettesToVoid using @FM
                            WmInKeys<1, -1> = CassetteToVoid<1,4>
                        Next CassetteToVoid
                        Service_Services('PostProcedure', 'WORK_ORDER_SERVICES', 'SignVoidWMI':SD$:WmInKeys:SD$:WoNo:SD$:@USER4)
                        If Error_Services('HasError') then
                            ErrorMessage = Error_Services('GetMessage')
                        end
                    end else
                        ErrorMessage = 'No cassettes were selected.'
                    end
                end else
                    CassettesToVoid = Popup(@WINDOW,TypeOver,'UNUSED_RDS')
                    WoMatKeyList = ''
                    for each CassetteToVoid in CassettesToVoid using @FM
                    
                        RDSToVoid = CassetteToVoid<1,4>
                        WONo = XLATE('RDS', RDSToVoid, RDS_WO$, 'X')
                        CassNo = XLATE('RDS', RDSToVoid, RDS_CASS_NO$, 'X')
                        WOMatKey = WONo : '*' : CassNo
                        WoMatKeyList<1, -1> = WoMatKey
                	    If Error_Services('HasError') then
                	        ErrorMessage = Error_Services('GetMessage')
                	    end   
                    Next CassetteToVoid
                    
                    If ErrorMessage EQ '' then
                        Service_Services('PostProcedure', 'WORK_ORDER_SERVICES', 'SignVoidNonEPP':SD$:WoMatKeyList:SD$:WoNo:SD$:@USER4)
                        if Error_Services('HasError') then
                            ErrorMessage = Error_Services('GetMessage')
                        end
                    end
                    
                end
            end else
                ErrorMessage = 'No eligible lots from this work order found to void.'
            end
        end
    end else
        Msg(@Window, ErrorMessage)
        return
    end
    If ErrorMessage EQ '' then
        //Now send a message
        Recipients		= XLATE('NOTIFICATION','WO_ENTRY',NOTIFICATION_USER_ID$,'X')
        SentFrom		= @USER4
        Subject			= 'Cassettes removed from WO ':WONo
        Message			= 'Cassettes removed from WO.'
        NewForm = Xlate('APP_INFO', 'NEW_WO_FORM', '', 'X')
        If NewForm then
            AttachWindow	= 'NDW_WO_LOG'
        end else
            AttachWindow	= 'WO_LOG2'
        end
        AttachKey		= WONo
        SendToGroup		= ''   
        
        Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup
        obj_Notes('Create',Parms)
        
        Msg(@Window, 'All selected lots queued for void.')
        
    end else
        Msg('Error in voiding lots process : ' : ErrorMessage)
    end
    GoSub PopulateControls
    
end event


Event PUB_REM_WM_OUT.CLICK()
    
    ErrorMessage = ''
    WONo = Get_Property(@WINDOW:'.EDL_WO_NO','TEXT')
    
    IF WONo NE '' then
        WOReactType = Xlate('WO_LOG', WONo, WO_LOG_REACT_TYPE$, 'X')
        Begin Case
            Case WOReactType EQ 'EPP'
                CassList = Work_Order_Services('GetEligiblePeelOffLotsByWOAndEntityType', WONo, 'WM_OUT')
            Case WOReactType EQ 'ASM' OR WOReactType EQ 'HTR' OR WOReactType EQ 'ASM+'
                ErrorMessage = 'Non EpiPro work order types do not utilize WM_OUT cassettes. Nothing to void.'
            Case Otherwise$
                ErrorMessage = 'Unsupported or null reactor type for this work order.'
        End Case
        If ErrorMessage EQ '' then
            If CassList NE '' then
                Display = ''
                DispLine = 1
                For each Cass in CassList using @VM
                    WOMatKey = Field(Cass, '*', 1) : '*' : Field(Cass, '*', 3)
                    WOMatRec = Database_Services('ReadDataRow', 'WO_MAT', WOMatKey, True$, 0, False$)
                    CassNo = Field(Cass, '*', 3)
                    CassId = Cass
                    UnConvCurrStatus = XLATE('WM_OUT',CassId,'CURR_STATUS','X')
                    CassCurrStatus = OCONV(UnConvCurrStatus,'[WM_OUT_CURR_STATUS_CONV]')

                    Display<1,DispLine,1>  = CassNo
                    Display<1,DispLine,2>  = CassCurrStatus
                    Display<1,DispLine,3>  = CassId
                    DispLine              += 1
                Next Cass
                CassettesToVoid = ''
                TypeOver = ''
                TypeOver<PDISPLAY$> = Display
                CassettesToVoid = Popup(@WINDOW,TypeOver,'UNUSED_WM_OUT')
                If CassettesToVoid NE ''  then
                    WmOutKeys = ''
                    for each CassetteToVoid in CassettesToVoid using @FM
                        WmOutKeys<1, -1> = CassetteToVoid<1,3>
                    Until ErrorMessage NE ''
                    Next CassetteToVoid
                    Service_Services('PostProcedure', 'WORK_ORDER_SERVICES', 'SignVoidWMO':SD$:WmOutKeys:SD$:WoNo:SD$:@USER4)
                    If Error_Services('HasError') then
                        ErrorMessage = Error_Services('GetMessage')
                    end
                end else
                    ErrorMessage = 'No lots were selected to void.'
                end
            end else
                ErrorMessage = 'No eligible lots from this work order found to void.'
            end
        end else
            Msg(@Window, ErrorMessage)
            return
        end
    end
    If ErrorMessage EQ '' then
        // Now send a message
        Recipients		= XLATE('NOTIFICATION','WO_ENTRY',NOTIFICATION_USER_ID$,'X')
        SentFrom		= @USER4
        Subject			= 'Cassettes removed from WO ':WONo
        Message			= 'Cassettes removed from WO.'
        NewForm = Xlate('APP_INFO', 'NEW_WO_FORM', '', 'X')
        If NewForm then
            AttachWindow	= 'NDW_WO_LOG'
        end else
            AttachWindow	= 'WO_LOG2'
        end
        AttachKey		= WONo
        SendToGroup		= ''   
        
        Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup
        obj_Notes('Create',Parms)
        
        Msg(@Window, 'All selected lots queued for void.')
        
    end else
        Msg('Error in voiding lots process : ' : ErrorMessage)
    end
    GoSub PopulateControls
    
end event


Event PUB_RECALL.CLICK()
    
    WONo = Get_Property(@WINDOW:'.EDL_WO_NO','TEXT')
    IF WONo = '' THEN RETURN
    
    Response = Msg(@WINDOW,'','WO_PURGE')
    
    IF Response = CHAR(27) THEN RETURN
    
    Send_Event(@WINDOW,'WRITE')
    
    TempWONo = WONo
    Set_Status(0)
    
    WORec			= XLATE('WO_LOG',WONo,'','X')
    WOMatKeys		= WORec<WO_LOG_WO_MAT_KEY$>
    WMInKeys		= XLATE('WO_MAT',WOMatKeys,WO_MAT_WMI_KEY$,'X')
    WMInTestSTring	= WMInKeys
    
    CONVERT @VM TO '' IN WMInTestString
    
    RDSNos = ''
    CassNos = ''
    
    IF WMInTestString NE '' THEN
        
        * EpiPRO material inbound
        
        EpiRDSNos = XLATE('WM_IN',WMInKeys,WM_IN_RDS_NO$,'X')
        EpiNCRNos = XLATE('WM_IN',WMInKeys,WM_IN_SLOT_NCR$,'X')
        
        CONVERT @VM TO '' IN EpiRDSNos
        CONVERT @VM TO '' IN EpiNCRNos
        
        IF EpiRDSNos NE '' OR EpiNCRNos NE '' THEN
            
            ErrMsg('Processing has started. Work Order cannot be recalled.')
            RETURN
            
        END
        
    END ELSE
        
        WOMatSigs = XLATE('WO_MAT',WOMatKeys,WO_MAT_SIGNATURE$,'X')
        
        CONVERT @VM TO '' IN WOMatSigs
        
        IF WOMatSigs NE '' THEN
            ErrMsg('Processing has started. Work Order cannot be recalled.')
            RETURN
        END
        
    END
    
    obj_WO_Log('RecallWO',TempWONo)		;* This variable gets changed down the line
    
    IF Get_Status(errCode) THEN
        
        Def = ''
        Def<MTEXT$>		= errCode[-1,'B':@SVM]			;* Error handling system puts a title in front of the @SVM, strip it off here
        Def<MICON$>		= '!'
        Def<MTYPE$>		= 'BO'
        Def<MCAPTION$>	= 'Work Order Recall'
        Def<MJUST$>		= 'C'
        
        Msg(@WINDOW,Def,'')
        Set_Status(0)
        
        GoSub PopulateControls
        Send_Event(@WINDOW,'PAGE',2)
        
        RETURN
    END
    
    GoSub PopulateControls
    
    Recipients = XLATE('NOTIFICATION','WO_ENTRY',NOTIFICATION_USER_ID$,'X')
    SentFrom   = @USER4
    Subject    = 'Work Order Recalled ':WONo
    Message    = 'Work Order Recalled from Production.'
    NewForm    = Xlate('APP_INFO', 'NEW_WO_FORM', '', 'X')
    If NewForm then
        AttachWindow	= 'NDW_WO_LOG'
    end else
        AttachWindow	= 'WO_LOG2'
    end
    AttachKey		= WONo
    SendToGroup		= ''   
    
    Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup
    obj_Notes('Create',Parms)
    
    IF Get_Status(errCode) THEN
        ErrMsg(errCode)
    END
    
end event


Event PUB_PRINT_SHELF_LABELS.CLICK()
    
    WONo = Get_Property(@WINDOW:'.EDL_WO_NO','TEXT')
    IF WONo = '' THEN RETURN
    
    Send_Event(@WINDOW,'WRITE')
    
    Set_Status(0)
    
    Print_Shelf_Label(WONo)
    
    IF Get_Status(errCode) THEN ErrMsg(errCode)
    
end event


Event PUB_WO_START_DT.CLICK()
    
    GoSub StartStopDate
    
end event


Event PUB_WO_STOP_DT.CLICK()
    
    GoSub StartStopDate
    
end event


Event PUB_REPROCESS.CLICK()
        
    WONo = Get_Property(@WINDOW:'.EDL_WO_NO','DEFPROP')
    
    IF WONo NE '' then
        Start_Window('WO_REPROCESS', @Window, WONo)
        Set_Property('WO_REPROCESS.WO_NO', 'TEXT', WONo)
        Post_Event('WO_REPROCESS', 'READ')
    end
    
end event


Event PUB_REORDER.CLICK()
    
    CtrlEntID = @WINDOW:'.EDT_CASS_NO'

    RelStamp = Get_Property(@WINDOW:'.EDT_REL_STAMP','TEXT')

    IF RelStamp NE '' THEN
        Message = 'Work order has been released to production.||Cassettes may only be renumbered prior to release'
        ErrMsg('Cassette Reorder Process':@SVM:Message)
        RETURN
    END

    OrgCassList = Get_Property(CtrlEntId,'LIST')

    IF OrgCassList<1,1> = '' THEN RETURN

    BlankLineCnt = 0
    LOOP
        LastLine = OrgCassList[-1,'B':@FM]			;* [] Operation sets COL1() and COL2()
    UNTIL LastLine<1,1> NE '' OR LastLine = ''
        OrgCassList[COL1(),COL2()] = ''				;* Strip trailing blank lines from edit table controls
        BlankLineCnt += 1
    REPEAT

    ListCnt = COUNT(OrgCassList,@FM) + (OrgCassList NE '')

    CONVERT @VM TO @SVM IN OrgCassList
    CONVERT @FM TO @VM IN OrgCassList

    TypeOver = ''
    TypeOver<PDISPLAY$> = OrgCassList

    ReSelect:

    SortedCassList = Popup(@WINDOW,TypeOver,'WO_CASSETTE_SORT')
    IF SortedCassList = '' OR SortedCassList = CHAR(27) THEN RETURN

    IF Get_Status(errCode) THEN ErrMsg(errCode)

    ResultCnt = COUNT(SortedCassList,@FM) + (SortedCassList NE '')

    IF ResultCnt NE ListCnt THEN
        Message = 'All cassettes must be selected in the order they are to be processed.'
        ErrMsg('Cassette Reorder Process':@SVM:Message)
        GOTO ReSelect
    END

    FOR I = 1 TO ResultCnt
        SortedCassList<I,1> = I
    NEXT I

    BlankLines = STR(STR(@VM,6):@FM,BlankLineCnt)
    SortedCassList<-1> = BlankLines

    SortedCassList[-1,1] = ''	;* Trailing @FM

    Set_Property(CtrlEntID,'LIST',SortedCassList)

    GoSub PopulateControls
    
end event


Event EDT_CASS_NO.DBLCLK(CtrlKey, ShiftKey, MouseButton)

    WONo = Get_Property(@Window:'.EDL_WO_NO', 'TEXT')

    IF WONo NE '' then

        CurrPos = Get_Property(CtrlEntID,'SELPOS')
        CurrCol = CurrPos<1>
        CurrRow = CurrPos<2>

        BEGIN CASE
            CASE CurrCol = COL$CASS_ID_SAP
                CassID = Get_Property(CtrlEntID,'CELLPOS',COL$CASS_ID_SAP:@FM:CurrRow)
                
                BEGIN CASE
                
                    CASE CassID = '' ; RETURN
                    
                    CASE INDEX(CassID,'.',1)
                    
                        WMOutKey = CassID[1,'.']:'*1*':CassID[COL2()+1,'.']
                        
                        Start_Window('WM_OUT', @Window, WMOutKey)
                        Set_Property('WM_OUT.WO_NO', 'TEXT', WONo)
                        Set_Property('WM_OUT.PROC_STEP_NO', 'TEXT', 1)
                        Set_Property('WM_OUT.OUT_CASS_NO', 'TEXT', CassID)
                        Post_Event('WM_OUT', 'READ')
                    
                    CASE NUM(CassID)
                        RDSNo = CassID

                        IF RDSNo NE '' THEN

                            Start_Window('RDS', @Window, RDSNo)
                            Set_Property('RDS.RDS_NO', 'TEXT', RDSNo)
                            Post_Event('RDS', 'READ')
                                
                        END

                END CASE
                
                    
            CASE 1
                CassNo = Get_Property(CtrlEntID,'CELLPOS',COL$CASS_NO:@FM:CurrRow)
                IF CassNo = '' THEN RETURN
                
                WOMatKey = WONo:'*':CassNo

                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
            
end event


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


SaveData:

    RefreshCtrls = ''
    WONo         = Get_Property(@Window:'.EDL_WO_NO', 'TEXT')
    If WONo NE '' then
        
        // The controls have been named to match the column name that they were database bound to.
        If Unassigned(CtrlMap) then CtrlMap = ''
        If CtrlMap EQ '' then CtrlMap = Get_Property(@Window, 'CTRLMAP')
        
        NumCtrls         = DCount(CtrlMap, @FM)
        Def              = ""
        Def<MCAPTION$>   = "Saving Work Order Detail..."
        Def<MTYPE$>      = "G"
        Def<MEXTENT$>    = NumCtrls
        Def<MTEXTWIDTH$> = 600
        MsgUp            = Msg(@WINDOW, Def) ;* Start gas guage message
        
        WOLogDict   = Database_Services('ReadDataRow', 'DICT.WO_LOG', '%FIELDS%')
        WOLogFields = WOLogDict<FIELDS_NAME$>
        WOLogConvs  = WOLogDict<FIELDS_CONV$>
        WOLogRec    = Database_Services('ReadDataRow', 'WO_LOG', WONo)
        
        For each Ctrl in CtrlMap using @FM setting fPos
            
            CtrlConv  = ''
            Val       = ''
            CtrlConvs = Get_Property(Ctrl, 'CONV')
            CtrlName  = Field(Ctrl, '.', 2)
        
            If CtrlName NE 'EDL_WO_NO' then
                CtrlType = Get_Property(Ctrl, 'TYPE')
                
                Begin Case
                    Case CtrlName[-1, 1] EQ 1
                        // This is just a duplicate editline for display purposes. 
                        Null
                        
                    Case ( (CtrlType EQ 'EDITFIELD') or (CtrlType EQ 'CHECKBOX') or (CtrlType EQ 'EDITBOX') )
                        
                        CtrlConv = CtrlConvs
                        Col      = CtrlName[5, 999]
                        If Num(Col[-1, 1]) then
                            Col[-1, -2] = ''
                        end
                        Val = Get_Property(Ctrl, 'DEFPROP')
                        GoSub SetColumnData
                        
                    Case CtrlName EQ 'EDT_PART_STEP_NO'

                        Cols  = 'PROD_VER_STEP_NO,PROD_VER_STEP_PSN,PROD_VER_STEP_PSN_TYPE,PROD_VER_STEP_DOPANT,'
                        Cols := 'PROD_VER_STEP_THICK_TARG,PROD_VER_STEP_THICK_UNITS,PROD_VER_STEP_RES_TARG,'
                        Cols := 'PROD_VER_STEP_RES_UNITS,PROD_VER_STEP_DESC,WO_STEP_CURR_STATUS,'
                        Cols := 'WO_STEP_SCHEDULED,WO_STEP_SCHED_DTM'
                        Vals  = ''
                        Steps = Xlate('WO_LOG', WONo, 'PROD_VER_STEP_NO', 'X')
                        For each StepNo in Steps using @VM setting RowPos
                            GoSub SaveEditTable
                        Next StepNo
                        
                    Case CtrlName EQ 'EDT_CASS_NO'
                        
                        Cols  = 'WO_MAT_CASS_NO,WO_MAT_LOT_NO,WO_MAT_WAFER_QTY,WO_MAT_SUB_PART_NO,WO_MAT_VEND_CD,'
                        Cols := 'WO_MAT_EPI_PART_NO,WO_MAT_RX_DTM,WO_MAT_REL_DTM,WO_MAT_CURR_STATUS,WO_MAT_SAP_TX_DTM,'
                        Cols := 'SAP_BATCH_NO,WO_MAT_CASS_ID_SAP,WO_MAT_SAP_YIELD,WO_MAT_SAP_CONFIRM_SCRAP,'
                        Cols := 'WO_MAT_SAP_GR_QTY,WO_MAT_SAP_RAW_SCRAP_QTY,WO_MAT_SAP_PROD_TEST_QTY,'
                        Cols := 'WO_MAT_SAP_MU_QTY'
                        GoSub SaveEditTable
                        
                    Case CtrlName EQ 'EDT_CUST_LOT_NO'
                        
                        Cols = 'CUST_LOT_NO,CUST_LOT_QTY'
                        GoSub SaveEditTable
                        
                    Case CtrlName EQ 'EDT_SHIP_NO'
                        
                        Cols = 'SHIP_NO,SAP_DEL_NO,SHIP_DT,SHIP_LOT_NOS,SHIP_INV_NO,SHIP_WFR_QTY,SHIP_REJ_QTY,SHIP_PROD_QTY'
                        GoSub SaveEditTable
                        
                    Case CtrlName EQ 'EDT_PSN_SUB_PART_NO'
                        
                        Cols = 'PSN_SUB_PART_NO,PSN_SUB_PART_MFG'
                        GoSub SaveEditTable
                        
                    Case CtrlName EQ 'EDT_LOAD_CASS_NO'
                        
                        Cols = 'LOAD_CASS_NO'
                        GoSub SaveEditTable
                        
                    Case CtrlName EQ 'EDT_RX_STAMP'
                        Col = 'RX_STAMP'
                        Val = Get_Property(Ctrl, 'ARRAY')
                        GoSub SetColumnData
                        
                    Case CtrlName EQ 'EDT_REL_STAMP'
                        Col = 'REL_STAMP'
                        Val = Get_Property(Ctrl, 'ARRAY')
                        GoSub SetColumnData
                        
                    Case Otherwise$
                        Null
                End Case
            end

            Running = Msg(@WINDOW, MsgUp, fPos, MSGINSTUPDATE$) ;* Update message
            
        Next Ctrl
        
        Msg(@WINDOW,MsgUp)      ;* Take message down

        Database_Services('WriteDataRow', 'WO_LOG', WONo, WOLogRec, True$, False$, True$)
        
    end

    // If any physical fields were updated, then update their controls.
    If RefreshCtrls NE '' then
        CtrlMap = RefreshCtrls
        Locate @Window:'.CHB_HOT_FLAG' in CtrlMap using @FM setting fPos then
            Send_Event('REACT_STATUS_EVEN', 'TIMER')
            Send_Event('REACT_STATUS_ODD', 'TIMER')
            Send_Event('NDW_SCHEDULER', 'OMNIEVENT', 'RefreshSchedule')
        end
    end
    GoSub PopulateControls
    
    // Reset CtrlMap variable so future calls to PopulateControls will populate all controls.
    CtrlMap = ''

    Set_Property(@Window, '@SAVEWARN', False$)
    
return


EnableControls:
    
    Ctrls   = 'PUB_RX,PUB_LABELS'
    WONo    = Get_Property(@Window:'.EDL_WO_NO', 'TEXT')
    ValidWO = RowExists('WO_LOG', WONo) 
    For each Ctrl in Ctrls using ','
        Set_Property(@Window:'.':Ctrl, 'ENABLED', ValidWO)
    Next Ctrl

    If ValidWO then
        RxQty         = Get_Property(@Window:'.EDL_RX_QTY', 'TEXT')
        RelQty        = Get_Property(@Window:'.EDL_REL_QTY', 'TEXT')
        Swap ',' with '' in RxQty
        Swap ',' with '' in RelQty
        If Num(RxQty) and Num(RelQty) then
            AvailToRel    = RxQty - RelQty
            RelBtnEnabled = (AvailToRel GT 0)
            Set_Property(@Window:'.PUB_RELEASE', 'ENABLED', RelBtnEnabled)
        end
        If MemberOf(@USER4, 'SCHEDULER_ADMIN') OR MemberOf(@USER4, 'SCHEDULER_MASTER') then
            Set_Property(@Window:'.CHB_HOT_FLAG', 'ENABLED', True$)
        end
    end
    
return


GetColumnData:
    
    Val              = Xlate('WO_LOG', WONo, Col, 'X')
    If Unassigned(CtrlConv) then CtrlConv = ''
    If CtrlConv EQ '' then
        Locate Col in WOLogFields using @VM setting ConvPos then
            Conv = WOLogConvs<0, ConvPos>
            If ( (Conv NE '') and (CtrlType NE 'CHECKBOX') ) then Val = OConv(Val, Conv)
        end
    end else
        Val = OConv(Val, CtrlConv)
    end
    Running   = Msg(@WINDOW, MsgUp, ColIndex, MSGINSTUPDATE$) ;* Update message
    ColIndex += 1
    
return


SetColumnData:
    
    Class       = Xlate('DICT.WO_LOG', Col, DICT_TYPE$, 'X')
    PhysicalCol = (Class EQ 'F')
    
    If PhysicalCol then
        FieldIndex = Xlate('DICT.WO_LOG', Col, DICT_COLUMN_NO$, 'X')
        If Unassigned(CtrlConv) then CtrlConv = ''
        If CtrlConv EQ '' then
            Locate Col in WOLogFields using @VM setting ConvPos then
                Conv = WOLogConvs<0, ConvPos>
                If ( (Conv NE '') and (CtrlType NE 'CHECKBOX') ) then Val = IConv(Val, Conv)
            end
        end else
            Val = IConv(Val, CtrlConv)
        end
        OrigVal              = WOLogRec<FieldIndex>
        If ( Assigned(RefreshCtrls) and (OrigVal NE Val) ) then
            RefreshCtrls<-1> = Ctrl
            If Col EQ 'WO_QTY' then
                RefreshCtrls<-1> = @Window:'.EDL_UNREL_QTY'
                RefreshCtrls<-1> = @Window:'.EDL_REL_QTY'
                RefreshCtrls<-1> = @Window:'.EDL_RX_QTY'
            end
            If Col EQ 'CLOSE_DATE' then RefreshCtrls<-1> = @Window:'.EDL_XSTATUS'
        end
        WOLogRec<FieldIndex> = Val
    end
    
return


FillEditTable:
    
    Vals = ''
    For each Col in Cols using ',' setting ColPos
        CtrlConv = CtrlConvs<0, 0, ColPos>
        GoSub GetColumnData
        Vals<ColPos> = Val
    Next Col
    Set_Property(Ctrl, 'ARRAY', Vals)
    
return


SaveEditTable:
    
    Vals = Get_Property(Ctrl, 'ARRAY')
    For each Col in Cols using ',' setting ColPos
        CtrlConv = CtrlConvs<0, 0, ColPos>
        GoSub SetColumnData
    Next Col
    
return


PopulateControls:

    WONo  = Get_Property(@Window:'.EDL_WO_NO', 'TEXT')
    If WONo NE '' then
        
        // The controls have been named to match the column name that they were database bound to.
        If Unassigned(CtrlMap) then CtrlMap = ''
        If CtrlMap EQ '' then CtrlMap = Get_Property(@Window, 'CTRLMAP')
        Set_Property(@Window, "REDRAW", False$)
        
        NumCtrls   = DCount(CtrlMap, @FM)
        NumEDTCols = 45
        
        Def              = ""
        Def<MCAPTION$>   = "Loading Work Order Detail..."
        Def<MTYPE$>      = "G"
        Def<MEXTENT$>    = NumCtrls + NumEDTCols
        Def<MTEXTWIDTH$> = 600
        MsgUp            = Msg(@WINDOW, Def) ;* Start gas guage message
        
        WOLogDict = Database_Services('ReadDataRow', 'DICT.WO_LOG', '%FIELDS%')
        
        WOLogFields = WOLogDict<FIELDS_NAME$>
        WOLogConvs  = WOLogDict<FIELDS_CONV$>
        
        LogData = ''
        LogData<1> = LoggingDTM
        
        ColIndex = 1
        
        For each Ctrl in CtrlMap using @FM setting fPos
            
            CtrlConvs = Get_Property(Ctrl, 'CONV')
            CtrlName  = Field(Ctrl, '.', 2)
        
            If CtrlName NE 'EDL_WO_NO' then
                CtrlType = Get_Property(Ctrl, 'TYPE')
                
                Begin Case
                    Case ( (CtrlType EQ 'EDITFIELD') or (CtrlType EQ 'CHECKBOX') )
                        
                        Col = CtrlName[5, 999]
                        If Num(Col[-1, 1]) then
                            Col[-1, -2] = ''
                        end
                        GoSub GetColumnData
                        Set_Property(Ctrl, 'DEFPROP', Val)
                        
                    Case CtrlName EQ 'EDT_PART_STEP_NO'
                        
                        Cols  = 'PROD_VER_STEP_NO,PROD_VER_STEP_PSN,PROD_VER_STEP_PSN_TYPE,PROD_VER_STEP_DOPANT,'
                        Cols := 'PROD_VER_STEP_THICK_TARG,PROD_VER_STEP_THICK_UNITS,PROD_VER_STEP_RES_TARG,'
                        Cols := 'PROD_VER_STEP_RES_UNITS,WO_STEP_CURR_STATUS'
                        Vals  = ''
                        Steps = Xlate('WO_LOG', WONo, 'PROD_VER_STEP_NO', 'X')
                        For each StepNo in Steps using @VM setting RowPos
                            For each Col in Cols using ',' setting ColPos
                                GoSub GetColumnData
                                Vals<RowPos, ColPos> = Val
                            Next Col
                        Next StepNo
                        Set_Property(@Window:'.EDT_PART_STEP_NO', 'LIST', Vals)
                        
                    Case CtrlName EQ 'EDT_CASS_NO'
                        
                        Cols  = 'WO_MAT_CASS_NO,WO_MAT_LOT_NO,WO_MAT_WAFER_QTY,WO_MAT_SUB_PART_NO,WO_MAT_VEND_CD,'
                        Cols := 'WO_MAT_EPI_PART_NO,WO_MAT_RX_DTM,WO_MAT_REL_DTM,WO_MAT_CURR_STATUS,WO_MAT_SAP_TX_DTM,'
                        Cols := 'SAP_BATCH_NO,WO_MAT_CASS_ID_SAP,WO_MAT_SAP_YIELD,WO_MAT_SAP_CONFIRM_SCRAP,'
                        Cols := 'WO_MAT_SAP_GR_QTY,WO_MAT_SAP_RAW_SCRAP_QTY,WO_MAT_SAP_PROD_TEST_QTY,'
                        Cols := 'WO_MAT_SAP_MU_QTY'
                        GoSub FillEditTable
                        
                    Case CtrlName EQ 'EDT_CUST_LOT_NO'
                        
                        Cols = 'CUST_LOT_NO,CUST_LOT_QTY'
                        GoSub FillEditTable
                        
                    Case CtrlName EQ 'EDT_SHIP_NO'
                        
                        Cols = 'SHIP_NO,SAP_DEL_NO,SHIP_DT,SHIP_LOT_NOS,SHIP_INV_NO,SHIP_WFR_QTY,SHIP_REJ_QTY,SHIP_PROD_QTY'
                        GoSub FillEditTable
                        
                    Case CtrlName EQ 'EDT_PSN_SUB_PART_NO'
                        
                        Cols = 'PSN_SUB_PART_NO,PSN_SUB_PART_MFG'
                        GoSub FillEditTable
                        
                    Case CtrlName EQ 'EDT_LOAD_CASS_NO'
                        
                        Cols = 'LOAD_CASS_NO'
                        GoSub FillEditTable
                        
                    Case CtrlName EQ 'EDT_RX_STAMP'
                        Col = 'RX_STAMP'
                        GoSub GetColumnData
                        Set_Property(Ctrl, 'ARRAY', Val)
                        
                    Case CtrlName EQ 'EDT_REL_STAMP'
                        Col = 'REL_STAMP'
                        GoSub GetColumnData
                        Set_Property(Ctrl, 'ARRAY', Val)
                        
                    Case Otherwise$
                        Running   = Msg(@WINDOW, MsgUp, ColIndex, MSGINSTUPDATE$) ;* Update message
                        ColIndex += 1
                        
                End Case
            end

        Next Ctrl

        Msg(@WINDOW,MsgUp)      ;* Take message down
        
        Set_Property(@Window, "REDRAW", True$)

        ReactType = Get_Property(@Window:'.EDL_REACT_TYPE', 'TEXT')
        If ReactType EQ 'GAN' then ReactType = 'GaN'
        Set_Property(@Window:'.REACT_TYPE_GROUP', 'TEXT', ReactType)
        
    end
    GoSub EnableControls
    
    // Reset CtrlMap variable so future calls to PopulateControls will populate all controls
    CtrlMap = ''
    
return


ClearControls:
    
    If Unassigned(CtrlMap) then CtrlMap = ''
    If CtrlMap EQ '' then CtrlMap = Get_Property(@Window, 'CTRLMAP')
    
    NumCtrls = DCount(CtrlMap, @FM)
            
    For each Ctrl in CtrlMap using @FM setting fPos
        
        Val       = ''
        CtrlName  = Field(Ctrl, '.', 2)
    
        CtrlType = Get_Property(Ctrl, 'TYPE')
        
        If ( (CtrlType EQ 'EDITFIELD') or (CtrlType EQ 'CHECKBOX') or (CtrlType EQ 'EDITBOX') or (CtrlType EQ 'EDITTABLE') ) then               
            Set_Property(@Window, 'DEFPROP', '')
        end
        
    Next Ctrl
    
    // Reset CtrlMap variable so future calls to PopulateControls will populate all controls
    CtrlMap = ''
    
return


StartStopDate:
    
    Ctrls  = @WINDOW:@RM					    ; Props  = 'FOCUS':@RM
    Ctrls := @WINDOW:'.EDL_WO_NO':@RM			; Props := 'DEFPROP':@RM
    Ctrls := @WINDOW:'.EDL_PROD_VER_NO':@RM		; Props := 'DEFPROP'
    
    Vals = Get_Property(Ctrls,Props)
    
    CtrlEntID = Vals[1,@RM]
    WONo      = Vals[COL2()+1,@RM]
    ProdVerNo = Vals[COL2()+1,@RM]
    WOMatKeys = Xlate('WO_LOG', WONo, 'WO_MAT_KEY', 'X')
    
    IF WONo = '' THEN RETURN
    
    CtrlName = FIELD(CtrlEntID,'.',2)
    
    ReactType = XLATE('PROD_VER', ProdVerNo, PROD_VER_REACT_TYPE$, 'X')
    
    IF ReactType = 'EPP' THEN RETURN		;* EpiPro is working don't mess with it.
    
    IF CtrlName = 'PUB_WO_START_DT' THEN
        CurrText = Get_Property(CtrlEntID,'TEXT')
        IF CurrText[1,' ']= 'Clear' THEN
            Set_Property(@WINDOW:'.EDL_WO_START_DTM','TEXT','')
        END ELSE
            RelStamp = Get_Property(@WINDOW:'.REL_STAMP','DEFPROP')<1,1>
            TimeStamp = FIELD(RelStamp,' ',1,2)
            Set_Property(@WINDOW:'.EDL_WO_START_DTM','TEXT',TimeStamp)
        END
    END
    
    IF CtrlName = 'PUB_WO_STOP_DT' THEN
        CurrText = Get_Property(CtrlEntID,'TEXT')
        IF CurrText[1,' ']= 'Clear' THEN
            Set_Property(@WINDOW:'.EDL_WO_STOP_DTM','TEXT','')
        END ELSE
            TimeStamp = OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTH')
            Set_Property(@WINDOW:'.EDL_WO_STOP_DTM','TEXT',TimeStamp)
        END
    END
    
return

