          PH.ARGS DRPT,BRCHS,BR,SD,ED,SLCT,SLIST,SEL.SORTBY,PG,HDR,PERD,CLMN,DET,INCL.EXCL,COST.TYPE,FITEM
** Version# 78.0002[92] - 02/07/2014 - 10:18am - TSMITH - eclipse
*** V78.0002 Change - Custom Coding . - 02/07/2014 - TSMITH - eclipse
** Copied from BP SLS.PHR.ITEM.SALES Version# 78 - 09/18/2009 - 02:33pm - KEVINM - main

*** Program: SLS.PHR.ITEM.SALES
*-------------------------------------------------------------------------*
*** This is the phantom routine for the Item Sales Report. It allows the
*** user to perform powerful product sales analysis. The report will
*** display data matching Select criteria set by the user from the Driver.
*** The user can also set Primary and Secondary Sorts, as well as the level
*** of detail they wish to see. Finally, the user can run the report for a
*** single time period OR run a comparison report showing sales totals for
*** two or three periods of time.
*-------------------------------------------------------------------------*
*** DRPT       - A standard report parameter.                      [IN]
*** BRCHS      - Branches to Select invoices for.                  [IN]
*** SD         - Start Date                                        [IN]
*** ED         - End Date                                          [IN]
*** SLCT       - Select Type (such as 'Price Line').               (IN)
*** SLIST      - Select Entities.                                  (IN)
*** SEL.SORTBY - A multi-valued Primary and Secondary Sortby list. [IN]
*** PG         - Page on Primary - if set to YES, a page break will be
***              inserted prior to each new report section.        [IN]
*** HDR        - Primary Header - if set to YES, a heading will be
***              inserted for each new report section, based on the
***              Primary Sort.                                     [IN]
*** PERD       - Periods to show data for. If a Start Date is specified,
***              this will be set to 'Start-End Date'.
***              > This parameter also includes any Difference Columns
***              that might be displayed. They are treated as Periods
***              within the structure of this program's logic.     [IN]
*** CLMN       - Column data (such as GP or GP%) the user wishes to see
***              for each time period.                             [IN]
*** DET        - Level of detail user wishes to see.               [IN]
*** INCL.EXCL  - a multi-valued list of order types to show on the
***              report.
***              <1,1> Variable to Include/Exclude/Only show Credits.
***              <1,2> Variable to Include/Exclude/Only show Directs.
***              <1,3> Variable to Include/Exclude Misc Charges.   [IN]
*** COST.TYPE  - Type of Costs to show.                            [IN]
*** FITEM      - Additional Select criteria specific to Ledger
***              Records.                                          (IN)
***
*** !! NOTE: All required parameters are designated by '[]'
*-------------------------------------------------------------------------*
*** SPECIAL NOTE:
***  Because of the potential width of this report, it may not always fit
***  on the page when printing. In such cases the report can be downloaded
***  in order to view all the data.
*-------------------------------------------------------------------------*

          DIM PCUS(200)

          CUS.TOL      = ''
          CUS.TOLS     = ''
          SEL.CREDS    = INCL.EXCL<1,1>
          SHOW.DIR     = INCL.EXCL<1,2>
          SEL.MISC     = INCL.EXCL<1,3>

          INCLUDE.MISC = (SEL.MISC[1,1] = 'I')

          PRI.SBY      = SEL.SORTBY<1,1>
          SEC.SBY      = SEL.SORTBY<1,2>
          SSBY.TYPE    = 1
          SV.SEL.GRP   = ''
          SV.BUY.GRP   = ''
          TB=CHAR(44)
          IF SEC.SBY = 'Product' OR SEC.SBY[1,7] = 'Bill-To' OR SEC.SBY[1,7] = 'Ship-To' OR SEC.SBY[1,6] = 'Parent' OR DET[1,3] = 'Sec' THEN SSBY.TYPE = 2

          SDT = OCONV(SD,'D4/')
          EDT = OCONV(ED,'D4/')
          DLM = CHAR(32)

          BRS = BR

          READ GL.TYPES FROM CTRLFILE,'GL.PRODUCT.TYPE' ELSE GL.TYPES=''
          READ PRD.STATS FROM CTRLFILE,'PROD.STATUS' ELSE PRD.STATS = ''

          MAX.SSBY     = 0
          IF COST.TYPE = 3 THEN COST.TYPE = ''
          PH.COST.DESC COST.TYPE,COST.DESC
          SORTBY.MSG   = ' by ':PRI.SBY

          IF SEC.SBY THEN SORTBY.MSG := ' by ':SEC.SBY

          CRED.MSG   = SEL.CREDS:" Credits"
          DIR.MSG    = SHOW.DIR: " Direct Shpmts"
          MISC.MSG   = SEL.MISC: " Misc Charges"

          SEL.CREDS  = SEL.CREDS[1,1]
          INV.DET    = NO
          STL        = 1
          DCNV       = 'MR02,'
          DFMT       = 'R#12':SPACE(1)
          SFMT       = 'R#16':SPACE(1)
          DIFF.DCNV  = 'MR02'

          BEGIN CASE
          CASE DET     = 'Invoice'
             DET.MSG   = 'Invoice Detail'
             INV.DET   = YES
             DCNV      = 'MR2'
             DIFF.DCNV = 'MR2'
          CASE DET     = 'Product'
             DCNV      = 'MR2'
             DET.MSG   = 'Detail'
          CASE DET     = 'Secondary Sort'
             DCNV      = 'MR2'
             DET.MSG   = 'Detail'
             STL       = 2
          CASE OTHERWISE
             DCNV      = 'MR2'
             DET.MSG   = 'Summary'
             STL       = 3
          END CASE

          IF FITEM  = '' THEN FILTER.FLAG = NO ELSE FILTER.FLAG = YES
          COL.HDG   = ''
          PERD.HDG  = ''
          PERD.SDTS = ''
          PERD.EDTS = ''
          CALC.SDT  = 999999
          CALC.EDT  = 0
          CWDTH     = 0
          TTOL      = 0
          MINIMUM.WIDTH = 0

          * Build the Period and Data Column Headings, set up the formatting we'll
          * use and the Start and End Dates for each of the Periods...
          PP = 1

          LOOP
             TPERD = FIELD(PERD,'/',PP)
             UNTIL TPERD = '' DO
             OWDTH = CWDTH
             MINIMUM.WIDTH += 15

             * Build each of the DATA Column Headings and set
             * up the appropriate formatting...
             CC = 1

             LOOP
                TCLMN = FIELD(CLMN,'/',CC)
                UNTIL TCLMN = '' DO

                BEGIN CASE
                CASE TCLMN  = 'Qty'
                   COL.HDG := 'Qty':TB   DFMT
                   CWDTH += 8
                CASE TCLMN  = 'Sales'
                   TWDTH    = 11
                   COL.HDG := 'Sales' SFMT
                   CWDTH   += TWDTH
                CASE TCLMN  = 'Cost'
                   THDG     = COST.DESC
                   TWDTH    = 16
                   COL.HDG := THDG    SFMT
                   CWDTH   += TWDTH
                CASE TCLMN  = 'GP'
                   TWDTH    = 16
                   THDG     = COST.DESC:' GP'
                   COL.HDG := THDG    SFMT
                   CWDTH   += TWDTH
                CASE TCLMN  = 'GP%'
                   COL.HDG := 'GP%' "R#8"
                   CWDTH   += 8
                CASE TCLMN  = 'Unit Price'
                   COL.HDG := '      Unit Price'
                   CWDTH   += 16
                CASE TCLMN  = 'Unit Cost'
                   COL.HDG := ' Unit Cost'
                   CWDTH   += 10
                END CASE
                CC += 1
             REPEAT



             * Here we will set up the Period Column Headings and store
             * the Start and End Dates for each Period...

             * If the Data Column width is less than 13, we'll
             * abbreviate the Period Headings....
             COL.HDG := ' '
             CWDTH += 1
             IF PERD[1,5]#'Start' THEN
                IF PP > 1 THEN PERD.HDG := ' '

                BEGIN CASE
                CASE TPERD = 'Month'
                   REALDATE TDT,'MO/FE/YR',ED
                   PERD.EDTS<PP> = ED
                   * This will give us the text string 'MONTH YEAR'...
                   MHDG = OCONV(TDT,'DMA')
                   IF CWDTH < MINIMUM.WIDTH THEN
                      * Abbreviate the month...
                      MHDG = MHDG[1,3]
                   END
                   *MHDG := ' ':OCONV(TDT,'DY4')

                   * Store our Date...
                   REALDATE TDT,'MO/FB/YR',ED
                   PERD.SDTS<PP> = TDT
                CASE TPERD = 'Month Last Year'
                   REALDATE TDT,'MO/FE/-1',ED
                   PERD.EDTS<PP> = TDT
                   * This will give us the text string 'MONTH YEAR'...
                   MHDG = OCONV(TDT,'DMA')
                   IF CWDTH < MINIMUM.WIDTH THEN
                      * Abbreviate the month...
                      MHDG = MHDG[1,3]
                   END
                   MHDG := ' ':OCONV(TDT,'DY4')

                   * Store our Date...
                   REALDATE TDT,'MO/FB/-1',ED
                   PERD.SDTS<PP> = TDT
                CASE TPERD = 'Last Month'
                   REALDATE TDT,'-1/FE/YR',ED
                   PERD.EDTS<PP> = TDT
                   * This will give us the text string 'MONTH YEAR'...
                   MHDG = OCONV(TDT,'DMA')
                   IF CWDTH < MINIMUM.WIDTH THEN
                      * Abbreviate the month...
                      MHDG = MHDG[1,3]
                   END
                   MHDG := ' ':OCONV(TDT,'DY4')

                   * Store our Date...
                   REALDATE TDT,'-1/FB/YR',ED
                   PERD.SDTS<PP> = TDT
                CASE TPERD = 'Quarter'
                   REALDATE TDT,'-2/FE/YR',ED
                   * This will give us the 1st 3 chars of the 'MONTH'
                   * that the beginning of our Quarter is in...
                   MHDG = OCONV(TDT,'DMA')[1,3]:'-'
                   REALDATE TDT,'MO/FE/YR',ED
                   PERD.EDTS<PP> = ED
                   * This will give us the 1st 3 chars of the 'MONTH'
                   * that the end of our Quarter is in, plus the Year...
                   MHDG := OCONV(TDT,'DMA')[1,3]:' ':OCONV(TDT,'DY4')
                   REALDATE TDT,'-2/FB/YR',ED
                   PERD.SDTS<PP> = TDT
                CASE TPERD = 'YTD'
                   REALDATE TDT,'MO/DA/YR',ED
                   PERD.EDTS<PP> = ED
                   MHDG = 'YTD ':OCONV(TDT,'DY4')
                   REALDATE TDT,'FB/FB/YR',ED
                   PERD.SDTS<PP> = TDT
                CASE TPERD = 'Last YTD'
                   REALDATE TDT,'MO/DA/-1',ED

                   * Get end date last year.  Convert from internal pick
                   * date number to xx/xx/xxxx
                   PR.EDT = OCONV(TDT,'D4/')
                   PR.EMO = PR.EDT[1,2]
                   PR.EDAY = PR.EDT[4,2]
                   PR.EYR = PR.EDT[7,4]

                   * Check to see if the month is 2 (Feb) and if it is the
                   * 28th day.
                   IF PR.EMO = 2 AND PR.EDAY = 28 THEN
                      PR.EDT = "03/01/":PR.EYR
                      TDT = ICONV(PR.EDT,"D")-1
                   END

                   PERD.EDTS<PP> = TDT
                   MHDG = 'YTD ':OCONV(TDT,'DY4')
                   REALDATE TDT,'FB/FB/-1',ED
                   PERD.SDTS<PP> = TDT
                CASE TPERD = 'Difference' OR TPERD = '% Difference'
                   IF CWDTH < MINIMUM.WIDTH THEN
                      IF TPERD[1,1] = '%' THEN
                         MHDG = '% Diff.'
                      END ELSE
                         MHDG = 'Diff.'
                      END
                   END ELSE
                      MHDG = TPERD
                   END
                   PERD.SDTS<PP> = 0
                   PERD.EDTS<PP> = 0
                END CASE
                * Create a String of Dashes equal to the width
                * of the Period Section...
                *THDG = STR('-',CWDTH-OWDTH-1)

                * Insert the Period Heading within our string of dashes.
                * We'll end up with '---- Period Heading ----'...

                THDG[INT(((CWDTH - OWDTH)-LEN(MHDG))/2)+1,LEN(MHDG)] = MHDG

                PERD.HDG := THDG
             END ELSE
                * Otherwise we just need the Start and End Dates...
                REALDATE TDT,SD
                PERD.SDTS<PP> = TDT
                REALDATE TDT,ED
                PERD.EDTS<PP> = TDT
             END

             * As long as this 'Period' wasn't really one of the
             * Difference Columns...
             IF NOT(INDEX(TPERD,'Difference',1)) THEN
                IF PERD.SDTS<PP> < CALC.SDT THEN CALC.SDT = PERD.SDTS<PP>
                IF PERD.EDTS<PP> > CALC.EDT THEN CALC.EDT = PERD.EDTS<PP>
             END
             IF PP = 1 THEN TCOL.HDG = COL.HDG
             PP += 1
          REPEAT

          PERD.CNT = PP - 1
          UT.TEMPFILE.CREATE FLNM.ID,TEMPFILE

          WRITE 'Selecting...' ON PHSTFILE,PID$

          GOSUB SEL.IDS
*-------------------------------------------------------------------------*
*** Set up the heading and title for the report.
          IF PERD[1,5] = 'Start' THEN
             HDG = 'Aquatherm Report for ':SDT:' to ':EDT

          END ELSE
             HDG = 'Item Sales ':DET.MSG:SORTBY.MSG:' thru ':EDT
          END

          IF DRPT<33> = '' THEN
             TITLE = HDG
          END ELSE
             TITLE = DRPT<33>
          END

          SEL.DESC = ''
          SCNT = DCOUNT(SLIST,VM)
          IF SCNT > 1 THEN
             SEL.DESC = "*Multi*"
          END ELSE
             WRK = SLIST
             BEGIN CASE
             CASE SLCT[9,16] ='Customer'
                READV SEL.DESC FROM CUSFILE,WRK,1 ELSE SEL.DESC = ''
             CASE SLCT[9,16] = 'Salesman'
                READV SEL.DESC FROM INIFILE,WRK,1 ELSE SEL.DESC = ''
             CASE OTHERWISE
                SEL.DESC = SLIST
             END CASE
          END
             * Product description heading

             CHDG = 'Customer':TB:'Job':TB:'City':TB:'State':TB
             WDTH = 70

          IF SEC.SBY # '' AND SSBY.TYPE=1 THEN
             IF MAX.SSBY LT LEN(SEC.SBY) THEN MAX.SSBY=LEN(SEC.SBY)
             MAX.SSBY += 1
             SSBY.FMT  = 'L#':MAX.SSBY
             CHDG := SEC.SBY SSBY.FMT
             WDTH += MAX.SSBY
          END
          IF INV.DET THEN
             CHDG := 'Invoice         ShipDate'
             WDTH += 24
          END
          IF PERD[1,5] # 'Start' THEN PHDG = SPACE(WDTH):PERD.HDG ELSE PHDG = ''
          PWDTH  = WDTH
          WDTH  += CWDTH
          CHDG   = CHDG:COL.HDG

          * If our Period Heading is larger than the Report Width
          * we've built...
          IF (LEN(PERD.HDG) + 36) > WDTH THEN WDTH = (LEN(PERD.HDG) + 36)

          * Update the Phantom Status...
          WRITE 'Spooling...' ON PHSTFILE,PID$
          IF LEN(HDG<1,1>) <= WDTH - 11 THEN
             CWDTH = WDTH-11
            * CFMT  = "L#":CWDTH
           *  HDG<1,1> = HDG<1,1>[1,CWDTH] CFMT:' Page:^####'
          END ELSE
          *   HDG<1,1> = HDG<1,1>:'    Page:^####'
             WDTH = LEN(HDG<1,1>)
          END

          *THDR  = 'Branches : ':BRS:'  ':CRED.MSG:' - ':DIR.MSG:' - '
          *THDR := MISC.MSG

          *HDG<1,-1> = 'Branches : ':BRS
          *HDG<1,-1> = CRED.MSG:' - ':DIR.MSG:' - ':MISC.MSG
          *HDG<1,-1> = 'Select Sales By : ':SLCT
          *HDG<1,-1> = 'Primary Sort : ':PRI.SBY:' ; Secondary Sort : ':SEC.SBY
          *HDG<1,-1> = 'Detail Level : ':DET

          IF SLIST THEN
             HDG<1,-1> = 'Selecting ':SLCT:': ':SEL.DESC
          END

          HDG<1,-1> = ''

          IF PHDG # '' THEN HDG<1,-1> = PHDG

          HDG<1,-1> = CHDG

          * Turn our printer on and print the report...
          PRINTER.ON WDTH,TITLE,DOC.ID,HDG,RPT.DFLT=DRPT
          FILTER.PRINT "S",FITEM
          TOLS   = ''
          OSBY   = '@@@':AM:'@@@':AM:'@@@'
          OPHDR  = '@@@'
          OSHDR  = '@@@'

          OLD.TSBY.CUS = ''
          NEW.TSBY.CUS = ''

          SSELECT TEMPFILE

          LOOP
             READNEXT SORTBY ELSE EXIT

             READ TEMPREC FROM TEMPFILE,SORTBY ELSE CONTINUE

             TSBY    = FIELD(SORTBY,DLM,3,2)
             TSBY<2> = FIELD(SORTBY,DLM,2)
             TSBY<3> = FIELD(SORTBY,DLM,1)

             NEW.TSBY.CUS = FIELD(SORTBY,DLM,2)

             FOR TOT.LVL = 3 TO STL STEP -1
                IF TSBY<TOT.LVL>#OSBY<TOT.LVL> AND OSBY<TOT.LVL>#'@@@' THEN
                   GOSUB PRT.TOLS
                   CUS.TOL = ''
                   CUS.TOLS = 0
                   TTOL = ''
                   EXIT
                END
             NEXT TOT.LVL

             NEW.TSBY.CUS = FIELD(SORTBY,DLM,2)
             IF NEW.TSBY.CUS # OLD.TSBY.CUS THEN
                CUS.TOLS = 0
             END

             TDATA = TEMPREC<1>
             TDATA<1,1,1+(PERD.CNT*3)> = 1

             IF TSBY<3> # OSBY<3> AND HDR THEN
                TLINE = TEMPREC<2>
                IF LEN(TLINE) > WDTH THEN
                   TIX   = INDEX(TLINE,':',1)
                   TTAG  = TLINE[1,TIX-1]
                   TLINE = TLINE[TIX+1,9999]
                   TLEN  = WDTH - (TIX+1)
                   FOLDCHAR PLINE,TLINE,TLEN,VCT,','

                   FOR SS = 1 TO 2
                      PRINT TTAG:': ':PLINE<1,SS>
                   NEXT SS
                END ELSE
                   *PRINT TLINE
                END
                *PRINT
             END

             IF DET = 'Invoice' OR DET = 'Product' THEN GOSUB PRT.ONE

             OLD.TSBY.CUS = NEW.TSBY.CUS
             OSBY  = TSBY
             OPHDR = TEMPREC<2>
             OSHDR = TEMPREC<3>

             FOR TT = 1 TO 4
                CUS.TOL = CUS.TOLS<TT>
                CUS.TOL = ADDS(CUS.TOL,TDATA)
                CUS.TOLS<TT> = CUS.TOL
                TTOL = TOLS<TT>
                TTOL = ADDS(TTOL,TDATA)
                TOLS<TT> = TTOL
             NEXT TT

          REPEAT

          IF TTOL THEN
             TOT.LVL = 4
             GOSUB PRT.TOLS
          END

          * Turn our printer off and clean up after ourselves...
          PRINTER.OFF DOC.ID
          UT.TEMPFILE.DELETE FLNM.ID
          UT.PH.CLEANUP
          SEND.MESSAGE 'Phantom',USER.ID,TITLE:' is Complete'
          STOP
*-------------------------------------------------------------------------*
PRT.ONE:  *** Print Sales data for one product...

          PN = FIELD(TSBY<1>,DLM,2)
          IF TEMPREC<4> = "" THEN
             READV DESC FROM PRDFILE,PN,1 ELSE DESC="'":PN:"' Not on file"
          END ELSE
             DESC = TEMPREC<4>
          END

          PRINT PN "L#8":DESC<1,1,1>"L#35":SPACE(1):

          IF SEC.SBY AND SSBY.TYPE = 1 THEN
             * In case this is '>NULL<' we need to Trim off any
             * spaces that we put in so that it would sort properly...
             *PRINT TRIM(TSBY<2>) SSBY.FMT:
          END

          IF INV.DET THEN
             TID = FIELD(FIELD(SORTBY,DLM,6),'.',1,2)
             SDT = FIELD(SORTBY,DLM,5)
             PRINT TID 'L#16':OCONV(SDT,'D2/')'L#8':
          END

          * Print the Column Data for each of our periods...
          * Initialize some period variables...
          P1 = 0
          P2 = 0

          FOR PP = 1 TO PERD.CNT

             * Check whether this is a Difference Column...
             PPERD  = FIELD(PERD,'/',PP)
             IF INDEX(PPERD,'Difference',1) THEN
                IF PPERD[1,1] = '%' THEN
                   DIFF.COLUMN = '%'
                END ELSE
                   DIFF.COLUMN = 'Raw'
                END
             END ELSE
                DIFF.COLUMN = ''
             END

             CC = 1

             * Print each of the data columns we need to print for the
             * current Sales Period...
             LOOP
                TCLMN = FIELD(CLMN,'/',CC)
                UNTIL TCLMN = '' DO

                BEGIN CASE
                CASE TCLMN = 'Qty'
                   * If we're printing a 'Difference between 2 Periods'
                   * Column...
                   IF DIFF.COLUMN THEN
                      * Get the Qtys from the previous two TRUE periods..
                      P1.AMT   = TDATA<1,P1,1> + 0
                      P2.AMT   = TDATA<1,P2,1> + 0
                      DIFF.AMT = P1.AMT - P2.AMT

                      IF DIFF.COLUMN = '%' THEN
                         GOSUB CALC.DIFF.PERCENT
                      END ELSE
                         DIFF.AMT = OCONV(DIFF.AMT,"MR0,")
                      END
                      PRINT DIFF.AMT                    DFMT:
                   END ELSE
                      * Otherwise we just need the Start and End Dates...
                      * Current Normal Period...
                      PRINT OCONV(TDATA<1,PP,1>,'MR0'):TB DFMT:
                   END
                CASE TCLMN = 'Sales'
                   * If we're printing a 'Difference between 2 Periods'
                   * Column...
                   IF DIFF.COLUMN THEN
                      * Get the Qtys from the previous two TRUE periods..
                      P1.AMT   = OCONV(TDATA<1,P1,2> + 0,DIFF.DCNV)
                      P2.AMT   = OCONV(TDATA<1,P2,2> + 0,DIFF.DCNV)
                      DIFF.AMT = P1.AMT - P2.AMT

                      IF DIFF.COLUMN = '%' THEN
                         GOSUB CALC.DIFF.PERCENT
                      END ELSE
                         * Only want to stick commas in if we're not
                         * displaying a percentage...
                         DIFF.AMT = OCONV(DIFF.AMT,"MR,")
                      END
                      PRINT DIFF.AMT                  SFMT:
                   END ELSE
                      PRINT OCONV(TDATA<1,PP,2>,DCNV) SFMT
                   END
                CASE TCLMN = 'Cost'
                   * If we're printing a 'Difference between 2 Periods'
                   * Column...
                   IF DIFF.COLUMN THEN
                      P1.AMT   = OCONV(TDATA<1,P1,3> + 0,DIFF.DCNV)
                      P2.AMT   = OCONV(TDATA<1,P2,3> + 0,DIFF.DCNV)
                      DIFF.AMT = P1.AMT - P2.AMT

                      * If we're looking for a % Difference...
                      IF DIFF.COLUMN = '%' THEN
                         GOSUB CALC.DIFF.PERCENT
                      END ELSE
                         * Only want to stick commas in if we're not
                         * displaying a percentage...
                         DIFF.AMT = OCONV(DIFF.AMT,"MR,")
                      END
                      PRINT DIFF.AMT                  SFMT:
                   END ELSE
                      PRINT OCONV(TDATA<1,PP,3>,DCNV) SFMT:
                   END
                CASE TCLMN = 'GP'
                   * If we're printing a 'Difference between 2 Periods'
                   * Column...
                   IF DIFF.COLUMN THEN
                      * Get the Qtys from the previous two TRUE periods..
                      P1.AMT   = (TDATA<1,P1,2> - TDATA<1,P1,3>) + 0
                      P1.AMT   = OCONV(P1.AMT,DIFF.DCNV)

                      P2.AMT   = (TDATA<1,P2,2> - TDATA<1,P2,3>) + 0
                      P2.AMT   = OCONV(P2.AMT,DIFF.DCNV)

                      DIFF.AMT = P1.AMT - P2.AMT

                      IF DIFF.COLUMN = '%' THEN
                         GOSUB CALC.DIFF.PERCENT
                      END ELSE
                         * Only want to stick commas in if we're not
                         * displaying a percentage...
                         DIFF.AMT = OCONV(DIFF.AMT,"MR,")
                      END
                      PRINT DIFF.AMT               SFMT:
                   END ELSE
                      GP.DOLLARS = TDATA<1,PP,2> - TDATA<1,PP,3>
                      PRINT OCONV(GP.DOLLARS,DCNV) SFMT:
                   END
                CASE TCLMN = 'GP%'
                   * If we're printing a 'Difference between 2 Periods'
                   * Column...
                   IF DIFF.COLUMN THEN
                      * Get the Price and Cost from the previous two
                      * TRUE periods...
                      PER1.PRICE = TDATA<1,P1,2> + 0
                      PER1.COST  = TDATA<1,P1,3> + 0
                      PER2.PRICE = TDATA<1,P2,2> + 0
                      PER2.COST  = TDATA<1,P2,3> + 0

                      IF PER1.PRICE # 0 THEN
                         PER1.GP$ = PER1.PRICE - PER1.COST
                         PER1.GP% = PER1.GP$ / PER1.PRICE
                      END ELSE
                         PER1.GP% = 0
                      END
                      P1.AMT = PER1.GP%

                      IF PER2.PRICE # 0 THEN
                         PER2.GP$ = PER2.PRICE - PER2.COST
                         PER2.GP% = PER2.GP$ / PER2.PRICE
                      END ELSE
                         PER2.GP% = 0
                      END
                      P2.AMT = PER2.GP%

                      DIFF.AMT = (P1.AMT - P2.AMT) * 100

                      IF DIFF.COLUMN = '%' THEN
                         GOSUB CALC.DIFF.PERCENT
                      END ELSE
                         DIFF.AMT = OCONV(ICONV(DIFF.AMT,"MR1"),"MR1")
                      END
                      PRINT DIFF.AMT "R#8":
                   END ELSE
                      IF TDATA<1,PP,2> + 0 # 0 THEN
                         GP.DOLS = (TDATA<1,PP,2> - TDATA<1,PP,3>) * 100
                         GP.PERC = GP.DOLS / TDATA<1,PP,2>
                         PRINT OCONV(ICONV(GP.PERC,'MR1'),'MR1') "R#8":
                      END ELSE
                         *PRINT SPACE(8):
                      END
                   END
                CASE TCLMN = 'Unit Price'
                   * If we're printing a 'Difference between 2 Periods'
                   * Column...
                   IF DIFF.COLUMN THEN
                      PER1.QTY = TDATA<1,P1,1> + 0
                      PER2.QTY = TDATA<1,P2,1> + 0

                      * Get the Unit Price from Period 1 (A)...
                      IF PER1.QTY # 0 THEN
                         PER1.PRICE  = TDATA<1,P1,2>
                         PER1.UPRICE = (PER1.PRICE / 100) / PER1.QTY
                      END ELSE
                         PER1.UPRICE = 0
                      END
                      P1.AMT = PER1.UPRICE

                      * Get the Unit Price from Period 2 (B)...
                      IF PER2.QTY # 0 THEN
                         PER2.PRICE  = TDATA<1,P2,2>
                         PER2.UPRICE = (PER2.PRICE / 100) / PER2.QTY
                      END ELSE
                         PER2.UPRICE = 0
                      END
                      P2.AMT = PER2.UPRICE

                      DIFF.AMT = P1.AMT - P2.AMT

                      * If we're looking for a % Difference...
                      IF DIFF.COLUMN = '%' THEN
                         GOSUB CALC.DIFF.PERCENT
                      END ELSE
                         DIFF.AMT = OCONV(ICONV(DIFF.AMT,"MR3"),"MR3")
                      END
                      PRINT DIFF.AMT                     "R#16":
                   END ELSE
                      IF TDATA<1,PP,1> + 0 # 0 THEN
                         TITEM = (TDATA<1,PP,2> / 100) / TDATA<1,PP,1>
                         TITEM = ICONV(TITEM,'MR3')
                      END ELSE TITEM = ''
                      PRINT OCONV(TITEM,'MR3') "R#16":
                   END
                CASE TCLMN = 'Unit Cost'
                   * If we're printing a 'Difference between 2 Periods'
                   * Column...
                   IF DIFF.COLUMN THEN
                      PER1.QTY = TDATA<1,P1,1> + 0
                      PER2.QTY = TDATA<1,P2,1> + 0

                      * Get the Unit Cost from Period 1 (A)...
                      IF PER1.QTY # 0 THEN
                         PER1.COST  = TDATA<1,P1,3>
                         PER1.UCOST = (PER1.COST / 100) / PER1.QTY
                      END ELSE
                         PER1.UCOST = 0
                      END
                      P1.AMT = PER1.UCOST

                      * Get the Unit Cost from Period 2 (B)...
                      IF PER2.QTY # 0 THEN
                         PER2.COST  = TDATA<1,P2,3>
                         PER2.UCOST = (PER2.COST / 100) / PER2.QTY
                      END ELSE
                         PER2.UCOST = 0
                      END
                      P2.AMT = PER2.UCOST

                      DIFF.AMT = P1.AMT - P2.AMT

                      * If we're looking for a % Difference...
                      IF DIFF.COLUMN = '%' THEN
                         GOSUB CALC.DIFF.PERCENT
                      END ELSE
                         DIFF.AMT = OCONV(ICONV(DIFF.AMT,"MR3"),"MR3")
                      END
                      PRINT DIFF.AMT                   "R#10":
                   END ELSE
                      IF TDATA<1,PP,1> + 0 # 0 THEN
                         TITEM = (TDATA<1,PP,3> / 100) / TDATA<1,PP,1>
                         TITEM = ICONV(TITEM,'MR3')
                      END ELSE TITEM = ''
                      PRINT OCONV(TITEM,'MR3')'R#10':
                   END
                END CASE
                CC += 1
             REPEAT
             *PRINT SPACE(1):

             * If we didn't just print a Difference Period Column, we
             * need to update our Period Variables...
             IF NOT(DIFF.COLUMN) THEN
                P1 = PP - 1
                P2 = PP
             END
          NEXT PP

          *PRINT

          * Delete the first line of our description...
     *     DEL DESC<1,1>
     *     DD = 1

          * Print the rest of our description...
     *     LOOP
     *        UNTIL DESC<1,DD> = '' DO
     *        PRINT DESC<1,DD>
     *        DD += 1
     *     REPEAT

          RETURN
*-------------------------------------------------------------------------*
PRT.TOLS: *** Print the Totals...

          FMT = 'L#':PWDTH
          TOT.PCNT = 0

          FOR TL = STL TO TOT.LVL
             IF TL > 2 OR (TL = 2 AND SSBY.TYPE = 2) THEN PRINT
             IF DET = 'Invoice' OR DET = 'Product' THEN
                IF TOLS<TL,1,1+(PERD.CNT*3)> < 2 THEN
                   BEGIN CASE
                   CASE TL=1
                      GOTO CLR.TOT
                   CASE TL=2 AND SSBY.TYPE#2
                      GOTO CLR.TOT
                   CASE TL=3 AND HDR
                      GOTO CLR.TOT
                   CASE TL#4 AND OSBY<TL>='@@@'
                      GOTO CLR.TOT
                   END CASE
                END
                IF TL=2 AND TOT.LVL=3 AND TOLS<2>=TOLS<3> AND SSBY.TYPE#2 THEN
                   IF FIELD(OSHDR,' ',2,9) = FIELD(OPHDR,' ',2,9) THEN
                      GOTO CLR.TOT
                   END
                END
             END

             IF DET = 'Invoice' AND TL = 1 THEN GOTO CLR.TOT

             THDR = ''
             TLINE = ''

             BEGIN CASE
             CASE TL  = 1
                TLINE = 'Product total'
             CASE TL  = 2
                THDR  = OSHDR
             CASE TL  = 3
                THDR  = OPHDR
             END CASE

             TOT.PCNT += 1
             IF TL < 4 THEN
                IF TL#1 THEN
                   IF THDR  = '' THEN
                      DCT   = DCOUNT(OSBY<TL>,'|')
                      TLINE = TLINE:'  ':FIELD(OSBY<TL>,'|',DCT)
                   END
                   TLINE    = THDR
                END
             END ELSE
                *TLINE = 'Grand Totals    '
             END
             *TLINE  = SPACE(5):TLINE
             LN.PRT = NO
             IF LEN(TLINE) > PWDTH THEN
                LN.PRT = YES
                IF LEN(TLINE) > WDTH THEN
                   TIX   = INDEX(TLINE,':',1)
                   TTAG  = TLINE[1,TIX-1]
                   TLINE = TLINE[TIX+1,9999]
                   TLEN  = WDTH - (TIX+1)
                   FOLDCHAR PLINE,TLINE,TLEN,VCT,','

                   FOR SS = 1 TO 2
                      PRINT TTAG:': ':PLINE<1,SS>
                   NEXT SS
                END ELSE
                   PRINT TLINE
                END

                IF DET = "Invoice" THEN
                   PRINT SPACE (60):
                END ELSE
                   PRINT SPACE (36):
                END
             END

             IF TRIM(TLINE) = '' THEN CONTINUE

             IF NOT(LN.PRT) THEN
                IF DET = "Invoice" THEN
                   PRINT TLINE "L#60":
                END ELSE
                   PRINT TLINE "L#70":
                END
             END
             TLINE = ''
             * Print the Column Data Totals for each of our Periods...
             * Initialize some period variables...
             P1 = 0
             P2 = 0

             * Add space if we have a Secondary Sort Column
             IF SEC.SBY # '' AND SSBY.TYPE = 1 THEN
                *PRINT SPACE (MAX.SSBY):
             END

             FOR PP = 1 TO PERD.CNT
                * Check whether this is a Difference Column...
                PPERD  = FIELD(PERD,'/',PP)
                IF INDEX(PPERD,'Difference',1) THEN
                   IF PPERD[1,1] = '%' THEN
                      DIFF.COLUMN = '%'
                   END ELSE
                      DIFF.COLUMN = 'Raw'
                   END
                END ELSE
                   DIFF.COLUMN = ''
                END

                CC = 1

                * Print each of the data columns we need to print for the
                * current Sales Period...
                LOOP
                   TCLMN = FIELD(CLMN,'/',CC)
                   UNTIL TCLMN = '' DO
                   BEGIN CASE
                   CASE TCLMN  = 'Qty'
                      * If we're printing a 'Difference between 2
                      * Periods' Column...
                      IF DIFF.COLUMN THEN
                         * Get the Qtys from the previous two
                         * TRUE Periods...
                         P1.AMT   = TOLS<TL,P1,1> + 0
                         P2.AMT   = TOLS<TL,P2,1> + 0
                         DIFF.AMT = P1.AMT - P2.AMT

                         IF DIFF.COLUMN = '%' THEN
                            GOSUB CALC.DIFF.PERCENT
                         END ELSE
                            DIFF.AMT = OCONV(DIFF.AMT,'MR0,')
                         END
                         PRINT DIFF.AMT                     DFMT:
                      END ELSE
                         * Otherwise we're just printing Sales data for
                         * the current normal Period...
                         PRINT OCONV(TOLS<TL,PP,1>,'MR0,'):TB  DFMT:
                      END
                   CASE TCLMN  = 'Sales'
                      * If we're printing a 'Difference between 2
                      * Periods' Column...
                      IF DIFF.COLUMN THEN
                         * Get the Qtys from the previous two
                         * TRUE Periods...
                         P1.AMT   = OCONV(TOLS<TL,P1,2> + 0,DIFF.DCNV)
                         P2.AMT   = OCONV(TOLS<TL,P2,2> + 0,DIFF.DCNV)
                         DIFF.AMT = P1.AMT - P2.AMT

                         IF DIFF.COLUMN = '%' THEN
                            GOSUB CALC.DIFF.PERCENT
                         END ELSE
                            * Only want to stick commas in if we're not
                            * displaying a percentage...
                            DIFF.AMT = OCONV(DIFF.AMT,"MR,")
                         END
                         PRINT DIFF.AMT                     SFMT:
                      END ELSE
                         PRINT OCONV(TOLS<TL,PP,2>,DCNV)    SFMT:
                      END
                   CASE TCLMN  = 'Cost'
                      * If we're printing a 'Difference between 2
                      * Periods' Column...
                      IF DIFF.COLUMN THEN
                         P1.AMT   = OCONV(TOLS<TL,P1,3> + 0,DIFF.DCNV)
                         P2.AMT   = OCONV(TOLS<TL,P2,3> + 0,DIFF.DCNV)
                         DIFF.AMT = TOL.PER1.COST - TOL.PER2.COST

                         * If we're looking for a % Difference...
                         IF DIFF.COLUMN = '%' THEN
                            GOSUB CALC.DIFF.PERCENT
                         END ELSE
                            * Only want to stick commas in if we're not
                            * displaying a percentage...
                            DIFF.AMT = OCONV(DIFF.AMT,"MR,")
                         END
                         PRINT DIFF.AMT                     SFMT:
                      END ELSE
                         PRINT OCONV(TOLS<TL,PP,3>,DCNV)    SFMT:
                      END
                   CASE TCLMN  = 'GP'
                      * If we're printing a 'Difference between 2
                      * Periods' Column...
                      IF DIFF.COLUMN THEN
                         * Get the Qtys from the previous two
                         * TRUE periods..
                         P1.AMT   = (TOLS<TL,P1,2> - TOLS<TL,P1,3>) + 0
                         P1.AMT   = OCONV(P1.AMT,DIFF.DCNV)

                         P2.AMT   = (TOLS<TL,P2,2> - TOLS<TL,P2,3>) + 0
                         P2.AMT   = OCONV(P2.AMT,DIFF.DCNV)

                         DIFF.AMT = P1.AMT - P2.AMT

                         IF DIFF.COLUMN = '%' THEN
                            GOSUB CALC.DIFF.PERCENT
                         END ELSE
                            * Only want to stick commas in if we're not
                            * displaying a percentage...
                            DIFF.AMT = OCONV(DIFF.AMT,"MR,")
                         END
                         PRINT DIFF.AMT                      SFMT:
                      END ELSE
                         GP.DOLLARS = TOLS<TL,PP,2> - TOLS<TL,PP,3>
                         PRINT OCONV(GP.DOLLARS,DCNV)        SFMT:
                      END
                   CASE TCLMN  = 'GP%'
                      * If we're printing a 'Difference between 2
                      * Periods' Column...
                      IF DIFF.COLUMN THEN
                         * Get the Price and Cost from the previous two
                         * TRUE periods...
                         TOL.PER1.PRICE = TOLS<TL,P1,2> + 0
                         TOL.PER1.COST  = TOLS<TL,P1,3> + 0
                         TOL.PER2.PRICE = TOLS<TL,P2,2> + 0
                         TOL.PER2.COST  = TOLS<TL,P2,3> + 0

                         IF TOL.PER1.PRICE # 0 THEN
                            TOL.PER1.GP$ = TOL.PER1.PRICE - TOL.PER1.COST
                            TOL.PER1.GP% = TOL.PER1.GP$ / TOL.PER1.PRICE
                         END ELSE
                            TOL.PER1.GP% = 0
                         END
                         P1.AMT          = TOL.PER1.GP%

                         IF TOL.PER2.PRICE # 0 THEN
                            TOL.PER2.GP$ = TOL.PER2.PRICE - TOL.PER2.COST
                            TOL.PER2.GP% = TOL.PER2.GP$ / TOL.PER2.PRICE
                         END ELSE
                            TOL.PER2.GP% = 0
                         END
                         P2.AMT          = TOL.PER2.GP%

                         DIFF.AMT = (P1.AMT - P2.AMT) * 100

                         IF DIFF.COLUMN = '%' THEN
                            GOSUB CALC.DIFF.PERCENT
                         END ELSE
                            DIFF.AMT = OCONV(ICONV(DIFF.AMT,"MR1"),"MR1")
                         END
                         PRINT DIFF.AMT        "R#8":
                      END ELSE
                         IF TOLS<TL,PP,2>+ 0 # 0 THEN
                            GP.DOLS = (TOLS<TL,PP,2>-TOLS<TL,PP,3>)*100
                            GP.PERC = GP.DOLS / TOLS<TL,PP,2>
                            PRINT OCONV(ICONV(GP.PERC,'MR1'),'MR1') 'R#8':
                         END ELSE
                            *PRINT SPACE(8):
                         END
                      END
                   CASE TCLMN  = 'Unit Price'
                      * If we're printing a 'Difference between 2
                      * Periods' Column...
                      IF DIFF.COLUMN THEN
                         TOL.PER1.QTY = TOLS<TL,P1,1> + 0
                         TOL.PER2.QTY = TOLS<TL,P2,1> + 0

                         * Get the Unit Price from Period 1 (A)...
                         IF TOL.PER1.QTY # 0 THEN
                            TOL.PER1.PRICE  = TOLS<TL,P1,2>
                            TOL.PER1.UPRICE = TOL.PER1.PRICE / 100
                            TOL.PER1.UPRICE = TOL.PER1.UPRICE/TOL.PER1.QTY
                         END ELSE
                            TOL.PER1.UPRICE = 0
                         END
                         P1.AMT             = TOL.PER1.UPRICE


                         * Get the Unit Price from Period 2 (B)...
                         IF TOL.PER2.QTY # 0 THEN
                            TOL.PER2.PRICE  = TOLS<TL,P2,2>
                            TOL.PER2.UPRICE = TOL.PER2.PRICE / 100
                            TOL.PER2.UPRICE = TOL.PER2.UPRICE/TOL.PER2.QTY
                         END ELSE
                            TOL.PER2.UPRICE = 0
                         END
                         P2.AMT             = TOL.PER2.UPRICE

                         DIFF.AMT = P1.AMT - P2.AMT

                         * If we're looking for a % Difference...
                         IF DIFF.COLUMN = '%' THEN
                            GOSUB CALC.DIFF.PERCENT
                         END ELSE
                            DIFF.AMT = OCONV(ICONV(DIFF.AMT,"MR3"),"MR3")
                         END
                         PRINT DIFF.AMT                  "R#16":
                      END ELSE
                         IF TOLS<TL,PP,1> + 0 # 0 THEN
                            TITEM = TOLS<TL,PP,2> / 100 / TOLS<TL,PP,1>
                            TITEM = ICONV(TITEM,"MR3")
                         END ELSE
                            TITEM = ''
                         END
                         PRINT OCONV(TITEM,"MR3")  "R#16":
                      END
                   CASE TCLMN  = 'Unit Cost'
                      * If we're printing a 'Difference between 2
                      * Periods' Column...
                      IF DIFF.COLUMN THEN
                         TOL.PER1.QTY = TOLS<TL,P1,1> + 0
                         TOL.PER2.QTY = TOLS<TL,P2,1> + 0

                         * Get the Unit Cost from Period 1 (A)...
                         IF TOL.PER1.QTY # 0 THEN
                            TOL.PER1.COST  = TOLS<TL,P1,3>
                            TOL.PER1.UCOST = TOL.PER1.COST / 100
                            TOL.PER1.UCOST = TOL.PER1.UCOST / TOL.PER1.QTY
                         END ELSE
                            TOL.PER1.UCOST = 0
                         END
                         P1.AMT            = TOL.PER1.UCOST

                         * Get the Unit Cost from Period 2 (B)...
                         IF TOL.PER2.QTY # 0 THEN
                            TOL.PER2.COST  = TOLS<TL,P2,3>
                            TOL.PER2.UCOST = TOL.PER2.COST / 100
                            TOL.PER2.UCOST = TOL.PER2.UCOST / TOL.PER2.QTY
                         END ELSE
                            TOL.PER2.UCOST = 0
                         END
                         P2.AMT            = TOL.PER2.UCOST

                         DIFF.AMT = P1.AMT - P2.AMT

                         * If we're looking for a % Difference...
                         IF DIFF.COLUMN = '%' THEN
                            GOSUB CALC.DIFF.PERCENT
                         END ELSE
                            DIFF.AMT = OCONV(ICONV(DIFF.AMT,"MR3"),"MR3")
                         END
                         PRINT DIFF.AMT                       "R#10":
                      END ELSE
                         IF TOLS<TL,PP,1>+0#0 THEN
                            TITEM = TOLS<TL,PP,3> / 100 / TOLS<TL,PP,1>
                            TITEM = ICONV(TITEM,"MR3")
                         END ELSE TITEM = ''
                         PRINT OCONV(TITEM,"MR3") "R#10":
                      END
                   END CASE

                   CC += 1
                REPEAT

                *PRINT SPACE(1):

                * If we didn't just print a Difference Period Column, we
                * need to update our Period Variables...
                IF NOT(DIFF.COLUMN) THEN
                   P1 = PP - 1
                   P2 = PP
                END
             NEXT PP

             PRINT
             IF TL > 2 THEN PRINT
CLR.TOT:     TOLS<TL> = ''
          NEXT TL

          IF TOT.LVL=4 OR (TOT.LVL=3 AND PRI.SBY[1,7] # 'Product') OR (TOT.LVL=2 AND SSBY.TYPE=2) THEN
             IF PG AND TOT.LVL#2 THEN
                * Print a Page Break...
                PRINT CHAR(12)
             END ELSE
                * Print a dashed line accross the page...
                *PRINT STR('-',WDTH)
             END
          END

          RETURN
*-------------------------------------------------------------------------*
CALC.DIFF.PERCENT: *** Calculate the difference percentage btwn 2 periods.

          BEGIN CASE
          CASE P1.AMT = 0 AND P2.AMT = 0
             * If both periods are zero then the difference % is zero
             DIFF.AMT = 0
          CASE P2.AMT = 0
             * If the 2nd Period is zero but the 1st is not then the
             * % change is infinite. We'll therefore just print
             * asterics...
             DIFF.AMT = '***'
          CASE P1.AMT = 0
             * If the 1st period is zero but the 2nd period is not
             * the we've gone DOWN 100%
             DIFF.AMT = -100
          CASE OTHERWISE
             DIFF.AMT = (DIFF.AMT * 100) / P2.AMT
          END CASE

          IF NUM(DIFF.AMT) THEN
             DIFF.AMT = OCONV(ICONV(DIFF.AMT,"MR1"),"MR1")
          END

          RETURN
*-------------------------------------------------------------------------*
SEL.IDS:  SORTBYS  = ''
          SDATA    = ''
          PRI.HDR  = ''
          SEC.HDR  = ''
          CUS.LIST = ''
          MAX.SLCT = DCOUNT(SLIST,VM)

          BEGIN CASE
          CASE SLIST  = ''
             NULL
          CASE SLCT   = 'Bill-To Customer'
             CUS.LIST = SLIST
          CASE SLCT   = 'Ship-To Customer'
             FOR SCNT = 1 TO MAX.SLCT
                TENTITY  = SLIST<1,SCNT>
                GET.CUS.BR ,TENTITY,ERR.CD
                IF NOT(ERR.CD) THEN
                   BT.CN = CUS(10)
                   IF BT.CN = '' THEN BT.CN = TENTITY
                   LOCATE BT.CN IN CUS.LIST<1> SETTING MV ELSE
                      CUS.LIST<1,-1> = BT.CN
                   END
                END
             NEXT SCNT
          CASE SLCT   = 'Parent Customer'
             * Get bill-to customers for each parent
             TLIST = SLIST
             SLIST = ''
             CUS.LIST = TLIST
             MAX.SLCT = DCOUNT(TLIST,VM)
             FOR SCNT = 1 TO MAX.SLCT
                READV BLIST FROM CUSFILE,TLIST<1,SCNT>,80 ELSE CONTINUE
                CNS = TRIM(BLIST<1,2>,SVM,"T")
                IF (CNS = "") THEN CONTINUE
                CUS.LIST<1,-1> = RAISE(CNS)
             NEXT SCNT
          CASE SLCT = 'Outside Salesman'
             EXEC.SLIST = ''
             FOR SCNT   = 1 TO MAX.SLCT
                EXEC.SLIST := '"':SLIST<1,SCNT>:'"'
             NEXT SCNT
             SNTC = "SELECT CUSTOMER WITH $OUTSIDE_SALES$ = ":EXEC.SLIST
             EXECUTE SNTC RETURNING NOTHING
             LOOP
                READNEXT BT.CN ELSE EXIT
                CUS.LIST<1,-1> = BT.CN
             REPEAT
          CASE SLCT = 'Inside Salesman'
             EXEC.SLIST = ''
             FOR SCNT   = 1 TO MAX.SLCT
                EXEC.SLIST := '"':SLIST<1,SCNT>:'"'
             NEXT SCNT
             SNTC = "SELECT CUSTOMER WITH $INSIDE_SALES$ = ":EXEC.SLIST
             EXECUTE SNTC RETURNING NOTHING
             LOOP
                READNEXT BT.CN ELSE EXIT
                CUS.LIST<1,-1> = BT.CN
             REPEAT
          END CASE

          IF CUS.LIST = '' THEN
             FOR DD   = CALC.SDT TO CALC.EDT
                DT.OK = NO

                FOR PP = 1 TO PERD.CNT UNTIL DT.OK
                   IF DD >= PERD.SDTS<PP> AND DD <= PERD.EDTS<PP> THEN
                      DT.OK = YES
                   END
                NEXT PP

                IF NOT(DT.OK) THEN CONTINUE

                * Update our Phantom Status...
                WRITE 'Selecting... ':OCONV(DD,'D2/') ON PHSTFILE,PID$

                * Read in a batch of AR Records with the current Date...
                IDL = JLI.READ.EMU('1*':DD)
                LLN = DCOUNT(IDL,AM)

                * For each of the records in our batch...
                FOR LLX = 1 TO LLN
                   ID = IDL<LLX>
                   * Go filter the Invoice...
                   GOSUB FILTR.ID
                NEXT LLX
             NEXT DD
          END ELSE
             IIDS = ''

             FOR SCNT = 1 TO DCOUNT(CUS.LIST,VM)
                TENTITY = CUS.LIST<1,SCNT>

                WRITE 'Selecting Customer ':TENTITY ON PHSTFILE,PID$

                ROOT = TENTITY:'~':CALC.SDT'R%5'

                LOOP
                   BSCAN PID FROM PSUBFILE,ROOT USING '&INDEX&.ENT' BY 'A' ELSE NULL
                   ROOT = ''
                   IF FIELD(PID,'~',1) # TENTITY THEN EXIT

                   DD = FIELD(PID,'~',2)
                   IF DD > CALC.EDT THEN EXIT

                   ID = FIELD(PID,'~',5):'.':FIELD(PID,'~',6)'R%3'

                   DT.OK = NO

                   FOR PP = 1 TO PERD.CNT UNTIL DT.OK
                      IF DD >= PERD.SDTS<PP> AND DD <= PERD.EDTS<PP> THEN
                         DT.OK = YES
                      END
                   NEXT PP

                   IF NOT(DT.OK) THEN CONTINUE
                   LOCATE ID IN IIDS SETTING TATTR THEN CONTINUE
                   IIDS<-1> = ID
                   GOSUB FILTR.ID
                REPEAT
             NEXT SCNT
          END

          RETURN
*-------------------------------------------------------------------------*
FILTR.ID: INVN = FIELD(ID,'.',2)+0
          OID  = FIELD(ID,'.',1)

          * Exclude rentals from report
          IF OID[1,1] = 'R' THEN RETURN

          MATREAD LED FROM LEDFILE,OID         ELSE RETURN
          LOCATE INVN IN LED(8)<1> SETTING GEN ELSE RETURN

          DGEN = ''
          IF LED(33)<1,GEN> THEN
             LOCATE LED(33)<1,GEN> IN LED(12)<1> SETTING DGEN THEN
                NULL
             END
          END

          BR = LED(2)<1,GEN,3>
          LOCATE BR IN BRCHS<1> SETTING XX     ELSE RETURN
          PRC.BR = LED(2)<1,GEN,1>

          * Check the Direct Shipments Option
          ISDIR = LED(33)<1,GEN>;  * If this is null, it isn't a direct

          * Consignment Transfers should not appear on the report.
          CONS.XFER = (LED(110)<1,1> = "S")
          IF CONS.XFER THEN RETURN

          BEGIN CASE
          CASE SHOW.DIR = 'Include';NULL
          CASE SHOW.DIR = 'Exclude' AND ISDIR # ''
             RETURN
          CASE SHOW.DIR = 'Only' AND ISDIR = ''
             RETURN
          END CASE

          * Filter against the 'Additional Select' values...
          IF FILTER.FLAG THEN
             FILTER.SELECT SKIP.FLAG,OID,GEN,FITEM
             IF SKIP.FLAG THEN RETURN
          END

          GET.CUS BR,LED(1)<1,GEN>,LED(5)<1,GEN>,'-1'

          * Filter all the products on this order...
          LDIDS = LED(48)<1,GEN>
          LD.CT = DCOUNT(LDIDS,SVM)

          FOR LDN = 1 TO LD.CT
             LDID = LDIDS<1,1,LDN>
             LD.GET LDID
             PN = LD(1)

             * Job Management Logic
             IF PN[1,2] = "L#" THEN
                IF PN = "L#LPAY" THEN CONTINUE
                OE.DESC.GET JM.DESC
                * LD(70) will have template id on new JM orders
                * otherwise we can get it from the vendor number
                IF LD(70) # "" THEN
                   PN = LD(70)
                END ELSE
                  JVN = LED(5)<1,DGEN>
                  PN  = JOBMGMT.GET.PN(JVN)
                END
             END ELSE
                JM.DESC = ""
             END

             IF NOT(NUM(PN)) OR PN = '' THEN CONTINUE

             QTY = -SUM(LD(5)<1,GEN>) + -SUM(LD(6)<1,GEN>)

             BEGIN CASE
             CASE SEL.CREDS = 'O'
                IF QTY >= 0 THEN CONTINUE
             CASE SEL.CREDS = 'E'
                IF QTY < 0 THEN CONTINUE
             END CASE

             GET.ALL.PRD PRC.BR,PN,-1

             * On Job Management items set PRD(1) to the JM Description.
             IF JM.DESC THEN PRD(1) = JM.DESC

             IF NOT(INCLUDE.MISC) AND PRD(3) = 3 THEN CONTINUE

             TSLCT = ''

             BEGIN CASE
             *** Filter against any Sell Groups that have been selected...
             CASE SLCT = 'Sell Group'
                SV.SEL.GRP = ''
                GO.FLAG    = NO
                PRD.BR.GET.VAL LED(2)<1,GEN,1>,PN,24,SEL.GRP
                RUN.THR = DCOUNT(SEL.GRP, VM)
                FOR X = 1 TO RUN.THR
                   LOCATE SEL.GRP<1,X> IN SLIST<1> SETTING XX ELSE CONTINUE
                   GO.FLAG    = YES
                   SV.SEL.GRP = SEL.GRP<1,X>
                   EXIT
                NEXT X
                IF GO.FLAG = NO THEN CONTINUE
             *** Filter against any Buy Groups that have been selected...
             CASE SLCT = 'Buy Group'
                SV.BUY.GRP = ''
                GO.FLAG    = NO
                PRD.BR.GET.VAL LED(2)<1,GEN,1>,PN,23,BUY.GRP
                RUN.THR = DCOUNT(BUY.GRP, VM)
                FOR X = 1 TO RUN.THR
                   LOCATE BUY.GRP<1,X> IN SLIST<1> SETTING XX ELSE CONTINUE
                   GO.FLAG    = YES
                   SV.BUY.GRP = BUY.GRP<1,X>
                   EXIT
                NEXT X
                IF GO.FLAG = NO THEN CONTINUE
             CASE SLCT # ''
                DATA.TYPE = SLCT
                GOSUB GET.DATA
                TSLCT = TDATA
                IF SLIST # '' THEN
                   LOCATE TSLCT IN SLIST<1> SETTING MV ELSE CONTINUE
                END
             END CASE

             IF SEC.SBY AND SEC.SBY # 'Product' THEN
                DATA.TYPE = SEC.SBY
                GOSUB GET.DATA
                IF LEN(TDATA) > MAX.SSBY THEN MAX.SSBY = LEN(TDATA)
             END

             GOSUB ADD.ID
          NEXT LDN

          RETURN
*-------------------------------------------------------------------------*
ADD.ID: *** Put together all the current product's sales data for each of
        *** Periods and create a Tempfile Record for it...

          ID   = OID:'.':LED(8)<1,GEN>'R%3':'.':LDID
          PRC  = LD(8)<1,GEN>

          * Show the cost type...
          IF COST.TYPE = '1' THEN
             CST  = LD(27)<1,GEN>
          END ELSE
             CST  = LD(10)<1,GEN>
          END

          CUST.PO  = LED(13)<1,GEN>
          SCUST.PO = OCONV(LED(13)<1,GEN>,'MCU')
          SHP.DT   = LED(9)<1,GEN>

          SORTBY = ''

          BEGIN CASE
          CASE SEC.SBY AND SEC.SBY # 'Product'
             DATA.TYPE = SEC.SBY
             GOSUB GET.DATA
             SEC.SORT = TSORT
             SHDR = THDR
          CASE OTHERWISE
             SEC.SORT=''
             SHDR = ''
          END CASE
          DATA.TYPE = PRI.SBY

          GOSUB GET.DATA

          SORTBY = TSORT:DLM:SEC.SORT:DLM:PRD(1)<1,1>:DLM:PN
          IF INV.DET THEN SORTBY := DLM:SHP.DT:DLM:ID

          READ TEMPREC FROM TEMPFILE,SORTBY ELSE
             TEMPREC = ''
             TEMPREC<2> = THDR
             TEMPREC<3> = SHDR
             IF JM.DESC THEN TEMPREC<4> = JM.DESC
          END

          ODATA = QTY
          ODATA<1,1,2> = ICONV(OCONV(QTY*PRC,'MR9'),'MR2')
          ODATA<1,1,3> = ICONV(OCONV(QTY*CST,'MR9'),'MR2')

          * Add the Qty, Price, and Cost to each of the
          * appropriate periods...
          FOR PP = 1 TO PERD.CNT
             * If the current date falls between the current period's
             * Start and End Dates...
             IF DD >= PERD.SDTS<PP> AND DD <= PERD.EDTS<PP> THEN
                TDATA = TEMPREC<1,PP>
                TDATA = ADDS(TDATA,ODATA)
                TEMPREC<1,PP> = TDATA
             END
          NEXT PP

          CONVERT VM TO "" IN SORTBY

          WRITE TEMPREC ON TEMPFILE,SORTBY

          RETURN
*-------------------------------------------------------------------------*
GET.DATA:
          TSORT = ''
          THDR  = ''
          TDATA = ''

          BEGIN CASE
          CASE DATA.TYPE = 'Buy Group'
             BUY.GRP = ''
             IF NOT(SV.BUY.GRP) THEN
                PRD.BR.GET.VAL LED(2)<1,GEN,1>,PN,23,BUY.GRP
                BUY.GRP = TRIM(BUY.GRP,VM,'L')<1,1>
             END ELSE
                BUY.GRP = SV.BUY.GRP
             END
             TDATA  = BUY.GRP
             READV THDR FROM PGRPFILE,TDATA,1 ELSE THDR=''
             THDR = TDATA:'-':THDR
          CASE DATA.TYPE = 'Buy Line'
             TDATA = PRD(12)
             READV THDR FROM BLNEFILE,TDATA,1 ELSE THDR=''
             THDR = TDATA:'-':THDR
          CASE DATA.TYPE = 'Price Line'
             TDATA = PRD(9)
             READV THDR FROM PLNEFILE,TDATA,1 ELSE THDR=''
             THDR = TDATA:'-':THDR
          CASE DATA.TYPE = 'Product'
             TDATA = PN
             TSORT = PRD(1)<1,1>:'|':TDATA
          CASE DATA.TYPE = 'Sell Group'
             SEL.GRP = ''
             IF NOT(SV.SEL.GRP) THEN
                PRD.BR.GET.VAL LED(2)<1,GEN,1>,PN,24,SEL.GRP
                SEL.GRP = TRIM(SEL.GRP,VM,'L')<1,1>
             END ELSE
                SEL.GRP = SV.SEL.GRP
             END
             TDATA  = SEL.GRP
             READV THDR FROM PGRPFILE,TDATA,1 ELSE THDR=''
             THDR = TDATA:'-':THDR
          CASE DATA.TYPE = 'Prod Comm Group'
             TDATA = PRD.BR(26)<1,1,1>
          CASE DATA.TYPE[1,7] = 'Bill-To'
             TDATA = LED(1)<1,GEN>
             TSORT = CUS(8):'|':CUS(1):'|':TDATA
             THDR  = '&':LED(1)<1,GEN>:' ':CUS(1):', ':CUS(2)<1,1>
             THDR := ', ':CUS(3):', ':CUS(4):'  ':CUS(5)
             DATA.TYPE = FIELD(DATA.TYPE,' ',1)
          CASE DATA.TYPE[1,6] = 'Parent'
             TDATA = LED(1)<1,GEN>
             PDATA = CUS(80)<1,1>
             IF (PDATA = "") THEN PDATA = TDATA
             MATREAD PCUS FROM CUSFILE,PDATA ELSE MAT PCUS = MAT CUS
             TSORT = PCUS(8):'|':PCUS(1):'|':PDATA
             THDR  = '&':PDATA:' ':PCUS(1):', ':PCUS(2)<1,1>
             THDR := ', ':PCUS(3):', ':PCUS(4):'  ':PCUS(5)
             DATA.TYPE = FIELD(DATA.TYPE,' ',1)
          CASE DATA.TYPE[9,5] = 'State'
             READV STATE FROM CUSFILE,LED(5)<1,GEN>,4 ELSE STATE = ''
             TDATA = STATE<1,1>
          CASE DATA.TYPE[1,7] = 'Ship-To'
             TDATA = LED(5)<1,GEN>
             CONVERT "," TO " " IN CUSS(1)
             JOB = OCONV(LED(65)<1,GEN>,'MCU')
             IF JOB = '' THEN
             JOB = OCONV(LED(13)<1,GEN>,'MCU')
             END
             *P1.AMT   = OCONV(TDATA<1,P1,2> + 0,DIFF.DCNV)
             TSORT = CUSS(8):'|':CUSS(1):'|':TDATA
             THDR  = CUSS(1):TB:JOB
             *:TB:CUSS(2)<1,1>
             THDR := TB:CUSS(3):TB:CUSS(4):TB
             DATA.TYPE = FIELD(DATA.TYPE,' ',1)
          CASE DATA.TYPE = 'Customer P/O'
             TDATA = OCONV(LED(13)<1,GEN>,'MCU')
          CASE DATA.TYPE = 'Customer Part#'
             * RVDH was PN.ID
             OE.CUS.PN.CMT.GET LED(1)<1,GEN>,LED(5)<1,GEN>,CUSS(66),PN,CMT
             IF CMT<1> THEN TDATA = CMT<1>

          CASE DATA.TYPE = 'Current Outside Slsp'
             TDATA = CUSS(41)
             READV THDR FROM INIFILE,TDATA,3 ELSE THDR=TDATA
          CASE DATA.TYPE = 'Current Inside Slsp'
             TDATA = CUSS(44)
             READV THDR FROM INIFILE,TDATA,3 ELSE THDR=TDATA
          CASE DATA.TYPE[1,1] = 'W'
             TDATA = LED(73)<1,GEN>
             READV THDR FROM INIFILE,TDATA,3 ELSE THDR=TDATA
          CASE DATA.TYPE[1,1] = 'O'
             TDATA = LED(72)<1,GEN>
             READV THDR FROM INIFILE,TDATA,3 ELSE THDR=TDATA
          CASE DATA.TYPE[1,1] = 'I'
             TDATA = LED(34)<1,GEN>
             READV THDR FROM INIFILE,TDATA,3 ELSE THDR=TDATA
          CASE DATA.TYPE[1,1] = 'R'
             TDATA = LED(65)<1,GEN>
          CASE DATA.TYPE = 'Product G/L Type'
             TYPE = PRD(2)
             LOCATE TYPE IN GL.TYPES<1> SETTING GLPOS ELSE NULL
             TDATA = GL.TYPES<2,GLPOS>
          CASE DATA.TYPE = 'Product Select Code'
             TDATA = PRD(19)
          CASE DATA.TYPE = 'Product Status'
             STAT.NUM = PRD(3)
             TDATA = PRD.STATS<1,STAT.NUM>
          CASE DATA.TYPE = 'Commodity Code'
             TDATA = PRD(14)
          CASE DATA.TYPE = 'Product Budget Grp'
             * Check for Budget Group on Product if null, check Price Line
             TDATA = PRD(92)
             IF TDATA = '' THEN
                READV TDATA FROM PLNEFILE,PRD(9),7 ELSE TDATA = ''
             END
          CASE DATA.TYPE = 'Customer Type'
             TDATA = CUS(35)
             GOSUB GET.CUS.TYPE
          CASE DATA.TYPE = 'Cust Select Code'
             TDATA = CUS(78)
          CASE DATA.TYPE = 'Sales Source'
             TDATA = LED(3)<1,GEN>
             READ STYPES FROM CTRLFILE,'GL.SALES.TYPE' ELSE STYPES = ''
             LOCATE TDATA IN STYPES<2> SETTING POS THEN
                THDR = STYPES<1,POS>
             END ELSE
                THDR = TDATA
             END
          CASE DATA.TYPE = 'Ship Via'
             TDATA = LED(70)<1,GEN>
          CASE DATA.TYPE = 'Product Description'
             TDATA = PRD(1)<1,1>
          END CASE

          * Need to put a space in front when it's null, so that
          * it will be sorted at the beginning of the report...
          IF TDATA = '' THEN TDATA = ' >NULL<'

          IF TSORT = '' THEN TSORT = TDATA

          * If this was null, then we want to remove the space from
          * the ' >NULL<' before sticking it in the Header label...
          *IF THDR  = '' THEN THDR  = TRIM(TDATA)
          *THDR     = DATA.TYPE:': ':THDR

          RETURN
*-------------------------------------------------------------------------*
GET.CUS.TYPE: * Determine a single value that represents the
          * customer type
          BEGIN CASE
          CASE SLCT # 'Customer Type'
             * We didn't select by customer type. Just use the first
             * customer type listed
             TDATA = TDATA<1,1>
          CASE SLCT = 'Customer Type' AND SLIST = ''
             * We did select by type but we didn't specify which type
             * so you can just use the first one.
             TDATA = TDATA<1,1>
          CASE OTHERWISE
             * Selected by customer type without specifying a list
             * of customer type's. Use the first customer type
             * listed for the customer that matches a customer type
             * in the list.
             TYPE.LIST = TDATA
             TDATA = ''
             TYPE.CNT = DCOUNT(TYPE.LIST,VM)
             FOR TYPE = 1 TO TYPE.CNT
                LOCATE TYPE.LIST<1,TYPE> IN SLIST<1> SETTING MV THEN
                   TDATA = TYPE.LIST<1,TYPE>
                   EXIT
                END
             NEXT TYPE
          END CASE
          RETURN
*-------------------------------------------------------------------------*
!TSMITH~02/07/14~10:18
