          SUBROUTINE (TOT.AMTS,GL.GRP,AMT.INDENT,ADD.INDENT,DET.LVL,CALL.LVL,ORIG.ID,PRINT.OUT,BRCHS,REP.ARRAY,ACCT.AMTS,VALIDATE,CHOICE,SIGN)
** Version# 78.0003[20] - 06/13/2014 - 09:52pm - TSMITH - eclipse
*** V78.0003 Change - Custom Coding CUSTOM - 06/13/2014 - TSMITH - eclipse
*** V78.0002 Change - Custom Coding . - 02/18/2014 - TSMITH - eclipse
*** V78.0001 Change - Custom Coding . - 02/07/2014 - TSMITH - eclipse

*** Subroutine: GL.REC.REPORT
*-------------------------------------------------------------------------*
*** This is a "recursive" routine that prints a General Ledger Report.
*** Recursion is a situation in which a routine/function calls itself
*** either directly or indirectly. In this case the routine is calling
*** itself directly... in order to print data for a GL Account that is
*** flagged as a group in GENLED(25)???
***
*** This program assumes it is being called from within a Report Generator
*** and actually PRINTs the information.
*-------------------------------------------------------------------------*
*** Parameters:
***   TOT.AMTS     -
***   GL.GRP       - All the LINEs of data that should print on the   [IN]
***                  report. Each line is Attribute Mark Delimited
***
***                  You can see a VISUAL representation of this paramter
***                  by looking at the Template (ORIG.ID) in 'G/L Report
***                  Template Maintenance', which is actually very helpful
***                  in understanding what this routine is doing.
***
***   AMT.INDENT   - # of chars to indent, as set up in G/L Template  [IN]
***                  Options from G/L Template Maintenance.
***   ADD.INDENT   -
***   DET.LVL      -
***   CALL.LVL     -
***   ORIG.ID      - The G/L Template Id(s).                          [IN]
***   PRINT.OUT    - Report Print/Preview variable.                   [IN]
***   BRCHS        - Branches the User wants to run the report for.   [IN]
***   REP.ARRAY    - The Report array built from the GENLED.RPT File. [IN]
***   ACCT.AMTS    -
***   VALIDATE     - Array of GL Accounts if the value in pos 1 is set[IN]
***                  then the GL will be validated in GL.VALIDATION
***   CHOICE       - Consolidation Option                             [IN]
***                  > 1 - 'Individual Reports by Branch'
***                  > 2 - 'Individual Branch Consolidated'
***                  > 3 - 'Consolidated with Branch Detail'
***                  > 4 - 'Consolidated, no Branch Detail'
***   SIGN         - Multiplier that changes the sign of a number,    [IN]
***                  making it negative or positive.
*-------------------------------------------------------------------------*
*** This program has some DIAGNOSTIC CODE to aid in solving problems.
***
*** All the variables that begin with DEBUG are for diagnostic
*** debugging of this program.  The following variables are used:
***
***  DEBUG.ACTIVE    - If YES, the diagnostic code is active
***                    If NO,  the diagnostic code is inactive and all
***                    of the other DEBUG variables are inactive.
***  DEBUG.IDS       - A "VM" separated list of USER.IDs.  If DEBUG.ACTIVE
***                    is YES and the current USER.ID is within this list,
***                    the diagnostic code will execute.
***
***                    "ECLIPSE" should always be in this list of IDs,
***                    but it can be expanded to include any other IDs; for
***                    example,
***                     -- A specific user id that is having problems
***                        with this report
***                     -- An Intuit developer that want to debug in the
***                        development environment.
***  DEBUG.LINE      - A line of text that that will be printed when the
***                    diagnostic code executes.
*-------------------------------------------------------------------------*
          * Should the diagnostic code be active
          DEBUG.ACTIVE = NO
          * VM separated list of user ids.  User id must be in list for
          * diagnostic code to execute.
          DEBUG.IDS = 'ECLIPSE'

          IF (DEBUG.ACTIVE) THEN
             LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
               DEBUG.LINE  = 'GL.REC.REPORT-START'
               DEBUG.LINE := ' CALL.LVL=[' :CALL.LVL :']'
               DEBUG.LINE := ' ORID.ID=['  :ORIG.ID  :']'
               DEBUG.LINE := ' TOT.AMTS=[' :TOT.AMTS :']'
               PRINT DEBUG.LINE
            END
          END

          *** Open the GL.BUDGET file...
          UT.OPEN.COMMON.FILE "GL.BUDGET",HNDL
          IF HNDL > 0 THEN
             BDGFILE = FILES(HNDL)
          END ELSE
             RETURN
          END


          *** GL.AUTO is a Common Handle for the 'GL.AUTO' Control File.
          *** COMMON.INIT calls INIT.GL.AUTO which is the routine that
          *** actually reads it in.
*** What is in the control file?
          LOCATE "RTN" IN GL.AUTO<1> SETTING POS THEN
             RET = GL.AUTO<2,POS>
          END ELSE RET = ''

          GPS = TRANS('GENLED.RPT.GPS',OCONV(REP.ARRAY<1,21>,'MCU'),1,'X')
          ADD                     = ADD.INDENT
          LOC.CALL.LVL            = CALL.LVL
          BLOCK.LVL               = 1
          BLOCK.TOT               = 0
          BLOCK.CRD               = 0
          BLOCK.DEB               = 0
          TEMPL.TOTAL             = 0
          TEMPL.SIGN              = 1
          TEMP                    = ''
          PROCESS.SL              = 0
          LINE.AMTS               = ''
          HIDE.BLOCK              = ''
          HIDE.BLOCK<BLOCK.LVL>   = NO
          BR.CT                   = DCOUNT(BRCHS,VM)
          REP.BR.CT               = BR.CT
          REP.BRCHS               = BRCHS;  * Original Branches Specified
          COLUMN.CT               = DCOUNT(REP.ARRAY<1,18>,SVM)
          IF USER.ID = 'FELIXW' THEN
          CDELIM = CHAR(44)
          END ELSE
          CDELIM                  = REP.ARRAY<1,26,1>
          END
          RDELIM                  = REP.ARRAY<1,26,2>
          TRIMIT                  = REP.ARRAY<1,26,3>
          NEG.SIGN                = (REP.ARRAY<1,26,4>='-')
          DOWNLOAD                = (RDELIM#'' OR CDELIM#'')
          REC.REC                 = ''
          BR.CTR                  = 1
          COST.CTRS               = ''
          GLBL.COST.CTRS          = '';* Contains all the Group Cost Ctrs
          UPD.SL.TOTALS           = YES

          *** Next If sets a flag to indicate if SubLedgers were specified
          IF REP.ARRAY<1,31,2> THEN
             SL.SPECIFIED = YES
          END ELSE
             SL.SPECIFIED = NO
          END

          *** Print data for each Line set up for this Report...
          J.MAX = DCOUNT(GL.GRP,AM)
          FOR J = 1 TO J.MAX
             GOSUB SET.LINE

             *** Cost Center Logic
             IF LINE<1,1> = '' AND LINE<1,2> = '' AND LINE<1,3> # '' THEN
                *** Get Cost Centers if there is any
                GOSUB GET.COST.CTRS
             END ELSE
                IF LINE<1,1> = 'Start' THEN
                   *** Get Cost Centers if there is any
                   GOSUB GET.COST.CTRS
                   GLBL.COST.CTRS<BLOCK.LVL+1> = COST.CTRS
                END
             END

             *** GROUP is expected to be set here through SET.LINE
             IF LINE<1,5> # '' AND NOT(GROUP) THEN
                GOSUB SET.VALID
             END

             BEGIN CASE
             *** This Line is a Comment...
             CASE LINE<1,1> = 'Comment'
                IF DET.LVL < LINE<1,4> THEN GOTO SKIP
                NUMERIC     = NO
             *** This Line is a Start...
             CASE LINE<1,1> = 'Start'
                NUMERIC     = NO
                IF (DET.LVL < GL.GRP<J,4>) OR (HIDE.BLOCK<BLOCK.LVL>) THEN
                   HIDE.BLOCK<BLOCK.LVL+1> = YES
                END ELSE HIDE.BLOCK<BLOCK.LVL+1> = NO

                IF LINE<1,3,1>='' AND PRINT.OUT AND NOT(DOWNLOAD) THEN
                   BLOCK.LVL  += 1
                   ADD        += AMT.INDENT
                   GOTO SKIP
                END
             *** This Line is a Break out of SubLedgers
             CASE LINE<1,5> # '' AND SL.ALLOWED # 'N'
                NUMERIC = YES
                PROCESS.SL = 0
                SL.TOTALS  = 0
                GOSUB PARSE.AMT
                *** Need to recheck to see if SubLedgers Allowed
                *** because if the first column is not a description
                *** we don't allow them
                IF SL.ALLOWED # 'N' THEN
                   GOSUB PRT.SL
                   GOTO SKIP
                END

             *** This Line is an End...
             CASE LINE<1,1> = 'End'
                BLOCK.LVL  -= 1
                ADD        -= AMT.INDENT
                REC.REC     = ''
                NUMERIC     = YES
             *** This Line is a Total...
             CASE LINE<1,1> = 'Total'
                REC.REC     = ''
                NUMERIC     = YES
             *** This Line is a Consolidated Total...
             CASE LINE<1,1> = 'CTotal'
                REC.REC     = ''
                NUMERIC     = YES
             *** This Line is a GL Id...
             CASE LINE<1,5> # ''
                NUMERIC     = YES
             CASE LINE<1,1> = '' AND LINE<1,2> = '' AND LINE<1,5> = ''
                IF PRINT.OUT AND NOT(DOWNLOAD) THEN PRINT
                GOTO SKIP
             END CASE

             GOSUB PARSE.AMT

             BEGIN CASE
             CASE LINE<1,1> = 'Start'
                BLOCK.LVL  += 1
                ADD        += AMT.INDENT
             END CASE

SKIP:        *

             IF GROUP AND DET.LVL >= GL.GRP<J,4> THEN
                GOSUB FINISH.GRP
             END
             IF PRINT.OUT AND DOWNLOAD THEN
                IF RDELIM THEN PRINT RDELIM: ELSE PRINT
             END
             IF ORIG.ID = '' THEN
                TOT.AMTS = ''
                RETURN
             END
          NEXT J

          TOT.AMTS = BLOCK.TOT<1>:AM:BLOCK.DEB<1>:AM:BLOCK.CRD<1>:AM:TEMPL.TOTAL<1>

          IF TOT.AMTS = 0 THEN TOT.AMTS = ''


          IF (DEBUG.ACTIVE) THEN
             LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
               DEBUG.LINE  = 'GL.REC.REPORT-END  '
               DEBUG.LINE := ' CALL.LVL=['      :CALL.LVL       :']'
               DEBUG.LINE := ' ORID.ID=['       :ORIG.ID        :']'
               DEBUG.LINE := ' TEMPL.TOTAL<1>=[':TEMPL.TOTAL<1> :']'
               DEBUG.LINE := ' BLOCK.TOT<1>=['  :BLOCK.TOT<1>   :']'
               DEBUG.LINE := ' BLOCK.DEB<1>=['  :BLOCK.DEB<1>   :']'
               DEBUG.LINE := ' BLOCK.CRD<1>=['  :BLOCK.CRD<1>   :']'
               DEBUG.LINE := ' TOT.AMTS=['      :TOT.AMTS       :']'
               PRINT DEBUG.LINE
            END
          END

          RETURN
*-------------------------------------------------------------------------*
SET.LINE: *

          SL.ALLOWED = 'N'
          *** LINE = the next line in our GL Group...
          LINE      = GL.GRP<J>


          LINE<1,6> = LOC.CALL.LVL
          LINE<1,7> = ADD
          GROUP     = NO

          *** If the line has a GL.ID...
          IF LINE<1,5> # '' THEN
             GLID = GL.GRP<J,5>
             *** If this template calls a parent, skip it.
             LOCATE GLID IN ORIG.ID<1> SETTING XX THEN
                RETURN TO SKIP
             END


             GL.READ GLID,REC.REC,REC.GRP,GROUP,GRP.OPT,REC.ERR
             * Rec.Rec 1 = Type
             * For accts 1 = CR and 0 = DR
             * For Template/Group 1 = standard results,0 = reverse results
             IF GROUP THEN
                DR.ACCT = ''
                CR.ACCT = ''
                IF REC.REC<1,1> THEN REVR.RSLTS = NO ELSE REVR.RSLTS = YES
             END ELSE
                REVR.RSLTS = NO
                IF REC.REC<1,1> THEN
                   DR.ACCT = YES   ;* Debit Balance Acct - Assets
                   CR.ACCT = NO    ;* Credit Balance Acct - Liabilities
                END ELSE
                   DR.ACCT = NO    ;* Debit Balance Acct - Assets
                   CR.ACCT = YES   ;* Credit Balance Acct - Liabilities
                END
             END

             IF REC.ERR # '' THEN RETURN TO SKIP

             *** Check to see if the "Show SubLedgers Option" is set
             *** If it is check the GL Account for Subledgers
             SL.OPT = REP.ARRAY<1,31,1>
             IF SL.OPT # 'Y' AND SL.OPT # 'O' THEN SL.OPT = 'N'
             IF SL.OPT # 'N' THEN
                *** Find out if SubLedgers are allowed.
                SL.ALLOWED = REC.REC<31>
                IF SL.ALLOWED = '' THEN SL.ALLOWED = 'N'
             END ELSE
                SL.ALLOWED = 'N'
             END

             *** If the GL Account is a group... (GROUP same as Template)
             IF GROUP THEN
                * SIGN was passed in on call to this routine
                * GL.SIGN is for the call for another template
                IF REVR.RSLTS THEN
                   GL.SIGN = -1*SIGN
                END ELSE
                   GL.SIGN = SIGN
                END

                IF DET.LVL >= GL.GRP<J,4> THEN
                   LINE<1,1> = 'Start'
                   * Check for suppress headings
                   IF GRP.OPT<1,5> THEN
                      LINE<1,3,1> = ''
                   END
                END ELSE
                   ORIG.ID<1,-1> = GLID

                   GL.REC.REPORT LINE.AMTS,REC.GRP,AMT.INDENT,ADD,0,LOC.CALL.LVL+1,ORIG.ID,NO,BRCHS,REP.ARRAY,ACCT.AMTS,VALIDATE,CHOICE,GL.SIGN

                   IF (DEBUG.ACTIVE) THEN
                      LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
                         DEBUG.LINE  = 'GL.REC.REPORT-AFTER GL.REC.REPORT'
                         DEBUG.LINE := ' CALL.LVL=['  :CALL.LVL  :']'
                         DEBUG.LINE := ' LINE.AMTS=[' :LINE.AMTS :']'
                         PRINT DEBUG.LINE
                      END
                   END

                   IF ORIG.ID = '' THEN LINE = ''; RETURN
                   ORIG.ID = DELETE(ORIG.ID,1,DCOUNT(ORIG.ID,VM))
                END
             END
          END
          RETURN
*-------------------------------------------------------------------------*
SET.VALID:*Set Validation logic for when it will be checked in GL.REP3
          *The whole idea behind this routine is to set up an array called
          *Validate that will determine what GL ID's to validate in the
          *GL Validation routine.  This routine is mainly seeing if any
          *GL Account is doubly defined in the report, and that the Acct.
          *Number is still valid.  This is only done on Audited reports.

          *** See if they are adding same GL Number but different
          *** Cost Centers
          IF VALIDATE<1,GLID,2> # '' THEN
             *** No cost centers so this is a duplicate
             IF COST.CTRS = '' THEN
                VALIDATE<1,GLID,1> += 1
             END ELSE
                VAL.CTRS = RAISE(RAISE(VALIDATE<1,GLID,2>))
                CST.CTR.CT = DCOUNT(COST.CTRS,VM)
                FOR CST.CTR = 1 TO CST.CTR.CT
                   *** If Cost Center has already been used for this
                   *** Account then we have an error.
                   LOCATE COST.CTRS<1,CST.CTR> IN VAL.CTRS<1> SETTING XPOS THEN
                      VALIDATE<1,GLID,1> += 1
                      CONTINUE
                   END ELSE
                      VALIDATE<1,GLID,2> := SSVM:COST.CTRS<1,CST.CTR>
                   END
                NEXT CST.CTR
                IF VALIDATE<1,GLID,1> = 1 THEN
                   VALIDATE<1,GLID,3> := SSVM:LOWER(LOWER(BRCHS))
                END
             END
          END ELSE
             VALIDATE<1,GLID,1> += 1
             VALIDATE<1,GLID,2>  = LOWER(LOWER(COST.CTRS))
             VALIDATE<1,GLID,3>  = LOWER(LOWER(BRCHS))
          END

          RETURN
*-------------------------------------------------------------------------*
FINISH.GRP:*
          ORIG.ID<1,-1> = GLID

          TMP.TOT.AMTS = ''
          GL.REC.REPORT TMP.TOT.AMTS,REC.GRP,AMT.INDENT,ADD,DET.LVL,LOC.CALL.LVL+1,ORIG.ID,PRINT.OUT,BRCHS,REP.ARRAY,ACCT.AMTS,VALIDATE,CHOICE,GL.SIGN
          ORIG.ID = DELETE(ORIG.ID,1,DCOUNT(ORIG.ID,VM))

          BLOCK.TOT<BLOCK.LVL> = TMP.TOT.AMTS<1>
          BLOCK.DEB<BLOCK.LVL> = TMP.TOT.AMTS<2>
          BLOCK.CRD<BLOCK.LVL> = TMP.TOT.AMTS<3>

          LN.OPT1    = LINE<1,10>
          LN.OPT2    = LINE<1,11>
          LINE       = ''
          LINE<1,5>  = GLID
          LINE<1,3>  = GL.GRP<J,3>
          LINE<1,1>  = 'End'
          LINE<1,10> = LN.OPT1
          LINE<1,11> = LN.OPT2
          NUMERIC    = YES
          BLOCK.LVL -= 1
          REC.REC    = ''
          ADD       -= AMT.INDENT

          GOSUB PARSE.AMT

          RETURN
*-------------------------------------------------------------------------*
PRT.TOT.LN:  *
          IF NOT(PRINT.OUT) OR REP.ARRAY<1,1> = 1    THEN RETURN
          IF LINE<1,1> = 'Start' OR DOWNLOAD         THEN RETURN

          FOR COLUMN = 1 TO COLUMN.CT
             STACK = RAISE(REP.ARRAY<1,18,COLUMN>)
             TOKEN = STACK<1,1>

             *** Get the column width...
             FLEN  = REP.ARRAY<1,29,COLUMN>
             *** If no width is defined make it 15...
             IF NOT(FLEN) THEN FLEN = 15

             *** Set our Format variable...
             FMT = "L#":FLEN

             BEGIN CASE
             *** Account #...
             CASE TOKEN = 'AC';     PRT.TMP = ''
             *** Account Segment...
             CASE TOKEN[1,2] = 'SG';PRT.TMP = ''
             *** Full Description...
             CASE TOKEN = 'FD';     PRT.TMP = ''
             *** Internal Description...
             CASE TOKEN = 'ID';     PRT.TMP = ''
             *** Short Description...
             CASE TOKEN = 'SD';     PRT.TMP = ''
             *** Internal Number...
             CASE TOKEN = 'IN';     PRT.TMP = ''
             *** Keyword...
             CASE TOKEN[1,1] = 'K'; PRT.TMP = ''
             *** Otherwise we're printing a Total Line...
             CASE OTHERWISE
                *** Make our Temp Print String a String of dashes...
                PRT.TMP = STR(DASH,FLEN)
             END CASE

             PRINT PRT.TMP FMT:' ':
          NEXT COLUMN

          PRINT

          RETURN
*-------------------------------------------------------------------------*
PARSE.AMT:*
          IF (DEBUG.ACTIVE) THEN
             LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
               DEBUG.LINE  = 'GL.REC.REPORT-PARSE.AMT:- START'
               DEBUG.LINE := ' CALL.LVL=[':CALL.LVL :']'
               DEBUG.LINE := ' ORID.ID=[':ORIG.ID:']'
               PRINT DEBUG.LINE
            END
          END

          *** If the Line is flagged to print the dashed (Total) lines...
          IF LINE<1,10,1> # '' THEN
             DASH = '-'
             GOSUB PRT.TOT.LN
          END
          LAST.COL    = ''
          TOTALS      = ''
          ZEROS       = YES
          ACCT.BAL    = NO
          BR.DETAIL   = (CHOICE = 3 AND REC.REC<9,1> AND NOT(DOWNLOAD))

          COL.COUNT = COLUMN.CT
          FOR COLUMN = 1 TO COL.COUNT
             AMT.STACK   = ''
             PTR         = 0
             AMT         = 0
             STACK       = RAISE(REP.ARRAY<1,18,COLUMN>)
             TOKENS      = DCOUNT(STACK,SVM)
             BLANK       = NO
             CREDIT.ONLY = NO
             DEBIT.ONLY  = NO
             USE.MULT    = NO
             IS.PCTG     = NO
             BR.CTR      = 1

             *** Column Width...
             FLEN        = REP.ARRAY<1,29,COLUMN>
             *** If no width is defined make it 15...
             IF NOT(FLEN) THEN FLEN = 15

             SKIP.COL = NO
             FOR T = 1 TO TOKENS
                GOSUB CALC.AMT
                IF SKIP.COL THEN GOTO SKIP.COL
             NEXT T
SKIP.COL:    *
             IF PTR = 0 THEN AMT = '' ELSE AMT = AMT.STACK<PTR>



             IF LINE<1,1> = 'End' OR LINE<1,1> = 'Total' OR LINE<1,1> = 'CTotal' THEN
                IF NOT(BR.DETAIL) OR NOT(PRINT.OUT) THEN
                   GOSUB MAKE.TOT.AMT
                END
             END ELSE
                *** Don't add subledgers to any total blocks
                IF PROCESS.SL = 0 AND ( NOT(BR.DETAIL) OR NOT(PRINT.OUT) ) THEN
                   GOSUB ADD.TO.REG.BLK
                END
                GOSUB MAKE.REG.AMT
             END
             IF NUMERIC AND TOKEN#'IN' AND TOKEN#'K' AND TOKEN[1,2] # 'SG' AND NUM(AMT) AND PROCESS.SL = 0 THEN
*** The next if statement stores the actual end total for a template in a
*** variable called TEMPL.TOTAL which is sent back to GL.REP3 to figure
*** template sign.  Because the Actual Amounts can switch real debit and
*** credit amounts we're never really sure whether we should be adding ro
*** subtracting.  As a result we always know that BLOCK.TOT contains the
*** real actual Amount.  As a result we can use it to determine whether to
*** add or subtract the sign altered Amt.  Somewhat confusing but it
*** works.
               IF ABS(TEMPL.TOTAL<BLOCK.LVL,COLUMN> + AMT) # ABS(BLOCK.TOT<BLOCK.LVL,COLUMN>) THEN
                  TEMPL.TOTAL<BLOCK.LVL,COLUMN> -= AMT
               END ELSE
                  TEMPL.TOTAL<BLOCK.LVL,COLUMN> += AMT
               END
             END

             IF (DEBUG.ACTIVE) THEN
                LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
                  DEBUG.LINE  = 'PARSE.AMT-AFTER TEMPL.TOTAL'
                  DEBUG.LINE := ' CALL.LVL=[' :CALL.LVL :']'
                  DEBUG.LINE := ' ORID.ID=['  : ORIG.ID :']'
                  DEBUG.LINE := ' AMT=['      : AMT     :']'
                  DEBUG.LINE := ' BLK.LVL=[':BLOCK.LVL:']'
                  DEBUG.LINE := ' COL=['   : COLUMN  :']'
                  DEBUG.LINE := ' TEMPL.TOTAL<BLK.LVL,COL>=[':TEMPL.TOTAL<BLOCK.LVL,COLUMN>:']'
                  PRINT DEBUG.LINE
               END
             END

             IF NOT(PRINT.OUT) THEN GOTO SKIP.PRT

             * If token is Full Description, Acct #, Internal Description
             * or Short Description
             DESC.TOKEN = (TOKEN = 'FD' OR TOKEN = 'AC' OR TOKEN[1,2] = 'SG' OR TOKEN = 'ID' OR TOKEN = 'SD')


             BEGIN CASE
             *** Description Token
             CASE DESC.TOKEN
                FMT = "L#":FLEN
                SP  = SPACE(ADD)
                IF BR.DETAIL THEN
                   FOR BR.LN = 1 TO BR.CT
                      AMT<1,1,-1> = SPACE(ADD):'Branch ':BRCHS<1,BR.LN>
                   NEXT BR.LN
                   AMT<1,1,-1> = SPACE(ADD):'Total'
                END
             *** Internal Number...
             CASE TOKEN = 'IN';     FMT = "L#":FLEN;  SP = ''
             *** Keyword...
             CASE TOKEN[1,1] = 'K'; FMT = "L#":FLEN;  SP = ''
             *** If it's not a number...
             CASE NOT(NUMERIC);   FMT = "L#":FLEN;  SP = ''
             *** Internal Description...
             CASE OTHERWISE
                FMT = "R#":FLEN
                SP  = ''
                IF IS.PCTG THEN
                   PTMP = REP.ARRAY<1,30> + 0
                   PAMT = 100 / PWR(10,PTMP)
                   IF NEG.SIGN THEN PFMT="MD":PTMP ELSE PFMT="MD":PTMP:",<"
                END ELSE
                   UNITS = REP.ARRAY<1,7>
                END
                *** Set the Sign for AMT
                GOSUB SET.SIGN

                IF BR.DETAIL THEN
                   UPD.SL.TOTALS = NO;* already updated
                   SV.BRCHS = BRCHS
                   TMP.AMT = ''
                   BR.TOTS = 0
                   FOR BR.LN = 1 TO BR.CT
                      AMT.STACK   = ''
                      PTR         = 0
                      AMT         = 0
                      CREDIT.ONLY = NO
                      DEBIT.ONLY  = NO
                      USE.MULT    = NO
                      BR.CTR      = BR.LN+1

                      BRCHS = SV.BRCHS<1,BR.LN>
                      SKIP.COL = NO
                      FOR T = 1 TO TOKENS
                         GOSUB CALC.AMT
                         IF SKIP.COL THEN GOTO BR.SKIP.COL
                      NEXT T
BR.SKIP.COL:          *
                      IF PTR=0 THEN AMT = '' ELSE AMT = AMT.STACK<PTR>

                      IF LINE<1,1> = 'End' OR LINE<1,1> = 'Total' OR LINE<1,1> = 'CTotal' THEN
                         GOSUB MAKE.TOT.AMT
                         BR.TOTS = AMT
                      END ELSE
                         * The acct has already been added to tot blocks
                         * Don't add subledgers to total blocks
                         IF PROCESS.SL = 0 THEN
                            GOSUB ADD.TO.REG.BLK
                         END
                         GOSUB MAKE.REG.AMT
                         BR.TOTS += AMT
                      END

                      IF IS.PCTG THEN
                         PTMP = REP.ARRAY<1,30> + 0
                         PAMT = 100 / PWR(10,PTMP)
                         PFMT = "MD":PTMP
                         IF NOT(NEG.SIGN) THEN PFMT := ",<"
                      END ELSE
                         UNITS = REP.ARRAY<1,7>
                      END

                      GOSUB SET.SIGN

                      TMP.AMT<1,1,-1> = AMT
                   NEXT BR.LN

                   AMT = SVM:TMP.AMT

                   * Next section gets the total for the branches, assigns
                   * the right signage and then stores in AMT array
                   SV.AMT = AMT
                   AMT = BR.TOTS
                   GOSUB SET.SIGN
                   BR.TOTS = AMT
                   AMT = SV.AMT

                   AMT<1,1,BR.CT+2> = BR.TOTS
                   BRCHS = SV.BRCHS
                   UPD.SL.TOTALS = YES
                END
             END CASE

             *** If first column not description then turn Account
             *** Balance setting off because we can't indent
             IF COLUMN = 1 AND FMT[1,1] # 'L' THEN
                REP.ARRAY<1,31,3> = ''
             END

             *** If they specified to Show Account Balance then we indent
             *** the SubLEdger Stuff by 5 spaces
             IF SL.ALLOWED # 'N' AND REP.ARRAY<1,31,3> AND COLUMN = 1 THEN
                FMT.LEN = FIELD(FMT,'#',2)+0
                FMT.LEN -= 10
                *** Not enough room to indent subLedger totals
                IF FMT.LEN < 0 THEN
                   REP.ARRAY<1,31,3> = ''
                END ELSE
                   IF PROCESS.SL = 0 THEN
                      AMT := " ** Account Balance**"
                      ACCT.BAL = YES
                   END ELSE
                      *** Indent the SubLedger Totals
                      FMT = "L#":FMT.LEN
                   END
                END
             END

             IF BLANK THEN
                IF NOT(DOWNLOAD) THEN TOTALS<-1>='':VM:'':VM:FMT
             END ELSE
                TOTALS<-1> = SP:VM:AMT:VM:FMT
             END
SKIP.PRT: *
          NEXT COLUMN

          OVERIDE = NOT(NUMERIC) OR LINE<1,1>='End' OR LINE<1,1>='Total' OR LINE<1,1> = 'CTotal'
          TESTER  = (REP.ARRAY<1,5,1> OR NOT(ZEROS) OR OVERIDE) AND NOT(HIDE.BLOCK<BLOCK.LVL>)
          IF PRINT.OUT AND TESTER THEN
*         IF PRINT.OUT AND (REP.ARRAY<1,5> OR NOT(ZEROS) OR OVERIDE) THEN
             GOSUB PRT.ACCT
          END

          *** If Line is flagged to print the dashed (Grand Total) lines...
          IF LINE<1,10,2> # '' THEN
             DASH = '='
             GOSUB PRT.TOT.LN
          END
SKIP.ALL: *
          RETURN
*-------------------------------------------------------------------------*
SET.SIGN: * Set Sign on Amount

          IF NEG.SIGN THEN N0FMT="MD"  ELSE N0FMT="MD,<"
          IF NEG.SIGN THEN N2FMT="MD2" ELSE N2FMT="MD2,<"
          IF NEG.SIGN THEN N1FMT="MD1" ELSE N1FMT="MD1,<"

          BEGIN CASE
             CASE IS.PCTG;     AMT=OCONV(AMT/PAMT,PFMT)
             CASE UNITS=2;     AMT=OCONV(AMT/100,N0FMT)
             CASE UNITS=3;     AMT=OCONV(AMT/100000,N0FMT)
             CASE UNITS=4;     AMT=OCONV(AMT/10,N1FMT)
             CASE OTHERWISE;   AMT=OCONV(AMT,N2FMT)
          END CASE

          RETURN
*-------------------------------------------------------------------------*
PRT.ACCT: *
          *** If Printing Account but SubLedger detail is set on then
          *** just print account description
          IF SL.ALLOWED # 'N' AND PROCESS.SL = 0 THEN
             IF NOT(ACCT.BAL) THEN
                SV.COL.CT = COLUMN.CT
                COLUMN.CT = 1
             END
          END

          IF BR.DETAIL THEN
             FOR ACCT.LN = 1 TO (BR.CT + 2)
                GOSUB PRT.LN
             NEXT ACCT.LN
          END ELSE
             IF NOT(DOWNLOAD) THEN
                ACCT.LN = 1
                GOSUB PRT.LN
             END ELSE
                FOR COLUMN = 1 TO COLUMN.CT
                   TMP = TOTALS<COLUMN,2>
                   IF NUM(TMP) THEN
                   TMP = OCONV(TMP,'MR,$')
                   END
                   IF TRIMIT THEN TMP = TRIM(TMP)
                   PRINT '"':TMP:'"':CDELIM:
                NEXT COLUMN
             END
          END

          *** Reset columnt count back
          IF SL.ALLOWED # 'N' AND PROCESS.SL = 0 AND NOT(ACCT.BAL) THEN
             COLUMN.CT = SV.COL.CT
          END

          RETURN
*-------------------------------------------------------------------------*
PRT.LN:   * Print one line of the report...

          *** If they want to see Branch Detail, (?the account line is NOT
          *** equal to the number of branches + 2?), and the they do NOT
          *** want to 'Show Zero Branches'...
          IF BR.DETAIL AND ACCT.LN#(BR.CT+2) AND NOT(REP.ARRAY<1,5,2>) THEN
             LN.BLANK = NO

             *** Make sure our dollar amounts aren't ALL "0.00"...
             FOR COLUMN = 1 TO COLUMN.CT
                *** Get the next column of data...
                TMP = TOTALS<COLUMN,2,ACCT.LN>

                *** Since the dollar amounts are stored in the TOTALS
                *** array WITH commas, they won't properly evaluate as a
                *** number. We need to take the commas and brackets out...
                *** Brackets are caused by negative numbers.
                NEXT.TEMP = TMP
                CONVERT ',' TO '' IN NEXT.TEMP
                CONVERT '<' TO '' IN NEXT.TEMP
                CONVERT '>' TO '' IN NEXT.TEMP

                *** We only want to validate TMP if it's a number...
                IF NEXT.TEMP # '' AND NUM(NEXT.TEMP) THEN
                   NEXT.TEMP += 0
                   IF NEXT.TEMP = 0 THEN
                      LN.BLANK = YES
                   END ELSE
                      *** If we find a non-zero we stop checking the rest
                      *** of the column data...
                      LN.BLANK = NO
                      EXIT
                   END
                END
             NEXT COLUMN

             IF LN.BLANK THEN RETURN
          END

          *** Print each column of data for this line of the report...
          FOR COLUMN = 1 TO COLUMN.CT
             TMP = TOTALS<COLUMN,1>:TOTALS<COLUMN,2,ACCT.LN>
             IF COLUMN = 1 AND TMP[1,3] = 'SL#' THEN TMP = '     ':TMP[4,LEN(TMP)-3]
             PRINT TMP TOTALS<COLUMN,3>:' ':
          NEXT COLUMN

          PRINT

          RETURN
*-------------------------------------------------------------------------*
PRT.SL:   * Print SubLedger Info
          *** The following logic will look to see if they have specified
          *** specific SubLedger Accounts.  If they have then we will only
          *** show those SubLedgers and will not not show a null amount.

          *** If they do not specify Subledgers then we will print all
          *** SubLedger Amounts including the null entry which we have to
          *** back into by getting the account total and subtracting out
          *** all other subledger amounts

          SUB.LEDS = ''

          IF SL.SPECIFIED THEN
             SL.LIST = RAISE(RAISE(REP.ARRAY<1,31,2>))
          END

          CMD = 'SELECT GENLED.TRANS WITH GL# = ':GLID

          EXECUTE CMD CAPTURING MSG

          LOOP
             READNEXT SLID ELSE EXIT

             SLID = FIELD(SLID,'~',3)
             *** Only get the summary fields so we don't have redundancy
             IF FIELD(SLID,'*',2) # '' THEN CONTINUE
             IF SLID = '' THEN CONTINUE
             *** If SubLedgers were specified then see if this subledger
             *** is specified in the list.
             IF SL.SPECIFIED THEN
                LOCATE SLID IN SL.LIST<1> SETTING POS ELSE
                   CONTINUE
                END
             END
             LOCATE SLID IN SUB.LEDS BY 'AR' SETTING POS ELSE
                SUB.LEDS = INSERT(SUB.LEDS,POS;SLID)
             END
          REPEAT

          SUB.CT = DCOUNT(SUB.LEDS,AM)

          FOR SL = 1 TO SUB.CT
             PROCESS.SL = SL
             GOSUB PARSE.AMT
          NEXT SL

          *** If SubLedgers were not specified then print the null Sub
          *** Ledger info, which is total account amount minu the subledger
          *** total which is in SL.TOTAL
          IF NOT(SL.SPECIFIED) THEN
             *** Set PROCESS.SL back to 0
             PROCESS.SL = 0

             *** IF SL.TOTALS is 0 then there is no null account info
             NULL.TOTAL =  SUBS(SL.TOTALS<1>,SL.TOTALS<2>)
             IF BR.DETAIL THEN
                NULL.TOTAL = RAISE(NULL.TOTAL)
             END

             *** Check to see if we even have an amount to display
             NULL.AMT = SUMMATION(NULL.TOTAL)+0

             *** If NULL.AMT = 0 then we need to get out of here.
             IF NULL.AMT = 0 THEN RETURN

             PROCESS.SL = SUB.CT + 1
             SUB.LEDS<PROCESS.SL> = "**Null**"
             GOSUB PARSE.AMT
          END

          *** Set PROCESS.SL back to 0
          PROCESS.SL = 0

          RETURN
*-------------------------------------------------------------------------*
CALC.AMT: * This routine actually decides what amt to get before sending
          * it through the MAKE.REG.AMT and Totals subroutines.

          TOKEN = STACK<1,1,T>

          IF (DEBUG.ACTIVE) THEN
             LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
               DEBUG.LINE  = 'GL.REC.REPORT-CALC.AMT: - START'
               DEBUG.LINE := ' CALL.LVL=['      :CALL.LVL        :']'
               DEBUG.LINE := ' ORID.ID=['       :ORIG.ID         :']'
               DEBUG.LINE := ' COLUMN=['        :COLUMN          :']'
               DEBUG.LINE := ' TOKEN=['         :TOKEN           :']'
               DEBUG.LINE := ' AMT.STACK=['     :AMT.STACK       :']'
               DEBUG.LINE := ' PTR=['           :PTR             :']'
               DEBUG.LINE := ' AMT.STACK<PTR>=[':AMT.STACK<PTR>  :']'
               PRINT DEBUG.LINE
            END
          END

          IF TOKEN = '' THEN RETURN

          BEGIN CASE
          *---------------------------------------------------------------*
          CASE TOKEN='AC' OR TOKEN='FD' OR TOKEN='SD' OR TOKEN='ID'
             PTR += 1
             DELIM.CHAR = ' '
             BEGIN CASE
             *** Account # is in Attribute 2 of GENLED
             CASE TOKEN='AC'
                POS = 2
                *** If using GL Structure then get correct delimiter
                READV DELIM.CHAR FROM CTRLFILE,'GL.STRUCTURE',1 ELSE DELIM.CHAR = ' '
                IF DELIM.CHAR = 'b' THEN DELIM.CHAR = ' '
             *** Full Description is in Attribute 3 of GENLED
             CASE TOKEN='FD';  POS = 3
             *** Short Description is in Attribute 4 of GENLED
             CASE TOKEN='SD';  POS = 4
             *** Internal Description is in Attribut 5 of GENLED
             CASE TOKEN='ID';  POS = 5
             END CASE

             BEGIN CASE
             CASE LINE<1,5>#'' AND LINE<1,1>#'End'
                IF LINE<1,3,3>='' THEN
                   *** See if we are processing a SubLedger
                   IF SL.ALLOWED # 'N' AND PROCESS.SL # 0 THEN
                      *** Print SubLedger Account Name
                      A = 'SL#':SUB.LEDS<PROCESS.SL>
                      START.NAME = A
                   END ELSE
                      *** If this is call group pull header from the
                      *** call line.
                      IF LINE<1,2> = 'Call' THEN
                         A = LINE<1,3,1>
                         START.NAME = A
                      END ELSE
                         *** Pull header from the gl description.
                         A = REC.REC<POS>
                         CONVERT VM TO DELIM.CHAR IN A
                         START.NAME = A
                      END
                   END
                END ELSE
                   A = LINE<1,3,3>
                   START.NAME = ''
                END
             CASE LINE<1,5>#'' AND LINE<1,1>='End'
                A = LINE<1,3,2>
                IF A = '' THEN A = 'Total for ':START.NAME
             CASE OTHERWISE
                A = LINE<1,3,1>
                START.NAME = ''
                IF LINE<1,1> = 'Start' THEN
                   START.NAME = A
                END
             END CASE
             *** If Cost Centers and we are displaying subledgers then
             *** Append Cost Center onto front of Account Name
             IF A # '' AND A[1,3] # 'SL#' AND COST.CTRS THEN
                A = COST.CTRS:' ':A
                CONVERT VM TO ',' IN A
             END

             AMT.STACK<PTR> = A
             SKIP.COL = YES

             IF (DEBUG.ACTIVE) THEN
                LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
                   DEBUG.LINE  = 'GL.REC.REPORT-CALC.AMT:-FD END'
                   DEBUG.LINE := ' CALL.LVL=['      :CALL.LVL        :']'
                   DEBUG.LINE := ' ORID.ID=['       :ORIG.ID         :']'
                   DEBUG.LINE := ' TOKEN=['         :TOKEN           :']'
                   DEBUG.LINE := ' AMT.STACK=['     :AMT.STACK       :']'
                   DEBUG.LINE := ' PTR=['           :PTR             :']'
                   DEBUG.LINE := ' AMT.STACK<PTR>=[':AMT.STACK<PTR>  :']'
                   PRINT DEBUG.LINE
                END
             END

             RETURN
          *---------------------------------------------------------------*
          *** Segment values
          CASE TOKEN[1,2] = 'SG'
             A = ''
             PTR += 1
             IF LINE<1,5>#'' AND LINE<1,1>#'End' THEN
                IF LINE<1,3,3>='' THEN
                   *** See if we are processing a SubLedger
                   IF SL.ALLOWED # 'N' AND PROCESS.SL # 0 THEN
                      BLANK = YES
                   END ELSE
                      A = REC.REC<2>
                      *** If we are looking for segment then pull out
                      *** Segment ID.
                      SPOS = TOKEN[3,99]
                      IF NUM(SPOS) THEN
                         A = A<1,SPOS>
                      END
                      START.NAME = A
                   END
                END ELSE
                   BLANK = YES
                END
             END ELSE
                BLANK = YES
             END

             AMT.STACK<PTR> = A
             SKIP.COL = YES

             IF (DEBUG.ACTIVE) THEN
                LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
                   DEBUG.LINE  = 'GL.REC.REPORT-CALC.AMT:-CASE TOKEN[1,2]="SG"'
                   DEBUG.LINE := ' CALL.LVL=['      :CALL.LVL        :']'
                   DEBUG.LINE := ' ORID.ID=['       :ORIG.ID         :']'
                   DEBUG.LINE := ' TOKEN=['         :TOKEN           :']'
                   DEBUG.LINE := ' AMT.STACK=['     :AMT.STACK       :']'
                   DEBUG.LINE := ' PTR=['           :PTR             :']'
                   DEBUG.LINE := ' AMT.STACK<PTR>=[':AMT.STACK<PTR>  :']'
                   PRINT DEBUG.LINE
                END
             END
          *---------------------------------------------------------------*
          CASE TOKEN='IN'
             PTR += 1
             AMT.STACK<PTR> = LINE<1,5>
             SKIP.COL = YES

             IF (DEBUG.ACTIVE) THEN
                LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
                   DEBUG.LINE  = 'GL.REC.REPORT-CALC.AMT:-CASE TOKEN="IN"'
                   DEBUG.LINE := ' CALL.LVL=['      :CALL.LVL        :']'
                   DEBUG.LINE := ' ORID.ID=['       :ORIG.ID         :']'
                   DEBUG.LINE := ' TOKEN=['         :TOKEN           :']'
                   DEBUG.LINE := ' AMT.STACK=['     :AMT.STACK       :']'
                   DEBUG.LINE := ' PTR=['           :PTR             :']'
                   DEBUG.LINE := ' AMT.STACK<PTR>=[':AMT.STACK<PTR>  :']'
                   PRINT DEBUG.LINE
                END
             END

             RETURN
          *---------------------------------------------------------------*
          CASE TOKEN[1,1]='K'
             PTR += 1
             KEYWORD = FIELD(TOKEN,'~',2)
             IF GROUP OR LINE<1,5>='' OR REC.REC<27,KEYWORD>='' THEN
                BLANK = YES
             END ELSE
                AMT.STACK<PTR> = REC.REC<27,KEYWORD>
             END
             SKIP.COL = YES

             IF (DEBUG.ACTIVE) THEN
                LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
                   DEBUG.LINE  = 'GL.REC.REPORT-CALC.AMT:-CASE TOKEN[1,1]="K"'
                   DEBUG.LINE := ' CALL.LVL=['      :CALL.LVL        :']'
                   DEBUG.LINE := ' ORID.ID=['       :ORIG.ID         :']'
                   DEBUG.LINE := ' TOKEN=['         :TOKEN           :']'
                   DEBUG.LINE := ' AMT.STACK=['     :AMT.STACK       :']'
                   DEBUG.LINE := ' PTR=['           :PTR             :']'
                   DEBUG.LINE := ' AMT.STACK<PTR>=[':AMT.STACK<PTR>  :']'
                   PRINT DEBUG.LINE
                END
             END

             RETURN
          *---------------------------------------------------------------*

          CASE REP.ARRAY<1,1>=1
             *** This is a listing of accounts, so no numeric data.

             IF (DEBUG.ACTIVE) THEN
                LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
                   DEBUG.LINE  = 'GL.REC.REPORT-CALC.AMT:-CASE REP.ARRAY<1,1>=1'
                   DEBUG.LINE := ' CALL.LVL=['      :CALL.LVL        :']'
                   DEBUG.LINE := ' ORID.ID=['       :ORIG.ID         :']'
                   DEBUG.LINE := ' TOKEN=['         :TOKEN           :']'
                   DEBUG.LINE := ' AMT.STACK=['     :AMT.STACK       :']'
                   DEBUG.LINE := ' PTR=['           :PTR             :']'
                   DEBUG.LINE := ' AMT.STACK<PTR>=[':AMT.STACK<PTR>  :']'
                   PRINT DEBUG.LINE
                END
             END

             RETURN TO SKIP.PRT

          *---------------------------------------------------------------*

          CASE NOT(NUMERIC) AND NOT(TOKEN='-' OR TOKEN='+' OR TOKEN='*' OR TOKEN='/')
             *** This must be after all non-numeric cases and befora all #
             BLANK = YES
             SKIP.COL = YES

             IF (DEBUG.ACTIVE) THEN
                LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
                   DEBUG.LINE  = 'GL.REC.REPORT-CALC.AMT:-CASE NOT(NUMERIC)...'
                   DEBUG.LINE := ' CALL.LVL=['      :CALL.LVL        :']'
                   DEBUG.LINE := ' ORID.ID=['       :ORIG.ID         :']'
                   DEBUG.LINE := ' TOKEN=['         :TOKEN           :']'
                   DEBUG.LINE := ' AMT.STACK=['     :AMT.STACK       :']'
                   DEBUG.LINE := ' PTR=['           :PTR             :']'
                   DEBUG.LINE := ' AMT.STACK<PTR>=[':AMT.STACK<PTR>  :']'
                   PRINT DEBUG.LINE
                END
             END

             RETURN

          *---------------------------------------------------------------*
          CASE TOKEN='T'
             *** Templates are an odd animal because we need to keep the
             *** normalized (if credit and liability account show positive)
             *** (if credit and flagged as asset show negative) value but
             *** for totals it needs to be in its gl stored form.
             PTR += 1
             *** Put the the normalized value in the AMT.STACK
             AMT.STACK<PTR> = ACCT.AMTS<1,COLUMN,1>

             IF (DEBUG.ACTIVE) THEN
                LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
                   DEBUG.LINE  = 'GL.REC.REPORT-CALC.AMT:-CASE TOKEN="T"'
                   DEBUG.LINE := ' CALL.LVL=['      :CALL.LVL        :']'
                   DEBUG.LINE := ' ORID.ID=['       :ORIG.ID         :']'
                   DEBUG.LINE := ' TOKEN=['         :TOKEN           :']'
                   DEBUG.LINE := ' AMT.STACK=['     :AMT.STACK       :']'
                   DEBUG.LINE := ' PTR=['           :PTR             :']'
                   DEBUG.LINE := ' AMT.STACK<PTR>=[':AMT.STACK<PTR>  :']'
                   PRINT DEBUG.LINE
                END
             END

          *---------------------------------------------------------------*
          CASE TOKEN='+' AND PTR>1
             PTR -= 1
             USE.MULT = YES
             AMT.STACK<PTR> = AMT.STACK<PTR> + AMT.STACK<PTR+1>

             IF (DEBUG.ACTIVE) THEN
                LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
                   DEBUG.LINE  = 'GL.REC.REPORT-CALC.AMT:-CASE TOKEN="+" AND PTR>1'
                   DEBUG.LINE := ' CALL.LVL=['      :CALL.LVL        :']'
                   DEBUG.LINE := ' ORID.ID=['       :ORIG.ID         :']'
                   DEBUG.LINE := ' TOKEN=['         :TOKEN           :']'
                   DEBUG.LINE := ' AMT.STACK=['     :AMT.STACK       :']'
                   DEBUG.LINE := ' PTR=['           :PTR             :']'
                   DEBUG.LINE := ' AMT.STACK<PTR>=[':AMT.STACK<PTR>  :']'
                   PRINT DEBUG.LINE
                END
             END

          *---------------------------------------------------------------*
          CASE TOKEN='-' AND PTR>1
             PTR -= 1
             USE.MULT = YES
             AMT.STACK<PTR> = AMT.STACK<PTR> - AMT.STACK<PTR+1>

             IF (DEBUG.ACTIVE) THEN
                LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
                   DEBUG.LINE  = 'GL.REC.REPORT-CALC.AMT:-CASE TOKEN="-" AND PTR>1'
                   DEBUG.LINE := ' CALL.LVL=['      :CALL.LVL        :']'
                   DEBUG.LINE := ' ORID.ID=['       :ORIG.ID         :']'
                   DEBUG.LINE := ' TOKEN=['         :TOKEN           :']'
                   DEBUG.LINE := ' AMT.STACK=['     :AMT.STACK       :']'
                   DEBUG.LINE := ' PTR=['           :PTR             :']'
                   DEBUG.LINE := ' AMT.STACK<PTR>=[':AMT.STACK<PTR>  :']'
                   PRINT DEBUG.LINE
                END
             END

          *---------------------------------------------------------------*
          CASE TOKEN='*' AND PTR>1
             PTR -= 1
             USE.MULT = YES
             AMT.STACK<PTR> = AMT.STACK<PTR> * AMT.STACK<PTR+1> / 100

             IF (DEBUG.ACTIVE) THEN
                LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
                   DEBUG.LINE  = 'GL.REC.REPORT-CALC.AMT:-CASE TOKEN="*" AND PTR>1'
                   DEBUG.LINE := ' CALL.LVL=['      :CALL.LVL        :']'
                   DEBUG.LINE := ' ORID.ID=['       :ORIG.ID         :']'
                   DEBUG.LINE := ' TOKEN=['         :TOKEN           :']'
                   DEBUG.LINE := ' AMT.STACK=['     :AMT.STACK       :']'
                   DEBUG.LINE := ' PTR=['           :PTR             :']'
                   DEBUG.LINE := ' AMT.STACK<PTR>=[':AMT.STACK<PTR>  :']'
                   PRINT DEBUG.LINE
                END
             END

          *---------------------------------------------------------------*
          CASE TOKEN='%' AND PTR>1
             PTR -= 1
             USE.MULT = YES
             IS.PCTG  = YES
             AMT.STACK<PTR> = AMT.STACK<PTR> * AMT.STACK<PTR+1> / 100

             IF (DEBUG.ACTIVE) THEN
                LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
                   DEBUG.LINE  = 'GL.REC.REPORT-CALC.AMT:-CASE TOKEN="%" AND PTR>1'
                   DEBUG.LINE := ' CALL.LVL=['      :CALL.LVL        :']'
                   DEBUG.LINE := ' ORID.ID=['       :ORIG.ID         :']'
                   DEBUG.LINE := ' TOKEN=['         :TOKEN           :']'
                   DEBUG.LINE := ' AMT.STACK=['     :AMT.STACK       :']'
                   DEBUG.LINE := ' PTR=['           :PTR             :']'
                   DEBUG.LINE := ' AMT.STACK<PTR>=[':AMT.STACK<PTR>  :']'
                   PRINT DEBUG.LINE
                END
             END

          *---------------------------------------------------------------*
          CASE TOKEN='/' AND PTR>1
             PTR -= 1
             TMP  = AMT.STACK<PTR+1>
             USE.MULT = YES
             IF TMP=0 OR TMP='' THEN AMT.STACK<PTR> = 0 ELSE
                AMT.STACK<PTR> = 100 * AMT.STACK<PTR> / AMT.STACK<PTR+1>
             END

             IF (DEBUG.ACTIVE) THEN
                LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
                   DEBUG.LINE  = 'GL.REC.REPORT-CALC.AMT:-CASE TOKEN="/" AND PTR>1'
                   DEBUG.LINE := ' CALL.LVL=['      :CALL.LVL        :']'
                   DEBUG.LINE := ' ORID.ID=['       :ORIG.ID         :']'
                   DEBUG.LINE := ' TOKEN=['         :TOKEN           :']'
                   DEBUG.LINE := ' AMT.STACK=['     :AMT.STACK       :']'
                   DEBUG.LINE := ' PTR=['           :PTR             :']'
                   DEBUG.LINE := ' AMT.STACK<PTR>=[':AMT.STACK<PTR>  :']'
                   PRINT DEBUG.LINE
                END
             END

          *---------------------------------------------------------------*
          CASE NUM(TOKEN[2,999]) AND TOKEN[1,1]='#'
             TOKEN = TOKEN[2,999]
             IF TOKEN<COLUMN THEN
                PTR += 1
*** This is derived field so we want to set the USE.MULT on so that when
*** totalling it will just used the derived field not some total field
                USE.MULT = YES
                AMT.STACK<PTR> = LAST.COL<BR.CTR,TOKEN>
             END

             IF (DEBUG.ACTIVE) THEN
                LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
                   DEBUG.LINE  = 'GL.REC.REPORT-CALC.AMT:-CASE NUM(TOKEN[2,999]) AND TOKEN[1,1]="#"'
                   DEBUG.LINE := ' CALL.LVL=['      :CALL.LVL        :']'
                   DEBUG.LINE := ' ORID.ID=['       :ORIG.ID         :']'
                   DEBUG.LINE := ' TOKEN=['         :TOKEN           :']'
                   DEBUG.LINE := ' AMT.STACK=['     :AMT.STACK       :']'
                   DEBUG.LINE := ' PTR=['           :PTR             :']'
                   DEBUG.LINE := ' AMT.STACK<PTR>=[':AMT.STACK<PTR>  :']'
                   PRINT DEBUG.LINE
                END
             END

          *---------------------------------------------------------------*
          CASE NUM(TOKEN) AND TOKEN#''
             PTR += 1
             AMT.STACK<PTR> = ICONV(TOKEN,'MR2')

             IF (DEBUG.ACTIVE) THEN
                LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
                   DEBUG.LINE  = 'GL.REC.REPORT-CALC.AMT:-CASE NUM(TOKEN) AND TOKEN#""'
                   DEBUG.LINE := ' CALL.LVL=['      :CALL.LVL        :']'
                   DEBUG.LINE := ' ORID.ID=['       :ORIG.ID         :']'
                   DEBUG.LINE := ' TOKEN=['         :TOKEN           :']'
                   DEBUG.LINE := ' AMT.STACK=['     :AMT.STACK       :']'
                   DEBUG.LINE := ' PTR=['           :PTR             :']'
                   DEBUG.LINE := ' AMT.STACK<PTR>=[':AMT.STACK<PTR>  :']'
                   PRINT DEBUG.LINE
                END
             END

          *---------------------------------------------------------------*
          CASE LINE<1,1>='Total' OR LINE<1,1> = 'CTotal'
             LOCATE 'D' IN STACK<1,1> SETTING P THEN DEBIT.ONLY = YES
             LOCATE 'C' IN STACK<1,1> SETTING P THEN CREDIT.ONLY = YES

             PTR += 1
             AMT.STACK<PTR> = 0
             SKIP.COL = YES

             IF (DEBUG.ACTIVE) THEN
                LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
                   DEBUG.LINE  = 'GL.REC.REPORT-CALC.AMT:-CASE LINE<1,1>="Total" OR LINE<1,1>="CTotal"'
                   DEBUG.LINE := ' CALL.LVL=['      :CALL.LVL        :']'
                   DEBUG.LINE := ' ORID.ID=['       :ORIG.ID         :']'
                   DEBUG.LINE := ' TOKEN=['         :TOKEN           :']'
                   DEBUG.LINE := ' AMT.STACK=['     :AMT.STACK       :']'
                   DEBUG.LINE := ' PTR=['           :PTR             :']'
                   DEBUG.LINE := ' AMT.STACK<PTR>=[':AMT.STACK<PTR>  :']'
                   PRINT DEBUG.LINE
                END
             END

             RETURN
          *---------------------------------------------------------------*
          CASE LINE<1,1>='End'
             LOCATE 'D' IN STACK<1,1> SETTING P THEN DEBIT.ONLY = YES
             LOCATE 'C' IN STACK<1,1> SETTING P THEN CREDIT.ONLY = YES

             PTR += 1
             AMT.STACK<PTR> = 0
             SKIP.COL = YES

             IF (DEBUG.ACTIVE) THEN
                LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
                   DEBUG.LINE  = 'GL.REC.REPORT-CALC.AMT:-CASE LINE<1,1>="End"'
                   DEBUG.LINE := ' CALL.LVL=['      :CALL.LVL        :']'
                   DEBUG.LINE := ' ORID.ID=['       :ORIG.ID         :']'
                   DEBUG.LINE := ' TOKEN=['         :TOKEN           :']'
                   DEBUG.LINE := ' AMT.STACK=['     :AMT.STACK       :']'
                   DEBUG.LINE := ' PTR=['           :PTR             :']'
                   DEBUG.LINE := ' AMT.STACK<PTR>=[':AMT.STACK<PTR>  :']'
                   PRINT DEBUG.LINE
                END
             END

             RETURN
          *---------------------------------------------------------------*
          CASE GROUP
             A = LINE.AMTS<1,COLUMN,1>
             PTR += 1
             AMT.STACK<PTR> = A
             IF A#0 THEN ZEROS = NO
             SKIP.COL = YES

             LOCATE 'D' IN STACK<1,1> SETTING P THEN DEBIT.ONLY = YES
             LOCATE 'C' IN STACK<1,1> SETTING P THEN CREDIT.ONLY = YES

             IF (DEBUG.ACTIVE) THEN
                LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
                   DEBUG.LINE  = 'GL.REC.REPORT-CALC.AMT:-CASE GROUP'
                   DEBUG.LINE := ' CALL.LVL=['      :CALL.LVL        :']'
                   DEBUG.LINE := ' ORID.ID=['       :ORIG.ID         :']'
                   DEBUG.LINE := ' TOKEN=['         :TOKEN           :']'
                   DEBUG.LINE := ' AMT.STACK=['     :AMT.STACK       :']'
                   DEBUG.LINE := ' PTR=['           :PTR             :']'
                   DEBUG.LINE := ' AMT.STACK<PTR>=[':AMT.STACK<PTR>  :']'
                   PRINT DEBUG.LINE
                END
             END


             RETURN
          *---------------------------------------------------------------*
          CASE TOKEN='A' OR TOKEN='D' OR TOKEN='C'
             IF NOT(PRINT.OUT) THEN TOKEN='A'

             *** Set CRED/DEB ONLY and TST for the call to GL.GET.AMT
             BEGIN CASE
             CASE TOKEN = 'D'
                DEBIT.ONLY  = YES
                TST         = 1
             CASE TOKEN = 'C'
                CREDIT.ONLY = YES
                TST         = -1
             CASE OTHERWISE
                CREDIT.ONLY = NO
                DEBIT.ONLY  = NO
                TST         = ''
             END CASE

             IF PROCESS.SL = 0 THEN
                GOSUB GET.AMT
             END ELSE
                *** If Process SubLedgers and null account get Amount
                *** From Null Total
                SL.ID = SUB.LEDS<PROCESS.SL>
                *** Null subledger is the total account - subLedgers
                IF SL.ID = "**Null**" THEN
                   IF BR.DETAIL THEN
                      A = NULL.TOTAL<BR.LN,COLUMN,PTR+1>
                   END ELSE
                      A = NULL.TOTAL<1,COLUMN,PTR+1>
                   END
                END ELSE
                   GOSUB GET.AMT
                END
             END

             IF A#0 THEN ZEROS=NO

             PTR += 1
             AMT.STACK<PTR> = A

             IF (DEBUG.ACTIVE) THEN
                LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
                   DEBUG.LINE  = 'GL.REC.REPORT-CALC.AMT:-CASE TOKEN="A" OR TOKEN="D" OR TOKEN="C"'
                   DEBUG.LINE := ' CALL.LVL=['      :CALL.LVL        :']'
                   DEBUG.LINE := ' ORID.ID=['       :ORIG.ID         :']'
                   DEBUG.LINE := ' TOKEN=['         :TOKEN           :']'
                   DEBUG.LINE := ' AMT.STACK=['     :AMT.STACK       :']'
                   DEBUG.LINE := ' PTR=['           :PTR             :']'
                   DEBUG.LINE := ' AMT.STACK<PTR>=[':AMT.STACK<PTR>  :']'
                   PRINT DEBUG.LINE
                END
             END

          *---------------------------------------------------------------*
          CASE TOKEN='BD' OR TOKEN='BB'
             IF TOKEN='BB' THEN ENDING='*BAL' ELSE ENDING=''
             A = 0

             EDATE = REP.ARRAY<1,17,COLUMN>
             IF EDATE='' THEN EDATE = REP.ARRAY<1,9>
             EDATE = OCONV(EDATE,'D4/')
             EYEAR = FIELD(EDATE,'/',3)
             EMNTH = FIELD(EDATE,'/',1)

             FOR B = 1 TO BR.CT
                BR = BRCHS<1,B>
                IF REP.ARRAY<1,1> = 2 THEN
                   IF PROCESS.SL = 0 THEN
                      BUD.KEY = LINE<1,5>:'*':EYEAR:'*':BR:ENDING
                   END ELSE
                      SL.ID = SUB.LEDS<PROCESS.SL>
                      *** Null subledger is the total account - subLedgers
                      IF SL.ID = "**Null**" THEN
                         BUD.KEY = LINE<1,5>:'~*':EYEAR:'*':BR:ENDING
                      END ELSE
                         BUD.KEY = LINE<1,5>:'~':SL.ID:'*':EYEAR:'*':BR:ENDING
                      END
                   END
                   READ TMP FROM BDGFILE,BUD.KEY ELSE TMP = ''
                   A += TMP<1,EMNTH>
                END ELSE



                   GPS = TRANS('GENLED.RPT.GPS',OCONV(REP.ARRAY<1,21>,'MCU'),1,'X')
                   IF GPS = '1' THEN
                   SDATE = '16938'
                   END ELSE
                   SDATE = REP.ARRAY<1,16,COLUMN>
                   END


                   SDATE = OCONV(SDATE,'D4/')
                   SYEAR = FIELD(SDATE,'/',3)
                   SMNTH = FIELD(SDATE,'/',1)

                   FOR YEAR = SYEAR TO EYEAR
                      IF PROCESS.SL = 0 THEN
                         BUD.KEY = LINE<1,5>:'*':YEAR:'*':BR:ENDING
                      END ELSE
                         SL.ID = SUB.LEDS<PROCESS.SL>
                         *** Null subledger is the total account-subLedgers
                         IF SL.ID = "**Null**" THEN
                            BUD.KEY = LINE<1,5>:'~*':YEAR:'*':BR:ENDING
                         END ELSE
                            BUD.KEY = LINE<1,5>:'~':SL.ID:'*':YEAR:'*':BR:ENDING
                         END
                      END
                      READ TMP FROM BDGFILE,BUD.KEY ELSE TMP = ''

                      IF YEAR=SYEAR THEN BEG.MNTH=SMNTH ELSE BEG.MNTH=1
                      IF YEAR=EYEAR THEN END.MNTH=EMNTH ELSE END.MNTH=12
                      FOR MNTH = BEG.MNTH TO END.MNTH
                         A += TMP<1,MNTH>
                      NEXT MNTH
                   NEXT YEAR
                END
             NEXT B

             IF A#0 THEN ZEROS=NO

             * compensate for credit accounts with debit budgets
             IF NOT(REC.REC<1,1>) THEN A = -A

             PTR += 1
             AMT.STACK<PTR> = A

             IF (DEBUG.ACTIVE) THEN
                LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
                   DEBUG.LINE  = 'GL.REC.REPORT-CALC.AMT:-CASE TOKEN="BD" OR TOKEN="BB"'
                   DEBUG.LINE := ' CALL.LVL=['      :CALL.LVL        :']'
                   DEBUG.LINE := ' ORID.ID=['       :ORIG.ID         :']'
                   DEBUG.LINE := ' TOKEN=['         :TOKEN           :']'
                   DEBUG.LINE := ' AMT.STACK=['     :AMT.STACK       :']'
                   DEBUG.LINE := ' PTR=['           :PTR             :']'
                   DEBUG.LINE := ' AMT.STACK<PTR>=[':AMT.STACK<PTR>  :']'
                   PRINT DEBUG.LINE
                END
             END

          *---------------------------------------------------------------*
          END CASE

          RETURN
*-------------------------------------------------------------------------*
GET.AMT:  *
          A = 0

          IF REP.ARRAY<1,1>#2 THEN
             ** Only use the sdate if it isn't a balence sheet.
             SDATE = REP.ARRAY<1,16,COLUMN>
          END ELSE
          IF GPS = '1' THEN
          SDATE = '16938'
          END ELSE
          SDATE = ''
          END
          END
          ** If it is a trial balance report and a balance sheet account,
          ** calculate the amount from the beginning of time.
          IF REP.ARRAY<1,1>=5 AND REC.REC<28> AND LINE<1,5>#RET THEN SDATE=''

          EDATE = REP.ARRAY<1,17,COLUMN>
          IF EDATE='' THEN EDATE = REP.ARRAY<1,9>

          *** Retained earnings requires a special range.
          IF LINE<1,5>=RET AND REP.ARRAY<1,1>=5 THEN
             GL.GET.AMT LINE<1,5>,'',BRCHS,SDATE-1,A,,REP.ARRAY<1,27>,REC.REC<29>,EDATE:VM:TST
          END ELSE
             BEGIN CASE

                *SubLedgers are to be displayed
                CASE SL.OPT = 'Y'
                   *SubLedger not allowed for account and we are processing
                   *Subledgers so set SL.ID to the Sub Ledger
                   IF SL.ALLOWED # 'N' AND PROCESS.SL # 0 THEN
                      SL.ID = SUB.LEDS<PROCESS.SL>
                   END ELSE
                      SL.ID = ''
                   END

                *SubLedgers Only
                CASE SL.OPT = 'O'
                   *SubLedger not allowed for account so don't show this
                   *Account, set amount to zero
                   IF SL.ALLOWED = 'N' THEN
                      A = 0
                      GOTO SKIP.AMT
                   END
                   ***SubLedgers are allowed
                   IF PROCESS.SL = 0 THEN
                      *Get Account total for just SubLedgers Specified
                      SL.ID = RAISE(REP.ARRAY<1,31,2>)
                   END ELSE
                      SL.ID = SUB.LEDS<PROCESS.SL>
                   END

                CASE OTHERWISE
                   SL.ID = ''

             END CASE

             GL.GET.AMT LINE<1,5>,SL.ID,BRCHS,EDATE,A,SDATE,REP.ARRAY<1,27>,REC.REC<29>,EDATE:VM:TST


             *** If we are processing subledgers keep track of total
             *** to back into null subledger total
SKIP.AMT:    IF UPD.SL.TOTALS AND SL.ALLOWED # 'N' THEN
                IF PROCESS.SL = 0 THEN
                   *** First Position will Hold Account Total
                   IF BR.DETAIL THEN
                      * For branch detail, we need to separate each BR
                      BRCT = DCOUNT(BRCHS,VM)
                      FOR BRLN = 1 TO BRCT
                         SBRCH = BRCHS<1,BRLN>
                         GL.GET.AMT LINE<1,5>,SL.ID,SBRCH,EDATE,A,SDATE,REP.ARRAY<1,27>,REC.REC<29>,EDATE:VM:TST
                         TMP.ARRAY = ''
                         TMP.ARRAY<1,1,PTR+1> = A
                         SL.TOTALS<1,BRLN,COLUMN> = LOWER(TMP.ARRAY)
                      NEXT BRLN
                   END ELSE
                      SL.TOTALS<1,COLUMN,PTR+1> = A
                   END
                END ELSE
                   *** Second attribute will hold SubLedger Totals
                   IF BR.DETAIL THEN
                      * For branch detail, we need to separate each BR
                      BRCT = DCOUNT(BRCHS,VM)
                      FOR BRLN = 1 TO BRCT
                         SBRCH = BRCHS<1,BRLN>
                         GL.GET.AMT LINE<1,5>,SL.ID,SBRCH,EDATE,A,SDATE,REP.ARRAY<1,27>,REC.REC<29>,EDATE:VM:TST
                         TMP.ARRAY = RAISE(SL.TOTALS<2,BRLN,COLUMN>)
                         TMP.ARRAY<1,1,PTR+1> += A
                         SL.TOTALS<2,BRLN,COLUMN> = LOWER(TMP.ARRAY)
                      NEXT BRLN
                   END ELSE
                      SL.TOTALS<2,COLUMN,PTR+1> += A
                   END
                END
             END
          END

          RETURN
*-------------------------------------------------------------------------*
MAKE.REG.AMT: * This routine normalizes the data by looking at the
              * Parameters such as Liability or Credit to determine what
              * sign to assign to the amt.
          CALC = (TOKEN='-' OR TOKEN='+' OR TOKEN='*' OR TOKEN='/')
          IF NUMERIC AND TOKEN#'IN' AND TOKEN#'K' AND TOKEN#'T' AND TOKEN[1,2] # 'SG' AND NOT(CALC) THEN

             IF NUM(AMT) AND NOT(IS.PCTG) THEN

                * Check for Line Option to Reverse Amount
                IF LINE<1,11> THEN AMT = -AMT

                * Handle Template Sign from Subroutine argument
                IF TOKEN # 'AC' THEN
                   * Never allow the sign to change on account number
                   AMT = SIGN * AMT
                END

                * If not showing Credit or Debit but Actual
                * need to adjust the sign according to the Line settings
                * of the account.
                IF NOT(CREDIT.ONLY) AND NOT(DEBIT.ONLY) THEN
                   READ USE.ACCT.TYPE FROM CTRLFILE,'GL.TB.ACCOUNT' ELSE USE.ACCT.TYPE = NO
                   * Rec.Rec 1,1 is Credit Bal Acct or Template Actual
                   * Balances.  The type of report is indicated by the
                   * REP.ARRAY attribute.
                   BEGIN CASE
                   CASE USE.ACCT.TYPE AND (TOKEN # 'AC')
                      * If the control record is set then we want to
                      * see the actual amount with the sign based on
                      * the account type.
                      * Accounts that usually carry a credit balance
                      * will show up on as a negative actual amount on
                      * all reports EXCEPT the Listing of Accounts.
                      IF REP.ARRAY<1,1> > 1 AND NOT(REC.REC<1,1>) THEN
                         AMT = -AMT
                      END
                   CASE NOT(USE.ACCT.TYPE) AND (TOKEN # 'AC')
                      * If the control record is not set then we want to
                      * see the actual amount with the sign based on the
                      * account type only on the Operating Statement and
                      * Balance Sheet. Accounts that usually carry a
                      * credit balance will show up as negatives on the
                      * Operating Statement and Balance Sheet only. The
                      * trial balance will show a negative in the actual
                      * column only if the account carries a balance
                      * opposite of it's natural state.
                      IF REP.ARRAY<1,1>=3 AND NOT(REC.REC<1,1>) THEN
                         AMT = -AMT
                      END
                      IF REP.ARRAY<1,1>=2 AND NOT(REC.REC<1,1>) THEN
                         AMT = -AMT
                      END
                   END CASE
                END
             END

             BEGIN CASE
             CASE AMT='' AND TOKEN[1,1]#'K';     AMT=0
             CASE CREDIT.ONLY
                IF AMT < 0 THEN AMT = -AMT ELSE AMT = 0
             CASE DEBIT.ONLY
                IF AMT < 0 THEN AMT = 0
             END CASE

          END

*** Save Altered sign amount in LAST.COL which may be used later on for
*** calculations on the same line in the report.
          LAST.COL<BR.CTR,COLUMN> = AMT

          RETURN
*-------------------------------------------------------------------------*
ADD.TO.REG.BLK:*
*** This routine will add the amount to the appropriate Block Total Amt.
*** Credits will go in BLOCK.CR, Debits in BLOCK.DEB

             IF (DEBUG.ACTIVE) THEN
                LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
                   DEBUG.LINE  = 'ADD.TO.REG.BLOCK:-START'
                   DEBUG.LINE := ' CALL.LVL=['      :CALL.LVL        :']'
                   DEBUG.LINE := ' ORID.ID=['       :ORIG.ID         :']'
                   DEBUG.LINE := ' TOKEN=['         :TOKEN           :']'
                   DEBUG.LINE := ' BLOCK.LVL=['     :BLOCK.LVL       :']'
                   DEBUG.LINE := ' COLUMN=['        :COLUMN          :']'
                   DEBUG.LINE := ' PTR=['           :PTR             :']'
                   DEBUG.LINE := ' AMT=['           :AMT             :']'
                   DEBUG.LINE := ' BLOCK.CRD<BLOCK.LVL,COL>=[':BLOCK.CRD<BLOCK.LVL,COLUMN> :']'
                   DEBUG.LINE := ' BLOCK.DEB<BLOCK.LVL,COL>=[':BLOCK.DEB<BLOCK.LVL,COLUMN> :']'
                   DEBUG.LINE := ' BLOCK.TOT<BLOCK.LVL,COL>=[':BLOCK.TOT<BLOCK.LVL,COLUMN>      :']'
                   PRINT DEBUG.LINE
                END
             END

             IF NOT(NUM(AMT)) THEN RETURN

             BEGIN CASE
                ***If a Credit or Debit column then simply base it on the
                ***sign of the Amount.
                CASE TOKEN = 'C' OR TOKEN = 'D'
                   IF AMT < 0 THEN
                      BLOCK.CRD<BLOCK.LVL,COLUMN> += -AMT
                   END ELSE
                      BLOCK.DEB<BLOCK.LVL,COLUMN> += AMT
                   END
                CASE OTHERWISE
                   IF NOT(REC.REC<1,1>) THEN
                      CALC = (TOKEN='-' OR TOKEN='+' OR TOKEN='*' OR TOKEN='/')
                      IF NUMERIC AND TOKEN#'IN' AND TOKEN#'K' AND TOKEN[1,2] # 'SG' AND TOKEN#'T' AND NOT(CALC) THEN
                         BLOCK.CRD<BLOCK.LVL,COLUMN> += -AMT
                      END ELSE
*** If we're here it means this was a calculated field so just store in
*** debit column, unless it is a credit only column
                         BLOCK.DEB<BLOCK.LVL,COLUMN> += AMT
                      END
                   END ELSE
                      BLOCK.DEB<BLOCK.LVL,COLUMN> += AMT
                   END
             END CASE

*** Block total is always the real Debits minus the Real Credits. Real in
*** this case means unaltered sign.
             BLOCK.TOT<BLOCK.LVL,COLUMN> = BLOCK.DEB<BLOCK.LVL,COLUMN> - BLOCK.CRD<BLOCK.LVL,COLUMN>

             IF (DEBUG.ACTIVE) THEN
                LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
                   DEBUG.LINE  = 'ADD.TO.REG.BLOCK:-END  '
                   DEBUG.LINE := ' CALL.LVL=['      :CALL.LVL        :']'
                   DEBUG.LINE := ' ORID.ID=['       :ORIG.ID         :']'
                   DEBUG.LINE := ' TOKEN=['         :TOKEN           :']'
                   DEBUG.LINE := ' BLOCK.LVL=['     :BLOCK.LVL       :']'
                   DEBUG.LINE := ' COLUMN=['        :COLUMN          :']'
                   DEBUG.LINE := ' PTR=['           :PTR             :']'
                   DEBUG.LINE := ' AMT=['           :AMT             :']'
                   DEBUG.LINE := ' BLOCK.CRD<BLOCK.LVL,COL>=[':BLOCK.CRD<BLOCK.LVL,COLUMN> :']'
                   DEBUG.LINE := ' BLOCK.DEB<BLOCK.LVL,COL>=[':BLOCK.DEB<BLOCK.LVL,COLUMN> :']'
                   DEBUG.LINE := ' BLOCK.TOT<BLOCK.LVL,COL>=[':BLOCK.TOT<BLOCK.LVL,COLUMN>      :']'
                   PRINT DEBUG.LINE
                END
             END


          RETURN
*-------------------------------------------------------------------------*
MAKE.TOT.AMT: * This routine actually prints the total column, after all of
              * the data is collected.

              * The use of USE.MULT in this routine means that if any total
              * is derived from any calculation then use the arrived at
              * amount since Calculated columns can give wacky totals
              * because of reversed signs.

             IF (DEBUG.ACTIVE) THEN
                LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
                   DEBUG.LINE  = 'MAKE.TOT.AMT:-START'
                   DEBUG.LINE := ' CALL.LVL=['      :CALL.LVL        :']'
                   DEBUG.LINE := ' ORID.ID=['       :ORIG.ID         :']'
                   DEBUG.LINE := ' BLOCK.LVL=['     :BLOCK.LVL       :']'
                   DEBUG.LINE := ' COLUMN=['        :COLUMN          :']'
                   DEBUG.LINE := ' PTR=['           :PTR             :']'
                   DEBUG.LINE := ' AMT=['           :AMT             :']'
                   DEBUG.LINE := ' BLOCK.CRD<BLOCK.LVL,COL>=[':BLOCK.CRD<BLOCK.LVL,COLUMN> :']'
                   DEBUG.LINE := ' BLOCK.DEB<BLOCK.LVL,COL>=[':BLOCK.DEB<BLOCK.LVL,COLUMN> :']'
                   DEBUG.LINE := ' BLOCK.TOT<BLOCK.LVL,COL>=[':BLOCK.TOT<BLOCK.LVL,COLUMN>      :']'
                   PRINT DEBUG.LINE
                END
             END

          IF NUMERIC THEN
             IF NUM(AMT) THEN

                IF LINE<1,1> # 'Total' THEN
                   *** If Consolidated Total then get amts from tot.amts
                   IF LINE<1,1> = 'CTotal' THEN
                      *** Print a couple of line seperator
                      PRINT
                      PRINT
                      AMT = BLOCK.TOT<BLOCK.LVL,COLUMN> + ACCT.AMTS<1,COLUMN>
                      DEB = BLOCK.DEB<BLOCK.LVL,COLUMN> + ACCT.AMTS<2,COLUMN>
                      CRD = BLOCK.CRD<BLOCK.LVL,COLUMN> + ACCT.AMTS<3,COLUMN>
                   END ELSE
                      IF USE.MULT THEN
                         IF AMT<0 THEN CRD=-AMT; DEB=0 ELSE CRD=0; DEB=AMT
                      END ELSE
                         AMT = BLOCK.TOT<BLOCK.LVL+1,COLUMN>
                         DEB = BLOCK.DEB<BLOCK.LVL+1,COLUMN>
                         CRD = BLOCK.CRD<BLOCK.LVL+1,COLUMN>
                      END

                      BLOCK.TOT<BLOCK.LVL,COLUMN> += AMT
                      BLOCK.DEB<BLOCK.LVL,COLUMN> += DEB
                      BLOCK.CRD<BLOCK.LVL,COLUMN> += CRD

                      BLOCK.TOT<BLOCK.LVL + 1, COLUMN> = 0
                      BLOCK.CRD<BLOCK.LVL + 1, COLUMN> = 0
                      BLOCK.DEB<BLOCK.LVL + 1, COLUMN> = 0
                   END
                END ELSE
                   IF USE.MULT THEN
                      IF AMT<0 THEN CRD=-AMT; DEB=0 ELSE CRD=0; DEB=AMT
                   END ELSE
                      AMT = BLOCK.TOT<BLOCK.LVL,COLUMN>
                      DEB = BLOCK.DEB<BLOCK.LVL,COLUMN>
                      CRD = BLOCK.CRD<BLOCK.LVL,COLUMN>
                   END
                END

                STAC = RAISE(REP.ARRAY<1,18,COLUMN>)
                TOK = STAC<1,1>

*** We are not going to swap signs if it is a calculated field.
                NOT.CALC = (TOK = 'A' OR TOK = 'C' OR TOK = 'D' OR TOK = 'BD' OR TOK = 'BB')


                IF NOT(IS.PCTG) AND NOT.CALC THEN
                   IF LINE<1,11> THEN
                      AMT = -AMT
                      SWAP DEB,CRD
                   END
                   AMT = SIGN * AMT
                   IF SIGN < 0 THEN
                      SWAP DEB,CRD
                   END
                END
             END

             BEGIN CASE
             CASE AMT='' AND TOKEN[1,1]#'K' AND TOKEN[1,2] # 'SG'; AMT = 0
             CASE CREDIT.ONLY;                   AMT = CRD
             CASE DEBIT.ONLY;                    AMT = DEB
             END CASE

             LAST.COL<BR.CTR,COLUMN> = AMT
          END

          IF (DEBUG.ACTIVE) THEN
             LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
                DEBUG.LINE  = 'MAKE.TOT.AMT:-END   '
                DEBUG.LINE := ' CALL.LVL=['      :CALL.LVL        :']'
                DEBUG.LINE := ' ORID.ID=['       :ORIG.ID         :']'
                DEBUG.LINE := ' BLOCK.LVL=['     :BLOCK.LVL       :']'
                DEBUG.LINE := ' COLUMN=['        :COLUMN          :']'
                DEBUG.LINE := ' PTR=['           :PTR             :']'
                DEBUG.LINE := ' AMT=['           :AMT             :']'
                DEBUG.LINE := ' BLOCK.CRD<BLOCK.LVL,COL>=[':BLOCK.CRD<BLOCK.LVL,COLUMN> :']'
                DEBUG.LINE := ' BLOCK.DEB<BLOCK.LVL,COL>=[':BLOCK.DEB<BLOCK.LVL,COLUMN> :']'
                DEBUG.LINE := ' BLOCK.TOT<BLOCK.LVL,COL>=[':BLOCK.TOT<BLOCK.LVL,COLUMN>      :']'
                PRINT DEBUG.LINE
             END
          END

          RETURN
*-------------------------------------------------------------------------*
MAKE.TOT.AMT.NO.UPD: *

             IF (DEBUG.ACTIVE) THEN
                LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
                   DEBUG.LINE  = 'MAKE.TOT.AMT.NO.UPD:-START'
                   DEBUG.LINE := ' CALL.LVL=['      :CALL.LVL        :']'
                   DEBUG.LINE := ' ORID.ID=['       :ORIG.ID         :']'
                   DEBUG.LINE := ' BLOCK.LVL=['     :BLOCK.LVL       :']'
                   DEBUG.LINE := ' COLUMN=['        :COLUMN          :']'
                   DEBUG.LINE := ' PTR=['           :PTR             :']'
                   DEBUG.LINE := ' AMT=['           :AMT             :']'
                   DEBUG.LINE := ' BLOCK.CRD<BLOCK.LVL,COL>=[':BLOCK.CRD<BLOCK.LVL,COLUMN> :']'
                   DEBUG.LINE := ' BLOCK.DEB<BLOCK.LVL,COL>=[':BLOCK.DEB<BLOCK.LVL,COLUMN> :']'
                   DEBUG.LINE := ' BLOCK.TOT<BLOCK.LVL,COL>=[':BLOCK.TOT<BLOCK.LVL,COLUMN>      :']'
                   PRINT DEBUG.LINE
                END
             END

          * The use of USE.MULT in this routine means that if any total
          * is derived from any calculation then use the arrived at
          * amount since Calculated columns can give wacky totals
          * because of reversed signs.

          IF NUMERIC THEN
             IF NUM(AMT) THEN
                IF LINE<1,1> # 'Total' THEN
                   *** If Consolidated Total then get amts from tot.amts
                   IF LINE<1,1> = 'CTotal' THEN
                      AMT = BLOCK.TOT<BLOCK.LVL,COLUMN> + ACCT.AMTS<1,COLUMN>
                      DEB = BLOCK.DEB<BLOCK.LVL,COLUMN> + ACCT.AMTS<2,COLUMN>
                      CRD = BLOCK.CRD<BLOCK.LVL,COLUMN> + ACCT.AMTS<3,COLUMN>
                   END ELSE
                      IF USE.MULT THEN
                         IF AMT<0 THEN CRD=-AMT; DEB=0 ELSE CRD=0; DEB=AMT
                      END ELSE
                         AMT = BLOCK.TOT<BLOCK.LVL+1,COLUMN>
                         DEB = BLOCK.DEB<BLOCK.LVL+1,COLUMN>
                         CRD = BLOCK.CRD<BLOCK.LVL+1,COLUMN>
                      END
                   END
                END ELSE
                   IF USE.MULT THEN
                      IF AMT<0 THEN CRD=-AMT; DEB=0 ELSE CRD=0; DEB=AMT
                   END ELSE
                      AMT = BLOCK.TOT<BLOCK.LVL,COLUMN>
                      DEB = BLOCK.DEB<BLOCK.LVL,COLUMN>
                      CRD = BLOCK.CRD<BLOCK.LVL,COLUMN>
                   END
                END

*** We are not going to swap signs if it is a calculated field.
                NOT.CALC = (TOK = 'A' OR TOK = 'C' OR TOK = 'D' OR TOK = 'BD' OR TOK = 'BB')

                IF NOT(IS.PCTG) AND NOT.CALC THEN
                   IF LINE<1,11> THEN
                      AMT = -AMT
                      SWAP DEB,CRD
                   END
                   AMT = SIGN * AMT
                   IF SIGN < 0 THEN
                      SWAP DEB,CRD
                   END
                END
             END



             BEGIN CASE
             CASE AMT='' AND TOKEN[1,1]#'K' AND TOKEN[1,2] # 'SG'; AMT = 0
             CASE CREDIT.ONLY;                   AMT = CRD
             CASE DEBIT.ONLY;                    AMT = DEB
             END CASE

             LAST.COL<BR.CTR,COLUMN> = AMT
          END




          IF (DEBUG.ACTIVE) THEN
             LOCATE USER.ID IN DEBUG.IDS<1> SETTING DEBUG.POS THEN
                DEBUG.LINE  = 'MAKE.TOT.AMT.NO.UPD:-END  '
                DEBUG.LINE := ' CALL.LVL=['      :CALL.LVL        :']'
                DEBUG.LINE := ' ORID.ID=['       :ORIG.ID         :']'
                DEBUG.LINE := ' BLOCK.LVL=['     :BLOCK.LVL       :']'
                DEBUG.LINE := ' COLUMN=['        :COLUMN          :']'
                DEBUG.LINE := ' PTR=['           :PTR             :']'
                DEBUG.LINE := ' AMT=['           :AMT             :']'
                DEBUG.LINE := ' BLOCK.CRD<BLOCK.LVL,COL>=[':BLOCK.CRD<BLOCK.LVL,COLUMN> :']'
                DEBUG.LINE := ' BLOCK.DEB<BLOCK.LVL,COL>=[':BLOCK.DEB<BLOCK.LVL,COLUMN> :']'
                DEBUG.LINE := ' BLOCK.TOT<BLOCK.LVL,COL>=[':BLOCK.TOT<BLOCK.LVL,COLUMN>      :']'
                PRINT DEBUG.LINE
             END
          END

          RETURN
*-------------------------------------------------------------------------*
GET.COST.CTRS: *** Get Cost Centers and compare to report branches

          *** Get Global Cost Centers if any exist.
          *** Since Global Cost Centers build on themselves we can just
          *** get the last one.
          NEW.COST.CTRS = GLBL.COST.CTRS<BLOCK.LVL>

          *** If no Cost Centers specified then go back to Report Branches
          IF LINE<1,9> = '' THEN
             COST.CTRS = NEW.COST.CTRS
             IF COST.CTRS = '' THEN
                BRCHS = REP.BRCHS
                RETURN
             END
          END

          *** Add this lines Cost Centers to the Global Cost Centers
          LN.COST.CTRS = RAISE(LINE<1,9>)
          LN.CTRS.CT = DCOUNT(LN.COST.CTRS,VM)
          FOR LN.CT = 1 TO LN.CTRS.CT
             LOCATE LN.COST.CTRS<1,LN.CT> IN NEW.COST.CTRS<1> SETTING XPOS ELSE
                NEW.COST.CTRS<1,-1> = LN.COST.CTRS<1,LN.CT>
             END
          NEXT LN.CT

          *** If cost Center didn't change then just return
          IF NEW.COST.CTRS = COST.CTRS THEN RETURN
          COST.CTRS = NEW.COST.CTRS

          BRCHS = ''
          *** Now find the branches associated with those cost centers from
          *** the branches that were specified on the report.
          FOR BRX = 1 to REP.BR.CT
             BR.ID = REP.BRCHS<1,BRX>
             READV TER.CTR FROM TERRFILE,BR.ID,34 ELSE TER.CTR = ''
             IF TER.CTR THEN
                LOCATE TER.CTR IN COST.CTRS<1> SETTING XPOS THEN
                   BRCHS<1,-1> = BR.ID
                END
             END
          NEXT BRX

          *** Reset Branch Count.
          BR.CT = DCOUNT(BRCHS,VM)

          RETURN
*-------------------------------------------------------------------------*
!TSMITH~06/13/14~21:52
