Case Study 2: Month-End Close Automation
Background
Precision Components International (PCI) is a mid-size manufacturing company headquartered in Grand Rapids, Michigan, producing precision-machined parts for the aerospace and automotive industries. PCI operates three manufacturing plants across the Midwest, maintains a central distribution warehouse, and runs a shared services center that handles corporate finance, human resources, and IT. Annual revenues are approximately $480 million, with 2,200 employees spread across five company codes in the General Ledger: PCI-01 (corporate), PCI-02 (aerospace plant), PCI-03 (automotive plant), PCI-04 (specialty components plant), and PCI-05 (distribution and logistics).
PCI's financial systems run on an IBM z/OS mainframe. The General Ledger, Accounts Payable, Accounts Receivable, Inventory, Fixed Assets, and Payroll systems are all COBOL-based, having been developed and extended over the past twenty-five years. The chart of accounts contains 3,400 active accounts, organized into a hierarchical structure: a four-digit natural account, a four-digit cost center, and a two-digit sub-account, prefixed by the four-character company code.
Each month, PCI's seven-person corporate accounting team performs a month-end closing process that transforms raw transactional data into the consolidated financial statements presented to the executive team and the board of directors. This process encompasses trial balance generation, adjusting journal entries, intercompany eliminations, multi-entity consolidation, and the production of financial statement packages.
Problem Statement
PCI's month-end close process has become the single largest pain point in the finance organization. The process takes an average of ten business days to complete, measured from the first business day after period end to the day the final consolidated financial statements are approved. During the most recent fiscal year, two months required twelve days, and one month required fourteen days due to a misposted intercompany transaction that was not detected until the consolidation step.
The root causes are systemic:
-
Manual trial balance preparation: The existing trial balance program produces a flat listing of all 3,400 accounts. The accounting team manually reviews this listing, identifies accounts requiring adjustment, and keys adjusting entries into the journal entry system one at a time. A typical month requires 85 to 120 adjusting entries, and each entry must be keyed, reviewed, approved, and posted before the adjusted trial balance can be regenerated.
-
Spreadsheet-based intercompany eliminations: PCI's five entities transact with each other regularly. The aerospace plant purchases raw materials through the distribution entity, corporate allocates shared service costs to all plants, and the plants sell finished goods to each other for secondary processing. Intercompany balances must net to zero in the consolidated financial statements. Currently, a senior accountant maintains a set of Excel spreadsheets that track intercompany balances and manually calculates the elimination entries. This process is error-prone: in the past fiscal year, four months had intercompany imbalances that required correction after the initial consolidation.
-
Sequential manual consolidation: After all adjusting entries and eliminations are posted, the accounting team manually consolidates the five entities by exporting data from each entity's trial balance into a master consolidation spreadsheet. Formulas in the spreadsheet sum the entity balances and apply eliminations. The spreadsheet has grown to contain over 15,000 formulas, and no one on the team fully understands all of them.
-
No automated reconciliation checkpoints: The existing process relies on the accounting team to manually verify that debits equal credits at each stage. On three occasions in the past year, a data entry error introduced an imbalance that was not caught until several steps later, requiring the team to backtrack and re-execute prior steps.
-
Report generation bottleneck: The final financial statement package -- income statement, balance sheet, cash flow statement, and supporting schedules -- is assembled manually in Microsoft Word using data copied from the consolidation spreadsheet. Formatting errors and transposition mistakes are common.
The CFO has mandated that the close cycle be reduced to three business days, with improved accuracy and a complete audit trail for every step. The IT team has been tasked with building an automated month-end close system using COBOL batch programs orchestrated by JCL.
System Design
The automated close system consists of six COBOL programs executed in sequence, with reconciliation checkpoints between each step. The programs communicate through sequential and indexed files, following the established batch processing patterns that PCI's operations team knows how to monitor and recover.
Close Process Flow
Step 1: MECTRBAL - Generate Unadjusted Trial Balance
|
[Checkpoint: Verify TB balances]
|
Step 2: MECADJEN - Generate and Post Adjusting Entries
|
[Checkpoint: Verify adjusted TB balances]
|
Step 3: MECICELM - Calculate and Post Intercompany Eliminations
|
[Checkpoint: Verify IC balances net to zero]
|
Step 4: MECCONSOL - Perform Multi-Entity Consolidation
|
[Checkpoint: Verify consolidated TB balances]
|
Step 5: MECFINST - Generate Financial Statements
|
Step 6: MECCLOSE - Close the Period and Roll Balances Forward
Each program sets a return code that determines whether the next step executes. A return code of zero means success. A return code of four means the step completed with warnings (such as accounts with unusual balances flagged for review). A return code of eight or higher means the step failed and the close process must halt for investigation.
Core Data Structures
All six programs share a common set of data structures. The chart of accounts, GL master file, and journal entry formats are consistent with the structures described in the earlier sections of this chapter. The close process introduces several additional structures specific to month-end processing.
The close control record governs the entire process:
01 CLOSE-CONTROL-RECORD.
05 CC-COMPANY-CODE PIC X(04).
05 CC-FISCAL-YEAR PIC 9(04).
05 CC-PERIOD PIC 9(02).
05 CC-CLOSE-STATUS PIC X(01).
88 CC-NOT-STARTED VALUE 'N'.
88 CC-IN-PROGRESS VALUE 'P'.
88 CC-COMPLETED VALUE 'C'.
88 CC-REVERSED VALUE 'R'.
05 CC-STEP-STATUSES.
10 CC-STEP-STATUS PIC X(01)
OCCURS 6 TIMES.
88 CC-STEP-PENDING VALUE 'P'.
88 CC-STEP-RUNNING VALUE 'R'.
88 CC-STEP-SUCCESS VALUE 'S'.
88 CC-STEP-WARNING VALUE 'W'.
88 CC-STEP-FAILED VALUE 'F'.
05 CC-STEP-TIMESTAMPS.
10 CC-STEP-TS PIC X(26)
OCCURS 6 TIMES.
05 CC-INITIATED-BY PIC X(08).
05 CC-INITIATED-DATE PIC 9(08).
05 CC-COMPLETED-DATE PIC 9(08).
05 CC-FILLER PIC X(100).
The trial balance work record accumulates balances for each account:
01 TB-WORK-RECORD.
05 TB-COMPANY-CODE PIC X(04).
05 TB-ACCOUNT-NUM PIC X(10).
05 TB-ACCOUNT-DESC PIC X(40).
05 TB-ACCOUNT-TYPE PIC X(01).
05 TB-NORMAL-BALANCE PIC X(01).
05 TB-BEG-BALANCE PIC S9(13)V99 COMP-3.
05 TB-PERIOD-DEBITS PIC S9(13)V99 COMP-3.
05 TB-PERIOD-CREDITS PIC S9(13)V99 COMP-3.
05 TB-ADJUSTMENTS PIC S9(13)V99 COMP-3.
05 TB-ADJUSTED-BALANCE PIC S9(13)V99 COMP-3.
05 TB-ELIMINATIONS PIC S9(13)V99 COMP-3.
05 TB-CONSOLIDATED-BAL PIC S9(13)V99 COMP-3.
05 TB-PRIOR-PERIOD-BAL PIC S9(13)V99 COMP-3.
05 TB-VARIANCE-AMT PIC S9(13)V99 COMP-3.
05 TB-VARIANCE-PCT PIC S9(05)V99 COMP-3.
05 TB-FLAG-UNUSUAL PIC X(01).
88 TB-NORMAL VALUE 'N'.
88 TB-UNUSUAL VALUE 'U'.
05 TB-FILLER PIC X(40).
The intercompany balance record tracks receivables and payables between entities:
01 IC-BALANCE-RECORD.
05 IC-FROM-COMPANY PIC X(04).
05 IC-TO-COMPANY PIC X(04).
05 IC-ACCOUNT-RECV PIC X(10).
05 IC-ACCOUNT-PAY PIC X(10).
05 IC-RECEIVABLE-BAL PIC S9(13)V99 COMP-3.
05 IC-PAYABLE-BAL PIC S9(13)V99 COMP-3.
05 IC-DIFFERENCE PIC S9(13)V99 COMP-3.
05 IC-ELIM-AMOUNT PIC S9(13)V99 COMP-3.
05 IC-STATUS PIC X(01).
88 IC-BALANCED VALUE 'B'.
88 IC-IMBALANCED VALUE 'I'.
88 IC-ELIMINATED VALUE 'E'.
05 IC-FILLER PIC X(50).
Step 1: Trial Balance Generation (MECTRBAL)
The trial balance program reads the GL master file sequentially and builds a trial balance for the specified period. For each account, it calculates the ending balance by applying the period's debit and credit activity to the beginning balance, then compares the result to the prior period to identify unusual variances.
IDENTIFICATION DIVISION.
PROGRAM-ID. MECTRBAL.
*================================================================*
* MONTH-END CLOSE - TRIAL BALANCE GENERATION *
* PRECISION COMPONENTS INTERNATIONAL *
* *
* READS GL MASTER, GENERATES UNADJUSTED TRIAL BALANCE, *
* FLAGS ACCOUNTS WITH UNUSUAL BALANCES FOR REVIEW. *
*================================================================*
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT GL-MASTER-FILE
ASSIGN TO GLMAST
ORGANIZATION IS INDEXED
ACCESS MODE IS SEQUENTIAL
RECORD KEY IS GL-FULL-KEY
FILE STATUS IS WS-GL-FS.
SELECT TB-OUTPUT-FILE
ASSIGN TO TBOUT
ORGANIZATION IS SEQUENTIAL
FILE STATUS IS WS-TB-FS.
SELECT PRIOR-TB-FILE
ASSIGN TO PRIORTB
ORGANIZATION IS INDEXED
ACCESS MODE IS RANDOM
RECORD KEY IS PTB-KEY
FILE STATUS IS WS-PTB-FS.
SELECT REPORT-FILE
ASSIGN TO TBRPT
ORGANIZATION IS SEQUENTIAL
FILE STATUS IS WS-RPT-FS.
DATA DIVISION.
FILE SECTION.
FD GL-MASTER-FILE
RECORD CONTAINS 600 CHARACTERS.
01 GL-MASTER-RECORD.
05 GL-FULL-KEY.
10 GL-COMPANY PIC X(04).
10 GL-ACCOUNT-NUM PIC X(10).
10 GL-FISCAL-YEAR PIC 9(04).
05 GL-DESCRIPTION PIC X(40).
05 GL-ACCOUNT-TYPE PIC X(01).
05 GL-NORMAL-BALANCE PIC X(01).
05 GL-CURRENCY-CODE PIC X(03).
05 GL-BEG-BALANCE PIC S9(13)V99 COMP-3.
05 GL-PERIOD-TABLE.
10 GL-PERIOD-ENTRY OCCURS 13 TIMES.
15 GL-PRD-DEBITS PIC S9(13)V99 COMP-3.
15 GL-PRD-CREDITS PIC S9(13)V99 COMP-3.
15 GL-PRD-NET PIC S9(13)V99 COMP-3.
15 GL-PRD-BUDGET PIC S9(13)V99 COMP-3.
05 GL-YTD-DEBITS PIC S9(13)V99 COMP-3.
05 GL-YTD-CREDITS PIC S9(13)V99 COMP-3.
05 GL-YTD-NET PIC S9(13)V99 COMP-3.
05 GL-END-BALANCE PIC S9(13)V99 COMP-3.
05 GL-LAST-POST-DATE PIC 9(08).
05 GL-LAST-POST-PERIOD PIC 9(02).
05 GL-ENTRY-COUNT-YTD PIC 9(06).
05 GL-FILLER PIC X(50).
* ... (additional FDs for TB-OUTPUT, PRIOR-TB, REPORT omitted
* for brevity -- structures match TB-WORK-RECORD above)
WORKING-STORAGE SECTION.
01 WS-FILE-STATUSES.
05 WS-GL-FS PIC XX.
05 WS-TB-FS PIC XX.
05 WS-PTB-FS PIC XX.
05 WS-RPT-FS PIC XX.
01 WS-PARM-PERIOD PIC 9(02).
01 WS-PARM-YEAR PIC 9(04).
01 WS-ACCUM-BALANCE PIC S9(15)V99 COMP-3.
01 WS-PRD-IDX PIC 9(02).
01 WS-VARIANCE-THRESHOLD PIC S9(05)V99
VALUE 20.00.
01 WS-MIN-VARIANCE-AMT PIC S9(13)V99
VALUE 5000.00.
01 WS-COUNTERS.
05 WS-ACCOUNTS-READ PIC 9(06) VALUE ZEROS.
05 WS-ACCOUNTS-WRITTEN PIC 9(06) VALUE ZEROS.
05 WS-ACCOUNTS-FLAGGED PIC 9(06) VALUE ZEROS.
05 WS-TOTAL-DEBITS PIC S9(15)V99
COMP-3 VALUE ZEROS.
05 WS-TOTAL-CREDITS PIC S9(15)V99
COMP-3 VALUE ZEROS.
01 WS-EOF-FLAG PIC X VALUE 'N'.
88 WS-EOF VALUE 'Y'.
PROCEDURE DIVISION.
*================================================================*
0000-MAIN-CONTROL.
*================================================================*
PERFORM 0100-INITIALIZE
PERFORM 1000-PROCESS-GL-RECORDS UNTIL WS-EOF
PERFORM 2000-VERIFY-BALANCE
PERFORM 9000-FINALIZE
STOP RUN
.
*================================================================*
1000-PROCESS-GL-RECORDS.
*================================================================*
READ GL-MASTER-FILE NEXT
AT END SET WS-EOF TO TRUE
END-READ
IF NOT WS-EOF
ADD 1 TO WS-ACCOUNTS-READ
* FILTER FOR REQUESTED PERIOD AND YEAR
IF GL-FISCAL-YEAR = WS-PARM-YEAR
PERFORM 1100-BUILD-TB-RECORD
PERFORM 1200-CHECK-VARIANCE
PERFORM 1300-WRITE-TB-RECORD
ADD 1 TO WS-ACCOUNTS-WRITTEN
END-IF
END-IF
.
*================================================================*
1100-BUILD-TB-RECORD.
*================================================================*
INITIALIZE TB-WORK-RECORD
MOVE GL-COMPANY TO TB-COMPANY-CODE
MOVE GL-ACCOUNT-NUM TO TB-ACCOUNT-NUM
MOVE GL-DESCRIPTION TO TB-ACCOUNT-DESC
MOVE GL-ACCOUNT-TYPE TO TB-ACCOUNT-TYPE
MOVE GL-NORMAL-BALANCE TO TB-NORMAL-BALANCE
MOVE GL-BEG-BALANCE TO TB-BEG-BALANCE
MOVE GL-PRD-DEBITS(WS-PARM-PERIOD)
TO TB-PERIOD-DEBITS
MOVE GL-PRD-CREDITS(WS-PARM-PERIOD)
TO TB-PERIOD-CREDITS
* CALCULATE ENDING BALANCE THROUGH CURRENT PERIOD
MOVE GL-BEG-BALANCE TO WS-ACCUM-BALANCE
PERFORM VARYING WS-PRD-IDX FROM 1 BY 1
UNTIL WS-PRD-IDX > WS-PARM-PERIOD
ADD GL-PRD-NET(WS-PRD-IDX)
TO WS-ACCUM-BALANCE
END-PERFORM
MOVE WS-ACCUM-BALANCE TO TB-ADJUSTED-BALANCE
* ACCUMULATE TOTALS FOR BALANCE VERIFICATION
ADD TB-PERIOD-DEBITS TO WS-TOTAL-DEBITS
ADD TB-PERIOD-CREDITS TO WS-TOTAL-CREDITS
SET TB-NORMAL TO TRUE
.
*================================================================*
1200-CHECK-VARIANCE.
*================================================================*
* COMPARE CURRENT BALANCE TO PRIOR PERIOD
* FLAG ACCOUNTS WITH VARIANCE > 20% AND > $5,000
MOVE TB-COMPANY-CODE TO PTB-COMPANY
MOVE TB-ACCOUNT-NUM TO PTB-ACCOUNT
READ PRIOR-TB-FILE
KEY IS PTB-KEY
INVALID KEY
MOVE ZEROS TO TB-PRIOR-PERIOD-BAL
END-READ
IF WS-PTB-FS = '00'
MOVE PTB-BALANCE TO TB-PRIOR-PERIOD-BAL
END-IF
IF TB-PRIOR-PERIOD-BAL NOT = ZEROS
COMPUTE TB-VARIANCE-AMT =
TB-ADJUSTED-BALANCE - TB-PRIOR-PERIOD-BAL
COMPUTE TB-VARIANCE-PCT =
(TB-VARIANCE-AMT / TB-PRIOR-PERIOD-BAL)
* 100
ELSE
MOVE TB-ADJUSTED-BALANCE TO TB-VARIANCE-AMT
MOVE ZEROS TO TB-VARIANCE-PCT
END-IF
IF (TB-VARIANCE-PCT > WS-VARIANCE-THRESHOLD
OR TB-VARIANCE-PCT < (WS-VARIANCE-THRESHOLD
* -1))
AND (TB-VARIANCE-AMT > WS-MIN-VARIANCE-AMT
OR TB-VARIANCE-AMT < (WS-MIN-VARIANCE-AMT
* -1))
SET TB-UNUSUAL TO TRUE
ADD 1 TO WS-ACCOUNTS-FLAGGED
END-IF
.
*================================================================*
2000-VERIFY-BALANCE.
*================================================================*
* THE FUNDAMENTAL CHECK: TOTAL DEBITS MUST EQUAL
* TOTAL CREDITS ACROSS ALL ACCOUNTS IN THE TRIAL BALANCE
IF WS-TOTAL-DEBITS NOT = WS-TOTAL-CREDITS
DISPLAY 'MECTRBAL: TRIAL BALANCE OUT OF BALANCE'
DISPLAY ' TOTAL DEBITS: ' WS-TOTAL-DEBITS
DISPLAY ' TOTAL CREDITS: ' WS-TOTAL-CREDITS
MOVE 8 TO RETURN-CODE
ELSE
IF WS-ACCOUNTS-FLAGGED > 0
DISPLAY 'MECTRBAL: ' WS-ACCOUNTS-FLAGGED
' ACCOUNTS FLAGGED FOR REVIEW'
MOVE 4 TO RETURN-CODE
ELSE
MOVE 0 TO RETURN-CODE
END-IF
END-IF
.
The variance detection logic compares each account's balance to the prior period using two thresholds: a percentage threshold (20%) and an absolute dollar threshold ($5,000). An account is flagged only when both thresholds are exceeded, which avoids flagging small accounts with large percentage swings (a $50 account that doubles to $100) and large accounts with insignificant percentage changes (a $10 million account that moves by $200). This dual-threshold approach was designed in collaboration with PCI's controller to reflect the materiality standards used in the external audit.
Step 2: Adjusting Entry Generation (MECADJEN)
The adjusting entry program automates the most common types of month-end adjustments. PCI's accounting team identified three categories of adjustments that follow predictable patterns and can be generated automatically: recurring entries (posted every month, such as straight-line depreciation and monthly insurance amortization), accrual calculations (computed from source data, such as payroll accruals based on days earned but unpaid), and reversal entries (automatic reversal of the prior month's accruals on the first day of the new period).
The program reads a schedule of recurring and calculated adjustments, generates the appropriate journal entries, validates them, and writes them to the journal entry file for posting by the existing GL posting program.
IDENTIFICATION DIVISION.
PROGRAM-ID. MECADJEN.
*================================================================*
* MONTH-END CLOSE - ADJUSTING ENTRY GENERATION *
* GENERATES RECURRING, ACCRUAL, AND REVERSAL ENTRIES *
*================================================================*
DATA DIVISION.
WORKING-STORAGE SECTION.
*---------------------------------------------------------------*
* ADJUSTMENT SCHEDULE RECORD *
* DEFINES EACH AUTOMATED ADJUSTING ENTRY *
*---------------------------------------------------------------*
01 ADJ-SCHEDULE-RECORD.
05 AS-ENTRY-ID PIC 9(06).
05 AS-COMPANY PIC X(04).
05 AS-TYPE PIC X(01).
88 AS-RECURRING VALUE 'R'.
88 AS-ACCRUAL VALUE 'A'.
88 AS-REVERSAL VALUE 'V'.
05 AS-DESCRIPTION PIC X(40).
05 AS-DEBIT-ACCOUNT PIC X(10).
05 AS-CREDIT-ACCOUNT PIC X(10).
05 AS-AMOUNT-TYPE PIC X(01).
88 AS-FIXED-AMOUNT VALUE 'F'.
88 AS-CALCULATED VALUE 'C'.
05 AS-FIXED-AMOUNT PIC S9(13)V99 COMP-3.
05 AS-CALC-SOURCE PIC X(08).
05 AS-CALC-METHOD PIC X(01).
88 AS-DAILY-PRORATE VALUE 'D'.
88 AS-PERCENTAGE VALUE 'P'.
88 AS-FORMULA VALUE 'X'.
05 AS-CALC-RATE PIC S9(05)V9(04) COMP-3.
05 AS-ACTIVE-FLAG PIC X(01).
88 AS-ACTIVE VALUE 'Y'.
05 AS-START-PERIOD PIC 9(02).
05 AS-END-PERIOD PIC 9(02).
05 AS-JOURNAL-CODE PIC X(03).
05 AS-LAST-RUN-PERIOD PIC 9(02).
05 AS-LAST-RUN-YEAR PIC 9(04).
05 AS-FILLER PIC X(40).
*---------------------------------------------------------------*
* GENERATED JOURNAL ENTRY WORK AREA *
*---------------------------------------------------------------*
01 WS-GEN-HEADER.
05 WS-GH-REC-TYPE PIC X(01) VALUE 'H'.
05 WS-GH-ENTRY-NUM PIC 9(10).
05 WS-GH-COMPANY PIC X(04).
05 WS-GH-JOURNAL-CODE PIC X(03).
05 WS-GH-ENTRY-DATE PIC 9(08).
05 WS-GH-PERIOD PIC 9(02).
05 WS-GH-FISCAL-YEAR PIC 9(04).
05 WS-GH-DESCRIPTION PIC X(40).
05 WS-GH-SOURCE-REF PIC X(20).
05 WS-GH-ENTRY-TYPE PIC X(01).
05 WS-GH-STATUS PIC X(01) VALUE 'A'.
05 WS-GH-LINE-COUNT PIC 9(04) VALUE 2.
05 WS-GH-TOTAL-DEBITS PIC S9(13)V99.
05 WS-GH-TOTAL-CREDITS PIC S9(13)V99.
05 WS-GH-ENTERED-BY PIC X(08) VALUE 'MECADJEN'.
05 WS-GH-APPROVED-BY PIC X(08) VALUE 'AUTOAPPV'.
05 WS-GH-FILLER PIC X(130).
01 WS-DAYS-IN-PERIOD PIC 9(02).
01 WS-DAYS-ACCRUED PIC 9(02).
01 WS-CALC-AMOUNT PIC S9(13)V99 COMP-3.
01 WS-ENTRY-COUNTER PIC 9(10) VALUE ZEROS.
PROCEDURE DIVISION.
*================================================================*
0000-MAIN-CONTROL.
*================================================================*
PERFORM 0100-INITIALIZE
PERFORM 1000-PROCESS-SCHEDULES UNTIL WS-EOF
PERFORM 9000-FINALIZE
STOP RUN
.
*================================================================*
1000-PROCESS-SCHEDULES.
*================================================================*
READ ADJ-SCHEDULE-FILE NEXT
AT END SET WS-EOF TO TRUE
END-READ
IF NOT WS-EOF
IF AS-ACTIVE
AND WS-PARM-PERIOD >= AS-START-PERIOD
AND WS-PARM-PERIOD <= AS-END-PERIOD
EVALUATE TRUE
WHEN AS-RECURRING
PERFORM 2000-GEN-RECURRING
WHEN AS-ACCRUAL
PERFORM 3000-GEN-ACCRUAL
WHEN AS-REVERSAL
PERFORM 4000-GEN-REVERSAL
END-EVALUATE
END-IF
END-IF
.
*================================================================*
2000-GEN-RECURRING.
*================================================================*
* RECURRING ENTRIES USE THE FIXED AMOUNT DIRECTLY.
* EXAMPLE: MONTHLY DEPRECIATION OF $47,250.00 FOR
* THE AEROSPACE PLANT'S CNC MACHINING EQUIPMENT.
IF AS-LAST-RUN-PERIOD = WS-PARM-PERIOD
AND AS-LAST-RUN-YEAR = WS-PARM-YEAR
DISPLAY 'MECADJEN: SKIP DUPLICATE - '
AS-ENTRY-ID
ELSE
MOVE AS-FIXED-AMOUNT TO WS-CALC-AMOUNT
PERFORM 5000-WRITE-JOURNAL-ENTRY
END-IF
.
*================================================================*
3000-GEN-ACCRUAL.
*================================================================*
* ACCRUALS ARE CALCULATED FROM SOURCE DATA.
* EXAMPLE: PAYROLL ACCRUAL -- DAILY PAYROLL COST
* PRORATED FOR DAYS EARNED BUT NOT YET PAID.
EVALUATE TRUE
WHEN AS-DAILY-PRORATE
PERFORM 3100-CALC-DAILY-PRORATE
WHEN AS-PERCENTAGE
PERFORM 3200-CALC-PERCENTAGE
WHEN OTHER
DISPLAY 'MECADJEN: UNKNOWN CALC METHOD '
AS-CALC-METHOD
MOVE 8 TO RETURN-CODE
END-EVALUATE
.
*================================================================*
3100-CALC-DAILY-PRORATE.
*================================================================*
* DAILY PRORATE: SOURCE AMOUNT * (DAYS / PERIOD DAYS)
* USED FOR PAYROLL ACCRUAL, INTEREST ACCRUAL
PERFORM 3150-GET-DAYS-IN-PERIOD
COMPUTE WS-CALC-AMOUNT ROUNDED =
WS-SOURCE-AMOUNT * AS-CALC-RATE
* (WS-DAYS-ACCRUED / WS-DAYS-IN-PERIOD)
IF WS-CALC-AMOUNT > ZEROS
PERFORM 5000-WRITE-JOURNAL-ENTRY
END-IF
.
*================================================================*
5000-WRITE-JOURNAL-ENTRY.
*================================================================*
* GENERATE A BALANCED TWO-LINE JOURNAL ENTRY
ADD 1 TO WS-ENTRY-COUNTER
MOVE WS-ENTRY-COUNTER TO WS-GH-ENTRY-NUM
MOVE AS-COMPANY TO WS-GH-COMPANY
MOVE AS-JOURNAL-CODE TO WS-GH-JOURNAL-CODE
MOVE WS-PERIOD-END-DATE TO WS-GH-ENTRY-DATE
MOVE WS-PARM-PERIOD TO WS-GH-PERIOD
MOVE WS-PARM-YEAR TO WS-GH-FISCAL-YEAR
MOVE AS-DESCRIPTION TO WS-GH-DESCRIPTION
STRING 'MEC-' AS-ENTRY-ID
DELIMITED BY SIZE
INTO WS-GH-SOURCE-REF
MOVE WS-CALC-AMOUNT TO WS-GH-TOTAL-DEBITS
MOVE WS-CALC-AMOUNT TO WS-GH-TOTAL-CREDITS
* WRITE HEADER
WRITE JE-OUTPUT-RECORD FROM WS-GEN-HEADER
* WRITE DEBIT LINE
INITIALIZE WS-GEN-LINE
MOVE 'L' TO WS-GL-REC-TYPE
MOVE WS-ENTRY-COUNTER TO WS-GL-ENTRY-NUM
MOVE 1 TO WS-GL-LINE-NUM
MOVE AS-DEBIT-ACCOUNT TO WS-GL-ACCOUNT
MOVE 'D' TO WS-GL-DC-IND
MOVE WS-CALC-AMOUNT TO WS-GL-AMOUNT
MOVE AS-DESCRIPTION TO WS-GL-DESCRIPTION
WRITE JE-OUTPUT-RECORD FROM WS-GEN-LINE
* WRITE CREDIT LINE
MOVE 2 TO WS-GL-LINE-NUM
MOVE AS-CREDIT-ACCOUNT TO WS-GL-ACCOUNT
MOVE 'C' TO WS-GL-DC-IND
WRITE JE-OUTPUT-RECORD FROM WS-GEN-LINE
ADD 1 TO WS-ENTRIES-GENERATED
.
The duplicate detection logic in paragraph 2000 prevents the same recurring entry from being generated twice if the close process is restarted. This is an essential safeguard: without it, rerunning the adjusting entry step after a failure in a later step would double-count every recurring adjustment. The schedule record's last-run-period and last-run-year fields serve as an idempotency key.
Step 3: Intercompany Elimination (MECICELM)
Intercompany elimination is where the previous spreadsheet-based process broke down most frequently. The COBOL program replaces the spreadsheets with a deterministic, auditable process.
PCI maintains an intercompany account mapping table that pairs each intercompany receivable account with its corresponding payable account in the counterparty entity. For example, when the distribution entity (PCI-05) sells materials to the aerospace plant (PCI-02), PCI-05 records a receivable and PCI-02 records a payable. At consolidation, both balances must be eliminated so the consolidated statements reflect only external transactions.
IDENTIFICATION DIVISION.
PROGRAM-ID. MECICELM.
*================================================================*
* MONTH-END CLOSE - INTERCOMPANY ELIMINATIONS *
* MATCHES IC BALANCES, GENERATES ELIMINATION ENTRIES, *
* REPORTS IMBALANCES FOR INVESTIGATION. *
*================================================================*
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-IC-MAP-RECORD.
05 WS-ICM-FROM-COMPANY PIC X(04).
05 WS-ICM-TO-COMPANY PIC X(04).
05 WS-ICM-RECV-ACCOUNT PIC X(10).
05 WS-ICM-PAY-ACCOUNT PIC X(10).
05 WS-ICM-ELIM-ACCOUNT PIC X(10).
05 WS-ICM-DESCRIPTION PIC X(40).
01 WS-TOLERANCE-AMT PIC S9(13)V99
VALUE 0.05.
01 WS-IC-DIFFERENCE PIC S9(13)V99 COMP-3.
01 WS-ABS-DIFFERENCE PIC S9(13)V99 COMP-3.
01 WS-IC-COUNTERS.
05 WS-PAIRS-PROCESSED PIC 9(04) VALUE ZEROS.
05 WS-PAIRS-BALANCED PIC 9(04) VALUE ZEROS.
05 WS-PAIRS-WITHIN-TOL PIC 9(04) VALUE ZEROS.
05 WS-PAIRS-IMBALANCED PIC 9(04) VALUE ZEROS.
05 WS-ELIM-ENTRIES-GEN PIC 9(04) VALUE ZEROS.
PROCEDURE DIVISION.
*================================================================*
1000-PROCESS-IC-PAIR.
*================================================================*
* FOR EACH INTERCOMPANY PAIR, READ BOTH BALANCES
* FROM THE TRIAL BALANCE AND COMPARE.
PERFORM 1100-GET-RECEIVABLE-BALANCE
PERFORM 1200-GET-PAYABLE-BALANCE
ADD 1 TO WS-PAIRS-PROCESSED
* THE RECEIVABLE IN ONE ENTITY SHOULD EQUAL
* THE PAYABLE IN THE COUNTERPARTY ENTITY
COMPUTE WS-IC-DIFFERENCE =
WS-RECV-BALANCE - WS-PAY-BALANCE
* USE ABSOLUTE VALUE FOR TOLERANCE COMPARISON
IF WS-IC-DIFFERENCE < ZEROS
COMPUTE WS-ABS-DIFFERENCE =
WS-IC-DIFFERENCE * -1
ELSE
MOVE WS-IC-DIFFERENCE TO WS-ABS-DIFFERENCE
END-IF
EVALUATE TRUE
WHEN WS-IC-DIFFERENCE = ZEROS
ADD 1 TO WS-PAIRS-BALANCED
PERFORM 2000-GENERATE-ELIMINATION
WHEN WS-ABS-DIFFERENCE <= WS-TOLERANCE-AMT
ADD 1 TO WS-PAIRS-WITHIN-TOL
DISPLAY 'MECICELM: IC PAIR '
WS-ICM-FROM-COMPANY '/'
WS-ICM-TO-COMPANY
' WITHIN TOLERANCE: '
WS-IC-DIFFERENCE
PERFORM 2000-GENERATE-ELIMINATION
WHEN OTHER
ADD 1 TO WS-PAIRS-IMBALANCED
PERFORM 3000-REPORT-IMBALANCE
END-EVALUATE
.
*================================================================*
2000-GENERATE-ELIMINATION.
*================================================================*
* GENERATE A JOURNAL ENTRY THAT ELIMINATES THE
* INTERCOMPANY BALANCES:
* DR INTERCOMPANY PAYABLE (ELIMINATE THE LIABILITY)
* CR INTERCOMPANY RECEIVABLE (ELIMINATE THE ASSET)
*
* ENTRIES ARE POSTED TO THE ELIMINATION COMPANY (PCI-99)
ADD 1 TO WS-ELIM-ENTRIES-GEN
INITIALIZE WS-ELIM-HEADER
MOVE 'H' TO WS-EH-REC-TYPE
MOVE WS-ELIM-COUNTER TO WS-EH-ENTRY-NUM
MOVE 'CI99' TO WS-EH-COMPANY
MOVE 'ICE' TO WS-EH-JOURNAL-CODE
MOVE WS-PERIOD-END-DT TO WS-EH-ENTRY-DATE
MOVE WS-PARM-PERIOD TO WS-EH-PERIOD
MOVE WS-PARM-YEAR TO WS-EH-FISCAL-YEAR
STRING 'IC ELIM '
WS-ICM-FROM-COMPANY '/'
WS-ICM-TO-COMPANY
DELIMITED BY SIZE
INTO WS-EH-DESCRIPTION
MOVE WS-RECV-BALANCE TO WS-EH-TOTAL-DEBITS
MOVE WS-RECV-BALANCE TO WS-EH-TOTAL-CREDITS
MOVE 'MECICELN' TO WS-EH-ENTERED-BY
MOVE 'AUTOAPPV' TO WS-EH-APPROVED-BY
WRITE ELIM-OUTPUT-RECORD FROM WS-ELIM-HEADER
* DEBIT: ELIMINATE THE PAYABLE
INITIALIZE WS-ELIM-LINE
MOVE 'L' TO WS-EL-REC-TYPE
MOVE WS-ELIM-COUNTER TO WS-EL-ENTRY-NUM
MOVE 1 TO WS-EL-LINE-NUM
MOVE WS-ICM-PAY-ACCOUNT
TO WS-EL-ACCOUNT
MOVE 'D' TO WS-EL-DC-IND
MOVE WS-PAY-BALANCE TO WS-EL-AMOUNT
WRITE ELIM-OUTPUT-RECORD FROM WS-ELIM-LINE
* CREDIT: ELIMINATE THE RECEIVABLE
MOVE 2 TO WS-EL-LINE-NUM
MOVE WS-ICM-RECV-ACCOUNT
TO WS-EL-ACCOUNT
MOVE 'C' TO WS-EL-DC-IND
MOVE WS-RECV-BALANCE TO WS-EL-AMOUNT
WRITE ELIM-OUTPUT-RECORD FROM WS-ELIM-LINE
.
*================================================================*
3000-REPORT-IMBALANCE.
*================================================================*
DISPLAY 'MECICELM: *** IC IMBALANCE ***'
DISPLAY ' FROM: ' WS-ICM-FROM-COMPANY
' RECV ACCT: ' WS-ICM-RECV-ACCOUNT
' BAL: ' WS-RECV-BALANCE
DISPLAY ' TO: ' WS-ICM-TO-COMPANY
' PAY ACCT: ' WS-ICM-PAY-ACCOUNT
' BAL: ' WS-PAY-BALANCE
DISPLAY ' DIFFERENCE: ' WS-IC-DIFFERENCE
PERFORM 3100-WRITE-IMBALANCE-REPORT
.
*================================================================*
8000-SET-FINAL-RC.
*================================================================*
IF WS-PAIRS-IMBALANCED > 0
DISPLAY 'MECICELM: ' WS-PAIRS-IMBALANCED
' IC PAIRS IMBALANCED - REVIEW REQUIRED'
MOVE 8 TO RETURN-CODE
ELSE
DISPLAY 'MECICELM: ALL ' WS-PAIRS-PROCESSED
' IC PAIRS BALANCED'
MOVE 0 TO RETURN-CODE
END-IF
.
The tolerance of $0.05 accommodates penny rounding differences that occur when intercompany transactions involve calculated amounts. PCI's external auditors reviewed and approved this threshold as immaterial. When a pair falls within the tolerance but is not exactly zero, the program still generates the elimination entry using the receivable balance, and the rounding difference flows to a designated rounding variance account during consolidation.
When an intercompany pair exceeds the tolerance, the program sets a return code of eight, which halts the close process. The imbalance report gives the accounting team the specific entities, accounts, and amounts needed to investigate and resolve the discrepancy before the close can continue.
Step 4: Consolidation (MECCONSOL)
The consolidation program combines the trial balances of all five operating entities and the elimination entity (CI99) into a single consolidated trial balance. The logic is straightforward -- it sums balances for each natural account across all company codes -- but the program also performs several critical validations.
*================================================================*
1000-CONSOLIDATE-ACCOUNTS.
*================================================================*
* READ EACH ENTITY'S TRIAL BALANCE AND ACCUMULATE
* INTO THE CONSOLIDATED TRIAL BALANCE BY NATURAL ACCOUNT.
PERFORM VARYING WS-ENTITY-IDX FROM 1 BY 1
UNTIL WS-ENTITY-IDX > WS-ENTITY-COUNT
MOVE WS-ENTITY-CODE(WS-ENTITY-IDX)
TO WS-CURRENT-ENTITY
PERFORM 1100-READ-ENTITY-TB
PERFORM 1200-ACCUMULATE-BALANCES
END-PERFORM
PERFORM 2000-VERIFY-CONSOLIDATION
.
*================================================================*
1200-ACCUMULATE-BALANCES.
*================================================================*
PERFORM UNTIL WS-ENTITY-EOF
READ ENTITY-TB-FILE NEXT
AT END SET WS-ENTITY-EOF TO TRUE
END-READ
IF NOT WS-ENTITY-EOF
* SEARCH CONSOLIDATED TABLE FOR MATCHING
* NATURAL ACCOUNT
MOVE ETB-ACCOUNT-NUM TO WS-SEARCH-ACCT
PERFORM 1250-FIND-CONSOL-SLOT
ADD ETB-ADJUSTED-BALANCE
TO CT-BALANCE(WS-CONSOL-IDX)
ADD ETB-PERIOD-DEBITS
TO CT-DEBITS(WS-CONSOL-IDX)
ADD ETB-PERIOD-CREDITS
TO CT-CREDITS(WS-CONSOL-IDX)
END-IF
END-PERFORM
.
*================================================================*
2000-VERIFY-CONSOLIDATION.
*================================================================*
* THREE VERIFICATION CHECKS:
* 1. CONSOLIDATED DEBITS = CONSOLIDATED CREDITS
* 2. ASSETS = LIABILITIES + EQUITY (BALANCE SHEET)
* 3. IC ELIMINATION ACCOUNTS NET TO ZERO
MOVE ZEROS TO WS-VERIFY-TOTAL-DR
WS-VERIFY-TOTAL-CR
WS-VERIFY-ASSETS
WS-VERIFY-LIABILITIES
WS-VERIFY-EQUITY
WS-VERIFY-IC-NET
PERFORM VARYING WS-CONSOL-IDX FROM 1 BY 1
UNTIL WS-CONSOL-IDX > WS-CONSOL-COUNT
ADD CT-DEBITS(WS-CONSOL-IDX)
TO WS-VERIFY-TOTAL-DR
ADD CT-CREDITS(WS-CONSOL-IDX)
TO WS-VERIFY-TOTAL-CR
EVALUATE CT-ACCT-TYPE(WS-CONSOL-IDX)
WHEN 'A'
ADD CT-BALANCE(WS-CONSOL-IDX)
TO WS-VERIFY-ASSETS
WHEN 'L'
ADD CT-BALANCE(WS-CONSOL-IDX)
TO WS-VERIFY-LIABILITIES
WHEN 'E'
ADD CT-BALANCE(WS-CONSOL-IDX)
TO WS-VERIFY-EQUITY
WHEN 'R'
ADD CT-BALANCE(WS-CONSOL-IDX)
TO WS-VERIFY-EQUITY
WHEN 'X'
SUBTRACT CT-BALANCE(WS-CONSOL-IDX)
FROM WS-VERIFY-EQUITY
END-EVALUATE
* CHECK IF THIS IS AN IC ACCOUNT
IF CT-ACCOUNT(WS-CONSOL-IDX)(1:2) = '19'
OR CT-ACCOUNT(WS-CONSOL-IDX)(1:2) = '29'
ADD CT-BALANCE(WS-CONSOL-IDX)
TO WS-VERIFY-IC-NET
END-IF
END-PERFORM
* CHECK 1: TRIAL BALANCE
IF WS-VERIFY-TOTAL-DR NOT = WS-VERIFY-TOTAL-CR
DISPLAY 'MECCONSOL: *** CONSOL TB IMBALANCE ***'
MOVE 8 TO RETURN-CODE
END-IF
* CHECK 2: ACCOUNTING EQUATION
COMPUTE WS-EQUATION-DIFF =
WS-VERIFY-ASSETS -
WS-VERIFY-LIABILITIES -
WS-VERIFY-EQUITY
IF WS-EQUATION-DIFF NOT = ZEROS
DISPLAY 'MECCONSOL: *** EQUATION IMBALANCE ***'
DISPLAY ' A=' WS-VERIFY-ASSETS
' L=' WS-VERIFY-LIABILITIES
' E=' WS-VERIFY-EQUITY
MOVE 8 TO RETURN-CODE
END-IF
* CHECK 3: IC ACCOUNTS FULLY ELIMINATED
IF WS-VERIFY-IC-NET NOT = ZEROS
DISPLAY 'MECCONSOL: *** IC NOT ELIMINATED ***'
DISPLAY ' IC NET BALANCE: ' WS-VERIFY-IC-NET
MOVE 8 TO RETURN-CODE
END-IF
.
The three verification checks in paragraph 2000 encode fundamental accounting rules that must hold true for any correct consolidation. The first check (debits equal credits) validates the mechanical integrity of the trial balance. The second check validates the accounting equation, treating revenue as an increase to equity and expenses as a decrease -- this is the expanded accounting equation that incorporates income statement accounts before they are closed to retained earnings. The third check specifically validates that all intercompany accounts (identified by the convention that IC receivable accounts begin with "19" and IC payable accounts begin with "29") have been fully eliminated and net to zero.
Step 5: Financial Statement Generation (MECFINST)
The financial statement program reads the consolidated trial balance and produces formatted income statements, balance sheets, and supporting schedules. The program uses a report definition table that maps each GL account to its position on the financial statements, allowing the finance team to modify the statement layout without changing the program.
Batch Job Sequencing with JCL
The entire close process is orchestrated by a single JCL procedure that executes the six steps in sequence, with conditional execution based on return codes:
//MECCLOSE JOB (PCI,ACCTG),'MONTH-END CLOSE',
// CLASS=A,MSGCLASS=X,MSGLEVEL=(1,1),
// NOTIFY=&SYSUID
//*
//*=============================================================*
//* PRECISION COMPONENTS INTERNATIONAL *
//* AUTOMATED MONTH-END CLOSE PROCESS *
//* PARM: PERIOD(2) YEAR(4) -- E.G., '062025' *
//*=============================================================*
//*
//*--- STEP 1: GENERATE UNADJUSTED TRIAL BALANCE ---------------*
//STEP01 EXEC PGM=MECTRBAL,
// PARM='&PERIOD&YEAR'
//STEPLIB DD DSN=PCI.PROD.LOADLIB,DISP=SHR
//GLMAST DD DSN=PCI.GL.MASTER.VSAM,DISP=SHR
//TBOUT DD DSN=PCI.MEC.TRIALBAL.UNADJ,
// DISP=(NEW,CATLG,DELETE),
// SPACE=(CYL,(5,2)),
// DCB=(RECFM=FB,LRECL=200,BLKSIZE=0)
//PRIORTB DD DSN=PCI.MEC.TRIALBAL.PRIOR,DISP=SHR
//TBRPT DD SYSOUT=*,DCB=(RECFM=FBA,LRECL=133)
//SYSOUT DD SYSOUT=*
//*
//*--- STEP 2: GENERATE AND POST ADJUSTING ENTRIES --------------*
//STEP02 EXEC PGM=MECADJEN,
// PARM='&PERIOD&YEAR',
// COND=(8,LE,STEP01)
//STEPLIB DD DSN=PCI.PROD.LOADLIB,DISP=SHR
//ADJSCHED DD DSN=PCI.MEC.ADJ.SCHEDULES,DISP=SHR
//JEOUT DD DSN=PCI.MEC.ADJENTRIES,
// DISP=(NEW,CATLG,DELETE),
// SPACE=(CYL,(1,1)),
// DCB=(RECFM=FB,LRECL=300,BLKSIZE=0)
//SYSOUT DD SYSOUT=*
//*
//*--- STEP 2A: POST THE ADJUSTING ENTRIES TO GL ----------------*
//STEP02A EXEC PGM=GLPOST,
// COND=(8,LE)
//STEPLIB DD DSN=PCI.PROD.LOADLIB,DISP=SHR
//JEINPUT DD DSN=PCI.MEC.ADJENTRIES,DISP=SHR
//GLMAST DD DSN=PCI.GL.MASTER.VSAM,DISP=SHR
//COAFILE DD DSN=PCI.CHART.OF.ACCOUNTS.VSAM,DISP=SHR
//PRDCTRL DD DSN=PCI.PERIOD.CONTROL.VSAM,DISP=SHR
//AUDTRL DD DSN=PCI.GL.AUDIT.TRAIL,DISP=MOD
//REJECTS DD DSN=PCI.MEC.ADJ.REJECTS,
// DISP=(NEW,CATLG,DELETE),
// SPACE=(CYL,(1,1)),
// DCB=(RECFM=FB,LRECL=350,BLKSIZE=0)
//POSTRPT DD SYSOUT=*,DCB=(RECFM=FBA,LRECL=133)
//SYSOUT DD SYSOUT=*
//*
//*--- STEP 3: INTERCOMPANY ELIMINATIONS ------------------------*
//STEP03 EXEC PGM=MECICELM,
// PARM='&PERIOD&YEAR',
// COND=(8,LE)
//STEPLIB DD DSN=PCI.PROD.LOADLIB,DISP=SHR
//ICMAP DD DSN=PCI.MEC.IC.MAPPING,DISP=SHR
//TBIN DD DSN=PCI.MEC.TRIALBAL.ADJUSTED,DISP=SHR
//ELIMOUT DD DSN=PCI.MEC.IC.ELIM.ENTRIES,
// DISP=(NEW,CATLG,DELETE),
// SPACE=(CYL,(1,1)),
// DCB=(RECFM=FB,LRECL=300,BLKSIZE=0)
//ICRPT DD SYSOUT=*,DCB=(RECFM=FBA,LRECL=133)
//SYSOUT DD SYSOUT=*
//*
//*--- STEP 3A: POST ELIMINATION ENTRIES TO GL ------------------*
//STEP03A EXEC PGM=GLPOST,
// COND=(8,LE)
//STEPLIB DD DSN=PCI.PROD.LOADLIB,DISP=SHR
//JEINPUT DD DSN=PCI.MEC.IC.ELIM.ENTRIES,DISP=SHR
//GLMAST DD DSN=PCI.GL.MASTER.VSAM,DISP=SHR
//COAFILE DD DSN=PCI.CHART.OF.ACCOUNTS.VSAM,DISP=SHR
//PRDCTRL DD DSN=PCI.PERIOD.CONTROL.VSAM,DISP=SHR
//AUDTRL DD DSN=PCI.GL.AUDIT.TRAIL,DISP=MOD
//REJECTS DD DSN=PCI.MEC.ELIM.REJECTS,
// DISP=(NEW,CATLG,DELETE),
// SPACE=(CYL,(1,1)),
// DCB=(RECFM=FB,LRECL=350,BLKSIZE=0)
//POSTRPT DD SYSOUT=*,DCB=(RECFM=FBA,LRECL=133)
//SYSOUT DD SYSOUT=*
//*
//*--- STEP 4: CONSOLIDATION -----------------------------------*
//STEP04 EXEC PGM=MECCONSOL,
// PARM='&PERIOD&YEAR',
// COND=(8,LE)
//STEPLIB DD DSN=PCI.PROD.LOADLIB,DISP=SHR
//TBIN01 DD DSN=PCI.MEC.TRIALBAL.PCI01,DISP=SHR
//TBIN02 DD DSN=PCI.MEC.TRIALBAL.PCI02,DISP=SHR
//TBIN03 DD DSN=PCI.MEC.TRIALBAL.PCI03,DISP=SHR
//TBIN04 DD DSN=PCI.MEC.TRIALBAL.PCI04,DISP=SHR
//TBIN05 DD DSN=PCI.MEC.TRIALBAL.PCI05,DISP=SHR
//TBINELIM DD DSN=PCI.MEC.TRIALBAL.CI99,DISP=SHR
//CONSOLOUT DD DSN=PCI.MEC.CONSOL.TRIALBAL,
// DISP=(NEW,CATLG,DELETE),
// SPACE=(CYL,(5,2)),
// DCB=(RECFM=FB,LRECL=200,BLKSIZE=0)
//CONSOLRPT DD SYSOUT=*,DCB=(RECFM=FBA,LRECL=133)
//SYSOUT DD SYSOUT=*
//*
//*--- STEP 5: GENERATE FINANCIAL STATEMENTS --------------------*
//STEP05 EXEC PGM=MECFINST,
// PARM='&PERIOD&YEAR',
// COND=(8,LE)
//STEPLIB DD DSN=PCI.PROD.LOADLIB,DISP=SHR
//CONSOLIN DD DSN=PCI.MEC.CONSOL.TRIALBAL,DISP=SHR
//RPTDEFN DD DSN=PCI.MEC.REPORT.DEFINITIONS,DISP=SHR
//INCOMEST DD SYSOUT=*,DCB=(RECFM=FBA,LRECL=133)
//BALSHEET DD SYSOUT=*,DCB=(RECFM=FBA,LRECL=133)
//CASHFLOW DD SYSOUT=*,DCB=(RECFM=FBA,LRECL=133)
//SCHEDULS DD SYSOUT=*,DCB=(RECFM=FBA,LRECL=133)
//SYSOUT DD SYSOUT=*
//*
//*--- STEP 6: CLOSE THE PERIOD --------------------------------*
//STEP06 EXEC PGM=MECPRCLS,
// PARM='&PERIOD&YEAR',
// COND=(8,LE)
//STEPLIB DD DSN=PCI.PROD.LOADLIB,DISP=SHR
//PRDCTRL DD DSN=PCI.PERIOD.CONTROL.VSAM,DISP=SHR
//CLSCTRL DD DSN=PCI.MEC.CLOSE.CONTROL.VSAM,DISP=SHR
//GLMAST DD DSN=PCI.GL.MASTER.VSAM,DISP=SHR
//SYSOUT DD SYSOUT=*
The COND=(8,LE) parameter on each step is the key to the error-handling strategy. In JCL, the COND parameter specifies conditions under which the step should be bypassed. COND=(8,LE) means "skip this step if any prior step's return code was greater than or equal to 8." This allows the process to continue when a step completes with warnings (return code 4) but halts when any step fails (return code 8 or higher). The operations team can then investigate the failure, correct the underlying issue, and restart the process from the failed step.
The design also reuses the existing GLPOST program (from Case Study 1) in steps 2A and 3A. Rather than building journal entry posting logic into every program, the adjustment and elimination programs generate standard journal entry files that GLPOST consumes. This separation of concerns means the same validation rules, audit trail, and SOX controls apply to automated entries as to manually entered ones.
Error Handling and Reconciliation Checkpoints
The reconciliation checkpoint strategy is the architectural element that most directly addresses the CFO's requirement for improved accuracy. Each checkpoint validates that the data meets specific accounting invariants before the next step begins.
Checkpoint 1 (after Step 1): The unadjusted trial balance must balance. Total debits must equal total credits. If the GL master file has been corrupted -- perhaps by an abended posting run or an unauthorized direct update -- this checkpoint catches it immediately, before any adjusting entries are applied.
Checkpoint 2 (after Step 2): The adjusted trial balance must balance. If any adjusting entry was generated out of balance (which should be impossible given the two-line entry design, but defense in depth is essential in financial systems), or if the posting program rejected an entry, this checkpoint prevents the close from proceeding with an incomplete set of adjustments.
Checkpoint 3 (after Step 3): All intercompany pairs must either balance exactly or fall within the $0.05 tolerance. This is the checkpoint that previously required manual investigation four times in the past fiscal year. By automating the comparison and halting the process immediately when an imbalance is detected, the accounting team is alerted on the first day of the close rather than discovering the problem on day seven.
Checkpoint 4 (after Step 4): The consolidated trial balance must satisfy three conditions: debits equal credits, the accounting equation holds (Assets = Liabilities + Equity), and all intercompany accounts net to zero. This triple verification catches errors that a simple debit-credit balance check would miss, such as an elimination entry that was posted to the wrong account type.
Results
PCI deployed the automated close system after a three-month development and testing cycle. The system was piloted during the September close, running in parallel with the manual process. The pilot revealed two issues: a missing intercompany mapping for a recently created account pair, and a recurring entry schedule that contained a deprecated cost center code. Both were corrected before the October close, which was the first month executed entirely using the automated system.
The results were immediate and measurable:
Close cycle reduction: The October close completed in 2.5 business days -- day one for the automated batch processing (steps 1 through 5), day two for the accounting team's review of the flagged accounts and financial statement package, and the first half of day three for the controller's sign-off and period closure (step 6). By comparison, the prior October close had taken eleven business days. Over the following six months, the close consistently completed in two to three business days, meeting the CFO's target.
Accuracy improvement: In the six months following deployment, zero intercompany imbalances reached the consolidation step. The automated matching in MECICELM caught three discrepancies during the close process, all of which were resolved within hours rather than days. The number of post-close adjustments (entries made after the financial statements were initially produced) dropped from an average of twelve per month to fewer than two.
Audit trail completeness: Every automated adjusting entry, elimination entry, and consolidation calculation is recorded in the GL audit trail through the standard GLPOST program. The external auditors noted in their management letter that the automated close system significantly improved the quality of audit evidence and reduced the time required for their substantive testing of the close process.
Staff reallocation: The seven-person accounting team previously spent the majority of each month-end period on mechanical close activities -- keying entries, running spreadsheet calculations, copying data, and formatting reports. With the automated system handling these tasks, the team redirected their effort toward analytical review: investigating the accounts flagged by the variance detection logic, performing flux analysis on key revenue and expense accounts, and preparing the management commentary that accompanies the financial statements. The controller reported that the quality of financial analysis presented to the executive team improved substantially.
Operational reliability: The batch job has run successfully for every close since deployment. On one occasion, the MECICELM step halted with a return code of eight due to a legitimate intercompany discrepancy (the automotive plant had recorded a transfer that the distribution entity had not yet processed). The accounting team resolved the discrepancy by posting the missing entry in the distribution entity's GL, and the close process was restarted from step 3. The restart completed in forty minutes, and the overall close still finished within three business days.
Discussion Questions
-
The adjustment schedule record includes start and end periods that control when each recurring entry is active. What happens at fiscal year-end when period 12 adjustments must be generated but period 1 of the new year should not yet include them? How would you handle adjustments that span fiscal years, such as a prepaid insurance policy that was set up in the prior year?
-
The intercompany elimination program uses a tolerance of $0.05. Consider a scenario where PCI acquires a sixth manufacturing entity that transacts in Canadian dollars. How would currency translation affect the intercompany matching logic? What changes would be needed to accommodate rounding differences that arise from exchange rate conversions?
-
The consolidation program validates the accounting equation (Assets = Liabilities + Equity). However, this check treats revenue as an addition to equity and expenses as a subtraction. Explain why this is correct from an accounting perspective. What would happen to this validation in the first period of a new fiscal year, after income statement accounts have been closed to retained earnings?
-
The JCL uses
COND=(8,LE)to control step execution. What would happen if step 2A (posting adjusting entries) completed with return code 4 (some entries rejected)? Should the close process continue or halt? Design a more granular error-handling strategy that distinguishes between acceptable warnings and conditions that should stop the close. -
The close process generates adjusting entries and elimination entries as standard journal entry files that are posted by the existing GLPOST program. What are the advantages and disadvantages of this approach compared to having each close program update the GL master file directly? Consider audit trail completeness, performance, recoverability, and the principle of separation of concerns.
-
PCI's close process runs as a single batch job with sequential steps. An alternative design would use separate jobs for each step, with a scheduling tool (such as CA-7 or TWS) managing the dependencies. What are the trade-offs between these two approaches in terms of restartability, monitoring, and operational complexity?