Challenge: nightly account update
Time for the real thing: the nightly batch update of a bank's account master. Yesterday's master and today's sorted transactions go in; a new master, an exceptions file and a set of control totals come out. The program uses everything in this module: DD names, FDs, file status checks, the priming read, writing several files, and the match-merge.
Adding records: process by current key
The price update in the previous lesson only changed existing records. Here, transactions can also open accounts (add a record) and close them (drop it). A new account can even receive a deposit later in the same run. The cleanest way to handle that is a small variation of the balance-line loop that works one key at a time:
- The current key is the lower of the master key and the transaction key.
- If the master has that key, copy the master record into a working record, mark it as existing, and read the next master. Otherwise mark the working record as missing.
- Apply every transaction with that key to the working record. An open fills it in and marks it existing; a close marks it missing again.
- If the working record exists at the end, write it to the new master.
1000-PROCESS-KEY.
IF WS-MAST-KEY < WS-TXN-KEY
MOVE WS-MAST-KEY TO WS-CURR-KEY
ELSE
MOVE WS-TXN-KEY TO WS-CURR-KEY
END-IF
IF WS-MAST-KEY = WS-CURR-KEY
MOVE OLD-REC TO WS-ACCT
SET ACCT-EXISTS TO TRUE
PERFORM 8000-READ-MASTER
ELSE
SET ACCT-MISSING TO TRUE
END-IF
PERFORM 2000-APPLY-TXN
UNTIL WS-TXN-KEY NOT = WS-CURR-KEY
IF ACCT-EXISTS
WRITE NEW-REC FROM WS-ACCT
END-IF.
The main loop runs 1000-PROCESS-KEY until both keys are HIGH-VALUES,
exactly as before. 2000-APPLY-TXN must end by reading the next
transaction, or the inner loop never finishes.
Rules as an ordered EVALUATE
Each transaction either succeeds or produces an exception with one
reason. As in the customer feed challenge, an EVALUATE TRUE with the
checks in priority order keeps this readable: invalid types first, then
opens, then "no such account", then the rules for each type.
Control totals must balance
Operations will check your totals before the new master is used:
- masters read + accounts opened - accounts closed = new master records
- every transaction either updates an account or appears in the exceptions file
If those do not add up, the run is rejected and someone gets a phone call.
On the job
Exceptions are not errors in the program: they are business events (a bounced withdrawal, a close request on an account that still has money in it) that the program must route to people. The job still ends with return code 0. A return code of 12 is for things that make the whole run invalid, like a missing input dataset.
Your task
Write the nightly account update. All files are line sequential; both inputs are sorted by account number, and transactions for the same account are in the order they happened.
Old master, DD ACCTOLD, and new master, DD ACCTNEW
(same layout; the starter's WS-ACCT has it):
| Field | Picture | Positions |
|---|---|---|
| account number | X(8) |
1–8 |
| name | X(20) |
9–28 |
| balance | 9(7)V99 |
29–37 |
Transactions, DD TXNIN (the starter's TXN-REC):
| Field | Picture | Positions |
|---|---|---|
TXN-ACCT |
X(8) |
1–8 |
TXN-TYPE |
X: O open, D deposit, W withdrawal, C close |
9 |
TXN-AMOUNT |
9(7)V99 |
10–18 |
TXN-NAME |
X(20), only used by O |
19–38 |
Exceptions, DD EXCEPT (the starter's EXC-REC): account,
type, amount (Z(6)9.99) and reason, separated by single spaces.
Apply each transaction by these rules, checked in this order:
| Condition | Result |
|---|---|
type is not O, D, W or C |
exception INVALID TYPE |
O and the account exists |
exception ACCOUNT EXISTS |
O |
create the account with that name, balance = amount |
| account does not exist (never did, or closed earlier in this run) | exception NO ACCOUNT |
D |
add the amount |
W and amount > balance |
exception INSUFFICIENT FUNDS |
W |
subtract the amount |
C and balance is not zero |
exception BALANCE NOT ZERO |
C |
close: the account is not written to the new master |
Write every surviving account to the new master, in key order. At the end display:
MASTERS READ: 004
TRANS READ: 009
ACCOUNTS OPENED: 001
ACCOUNTS CLOSED: 001
EXCEPTIONS: 004
NEW MASTER: 004
TOTAL BALANCE: 11375.00
(TOTAL BALANCE is the sum of the new master balances, via
WS-TOTAL-ED.)
If either input fails to open, display
OPEN FAILED: ACCTOLD ss TXNIN ss with the two statuses and stop with
return code 12.