Compile Subroutine Report_Thruput_GaN(dummy)
#pragma precomp SRP_PreCompiler

* General Manager Report - goes straight to Excel

* 09/23/2006 John C. Henry, J.C. Henry & Co., Inc.  Initial coding
* 11/05/2019 DJS - Adapted from Report_Thruput for GaN

Declare Subroutine  ErrMsg, Btree.Extract, Set_Status, SetInitDirOptions, ErrMsg, Logging_Services
Declare Function    Msg, Get_Status, obj_Calendar, Utility, SetInitDirOptions, Dialog_Box, obj_RDS_Test
Declare Function    Logging_Services, Environment_Services, Gan_Services, obj_NCR

$INSERT RDS_EQU
$INSERT COMPANY_EQU
$INSERT REACTOR_EQUATES
$INSERT FISCAL_QTR_EQUATES
$INSERT COC_EQUATES
$INSERT MSG_EQUATES
$INSERT EXCEL_EQU
$INSERT LOGICAL

EQU COMMA$                  TO ','
EQU ROW$TOT_REACTOR_OUTS    TO  2
EQU ROW$TOT_YIELD_OUTS      TO  3
EQU ROW$TOT_CUST_SCRAP      TO  4
EQU ROW$TOT_EPI_SCRAP       TO  5
EQU ROW$TOT_OTHER           TO  6
EQU ROW$TOT_DUMMY           TO  7
EQU ROW$TOT_YIELD           TO  8
EQU ROW$TOT_SCRAP_RATE      TO  9
EQU ROW$TOT_SHIP            TO 10
EQU ROW$BLANK_LINE_1        TO 11

EQU COL$MON					TO 2
EQU COL$TUE					TO 3
EQU COL$WED				    TO 4
EQU COL$THU				    TO 5
EQU COL$FRI				    TO 6
EQU COL$SAT				    TO 7
EQU COL$SUN				    TO 8
EQU COL$WTD_ACTUAL		    TO 9
EQU COL$QTD_ACTUAL		    TO 10
EQU COL$QTD_MF_PLAN     	TO 11
EQU COL$QTD_MF_REMAIN       TO 12
EQU COL$ORG_MF_DAILY_PLAN   TO 13
EQU COL$QTD_MF_OVER_UNDER   TO 14

EQU COL$PERIOD				TO 15
EQU COL$PERIOD_VALUE		TO 16
EQU COL$PERIOD_START		TO 17
EQU COL$PERIOD_END			TO 18

EQU CRLF$ TO \0D0A\

Main:
    
    errCode = ''
    
    eXcelCols = 'A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,AA,BB,CC,DD,EE,FF,GG,HH,II,JJ,KK,LL'
    SWAP "','" WITH ',' IN eXcelCols
    CONVERT ',' TO @VM IN eXcelCols
    
    NoteText  = 'Enter an ending date for data selection.':CRLF$:CRLF$
    NoteText := 'The report will calculate the Quarter and Week '
    NoteText := 'beginning and ending dates and report on the QTD '
    NoteText := 'through the ending date entered.'
    
    DateLabel = 'Include data through:'
    
    CutOffDt = Dialog_Box("DIALOG_DATE",@WINDOW,NoteText:@FM:DateLabel)
    thisCutOffDt = ICONV(CutOffDt,'D4/')
    IF thisCutOffDt = '' THEN
        RETURN
    END
    
    LogPath     = Environment_Services('GetApplicationRootPath') : '\LogFiles\ThruPut'
    LogDate     = Oconv(Date(), 'D4/')
    LogTime     = Oconv(Time(), 'MTS')
    LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' ThruPut Log.csv'
    Headers     = 'RDS' : @FM : 'Work Order' : @FM : 'Date Out' : @FM : 'Time Out' : @FM : 'Wafers'
    objLog      = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, Comma$, Headers, '', False$, True$)
    LoggingDTM  = LogDate : ' ' : LogTime   ; // Logging DTM
    
    CutOffDt = OCONV(thisCutOffDt,'D4/')
    
    IF CutOffDt = '' THEN RETURN
    
    FiscalYear = obj_Calendar('IRFiscalYear',CutOffDt)
    
    FWData = obj_Calendar('IRFiscalWeek',CutOffDt)
    
    FiscalWeek  = FWData[1,@FM]
    FWStartDt   = FWData[COL2()+1,@FM]
    FWEndDt     = FWData[COL2()+1,@FM]
    
    StartDt = ICONV(FWStartDt,'D')
    
    WeekDates = ''
    FOR I = StartDt TO StartDt + 6
        WeekDates<1,-1> = OCONV(I,'D4/')
    NEXT I
    
    FQData = obj_Calendar('IRFiscalQuarter',CutOffDt)
    
    FiscalQuarter   = FQData<1>
    FQStartDt       = FQData<2>
    FQEndDt         = FQData<3>
    
    DataArray = ''
    DataArray<1,ROW$TOT_REACTOR_OUTS>   = 'Reactor Outs'
    DataArray<1,ROW$TOT_YIELD_OUTS>     = '  Yield Outs'
    DataArray<1,ROW$TOT_CUST_SCRAP>     = '  Sup/Cust Scrap'
    DataArray<1,ROW$TOT_EPI_SCRAP>      = '  IFX Scrap'
    DataArray<1,ROW$TOT_OTHER>          = '  Prod Test'
    DataArray<1,ROW$TOT_DUMMY>          = '  Dummy'
    DataArray<1,ROW$TOT_YIELD>          = '  Yield %'
    DataArray<1,ROW$TOT_SCRAP_RATE>     = '  Scrap/1k'
    DataArray<1,ROW$TOT_SHIP>           = '  Shipped'
    
    DataArray<COL$MON,1>                = 'Monday ':WeekDates<1,1>
    DataArray<COL$TUE,1>                = 'Tuesday ':WeekDates<1,2>
    DataArray<COL$WED,1>                = 'Wednesday ':WeekDates<1,3>
    DataArray<COL$THU,1>                = 'Thursday ':WeekDates<1,4>
    DataArray<COL$FRI,1>                = 'Friday ':WeekDates<1,5>
    DataArray<COL$SAT,1>                = 'Saturday ':WeekDates<1,6>
    DataArray<COL$SUN,1>                = 'Sunday ':WeekDates<1,7>
    DataArray<COL$WTD_ACTUAL,1>         = 'WTD Actual'
    DataArray<COL$QTD_ACTUAL,1>         = 'QTD Actual'
    DataArray<COL$QTD_MF_PLAN,1>    	= 'MF QTY Plan'            ;* dkk 12/30/13
    DataArray<COL$QTD_MF_REMAIN,1>  	= 'MF QTD Remain'          ;* dkk 12/30/13
    DataArray<COL$ORG_MF_DAILY_PLAN,1>  = 'MF Plan Daily'          ;* dkk 12/30/13
    DataArray<COL$QTD_MF_OVER_UNDER,1>  = 'MF QTD   +/-'           ;* dkk 12/30/13
    
    FQRec = XLATE('FISCAL_QTR',FiscalYear:'*':FiscalQuarter,'','X')
    
    TargKeys = ''
    
    FOR I = 1 TO COUNT(FQRec<FISCAL_QTR_THRU_GROUP$>,@VM) + (FQRec<FISCAL_QTR_THRU_GROUP$> NE '')
        TargKey     = FQRec<FISCAL_QTR_THRU_GROUP$,I>:'*':FQRec<FISCAL_QTR_THRU_TARGET$,I>
        TargQty     = OCONV(FQRec<FISCAL_QTR_THRU_QTY$,I>,'MD0,Z')
        TargPcnt    = OCONV(FQRec<FISCAL_QTR_THRU_PCNT$,I>, 'MD2%SZ')
        
        BEGIN CASE
            CASE TargKey = 'GANTOT*Reactor_Outs'     	   ; DataArray<COL$QTD_MF_PLAN,ROW$TOT_REACTOR_OUTS>  = TargQty
            CASE TargKey = 'GANTOT*Yield_Outs'             ; DataArray<COL$QTD_MF_PLAN,ROW$TOT_YIELD_OUTS>    = TargQty
            CASE TargKey = 'GANTOT*IFX_Scrap'              ; DataArray<COL$QTD_MF_PLAN,ROW$TOT_EPI_SCRAP>     = TargQty
            CASE TargKey = 'GANTOT*Prod_Test'              ; DataArray<COL$QTD_MF_PLAN,ROW$TOT_OTHER>         = TargQty
            CASE TargKey = 'GANTOT*Yield'                  ; DataArray<COL$QTD_MF_PLAN,ROW$TOT_YIELD>         = TargPcnt
        END CASE
    NEXT I
    
    DataArray<COL$PERIOD,1>             = 'Fiscal Period'
    DataArray<COL$PERIOD_VALUE,1>       = ''
    DataArray<COL$PERIOD_START,1>       = 'Start Date'
    DataArray<COL$PERIOD_END,1>         = 'End Date'
    
    DataArray<COL$PERIOD,2>             = 'Week'
    DataArray<COL$PERIOD_VALUE,2>       = FiscalWeek
    DataArray<COL$PERIOD_START,2>       = FWStartDt
    DataArray<COL$PERIOD_END,2>         = FWEndDt
    
    DataArray<COL$PERIOD,3>             = 'Quarter'
    DataArray<COL$PERIOD_VALUE,3>       = FiscalQuarter
    DataArray<COL$PERIOD_START,3>       = FQStartDt
    DataArray<COL$PERIOD_END,3>         = FQEndDt
    
    DataArray<COL$PERIOD,5>             = 'QTD As Of'
    DataArray<COL$PERIOD_VALUE,5>       = ''
    DataArray<COL$PERIOD_START,5>       = ''
    DataArray<COL$PERIOD_END,5>         = CutOffDt
    
    DataArray<COL$PERIOD,7>             = 'Ran At'
    DataArray<COL$PERIOD_VALUE,7>       = ''
    DataArray<COL$PERIOD_START,7>       = OCONV(Date(),'D4/')
    DataArray<COL$PERIOD_END,7>         = OCONV(Time(),'MTH')
    
    FQRec           = XLATE('FISCAL_QTR',FiscalYear:'*':FiscalQuarter,'','X')
    QtrStartDt      = FQRec<FISCAL_QTR_START_DT$>
    QtrEndDt        = FQRec<FISCAL_QTR_END_DT$>
    PlanIdleDts     = FQRec<FISCAL_QTR_PLAN_IDLE_DTS_GAN$>
    
    IF QtrStartDt = '' THEN
        ErrMsg('Fiscal Quarter ':FiscalYear:'*':FiscalQuarter:' is missing the start date.')
        RETURN
    END
    
    IF QtrEndDt = '' THEN
        ErrMsg('Fiscal Quarter ':FiscalYear:'*':FiscalQuarter:' is missing the end date.')
        RETURN
    END
    
    IF QtrStartDt >= QtrEndDt THEN
        ErrMsg('Fiscal Quarter ':FiscalYear:'*':FiscalQuarter:' has incorrect Start and/or End dates.')
        RETURN
    END
    
    TotQtrDays      = QtrEndDt - QtrStartDt + 1
    QtrDaysRem      = QtrEndDt - thisCutOffDt
    PlanIdleDaysRem = 0
    
    PlanDtCnt = COUNT(PlanIdleDts,@VM) + (PlanIdleDts NE '')
    FOR I = 1 TO PlanDtCnt
        PlanIdleDt = PlanIdleDts<1,I>
        IF PlanIdleDt >= thisCutOffDt THEN PlanIdleDaysRem += 1
    NEXT I
    
    PlanIdleDays    = PlanDtCnt
    
    PlanWorkingDays = TotQtrDays - PlanIdleDays
    
    IF PlanWorkingDays < 0 THEN PlanWorkingDays = 0
    
    PlanDaysRem = QtrDaysRem - PlanIdleDaysRem
    IF PlanDaysRem < 0 THEN PlanDaysRem = 0
    
    BEGIN CASE
        CASE QtrDaysRem = ''
            CalDaysDelta = ICONV(FWEndDt,'D') - ICONV(FQStartDt,'D')
            DaysWorked = INT((CalDaysDelta/TotQtrDays) * PlanWorkingDays)
            
        CASE PlanWorkingDays > PlanDaysRem
            DaysWorked = PlanWorkingDays - PlanDaysRem
            
        CASE 1
            DaysWorked = 0
            
    END CASE
    
    DataArray<COL$PERIOD,9>		= 'Actual Quarter Days'         ;   DataArray<COL$PERIOD_VALUE,9>  = TotQtrDays
    DataArray<COL$PERIOD,10>    = 'Planned Working Days'        ;   DataArray<COL$PERIOD_VALUE,10> = PlanWorkingDays
    DataArray<COL$PERIOD,11>    = 'Actual Days Left'            ;   DataArray<COL$PERIOD_VALUE,11> = QtrDaysRem
    DataArray<COL$PERIOD,12>    = 'Total Idle Days'             ;   DataArray<COL$PERIOD_VALUE,12> = PlanIdleDays
    DataArray<COL$PERIOD,13>    = 'Idle Days Left'              ;   DataArray<COL$PERIOD_VALUE,13> = PlanIdleDaysRem
    DataArray<COL$PERIOD,14>    = 'Planned Days Left'           ;   DataArray<COL$PERIOD_VALUE,14> = PlanDaysRem
    
    OPEN 'DICT.REACT_RUN' TO @DICT ELSE
        ErrMsg('Unable to open "DICT.REACT_RUN" for index lookup')
        RETURN
    END
    
    OPEN 'REACT_RUN' TO ReactRunTable ELSE
        ErrMsg('Unable to open "REACT_RUN" to read records')
        RETURN
    END
    
    * Fudge the dates - '~' is not inclusive of the end dates
    StartDt = ICONV(FQStartDt,'D') - 1
    EndDt   = thisCutOffDt + 1
    
    SearchString = 'UNLOAD_DT':@VM:StartDt:'~':EndDt:@FM:'REACTOR_TYPE':@VM:"GAN":@FM     ;**************
    
    ReactRunKeys = ''
    Option = ''
    Flag = ''
    
    Def = ""
    Def<MTEXT$> = "Selecting REACT_RUN records..."
    Def<MTYPE$> = "U"
    MsgUp = Msg(@window, Def)   ;* display the processing message
    
    Set_Status(0)
    Btree.Extract(SearchString, 'REACT_RUN', @DICT, ReactRunKeys, Option, Flag)
    
    Msg(@WINDOW, MsgUp)
    
    IF Get_Status(errCode) THEN
        ErrMsg(errCode)
        RETURN
    END
    
    IF ReactRunKeys = '' THEN
        ErrMsg('No REACT_RUN Records found for the current quarter!')
        RETURN
    END
    
    ReactRunCnt  = COUNT(ReactRunKeys,@VM) + (ReactRunKeys NE '')
    LoopCnt = 0
    LastCheck = 0
    
    Def = ""
    Def<MCAPTION$>      = "Building Report..."
    Def<MTYPE$>         = "GC"
    Def<MEXTENT$>       = ReactRunCnt
    Def<MTEXTWIDTH$>    = 600
    
    AArray = ''
    AATot = 0
    MerProdRow = ''     ;* Moved from line 588 - dkk 1/13/14
    CapFabRow = 9       ;* Moved from line 589 - dkk 1/13/14
    
    MsgUp = Msg(@WINDOW, Def)
    
    LOOP
        @ID = ReactRunKeys[1,@VM]
        ReactRunKeys[1,COL2()] = ''
        LoopCnt += 1

        READ @RECORD FROM ReactRunTable,@ID THEN
                        
            YieldInfo = Gan_Services('GetYieldInfo', @ID)
            GRWfrQty  = YieldInfo<1>
            ScrapQty  = YieldInfo<2>
            ProdTWQty = YieldInfo<3>
            DummyQty  = YieldInfo<4>
            WafersOut = GRWfrQty - ScrapQty - ProdTWQty - DummyQty
            ReactorsOut = GRWfrQty
            AATot = AATot + ReactorsOut

            AArray<LoopCnt,1> = @ID
            AArray<LoopCnt,2> = AATot
            AArray<LoopCnt,3> = ReactorsOut
            
            NCRNos        = Xlate('REACT_RUN', @ID, 'NCR_NOS', 'X')
            NCRsByStage   = obj_NCR('StageBy', NCRNos)
            LSLPreScrap   = Sum(Xlate('NCR', NCRsByStage<1>, 'REJ_CNT', 'X'))
            LSLPostScrap  = Sum(Xlate('NCR', NCRsByStage<2>, 'REJ_CNT', 'X'))
            CustPreScrap  = Sum(Xlate('NCR', NCRsByStage<3>, 'REJ_CNT', 'X'))
            CustPostScrap = Sum(Xlate('NCR', NCRsByStage<4>, 'REJ_CNT', 'X'))
            CustScrap     = CustPreScrap + CustPostScrap
            IFXEpiScrap   = LSLPreScrap + LSLPostScrap
            
            OtherWafers = ProdTWQty
            
            DateOut = {UNLOAD_DT}
            Day = MOD(DateOut,7)
            
            BEGIN CASE
                CASE Day = 0 ; DayCol = COL$SUN
                CASE Day = 1 ; DayCol = COL$MON
                CASE Day = 2 ; DayCol = COL$TUE
                CASE Day = 3 ; DayCol = COL$WED
                CASE Day = 4 ; DayCol = COL$THU
                CASE Day = 5 ; DayCol = COL$FRI
                CASE Day = 6 ; DayCol = COL$SAT
            END CASE
            
            DateOut = OCONV(DateOut,'D4/')
            
            RDSFiscalWeek = obj_Calendar('IRFiscalWeek',DateOut)<1> ;* 2nd and 3rd fields are the start and end dates of the week
            
            
            DataArray<COL$QTD_ACTUAL,ROW$TOT_REACTOR_OUTS>  = DataArray<COL$QTD_ACTUAL,ROW$TOT_REACTOR_OUTS> + ReactorsOut
            DataArray<COL$QTD_ACTUAL,ROW$TOT_YIELD_OUTS>    = DataArray<COL$QTD_ACTUAL,ROW$TOT_YIELD_OUTS> + WafersOut
            DataArray<COL$QTD_ACTUAL,ROW$TOT_CUST_SCRAP>    = DataArray<COL$QTD_ACTUAL,ROW$TOT_CUST_SCRAP> + CustScrap
            DataArray<COL$QTD_ACTUAL,ROW$TOT_EPI_SCRAP>     = DataArray<COL$QTD_ACTUAL,ROW$TOT_EPI_SCRAP> + IFXEpiScrap
            DataArray<COL$QTD_ACTUAL,ROW$TOT_OTHER>         = DataArray<COL$QTD_ACTUAL,ROW$TOT_OTHER> + OtherWafers
            DataArray<COL$QTD_ACTUAL,ROW$TOT_DUMMY>         = DataArray<COL$QTD_ACTUAL,ROW$TOT_DUMMY> + DummyQty
            
            Divisor = (DataArray<COL$QTD_ACTUAL,ROW$TOT_REACTOR_OUTS>)
            If Divisor > 0 then               
                Yield =  1 - (DataArray<COL$QTD_ACTUAL,ROW$TOT_EPI_SCRAP> / Divisor)
                DataArray<COL$QTD_ACTUAL,ROW$TOT_YIELD> = OCONV(ICONV(Yield*100,'MD2'),'MD2S%')
            end else
                Yield = 0
            end
            
            **********************
            * IFX Scrap Rate Row *
            **********************
            IF DataArray<COL$QTD_ACTUAL,ROW$TOT_REACTOR_OUTS> > 0 THEN
                ScrapRate = (DataArray<COL$QTD_ACTUAL,ROW$TOT_EPI_SCRAP> / DataArray<COL$QTD_ACTUAL,ROW$TOT_YIELD_OUTS>) * 1000
            END ELSE
                ScrapRate = 0
            END
            DataArray<COL$QTD_ACTUAL,ROW$TOT_SCRAP_RATE> = OCONV(ICONV(ScrapRate,'MD2'),'MD2')
            
            **********************************
            * Begin of Planning Calculations *
            **********************************
            
            *************
            * Scrap Row *
            *************
            QTDRem = (ICONV(DataArray<COL$QTD_MF_PLAN,ROW$TOT_EPI_SCRAP>,'MD0') - ICONV(DataArray<COL$QTD_ACTUAL,ROW$TOT_EPI_SCRAP>,'MD0'))
            DataArray<COL$QTD_MF_REMAIN,ROW$TOT_EPI_SCRAP> = OCONV(QTDRem,'MD0,')
            
            IF PlanWorkingDays = 0 THEN
                OrgDailyPlan = 0
            END ELSE
                OrgDailyPlan = ICONV(DataArray<COL$QTD_MF_REMAIN,ROW$TOT_EPI_SCRAP>,'MD0')/PlanDaysRem
            END
            DataArray<COL$ORG_MF_DAILY_PLAN,ROW$TOT_EPI_SCRAP> = OCONV(ICONV(OrgDailyPlan,'MD0'),'MD0')
            
            IF OrgDailyPlan NE 0 THEN
                PlanQTD = ICONV((ICONV(DataArray<COL$QTD_MF_PLAN,ROW$TOT_EPI_SCRAP>,'MD0')/PlanWorkingDays)*DaysWorked,'MD0')
                QTDOverUnder = ICONV(DataArray<COL$QTD_ACTUAL,ROW$TOT_EPI_SCRAP> - PlanQTD,'MD0')
                DataArray<COL$QTD_MF_OVER_UNDER,ROW$TOT_EPI_SCRAP> = OCONV(QTDOverUnder,'MD0,')
            END
            
            ******************
            * Yield Outs Row *
            ******************
            QTDRem = (ICONV(DataArray<COL$QTD_MF_PLAN,ROW$TOT_YIELD_OUTS>,'MD0') - ICONV(DataArray<COL$QTD_ACTUAL,ROW$TOT_YIELD_OUTS>,'MD0'))
            DataArray<COL$QTD_MF_REMAIN,ROW$TOT_YIELD_OUTS> = OCONV(QTDRem,'MD0,')
            
            IF PlanWorkingDays = 0 THEN
                OrgDailyPlan = 0
            END ELSE
                OrgDailyPlan = ICONV(DataArray<COL$QTD_MF_REMAIN,ROW$TOT_YIELD_OUTS>,'MD0')/PlanDaysRem
            END
            DataArray<COL$ORG_MF_DAILY_PLAN,ROW$TOT_YIELD_OUTS> = OCONV(ICONV(OrgDailyPlan,'MD0'),'MD0')
            
            IF OrgDailyPlan NE 0 THEN
                PlanQTD = ICONV((ICONV(DataArray<COL$QTD_MF_PLAN,ROW$TOT_YIELD_OUTS>,'MD0')/PlanWorkingDays)*DaysWorked,'MD0')
                QTDOverUnder = ICONV(DataArray<COL$QTD_ACTUAL,ROW$TOT_YIELD_OUTS> - PlanQTD,'MD0')
                DataArray<COL$QTD_MF_OVER_UNDER,ROW$TOT_YIELD_OUTS> = OCONV(QTDOverUnder,'MD0,')
            END
            
            ********************************
            * End of Planning Calculations *
            ********************************
            
            IF RDSFiscalWeek = FiscalWeek THEN
                
                
                IF DayCol NE '' THEN
                    DataArray<DayCol,ROW$TOT_REACTOR_OUTS>  = DataArray<DayCol,ROW$TOT_REACTOR_OUTS> + ReactorsOut
                    DataArray<DayCol,ROW$TOT_YIELD_OUTS>    = DataArray<DayCol,ROW$TOT_YIELD_OUTS> + WafersOut
                    DataArray<DayCol,ROW$TOT_CUST_SCRAP>    = DataArray<DayCol,ROW$TOT_CUST_SCRAP> + CustScrap
                    DataArray<DayCol,ROW$TOT_EPI_SCRAP>     = DataArray<DayCol,ROW$TOT_EPI_SCRAP> + IFXEpiScrap
                    DataArray<DayCol,ROW$TOT_OTHER>         = DataArray<DayCol,ROW$TOT_OTHER> + OtherWafers
                    DataArray<DayCol,ROW$TOT_DUMMY>         = DataArray<DayCol,ROW$TOT_DUMMY> + DummyQty                   
                    
                    Divisor = DataArray<DayCol,ROW$TOT_REACTOR_OUTS>
                    IF Divisor > 0 THEN
                        Yield = 1 - (DataArray<DayCol,ROW$TOT_EPI_SCRAP> / Divisor)
                    END ELSE
                        Yield = 0
                    END
                    
                    DataArray<DayCol,ROW$TOT_YIELD> = OCONV(ICONV(Yield*100,'MD2'),'MD2S%')
                END
                
                DataArray<COL$WTD_ACTUAL,ROW$TOT_REACTOR_OUTS> = DataArray<COL$WTD_ACTUAL,ROW$TOT_REACTOR_OUTS> + ReactorsOut
                DataArray<COL$WTD_ACTUAL,ROW$TOT_YIELD_OUTS>   = DataArray<COL$WTD_ACTUAL,ROW$TOT_YIELD_OUTS> + WafersOut
                DataArray<COL$WTD_ACTUAL,ROW$TOT_CUST_SCRAP>   = DataArray<COL$WTD_ACTUAL,ROW$TOT_CUST_SCRAP> + CustScrap
                DataArray<COL$WTD_ACTUAL,ROW$TOT_EPI_SCRAP>    = DataArray<COL$WTD_ACTUAL,ROW$TOT_EPI_SCRAP> + IFXEpiScrap
                DataArray<COL$WTD_ACTUAL,ROW$TOT_OTHER>        = DataArray<COL$WTD_ACTUAL,ROW$TOT_OTHER> + OtherWafers
                DataArray<COL$WTD_ACTUAL,ROW$TOT_DUMMY>        = DataArray<COL$WTD_ACTUAL,ROW$TOT_DUMMY> + DummyQty
                
                Divisor = DataArray<COL$WTD_ACTUAL,ROW$TOT_REACTOR_OUTS>
                If Divisor > 0 then
                    Yield = 1 - (DataArray<COL$WTD_ACTUAL,ROW$TOT_EPI_SCRAP> / Divisor)
                end else
                    Yield = 0
                end

                DataArray<COL$WTD_ACTUAL,ROW$TOT_YIELD> = OCONV(ICONV(Yield*100,'MD2'),'MD2S%')
                
                * Scrap Rate
                IF DataArray<COL$WTD_ACTUAL,ROW$TOT_YIELD_OUTS> > 0 THEN
                    ScrapRate = (DataArray<COL$WTD_ACTUAL,ROW$TOT_EPI_SCRAP>/DataArray<COL$WTD_ACTUAL,ROW$TOT_YIELD_OUTS>)*1000
                END ELSE
                    ScrapRate = 0
                END
                DataArray<COL$WTD_ACTUAL,ROW$TOT_SCRAP_RATE> = OCONV(ICONV(ScrapRate,'MD2'),'MD2')
                
            END     ;*  End of check for current fiscal week
            
        END ;* End of RDS Record read
        
        Running = Msg(@WINDOW, MsgUp, LoopCnt, MSGINSTUPDATE$) 
        
        
    UNTIL ReactRunKeys = '' OR NOT(Running)
    REPEAT
    
    Msg(@WINDOW,MsgUp)      ;* Take message down
    
    * * * * New Section to calculate Shipments - JCH 3/26/2014  ********************************************************
    
    OPEN 'COC' TO ShipTable ELSE
        ErrMsg('Unable to open COC for report.')
        RETURN
    END
    
    OPEN 'DICT.COC' TO @DICT ELSE
        ErrMsg('Unable to open DICT.COC for report.')
        RETURN
    END
    
    StartDt = ICONV(FQStartDt,'D') - 1
    EndDt  = ICONV(FWEndDt,'D') + 1        ;* 12/2/2015 JCH - Use cutoff date for data selection rather than week ending date
    EndDt   = thisCutOffDt + 1
    
    SearchString = 'SHIP_DT':@VM:StartDt:'~':EndDt:@FM
    
    ShipKeys = ''
    Option = ''
    Flag = ''
    
    Def = ""
    Def<MTEXT$> = "Selecting Shipment records..."
    Def<MTYPE$> = "U"
    MsgUp = Msg(@window, Def)   ;* display the processing message
    
    Set_Status(0)
    Btree.Extract(SearchString, 'COC', @DICT, ShipKeys, Option, Flag)
    
    Msg(@WINDOW, MsgUp)
    
    IF Get_Status(errCode) THEN
        ErrMsg(errCode)
        RETURN
    END
    
    IF ShipKeys = '' THEN
        ErrMsg('No Shipment Records found for the current quarter!')
        RETURN
    END
    
    ShipCnt = COUNT(ShipKeys,@VM) + (ShipKeys NE '')
    LoopCnt = 0
    LastCheck = 0
    
    Def = ""
    Def<MCAPTION$>      = "Building Report Shipments..."
    Def<MTYPE$>         = "GC"
    Def<MEXTENT$>       = ShipCnt
    Def<MTEXTWIDTH$>    = 600
    
    MsgUp = Msg(@WINDOW, Def)
    
    LOOP
        @ID = ShipKeys[1,@VM]
        ShipKeys[1,COL2()] = ''
        LoopCnt += 1
        
        READ @RECORD FROM ShipTable,@ID THEN
            RDSNos = {RDS_NO}
            For each RDSNo in RDSNos using @VM
                ReactorType = Xlate('RDS', RDSNo, 'REACTOR_TYPE', 'X')
                If ReactorType EQ 'GAN' then
                    
                    ShipQty = 0
                    OutSlotIDs = Xlate('REACT_RUN', RDSNo, 'OUT_SLOT_ID', 'X')
                    For each OutSlotID in OutSlotIDs using @VM
                        If OutSlotID NE '' then ShipQty += 1
                    Next OutSlotID
                    
                    ShipDt  = @RECORD<COC_SHIP_DT$>
                    Day     = MOD(ShipDt,7)
                    
                    BEGIN CASE
                        CASE Day = 0 ; DayCol = COL$SUN
                        CASE Day = 1 ; DayCol = COL$MON
                        CASE Day = 2 ; DayCol = COL$TUE
                        CASE Day = 3 ; DayCol = COL$WED
                        CASE Day = 4 ; DayCol = COL$THU
                        CASE Day = 5 ; DayCol = COL$FRI
                        CASE Day = 6 ; DayCol = COL$SAT
                    END CASE
                    
                    ShipDt = OCONV(ShipDt,'D4/')
                    ShipFiscalWeek = obj_Calendar('IRFiscalWeek',ShipDt)<1> ;* 2nd and 3rd fields are the start and end dates of the week
                    
                    Row = ROW$TOT_SHIP
                    DataArray<COL$QTD_ACTUAL,Row> = DataArray<COL$QTD_ACTUAL,Row> + ShipQty
                    
                    IF ShipFiscalWeek = FiscalWeek THEN
                        DataArray<COL$WTD_ACTUAL,Row> = DataArray<COL$WTD_ACTUAL,Row> + ShipQty 
                        DataArray<DayCol,Row> = DataArray<DayCol,Row> + ShipQty
                    END
                end
                
            Next RDSNo
            
        END ;* End of Shipment Record Read
        
        Running = Msg(@WINDOW, MsgUp, LoopCnt, MSGINSTUPDATE$) 
        
    UNTIL ShipKeys = '' OR NOT(Running)
        
    REPEAT
    
    **************************************
    * Beginning Of Planning Calculations *
    **************************************
    
    ***************
    * Shipped Row *
    ***************
    QTDRem = (ICONV(DataArray<COL$QTD_MF_PLAN,ROW$TOT_SHIP>,'MD0') - ICONV(DataArray<COL$QTD_ACTUAL,ROW$TOT_SHIP>,'MD0'))
    DataArray<COL$QTD_MF_REMAIN,ROW$TOT_SHIP> = OCONV(QTDRem,'MD0,')
    
    IF PlanWorkingDays = 0 THEN
        OrgDailyPlan = 0
    END ELSE
        OrgDailyPlan = ICONV(DataArray<COL$QTD_MF_REMAIN,ROW$TOT_SHIP>,'MD0')/PlanDaysRem
    END
    DataArray<COL$ORG_MF_DAILY_PLAN,ROW$TOT_SHIP> = OCONV(ICONV(OrgDailyPlan,'MD0'),'MD0')
    
    IF OrgDailyPlan NE 0 THEN
        PlanQTD = ICONV((ICONV(DataArray<COL$QTD_MF_PLAN,ROW$TOT_SHIP>,'MD0')/PlanWorkingDays)*DaysWorked,'MD0')
        QTDOverUnder = ICONV(DataArray<COL$QTD_ACTUAL,ROW$TOT_SHIP> - PlanQTD,'MD0')
        DataArray<COL$QTD_MF_OVER_UNDER,ROW$TOT_SHIP> = OCONV(QTDOverUnder,'MD0,')
    END
    
    ********************************
    * End Of Planning Calculations *
    ********************************
    
    * * * * * End of shipment section   
    
    FOR I = ROW$TOT_REACTOR_OUTS TO ROW$TOT_SHIP
        IF I NE ROW$TOT_YIELD THEN
            FOR J = COL$MON TO COL$QTD_ACTUAL
                DataArray<J,I> = OCONV(DataArray<J,I>,'MD0,Z')
            NEXT J
        END
    NEXT I
    
    IF @USER4 EQ 'DANIEL_ST' THEN
        // This block of code to copy the report to the clipboard. This is necessary for debugging in
        // development environments that do not have Excel installed.
        PasteBlob = ''
        
        FOR I = 1 TO ROW$BLANK_LINE_1
            FOR J = 1 TO COL$PERIOD_END
                PasteBlob<I,J> = DataArray<J,I>
            NEXT J
        NEXT I
        
        SWAP @VM WITH CHAR(9) IN PasteBlob
        SWAP @FM WITH CRLF$ IN PasteBlob
        CALL Set_Property('CLIPBOARD', 'TEXT', PasteBlob)
        
        Msg(@WINDOW,MsgUp)      ;* Take message down
        
        RETURN
        
    END
    
    Msg(@WINDOW,MsgUp)
    
    xlApp = OleCreateInstance("excel.Application")                              ;* Create instance of Excel
    OlePutProperty(XlApp, 'Visible', xlSheetVisible)
    if OleStatus() then Goto HadError
    
    xlWorkBooks =OleGetProperty(xlApp, "Workbooks")                             ;* Create workbook
    xlWkb = OleCallMethod(xlWorkbooks,"Add")
    if OleStatus() then Goto HadError
    
    xlSht = OleGetProperty(xlWkb, "Worksheets",1)                               ;* Select worksheet 1
    if OleStatus() then Goto HadError
    
    xlPageSetup = OleGetProperty(xlSht,"PageSetup")                             ;* Get PageSetup object for Page/Printing stuff
    if OleStatus() then GOTO HadError
    
    OlePutProperty( xlPageSetup , 'PrintGridLines', xlTrue )                                        ;* Print Gridlines on
    OlePutProperty( xlPageSetup , 'Orientation' , xlLandscape )                                     ;* Orientation to Landscape
    OlePutProperty( xlPageSetup , 'HeaderMargin', '20')                                             ;* HeaderMargin to 20pts
    
    OlePutProperty( xlPageSetup , 'CenterHeader' , '&14Epi SERVICES - Thruput Report - w/o Makeup Activity' )       ;* Set Center Header
    OlePutProperty( xlPageSetup , 'LeftHeader' , '&G' )                                             ;* Set graphic in Left Header
    
    graphic = OleGetProperty( xlPageSetup , 'LeftHeaderPicture' )                                   ;* Get graphic object for Left Header Picture
    OlePutProperty( graphic , 'FileName' , 'R:\Oinsight\BMPS\EpiSvcs.png' )                         ;* Set filename for graphic
    OlePutProperty( graphic , 'Height' , '51.75' )                                                  ;* Scale graphic to fit header      
    OlePutProperty( graphic , 'Width' , '81')
    
    OlePutProperty( xlPageSetup , 'RightHeader' , 'Page &P' )                   ;* Set Right Header to show current page number
    
    
    ColCnt = COUNT(DataArray,@FM) + (DataArray NE '')
    LineCnt = COUNT(DataArray<1>,@VM) + (DataArray<1> NE '')
    FOR LineNo = 1 TO LineCnt
        FOR Column = 1 to ColCnt
            RangeColumn = eXcelCols<1,Column>
            range = OleGetProperty( xlSht, 'Range',RangeColumn:LineNo)
            OlePutProperty(range, 'Value', DataArray<Column,LineNo>)            ;* Load report array into spreadsheet cells
            IF OleStatus() THEN GOTO HadError
        NEXT Column
    NEXT LineCnt
    
    LastColumn = eXcelCols<1,ColCnt>
    range = OleGetProperty( xlSht, 'Range','B1:':LastColumn:'1')                ;* Turn on word wrap in columns from B through end
    OlePutProperty( range, 'WrapText', xlTrue)
    IF OleStatus() THEN GOTO HadError
    
    RangeColumn = eXcelCols<1,ColCnt>
    range = OleGetProperty( xlSht, 'Range','A1:':RangeColumn:LineCnt)
    
    Void = OleCallMethod( range, 'AutoFormat', xlRangeAutoFormatClassic1 )      ;* Turn on autoformat (FormatClassic1)
    IF OleStatus() THEN GOTO HadError
    
    FOR I = COL$MON TO COL$SUN
        eXcelCol = eXcelCols<1,I>
        column = OleGetProperty( xlSht, 'Range' , eXcelCol:':':exCelCol )       ;* Set the day columns to a standard width
        OlePutProperty( column , 'ColumnWidth' , '10.6' )                       ;* Originally 10.3 - changed to 10.6 to fit Wednesday - dkk 12/30/13
        a = OleStatus()
    NEXT I
    
    EdgeList = xlDiagonalDown:@VM:xlDiagonalup:@VM:xlEdgeLeft:@VM:xlEdgeTop:@VM:xlEdgeRight:@VM:xlInsideVertical
    
    * Put border on the BOTTOM of this row
    
    range = OleGetProperty( xlSht, 'Range', 'A':ROW$TOT_SHIP:':':RangeColumn:ROW$TOT_SHIP)
    
    FOR I = 1 TO COUNT(EdgeList,@VM) + (EdgeList NE '')
        edge = OleGetProperty( range, 'Borders' , EdgeList<1,I> )
        OlePutProperty( edge , 'LineStyle' , xlLineStyleNone )                  ;* Clear border segments EXCEPT bottom
    NEXT I
    * Set border segment for bottom to medium weight line
    edge = OleGetProperty( range, 'Borders' , xlEdgeBottom )                    
    olePutProperty( edge , 'LineStyle', xlContinuous )
    olePutProperty( edge , 'Weight' , xlMedium )
    olePutProperty( edge , 'ColorIndex', xlColorIndexAutomatic )
    * Save to local drive
    Void = OleCallMethod( xlWkb, 'SaveAs',Environment_Services('GetReportsRootPath') : '\ThruPut.xls', xlWorkbookNormal)        
    
RETURN


* * * * * * *
HadError:
* * * * * * *
    
    xlChart = ''
    Charts = ''
    range = ''
    xlSht = ''
    xlWkb=''
    xlWorkBooks = ''
    x = OleCallMethod(xlApp, 'Quit')
    
RETURN 
