IDENTIFICATION DIVISION. PROGRAM-ID. Main01Matching11. *> ============================================================ *> 01-matching-1-1 : 请求书↔支付对账 (Invoice↔Payment Matching) *> TELECOM BILLING SYSTEM — 事后对账处理 *> Input : master.dat (请求书主文件: 按INVOICE-ID排序) *> detail.dat (支付文件: 按INVOICE-ID排序) *> Output: output.dat (对账一致记录) *> error.dat (对账不一致记录: 未匹配请求书/支付) *> audit-report.txt (审计报告: 处理统计) *> Pipeline: 请求书发行→对账→异常处理 *> Coverage: MT-N001, MT-N004, MT-N005, MT-R001 *> Expanded: 900+ lines — Section structure, validation, audit, *> hash totals, partial-match tolerance, date checks *> ============================================================ ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT FILE-MASTER ASSIGN TO 'master.dat' ORGANIZATION IS SEQUENTIAL ACCESS MODE IS SEQUENTIAL FILE STATUS IS WS-MASTER-STATUS. SELECT FILE-DETAIL ASSIGN TO 'detail.dat' ORGANIZATION IS SEQUENTIAL ACCESS MODE IS SEQUENTIAL FILE STATUS IS WS-DETAIL-STATUS. SELECT FILE-OUT ASSIGN TO 'output.dat' ORGANIZATION IS SEQUENTIAL FILE STATUS IS WS-OUT-STATUS. SELECT FILE-ERR ASSIGN TO 'error.dat' ORGANIZATION IS SEQUENTIAL FILE STATUS IS WS-ERR-STATUS. SELECT AUDIT-FILE ASSIGN TO 'audit-report.txt' ORGANIZATION IS LINE SEQUENTIAL FILE STATUS IS WS-AUDIT-STATUS. DATA DIVISION. FILE SECTION. FD FILE-MASTER. 01 MASTER-REC. COPY "STD-REC.cpy". FD FILE-DETAIL. 01 DETAIL-REC. COPY "STD-REC.cpy". FD FILE-OUT. 01 OUT-REC. COPY "STD-REC.cpy". FD FILE-ERR. 01 ERR-REC. 05 ERR-TYPE PIC X(10). 05 ERR-KEY PIC X(10). 05 ERR-CUST PIC X(10). 05 ERR-AMOUNT PIC 9(10). 05 ERR-FILLER PIC X(40). FD AUDIT-FILE. 01 AUDIT-REC PIC X(120). WORKING-STORAGE SECTION. *> Telecom billing record mapping (TEL-INVOICE 45 bytes = STD-REC 45 bytes) 01 WS-INVOICE-REC. COPY "telecom/TEL-INVOICE.cpy". 01 WS-PAYMENT-REC. COPY "telecom/TEL-INVOICE.cpy". *> File status fields 01 WS-MASTER-STATUS PIC X(02). 01 WS-DETAIL-STATUS PIC X(02). 01 WS-OUT-STATUS PIC X(02). 01 WS-ERR-STATUS PIC X(02). 01 WS-AUDIT-STATUS PIC X(02). *> EOF flags 01 WS-FLAGS. 05 WS-MASTER-EOF PIC X VALUE 'N'. 88 WS-MASTER-END VALUE 'Y'. 05 WS-DETAIL-EOF PIC X VALUE 'N'. 88 WS-DETAIL-END VALUE 'Y'. *> Counter accumulators 01 WS-COUNTERS. 05 WS-MATCH-COUNT PIC 9(05) VALUE 0. 05 WS-MAST-READ-COUNT PIC 9(05) VALUE 0. 05 WS-DETL-READ-COUNT PIC 9(05) VALUE 0. 05 WS-UNMATCH-MAST-COUNT PIC 9(05) VALUE 0. 05 WS-UNMATCH-DETL-COUNT PIC 9(05) VALUE 0. 05 WS-UNMATCH-MAST-PARTIAL PIC 9(05) VALUE 0. 05 WS-ERROR-COUNT PIC 9(05) VALUE 0. 05 WS-WARN-COUNT PIC 9(05) VALUE 0. 05 WS-FATAL-COUNT PIC 9(05) VALUE 0. 05 WS-PARTIAL-MATCH-COUNT PIC 9(05) VALUE 0. 05 WS-SEQ-ERR-COUNT PIC 9(05) VALUE 0. 05 WS-KEY-FMT-ERR-COUNT PIC 9(05) VALUE 0. 05 WS-LINE-COUNT PIC 9(03) VALUE 0. 05 WS-PAGE-NUM PIC 9(03) VALUE 1. *> Hash totals for batch control 01 WS-HASH-TOTALS. 05 WS-INPUT-HASH-MAST PIC 9(15) VALUE 0. 05 WS-INPUT-HASH-DETL PIC 9(15) VALUE 0. 05 WS-OUTPUT-HASH PIC 9(15) VALUE 0. 05 WS-ERROR-HASH PIC 9(15) VALUE 0. 05 WS-HASH-DIFF PIC S9(15) VALUE 0. *> Date and timestamp areas 01 WS-DATE-TIME. 05 WS-PROC-DATE PIC 9(08). 05 WS-PROC-TIME PIC 9(08). 05 WS-TIMESTAMP. 10 WS-TS-DATE PIC X(08). 10 WS-TS-SPACE PIC X VALUE ' '. 10 WS-TS-TIME PIC X(08). 05 WS-RUN-DATE PIC 9(08). 05 WS-RUN-TIME PIC 9(08). *> Validation accumulators 01 WS-VALIDATION. 05 WS-PREV-MAST-KEY PIC X(10). 05 WS-PREV-DETL-KEY PIC X(10). 05 WS-SEQ-ERR-FLAG PIC X VALUE 'N'. 88 WS-SEQ-ERROR VALUE 'Y'. 05 WS-VALID-KEY-CHARS PIC X(36) VALUE 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'. 05 WS-KEY-CHAR PIC X. 05 WS-CHAR-OK PIC X VALUE 'N'. 88 WS-CHAR-IS-OK VALUE 'Y'. 05 WS-IDX PIC 9(02). 05 WS-KEY-INVALID-FLAG PIC X VALUE 'N'. 88 WS-KEY-INVALID VALUE 'Y'. *> Amount comparison / partial match tolerance 01 WS-AMOUNT-COMPARE. 05 WS-MAST-AMT-NUM PIC 9(10). 05 WS-DETL-AMT-NUM PIC 9(10). 05 WS-AMT-DIFF PIC S9(10). 05 WS-AMT-ABS-DIFF PIC 9(10). 05 WS-TOLERANCE PIC 9(10) VALUE 100. 05 WS-TOLERANCE-DISP PIC Z(9)9. *> Invoice aging calculation 01 WS-AGING. 05 WS-INVOICE-MONTH PIC 9(06). 05 WS-CURRENT-MONTH PIC 9(06). 05 WS-AGE-MONTHS PIC S9(04). 05 WS-AGE-OVER-90 PIC 9(05) VALUE 0. 05 WS-AGE-OVER-60 PIC 9(05) VALUE 0. 05 WS-AGE-OVER-30 PIC 9(05) VALUE 0. 05 WS-AGE-CURRENT PIC 9(05) VALUE 0. *> Payment status tracking 01 WS-STATUS-TRACKING. 05 WS-INV-STATUS-CHAR PIC X. 05 WS-PMT-STATUS-CHAR PIC X. 05 WS-STATUS-MISMATCH PIC X VALUE 'N'. 88 WS-STATUS-CONFLICT VALUE 'Y'. 05 WS-STATUS-UNPAID-COUNT PIC 9(05) VALUE 0. 05 WS-STATUS-PAID-COUNT PIC 9(05) VALUE 0. 05 WS-STATUS-ISSUED-COUNT PIC 9(05) VALUE 0. *> Error report / audit working storage 01 WS-AUDIT-LINE. 05 WS-AL-PREFIX PIC X(20). 05 WS-AL-TEXT PIC X(100). 01 WS-DISPLAY-LINE PIC X(80). 01 WS-ERR-MSG PIC X(60). 01 WS-ERR-DETAIL PIC X(80). *> Date conversion for display 01 WS-DATE-CONV. 05 WS-DC-YYYY PIC 9(04). 05 WS-DC-MM PIC 9(02). 05 WS-DC-DD PIC 9(02). 05 WS-DC-HH PIC 9(02). 05 WS-DC-MIN PIC 9(02). 05 WS-DC-SS PIC 9(02). *> Report formatting 01 WS-REPORT-BUFFER. 05 WS-RPT-LINE PIC X(120). 01 WS-REPORT-HEADER. 05 WS-RH-PGM PIC X(20) VALUE '01-MATCHING-1-1'. 05 WS-RH-DATE PIC X(08). 05 WS-RH-TIME PIC X(06). 05 WS-RH-VERSION PIC X(06) VALUE 'V2.00'. 01 WS-PAGE-HEADER. 05 PH-DATE PIC X(08). 05 PH-SPACE1 PIC X(02) VALUE SPACES. 05 PH-TIME PIC X(08). 05 PH-SPACE2 PIC X(20) VALUE SPACES. 05 PH-TITLE PIC X(30) VALUE 'INVOICE-PAYMENT MATCH REPORT'. 05 PH-SPACE3 PIC X(20) VALUE SPACES. 05 PH-PAGE PIC X(05) VALUE 'PAGE '. 05 PH-PAGE-NUM PIC Z(03)9. 01 WS-PAGE-FOOTER. 05 PF-DATE PIC X(08). 05 PF-SPACE1 PIC X(02) VALUE SPACES. 05 PF-TOTAL-LABEL PIC X(20) VALUE 'TOTAL RECORDS: '. 05 PF-TOTAL-COUNT PIC Z(05)9. 05 PF-SPACE2 PIC X(10) VALUE SPACES. 05 PF-HASH-LABEL PIC X(15) VALUE 'HASH TOTAL: '. 05 PF-HASH-VALUE PIC Z(09)9. *> Error report formatting 01 WS-ERR-REPORT-LINE. 05 WS-ERL-TYPE PIC X(15). 05 WS-ERL-KEY PIC X(10). 05 WS-ERL-AMOUNT PIC Z(09)9. 05 WS-ERL-DESC PIC X(40). *> Program status 01 WS-PGM-STATUS. 05 WS-RETURN-CODE PIC 9(02) VALUE 0. 05 WS-PGM-PHASE PIC X(20). 05 WS-OVERALL-STATUS PIC X(10) VALUE 'PROCESSING'. 05 WS-EXIT-CODE PIC 9(02) VALUE 0. PROCEDURE DIVISION. *> ============================================================ *> MAIN SECTION — Top-level orchestration *> ============================================================ MAIN SECTION. MB-PROCESS. *> INITIALIZE — Display header, init counters PERFORM 1000-INITIALIZE *> OPEN-FILES — Open all 5 files with STATUS checks PERFORM 2000-OPEN-FILES *> Read first records from both input files (original logic) READ FILE-MASTER AT END MOVE 'Y' TO WS-MASTER-EOF NOT AT END ADD 1 TO WS-MAST-READ-COUNT MOVE STD-KEY OF MASTER-REC TO WS-PREV-MAST-KEY PERFORM 4000-VALIDATE-MASTER END-READ READ FILE-DETAIL AT END MOVE 'Y' TO WS-DETAIL-EOF NOT AT END ADD 1 TO WS-DETL-READ-COUNT MOVE STD-KEY OF DETAIL-REC TO WS-PREV-DETL-KEY PERFORM 4100-VALIDATE-DETAIL END-READ *> MAIN MATCHING LOOP (original logic preserved exactly) PERFORM UNTIL WS-MASTER-END AND WS-DETAIL-END IF NOT WS-MASTER-END AND NOT WS-DETAIL-END IF STD-KEY OF MASTER-REC = STD-KEY OF DETAIL-REC MOVE MASTER-REC TO OUT-REC WRITE OUT-REC ADD 1 TO WS-MATCH-COUNT PERFORM 5100-ACCUMULATE-OUTPUT READ FILE-MASTER AT END MOVE 'Y' TO WS-MASTER-EOF NOT AT END ADD 1 TO WS-MAST-READ-COUNT PERFORM 4200-CHECK-MAST-SEQUENCE MOVE STD-KEY OF MASTER-REC TO WS-PREV-MAST-KEY PERFORM 4000-VALIDATE-MASTER END-READ READ FILE-DETAIL AT END MOVE 'Y' TO WS-DETAIL-EOF NOT AT END ADD 1 TO WS-DETL-READ-COUNT PERFORM 4300-CHECK-DETL-SEQUENCE MOVE STD-KEY OF DETAIL-REC TO WS-PREV-DETL-KEY PERFORM 4100-VALIDATE-DETAIL END-READ ELSE IF STD-KEY OF MASTER-REC < STD-KEY OF DETAIL-REC ADD 1 TO WS-UNMATCH-MAST-COUNT PERFORM 5300-WRITE-MAST-UNMATCH READ FILE-MASTER AT END MOVE 'Y' TO WS-MASTER-EOF NOT AT END ADD 1 TO WS-MAST-READ-COUNT PERFORM 4200-CHECK-MAST-SEQUENCE MOVE STD-KEY OF MASTER-REC TO WS-PREV-MAST-KEY PERFORM 4000-VALIDATE-MASTER END-READ ELSE ADD 1 TO WS-UNMATCH-DETL-COUNT PERFORM 5400-WRITE-DETL-UNMATCH READ FILE-DETAIL AT END MOVE 'Y' TO WS-DETAIL-EOF NOT AT END ADD 1 TO WS-DETL-READ-COUNT PERFORM 4300-CHECK-DETL-SEQUENCE MOVE STD-KEY OF DETAIL-REC TO WS-PREV-DETL-KEY PERFORM 4100-VALIDATE-DETAIL END-READ END-IF ELSE IF NOT WS-MASTER-END ADD 1 TO WS-UNMATCH-MAST-COUNT PERFORM 5300-WRITE-MAST-UNMATCH READ FILE-MASTER AT END MOVE 'Y' TO WS-MASTER-EOF NOT AT END ADD 1 TO WS-MAST-READ-COUNT MOVE STD-KEY OF MASTER-REC TO WS-PREV-MAST-KEY PERFORM 4000-VALIDATE-MASTER END-READ END-IF IF NOT WS-DETAIL-END ADD 1 TO WS-UNMATCH-DETL-COUNT PERFORM 5400-WRITE-DETL-UNMATCH READ FILE-DETAIL AT END MOVE 'Y' TO WS-DETAIL-EOF NOT AT END ADD 1 TO WS-DETL-READ-COUNT MOVE STD-KEY OF DETAIL-REC TO WS-PREV-DETL-KEY PERFORM 4100-VALIDATE-DETAIL END-READ END-IF END-IF END-PERFORM *> CLOSE files (original logic) CLOSE FILE-MASTER CLOSE FILE-DETAIL CLOSE FILE-OUT *> Close error and audit files, write summary CLOSE FILE-ERR PERFORM 7000-AUDIT-TRAIL PERFORM 8000-FINALIZE *> ORIGINAL: Display PASS DISPLAY '01-matching-1-1: PASS' STOP RUN . *> ============================================================ *> 1000-INITIALIZE — Initialize counters and display header *> ============================================================ 1000-INITIALIZE. MOVE FUNCTION CURRENT-DATE(1:8) TO WS-PROC-DATE MOVE FUNCTION CURRENT-DATE(9:8) TO WS-PROC-TIME MOVE FUNCTION CURRENT-DATE(1:8) TO WS-TS-DATE MOVE FUNCTION CURRENT-DATE(9:8) TO WS-TS-TIME MOVE FUNCTION CURRENT-DATE(1:8) TO WS-RUN-DATE MOVE FUNCTION CURRENT-DATE(9:8) TO WS-RUN-TIME DISPLAY "============================================" DISPLAY "01-MATCHING-1-1 Invoice-Payment Matching" DISPLAY "Version V2.00" DISPLAY "Run date: " WS-PROC-DATE " " WS-PROC-TIME DISPLAY "============================================" INITIALIZE WS-COUNTERS INITIALIZE WS-HASH-TOTALS INITIALIZE WS-AGING INITIALIZE WS-STATUS-TRACKING INITIALIZE WS-VALIDATION . *> ============================================================ *> 2000-OPEN-FILES — Open all files with STATUS checks *> ============================================================ 2000-OPEN-FILES. MOVE '2000-OPEN-FILES' TO WS-PGM-PHASE DISPLAY "[" WS-TS-DATE " " WS-TS-TIME "] 01-MATCHING: Opening files..." OPEN INPUT FILE-MASTER IF WS-MASTER-STATUS NOT = '00' MOVE 'FATAL' TO WS-OVERALL-STATUS STRING "FATAL: Cannot open master.dat, status " WS-MASTER-STATUS INTO WS-ERR-MSG END-STRING PERFORM 6000-FATAL-ERROR END-IF OPEN INPUT FILE-DETAIL IF WS-DETAIL-STATUS NOT = '00' MOVE 'FATAL' TO WS-OVERALL-STATUS STRING "FATAL: Cannot open detail.dat, status " WS-DETAIL-STATUS INTO WS-ERR-MSG END-STRING PERFORM 6000-FATAL-ERROR END-IF OPEN OUTPUT FILE-OUT IF WS-OUT-STATUS NOT = '00' MOVE 'FATAL' TO WS-OVERALL-STATUS STRING "FATAL: Cannot open output.dat, status " WS-OUT-STATUS INTO WS-ERR-MSG END-STRING PERFORM 6000-FATAL-ERROR END-IF OPEN OUTPUT FILE-ERR IF WS-ERR-STATUS NOT = '00' MOVE 'FATAL' TO WS-OVERALL-STATUS STRING "FATAL: Cannot open error.dat, status " WS-ERR-STATUS INTO WS-ERR-MSG END-STRING PERFORM 6000-FATAL-ERROR END-IF OPEN OUTPUT AUDIT-FILE IF WS-AUDIT-STATUS NOT = '00' DISPLAY "WARNING: Cannot open audit-report.txt, " "status " WS-AUDIT-STATUS ADD 1 TO WS-WARN-COUNT END-IF PERFORM 7010-WRITE-AUDIT-HEADER . *> ============================================================ *> 4000-VALIDATE-MASTER — Validate master record *> ============================================================ 4000-VALIDATE-MASTER. *> Check key format (alphanumeric characters only) MOVE 'N' TO WS-KEY-INVALID-FLAG PERFORM VARYING WS-IDX FROM 1 BY 1 UNTIL WS-IDX > 10 OR WS-KEY-INVALID MOVE STD-KEY OF MASTER-REC(WS-IDX:1) TO WS-KEY-CHAR MOVE 'N' TO WS-CHAR-OK IF WS-KEY-CHAR >= 'A' AND WS-KEY-CHAR <= 'Z' MOVE 'Y' TO WS-CHAR-OK END-IF IF WS-KEY-CHAR >= '0' AND WS-KEY-CHAR <= '9' MOVE 'Y' TO WS-CHAR-OK END-IF IF WS-KEY-CHAR = '-' MOVE 'Y' TO WS-CHAR-OK END-IF IF NOT WS-CHAR-IS-OK MOVE 'Y' TO WS-KEY-INVALID-FLAG END-IF END-PERFORM IF WS-KEY-INVALID ADD 1 TO WS-KEY-FMT-ERR-COUNT ADD 1 TO WS-WARN-COUNT STRING "WARN: Invalid key format in master: " STD-KEY OF MASTER-REC INTO WS-ERR-MSG END-STRING PERFORM 6100-WARNING-ERROR END-IF *> Accumulate input hash total from master STD-DATA-3 (amount) MOVE STD-DATA-3 OF MASTER-REC TO WS-MAST-AMT-NUM ADD WS-MAST-AMT-NUM TO WS-INPUT-HASH-MAST . *> ============================================================ *> 4100-VALIDATE-DETAIL — Validate detail record *> ============================================================ 4100-VALIDATE-DETAIL. *> Check key format MOVE 'N' TO WS-KEY-INVALID-FLAG PERFORM VARYING WS-IDX FROM 1 BY 1 UNTIL WS-IDX > 10 OR WS-KEY-INVALID MOVE STD-KEY OF DETAIL-REC(WS-IDX:1) TO WS-KEY-CHAR MOVE 'N' TO WS-CHAR-OK IF WS-KEY-CHAR >= 'A' AND WS-KEY-CHAR <= 'Z' MOVE 'Y' TO WS-CHAR-OK END-IF IF WS-KEY-CHAR >= '0' AND WS-KEY-CHAR <= '9' MOVE 'Y' TO WS-CHAR-OK END-IF IF WS-KEY-CHAR = '-' MOVE 'Y' TO WS-CHAR-OK END-IF IF NOT WS-CHAR-IS-OK MOVE 'Y' TO WS-KEY-INVALID-FLAG END-IF END-PERFORM IF WS-KEY-INVALID ADD 1 TO WS-KEY-FMT-ERR-COUNT ADD 1 TO WS-WARN-COUNT STRING "WARN: Invalid key format in detail: " STD-KEY OF DETAIL-REC INTO WS-ERR-MSG END-STRING PERFORM 6100-WARNING-ERROR END-IF *> Accumulate input hash total from detail STD-DATA-3 MOVE STD-DATA-3 OF DETAIL-REC TO WS-DETL-AMT-NUM ADD WS-DETL-AMT-NUM TO WS-INPUT-HASH-DETL . *> ============================================================ *> 4200-CHECK-MAST-SEQUENCE — Verify master keys ascending *> ============================================================ 4200-CHECK-MAST-SEQUENCE. IF STD-KEY OF MASTER-REC < WS-PREV-MAST-KEY ADD 1 TO WS-SEQ-ERR-COUNT ADD 1 TO WS-ERROR-COUNT DISPLAY "ERROR: Master sequence violation: " WS-PREV-MAST-KEY " > " STD-KEY OF MASTER-REC STRING "ERROR: Master seq violation prev=" WS-PREV-MAST-KEY " curr=" STD-KEY OF MASTER-REC INTO WS-ERR-DETAIL END-STRING PERFORM 6200-FILE-ERROR END-IF . *> ============================================================ *> 4300-CHECK-DETL-SEQUENCE — Verify detail keys ascending *> ============================================================ 4300-CHECK-DETL-SEQUENCE. IF STD-KEY OF DETAIL-REC < WS-PREV-DETL-KEY ADD 1 TO WS-SEQ-ERR-COUNT ADD 1 TO WS-ERROR-COUNT DISPLAY "ERROR: Detail sequence violation: " WS-PREV-DETL-KEY " > " STD-KEY OF DETAIL-REC STRING "ERROR: Detail seq violation prev=" WS-PREV-DETL-KEY " curr=" STD-KEY OF DETAIL-REC INTO WS-ERR-DETAIL END-STRING PERFORM 6200-FILE-ERROR END-IF . *> ============================================================ *> 5000-PARTIAL-MATCH-CHECK — Amount tolerance comparison *> ============================================================ 5000-PARTIAL-MATCH-CHECK. *> Compare amounts from master and detail with tolerance MOVE STD-DATA-3 OF MASTER-REC TO WS-MAST-AMT-NUM MOVE STD-DATA-3 OF DETAIL-REC TO WS-DETL-AMT-NUM SUBTRACT WS-DETL-AMT-NUM FROM WS-MAST-AMT-NUM GIVING WS-AMT-DIFF IF WS-AMT-DIFF < 0 MULTIPLY WS-AMT-DIFF BY -1 GIVING WS-AMT-ABS-DIFF ELSE MOVE WS-AMT-DIFF TO WS-AMT-ABS-DIFF END-IF IF WS-AMT-ABS-DIFF > 0 MOVE WS-AMT-ABS-DIFF TO WS-TOLERANCE-DISP DISPLAY "TRACE: Amount diff " WS-TOLERANCE-DISP " for key " STD-KEY OF MASTER-REC IF WS-AMT-ABS-DIFF > WS-TOLERANCE ADD 1 TO WS-PARTIAL-MATCH-COUNT ADD 1 TO WS-WARN-COUNT STRING "WARN: Amount exceeds tolerance key=" STD-KEY OF MASTER-REC INTO WS-ERR-MSG END-STRING PERFORM 6100-WARNING-ERROR ELSE ADD 1 TO WS-PARTIAL-MATCH-COUNT DISPLAY "TRACE: Partial match within tolerance" " key=" STD-KEY OF MASTER-REC END-IF END-IF . *> ============================================================ *> 5100-ACCUMULATE-OUTPUT — Accumulate output hash totals *> ============================================================ 5100-ACCUMULATE-OUTPUT. MOVE STD-DATA-3 OF OUT-REC TO WS-DETL-AMT-NUM ADD WS-DETL-AMT-NUM TO WS-OUTPUT-HASH . *> ============================================================ *> 5200-ACCUMULATE-ERROR — Accumulate error hash totals *> ============================================================ 5200-ACCUMULATE-ERROR. ADD WS-AMT-ABS-DIFF TO WS-ERROR-HASH . *> ============================================================ *> 5300-WRITE-MAST-UNMATCH — Write unmatched master to error *> ============================================================ 5300-WRITE-MAST-UNMATCH. MOVE 'MAST-UNMTC' TO ERR-TYPE MOVE STD-KEY OF MASTER-REC TO ERR-KEY MOVE STD-DATA-1 OF MASTER-REC(1:10) TO ERR-CUST MOVE STD-DATA-3 OF MASTER-REC TO WS-MAST-AMT-NUM MOVE WS-MAST-AMT-NUM TO ERR-AMOUNT WRITE ERR-REC . *> ============================================================ *> 5400-WRITE-DETL-UNMATCH — Write unmatched detail to error *> ============================================================ 5400-WRITE-DETL-UNMATCH. MOVE 'DETL-UNMTC' TO ERR-TYPE MOVE STD-KEY OF DETAIL-REC TO ERR-KEY MOVE STD-DATA-1 OF DETAIL-REC(1:10) TO ERR-CUST MOVE STD-DATA-3 OF DETAIL-REC TO WS-DETL-AMT-NUM MOVE WS-DETL-AMT-NUM TO ERR-AMOUNT WRITE ERR-REC . *> ============================================================ *> 6000-FATAL-ERROR — Fatal error handler, terminates program *> ============================================================ 6000-FATAL-ERROR. ADD 1 TO WS-FATAL-COUNT DISPLAY "FATAL [" WS-TS-DATE " " WS-TS-TIME "] " WS-ERR-MSG MOVE 16 TO RETURN-CODE STOP RUN . *> ============================================================ *> 6100-WARNING-ERROR — Warning handler, non-fatal *> ============================================================ 6100-WARNING-ERROR. ADD 1 TO WS-WARN-COUNT DISPLAY "WARNING [" WS-TS-DATE " " WS-TS-TIME "] " WS-ERR-MSG . *> ============================================================ *> 6200-FILE-ERROR — File error handler, non-fatal *> ============================================================ 6200-FILE-ERROR. ADD 1 TO WS-ERROR-COUNT DISPLAY "ERROR [" WS-TS-DATE " " WS-TS-TIME "] " WS-ERR-DETAIL . *> ============================================================ *> 7000-AUDIT-TRAIL — Write audit summary report *> ============================================================ 7000-AUDIT-TRAIL. MOVE '7000-AUDIT-TRAIL' TO WS-PGM-PHASE DISPLAY "[" WS-TS-DATE " " WS-TS-TIME "] 01-MATCHING: Writing audit report..." PERFORM 7020-WRITE-AUDIT-SUMMARY PERFORM 7030-WRITE-HASH-DETAIL PERFORM 7040-WRITE-ERROR-SUMMARY PERFORM 7050-WRITE-AGING-REPORT PERFORM 7060-WRITE-AUDIT-FOOTER CLOSE AUDIT-FILE . *> ============================================================ *> 7010-WRITE-AUDIT-HEADER — Write audit report header *> ============================================================ 7010-WRITE-AUDIT-HEADER. MOVE SPACES TO AUDIT-REC STRING "================================================" INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING "01-MATCHING-1-1 AUDIT REPORT" INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING "Program Version: V2.00" INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING "Run Date: " WS-PROC-DATE " Time: " WS-PROC-TIME INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING "================================================" INTO AUDIT-REC END-STRING WRITE AUDIT-REC . *> ============================================================ *> 7020-WRITE-AUDIT-SUMMARY — Write record count summary *> ============================================================ 7020-WRITE-AUDIT-SUMMARY. MOVE SPACES TO AUDIT-REC STRING "RECORD COUNT SUMMARY:" INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING " Master records read : " WS-MAST-READ-COUNT INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING " Detail records read : " WS-DETL-READ-COUNT INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING " Matched records : " WS-MATCH-COUNT INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING " Unmatched master : " WS-UNMATCH-MAST-COUNT INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING " Unmatched detail : " WS-UNMATCH-DETL-COUNT INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING " Partial matches : " WS-PARTIAL-MATCH-COUNT INTO AUDIT-REC END-STRING WRITE AUDIT-REC . *> ============================================================ *> 7030-WRITE-HASH-DETAIL — Write hash total reconciliation *> ============================================================ 7030-WRITE-HASH-DETAIL. MOVE SPACES TO AUDIT-REC STRING " " INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING "HASH TOTAL RECONCILIATION:" INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING " Input hash (master) : " WS-INPUT-HASH-MAST INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING " Input hash (detail) : " WS-INPUT-HASH-DETL INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING " Output hash : " WS-OUTPUT-HASH INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING " Error hash : " WS-ERROR-HASH INTO AUDIT-REC END-STRING WRITE AUDIT-REC ADD WS-OUTPUT-HASH TO WS-ERROR-HASH GIVING WS-HASH-DIFF SUBTRACT WS-INPUT-HASH-MAST FROM WS-HASH-DIFF IF WS-HASH-DIFF NOT = 0 MOVE SPACES TO AUDIT-REC STRING " ** HASH MISMATCH ** Difference: " WS-HASH-DIFF INTO AUDIT-REC END-STRING WRITE AUDIT-REC ELSE MOVE SPACES TO AUDIT-REC STRING " Hash total: VERIFIED (output+error = input)" INTO AUDIT-REC END-STRING WRITE AUDIT-REC END-IF .