Chapter 36 Exercises: Accounting and General Ledger Systems

Tier 1: Recall and Recognition (Exercises 1-8)

Exercise 1: Double-Entry Bookkeeping Rules

Complete the following table showing how debits and credits affect each account type:

Account Type Normal Balance Increased By Decreased By
Assets ____ ____ ____
Liabilities ____ ____ ____
Equity ____ ____ ____
Revenue ____ ____ ____
Expenses ____ ____ ____

Solution:

Account Type Normal Balance Increased By Decreased By
Assets Debit Debit Credit
Liabilities Credit Credit Debit
Equity Credit Credit Debit
Revenue Credit Credit Debit
Expenses Debit Debit Credit

Exercise 2: Account Number Structure

Given the following account number structure, decode account number 0200-5100-4200-00:

XXXX-XXXX-XXXX-XX
|    |    |    |
|    |    |    +-- Sub-account
|    |    +------- Cost Center / Department
|    +----------- Natural Account
+---------------- Company Code

Use these reference tables: - Company 0200 = European Operations - Natural Account 5100 = Salary Expenses - Cost Center 4200 = Human Resources - Sub-account 00 = Default

What type of account is this? On which financial statement would it appear?

Solution: This is the Salary Expenses account for the Human Resources department in the European Operations company. It is an expense account. It would appear on the Income Statement (Statement of Operations / Profit and Loss). Its normal balance is debit. A debit to this account increases salary expense; a credit decreases it.

Exercise 3: Chart of Accounts Classification

Classify each of the following accounts by type (Asset, Liability, Equity, Revenue, Expense) and indicate the typical account number range:

a) Cash b) Accounts Payable c) Retained Earnings d) Product Sales Revenue e) Depreciation Expense f) Accounts Receivable g) Long-term Debt h) Common Stock i) Cost of Goods Sold j) Accumulated Depreciation

Solution: a) Cash -- Asset (1000-1999) b) Accounts Payable -- Liability (2000-2999) c) Retained Earnings -- Equity (3000-3999) d) Product Sales Revenue -- Revenue (4000-4999) e) Depreciation Expense -- Expense (5000-9999) f) Accounts Receivable -- Asset (1000-1999) g) Long-term Debt -- Liability (2000-2999) h) Common Stock -- Equity (3000-3999) i) Cost of Goods Sold -- Expense (5000-9999) j) Accumulated Depreciation -- Asset (contra-asset, 1000-1999)

Exercise 4: GL Master Record Structure

Given the GL master record layout from the chapter, answer the following:

       05  GL-PERIOD-DATA OCCURS 13 TIMES.
           10  GL-PRD-DEBITS      PIC S9(13)V99.
           10  GL-PRD-CREDITS     PIC S9(13)V99.
           10  GL-PRD-NET         PIC S9(13)V99.
           10  GL-PRD-END-BAL     PIC S9(13)V99.
           10  GL-PRD-BUDGET      PIC S9(13)V99.

a) Why does the table have 13 periods instead of 12? b) What is period 13 used for? c) How would you access the debit total for period 6 (June)? d) If each PIC S9(13)V99 field uses COMP-3 (8 bytes), what is the total size of the period table?

Solution: a) The 13th period provides an adjustment period for year-end audit adjustments that should not affect any specific month's reporting. b) Period 13 is used for audit adjustments, corrections, and reclassifications that auditors make at year-end. These adjustments are kept separate from the regular monthly periods so that monthly financial statements already distributed to management are not disturbed. c) GL-PRD-DEBITS(6) -- using the OCCURS subscript to access the sixth element of the period table. d) 13 periods x 5 fields x 8 bytes = 520 bytes for the period table.

Exercise 5: Journal Entry Types

Match each journal entry type with its description:

Type Code Type Description
a) S ____ 1) Template that generates the same entry each period
b) R ____ 2) One-time entry for standard business transactions
c) A ____ 3) Entry that automatically reverses on the first day of the next period
d) T ____ 4) Non-financial entry used for tracking units or quantities

Solution: a) S -- Standard (description 2): One-time entry for standard business transactions. b) R -- Recurring (description 1): Template that generates the same entry each period. c) A -- Auto-Reverse (description 3): Entry that automatically reverses on the first day of the next period. Used for accruals. d) T -- Statistical (description 4): Non-financial entry used for tracking units, headcount, square footage, etc.

Exercise 6: Trial Balance Fundamentals

A company has the following account balances at month-end. Determine whether the trial balance is in balance.

Account Debit Credit
Cash $125,000
Accounts Receivable $85,000
Equipment $200,000
Accumulated Depreciation $45,000
Accounts Payable $62,000
Notes Payable $100,000
Common Stock $50,000
Retained Earnings $78,000
Revenue $320,000
Salaries Expense $180,000
Rent Expense $36,000
Utilities Expense $12,000
Depreciation Expense $17,000

Solution: Total Debits: $125,000 + $85,000 + $200,000 + $180,000 + $36,000 + $12,000 + $17,000 = **$655,000**

Total Credits: $45,000 + $62,000 + $100,000 + $50,000 + $78,000 + $320,000 = $655,000

The trial balance is in balance. Total debits ($655,000) equal total credits ($655,000).

Exercise 7: Period Status Codes

Explain the significance of each period status code in a GL system:

       10  GL-PRD-STATUS      PIC X(01).
           88  GL-PRD-OPEN    VALUE 'O'.
           88  GL-PRD-CLOSED  VALUE 'C'.
           88  GL-PRD-LOCKED  VALUE 'L'.

What would happen if a journal entry attempted to post to a closed period? How does a locked period differ from a closed period?

Solution: - Open ('O'): The period accepts journal entry postings. Normal day-to-day entries are posted to the current open period. - Closed ('C'): The period has been formally closed during month-end processing. No new entries can be posted. Financial statements for this period are final. - Locked ('L'): The period is temporarily locked to prevent posting during the month-end close process (while accruals, recurring entries, and adjustments are being generated), but it has not yet been formally closed. Once the close process completes, the status changes to Closed.

If a journal entry attempts to post to a closed period, the posting program rejects the entry with an error indicating the period is not open. This is a critical control: once financial statements are issued for a closed period, no further changes should be made.

A locked period differs from a closed period in that a locked period can be unlocked and reopened if needed (for example, if the close process encounters an error and must be restarted), whereas closing is typically a one-way operation.

Exercise 8: Subledger-to-GL Relationship

A company's Accounts Receivable subledger shows the following customer balances:

Customer Balance
Customer A $15,200.00
Customer B $8,750.00
Customer C $22,400.00
Customer D $3,650.00

What should the balance of the GL Accounts Receivable control account be? If the GL shows $49,500.00 instead, what does this indicate?

Solution: The subledger total is: $15,200 + $8,750 + $22,400 + $3,650 = $50,000.00

The GL Accounts Receivable control account should show $50,000.00 -- the exact total of the subledger detail.

If the GL shows $49,500.00 instead, the $500.00 difference indicates a reconciliation discrepancy. Possible causes include: - A subledger entry was posted but the corresponding GL entry was not. - A GL journal entry was posted that did not flow through the subledger. - A timing difference: one of the systems was updated and the other has not yet processed. - A posting error in either the subledger or the GL. This discrepancy must be investigated and resolved before the period can be closed.


Tier 2: Comprehension and Application (Exercises 9-16)

Exercise 9: Journal Entry Validation

Write a COBOL paragraph named VALIDATE-JOURNAL-ENTRY that performs the following validations on a journal entry:

  1. Total debits must equal total credits (balance check).
  2. Each line's account must exist in the chart of accounts and must be active and postable.
  3. The posting period must be open.
  4. No line may have a zero amount.
  5. If the entry total exceeds $100,000, it must have an approver (JE-APPROVED-BY must not be spaces).

Track the number of errors found and set WS-ENTRY-VALID accordingly.

Solution:

       01  WS-VALIDATION-WORK.
           05  WS-ERROR-COUNT      PIC 9(03) VALUE ZEROS.
           05  WS-ENTRY-STATUS     PIC X(01) VALUE 'Y'.
               88  WS-ENTRY-VALID  VALUE 'Y'.
               88  WS-ENTRY-INVALID VALUE 'N'.
           05  WS-IDX              PIC 9(04).

       VALIDATE-JOURNAL-ENTRY.
           MOVE ZEROS TO WS-ERROR-COUNT
           SET WS-ENTRY-VALID TO TRUE

      *    CHECK 1: ENTRY MUST BALANCE
           IF JE-TOTAL-DEBITS NOT = JE-TOTAL-CREDITS
               ADD 1 TO WS-ERROR-COUNT
               DISPLAY 'ERROR: ENTRY ' JE-ENTRY-NUMBER
                       ' OUT OF BALANCE'
               SET WS-ENTRY-INVALID TO TRUE
           END-IF

      *    CHECK 2: VALIDATE EACH LINE ACCOUNT
           PERFORM VARYING WS-IDX FROM 1 BY 1
               UNTIL WS-IDX > JE-LINE-COUNT

               IF JE-LN-AMOUNT(WS-IDX) = ZEROS
                   ADD 1 TO WS-ERROR-COUNT
                   DISPLAY 'ERROR: LINE ' WS-IDX
                           ' HAS ZERO AMOUNT'
                   SET WS-ENTRY-INVALID TO TRUE
               END-IF

               MOVE JE-LN-ACCOUNT(WS-IDX)
                   TO COA-ACCOUNT-KEY
               READ CHART-OF-ACCOUNTS-FILE
                   KEY IS COA-ACCOUNT-KEY
                   INVALID KEY
                       ADD 1 TO WS-ERROR-COUNT
                       DISPLAY 'ERROR: LINE ' WS-IDX
                               ' INVALID ACCOUNT '
                               JE-LN-ACCOUNT(WS-IDX)
                       SET WS-ENTRY-INVALID TO TRUE
               END-READ

               IF WS-ENTRY-VALID OR WS-ERROR-COUNT < 10
                   IF NOT COA-ACTIVE
                       ADD 1 TO WS-ERROR-COUNT
                       DISPLAY 'ERROR: LINE ' WS-IDX
                               ' ACCOUNT INACTIVE'
                       SET WS-ENTRY-INVALID TO TRUE
                   END-IF
                   IF COA-SUMMARY-ONLY
                       ADD 1 TO WS-ERROR-COUNT
                       DISPLAY 'ERROR: LINE ' WS-IDX
                               ' ACCOUNT NOT POSTABLE'
                       SET WS-ENTRY-INVALID TO TRUE
                   END-IF
               END-IF
           END-PERFORM

      *    CHECK 3: VALIDATE POSTING PERIOD
           PERFORM CHECK-PERIOD-STATUS
           IF NOT WS-PERIOD-OPEN
               ADD 1 TO WS-ERROR-COUNT
               DISPLAY 'ERROR: PERIOD ' JE-PERIOD
                       ' IS NOT OPEN'
               SET WS-ENTRY-INVALID TO TRUE
           END-IF

      *    CHECK 4: APPROVAL FOR LARGE ENTRIES
           IF JE-TOTAL-DEBITS > 100000.00
               IF JE-APPROVED-BY = SPACES
                   ADD 1 TO WS-ERROR-COUNT
                   DISPLAY 'ERROR: ENTRY OVER $100K '
                           'REQUIRES APPROVAL'
                   SET WS-ENTRY-INVALID TO TRUE
               END-IF
           END-IF
           .

Exercise 10: GL Posting Logic

Write a COBOL paragraph named POST-JOURNAL-ENTRY that posts a validated journal entry to the GL master file. For each line of the journal entry:

  1. Read the GL master record using the account key and period.
  2. If the record does not exist, initialize a new GL record.
  3. Add the amount to either the period debits or period credits based on the debit/credit indicator.
  4. Recalculate the period net amount.
  5. Recalculate the year-to-date totals.
  6. REWRITE (or WRITE for new records) the GL master record.
  7. Update the journal entry status to 'D' (posted) and record the posting date.

Solution:

       POST-JOURNAL-ENTRY.
           PERFORM VARYING WS-IDX FROM 1 BY 1
               UNTIL WS-IDX > JE-LINE-COUNT

               MOVE JE-LN-ACCOUNT(WS-IDX) TO GL-ACCOUNT-NUM
               MOVE JE-FISCAL-YEAR         TO GL-FISCAL-YEAR
               MOVE JE-COMPANY             TO GL-COMPANY

               READ GL-MASTER-FILE
                   KEY IS GL-FULL-KEY
                   INVALID KEY
                       PERFORM INITIALIZE-NEW-GL-RECORD
               END-READ

               IF JE-LN-DEBIT(WS-IDX)
                   ADD JE-LN-AMOUNT(WS-IDX)
                       TO GL-PRD-DEBITS(JE-PERIOD)
                   ADD JE-LN-AMOUNT(WS-IDX)
                       TO GL-YTD-DEBITS
               ELSE
                   ADD JE-LN-AMOUNT(WS-IDX)
                       TO GL-PRD-CREDITS(JE-PERIOD)
                   ADD JE-LN-AMOUNT(WS-IDX)
                       TO GL-YTD-CREDITS
               END-IF

               COMPUTE GL-PRD-NET(JE-PERIOD) =
                   GL-PRD-DEBITS(JE-PERIOD) -
                   GL-PRD-CREDITS(JE-PERIOD)

               COMPUTE GL-YTD-NET =
                   GL-YTD-DEBITS - GL-YTD-CREDITS

               COMPUTE GL-ENDING-BALANCE =
                   GL-BEGINNING-BALANCE + GL-YTD-NET

               MOVE WS-CURRENT-DATE
                   TO GL-LAST-ACTIVITY-DATE
               MOVE JE-PERIOD TO GL-LAST-ACTIVITY-PRD

               REWRITE GL-MASTER-RECORD
                   INVALID KEY
                       WRITE GL-MASTER-RECORD
                       INVALID KEY
                           DISPLAY 'GL WRITE ERROR: '
                                   GL-FULL-KEY
                       END-WRITE
               END-REWRITE

               ADD 1 TO WS-LINES-POSTED
           END-PERFORM

           MOVE 'D' TO JE-STATUS
           MOVE WS-CURRENT-DATE TO JE-POSTED-DATE
           MOVE WS-USER-ID TO JE-POSTED-BY
           .

Exercise 11: Trial Balance Generation

Write a COBOL paragraph that reads the GL master file sequentially and generates a trial balance report. The report should:

  1. List each account with its description, debit balance, and credit balance.
  2. Accounts with normal debit balances (Assets, Expenses) show their ending balance in the debit column.
  3. Accounts with normal credit balances (Liabilities, Equity, Revenue) show their ending balance in the credit column.
  4. Accumulate total debits and total credits.
  5. Print a total line and indicate whether the trial balance is in balance.

Solution:

       01  WS-TB-TOTALS.
           05  WS-TB-TOTAL-DEBITS  PIC S9(15)V99
                                   COMP-3 VALUE ZEROS.
           05  WS-TB-TOTAL-CREDITS PIC S9(15)V99
                                   COMP-3 VALUE ZEROS.
           05  WS-TB-ACCT-BAL      PIC S9(13)V99
                                   COMP-3.

       01  WS-TB-DETAIL-LINE.
           05  FILLER              PIC X(02) VALUE SPACES.
           05  WS-TBD-ACCOUNT     PIC X(14).
           05  FILLER              PIC X(02) VALUE SPACES.
           05  WS-TBD-DESC        PIC X(40).
           05  FILLER              PIC X(02) VALUE SPACES.
           05  WS-TBD-DEBIT       PIC $$$,$$$,$$$,$$9.99.
           05  FILLER              PIC X(02) VALUE SPACES.
           05  WS-TBD-CREDIT      PIC $$$,$$$,$$$,$$9.99.

       GENERATE-TRIAL-BALANCE.
           OPEN INPUT GL-MASTER-FILE
           MOVE ZEROS TO WS-TB-TOTAL-DEBITS
                         WS-TB-TOTAL-CREDITS
           PERFORM PRINT-TB-HEADERS

           PERFORM UNTIL WS-EOF-GL
               READ GL-MASTER-FILE
                   AT END SET WS-EOF-GL TO TRUE
               END-READ
               IF NOT WS-EOF-GL
                   MOVE GL-ENDING-BALANCE TO WS-TB-ACCT-BAL
                   MOVE GL-ACCOUNT-NUM TO WS-TBD-ACCOUNT
                   MOVE GL-ACCOUNT-DESC TO WS-TBD-DESC

                   IF GL-NORMAL-BALANCE = 'D'
                       MOVE WS-TB-ACCT-BAL TO WS-TBD-DEBIT
                       MOVE SPACES TO WS-TBD-CREDIT
                       ADD WS-TB-ACCT-BAL
                           TO WS-TB-TOTAL-DEBITS
                   ELSE
                       COMPUTE WS-TB-ACCT-BAL =
                           WS-TB-ACCT-BAL * -1
                       MOVE SPACES TO WS-TBD-DEBIT
                       MOVE WS-TB-ACCT-BAL TO WS-TBD-CREDIT
                       ADD WS-TB-ACCT-BAL
                           TO WS-TB-TOTAL-CREDITS
                   END-IF

                   WRITE REPORT-RECORD FROM WS-TB-DETAIL-LINE
                       AFTER ADVANCING 1 LINE
               END-IF
           END-PERFORM

           MOVE WS-TB-TOTAL-DEBITS TO WS-TBD-DEBIT
           MOVE WS-TB-TOTAL-CREDITS TO WS-TBD-CREDIT
           MOVE 'TOTALS' TO WS-TBD-DESC
           MOVE ALL '=' TO WS-TBD-ACCOUNT
           WRITE REPORT-RECORD FROM WS-TB-DETAIL-LINE
               AFTER ADVANCING 2 LINES

           IF WS-TB-TOTAL-DEBITS = WS-TB-TOTAL-CREDITS
               MOVE 'TRIAL BALANCE IS IN BALANCE'
                   TO REPORT-RECORD
           ELSE
               MOVE 'WARNING: TRIAL BALANCE OUT OF BALANCE'
                   TO REPORT-RECORD
           END-IF
           WRITE REPORT-RECORD AFTER ADVANCING 2 LINES

           CLOSE GL-MASTER-FILE
           .

Exercise 12: Budget Variance Calculation

Write a COBOL paragraph that calculates budget variance for a single GL account and period. The paragraph should:

  1. Compute the dollar variance (budget minus actual).
  2. Compute the percentage variance.
  3. Classify the variance as favorable or unfavorable based on the account type (for expenses, under-budget is favorable; for revenue, over-budget is favorable).
  4. Flag variances exceeding 10% for management review.

Solution:

       01  WS-VARIANCE-WORK.
           05  WS-VAR-DOLLARS      PIC S9(13)V99
                                   COMP-3.
           05  WS-VAR-PERCENT      PIC S9(05)V99
                                   COMP-3.
           05  WS-VAR-TYPE         PIC X(12).
           05  WS-VAR-FLAG         PIC X(01).
               88  WS-VAR-FLAGGED  VALUE 'Y'.

       CALCULATE-BUDGET-VARIANCE.
           COMPUTE WS-VAR-DOLLARS =
               GL-PRD-BUDGET(WS-PERIOD) -
               GL-PRD-NET(WS-PERIOD)

           IF GL-PRD-BUDGET(WS-PERIOD) NOT = ZEROS
               COMPUTE WS-VAR-PERCENT =
                   (WS-VAR-DOLLARS /
                    GL-PRD-BUDGET(WS-PERIOD)) * 100
           ELSE
               MOVE ZEROS TO WS-VAR-PERCENT
           END-IF

           EVALUATE GL-ACCOUNT-TYPE
               WHEN 'X'
                   IF WS-VAR-DOLLARS >= ZEROS
                       MOVE 'FAVORABLE   ' TO WS-VAR-TYPE
                   ELSE
                       MOVE 'UNFAVORABLE ' TO WS-VAR-TYPE
                   END-IF
               WHEN 'R'
                   IF WS-VAR-DOLLARS <= ZEROS
                       MOVE 'FAVORABLE   ' TO WS-VAR-TYPE
                   ELSE
                       MOVE 'UNFAVORABLE ' TO WS-VAR-TYPE
                   END-IF
               WHEN OTHER
                   MOVE 'N/A         ' TO WS-VAR-TYPE
           END-EVALUATE

           IF WS-VAR-PERCENT > 10.00
              OR WS-VAR-PERCENT < -10.00
               SET WS-VAR-FLAGGED TO TRUE
           ELSE
               MOVE 'N' TO WS-VAR-FLAG
           END-IF
           .

Exercise 13: Auto-Reversing Entry Generation

Write a COBOL paragraph that processes auto-reversing entries. Given a posted journal entry from the prior period that is marked as auto-reversing, generate a new journal entry for the current period that swaps all debits and credits.

The paragraph should: 1. Create a new entry number. 2. Set the period to the current period. 3. For each line, swap the debit/credit indicator ('D' becomes 'C', 'C' becomes 'D'). 4. Keep the same accounts and amounts. 5. Append "AUTO-REVERSAL OF " to the description. 6. Mark the new entry as type 'S' (standard) with status 'P' (pending).

Solution:

       CREATE-REVERSAL-ENTRY.
           ADD 1 TO WS-NEXT-ENTRY-NUMBER
           MOVE WS-NEXT-ENTRY-NUMBER TO REV-ENTRY-NUMBER
           MOVE WS-CURRENT-PERIOD    TO REV-PERIOD
           MOVE WS-CURRENT-YEAR      TO REV-FISCAL-YEAR
           MOVE WS-CURRENT-DATE      TO REV-ENTRY-DATE
           STRING 'AUTO-REVERSAL OF '
                  JH-ENTRY-NUMBER
               DELIMITED BY SIZE
               INTO REV-DESCRIPTION
           MOVE 'S' TO REV-ENTRY-TYPE
           MOVE 'P' TO REV-STATUS
           MOVE JH-LINE-COUNT TO REV-LINE-COUNT
           MOVE ZEROS TO REV-TOTAL-DEBITS
                         REV-TOTAL-CREDITS

           PERFORM VARYING WS-IDX FROM 1 BY 1
               UNTIL WS-IDX > JH-LINE-COUNT

               MOVE JH-LN-ACCOUNT(WS-IDX)
                   TO REV-LN-ACCOUNT(WS-IDX)
               MOVE JH-LN-AMOUNT(WS-IDX)
                   TO REV-LN-AMOUNT(WS-IDX)

               IF JH-LN-DC-IND(WS-IDX) = 'D'
                   MOVE 'C' TO REV-LN-DC-IND(WS-IDX)
                   ADD JH-LN-AMOUNT(WS-IDX)
                       TO REV-TOTAL-CREDITS
               ELSE
                   MOVE 'D' TO REV-LN-DC-IND(WS-IDX)
                   ADD JH-LN-AMOUNT(WS-IDX)
                       TO REV-TOTAL-DEBITS
               END-IF

               STRING 'REV: '
                      JH-LN-DESCRIPTION(WS-IDX)(1:25)
                   DELIMITED BY SIZE
                   INTO REV-LN-DESCRIPTION(WS-IDX)
           END-PERFORM

           WRITE REVERSAL-RECORD FROM REV-ENTRY
           ADD 1 TO WS-REVERSALS-GENERATED
           .

Exercise 14: Depreciation Journal Entry

Write a COBOL paragraph that generates a depreciation journal entry. Given a fixed asset master record with the following fields, calculate the monthly straight-line depreciation and create a two-line journal entry:

  • FA-ASSET-COST: Original cost of the asset
  • FA-SALVAGE-VALUE: Estimated salvage value
  • FA-USEFUL-LIFE-MONTHS: Useful life in months
  • FA-DEPR-EXPENSE-ACCT: GL account for depreciation expense
  • FA-ACCUM-DEPR-ACCT: GL account for accumulated depreciation

Line 1: Debit Depreciation Expense Line 2: Credit Accumulated Depreciation

Solution:

       01  WS-MONTHLY-DEPR     PIC S9(09)V99 COMP-3.

       CALCULATE-DEPRECIATION.
           IF FA-USEFUL-LIFE-MONTHS > ZEROS
               COMPUTE WS-MONTHLY-DEPR ROUNDED =
                   (FA-ASSET-COST - FA-SALVAGE-VALUE) /
                    FA-USEFUL-LIFE-MONTHS
                   ON SIZE ERROR
                       DISPLAY 'DEPRECIATION OVERFLOW FOR '
                               'ASSET: ' FA-ASSET-ID
                       MOVE ZEROS TO WS-MONTHLY-DEPR
               END-COMPUTE
           ELSE
               MOVE ZEROS TO WS-MONTHLY-DEPR
           END-IF

           IF WS-MONTHLY-DEPR > ZEROS
               MOVE FA-DEPR-EXPENSE-ACCT
                   TO JE-LN-ACCOUNT(1)
               MOVE 'D'             TO JE-LN-DC-IND(1)
               MOVE WS-MONTHLY-DEPR TO JE-LN-AMOUNT(1)
               MOVE 'MONTHLY DEPRECIATION'
                   TO JE-LN-DESCRIPTION(1)

               MOVE FA-ACCUM-DEPR-ACCT
                   TO JE-LN-ACCOUNT(2)
               MOVE 'C'             TO JE-LN-DC-IND(2)
               MOVE WS-MONTHLY-DEPR TO JE-LN-AMOUNT(2)
               MOVE 'MONTHLY DEPRECIATION'
                   TO JE-LN-DESCRIPTION(2)

               MOVE 2 TO JE-LINE-COUNT
               MOVE WS-MONTHLY-DEPR TO JE-TOTAL-DEBITS
               MOVE WS-MONTHLY-DEPR TO JE-TOTAL-CREDITS
               PERFORM WRITE-JOURNAL-ENTRY
           END-IF
           .

Exercise 15: SOX Compliance Check

Write a COBOL paragraph named CHECK-SOX-CONTROLS that enforces the following Sarbanes-Oxley internal controls on journal entries:

  1. Segregation of duties: The person who created the entry must not be the same person who approved it.
  2. Approval threshold: Entries with total debits exceeding $50,000 require approval.
  3. Entries exceeding $500,000 require two approvers (a second approval field must also be populated).
  4. No backdating: The entry date must not be more than 5 business days before the current date.

Log any violations to a SOX exception file.

Solution:

       01  WS-SOX-VIOLATIONS     PIC 9(02) VALUE ZEROS.
       01  WS-SOX-MSG            PIC X(80) VALUE SPACES.

       CHECK-SOX-CONTROLS.
           MOVE ZEROS TO WS-SOX-VIOLATIONS

      *    CHECK 1: SEGREGATION OF DUTIES
           IF JE-ENTERED-BY = JE-APPROVED-BY
              AND JE-APPROVED-BY NOT = SPACES
               ADD 1 TO WS-SOX-VIOLATIONS
               MOVE 'SEGREGATION VIOLATION: SAME USER '
                    'ENTERED AND APPROVED'
                   TO WS-SOX-MSG
               PERFORM WRITE-SOX-EXCEPTION
           END-IF

      *    CHECK 2: APPROVAL THRESHOLD $50K
           IF JE-TOTAL-DEBITS > 50000.00
               IF JE-APPROVED-BY = SPACES
                   ADD 1 TO WS-SOX-VIOLATIONS
                   MOVE 'ENTRY OVER $50K WITHOUT APPROVAL'
                       TO WS-SOX-MSG
                   PERFORM WRITE-SOX-EXCEPTION
               END-IF
           END-IF

      *    CHECK 3: DUAL APPROVAL THRESHOLD $500K
           IF JE-TOTAL-DEBITS > 500000.00
               IF JE-SECOND-APPROVER = SPACES
                   ADD 1 TO WS-SOX-VIOLATIONS
                   MOVE 'ENTRY OVER $500K REQUIRES '
                        'DUAL APPROVAL'
                       TO WS-SOX-MSG
                   PERFORM WRITE-SOX-EXCEPTION
               END-IF
           END-IF

      *    CHECK 4: NO BACKDATING BEYOND 5 DAYS
           COMPUTE WS-DATE-DIFF =
               FUNCTION INTEGER-OF-DATE(WS-CURRENT-DATE) -
               FUNCTION INTEGER-OF-DATE(JE-ENTRY-DATE)
           IF WS-DATE-DIFF > 7
               ADD 1 TO WS-SOX-VIOLATIONS
               MOVE 'ENTRY BACKDATED MORE THAN 5 '
                    'BUSINESS DAYS'
                   TO WS-SOX-MSG
               PERFORM WRITE-SOX-EXCEPTION
           END-IF

           IF WS-SOX-VIOLATIONS > 0
               SET WS-SOX-FAILED TO TRUE
           ELSE
               SET WS-SOX-PASSED TO TRUE
           END-IF
           .

Exercise 16: Subledger Reconciliation

Write a COBOL paragraph that reconciles the Accounts Payable subledger total against the GL Accounts Payable control account balance. The paragraph should:

  1. Read the AP subledger file sequentially and sum all open invoice balances.
  2. Read the GL AP control account record and extract the ending balance.
  3. Compare the two amounts.
  4. If they match, write a "RECONCILED" record.
  5. If they differ, write an "OUT OF BALANCE" exception record with the difference amount.

Solution:

       01  WS-RECON-WORK.
           05  WS-AP-SUB-TOTAL    PIC S9(13)V99
                                  COMP-3 VALUE ZEROS.
           05  WS-AP-GL-BALANCE   PIC S9(13)V99
                                  COMP-3 VALUE ZEROS.
           05  WS-RECON-DIFF      PIC S9(13)V99
                                  COMP-3.
           05  WS-AP-SUB-COUNT    PIC 9(06) VALUE ZEROS.

       RECONCILE-AP-SUBLEDGER.
           MOVE ZEROS TO WS-AP-SUB-TOTAL
                         WS-AP-SUB-COUNT

      *    SUM ALL OPEN AP INVOICES
           OPEN INPUT AP-SUBLEDGER-FILE
           PERFORM UNTIL WS-EOF-AP
               READ AP-SUBLEDGER-FILE
                   AT END SET WS-EOF-AP TO TRUE
               END-READ
               IF NOT WS-EOF-AP
                   IF AP-INVOICE-STATUS = 'O'
                       ADD AP-INVOICE-BALANCE
                           TO WS-AP-SUB-TOTAL
                       ADD 1 TO WS-AP-SUB-COUNT
                   END-IF
               END-IF
           END-PERFORM
           CLOSE AP-SUBLEDGER-FILE

      *    READ GL AP CONTROL ACCOUNT
           MOVE WS-AP-CONTROL-ACCT-KEY TO GL-FULL-KEY
           READ GL-MASTER-FILE
               KEY IS GL-FULL-KEY
               INVALID KEY
                   DISPLAY 'ERROR: AP CONTROL ACCOUNT '
                           'NOT FOUND IN GL'
                   GO TO RECONCILE-AP-EXIT
           END-READ
           MOVE GL-ENDING-BALANCE TO WS-AP-GL-BALANCE

      *    COMPARE AND REPORT
           COMPUTE WS-RECON-DIFF =
               WS-AP-SUB-TOTAL - WS-AP-GL-BALANCE

           IF WS-RECON-DIFF = ZEROS
               DISPLAY 'AP RECONCILIATION: BALANCED'
               DISPLAY '  SUBLEDGER TOTAL:  ' WS-AP-SUB-TOTAL
               DISPLAY '  GL CONTROL TOTAL: ' WS-AP-GL-BALANCE
               DISPLAY '  INVOICE COUNT:    ' WS-AP-SUB-COUNT
               PERFORM WRITE-RECON-MATCHED
           ELSE
               DISPLAY 'AP RECONCILIATION: OUT OF BALANCE'
               DISPLAY '  SUBLEDGER TOTAL:  ' WS-AP-SUB-TOTAL
               DISPLAY '  GL CONTROL TOTAL: ' WS-AP-GL-BALANCE
               DISPLAY '  DIFFERENCE:       ' WS-RECON-DIFF
               PERFORM WRITE-RECON-EXCEPTION
           END-IF

       RECONCILE-AP-EXIT.
           EXIT
           .

Tier 3: Analysis and Problem Solving (Exercises 17-24)

Exercise 17: Debugging a GL Posting Program

The following posting paragraph has four bugs. Identify each bug and explain the impact on the financial statements.

       POST-TO-GL.
           PERFORM VARYING WS-IDX FROM 1 BY 1
               UNTIL WS-IDX > JE-LINE-COUNT

               MOVE JE-LN-ACCOUNT(WS-IDX) TO GL-ACCOUNT-NUM
               READ GL-MASTER-FILE
                   KEY IS GL-ACCOUNT-NUM

               IF JE-LN-DEBIT(WS-IDX)
                   ADD JE-LN-AMOUNT(WS-IDX)
                       TO GL-PRD-DEBITS(JE-PERIOD)
               ELSE
                   ADD JE-LN-AMOUNT(WS-IDX)
                       TO GL-PRD-CREDITS(JE-PERIOD)
               END-IF

               REWRITE GL-MASTER-RECORD
           END-PERFORM
           .

Solution:

Bug 1: No INVALID KEY handling on the READ statement. If the account does not exist in the GL master, the READ fails silently, and the subsequent ADD and REWRITE operate on whatever record was in the buffer from a previous read. This could corrupt another account's balances.

Bug 2: The full key is not constructed. Only GL-ACCOUNT-NUM is moved, but the GL master key also includes GL-COMPANY and GL-FISCAL-YEAR. Without setting all key components, the READ may find the wrong record or fail entirely.

Bug 3: Period net and YTD totals are not recalculated. The paragraph adds to period debits or credits but never recomputes GL-PRD-NET or GL-YTD-NET. Financial reports that use these derived fields will show stale values, causing incorrect financial statements.

Bug 4: No INVALID KEY handling on the REWRITE statement. If the REWRITE fails (for example, if the key was changed), the error is not detected or logged. The entry appears to have been posted successfully, but the GL was not actually updated.

Exercise 18: Year-End Closing Entry Analysis

A company has the following income statement account balances at year-end:

Account Balance
Product Sales Revenue $2,400,000 (Credit)
Service Revenue $800,000 (Credit)
Salaries Expense $1,600,000 (Debit)
Rent Expense $240,000 (Debit)
Depreciation Expense $180,000 (Debit)
Interest Expense $60,000 (Debit)

Write the year-end closing journal entries needed to close these temporary accounts to Retained Earnings (account 3200). Show each entry with debits and credits, and calculate the net income that will be added to Retained Earnings.

Solution:

Net Income = Total Revenue - Total Expenses = ($2,400,000 + $800,000) - ($1,600,000 + $240,000 + $180,000 + $60,000) = $3,200,000 - $2,080,000 = $1,120,000

Closing Entry 1 -- Close Revenue Accounts:

Debit: Product Sales Revenue (4100)     $2,400,000
Debit: Service Revenue (4200)             $800,000
  Credit: Income Summary (3900)                      $3,200,000

Closing Entry 2 -- Close Expense Accounts:

Debit: Income Summary (3900)            $2,080,000
  Credit: Salaries Expense (5100)                    $1,600,000
  Credit: Rent Expense (5200)                          $240,000
  Credit: Depreciation Expense (5300)                  $180,000
  Credit: Interest Expense (5400)                       $60,000

Closing Entry 3 -- Close Income Summary to Retained Earnings:

Debit: Income Summary (3900)            $1,120,000
  Credit: Retained Earnings (3200)                   $1,120,000

After these entries, all revenue and expense accounts have zero balances, and Retained Earnings has increased by the net income of $1,120,000.

Exercise 19: Intercompany Elimination

Company A (the parent) sells goods to Company B (its subsidiary) for $500,000. Company B's books show the purchase as an expense, and Company A's books show the sale as revenue. When consolidating financial statements, these intercompany transactions must be eliminated.

Write the COBOL logic that: 1. Reads an intercompany transaction file. 2. For each transaction, generates an elimination journal entry that debits the selling company's revenue and credits the buying company's expense. 3. Ensures the elimination entry balances. 4. Writes the elimination entries to a consolidation journal file.

Solution:

       GENERATE-IC-ELIMINATIONS.
           OPEN INPUT IC-TRANSACTION-FILE
           OPEN OUTPUT IC-ELIMINATION-FILE
           MOVE ZEROS TO WS-ELIM-COUNT
                         WS-ELIM-TOTAL

           PERFORM UNTIL WS-EOF-IC
               READ IC-TRANSACTION-FILE
                   AT END SET WS-EOF-IC TO TRUE
               END-READ
               IF NOT WS-EOF-IC
                   PERFORM CREATE-IC-ELIMINATION
               END-IF
           END-PERFORM

           DISPLAY 'INTERCOMPANY ELIMINATIONS GENERATED: '
                   WS-ELIM-COUNT
           DISPLAY 'TOTAL ELIMINATION AMOUNT: '
                   WS-ELIM-TOTAL
           CLOSE IC-TRANSACTION-FILE
                 IC-ELIMINATION-FILE
           .

       CREATE-IC-ELIMINATION.
           ADD 1 TO WS-NEXT-ENTRY-NUMBER

      *    LINE 1: DEBIT SELLER'S REVENUE (REDUCES REVENUE)
           MOVE IC-SELLER-REVENUE-ACCT
               TO ELIM-LN-ACCOUNT(1)
           MOVE 'D' TO ELIM-LN-DC-IND(1)
           MOVE IC-AMOUNT TO ELIM-LN-AMOUNT(1)
           STRING 'IC ELIM: SALE TO '
                  IC-BUYER-COMPANY
               DELIMITED BY SIZE
               INTO ELIM-LN-DESC(1)

      *    LINE 2: CREDIT BUYER'S EXPENSE (REDUCES EXPENSE)
           MOVE IC-BUYER-EXPENSE-ACCT
               TO ELIM-LN-ACCOUNT(2)
           MOVE 'C' TO ELIM-LN-DC-IND(2)
           MOVE IC-AMOUNT TO ELIM-LN-AMOUNT(2)
           STRING 'IC ELIM: PURCHASE FROM '
                  IC-SELLER-COMPANY
               DELIMITED BY SIZE
               INTO ELIM-LN-DESC(2)

      *    VERIFY BALANCE
           IF ELIM-LN-AMOUNT(1) = ELIM-LN-AMOUNT(2)
               MOVE 2 TO ELIM-LINE-COUNT
               MOVE IC-AMOUNT TO ELIM-TOTAL-DEBITS
               MOVE IC-AMOUNT TO ELIM-TOTAL-CREDITS
               WRITE IC-ELIM-RECORD FROM ELIM-ENTRY
               ADD 1 TO WS-ELIM-COUNT
               ADD IC-AMOUNT TO WS-ELIM-TOTAL
           ELSE
               DISPLAY 'ERROR: IC ELIMINATION OUT OF BALANCE'
           END-IF
           .

Exercise 20: Hash Total Verification

A GL posting batch processes 5,000 journal entry lines. Before posting, the batch control record reports the following control totals:

  • Record count: 5,000
  • Hash total of account numbers: 2,847,391,250
  • Total debit amount: $12,458,930.45
  • Total credit amount: $12,458,930.45

After processing, the program's accumulators show: - Record count: 5,001 - Hash total: 2,847,391,250 - Total debits: $12,458,930.45 - Total credits: $12,458,930.45

The record count is off by one, but the hash total and dollar amounts match. What could have caused this? Is this a serious error? How would you investigate?

Solution:

The record count discrepancy of one extra record suggests one of the following:

  1. A blank or header record was counted but not processed. The accumulator incremented the count for a non-data record (such as a batch header or trailer), but because it had no account number or amount, the hash total and dollar amounts were unaffected.

  2. A duplicate entry with a zero amount was included. A zero-dollar entry would increment the count but add nothing to the debit/credit totals. However, the hash total should have been affected unless the account number was also zero.

  3. An addenda or comment record was counted. Some journal entry files include comment records that are counted as records but do not contain financial data.

This is a moderately serious error because it indicates a data integrity issue. Even though the financial totals match, the extra record could mask a more subtle problem: for example, an entry might have been duplicated with a zero amount, or a legitimate entry might have been replaced by a non-data record.

Investigation steps: Compare the input file record count with the expected count. Identify the extra record by scanning for records that were counted but not posted. Check for blank records, duplicate entry numbers, or non-standard record types.

Exercise 21: Financial Statement Format Analysis

Analyze the following COBOL data definition for a financial statement line. Identify the purpose of each field and explain why accounting convention uses parentheses for negative numbers:

       01  WS-IS-DETAIL-LINE.
           05  FILLER              PIC X(04) VALUE SPACES.
           05  WS-ISD-DESCRIPTION  PIC X(40).
           05  FILLER              PIC X(04) VALUE SPACES.
           05  WS-ISD-CURRENT      PIC $$$,$$$,$$$,$$9.99-.
           05  FILLER              PIC X(04) VALUE SPACES.
           05  WS-ISD-BUDGET       PIC $$$,$$$,$$$,$$9.99-.
           05  FILLER              PIC X(04) VALUE SPACES.
           05  WS-ISD-VARIANCE     PIC $$$,$$$,$$$,$$9.99-.
           05  FILLER              PIC X(04) VALUE SPACES.
           05  WS-ISD-VAR-PCT      PIC --9.9.
           05  FILLER              PIC X(01) VALUE '%'.

How would you modify the amount fields to display negative numbers in parentheses instead of with a trailing minus sign?

Solution:

Field purposes: - WS-ISD-DESCRIPTION: The account or category name (left-justified, 40 characters). - WS-ISD-CURRENT: The actual amount for the current period. The `$$$,...` pattern provides floating dollar sign with comma separators. The trailing `-` displays a minus sign for negative values. - **WS-ISD-BUDGET**: The budgeted amount for comparison. - **WS-ISD-VARIANCE**: The difference between budget and actual. - **WS-ISD-VAR-PCT**: The variance as a percentage. The `--9.9` pattern suppresses leading zeros and shows one decimal place. Accounting convention uses **parentheses** for negative numbers rather than minus signs because parentheses are more visually prominent and less likely to be missed or confused with a hyphen or dash. To display parentheses, you cannot use a simple PICTURE clause; instead, you must use procedural logic: ```cobol 01 WS-FORMATTED-AMOUNT PIC X(20). 01 WS-ABS-AMOUNT PIC $$$,MATH11$,$$9.99.

   FORMAT-WITH-PARENS.
       IF WS-AMOUNT < ZEROS
           COMPUTE WS-ABS-VALUE = WS-AMOUNT * -1
           MOVE WS-ABS-VALUE TO WS-ABS-AMOUNT
           STRING '(' WS-ABS-AMOUNT ')'
               DELIMITED BY SIZE
               INTO WS-FORMATTED-AMOUNT
       ELSE
           MOVE WS-AMOUNT TO WS-ABS-AMOUNT
           MOVE WS-ABS-AMOUNT TO WS-FORMATTED-AMOUNT
       END-IF
       .

### Exercise 22: Multi-Company Consolidation Logic
Write the COBOL logic for consolidating financial statements across three companies: Company 0100 (USA), Company 0200 (UK, currency GBP), and Company 0300 (Japan, currency JPY). The consolidation must:

1. Convert each subsidiary's balances from local currency to USD using provided exchange rates.
2. Aggregate the converted balances.
3. Handle the currency translation adjustment (the difference caused by exchange rate changes).

Given: GBP-to-USD rate = 1.27, JPY-to-USD rate = 0.0067.

**Solution:**

```cobol
       01  WS-CONSOL-RATES.
           05  WS-GBP-TO-USD      PIC 9(03)V9(08)
                                  VALUE 1.27000000.
           05  WS-JPY-TO-USD      PIC 9(03)V9(08)
                                  VALUE 0.00670000.

       01  WS-CONSOL-TOTALS.
           05  WS-CONSOL-BALANCE  PIC S9(15)V99
                                  COMP-3 VALUE ZEROS.
           05  WS-CONVERTED-AMT   PIC S9(15)V99
                                  COMP-3.
           05  WS-TRANS-ADJ       PIC S9(15)V99
                                  COMP-3 VALUE ZEROS.

       CONSOLIDATE-COMPANIES.
           MOVE ZEROS TO WS-CONSOL-BALANCE
                         WS-TRANS-ADJ

           PERFORM PROCESS-COMPANY-0100
           PERFORM PROCESS-COMPANY-0200
           PERFORM PROCESS-COMPANY-0300

           DISPLAY 'CONSOLIDATED BALANCE (USD): '
                   WS-CONSOL-BALANCE
           DISPLAY 'TRANSLATION ADJUSTMENT:     '
                   WS-TRANS-ADJ
           .

       PROCESS-COMPANY-0100.
      *    US COMPANY - NO CONVERSION NEEDED
           ADD GL-ENDING-BALANCE TO WS-CONSOL-BALANCE
           .

       PROCESS-COMPANY-0200.
      *    UK COMPANY - CONVERT GBP TO USD
           COMPUTE WS-CONVERTED-AMT ROUNDED =
               GL-ENDING-BALANCE * WS-GBP-TO-USD
           ADD WS-CONVERTED-AMT TO WS-CONSOL-BALANCE

      *    CALCULATE TRANSLATION ADJUSTMENT
           COMPUTE WS-TRANS-ADJ =
               WS-TRANS-ADJ +
               (WS-CONVERTED-AMT -
                (GL-ENDING-BALANCE * WS-PRIOR-GBP-RATE))
           .

       PROCESS-COMPANY-0300.
      *    JAPAN COMPANY - CONVERT JPY TO USD
           COMPUTE WS-CONVERTED-AMT ROUNDED =
               GL-ENDING-BALANCE * WS-JPY-TO-USD
           ADD WS-CONVERTED-AMT TO WS-CONSOL-BALANCE

           COMPUTE WS-TRANS-ADJ =
               WS-TRANS-ADJ +
               (WS-CONVERTED-AMT -
                (GL-ENDING-BALANCE * WS-PRIOR-JPY-RATE))
           .

Exercise 23: Audit Trail Analysis

A regulatory auditor asks you to trace a specific dollar amount ($47,250.00) from the financial statements back to its source. The amount appears on the income statement as "Consulting Expense" for June. Describe the complete audit trail you would follow using the GL system, and write the COBOL logic that would retrieve each step of the trail.

Solution:

The audit trail follows these steps in reverse:

  1. Financial Statement to GL: Query the GL master file for the Consulting Expense account (natural account 5400, or whatever the COA specifies) for period 6.

  2. GL to Journal Entries: Query the journal history file for all entries posted to this account in period 6.

  3. Journal Entries to Source Documents: For each journal entry, retrieve the source reference field to identify the originating document (invoice, purchase order, contract).

       TRACE-AUDIT-TRAIL.
      *    STEP 1: READ GL FOR THE ACCOUNT AND PERIOD
           MOVE '5400' TO GL-NATURAL-ACCT
           MOVE 6 TO WS-TRACE-PERIOD
           READ GL-MASTER-FILE
               KEY IS GL-FULL-KEY
           END-READ

           DISPLAY 'GL BALANCE FOR PERIOD 6: '
                   GL-PRD-NET(6)
           DISPLAY 'DEBITS:  ' GL-PRD-DEBITS(6)
           DISPLAY 'CREDITS: ' GL-PRD-CREDITS(6)

      *    STEP 2: FIND ALL JOURNAL ENTRIES FOR THIS ACCT
           OPEN INPUT JOURNAL-HISTORY-FILE
           PERFORM UNTIL WS-EOF-JH
               READ JOURNAL-HISTORY-FILE
                   AT END SET WS-EOF-JH TO TRUE
               END-READ
               IF NOT WS-EOF-JH
                   PERFORM VARYING WS-IDX FROM 1 BY 1
                       UNTIL WS-IDX > JH-LINE-COUNT
                       IF JH-LN-ACCOUNT(WS-IDX) = '5400'
                          AND JH-PERIOD = 6
                           DISPLAY 'ENTRY: ' JH-ENTRY-NUMBER
                                   ' DATE: ' JH-ENTRY-DATE
                                   ' AMT: '
                                   JH-LN-AMOUNT(WS-IDX)
                                   ' REF: ' JH-SOURCE-REF
                       END-IF
                   END-PERFORM
               END-IF
           END-PERFORM
           CLOSE JOURNAL-HISTORY-FILE

      *    STEP 3: FOR EACH ENTRY, THE SOURCE-REF FIELD
      *    LINKS TO THE ORIGINATING DOCUMENT (INVOICE, PO, ETC.)
           .

Exercise 24: Month-End Close JCL Design

Design the complete JCL job stream for a month-end close process. The job should execute the following steps in sequence:

  1. Verify all daily postings are complete (program GLVERFY).
  2. Process recurring entries (program GLRECUR).
  3. Generate accrual entries (program GLACRLS).
  4. Post all pending entries including recurring and accruals (program GLPOST).
  5. Generate trial balance (program GLTRIAL).
  6. Generate income statement (program GLINCOM).
  7. Generate balance sheet (program GLBALSH).
  8. Close the period (program GLCLOSE).
  9. Generate auto-reversals for next period (program GLREVRSL).

Each step should fail if the previous step returned a code greater than 4.

Solution:

//GLMEC    JOB (ACCTG,MEC),'MONTH-END CLOSE',
//             CLASS=A,MSGCLASS=X,MSGLEVEL=(1,1),
//             NOTIFY=&SYSUID
//*
//*-----------------------------------------------------------*
//*  STEP 1: VERIFY ALL DAILY POSTINGS COMPLETE               *
//*-----------------------------------------------------------*
//VERIFY   EXEC PGM=GLVERFY
//STEPLIB  DD DSN=ACCTG.PROD.LOADLIB,DISP=SHR
//GLMAST   DD DSN=ACCTG.GL.MASTER.VSAM,DISP=SHR
//PRDCTRL  DD DSN=ACCTG.PERIOD.CONTROL.VSAM,DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSOUT   DD SYSOUT=*
//*
//*-----------------------------------------------------------*
//*  STEP 2: PROCESS RECURRING ENTRIES                        *
//*-----------------------------------------------------------*
//RECUR    EXEC PGM=GLRECUR,COND=(4,LT)
//STEPLIB  DD DSN=ACCTG.PROD.LOADLIB,DISP=SHR
//RECTMPLT DD DSN=ACCTG.RECURRING.TEMPLATES,DISP=SHR
//JEOUTPUT DD DSN=ACCTG.GENERATED.JE.RECUR,
//            DISP=(NEW,CATLG,DELETE),
//            SPACE=(CYL,(1,1)),
//            DCB=(RECFM=FB,LRECL=300,BLKSIZE=0)
//SYSPRINT DD SYSOUT=*
//SYSOUT   DD SYSOUT=*
//*
//*-----------------------------------------------------------*
//*  STEP 3: GENERATE ACCRUAL ENTRIES                         *
//*-----------------------------------------------------------*
//ACCRLS   EXEC PGM=GLACRLS,COND=(4,LT)
//STEPLIB  DD DSN=ACCTG.PROD.LOADLIB,DISP=SHR
//ACRTMPLT DD DSN=ACCTG.ACCRUAL.TEMPLATES,DISP=SHR
//JEOUTPUT DD DSN=ACCTG.GENERATED.JE.ACRLS,
//            DISP=(NEW,CATLG,DELETE),
//            SPACE=(CYL,(1,1)),
//            DCB=(RECFM=FB,LRECL=300,BLKSIZE=0)
//SYSPRINT DD SYSOUT=*
//SYSOUT   DD SYSOUT=*
//*
//*-----------------------------------------------------------*
//*  STEP 4: POST ALL PENDING ENTRIES                         *
//*-----------------------------------------------------------*
//POST     EXEC PGM=GLPOST,COND=(4,LT)
//STEPLIB  DD DSN=ACCTG.PROD.LOADLIB,DISP=SHR
//GLMAST   DD DSN=ACCTG.GL.MASTER.VSAM,DISP=SHR
//COAFILE  DD DSN=ACCTG.CHART.OF.ACCOUNTS.VSAM,DISP=SHR
//JEINPUT  DD DSN=ACCTG.PENDING.JOURNAL.ENTRIES,DISP=SHR
//         DD DSN=ACCTG.GENERATED.JE.RECUR,DISP=SHR
//         DD DSN=ACCTG.GENERATED.JE.ACRLS,DISP=SHR
//JEHIST   DD DSN=ACCTG.JOURNAL.HISTORY,DISP=MOD
//REJECTS  DD DSN=ACCTG.POSTING.REJECTS,
//            DISP=(NEW,CATLG,DELETE),
//            SPACE=(CYL,(1,1)),
//            DCB=(RECFM=FB,LRECL=300,BLKSIZE=0)
//SYSPRINT DD SYSOUT=*
//SYSOUT   DD SYSOUT=*
//*
//*-----------------------------------------------------------*
//*  STEP 5: GENERATE TRIAL BALANCE                           *
//*-----------------------------------------------------------*
//TRIAL    EXEC PGM=GLTRIAL,COND=(4,LT)
//STEPLIB  DD DSN=ACCTG.PROD.LOADLIB,DISP=SHR
//GLMAST   DD DSN=ACCTG.GL.MASTER.VSAM,DISP=SHR
//TBRPT    DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSOUT   DD SYSOUT=*
//*
//*-----------------------------------------------------------*
//*  STEP 6: GENERATE INCOME STATEMENT                        *
//*-----------------------------------------------------------*
//INCOME   EXEC PGM=GLINCOM,COND=(4,LT)
//STEPLIB  DD DSN=ACCTG.PROD.LOADLIB,DISP=SHR
//GLMAST   DD DSN=ACCTG.GL.MASTER.VSAM,DISP=SHR
//COAFILE  DD DSN=ACCTG.CHART.OF.ACCOUNTS.VSAM,DISP=SHR
//ISRPT    DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSOUT   DD SYSOUT=*
//*
//*-----------------------------------------------------------*
//*  STEP 7: GENERATE BALANCE SHEET                           *
//*-----------------------------------------------------------*
//BALSH    EXEC PGM=GLBALSH,COND=(4,LT)
//STEPLIB  DD DSN=ACCTG.PROD.LOADLIB,DISP=SHR
//GLMAST   DD DSN=ACCTG.GL.MASTER.VSAM,DISP=SHR
//COAFILE  DD DSN=ACCTG.CHART.OF.ACCOUNTS.VSAM,DISP=SHR
//BSRPT    DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSOUT   DD SYSOUT=*
//*
//*-----------------------------------------------------------*
//*  STEP 8: CLOSE THE PERIOD                                 *
//*-----------------------------------------------------------*
//CLOSE    EXEC PGM=GLCLOSE,COND=(4,LT)
//STEPLIB  DD DSN=ACCTG.PROD.LOADLIB,DISP=SHR
//GLMAST   DD DSN=ACCTG.GL.MASTER.VSAM,DISP=SHR
//PRDCTRL  DD DSN=ACCTG.PERIOD.CONTROL.VSAM,DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSOUT   DD SYSOUT=*
//*
//*-----------------------------------------------------------*
//*  STEP 9: GENERATE AUTO-REVERSALS                          *
//*-----------------------------------------------------------*
//REVRSL   EXEC PGM=GLREVRSL,COND=(4,LT)
//STEPLIB  DD DSN=ACCTG.PROD.LOADLIB,DISP=SHR
//JEHIST   DD DSN=ACCTG.JOURNAL.HISTORY,DISP=SHR
//REVOUT   DD DSN=ACCTG.GENERATED.JE.REVERSALS,
//            DISP=(NEW,CATLG,DELETE),
//            SPACE=(CYL,(1,1)),
//            DCB=(RECFM=FB,LRECL=300,BLKSIZE=0)
//SYSPRINT DD SYSOUT=*
//SYSOUT   DD SYSOUT=*

Tier 4: Synthesis and Design (Exercises 25-32)

Exercise 25: Complete GL Posting System

Design and write a complete COBOL program that reads a file of journal entries, validates each entry, posts valid entries to the GL master file, writes rejected entries to an error file, and produces a posting summary report. The program should handle:

  • Multi-line journal entries (header + detail lines).
  • Balance verification (debits must equal credits).
  • Account validation against the chart of accounts.
  • Period status checking.
  • Audit trail generation.

Include the complete FILE SECTION, WORKING-STORAGE SECTION, PROCEDURE DIVISION, and companion JCL.

Hint: Read the journal entry file sequentially. Use the record type indicator ('H' for header, 'L' for line) to distinguish between headers and detail lines. Accumulate lines until the next header is read, then validate and post the complete entry.

Exercise 26: Financial Statement Generator

Design a COBOL program that generates a complete income statement with budget comparison. The program should:

  1. Read the GL master file and the chart of accounts.
  2. Group accounts by category (using the natural account segment).
  3. Calculate subtotals for each category (Revenue, Cost of Goods Sold, Operating Expenses, Other Income/Expenses).
  4. Calculate gross profit (Revenue minus COGS), operating income (Gross Profit minus Operating Expenses), and net income.
  5. Show current period, YTD, budget, and variance columns.
  6. Format with proper headers, page breaks, and accounting-style number formatting.

Provide the report layout design, the main processing logic, and the control break logic for category subtotals.

Hint: Sort the GL records by natural account before processing. Use control break logic on the first digit of the natural account to detect category changes.

Exercise 27: Accrual Processing Engine

Design a COBOL program that generates month-end accrual journal entries from templates. The program should support three types of accruals:

  1. Fixed accruals: Same amount every month (e.g., monthly rent of $10,000).
  2. Calculated accruals: Amount based on a formula (e.g., salary accrual = annual salary / 12 * business days remaining / total business days).
  3. Estimated accruals: Based on percentage of a reference account balance (e.g., bad debt accrual = 2% of accounts receivable balance).

For each type, design the template record layout, the calculation logic, and the journal entry generation. All generated entries should be marked as auto-reversing.

Hint: Load the accrual templates into a working-storage table at program start. For estimated accruals, you will need to read the GL master to get the reference account balance.

Exercise 28: Period Close Program

Design a COBOL program that performs the period close process. The program should:

  1. Verify that the trial balance is in balance.
  2. Verify that all subledger reconciliations have been completed (check a reconciliation status file).
  3. Change the current period status from 'O' (Open) to 'C' (Closed).
  4. Open the next period (change status from future to Open).
  5. For year-end close (period 12), also close all revenue and expense accounts to Retained Earnings and create opening balances for the new year.
  6. Generate a close confirmation report.

Include error handling for the case where the trial balance does not balance (the close must be aborted) and for the case where subledger reconciliations are incomplete.

Hint: Use a period control file that stores the status of each period for each company. The year-end close is a special case that requires additional processing beyond a regular month-end close.


Tier 5: Evaluation and Creation (Exercises 29-35)

Exercise 29: GL System Migration to DB2

Your organization is migrating the GL master file from VSAM to DB2. Design the DB2 table schema, write the COBOL embedded SQL statements that replace the VSAM I/O operations, and discuss the performance implications.

Consider: How does a sequential read of the entire GL master file for report generation translate to SQL? How do you handle the OCCURS 13 TIMES period table in a relational schema? What indexes are needed for efficient access?

Hint: You have two choices for the period table: (1) store all 13 periods as columns in a single row (denormalized), or (2) create a separate period detail table with one row per account per period (normalized). Discuss the trade-offs of each approach for reporting vs. posting.

Exercise 30: Real-Time GL Dashboard

Design a system that provides real-time GL balance information through a CICS inquiry transaction. The system should:

  1. Accept an account number and period from the user.
  2. Display the account description, current period debits, credits, net, budget, variance, and YTD balance.
  3. Allow drill-down to see the individual journal entries that make up the period activity.
  4. Support both detail accounts and summary (roll-up) accounts.

Design the CICS BMS maps, the inquiry program logic, and discuss how to handle the performance challenge of real-time roll-up calculations.

Hint: Consider pre-computing summary balances in a separate VSAM file that is updated during each posting run. This avoids the expensive real-time roll-up calculation.

Exercise 31: Multi-GAAP Reporting

A multinational company must produce financial statements under both US GAAP and IFRS. The differences between the two standards affect revenue recognition, lease accounting, and depreciation methods, among other areas. Design a GL system that supports dual reporting:

  1. How would you structure the chart of accounts to capture both GAAP and IFRS adjustments?
  2. How would you modify the journal entry structure to indicate which reporting standard an entry applies to?
  3. How would you generate financial statements under each standard from the same GL data?

Discuss the COBOL data structures and processing logic needed.

Hint: Consider a "reporting book" concept where each journal entry line can specify which book(s) it applies to: 'B' (both), 'G' (GAAP only), or 'I' (IFRS only). Financial statement generation would then filter by book.

Exercise 32: Automated Journal Entry Testing Framework

Design a COBOL testing framework for validating journal entry processing. The framework should:

  1. Read a file of test cases, each containing a journal entry and expected results (post/reject, reason codes, resulting GL balances).
  2. Execute each test case through the GL posting program.
  3. Compare actual results against expected results.
  4. Report pass/fail for each test case with detailed differences.
  5. Calculate overall pass rate and identify regression failures.

This is a meta-program: a COBOL program that tests other COBOL programs. Discuss the challenges of automated testing in a mainframe batch environment.

Hint: The test framework can use the CALL statement to invoke the posting program as a subprogram. Test data files should include both valid entries (expected to post) and invalid entries (expected to be rejected for specific reasons).

Exercise 33: Fraud Detection in Journal Entries

Design a COBOL program that analyzes journal entries for potential fraud indicators. The program should detect:

  1. Entries posted just below the approval threshold (e.g., multiple entries of $49,999 when the threshold is $50,000).
  2. Unusual account combinations (e.g., debiting cash and crediting a revenue account directly, bypassing accounts receivable).
  3. Entries posted to periods that were recently reopened.
  4. Round-dollar entries above a threshold (which may indicate estimation rather than actual transactions).
  5. Entries posted by users outside their normal account range.

Design the detection rules, the data structures for user profiles and account associations, and the alert generation logic.

Hint: Build a user profile table that records each user's typical accounts and amount ranges. Compare each journal entry against the profile and flag deviations.

Exercise 34: GL Consolidation Engine

Design a complete consolidation engine that produces consolidated financial statements for a parent company with five subsidiaries in four countries. The engine must handle:

  1. Currency translation for each subsidiary.
  2. Intercompany elimination entries.
  3. Minority interest calculations.
  4. Translation adjustment reporting.
  5. Roll-up of consolidated balances.
  6. Production of consolidated Income Statement, Balance Sheet, and Cash Flow Statement.

Provide the key data structures, processing logic, and JCL for the consolidation batch job.

Hint: Process in sequence: translate, eliminate, calculate minority interest, aggregate, report. Each step produces intermediate files that feed the next step.

Exercise 35: Comprehensive GL System Evaluation

You are evaluating whether to modernize a 30-year-old COBOL GL system or replace it with a commercial ERP package. Prepare a detailed analysis that addresses:

  1. What features of COBOL make it well-suited for GL processing?
  2. What limitations of the current COBOL system drive the modernization discussion?
  3. What risks does a replacement project carry?
  4. What hybrid approaches might preserve the strengths of both COBOL and modern technology?
  5. How would you ensure data integrity during migration?

Support your analysis with specific examples from this chapter's code and data structures. Consider performance, reliability, auditability, regulatory compliance, and total cost of ownership.

Hint: Consider that the COBOL system processes 100,000 journal entries per night in a 45-minute batch window. Any replacement must match or exceed this performance. Also consider that the existing system has 30 years of accumulated business rules that must be preserved.