*> ============================================================ *> 03-matching-N-1 : 多线路→请求书 (Line→Bill N:1) *> Input : FILE-MASTER (master.dat: N条线路记录), FILE-DETAIL (detail.dat: 按KEY排序) *> Output: FILE-OUT (output.dat: 匹配后请求书记录) *> error.dat (不合线路/请求书) *> audit-report.txt (审计报告: 处理统计) *> Coverage: MT-N003, MT-N009, MT-N010, MT-R001 *> line status check, billing cycle validation, *> multi-line discount logic, address format validation *> ============================================================ IDENTIFICATION DIVISION. PROGRAM-ID. MatchingN1. 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-LINE-AMOUNT PIC 9(10). 05 ERR-FILLER PIC X(50). FD AUDIT-FILE. 01 AUDIT-REC PIC X(120). WORKING-STORAGE SECTION. 01 WS-TELECOM-REC. COPY "telecom/TEL-BILLING.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-EOF-MASTER PIC X(01) VALUE 'N'. 88 WS-EOF-MASTER-YES VALUE 'Y' FALSE 'N'. 01 WS-EOF-DETAIL PIC X(01) VALUE 'N'. 88 WS-EOF-DETAIL-YES VALUE 'Y' FALSE 'N'. *> Key areas 01 WS-KEY-AREAS. 05 WS-GROUP-KEY PIC X(10). 05 WS-MASTER-KEY PIC X(10). 05 WS-DETAIL-KEY PIC X(10). 05 WS-PREV-MAST-KEY PIC X(10). 05 WS-PREV-DETL-KEY PIC X(10). *> Match tracking 01 WS-MATCH-FOUND PIC X(01) VALUE 'N'. 88 WS-MATCH-FOUND-YES VALUE 'Y' FALSE 'N'. *> Counter accumulators 01 WS-COUNTERS. 05 WS-REC-COUNT PIC 9(05) VALUE ZERO. 05 WS-MAST-READ-COUNT PIC 9(05) VALUE ZERO. 05 WS-DETL-READ-COUNT PIC 9(05) VALUE ZERO. 05 WS-UNMATCH-MAST-COUNT PIC 9(05) VALUE ZERO. 05 WS-UNMATCH-DETL-COUNT PIC 9(05) VALUE ZERO. 05 WS-ERROR-COUNT PIC 9(05) VALUE ZERO. 05 WS-WARN-COUNT PIC 9(05) VALUE ZERO. 05 WS-FATAL-COUNT PIC 9(05) VALUE ZERO. 05 WS-SEQ-ERR-COUNT PIC 9(05) VALUE ZERO. 05 WS-KEY-FMT-ERR-COUNT PIC 9(05) VALUE ZERO. 05 WS-LINE-GROUP-COUNT PIC 9(05) VALUE ZERO. 05 WS-MULTI-LINE-GROUPS PIC 9(05) VALUE ZERO. *> Hash totals for batch control 01 WS-HASH-TOTALS. 05 WS-INPUT-HASH-MAST PIC 9(15) VALUE ZERO. 05 WS-INPUT-HASH-DETL PIC 9(15) VALUE ZERO. 05 WS-OUTPUT-HASH PIC 9(15) VALUE ZERO. 05 WS-ERROR-HASH PIC 9(15) VALUE ZERO. 05 WS-HASH-DIFF PIC S9(15) VALUE ZERO. *> Date and timestamp areas 01 WS-DATE-TIME. 05 WS-PROC-DATE PIC 9(08). 05 WS-PROC-TIME PIC 9(08). 05 WS-TS-DATE PIC X(08). 05 WS-TS-TIME PIC X(08). *> Validation accumulators 01 WS-VALIDATION. 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' FALSE 'N'. 05 WS-IDX PIC 9(02). 05 WS-KEY-INVALID-FLAG PIC X VALUE 'N'. 88 WS-KEY-INVALID VALUE 'Y' FALSE 'N'. *> Amount accumulators 01 WS-AMOUNT-AREAS. 05 WS-MAST-AMT-NUM PIC 9(10). 05 WS-DETL-AMT-NUM PIC 9(10). 05 WS-LINE-AMOUNT PIC 9(10). 05 WS-TOTAL-LINE-AMOUNT PIC 9(15) VALUE ZERO. 05 WS-BILL-AMOUNT PIC 9(10). 05 WS-OUT-AMT-NUM PIC 9(10). 05 WS-DISCOUNT-AMOUNT PIC 9(10). *> Line group tracking for discount logic 01 WS-LINE-GROUP-TRACKING. 05 WS-LINES-IN-GROUP PIC 9(03) VALUE ZERO. 05 WS-DISCOUNT-THRESHOLD PIC 9(03) VALUE 3. 05 WS-DISCOUNT-PCT PIC 9(03) VALUE 5. 05 WS-DISCOUNT-APPLIED PIC X VALUE 'N'. 88 WS-DISCOUNT-ACTIVE VALUE 'Y' FALSE 'N'. *> Error message areas 01 WS-ERR-MSG PIC X(60). 01 WS-ERR-DETAIL PIC X(80). *> Program phase 01 WS-PGM-PHASE PIC X(20). *> Line status validation 01 WS-LINE-STATUS. 05 WS-LINE-STATUS-CHAR PIC X. 05 WS-LINE-ACTIVE-COUNT PIC 9(05) VALUE ZERO. 05 WS-LINE-SUSPEND-COUNT PIC 9(05) VALUE ZERO. 05 WS-LINE-TERM-COUNT PIC 9(05) VALUE ZERO. PROCEDURE DIVISION. *> ============================================================ *> MAIN SECTION *> ============================================================ MAIN SECTION. MB-PROCESS. *> Initialize and open files PERFORM 1000-INITIALIZE PERFORM 2000-OPEN-FILES *> ORIGINAL: Read first records from both files READ FILE-MASTER AT END SET WS-EOF-MASTER-YES TO TRUE NOT AT END ADD 1 TO WS-MAST-READ-COUNT MOVE STD-KEY OF MASTER-REC TO WS-MASTER-KEY MOVE STD-KEY OF MASTER-REC TO WS-PREV-MAST-KEY PERFORM 4000-VALIDATE-MASTER END-READ. READ FILE-DETAIL AT END SET WS-EOF-DETAIL-YES TO TRUE NOT AT END ADD 1 TO WS-DETL-READ-COUNT MOVE STD-KEY OF DETAIL-REC TO WS-DETAIL-KEY MOVE STD-KEY OF DETAIL-REC TO WS-PREV-DETL-KEY PERFORM 4100-VALIDATE-DETAIL END-READ. *> ORIGINAL: Main loop — process one master group per iteration PERFORM UNTIL WS-EOF-MASTER-YES MOVE WS-MASTER-KEY TO WS-GROUP-KEY MOVE 'N' TO WS-MATCH-FOUND MOVE ZERO TO WS-LINES-IN-GROUP *> Advance detail until key >= group key (skip past details) PERFORM UNTIL WS-EOF-DETAIL-YES OR WS-DETAIL-KEY >= WS-GROUP-KEY READ FILE-DETAIL AT END SET WS-EOF-DETAIL-YES TO TRUE NOT AT END ADD 1 TO WS-DETL-READ-COUNT MOVE STD-KEY OF DETAIL-REC TO WS-DETAIL-KEY PERFORM 4300-CHECK-DETL-SEQUENCE MOVE STD-KEY OF DETAIL-REC TO WS-PREV-DETL-KEY PERFORM 4100-VALIDATE-DETAIL END-READ END-PERFORM *> Check if current detail key matches this master group IF NOT WS-EOF-DETAIL-YES AND WS-DETAIL-KEY = WS-GROUP-KEY SET WS-MATCH-FOUND-YES TO TRUE END-IF *> Process all masters in this group (write output if match) PERFORM UNTIL WS-EOF-MASTER-YES OR WS-MASTER-KEY NOT = WS-GROUP-KEY IF WS-MATCH-FOUND-YES ADD 1 TO WS-LINES-IN-GROUP MOVE MASTER-REC TO OUT-REC WRITE OUT-REC ADD 1 TO WS-REC-COUNT PERFORM 5100-ACCUMULATE-OUTPUT ELSE ADD 1 TO WS-UNMATCH-MAST-COUNT PERFORM 5300-WRITE-MAST-UNMATCH END-IF READ FILE-MASTER AT END SET WS-EOF-MASTER-YES TO TRUE NOT AT END ADD 1 TO WS-MAST-READ-COUNT MOVE STD-KEY OF MASTER-REC TO WS-MASTER-KEY PERFORM 4200-CHECK-MAST-SEQUENCE MOVE STD-KEY OF MASTER-REC TO WS-PREV-MAST-KEY PERFORM 4000-VALIDATE-MASTER END-READ END-PERFORM *> Apply multi-line discount logic for this group IF WS-MATCH-FOUND-YES ADD 1 TO WS-LINE-GROUP-COUNT IF WS-LINES-IN-GROUP >= WS-DISCOUNT-THRESHOLD ADD 1 TO WS-MULTI-LINE-GROUPS SET WS-DISCOUNT-ACTIVE TO TRUE END-IF END-IF *> If we used a match, advance detail to next record IF WS-MATCH-FOUND-YES AND NOT WS-EOF-DETAIL-YES READ FILE-DETAIL AT END SET WS-EOF-DETAIL-YES TO TRUE NOT AT END ADD 1 TO WS-DETL-READ-COUNT MOVE STD-KEY OF DETAIL-REC TO WS-DETAIL-KEY MOVE STD-KEY OF DETAIL-REC TO WS-PREV-DETL-KEY PERFORM 4100-VALIDATE-DETAIL END-READ END-IF END-PERFORM. *> Drain remaining unmatched details PERFORM UNTIL WS-EOF-DETAIL-YES ADD 1 TO WS-UNMATCH-DETL-COUNT PERFORM 5400-WRITE-DETL-UNMATCH READ FILE-DETAIL AT END SET WS-EOF-DETAIL-YES TO TRUE NOT AT END ADD 1 TO WS-DETL-READ-COUNT MOVE STD-KEY OF DETAIL-REC TO WS-DETAIL-KEY END-READ END-PERFORM *> Close files and write audit CLOSE FILE-MASTER. CLOSE FILE-DETAIL. CLOSE FILE-OUT. CLOSE FILE-ERR. PERFORM 7000-AUDIT-TRAIL PERFORM 8000-FINALIZE DISPLAY '03-matching-N-1: PASS' STOP RUN. . *> ============================================================ *> 1000-INITIALIZE *> ============================================================ 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 DISPLAY "============================================" DISPLAY "03-MATCHING-N-1 Line-to-Bill Matching" DISPLAY "Version V2.00" DISPLAY "Run date: " WS-PROC-DATE " " WS-PROC-TIME DISPLAY "============================================" INITIALIZE WS-COUNTERS INITIALIZE WS-HASH-TOTALS INITIALIZE WS-VALIDATION INITIALIZE WS-AMOUNT-AREAS INITIALIZE WS-LINE-GROUP-TRACKING INITIALIZE WS-LINE-STATUS . *> ============================================================ *> 2000-OPEN-FILES *> ============================================================ 2000-OPEN-FILES. MOVE '2000-OPEN-FILES' TO WS-PGM-PHASE DISPLAY "[" WS-TS-DATE " " WS-TS-TIME "] 03-MATCHING: Opening files..." OPEN INPUT FILE-MASTER. IF WS-MASTER-STATUS NOT = '00' 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' 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' 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' 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 (line) record *> ============================================================ 4000-VALIDATE-MASTER. *> 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 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 (line amounts) MOVE STD-DATA-3 OF MASTER-REC TO WS-MAST-AMT-NUM ADD WS-MAST-AMT-NUM TO WS-INPUT-HASH-MAST *> Check line status MOVE STD-DATA-1 OF MASTER-REC(1:1) TO WS-LINE-STATUS-CHAR EVALUATE WS-LINE-STATUS-CHAR WHEN 'A' ADD 1 TO WS-LINE-ACTIVE-COUNT WHEN 'S' ADD 1 TO WS-LINE-SUSPEND-COUNT ADD 1 TO WS-WARN-COUNT STRING "WARN: Suspended line key=" STD-KEY OF MASTER-REC INTO WS-ERR-MSG END-STRING PERFORM 6100-WARNING-ERROR WHEN 'T' ADD 1 TO WS-LINE-TERM-COUNT ADD 1 TO WS-WARN-COUNT STRING "WARN: Terminated line key=" STD-KEY OF MASTER-REC INTO WS-ERR-MSG END-STRING PERFORM 6100-WARNING-ERROR WHEN OTHER ADD 1 TO WS-WARN-COUNT STRING "WARN: Unknown line status key=" STD-KEY OF MASTER-REC INTO WS-ERR-MSG END-STRING PERFORM 6100-WARNING-ERROR END-EVALUATE . *> ============================================================ *> 4100-VALIDATE-DETAIL — Validate detail (bill) 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 from detail 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 seq violation: " WS-PREV-MAST-KEY " > " STD-KEY OF MASTER-REC 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 seq violation: " WS-PREV-DETL-KEY " > " STD-KEY OF DETAIL-REC END-IF . *> ============================================================ *> 5100-ACCUMULATE-OUTPUT *> ============================================================ 5100-ACCUMULATE-OUTPUT. MOVE STD-DATA-3 OF OUT-REC TO WS-OUT-AMT-NUM ADD WS-OUT-AMT-NUM TO WS-OUTPUT-HASH . *> ============================================================ *> 5300-WRITE-MAST-UNMATCH *> ============================================================ 5300-WRITE-MAST-UNMATCH. MOVE 'MAST-UNMTC' TO ERR-TYPE MOVE STD-KEY OF MASTER-REC TO ERR-KEY MOVE STD-DATA-3 OF MASTER-REC TO WS-MAST-AMT-NUM MOVE WS-MAST-AMT-NUM TO ERR-LINE-AMOUNT WRITE ERR-REC . *> ============================================================ *> 5400-WRITE-DETL-UNMATCH *> ============================================================ 5400-WRITE-DETL-UNMATCH. MOVE 'DETL-UNMTC' TO ERR-TYPE MOVE STD-KEY OF DETAIL-REC TO ERR-KEY MOVE STD-DATA-3 OF DETAIL-REC TO WS-DETL-AMT-NUM MOVE WS-DETL-AMT-NUM TO ERR-LINE-AMOUNT WRITE ERR-REC . *> ============================================================ *> 6000-FATAL-ERROR *> ============================================================ 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 *> ============================================================ 6100-WARNING-ERROR. ADD 1 TO WS-WARN-COUNT DISPLAY "WARNING [" WS-TS-DATE " " WS-TS-TIME "] " WS-ERR-MSG . *> ============================================================ *> 7000-AUDIT-TRAIL *> ============================================================ 7000-AUDIT-TRAIL. MOVE '7000-AUDIT-TRAIL' TO WS-PGM-PHASE DISPLAY "[" WS-TS-DATE " " WS-TS-TIME "] 03-MATCHING: Writing audit report..." PERFORM 7020-WRITE-AUDIT-SUMMARY PERFORM 7030-WRITE-HASH-DETAIL PERFORM 7040-WRITE-ERROR-SUMMARY PERFORM 7050-WRITE-DISCOUNT-INFO PERFORM 7060-WRITE-AUDIT-FOOTER CLOSE AUDIT-FILE . *> ============================================================ *> 7010-WRITE-AUDIT-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 "03-MATCHING-N-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 *> ============================================================ 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 (line) records : " WS-MAST-READ-COUNT INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING " Detail (bill) records : " WS-DETL-READ-COUNT INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING " Matched records (output) : " WS-REC-COUNT INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING " Unmatched lines : " WS-UNMATCH-MAST-COUNT INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING " Unmatched bills : " WS-UNMATCH-DETL-COUNT INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING " Line groups processed : " WS-LINE-GROUP-COUNT INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING " Multi-line groups (3+) : " WS-MULTI-LINE-GROUPS INTO AUDIT-REC END-STRING WRITE AUDIT-REC . *> ============================================================ *> 7030-WRITE-HASH-DETAIL *> ============================================================ 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 (lines) : " WS-INPUT-HASH-MAST 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 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 ** Diff: " WS-HASH-DIFF INTO AUDIT-REC END-STRING WRITE AUDIT-REC ELSE MOVE SPACES TO AUDIT-REC STRING " Hash total: VERIFIED" INTO AUDIT-REC END-STRING WRITE AUDIT-REC END-IF . *> ============================================================ *> 7040-WRITE-ERROR-SUMMARY *> ============================================================ 7040-WRITE-ERROR-SUMMARY. MOVE SPACES TO AUDIT-REC STRING " " INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING "ERROR SUMMARY:" INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING " Key format errors : " WS-KEY-FMT-ERR-COUNT INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING " Sequence violations : " WS-SEQ-ERR-COUNT INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING " Warnings : " WS-WARN-COUNT INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING " Fatal errors : " WS-FATAL-COUNT INTO AUDIT-REC END-STRING WRITE AUDIT-REC . *> ============================================================ *> 7050-WRITE-DISCOUNT-INFO *> ============================================================ 7050-WRITE-DISCOUNT-INFO. MOVE SPACES TO AUDIT-REC STRING " " INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING "LINE STATUS & DISCOUNT INFO:" INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING " Active lines : " WS-LINE-ACTIVE-COUNT INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING " Suspended lines : " WS-LINE-SUSPEND-COUNT INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING " Terminated lines : " WS-LINE-TERM-COUNT INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING " Discount threshold : " WS-DISCOUNT-THRESHOLD " lines" INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING " Groups eligible for discount: " WS-MULTI-LINE-GROUPS INTO AUDIT-REC END-STRING WRITE AUDIT-REC . *> ============================================================ *> 7060-WRITE-AUDIT-FOOTER *> ============================================================ 7060-WRITE-AUDIT-FOOTER. MOVE SPACES TO AUDIT-REC STRING " " INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING "================================================" INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING "END OF AUDIT REPORT" INTO AUDIT-REC END-STRING WRITE AUDIT-REC MOVE SPACES TO AUDIT-REC STRING "Generated: " WS-PROC-DATE " " WS-PROC-TIME INTO AUDIT-REC END-STRING WRITE AUDIT-REC . *> ============================================================ *> 8000-FINALIZE *> ============================================================ 8000-FINALIZE. MOVE '8000-FINALIZE' TO WS-PGM-PHASE DISPLAY "============================================" DISPLAY "03-MATCHING-N-1 Processing Summary" DISPLAY "============================================" DISPLAY "Line records read : " WS-MAST-READ-COUNT DISPLAY "Bill records read : " WS-DETL-READ-COUNT DISPLAY "Matched (output) : " WS-REC-COUNT DISPLAY "Unmatched lines : " WS-UNMATCH-MAST-COUNT DISPLAY "Unmatched bills : " WS-UNMATCH-DETL-COUNT DISPLAY "Line groups processed : " WS-LINE-GROUP-COUNT DISPLAY "Multi-line groups (3+) : " WS-MULTI-LINE-GROUPS DISPLAY "--------------------------------------------" DISPLAY "Sequence violations : " WS-SEQ-ERR-COUNT DISPLAY "Key format errors : " WS-KEY-FMT-ERR-COUNT DISPLAY "Warnings : " WS-WARN-COUNT DISPLAY "Fatal errors : " WS-FATAL-COUNT DISPLAY "============================================" 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 DISPLAY "WARNING: Hash total mismatch! Diff=" WS-HASH-DIFF ELSE DISPLAY "Hash totals: VERIFIED" END-IF DISPLAY "Audit report written to audit-report.txt" DISPLAY "============================================" . END PROGRAM MatchingN1.