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

    Name        :   NDW_GAN_INBOUND_MATERIAL_EVENTS

    Description :   Commuter module for the NDW_GAN_INBOUND_MATERIAL 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)
        01/24/20    djs     Original programmer.

***********************************************************************************************************************/
#pragma precomp SRP_PreCompiler
#window NDW_GAN_INBOUND_MATERIAL

$Insert APP_INSERTS
$Insert EVENT_SETUP
$Insert WO_MAT_WFR_EQUATES
$Insert REACT_RUN_EQUATES
$Insert WO_WFR_EQUATES
$Insert WO_MAT_EQUATES

EQU OI_BLUE$        TO 1 + (120*256) + (215*65536)      ;* Matches the default blue of OI selection style in edit tables
EQU OI_GREY$        TO 225 + (225*256) + (225*65536)    ;* Matches the default grey of OI push buttons when not hot
EQU OI_HOT_BLUE$    TO 229 + (241*256) + (251*65536)    ;* Matches the default blue of OI push buttons when hot
EQU OI_CLICK_BLUE$  TO 205 + (228*256) + (246*65536)    ;* Matches the default blue of OI push buttons when depressed

// In Cass OLE Edit Table
EQU COL$CASS_SLOT		    TO 1
EQU COL$CASS_WFR_ID  		TO 2
EQU COL$CASS_CARR_SLOT_ID	TO 3
EQU COL$CASS_OUT_SLOT_ID    TO 4
EQU COL$CASS_GAN_WFR_ID		TO 5
EQU COL$CASS_SCRIBE		    TO 6
EQU COL$CASS_GRADE	        TO 7
EQU COL$CASS_WMI_NCR	    TO 8
EQU COL$CASS_RDS_NCR        TO 9
EQU COL$CASS_WMO_NCR        TO 10

// NCR OLE Edit Table
EQU COL$NCR_NO			 TO 1
EQU COL$NCR_STATUS		 TO 2
EQU COL$NCR_REJ_QTY		 TO 3
EQU COL$NCR_RESP		 TO 4
EQU COL$NCR_STAGE		 TO 5
EQU COL$NCR_LOSS_DESC	 TO 6
EQU COL$NCR_LOSS_COMM	 TO 7
EQU COL$NCR_FIN_SIG		 TO 8
EQU COL$NCR_FIN_SIG_DTM	 TO 9

Declare subroutine SRP_Show_Window, Set_Property, Set_Status, ErrMsg, Dialog_Box, Database_Services
Declare subroutine GaN_Services
Declare function Database_Services, Get_Property, SRP_Array, RGB, obj_NCR, Get_Status

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

Return EventFlow or 1

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

Event WINDOW.CREATE(CreateParam)

    GoSub SetupOLEControls
    If CreateParam NE '' then
        WOMatKey = CreateParam
        WONo     = Field(WOMatKey, '*', 1)
        CassNo   = Field(WOMatKey, '*', 2)
        Set_Property(@Window:'.WO_NO', 'TEXT', WONo)
        Set_Property(@Window:'.CASS_NO', 'TEXT', CassNo)               
        GoSub FillForm       
    end
    SRP_Show_Window(@Window, '', 'C', 'C', 1, '', False$, False$, FormSize)
    EventFlow = 1
    
End Event


Event PUB_CREATE_NCR.CLICK()
    
    CassCtrl  = @Window:".OLE_EDT_IN_CASS"
    CassList  = Get_Property(CassCtrl, 'OLE.List')
    SelectedRows = Get_Property(CassCtrl, "OLE.ColumnData[":COL$CASS_WMI_NCR:"]")
    CONVERT @VM TO @FM in SelectedRows
    NumWfrs		= DCount(SelectedRows, @FM)

    WONo		= Get_Property(@Window:'.WO_NO', 'TEXT')
    CassNo      = Get_Property(@Window:'.CASS_NO', 'TEXT')
    RejWfrIDs	= ''
    RejSlotIDs	= ''
    
    GoodLines = 0
    FOR WfrIndex = 1 TO NumWfrs
        RowSelected = SelectedRows<WfrIndex>
        If RowSelected EQ True$ then
            GoodLines += 1
            RejWfrIDs<1,GoodLines> = CassList<WfrIndex,COL$CASS_WFR_ID>
        end        
    NEXT I

    ncrParms  = WONo:@RM
    ncrParms := '1':@RM
    ncrParms := CassNo:@RM		;* Place holder for WO_MAT_CASS_NO
    ncrParms := '':@RM		    ;* Single RDS field 
    ncrParms := '':@RM		    ;* Reactor No
    ncrParms := '':@RM			;* Loss Stage
    ncrParms := RejWfrIDs:@RM	;* WfrIDs			;* CarrWafer IDs
    ncrParms := '':@RM	        ;* CarrSlotIDs		;* GaN PostEpi Carrier Slot ID	-> GaN non-characterization wafers
    ncrParms := '':@RM			;* CassSlotIDs		;* WOMat Cassette Slot ID		-> Rej from cassette
    ncrParms := ''				;* RunPocketZone	;* RPZ							-> Rej from susceptor

    Set_Status(0)
    NCRNo = obj_NCR('CreateWfr',ncrParms)		;* Create new NCR for this wafer/group of wafers

    IF Get_Status(errCode) THEN
        ErrMsg(errCode)
    end else
        Dialog_Box('NCR', @Window, NCRNo)
        PrevCursor  = Set_Property('SYSTEM', 'CURSOR', 'H')
        GaN_Services('ConsumeInboundMaterial', RejWfrIDs)
        // Add NCRNo to the rejected wafer ID records (WO_WFR table)
        For each WfrID in RejWfrIDs using @VM
            WOWfrRec = Database_Services('ReadDataRow', 'WO_WFR', WfrID)
            WOWfrRec<WO_WFR_WMI_NCR_NO$> = NCRNo
            Database_Services('WriteDataRow', 'WO_WFR', WfrID, WOWfrRec, True$, False$, True$)
        Next WfrID
        Set_Property(CassCtrl, "OLE.CellCheck[":COL$CASS_WMI_NCR:";All]", False$)
        GoSub FillCassEditTable
        GoSub FillNCREditTable
        GoSub EnableCreateNCRButton
        // If the GaN work order processing form is open, then refresh the page to update the inbound quantities.
        GaNProdVis = Get_Property('WO_PROD_GAN', 'VISIBLE')
        If GaNProdVis EQ True$ then Send_Event('WO_PROD_GAN', 'READ')
        PrevCursor  = Set_Property('SYSTEM', 'CURSOR', 'A')
    end

end event


Event CASS_NO.LOSTFOCUS(Flag, FocusID)

    WONo         = Get_Property(@Window:'.WO_NO', 'TEXT')
    CassNo       = Get_Property(@Window:'.CASS_NO', 'TEXT')
    If ( (WONo NE '') and (CassNo NE '') ) then
        PrevWONo = Get_Property(@Window, '@WO_NO')
        PrevCassNo = Get_Property(@Window, '@CASS_NO')
        If ( (PrevWONo NE WONo) or (PrevCassNo NE CassNo) ) then
            GoSub FillForm
        end
    end
    
end event


Event OLE_EDT_IN_CASS.OnCheckChanged(Cell, OldValue, NewValue)

    GoSub EnableCreateNCRButton
    
end event


Event OLE_EDT_NCR.OnDblClick(Cell, Point, Button, Shift, Ctrl)

    Row   = Field(Cell, ';', 2, 1)
    NCRNo = Get_Property(CtrlEntID, "OLE.CellText[":COL$NCR_NO:";":Row:"]")
    If RowExists('NCR', NCRNo) then
        PreNCRRec  = Database_Services('ReadDataRow', 'NCR', NCRNo)
        Dialog_Box('NCR', @Window, NCRNo)
        PostNCRRec = Database_Services('ReadDataRow', 'NCR', NCRNo)
        If PreNCRRec NE PostNCRRec then GoSub FillNCREditTable          
    end
end event


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


SetupOLEControls:
    
    NumCassCols = 10
    NumCassRows = 25
    NumNCRCols  = 9
    NumNCRRows  = 5
    CassCtrl    = @Window:'.OLE_EDT_IN_CASS'
    NCRCtrl     = @Window:'.OLE_EDT_NCR'
    
    HeaderFontArray   = 'Segoe UI':@SVM:8:@SVM:700
    CassDimArray      = NumCassCols :@FM: NumCassRows
    NCRDimArray       = NumNCRCols :@FM: NumNCRRows
    
    Set_Property(CassCtrl, "OLE.CellFont[All; All]", 'Segoe UI':@SVM:8)
    Set_Property(CassCtrl, "OLE.Dimension", CassDimArray)
    Set_Property(CassCtrl, "OLE.HeaderFont[All; 1]", HeaderFontArray)
    Set_Property(CassCtrl, "OLE.HeaderFont[1; All]", HeaderFontArray)
        
    Set_Property(NCRCtrl, "OLE.CellFont[All; All]", 'Segoe UI':@SVM:8)
    Set_Property(NCRCtrl, "OLE.Dimension", NCRDimArray)
    Set_Property(NCRCtrl, "OLE.HeaderFont[All; 1]", HeaderFontArray)
    Set_Property(NCRCtrl, "OLE.HeaderFont[1; All]", HeaderFontArray)
    
    CassHeaderTitles  = 'Slot':@VM:'Inbound':@VM:'Carrier':@VM:'Outbound':@VM:'GaN Wfr ID':@VM:'Scribe':@VM:'Grade':@VM
    CassHeaderTitles := 'WMI NCR':@VM:'RDS NCR':@VM:'WMO NCR'
    Set_Property(CassCtrl, "OLE.TitleList", CassHeaderTitles)
    Set_Property(CassCtrl, "OLE.HeaderAlignment[All; 1]", 'C':@FM:'C':@FM:'L')
    Set_Property(CassCtrl, "OLE.CellAlignment[1; All]", 'C':@FM:'C':@FM:'L')
    Set_Property(CassCtrl, "OLE.CellAlignment[2-":COL$CASS_GRADE:"; All]", 'C':@FM:'L':@FM:'L')
    Set_Property(CassCtrl, "OLE.CellAlignment[":COL$CASS_WMI_NCR:"-":COL$CASS_WMO_NCR:"; All]", 'C':@FM:'C':@FM:'L')
    Set_Property(CassCtrl, "OLE.AllowDeletions", False$)
    Set_Property(CassCtrl, "OLE.AllowInserts", False$)
    HeaderColArray    = ''
    HeaderColArray<2> = False$
    Set_Property(CassCtrl, "OLE.HeaderColumn[1]", HeaderColArray)
    
    NCRHeaderTitles = 'NCR':@VM:'Status':@VM:'Qty':@VM:'Responsible':@VM:'Stage':@VM:'Loss Desc':@VM:'Loss Comments' |
                    :@VM:'Signature':@VM:'Date & Time'
    Set_Property(NCRCtrl, "OLE.TitleList", NCRHeaderTitles)
    Set_Property(NCRCtrl, "OLE.HeaderAlignment[All; 1]", 'C':@FM:'C':@FM:'L')
    Set_Property(NCRCtrl, "OLE.CellAlignment[All; All]", 'C':@FM:'C':@FM:'L')
    Set_Property(NCRCtrl, "OLE.AllowDeletions", False$)
    Set_Property(NCRCtrl, "OLE.AllowInserts", False$)
    HeaderColArray    = ''
    HeaderColArray<2> = False$
    Set_Property(NCRCtrl, "OLE.HeaderColumn[1]", HeaderColArray)
    
    // Set default header colors
    HeaderColorArray    = ''
    HeaderColorArray<1> = 'Auto'
    HeaderColorArray<2> = 'None'
    HeaderColorArray<3> = 'None'
    HeaderColorArray<4> = OI_HOT_BLUE$
    HeaderColorARray<5> = False$
    Set_Property(CassCtrl, "OLE.HeaderColors[All; All]", HeaderColorArray)
    Set_Property(NCRCtrl, "OLE.HeaderColors[All; All]", HeaderColorArray)
   
    // Qualify OLE events that we want to intercept
    Qualifier = ''
    Qualifier<1> = 1
    Qualifier<4> = 0 ; * process synchronously (i.e. immediately)
    Send_Message(CassCtrl,          'QUALIFY_EVENT', 'OLE.OnCheckChanged',      Qualifier)
    Send_Message(NCRCtrl,           'QUALIFY_EVENT', 'OLE.OnDblClick',          Qualifier)
    
    //////////////////////////////////// In Cass OLE Edit Table //////////////////////////////////////////////
    
    // Disable resizing of the header row and header column
    // Resize header column to fit contents
    HeaderRowArray = Get_Property(CassCtrl, "OLE.HeaderRow[1]")
    HeaderRowArray<3> = False$
    Set_Property(NCRCtrl, "OLE.HeaderRow[1]", HeaderRowArray)
    // Disable resizing of columns as there is no need for this on this form
    ColSize = Get_Property(CassCtrl, "OLE.DataColumn[1]")
    ColSize<3> = False$
    Set_Property(CassCtrl, "OLE.DataColumn[All]", ColSize)
    ColSize<1> = 40
    Set_Property(CassCtrl, "OLE.DataColumn[":COL$CASS_SLOT:"]", ColSize)
    ColSize<1> = 80
    Set_Property(CassCtrl, "OLE.DataColumn[":COL$CASS_WFR_ID:"]", ColSize)
    ColSize<1> = 60
    Set_Property(CassCtrl, "OLE.DataColumn[":COL$CASS_CARR_SLOT_ID:"]", ColSize)
    ColSize<4> = True$
    Set_Property(CassCtrl, "OLE.DataColumn[":COL$CASS_OUT_SLOT_ID:"]", ColSize)
    ColSize<4> = False$
    ColSize<1> = 95
    Set_Property(CassCtrl, "OLE.DataColumn[":COL$CASS_GAN_WFR_ID:"]", ColSize)
    ColSize<1> = 70
    Set_Property(CassCtrl, "OLE.DataColumn[":COL$CASS_SCRIBE:"]", ColSize)
    ColSize<1> = 40
    Set_Property(CassCtrl, "OLE.DataColumn[":COL$CASS_GRADE:"]", ColSize)
    ColSize<1> = 65
    Set_Property(CassCtrl, "OLE.DataColumn[":COL$CASS_WMI_NCR:"-":COL$CASS_WMO_NCR:"]", ColSize)
    
    // Hide scrollbars
    Set_Property(CassCtrl, "OLE.ScrollBarsVisible", 'N':@FM:'N')
    
    // Disable resizing of rows as there is no need for this on this form
    RowSizeProps = Get_Property(CassCtrl, "OLE.DataRow[1]")
    RowSizeProps<3> = False$
    Set_Property(CassCtrl, "OLE.DataRow[All]", RowSizeProps)   
    Set_Property(CassCtrl, "OLE.CellProtection[All; All]", 'SEL')
    
    // Color headers
    Set_Property(CassCtrl, "OLE.HeaderColors[All; 1]", @FM:"{200, 200, 200}")
    
    // Color cells
    Set_Property(CassCtrl, "OLE.CellColors[All; All]", 'None':@FM:RGB(192,220,192))
                 
    //////////////////////////////////// NCR OLE Edit Table //////////////////////////////////////////////
    
    // Disable resizing of the header row and header column
    // Resize header column to fit contents
    HeaderRowArray = Get_Property(NCRCtrl, "OLE.HeaderRow[1]")
    HeaderRowArray<3> = False$
    Set_Property(NCRCtrl, "OLE.HeaderRow[1]", HeaderRowArray)
    // Disable resizing of columns as there is no need for this on this form
    ColSize = Get_Property(NCRCtrl, "OLE.DataColumn[1]")
    ColSize<3> = False$
    ColSize<1> = 50
    Set_Property(NCRCtrl, "OLE.DataColumn[":COL$NCR_NO:"]", ColSize)
    ColSize<1> = 45
    Set_Property(NCRCtrl, "OLE.DataColumn[":COL$NCR_STATUS:"]", ColSize)
    ColSize<1> = 32
    Set_Property(NCRCtrl, "OLE.DataColumn[":COL$NCR_REJ_QTY:"]", ColSize)
    ColSize<1> = 70
    Set_Property(NCRCtrl, "OLE.DataColumn[":COL$NCR_RESP:"]", ColSize)
    ColSize<1> = 58
    Set_Property(NCRCtrl, "OLE.DataColumn[":COL$NCR_STAGE:"]", ColSize)
    ColSize<1> = 100
    Set_Property(NCRCtrl, "OLE.DataColumn[":COL$NCR_LOSS_DESC:"]", ColSize)
    ColSize<1> = 100
    Set_Property(NCRCtrl, "OLE.DataColumn[":COL$NCR_LOSS_COMM:"]", ColSize)
    ColSize<4> = True$
    Set_Property(NCRCtrl, "OLE.DataColumn[":COL$NCR_FIN_SIG:"]", ColSize)
    ColSize<4> = False$
    ColSize<1> = 100
    Set_Property(NCRCtrl, "OLE.DataColumn[":COL$NCR_FIN_SIG_DTM:"]", ColSize)
    
    // Left-align the last four columns
    Set_Property(NCRCtrl, "OLE.CellAlignment[":COL$NCR_LOSS_DESC:"-":COL$NCR_FIN_SIG_DTM:";All]", 'C':@FM:'L':@FM:'L')
    
    // Disable resizing of rows as there is no need for this on this form
    RowSizeProps = Get_Property(NCRCtrl, "OLE.DataRow[1]")
    RowSizeProps<3> = False$
    Set_Property(NCRCtrl, "OLE.DataRow[All]", RowSizeProps)   
    Set_Property(NCRCtrl, "OLE.CellProtection[":COL$NCR_NO:"-":COL$NCR_FIN_SIG_DTM:"; All]", 'SEL')
    
    // Color headers
    Set_Property(NCRCtrl, "OLE.HeaderColors[All; 1]", @FM:"{200, 200, 200}")
    
    // Color cells
    Set_Property(NCRCtrl, "OLE.CellColors[All; All]", 'None':@FM:RGB(192,220,192))
    
    // Scroll bars
    Set_Property(NCRCtrl, "OLE.ScrollBarsVisible", 'A':@FM:'A')

return


FillForm:
       
    WONo         = Get_Property(@Window:'.WO_NO', 'TEXT')
    CassNo       = Get_Property(@Window:'.CASS_NO', 'TEXT')
    If ( (WONo NE '') and (CassNo NE '') ) then
        Set_Property(@Window, '@WO_NO', WONo)
        Set_Property(@Window, '@CASS_NO', CassNo)
        WOMatKey   = WONo:'*':CassNo
        WOMatRec   = Database_Services('ReadDataRow', 'WO_MAT', WOMatKey)
        LotNo      = WOMatRec<WO_MAT_LOT_NO$>
        SubPartNo  = WOMatRec<WO_MAT_SUB_PART_NO$>
        CustPartNo = WOMatRec<WO_MAT_CUST_PART_NO$>
        Set_Property(@Window:'.LOT_NO', 'TEXT', LotNo)
        Set_Property(@Window:'.SUB_PART_NO', 'TEXT', SubPartNo)
        Set_Property(@Window:'.CUST_PART_NO', 'TEXT', CustPartNo)
    end
    
    GoSub FillCassEditTable
    GoSub FillNCREditTable
    
return


FillCassEditTable:
    
    CassCtrl     = @Window:'.OLE_EDT_IN_CASS'
    WONo         = Get_Property(@Window:'.WO_NO', 'TEXT')
    CassNo       = Get_Property(@Window:'.CASS_NO', 'TEXT')
    
    If ( (WONo NE '') and (CassNo NE '') ) then
        // Suppress redraw until all properties are set
        Set_Property(CassCtrl, "OLE.Redraw", False$)
        
        WOMatKey     = WONo:'*':CassNo
        WOMatWfrRec  = Database_Services('ReadDataRow', 'WO_MAT_WFR', WOMatKey)
        AvailWfrs    = WOMatWfrRec<WO_MAT_WFR_IN_WFR_ID$>   
        ConsumedWfrs = WOMatWfrRec<WO_MAT_WFR_IN_PREV_WFR_ID$>
        InWfrIDs     = ''
        For Slot = 1 to 25
            If AvailWfrs<0, Slot> NE '' then
                InWfrIDs<0, Slot> = AvailWfrs<0, Slot>
            end else
                InWfrIDs<0, Slot> = ConsumedWfrs<0, Slot>
            end
        Next Slot
        
        CassCtrlArray = ''
        For each InWfrID in InWfrIDs using @VM setting RowIndex
            CarrSlotID  = ''
            OutSlotID   = ''
            GaNWfrID    = ''
            Scribe      = ''
            Grade       = ''
            WMINCRNo    = ''
            RDSNCRNo    = ''
            WMONCRNo    = ''
            RDSNo = Xlate('WO_WFR', InWfrID, 'RDS_NO', 'X')
            If RDSNo NE '' then
                ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo, True$, 30, False$)
                RDSWfrIDs   = ReactRunRec<REACT_RUN_IN_WFR_ID$>
                Locate InWfrID in RDSWfrIDs using @VM setting WfrIndex then
                    CarrSlotID = ReactRunRec<REACT_RUN_CARR_SLOT_ID$, WfrIndex>
                    OutSlotID  = ReactRunRec<REACT_RUN_OUT_SLOT_ID$, WfrIndex>
                    GaNWfrID   = Xlate('WO_WFR', InWfrID, 'GAN_WFR_ID', 'X')
                    Scribe     = Xlate('WO_WFR', InWfrID, 'SCRIBE', 'X')
                    Grade      = Xlate('WO_WFR', InWfrID, 'GRADE', 'X')                  
                end
            end
            WOWfrRec = Database_Services('ReadDataRow', 'WO_WFR', InWfrID)
            WMINCRNo = WOWfrRec<WO_WFR_WMI_NCR_NO$>
            RDSNCRNo = WOWfrRec<WO_WFR_RDS_NCR_NO$>
            WMONCRNo = WOWfrRec<WO_WFR_WMO_NCR_NO$>
            CassCtrlArray<COL$CASS_SLOT, RowIndex>         = RowIndex
            CassCtrlArray<COL$CASS_WFR_ID, RowIndex>       = InWfrID
            CassCtrlArray<COL$CASS_CARR_SLOT_ID, RowIndex> = CarrSlotID
            CassCtrlArray<COL$CASS_OUT_SLOT_ID, RowIndex>  = OutSlotID
            CassCtrlArray<COL$CASS_GAN_WFR_ID, RowIndex>   = GaNWfrID
            CassCtrlArray<COL$CASS_SCRIBE, RowIndex>       = Scribe
            CassCtrlArray<COL$CASS_GRADE, RowIndex>        = Grade
            CassCtrlArray<COL$CASS_WMI_NCR, RowIndex>      = WMINCRNo
            CassCtrlArray<COL$CASS_RDS_NCR, RowIndex>      = RDSNCRNo
            CassCtrlArray<COL$CASS_WMO_NCR, RowIndex>      = WMONCRNo
            
            If ( (WMINCRNo EQ '') and (CarrSlotID EQ '') ) then
                // This inbound wafer is eligible to be NCR'd
                // Convert NCR cell for this row into a check box
                Set_Property(CassCtrl, "OLE.CellText[":COL$CASS_WMI_NCR:";":RowIndex:"]", '')
                CheckBoxArray      = 'Check Box'
                CheckBoxArray<2,1> = True$
                Set_Property(CassCtrl, "OLE.CellType[":COL$CASS_WMI_NCR:";":RowIndex:"]", CheckBoxArray)
                Set_Property(CassCtrl, "OLE.CellCheckEnabled[":COL$CASS_WMI_NCR:";":RowIndex:"]", True$)                
            end else                
                Set_Property(CassCtrl, "OLE.CellType[":COL$CASS_WMI_NCR:";":RowIndex:"]", 'Text')
            end
        Next InWfrID
        
        Set_Property(CassCtrl, 'OLE.ARRAY', CassCtrlArray)
        // Re-enable redraw now that all properties are set
        Set_Property(CassCtrl, "OLE.Redraw", True$)
    end
    
return


FillNCREditTable:
    
    CassCtrl     = @Window:".OLE_EDT_IN_CASS"
    NCRCtrl      = @Window:'.OLE_EDT_NCR'
    WMINCRNos    = Get_Property(CassCtrl, "OLE.ColumnData[":COL$CASS_WMI_NCR:"]")
    Swap 0 with '' in WMINCRNos ; // We don't wan't checkmark values (False = 0)
    RDSNCRNos    = Get_Property(CassCtrl, 'OLE.ColumnData[':COL$CASS_RDS_NCR:']')
    WMONCRNos    = Get_Property(CassCtrl, "OLE.ColumnData[":COL$CASS_WMO_NCR:"]")
    NCRNos       = SRP_Array('Join', WMINCRNos, RDSNCRNos, 'OR', @VM)
    NCRNos       = SRP_Array('Join', NCRNos, WMONCRNos, 'OR', @VM)
    NCRNos       = SRP_Array('Clean', NCRNos, 'TrimAndMakeUnique', @VM)
    NCRCtrlArray = ''
    Set_Property(NCRCtrl, "OLE.Redraw", False$)
    
    If ( (NCRNos NE 0) and (NCRNos NE '') ) then           
        NCRCtrl = @Window:'.OLE_EDT_NCR'
        For each NCRNo in NCRNos using @VM setting nPos
            If ( (RowExists('NCR', NCRNo)) and (NCRNo NE 0) ) then
                Database_Services('ActivateRecord', 'NCR', NCRNo)
                NCRCtrlArray<COL$NCR_NO, nPos>          =  NCRNo
                NCRCtrlArray<COL$NCR_STATUS, nPos>      = {STATUS}
                NCRCtrlArray<COL$NCR_REJ_QTY, nPos>     = {REJ_CNT}
                NCRCtrlArray<COL$NCR_RESP, nPos>        = {LOSS_BY}
                NCRCtrlArray<COL$NCR_STAGE, nPos>       = {LOSS_STAGE}
                NCRCtrlArray<COL$NCR_LOSS_DESC, nPos>   = {LOSS_DESC}
                NCRCtrlArray<COL$NCR_LOSS_COMM, nPos>   = {LOSS_COMMENTS}
                NCRCtrlArray<COL$NCR_FIN_SIG, nPos>     = OConv({AUTH_SHIP_SIG}, '[XLATE_CONV,LSL_USERS*FIRST_LAST]')
                NCRCtrlArray<COL$NCR_FIN_SIG_DTM, nPos> = OConv({AUTH_SHIP_SIG_DTM}, 'DT')
            end
        Next NCR
    end else
        // No NCRs associated with this inbound cassette, so clear the NCR table.
        For nPos = 1 to 5
            NCRCtrlArray<COL$NCR_NO, nPos>          = ''
            NCRCtrlArray<COL$NCR_STATUS, nPos>      = ''
            NCRCtrlArray<COL$NCR_REJ_QTY, nPos>     = ''
            NCRCtrlArray<COL$NCR_RESP, nPos>        = ''
            NCRCtrlArray<COL$NCR_STAGE, nPos>       = ''
            NCRCtrlArray<COL$NCR_LOSS_DESC, nPos>   = ''
            NCRCtrlArray<COL$NCR_LOSS_COMM, nPos>   = ''
            NCRCtrlArray<COL$NCR_FIN_SIG, nPos>     = ''
            NCRCtrlArray<COL$NCR_FIN_SIG_DTM, nPos> = ''
        Next nPos
    end
    Set_Property(NCRCtrl, "OLE.ARRAY", NCRCtrlArray)
    Set_Property(NCRCtrl, "OLE.Redraw", True$)
return


EnableCreateNCRButton:

    CassCtrl = @Window:'.OLE_EDT_IN_CASS'
    Checkmarks = Get_Property(CassCtrl, "OLE.CellCheck[":COL$CASS_WMI_NCR:"; All]")
    Checksum   = Sum(Checkmarks)
    ButtonEnabled = False$
    If ( Checksum GT 0 ) then ButtonEnabled = True$ 
    Set_Property(@Window:'.PUB_CREATE_NCR', 'ENABLED', ButtonEnabled)

return

