COTRN02C
Source: cbl/COTRN02C.cbl
Type: CICS transaction program
Purpose
COTRN02C is a CICS transaction (CT02) that lets a user add a new financial transaction to the TRANSACT file in the CardDemo application. It validates the account/card identifiers and transaction detail fields entered on the BMS map COTRN2A, then writes a new transaction record only after the user explicitly confirms the add. It also supports copying the details of the most recent transaction for a given account/card as a starting point for a new entry.
How it works
-
MAIN-PARA is the entry point on every CICS invocation.
-
If EIBCALEN = 0 (first-ever call, no commarea), it routes back to the sign-on program COSGN00C via RETURN-TO-PREV-SCREEN.
-
Otherwise it loads the commarea into CARDDEMO-COMMAREA. On first entry into this program (NOT CDEMO-PGM-REENTER), it initializes the map, and — if a transaction ID was already selected (CDEMO-CT02-TRN-SELECTED) — pre-loads the card number and immediately runs PROCESS-ENTER-KEY before sending the screen.
-
On subsequent (re-entrant) calls, it receives the map (RECEIVE-TRNADD-SCREEN) and dispatches based on the AID key: ENTER → PROCESS-ENTER-KEY PF3 → RETURN-TO-PREV-SCREEN (back to caller or COMEN01C) PF4 → CLEAR-CURRENT-SCREEN PF5 → COPY-LAST-TRAN-DATA any other key → error message, screen re-sent
-
Every path ends in EXEC CICS RETURN TRANSID(CT02) COMMAREA(...), keeping the transaction pseudo-conversational.
-
PROCESS-ENTER-KEY drives the core validation/add sequence:
-
VALIDATE-INPUT-KEY-FIELDS — requires either Account ID or Card Number. If Account ID is given, looks it up via READ-CXACAIX-FILE (cross-reference by account) and derives the card number; if Card Number is given instead, looks it up via READ-CCXREF-FILE and derives the account ID. Missing/non-numeric key data sends the screen with an error.
-
VALIDATE-INPUT-DATA-FIELDS — checks that type code, category code, source, description, amount, original date, processing date, merchant ID/name/city/zip are all populated; verifies type/category codes and merchant ID are numeric; checks the amount format (±99999999.99) and date formats (YYYY-MM-DD); calls the external routine CSUTLDTC twice (once per date field) to validate that the dates are real calendar dates.
-
If no errors, the confirmation field (CONFIRMI) is evaluated: Y/y triggers ADD-TRANSACTION; N/n/blank asks the user to confirm; anything else is flagged invalid.
-
ADD-TRANSACTION generates the next transaction ID by browsing the TRANSACT file backwards from HIGH-VALUES (STARTBR-TRANSACT-FILE → READPREV-TRANSACT-FILE → ENDBR-TRANSACT-FILE), taking the highest existing TRAN-ID and adding 1. It then builds a new TRAN-RECORD from the input fields and calls WRITE-TRANSACT-FILE.
-
COPY-LAST-TRAN-DATA (PF5) re-validates the key fields, then browses the TRANSACT file the same way to find the most recent transaction, copies its data into the input map fields, and re-runs PROCESS-ENTER-KEY (effectively pre-filling the "add" screen with the last transaction's details for confirmation/editing).
-
SEND-TRNADD-SCREEN always runs POPULATE-HEADER-INFO (titles, program/transaction name, current date/time) before sending the map, and issues the pseudo-conversational CICS RETURN.
-
CLEAR-CURRENT-SCREEN and INITIALIZE-ALL-FIELDS reset all input fields and the message area, used both for PF4 and after a successful write.
Inputs & outputs
Things to know
-
Hard-coded values: transaction ID CT02, program name COTRN02C, file names TRANSACT, ACCTDAT, CCXREF, CXACAIX are all fixed in WS-VARIABLES. ACCTDAT is defined but appears unused in the procedure logic — worth confirming this isn't dead code or a missing feature.
-
Transaction ID generation is not concurrency-safe: the "next" TRAN-ID is computed by browsing backward for the highest existing key and adding 1, in both ADD-TRANSACTION and COPY-LAST-TRAN-DATA. Under concurrent use, two users could compute the same next ID before either writes, though a duplicate-key WRITE response is handled (DFHRESP(DUPKEY)/DUPREC) with an error message rather than a retry.
-
Explicit confirmation required: transactions are only written when the user types Y/y in the confirm field; blank, N/n, or anything else blocks the write and re-prompts — the write is never automatic even if all other validations pass.
-
Date validation quirk: CSUTLDTC returning message number '2513' is treated as acceptable (not an error) even when severity isn't '0000' — this special-cased message number's exact meaning isn't stated in the source and should be confirmed against CSUTLDTC's documentation before assuming it's benign.
-
Field-level error handling pattern: nearly every validation failure sets WS-ERR-FLG to Y, moves an explicit message to WS-MESSAGE, positions the cursor (MOVE -1 to the relevant *L length field), and immediately calls SEND-TRNADD-SCREEN, which itself issues a CICS RETURN. This means multiple validation checks in VALIDATE-INPUT-DATA-FIELDS execute in strict order and the first failure short-circuits the rest for that screen round-trip.
-
Amount field parsing uses positional substring checks (TRNAMTI(1:1), (2:8), etc.) rather than symbolic validation, so the input format is rigid (+99999999.99 / -99999999.99); any deviation in field width/format assumptions elsewhere in the copybook could break this logic silently.
-
No SQL/DB2 usage — all data access is via CICS VSAM file control commands (READ, STARTBR, READPREV, ENDBR, WRITE), consistent with the empty sql_tables list.
-
Error/diagnostic output: unexpected file-access failures (WHEN OTHER in the RESP evaluations) are logged via DISPLAY of the response/reason codes — useful for debugging in CICS but not surfaced to the end user beyond a generic error message.
CICS commands
RETURN, SEND, RECEIVE, READ, STARTBR, READPREV, ENDBR, WRITE
Copybooks
COCOM01Y, COTRN02, COTTL01Y, CSDAT01Y, CSMSG01Y, CVACT01Y, CVACT03Y, CVTRA05Y, DFHAID, DFHBMSCA
Calls
CSUTLDTC
Unresolved conditions
Numeric comparisons with no matching 88-level condition-name anywhere in this program or the copybooks it COPYs — no meaning found in the source export, not guessed.
| Field | Value | Line |
|---|---|---|
EIBCALEN |
0 |
115 |
Paragraph flow
flowchart TD
MAIN_PARA["MAIN-PARA"]
PROCESS_ENTER_KEY["PROCESS-ENTER-KEY"]
VALIDATE_INPUT_KEY_FIELDS["VALIDATE-INPUT-KEY-FIELDS"]
VALIDATE_INPUT_DATA_FIELDS["VALIDATE-INPUT-DATA-FIELDS"]
ADD_TRANSACTION["ADD-TRANSACTION"]
COPY_LAST_TRAN_DATA["COPY-LAST-TRAN-DATA"]
RETURN_TO_PREV_SCREEN["RETURN-TO-PREV-SCREEN"]
SEND_TRNADD_SCREEN["SEND-TRNADD-SCREEN"]
RECEIVE_TRNADD_SCREEN["RECEIVE-TRNADD-SCREEN"]
POPULATE_HEADER_INFO["POPULATE-HEADER-INFO"]
READ_CXACAIX_FILE["READ-CXACAIX-FILE"]
READ_CCXREF_FILE["READ-CCXREF-FILE"]
STARTBR_TRANSACT_FILE["STARTBR-TRANSACT-FILE"]
READPREV_TRANSACT_FILE["READPREV-TRANSACT-FILE"]
ENDBR_TRANSACT_FILE["ENDBR-TRANSACT-FILE"]
WRITE_TRANSACT_FILE["WRITE-TRANSACT-FILE"]
CLEAR_CURRENT_SCREEN["CLEAR-CURRENT-SCREEN"]
INITIALIZE_ALL_FIELDS["INITIALIZE-ALL-FIELDS"]
ADD_TRANSACTION --> ENDBR_TRANSACT_FILE
ADD_TRANSACTION --> READPREV_TRANSACT_FILE
ADD_TRANSACTION --> STARTBR_TRANSACT_FILE
ADD_TRANSACTION --> WRITE_TRANSACT_FILE
CLEAR_CURRENT_SCREEN --> INITIALIZE_ALL_FIELDS
CLEAR_CURRENT_SCREEN --> SEND_TRNADD_SCREEN
COPY_LAST_TRAN_DATA --> ENDBR_TRANSACT_FILE
COPY_LAST_TRAN_DATA --> PROCESS_ENTER_KEY
COPY_LAST_TRAN_DATA --> READPREV_TRANSACT_FILE
COPY_LAST_TRAN_DATA --> STARTBR_TRANSACT_FILE
COPY_LAST_TRAN_DATA --> VALIDATE_INPUT_KEY_FIELDS
MAIN_PARA --> CLEAR_CURRENT_SCREEN
MAIN_PARA --> COPY_LAST_TRAN_DATA
MAIN_PARA --> PROCESS_ENTER_KEY
MAIN_PARA --> RECEIVE_TRNADD_SCREEN
MAIN_PARA --> RETURN_TO_PREV_SCREEN
MAIN_PARA --> SEND_TRNADD_SCREEN
PROCESS_ENTER_KEY --> ADD_TRANSACTION
PROCESS_ENTER_KEY --> SEND_TRNADD_SCREEN
PROCESS_ENTER_KEY --> VALIDATE_INPUT_DATA_FIELDS
PROCESS_ENTER_KEY --> VALIDATE_INPUT_KEY_FIELDS
READ_CCXREF_FILE --> SEND_TRNADD_SCREEN
READ_CXACAIX_FILE --> SEND_TRNADD_SCREEN
READPREV_TRANSACT_FILE --> SEND_TRNADD_SCREEN
SEND_TRNADD_SCREEN --> POPULATE_HEADER_INFO
STARTBR_TRANSACT_FILE --> SEND_TRNADD_SCREEN
VALIDATE_INPUT_DATA_FIELDS --> SEND_TRNADD_SCREEN
VALIDATE_INPUT_KEY_FIELDS --> READ_CCXREF_FILE
VALIDATE_INPUT_KEY_FIELDS --> READ_CXACAIX_FILE
VALIDATE_INPUT_KEY_FIELDS --> SEND_TRNADD_SCREEN
WRITE_TRANSACT_FILE --> INITIALIZE_ALL_FIELDS
WRITE_TRANSACT_FILE --> SEND_TRNADD_SCREEN
Paragraphs
| Paragraph | Line | Performs |
|---|---|---|
| MAIN-PARA | 107 | RETURN-TO-PREV-SCREEN, PROCESS-ENTER-KEY, SEND-TRNADD-SCREEN, RECEIVE-TRNADD-SCREEN, PROCESS-ENTER-KEY, RETURN-TO-PREV-SCREEN |
| PROCESS-ENTER-KEY | 164 | VALIDATE-INPUT-KEY-FIELDS, VALIDATE-INPUT-DATA-FIELDS, ADD-TRANSACTION, SEND-TRNADD-SCREEN, SEND-TRNADD-SCREEN |
| VALIDATE-INPUT-KEY-FIELDS | 193 | SEND-TRNADD-SCREEN, READ-CXACAIX-FILE, SEND-TRNADD-SCREEN, READ-CCXREF-FILE, SEND-TRNADD-SCREEN |
| VALIDATE-INPUT-DATA-FIELDS | 235 | SEND-TRNADD-SCREEN, SEND-TRNADD-SCREEN, SEND-TRNADD-SCREEN, SEND-TRNADD-SCREEN, SEND-TRNADD-SCREEN, SEND-TRNADD-SCREEN |
| ADD-TRANSACTION | 442 | STARTBR-TRANSACT-FILE, READPREV-TRANSACT-FILE, ENDBR-TRANSACT-FILE, WRITE-TRANSACT-FILE |
| COPY-LAST-TRAN-DATA | 471 | VALIDATE-INPUT-KEY-FIELDS, STARTBR-TRANSACT-FILE, READPREV-TRANSACT-FILE, ENDBR-TRANSACT-FILE, PROCESS-ENTER-KEY |
| RETURN-TO-PREV-SCREEN | 500 | |
| SEND-TRNADD-SCREEN | 516 | POPULATE-HEADER-INFO |
| RECEIVE-TRNADD-SCREEN | 539 | |
| POPULATE-HEADER-INFO | 552 | |
| READ-CXACAIX-FILE | 576 | SEND-TRNADD-SCREEN, SEND-TRNADD-SCREEN |
| READ-CCXREF-FILE | 609 | SEND-TRNADD-SCREEN, SEND-TRNADD-SCREEN |
| STARTBR-TRANSACT-FILE | 642 | SEND-TRNADD-SCREEN, SEND-TRNADD-SCREEN |
| READPREV-TRANSACT-FILE | 673 | SEND-TRNADD-SCREEN |
| ENDBR-TRANSACT-FILE | 702 | |
| WRITE-TRANSACT-FILE | 711 | INITIALIZE-ALL-FIELDS, SEND-TRNADD-SCREEN, SEND-TRNADD-SCREEN, SEND-TRNADD-SCREEN |
| CLEAR-CURRENT-SCREEN | 754 | INITIALIZE-ALL-FIELDS, SEND-TRNADD-SCREEN |
| INITIALIZE-ALL-FIELDS | 762 |