Case Study 2: Batch Reconciliation and Exception Processing
Background
Every business day, Heartland Community Bank must reconcile the total of all individual account transactions against the general ledger (GL) summary entries. This reconciliation ensures that every dollar flowing through the bank's systems is accounted for -- that deposits, withdrawals, transfers, fees, and interest postings in the transaction detail files exactly match the aggregated entries in the general ledger.
When the reconciliation finds discrepancies, these are classified as exceptions that require investigation. Some exceptions can be resolved automatically (timing differences, rounding adjustments, known system offsets). Others require manual review by the accounting team.
Senior COBOL developer Sandra Kowalski designed and coded the batch reconciliation program, RECONMCH, which runs as part of the bank's nightly end-of-day cycle. The program reads two input files -- the daily transaction detail and the GL summary -- performs a matching algorithm, and produces three output files: matched items, unmatched items, and an exception report.
This case study presents the complete COBOL reconciliation program, explains the matching logic, and examines the exception handling workflow.
The Reconciliation Business Rules
The reconciliation follows specific rules established by the bank's accounting department:
-
Matching criteria: A transaction detail record matches a GL summary record when both the account category code and the transaction type agree, and the aggregated transaction amounts for that category/type combination equal the GL summary amount within a tolerance of $0.01.
-
Out-of-balance detection: If the total debits minus total credits in the transaction detail differs from the GL net change by more than $0.01, the entire day is flagged as out-of-balance.
-
Automatic corrections: Rounding differences of $0.01 or less are adjusted automatically. Known system offsets (such as end-of-day interest accrual timing) are recognized and documented but not flagged as errors.
-
Manual review threshold: Any single unmatched amount exceeding $10,000 is flagged for immediate supervisor review. Amounts between $100 and $10,000 are flagged for next-day review. Amounts under $100 are logged but not escalated.
-
Balancing proof: The sum of all matched amounts plus the sum of all unmatched amounts must equal the original transaction detail total. This is the "proof of reconciliation" that auditors verify.
Input File Layouts
The daily transaction detail file is sorted by account category and transaction type. Each record represents a single transaction:
01 WS-TXN-DETAIL-REC.
05 WS-TXN-ACCT-CATEGORY PIC X(4).
05 WS-TXN-TYPE-CODE PIC X(3).
05 WS-TXN-ACCT-NUM PIC X(12).
05 WS-TXN-DATE PIC X(10).
05 WS-TXN-SEQ-NUM PIC 9(8).
05 WS-TXN-AMOUNT PIC S9(11)V99 COMP-3.
05 WS-TXN-DR-CR-IND PIC X(1).
88 TXN-DEBIT VALUE 'D'.
88 TXN-CREDIT VALUE 'C'.
05 WS-TXN-DESCRIPTION PIC X(40).
05 WS-TXN-SOURCE-SYS PIC X(3).
05 WS-TXN-BRANCH PIC X(4).
05 WS-TXN-TELLER-ID PIC X(6).
05 FILLER PIC X(53).
The GL summary file contains one record per account-category/transaction-type combination, showing the aggregated totals posted to the general ledger:
01 WS-GL-SUMMARY-REC.
05 WS-GL-ACCT-CATEGORY PIC X(4).
05 WS-GL-TYPE-CODE PIC X(3).
05 WS-GL-DEBIT-TOTAL PIC S9(13)V99 COMP-3.
05 WS-GL-CREDIT-TOTAL PIC S9(13)V99 COMP-3.
05 WS-GL-NET-AMOUNT PIC S9(13)V99 COMP-3.
05 WS-GL-ENTRY-COUNT PIC 9(7).
05 WS-GL-POST-DATE PIC X(10).
05 WS-GL-BATCH-ID PIC X(8).
05 FILLER PIC X(65).
Complete COBOL Reconciliation Program
IDENTIFICATION DIVISION.
PROGRAM-ID. RECONMCH.
*================================================================*
* RECONMCH - Daily Transaction Reconciliation Program *
* Matches transaction detail against GL summary entries. *
* Produces matched, unmatched, and exception report files. *
*================================================================*
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT TXN-DETAIL-FILE ASSIGN TO TXNDTL
FILE STATUS IS WS-TXN-FS.
SELECT GL-SUMMARY-FILE ASSIGN TO GLSUMM
FILE STATUS IS WS-GL-FS.
SELECT MATCHED-FILE ASSIGN TO MATCHED
FILE STATUS IS WS-MAT-FS.
SELECT UNMATCHED-FILE ASSIGN TO UNMATCH
FILE STATUS IS WS-UNM-FS.
SELECT EXCEPTION-RPT ASSIGN TO EXCPRPT
FILE STATUS IS WS-EXC-FS.
DATA DIVISION.
FILE SECTION.
FD TXN-DETAIL-FILE
RECORDING MODE IS F
RECORD CONTAINS 150 CHARACTERS.
01 TXN-DETAIL-INPUT PIC X(150).
FD GL-SUMMARY-FILE
RECORDING MODE IS F
RECORD CONTAINS 120 CHARACTERS.
01 GL-SUMMARY-INPUT PIC X(120).
FD MATCHED-FILE
RECORDING MODE IS F
RECORD CONTAINS 200 CHARACTERS.
01 MATCHED-OUTPUT PIC X(200).
FD UNMATCHED-FILE
RECORDING MODE IS F
RECORD CONTAINS 200 CHARACTERS.
01 UNMATCHED-OUTPUT PIC X(200).
FD EXCEPTION-RPT
RECORDING MODE IS F
RECORD CONTAINS 133 CHARACTERS.
01 EXCEPTION-RPT-REC PIC X(133).
WORKING-STORAGE SECTION.
*================================================================*
* File status codes *
*================================================================*
01 WS-TXN-FS PIC XX VALUE '00'.
01 WS-GL-FS PIC XX VALUE '00'.
01 WS-MAT-FS PIC XX VALUE '00'.
01 WS-UNM-FS PIC XX VALUE '00'.
01 WS-EXC-FS PIC XX VALUE '00'.
*================================================================*
* Transaction detail record (working copy) *
*================================================================*
01 WS-TXN-DETAIL-REC.
05 WS-TXN-ACCT-CATEGORY PIC X(4).
05 WS-TXN-TYPE-CODE PIC X(3).
05 WS-TXN-ACCT-NUM PIC X(12).
05 WS-TXN-DATE PIC X(10).
05 WS-TXN-SEQ-NUM PIC 9(8).
05 WS-TXN-AMOUNT PIC S9(11)V99 COMP-3.
05 WS-TXN-DR-CR-IND PIC X(1).
88 TXN-DEBIT VALUE 'D'.
88 TXN-CREDIT VALUE 'C'.
05 WS-TXN-DESCRIPTION PIC X(40).
05 WS-TXN-SOURCE-SYS PIC X(3).
05 WS-TXN-BRANCH PIC X(4).
05 WS-TXN-TELLER-ID PIC X(6).
05 FILLER PIC X(53).
*================================================================*
* GL summary record (working copy) *
*================================================================*
01 WS-GL-SUMMARY-REC.
05 WS-GL-ACCT-CATEGORY PIC X(4).
05 WS-GL-TYPE-CODE PIC X(3).
05 WS-GL-DEBIT-TOTAL PIC S9(13)V99 COMP-3.
05 WS-GL-CREDIT-TOTAL PIC S9(13)V99 COMP-3.
05 WS-GL-NET-AMOUNT PIC S9(13)V99 COMP-3.
05 WS-GL-ENTRY-COUNT PIC 9(7).
05 WS-GL-POST-DATE PIC X(10).
05 WS-GL-BATCH-ID PIC X(8).
05 FILLER PIC X(65).
*================================================================*
* Composite keys for matching *
*================================================================*
01 WS-TXN-MATCH-KEY.
05 WS-TXN-KEY-CAT PIC X(4).
05 WS-TXN-KEY-TYPE PIC X(3).
01 WS-GL-MATCH-KEY.
05 WS-GL-KEY-CAT PIC X(4).
05 WS-GL-KEY-TYPE PIC X(3).
*================================================================*
* Accumulation fields for transaction group totals *
*================================================================*
01 WS-GROUP-ACCUM.
05 WS-GRP-DEBIT-TOTAL PIC S9(13)V99 VALUE ZEROS.
05 WS-GRP-CREDIT-TOTAL PIC S9(13)V99 VALUE ZEROS.
05 WS-GRP-NET-AMOUNT PIC S9(13)V99 VALUE ZEROS.
05 WS-GRP-ENTRY-COUNT PIC 9(7) VALUE ZEROS.
*================================================================*
* Reconciliation variance fields *
*================================================================*
01 WS-VARIANCE.
05 WS-VAR-DEBIT PIC S9(13)V99 VALUE ZEROS.
05 WS-VAR-CREDIT PIC S9(13)V99 VALUE ZEROS.
05 WS-VAR-NET PIC S9(13)V99 VALUE ZEROS.
05 WS-VAR-COUNT PIC S9(7) VALUE ZEROS.
*================================================================*
* Grand total fields *
*================================================================*
01 WS-GRAND-TOTALS.
05 WS-GT-TXN-DEBITS PIC S9(15)V99 VALUE ZEROS.
05 WS-GT-TXN-CREDITS PIC S9(15)V99 VALUE ZEROS.
05 WS-GT-TXN-NET PIC S9(15)V99 VALUE ZEROS.
05 WS-GT-TXN-COUNT PIC 9(9) VALUE ZEROS.
05 WS-GT-GL-DEBITS PIC S9(15)V99 VALUE ZEROS.
05 WS-GT-GL-CREDITS PIC S9(15)V99 VALUE ZEROS.
05 WS-GT-GL-NET PIC S9(15)V99 VALUE ZEROS.
05 WS-GT-GL-COUNT PIC 9(9) VALUE ZEROS.
05 WS-GT-MATCHED-AMT PIC S9(15)V99 VALUE ZEROS.
05 WS-GT-UNMATCHED-AMT PIC S9(15)V99 VALUE ZEROS.
*================================================================*
* Processing counters *
*================================================================*
01 WS-CTR.
05 WS-TXN-RECORDS-READ PIC 9(9) VALUE ZEROS.
05 WS-GL-RECORDS-READ PIC 9(7) VALUE ZEROS.
05 WS-MATCHED-GROUPS PIC 9(7) VALUE ZEROS.
05 WS-UNMATCHED-TXN PIC 9(7) VALUE ZEROS.
05 WS-UNMATCHED-GL PIC 9(7) VALUE ZEROS.
05 WS-EXCEPTIONS PIC 9(7) VALUE ZEROS.
05 WS-AUTO-CORRECTIONS PIC 9(7) VALUE ZEROS.
05 WS-MANUAL-REVIEWS PIC 9(7) VALUE ZEROS.
*================================================================*
* Tolerance and thresholds *
*================================================================*
01 WS-MATCH-TOLERANCE PIC S9(3)V99 VALUE +0.01.
01 WS-SUPERVISOR-THRESHOLD PIC S9(7)V99 VALUE +10000.00.
01 WS-REVIEW-THRESHOLD PIC S9(5)V99 VALUE +100.00.
*================================================================*
* EOF flags *
*================================================================*
01 WS-TXN-EOF PIC X VALUE 'N'.
88 TXN-AT-END VALUE 'Y'.
01 WS-GL-EOF PIC X VALUE 'N'.
88 GL-AT-END VALUE 'Y'.
*================================================================*
* Match result output record *
*================================================================*
01 WS-MATCH-RESULT-REC.
05 WS-MR-RESULT-CODE PIC X(1).
88 MR-MATCHED VALUE 'M'.
88 MR-UNMATCHED-TXN VALUE 'T'.
88 MR-UNMATCHED-GL VALUE 'G'.
88 MR-AUTO-CORRECTED VALUE 'A'.
05 WS-MR-ACCT-CATEGORY PIC X(4).
05 WS-MR-TYPE-CODE PIC X(3).
05 WS-MR-TXN-DEBIT PIC S9(13)V99 COMP-3.
05 WS-MR-TXN-CREDIT PIC S9(13)V99 COMP-3.
05 WS-MR-TXN-NET PIC S9(13)V99 COMP-3.
05 WS-MR-TXN-COUNT PIC 9(7).
05 WS-MR-GL-DEBIT PIC S9(13)V99 COMP-3.
05 WS-MR-GL-CREDIT PIC S9(13)V99 COMP-3.
05 WS-MR-GL-NET PIC S9(13)V99 COMP-3.
05 WS-MR-GL-COUNT PIC 9(7).
05 WS-MR-VARIANCE PIC S9(13)V99 COMP-3.
05 FILLER PIC X(83).
*================================================================*
* Exception report lines *
*================================================================*
01 WS-EXC-HEADER-1.
05 FILLER PIC X(1) VALUE '1'.
05 FILLER PIC X(20) VALUE SPACES.
05 FILLER PIC X(50)
VALUE 'HEARTLAND COMMUNITY BANK'.
05 FILLER PIC X(40) VALUE SPACES.
05 FILLER PIC X(6) VALUE 'PAGE: '.
05 WS-EXH-PAGE PIC Z(4)9.
05 FILLER PIC X(11) VALUE SPACES.
01 WS-EXC-HEADER-2.
05 FILLER PIC X(1) VALUE ' '.
05 FILLER PIC X(20) VALUE SPACES.
05 FILLER PIC X(50)
VALUE 'DAILY RECONCILIATION EXCEPTION REPORT'.
05 FILLER PIC X(62) VALUE SPACES.
01 WS-EXC-HEADER-3.
05 FILLER PIC X(1) VALUE ' '.
05 FILLER PIC X(20) VALUE SPACES.
05 FILLER PIC X(14) VALUE 'Report Date: '.
05 WS-EXH-DATE PIC X(10).
05 FILLER PIC X(88) VALUE SPACES.
01 WS-EXC-COL-HDR.
05 FILLER PIC X(1) VALUE '0'.
05 FILLER PIC X(2) VALUE SPACES.
05 FILLER PIC X(8) VALUE 'CATEGORY'.
05 FILLER PIC X(2) VALUE SPACES.
05 FILLER PIC X(6) VALUE 'TYPE'.
05 FILLER PIC X(2) VALUE SPACES.
05 FILLER PIC X(10) VALUE 'STATUS'.
05 FILLER PIC X(2) VALUE SPACES.
05 FILLER PIC X(18) VALUE ' TXN AMOUNT'.
05 FILLER PIC X(2) VALUE SPACES.
05 FILLER PIC X(18) VALUE ' GL AMOUNT'.
05 FILLER PIC X(2) VALUE SPACES.
05 FILLER PIC X(18) VALUE ' VARIANCE'.
05 FILLER PIC X(2) VALUE SPACES.
05 FILLER PIC X(10) VALUE 'ACTION'.
05 FILLER PIC X(30) VALUE SPACES.
01 WS-EXC-DETAIL-LINE.
05 FILLER PIC X(1) VALUE ' '.
05 FILLER PIC X(2) VALUE SPACES.
05 WS-EXD-CAT PIC X(4).
05 FILLER PIC X(6) VALUE SPACES.
05 WS-EXD-TYPE PIC X(3).
05 FILLER PIC X(5) VALUE SPACES.
05 WS-EXD-STATUS PIC X(10).
05 FILLER PIC X(2) VALUE SPACES.
05 WS-EXD-TXN-AMT PIC $$$,$$$, MATH1 $,$$9.99-.
05 FILLER PIC X(2) VALUE SPACES.
05 WS-EXD-GL-AMT PIC $$$, MATH3 $,$$$,$$9.99-.
05 FILLER PIC X(2) VALUE SPACES.
05 WS-EXD-VARIANCE PIC $$$,$$$, MATH6 $,$$9.99-.
05 FILLER PIC X(2) VALUE SPACES.
05 WS-EXD-ACTION PIC X(10).
05 FILLER PIC X(24) VALUE SPACES.
01 WS-EXC-TOTAL-LINE.
05 FILLER PIC X(1) VALUE '0'.
05 FILLER PIC X(2) VALUE SPACES.
05 WS-EXT-LABEL PIC X(30).
05 FILLER PIC X(2) VALUE SPACES.
05 WS-EXT-VALUE PIC $$$, MATH8 $,$$$,$$$,$$9.99-.
05 FILLER PIC X(74) VALUE SPACES.
01 WS-EXC-SEPARATOR.
05 FILLER PIC X(1) VALUE ' '.
05 FILLER PIC X(2) VALUE SPACES.
05 FILLER PIC X(120) VALUE ALL '-'.
05 FILLER PIC X(10) VALUE SPACES.
*================================================================*
* Report control *
*================================================================*
01 WS-RPT-PAGE-COUNT PIC 9(5) VALUE ZEROS.
01 WS-RPT-LINE-COUNT PIC 99 VALUE 99.
01 WS-RPT-LINES-PER-PAGE PIC 99 VALUE 55.
*================================================================*
* Work fields *
*================================================================*
01 WS-ABS-VARIANCE PIC S9(13)V99 VALUE ZEROS.
01 WS-SYS-DATE PIC 9(8).
01 WS-REPORT-DATE PIC X(10).
01 WS-OUT-OF-BALANCE PIC X VALUE 'N'.
88 DAY-OUT-OF-BALANCE VALUE 'Y'.
PROCEDURE DIVISION.
0000-MAIN-CONTROL.
PERFORM 1000-INITIALIZE
PERFORM 2000-RECONCILE
PERFORM 3000-PROOF-OF-RECONCILIATION
PERFORM 4000-PRINT-SUMMARY
PERFORM 9000-WRAP-UP
STOP RUN.
*================================================================*
* 1000-INITIALIZE: Open files, initialize fields, print *
* report header. *
*================================================================*
1000-INITIALIZE.
OPEN INPUT TXN-DETAIL-FILE
OPEN INPUT GL-SUMMARY-FILE
OPEN OUTPUT MATCHED-FILE
OPEN OUTPUT UNMATCHED-FILE
OPEN OUTPUT EXCEPTION-RPT
IF WS-TXN-FS NOT = '00'
DISPLAY 'ERROR: Cannot open transaction file. '
'Status: ' WS-TXN-FS
MOVE 16 TO RETURN-CODE
STOP RUN
END-IF
IF WS-GL-FS NOT = '00'
DISPLAY 'ERROR: Cannot open GL summary file. '
'Status: ' WS-GL-FS
MOVE 16 TO RETURN-CODE
STOP RUN
END-IF
ACCEPT WS-SYS-DATE FROM DATE YYYYMMDD
STRING WS-SYS-DATE(1:4) '-'
WS-SYS-DATE(5:2) '-'
WS-SYS-DATE(7:2)
DELIMITED SIZE INTO WS-REPORT-DATE
DISPLAY '============================================='
DISPLAY ' RECONMCH - Daily Reconciliation'
DISPLAY ' Date: ' WS-REPORT-DATE
DISPLAY '============================================='
.
*================================================================*
* 2000-RECONCILE: Main matching logic. Uses a merge-match *
* algorithm on two sorted files. Both files are sorted by *
* account category and transaction type. *
* *
* Algorithm: *
* 1. Read one record from each file (priming reads). *
* 2. Compare keys: *
* - If TXN key = GL key: accumulate TXN group, match. *
* - If TXN key < GL key: TXN has no GL match. *
* - If TXN key > GL key: GL has no TXN match. *
* 3. Repeat until both files are exhausted. *
*================================================================*
2000-RECONCILE.
* Priming reads
PERFORM 2010-READ-TXN-DETAIL
PERFORM 2020-READ-GL-SUMMARY
* Main matching loop
PERFORM UNTIL TXN-AT-END AND GL-AT-END
* Build TXN match key
IF NOT TXN-AT-END
MOVE WS-TXN-ACCT-CATEGORY TO WS-TXN-KEY-CAT
MOVE WS-TXN-TYPE-CODE TO WS-TXN-KEY-TYPE
END-IF
* Build GL match key
IF NOT GL-AT-END
MOVE WS-GL-ACCT-CATEGORY TO WS-GL-KEY-CAT
MOVE WS-GL-TYPE-CODE TO WS-GL-KEY-TYPE
END-IF
EVALUATE TRUE
* Both files exhausted
WHEN TXN-AT-END AND GL-AT-END
CONTINUE
* TXN file exhausted: remaining GL records unmatched
WHEN TXN-AT-END
PERFORM 2300-GL-NO-MATCH
PERFORM 2020-READ-GL-SUMMARY
* GL file exhausted: remaining TXN records unmatched
WHEN GL-AT-END
PERFORM 2400-ACCUMULATE-TXN-GROUP
PERFORM 2200-TXN-NO-MATCH
* Keys match: accumulate TXN group and compare
WHEN WS-TXN-MATCH-KEY = WS-GL-MATCH-KEY
PERFORM 2400-ACCUMULATE-TXN-GROUP
PERFORM 2100-COMPARE-MATCH
PERFORM 2020-READ-GL-SUMMARY
* TXN key is lower: TXN group has no GL entry
WHEN WS-TXN-MATCH-KEY < WS-GL-MATCH-KEY
PERFORM 2400-ACCUMULATE-TXN-GROUP
PERFORM 2200-TXN-NO-MATCH
* GL key is lower: GL entry has no TXN detail
WHEN WS-TXN-MATCH-KEY > WS-GL-MATCH-KEY
PERFORM 2300-GL-NO-MATCH
PERFORM 2020-READ-GL-SUMMARY
END-EVALUATE
END-PERFORM
.
*================================================================*
* 2010-READ-TXN-DETAIL: Read next transaction detail record. *
*================================================================*
2010-READ-TXN-DETAIL.
READ TXN-DETAIL-FILE INTO WS-TXN-DETAIL-REC
AT END
MOVE 'Y' TO WS-TXN-EOF
NOT AT END
ADD 1 TO WS-TXN-RECORDS-READ
END-READ
.
*================================================================*
* 2020-READ-GL-SUMMARY: Read next GL summary record. *
*================================================================*
2020-READ-GL-SUMMARY.
READ GL-SUMMARY-FILE INTO WS-GL-SUMMARY-REC
AT END
MOVE 'Y' TO WS-GL-EOF
NOT AT END
ADD 1 TO WS-GL-RECORDS-READ
ADD WS-GL-DEBIT-TOTAL TO WS-GT-GL-DEBITS
ADD WS-GL-CREDIT-TOTAL TO WS-GT-GL-CREDITS
ADD WS-GL-NET-AMOUNT TO WS-GT-GL-NET
ADD WS-GL-ENTRY-COUNT TO WS-GT-GL-COUNT
END-READ
.
*================================================================*
* 2400-ACCUMULATE-TXN-GROUP: Read all transaction detail *
* records with the same category/type key and accumulate *
* their totals. This builds the aggregated TXN total to *
* compare against the GL summary record. *
*================================================================*
2400-ACCUMULATE-TXN-GROUP.
MOVE ZEROS TO WS-GROUP-ACCUM
MOVE WS-TXN-ACCT-CATEGORY TO WS-TXN-KEY-CAT
MOVE WS-TXN-TYPE-CODE TO WS-TXN-KEY-TYPE
PERFORM UNTIL TXN-AT-END
OR WS-TXN-ACCT-CATEGORY NOT = WS-TXN-KEY-CAT
OR WS-TXN-TYPE-CODE NOT = WS-TXN-KEY-TYPE
IF TXN-DEBIT
ADD WS-TXN-AMOUNT TO WS-GRP-DEBIT-TOTAL
ELSE
ADD WS-TXN-AMOUNT TO WS-GRP-CREDIT-TOTAL
END-IF
ADD 1 TO WS-GRP-ENTRY-COUNT
ADD WS-TXN-AMOUNT TO WS-GT-TXN-NET
IF TXN-DEBIT
ADD WS-TXN-AMOUNT TO WS-GT-TXN-DEBITS
ELSE
ADD WS-TXN-AMOUNT TO WS-GT-TXN-CREDITS
END-IF
ADD 1 TO WS-GT-TXN-COUNT
PERFORM 2010-READ-TXN-DETAIL
END-PERFORM
COMPUTE WS-GRP-NET-AMOUNT =
WS-GRP-DEBIT-TOTAL - WS-GRP-CREDIT-TOTAL
.
*================================================================*
* 2100-COMPARE-MATCH: Compare accumulated TXN group totals *
* against the GL summary record. Determine if they match *
* within tolerance. *
*================================================================*
2100-COMPARE-MATCH.
COMPUTE WS-VAR-NET =
WS-GRP-NET-AMOUNT - WS-GL-NET-AMOUNT
COMPUTE WS-VAR-DEBIT =
WS-GRP-DEBIT-TOTAL - WS-GL-DEBIT-TOTAL
COMPUTE WS-VAR-CREDIT =
WS-GRP-CREDIT-TOTAL - WS-GL-CREDIT-TOTAL
COMPUTE WS-VAR-COUNT =
WS-GRP-ENTRY-COUNT - WS-GL-ENTRY-COUNT
* Compute absolute value of net variance
IF WS-VAR-NET < ZEROS
COMPUTE WS-ABS-VARIANCE =
WS-VAR-NET * -1
ELSE
MOVE WS-VAR-NET TO WS-ABS-VARIANCE
END-IF
EVALUATE TRUE
* Exact match
WHEN WS-ABS-VARIANCE = ZEROS
PERFORM 2110-WRITE-MATCHED
ADD 1 TO WS-MATCHED-GROUPS
ADD WS-GRP-NET-AMOUNT
TO WS-GT-MATCHED-AMT
* Within tolerance - auto-correct
WHEN WS-ABS-VARIANCE <= WS-MATCH-TOLERANCE
PERFORM 2120-AUTO-CORRECT
ADD 1 TO WS-MATCHED-GROUPS
ADD 1 TO WS-AUTO-CORRECTIONS
ADD WS-GRP-NET-AMOUNT
TO WS-GT-MATCHED-AMT
* Out of tolerance - exception
WHEN OTHER
PERFORM 2130-WRITE-EXCEPTION
ADD 1 TO WS-EXCEPTIONS
ADD WS-VAR-NET
TO WS-GT-UNMATCHED-AMT
END-EVALUATE
.
*================================================================*
* 2110-WRITE-MATCHED: Write a matched result record. *
*================================================================*
2110-WRITE-MATCHED.
INITIALIZE WS-MATCH-RESULT-REC
MOVE 'M' TO WS-MR-RESULT-CODE
MOVE WS-TXN-KEY-CAT TO WS-MR-ACCT-CATEGORY
MOVE WS-TXN-KEY-TYPE TO WS-MR-TYPE-CODE
MOVE WS-GRP-DEBIT-TOTAL TO WS-MR-TXN-DEBIT
MOVE WS-GRP-CREDIT-TOTAL TO WS-MR-TXN-CREDIT
MOVE WS-GRP-NET-AMOUNT TO WS-MR-TXN-NET
MOVE WS-GRP-ENTRY-COUNT TO WS-MR-TXN-COUNT
MOVE WS-GL-DEBIT-TOTAL TO WS-MR-GL-DEBIT
MOVE WS-GL-CREDIT-TOTAL TO WS-MR-GL-CREDIT
MOVE WS-GL-NET-AMOUNT TO WS-MR-GL-NET
MOVE WS-GL-ENTRY-COUNT TO WS-MR-GL-COUNT
MOVE ZEROS TO WS-MR-VARIANCE
WRITE MATCHED-OUTPUT FROM WS-MATCH-RESULT-REC
.
*================================================================*
* 2120-AUTO-CORRECT: Rounding variance within tolerance. *
* Write as matched with auto-correction notation. *
*================================================================*
2120-AUTO-CORRECT.
INITIALIZE WS-MATCH-RESULT-REC
MOVE 'A' TO WS-MR-RESULT-CODE
MOVE WS-TXN-KEY-CAT TO WS-MR-ACCT-CATEGORY
MOVE WS-TXN-KEY-TYPE TO WS-MR-TYPE-CODE
MOVE WS-GRP-DEBIT-TOTAL TO WS-MR-TXN-DEBIT
MOVE WS-GRP-CREDIT-TOTAL TO WS-MR-TXN-CREDIT
MOVE WS-GRP-NET-AMOUNT TO WS-MR-TXN-NET
MOVE WS-GRP-ENTRY-COUNT TO WS-MR-TXN-COUNT
MOVE WS-GL-DEBIT-TOTAL TO WS-MR-GL-DEBIT
MOVE WS-GL-CREDIT-TOTAL TO WS-MR-GL-CREDIT
MOVE WS-GL-NET-AMOUNT TO WS-MR-GL-NET
MOVE WS-GL-ENTRY-COUNT TO WS-MR-GL-COUNT
MOVE WS-VAR-NET TO WS-MR-VARIANCE
WRITE MATCHED-OUTPUT FROM WS-MATCH-RESULT-REC
* Log auto-correction on exception report
PERFORM 5100-PRINT-PAGE-HEADER-CHECK
MOVE WS-TXN-KEY-CAT TO WS-EXD-CAT
MOVE WS-TXN-KEY-TYPE TO WS-EXD-TYPE
MOVE 'AUTO-CORR ' TO WS-EXD-STATUS
MOVE WS-GRP-NET-AMOUNT TO WS-EXD-TXN-AMT
MOVE WS-GL-NET-AMOUNT TO WS-EXD-GL-AMT
MOVE WS-VAR-NET TO WS-EXD-VARIANCE
MOVE 'ADJUSTED ' TO WS-EXD-ACTION
WRITE EXCEPTION-RPT-REC FROM WS-EXC-DETAIL-LINE
ADD 1 TO WS-RPT-LINE-COUNT
.
*================================================================*
* 2130-WRITE-EXCEPTION: Variance exceeds tolerance. Write to *
* unmatched file and exception report. Determine action based *
* on severity. *
*================================================================*
2130-WRITE-EXCEPTION.
INITIALIZE WS-MATCH-RESULT-REC
MOVE 'T' TO WS-MR-RESULT-CODE
MOVE WS-TXN-KEY-CAT TO WS-MR-ACCT-CATEGORY
MOVE WS-TXN-KEY-TYPE TO WS-MR-TYPE-CODE
MOVE WS-GRP-DEBIT-TOTAL TO WS-MR-TXN-DEBIT
MOVE WS-GRP-CREDIT-TOTAL TO WS-MR-TXN-CREDIT
MOVE WS-GRP-NET-AMOUNT TO WS-MR-TXN-NET
MOVE WS-GRP-ENTRY-COUNT TO WS-MR-TXN-COUNT
MOVE WS-GL-DEBIT-TOTAL TO WS-MR-GL-DEBIT
MOVE WS-GL-CREDIT-TOTAL TO WS-MR-GL-CREDIT
MOVE WS-GL-NET-AMOUNT TO WS-MR-GL-NET
MOVE WS-GL-ENTRY-COUNT TO WS-MR-GL-COUNT
MOVE WS-VAR-NET TO WS-MR-VARIANCE
WRITE UNMATCHED-OUTPUT FROM WS-MATCH-RESULT-REC
* Print exception with appropriate action
PERFORM 5100-PRINT-PAGE-HEADER-CHECK
MOVE WS-TXN-KEY-CAT TO WS-EXD-CAT
MOVE WS-TXN-KEY-TYPE TO WS-EXD-TYPE
MOVE 'VARIANCE ' TO WS-EXD-STATUS
MOVE WS-GRP-NET-AMOUNT TO WS-EXD-TXN-AMT
MOVE WS-GL-NET-AMOUNT TO WS-EXD-GL-AMT
MOVE WS-VAR-NET TO WS-EXD-VARIANCE
* Determine action based on variance magnitude
IF WS-ABS-VARIANCE > WS-SUPERVISOR-THRESHOLD
MOVE 'SUPERVISOR' TO WS-EXD-ACTION
ADD 1 TO WS-MANUAL-REVIEWS
ELSE IF WS-ABS-VARIANCE > WS-REVIEW-THRESHOLD
MOVE 'REVIEW ' TO WS-EXD-ACTION
ADD 1 TO WS-MANUAL-REVIEWS
ELSE
MOVE 'LOG ONLY ' TO WS-EXD-ACTION
END-IF
WRITE EXCEPTION-RPT-REC FROM WS-EXC-DETAIL-LINE
ADD 1 TO WS-RPT-LINE-COUNT
MOVE 'Y' TO WS-OUT-OF-BALANCE
.
*================================================================*
* 2200-TXN-NO-MATCH: Transaction group has no corresponding *
* GL entry. Write to unmatched file. *
*================================================================*
2200-TXN-NO-MATCH.
ADD 1 TO WS-UNMATCHED-TXN
ADD 1 TO WS-EXCEPTIONS
INITIALIZE WS-MATCH-RESULT-REC
MOVE 'T' TO WS-MR-RESULT-CODE
MOVE WS-TXN-KEY-CAT TO WS-MR-ACCT-CATEGORY
MOVE WS-TXN-KEY-TYPE TO WS-MR-TYPE-CODE
MOVE WS-GRP-DEBIT-TOTAL TO WS-MR-TXN-DEBIT
MOVE WS-GRP-CREDIT-TOTAL TO WS-MR-TXN-CREDIT
MOVE WS-GRP-NET-AMOUNT TO WS-MR-TXN-NET
MOVE WS-GRP-ENTRY-COUNT TO WS-MR-TXN-COUNT
MOVE ZEROS TO WS-MR-GL-DEBIT
MOVE ZEROS TO WS-MR-GL-CREDIT
MOVE ZEROS TO WS-MR-GL-NET
MOVE ZEROS TO WS-MR-GL-COUNT
MOVE WS-GRP-NET-AMOUNT TO WS-MR-VARIANCE
WRITE UNMATCHED-OUTPUT FROM WS-MATCH-RESULT-REC
ADD WS-GRP-NET-AMOUNT TO WS-GT-UNMATCHED-AMT
* Exception report
PERFORM 5100-PRINT-PAGE-HEADER-CHECK
MOVE WS-TXN-KEY-CAT TO WS-EXD-CAT
MOVE WS-TXN-KEY-TYPE TO WS-EXD-TYPE
MOVE 'NO GL ENT ' TO WS-EXD-STATUS
MOVE WS-GRP-NET-AMOUNT TO WS-EXD-TXN-AMT
MOVE ZEROS TO WS-EXD-GL-AMT
MOVE WS-GRP-NET-AMOUNT TO WS-EXD-VARIANCE
MOVE 'SUPERVISOR' TO WS-EXD-ACTION
ADD 1 TO WS-MANUAL-REVIEWS
WRITE EXCEPTION-RPT-REC FROM WS-EXC-DETAIL-LINE
ADD 1 TO WS-RPT-LINE-COUNT
MOVE 'Y' TO WS-OUT-OF-BALANCE
.
*================================================================*
* 2300-GL-NO-MATCH: GL entry has no corresponding transaction *
* detail. Write to unmatched file. *
*================================================================*
2300-GL-NO-MATCH.
ADD 1 TO WS-UNMATCHED-GL
ADD 1 TO WS-EXCEPTIONS
INITIALIZE WS-MATCH-RESULT-REC
MOVE 'G' TO WS-MR-RESULT-CODE
MOVE WS-GL-ACCT-CATEGORY TO WS-MR-ACCT-CATEGORY
MOVE WS-GL-TYPE-CODE TO WS-MR-TYPE-CODE
MOVE ZEROS TO WS-MR-TXN-DEBIT
MOVE ZEROS TO WS-MR-TXN-CREDIT
MOVE ZEROS TO WS-MR-TXN-NET
MOVE ZEROS TO WS-MR-TXN-COUNT
MOVE WS-GL-DEBIT-TOTAL TO WS-MR-GL-DEBIT
MOVE WS-GL-CREDIT-TOTAL TO WS-MR-GL-CREDIT
MOVE WS-GL-NET-AMOUNT TO WS-MR-GL-NET
MOVE WS-GL-ENTRY-COUNT TO WS-MR-GL-COUNT
COMPUTE WS-MR-VARIANCE =
ZEROS - WS-GL-NET-AMOUNT
WRITE UNMATCHED-OUTPUT FROM WS-MATCH-RESULT-REC
COMPUTE WS-ABS-VARIANCE =
WS-GL-NET-AMOUNT * -1
IF WS-GL-NET-AMOUNT > ZEROS
MOVE WS-GL-NET-AMOUNT TO WS-ABS-VARIANCE
END-IF
ADD WS-ABS-VARIANCE TO WS-GT-UNMATCHED-AMT
* Exception report
PERFORM 5100-PRINT-PAGE-HEADER-CHECK
MOVE WS-GL-ACCT-CATEGORY TO WS-EXD-CAT
MOVE WS-GL-TYPE-CODE TO WS-EXD-TYPE
MOVE 'NO TXN DET' TO WS-EXD-STATUS
MOVE ZEROS TO WS-EXD-TXN-AMT
MOVE WS-GL-NET-AMOUNT TO WS-EXD-GL-AMT
COMPUTE WS-EXD-VARIANCE =
ZEROS - WS-GL-NET-AMOUNT
MOVE 'SUPERVISOR' TO WS-EXD-ACTION
ADD 1 TO WS-MANUAL-REVIEWS
WRITE EXCEPTION-RPT-REC FROM WS-EXC-DETAIL-LINE
ADD 1 TO WS-RPT-LINE-COUNT
MOVE 'Y' TO WS-OUT-OF-BALANCE
.
*================================================================*
* 3000-PROOF-OF-RECONCILIATION: Verify that matched plus *
* unmatched equals the original total. This is the auditor's *
* proof that the reconciliation is complete. *
*================================================================*
3000-PROOF-OF-RECONCILIATION.
PERFORM 5100-PRINT-PAGE-HEADER-CHECK
WRITE EXCEPTION-RPT-REC FROM WS-EXC-SEPARATOR
INITIALIZE WS-EXC-DETAIL-LINE
MOVE ' ' TO WS-EXC-DETAIL-LINE(1:1)
MOVE 'PROOF OF RECONCILIATION'
TO WS-EXC-DETAIL-LINE(4:30)
WRITE EXCEPTION-RPT-REC FROM WS-EXC-DETAIL-LINE
WRITE EXCEPTION-RPT-REC FROM WS-EXC-SEPARATOR
* TXN totals
MOVE 'Total Transaction Debits: '
TO WS-EXT-LABEL
MOVE WS-GT-TXN-DEBITS TO WS-EXT-VALUE
WRITE EXCEPTION-RPT-REC FROM WS-EXC-TOTAL-LINE
ADD 1 TO WS-RPT-LINE-COUNT
MOVE 'Total Transaction Credits: '
TO WS-EXT-LABEL
MOVE WS-GT-TXN-CREDITS TO WS-EXT-VALUE
WRITE EXCEPTION-RPT-REC FROM WS-EXC-TOTAL-LINE
ADD 1 TO WS-RPT-LINE-COUNT
MOVE 'Transaction Net: '
TO WS-EXT-LABEL
MOVE WS-GT-TXN-NET TO WS-EXT-VALUE
WRITE EXCEPTION-RPT-REC FROM WS-EXC-TOTAL-LINE
ADD 1 TO WS-RPT-LINE-COUNT
WRITE EXCEPTION-RPT-REC FROM WS-EXC-SEPARATOR
* GL totals
MOVE 'Total GL Debits: '
TO WS-EXT-LABEL
MOVE WS-GT-GL-DEBITS TO WS-EXT-VALUE
WRITE EXCEPTION-RPT-REC FROM WS-EXC-TOTAL-LINE
ADD 1 TO WS-RPT-LINE-COUNT
MOVE 'Total GL Credits: '
TO WS-EXT-LABEL
MOVE WS-GT-GL-CREDITS TO WS-EXT-VALUE
WRITE EXCEPTION-RPT-REC FROM WS-EXC-TOTAL-LINE
ADD 1 TO WS-RPT-LINE-COUNT
MOVE 'GL Net: '
TO WS-EXT-LABEL
MOVE WS-GT-GL-NET TO WS-EXT-VALUE
WRITE EXCEPTION-RPT-REC FROM WS-EXC-TOTAL-LINE
ADD 1 TO WS-RPT-LINE-COUNT
WRITE EXCEPTION-RPT-REC FROM WS-EXC-SEPARATOR
* Reconciliation proof
MOVE 'Matched Amount: '
TO WS-EXT-LABEL
MOVE WS-GT-MATCHED-AMT TO WS-EXT-VALUE
WRITE EXCEPTION-RPT-REC FROM WS-EXC-TOTAL-LINE
ADD 1 TO WS-RPT-LINE-COUNT
MOVE 'Unmatched Amount: '
TO WS-EXT-LABEL
MOVE WS-GT-UNMATCHED-AMT TO WS-EXT-VALUE
WRITE EXCEPTION-RPT-REC FROM WS-EXC-TOTAL-LINE
ADD 1 TO WS-RPT-LINE-COUNT
WRITE EXCEPTION-RPT-REC FROM WS-EXC-SEPARATOR
* Overall balance check
IF DAY-OUT-OF-BALANCE
INITIALIZE WS-EXC-DETAIL-LINE
MOVE '0' TO WS-EXC-DETAIL-LINE(1:1)
MOVE '*** DAY IS OUT OF BALANCE ***'
TO WS-EXC-DETAIL-LINE(4:35)
MOVE 'IMMEDIATE REVIEW REQUIRED'
TO WS-EXC-DETAIL-LINE(40:30)
WRITE EXCEPTION-RPT-REC FROM WS-EXC-DETAIL-LINE
ELSE
INITIALIZE WS-EXC-DETAIL-LINE
MOVE '0' TO WS-EXC-DETAIL-LINE(1:1)
MOVE 'DAY IS IN BALANCE - RECONCILIATION COMPLETE'
TO WS-EXC-DETAIL-LINE(4:45)
WRITE EXCEPTION-RPT-REC FROM WS-EXC-DETAIL-LINE
END-IF
.
*================================================================*
* 4000-PRINT-SUMMARY: Print processing statistics on the *
* exception report. *
*================================================================*
4000-PRINT-SUMMARY.
WRITE EXCEPTION-RPT-REC FROM WS-EXC-SEPARATOR
INITIALIZE WS-EXC-DETAIL-LINE
MOVE '0' TO WS-EXC-DETAIL-LINE(1:1)
MOVE 'PROCESSING STATISTICS'
TO WS-EXC-DETAIL-LINE(4:25)
WRITE EXCEPTION-RPT-REC FROM WS-EXC-DETAIL-LINE
INITIALIZE WS-EXC-DETAIL-LINE
STRING ' TXN Records Read: '
WS-TXN-RECORDS-READ
DELIMITED SIZE INTO WS-EXC-DETAIL-LINE(2:50)
WRITE EXCEPTION-RPT-REC FROM WS-EXC-DETAIL-LINE
INITIALIZE WS-EXC-DETAIL-LINE
STRING ' GL Records Read: '
WS-GL-RECORDS-READ
DELIMITED SIZE INTO WS-EXC-DETAIL-LINE(2:50)
WRITE EXCEPTION-RPT-REC FROM WS-EXC-DETAIL-LINE
INITIALIZE WS-EXC-DETAIL-LINE
STRING ' Matched Groups: '
WS-MATCHED-GROUPS
DELIMITED SIZE INTO WS-EXC-DETAIL-LINE(2:50)
WRITE EXCEPTION-RPT-REC FROM WS-EXC-DETAIL-LINE
INITIALIZE WS-EXC-DETAIL-LINE
STRING ' Unmatched TXN Groups:'
WS-UNMATCHED-TXN
DELIMITED SIZE INTO WS-EXC-DETAIL-LINE(2:50)
WRITE EXCEPTION-RPT-REC FROM WS-EXC-DETAIL-LINE
INITIALIZE WS-EXC-DETAIL-LINE
STRING ' Unmatched GL Entries:'
WS-UNMATCHED-GL
DELIMITED SIZE INTO WS-EXC-DETAIL-LINE(2:50)
WRITE EXCEPTION-RPT-REC FROM WS-EXC-DETAIL-LINE
INITIALIZE WS-EXC-DETAIL-LINE
STRING ' Total Exceptions: '
WS-EXCEPTIONS
DELIMITED SIZE INTO WS-EXC-DETAIL-LINE(2:50)
WRITE EXCEPTION-RPT-REC FROM WS-EXC-DETAIL-LINE
INITIALIZE WS-EXC-DETAIL-LINE
STRING ' Auto-Corrections: '
WS-AUTO-CORRECTIONS
DELIMITED SIZE INTO WS-EXC-DETAIL-LINE(2:50)
WRITE EXCEPTION-RPT-REC FROM WS-EXC-DETAIL-LINE
INITIALIZE WS-EXC-DETAIL-LINE
STRING ' Manual Reviews: '
WS-MANUAL-REVIEWS
DELIMITED SIZE INTO WS-EXC-DETAIL-LINE(2:50)
WRITE EXCEPTION-RPT-REC FROM WS-EXC-DETAIL-LINE
.
*================================================================*
* 5100-PRINT-PAGE-HEADER-CHECK: Print header if new page. *
*================================================================*
5100-PRINT-PAGE-HEADER-CHECK.
IF WS-RPT-LINE-COUNT >= WS-RPT-LINES-PER-PAGE
ADD 1 TO WS-RPT-PAGE-COUNT
MOVE WS-RPT-PAGE-COUNT TO WS-EXH-PAGE
MOVE WS-REPORT-DATE TO WS-EXH-DATE
WRITE EXCEPTION-RPT-REC FROM WS-EXC-HEADER-1
WRITE EXCEPTION-RPT-REC FROM WS-EXC-HEADER-2
WRITE EXCEPTION-RPT-REC FROM WS-EXC-HEADER-3
WRITE EXCEPTION-RPT-REC FROM WS-EXC-COL-HDR
WRITE EXCEPTION-RPT-REC FROM WS-EXC-SEPARATOR
MOVE 6 TO WS-RPT-LINE-COUNT
END-IF
.
*================================================================*
* 9000-WRAP-UP: Close files, set return code, display summary. *
*================================================================*
9000-WRAP-UP.
CLOSE TXN-DETAIL-FILE
CLOSE GL-SUMMARY-FILE
CLOSE MATCHED-FILE
CLOSE UNMATCHED-FILE
CLOSE EXCEPTION-RPT
DISPLAY ' '
DISPLAY '============================================='
DISPLAY ' RECONMCH - RECONCILIATION COMPLETE'
DISPLAY ' TXN Records: '
WS-TXN-RECORDS-READ
DISPLAY ' GL Records: '
WS-GL-RECORDS-READ
DISPLAY ' Matched Groups: '
WS-MATCHED-GROUPS
DISPLAY ' Exceptions: '
WS-EXCEPTIONS
DISPLAY ' Auto-Corrections: '
WS-AUTO-CORRECTIONS
DISPLAY ' Manual Reviews: '
WS-MANUAL-REVIEWS
IF DAY-OUT-OF-BALANCE
DISPLAY ' *** OUT OF BALANCE ***'
DISPLAY '============================================='
MOVE 8 TO RETURN-CODE
ELSE
IF WS-EXCEPTIONS > ZEROS
DISPLAY ' In balance with exceptions.'
DISPLAY
'============================================='
MOVE 4 TO RETURN-CODE
ELSE
DISPLAY ' In balance - clean reconciliation.'
DISPLAY
'============================================='
MOVE 0 TO RETURN-CODE
END-IF
END-IF
.
Solution Walkthrough
The Merge-Match Algorithm
The reconciliation program uses a classic merge-match algorithm, the same pattern used in tape-era COBOL for matching two sorted files. The algorithm depends on both files being sorted by the same key (account category + transaction type).
The logic works as follows:
- Read one record from each file (priming reads).
- Compare the keys from the two files.
- If the keys are equal, the records potentially match -- accumulate the transaction detail group and compare totals.
- If the transaction key is less than the GL key, the transaction group has no corresponding GL entry (an exception).
- If the GL key is less than the transaction key, the GL entry has no corresponding transaction detail (an exception).
- Advance the file(s) as appropriate and repeat.
This algorithm makes a single pass through both files (O(n + m) complexity), making it highly efficient for large datasets. The key requirement is that both files must be sorted identically. If the sort order is wrong, the algorithm produces incorrect results without any obvious error.
Transaction Group Accumulation
A critical design element is that the transaction detail file contains individual transactions (one per record), while the GL summary file contains aggregated totals (one record per category/type combination). Before comparing, the program must accumulate all transaction records for a given category/type into group totals.
The accumulation loop in 2400-ACCUMULATE-TXN-GROUP reads forward through the transaction file until the key changes, summing debits and credits separately. This accumulated total is then compared against the single GL summary record for that key.
Exception Classification
The program classifies exceptions by severity, determining the appropriate workflow action:
| Variance Amount | Action | Workflow |
|---|---|---|
| $0.00 | None | Exact match |
| $0.01 or less | Auto-correct | Logged, no human action |
| $0.02 - $99.99 | Log only | Documented, no escalation |
| $100.00 - $9,999.99 | Review | Next-day review by accounting |
| $10,000.00+ | Supervisor | Immediate supervisor notification |
| No GL entry for TXN | Supervisor | Always escalated |
| No TXN for GL entry | Supervisor | Always escalated |
This tiered approach ensures that trivial discrepancies (common in systems with rounding differences across multiple applications) do not overwhelm the accounting team, while significant discrepancies receive prompt attention.
Proof of Reconciliation
The proof of reconciliation is the auditor's validation that the reconciliation is complete and accurate. It verifies the fundamental equation:
Matched Amount + Unmatched Amount = Total Transaction Amount
If this equation does not balance, the reconciliation program itself has a bug -- some transactions were lost, double-counted, or misclassified during the matching process. The proof section on the exception report allows auditors to verify this independently.
Return Code Strategy
The program uses a tiered return code strategy:
- RC=0: Clean reconciliation, no exceptions.
- RC=4: In balance overall, but exceptions exist that need review. This is the most common outcome in practice, as minor timing differences are normal.
- RC=8: Out of balance. This triggers the NOTIFY step in the job stream to alert operations.
- RC=16: File open error or other fatal condition. Not reached in normal operation.
The JCL uses COND=(4,LT,RCMATCH) for subsequent steps, which means they execute if RC is 0 or 4 (normal or warning) but not if RC is 8 or higher.
Automated vs. Manual Correction Workflow
The distinction between automated and manual corrections is essential to the bank's internal controls:
Automated corrections (rounding adjustments) are applied by the program itself. They are fully documented in the audit trail with the auto-correction flag. Internal audit reviews these periodically to ensure the auto-correction logic is not masking real problems.
Manual corrections are not applied by this program. Instead, the exception report identifies items requiring human review, and the accounting team investigates each one during the next business day. If a correction is needed, the accountant creates a journal entry through the bank's GL posting system, which will appear in the next day's reconciliation.
This separation of automated and manual processing is a fundamental internal control requirement. No batch program should have the authority to make arbitrary corrections to the general ledger. The auto-correction authority is strictly limited to the defined tolerance ($0.01).
Discussion Questions
-
The merge-match algorithm requires both input files to be sorted by the same key. What would happen if the transaction file were sorted by account category ascending but the GL file were sorted by account category descending? Would the program detect this, or would it silently produce wrong results? How would you add sort-order validation?
-
The auto-correction tolerance is set at $0.01. In a system processing millions of transactions daily, even a $0.01 rounding difference per transaction could accumulate into a significant amount. How would you monitor and control the cumulative auto-correction amount over time? At what point should auto-corrections trigger an investigation?
-
The exception report is a print file (SYSOUT class H). In a modern banking environment, exception data might need to flow into a case management system for tracking and resolution. How would you redesign the exception output to support both a print report and a structured data feed to a downstream system?
-
The program accumulates grand totals for the proof of reconciliation. If the transaction file contains billions of dollars in daily activity, the accumulator fields need to be large enough to hold the total. What is the maximum value that
PIC S9(15)V99can hold? At what point would this field overflow, and how should the program detect and handle accumulator overflow? -
Consider a scenario where a transaction was posted to the wrong account category. The transaction detail would show it in category A, but the GL entry would be in category B. How would this manifest in the reconciliation results? Category A would have an unmatched TXN group, and category B would have an unmatched GL entry. How would an investigator connect these two exceptions to identify the root cause?
-
The program produces three separate output files (matched, unmatched, exception report). Argue for or against consolidating these into a single output file with a status indicator. What are the trade-offs in terms of downstream processing, storage efficiency, and operational usability?