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:
- Total debits must equal total credits (balance check).
- Each line's account must exist in the chart of accounts and must be active and postable.
- The posting period must be open.
- No line may have a zero amount.
- If the entry total exceeds $100,000, it must have an approver (
JE-APPROVED-BYmust 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:
- Read the GL master record using the account key and period.
- If the record does not exist, initialize a new GL record.
- Add the amount to either the period debits or period credits based on the debit/credit indicator.
- Recalculate the period net amount.
- Recalculate the year-to-date totals.
- REWRITE (or WRITE for new records) the GL master record.
- 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:
- List each account with its description, debit balance, and credit balance.
- Accounts with normal debit balances (Assets, Expenses) show their ending balance in the debit column.
- Accounts with normal credit balances (Liabilities, Equity, Revenue) show their ending balance in the credit column.
- Accumulate total debits and total credits.
- 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:
- Compute the dollar variance (budget minus actual).
- Compute the percentage variance.
- Classify the variance as favorable or unfavorable based on the account type (for expenses, under-budget is favorable; for revenue, over-budget is favorable).
- 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 assetFA-SALVAGE-VALUE: Estimated salvage valueFA-USEFUL-LIFE-MONTHS: Useful life in monthsFA-DEPR-EXPENSE-ACCT: GL account for depreciation expenseFA-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:
- Segregation of duties: The person who created the entry must not be the same person who approved it.
- Approval threshold: Entries with total debits exceeding $50,000 require approval.
- Entries exceeding $500,000 require two approvers (a second approval field must also be populated).
- 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:
- Read the AP subledger file sequentially and sum all open invoice balances.
- Read the GL AP control account record and extract the ending balance.
- Compare the two amounts.
- If they match, write a "RECONCILED" record.
- 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:
-
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.
-
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.
-
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:
-
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.
-
GL to Journal Entries: Query the journal history file for all entries posted to this account in period 6.
-
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:
- Verify all daily postings are complete (program GLVERFY).
- Process recurring entries (program GLRECUR).
- Generate accrual entries (program GLACRLS).
- Post all pending entries including recurring and accruals (program GLPOST).
- Generate trial balance (program GLTRIAL).
- Generate income statement (program GLINCOM).
- Generate balance sheet (program GLBALSH).
- Close the period (program GLCLOSE).
- 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:
- Read the GL master file and the chart of accounts.
- Group accounts by category (using the natural account segment).
- Calculate subtotals for each category (Revenue, Cost of Goods Sold, Operating Expenses, Other Income/Expenses).
- Calculate gross profit (Revenue minus COGS), operating income (Gross Profit minus Operating Expenses), and net income.
- Show current period, YTD, budget, and variance columns.
- 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:
- Fixed accruals: Same amount every month (e.g., monthly rent of $10,000).
- Calculated accruals: Amount based on a formula (e.g., salary accrual = annual salary / 12 * business days remaining / total business days).
- 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:
- Verify that the trial balance is in balance.
- Verify that all subledger reconciliations have been completed (check a reconciliation status file).
- Change the current period status from 'O' (Open) to 'C' (Closed).
- Open the next period (change status from future to Open).
- For year-end close (period 12), also close all revenue and expense accounts to Retained Earnings and create opening balances for the new year.
- 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:
- Accept an account number and period from the user.
- Display the account description, current period debits, credits, net, budget, variance, and YTD balance.
- Allow drill-down to see the individual journal entries that make up the period activity.
- 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:
- How would you structure the chart of accounts to capture both GAAP and IFRS adjustments?
- How would you modify the journal entry structure to indicate which reporting standard an entry applies to?
- 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:
- Read a file of test cases, each containing a journal entry and expected results (post/reject, reason codes, resulting GL balances).
- Execute each test case through the GL posting program.
- Compare actual results against expected results.
- Report pass/fail for each test case with detailed differences.
- 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:
- Entries posted just below the approval threshold (e.g., multiple entries of $49,999 when the threshold is $50,000).
- Unusual account combinations (e.g., debiting cash and crediting a revenue account directly, bypassing accounts receivable).
- Entries posted to periods that were recently reopened.
- Round-dollar entries above a threshold (which may indicate estimation rather than actual transactions).
- 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:
- Currency translation for each subsidiary.
- Intercompany elimination entries.
- Minority interest calculations.
- Translation adjustment reporting.
- Roll-up of consolidated balances.
- 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:
- What features of COBOL make it well-suited for GL processing?
- What limitations of the current COBOL system drive the modernization discussion?
- What risks does a replacement project carry?
- What hybrid approaches might preserve the strengths of both COBOL and modern technology?
- 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.