feat: add benchmark-programs — 58 telecom COBOL test programs
作为子目录纳入系统,与核心测试管道协同 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
# 03-matching-N-1: N:1 Matching (N master records match one detail record)
|
||||
|
||||
## 电信业务场景
|
||||
|
||||
多线路→请求书汇集。读取多条电话线路记录(LINE)和请求地址文件(BILL-ADDR),按地址进行N:1汇集。同一个地址的多条线路汇总到一张请求书。
|
||||
|
||||
## Description
|
||||
|
||||
Tests N:1 matching where multiple master records sharing the same key match
|
||||
a single detail record. The program groups masters by key, finds the
|
||||
corresponding detail, and writes one output record per master that has a match.
|
||||
|
||||
## Record Layout
|
||||
|
||||
| Field | Type | Length | Description |
|
||||
|------------|-----------------|--------|---------------------------|
|
||||
| STD-KEY | PIC X | 10 | Record key |
|
||||
| STD-DATA-1 | PIC X | 20 | Description text |
|
||||
| STD-DATA-2 | PIC 9 | 10 | Numeric data (display) |
|
||||
| STD-DATA-3 | PIC S9(7)V99 | 05 | Numeric data (COMP-3) |
|
||||
|
||||
Total record length: 45 bytes.
|
||||
|
||||
## Files
|
||||
|
||||
| File | Purpose |
|
||||
|-----------------------------|-----------------------------------|
|
||||
| main-03-matching-N-1.cbl | Main COBOL program (fixed format) |
|
||||
| data-gen.sh | Generate test data files |
|
||||
| run.sh | Compile, run, verify |
|
||||
| README.md | This file |
|
||||
|
||||
## Data
|
||||
|
||||
- **master.dat**: 3 records, all with key `KEY00001` (N=3 masters)
|
||||
- **detail.dat**: 2 records — `KEY00001` (matches the 3 masters),
|
||||
`KEY00002` (unmatched, not referenced)
|
||||
|
||||
## Matching Logic
|
||||
|
||||
1. Read masters by group (all records sharing the same key).
|
||||
2. Advance the detail pointer to find a key matching the group.
|
||||
3. If a match is found, write one output record per master in the group.
|
||||
4. If no match is found, skip the entire master group.
|
||||
5. Unmatched detail records are also skipped.
|
||||
|
||||
## Test
|
||||
|
||||
| Check | Expected |
|
||||
|------------------------|------------------------|
|
||||
| Output records | 3 (3 masters x 1 match) |
|
||||
| Output file size | 135 bytes (3 x 45) |
|
||||
| Unmatched master groups| 0 (all 3 have a match) |
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
cd 03-matching-N-1
|
||||
bash run.sh
|
||||
```
|
||||
@@ -0,0 +1,35 @@
|
||||
================================================
|
||||
03-MATCHING-N-1 AUDIT REPORT
|
||||
Program Version: V2.00
|
||||
Run Date: 20260622 Time: 16452810
|
||||
================================================
|
||||
RECORD COUNT SUMMARY:
|
||||
Master (line) records : 00002
|
||||
Detail (bill) records : 00002
|
||||
Matched records (output) : 00002
|
||||
Unmatched lines : 00000
|
||||
Unmatched bills : 00000
|
||||
Line groups processed : 00002
|
||||
Multi-line groups (3+) : 00002
|
||||
|
||||
HASH TOTAL RECONCILIATION:
|
||||
Input hash (lines) : 000000006060606
|
||||
Output hash : 000000006060606
|
||||
Hash total: VERIFIED
|
||||
|
||||
ERROR SUMMARY:
|
||||
Key format errors : 00004
|
||||
Sequence violations : 00000
|
||||
Warnings : 00012
|
||||
Fatal errors : 00000
|
||||
|
||||
LINE STATUS & DISCOUNT INFO:
|
||||
Active lines : 00000
|
||||
Suspended lines : 00000
|
||||
Terminated lines : 00000
|
||||
Discount threshold : 000 lines
|
||||
Groups eligible for discount: 00002
|
||||
|
||||
================================================
|
||||
END OF AUDIT REPORT
|
||||
Generated: 20260622 16452810
|
||||
@@ -0,0 +1 @@
|
||||
0000000000000000000
|
||||
@@ -0,0 +1,854 @@
|
||||
*> ============================================================
|
||||
*> 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.
|
||||
@@ -0,0 +1 @@
|
||||
0000000000000000000
|
||||
@@ -0,0 +1 @@
|
||||
0000000000000000000 000000000000000
|
||||
Reference in New Issue
Block a user