feat: add benchmark-programs — 58 telecom COBOL test programs

作为子目录纳入系统,与核心测试管道协同

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
NB-076
2026-06-25 09:53:21 +08:00
parent 50f9f0f52f
commit 94400d50d4
278 changed files with 44125 additions and 0 deletions
@@ -0,0 +1,1473 @@
IDENTIFICATION DIVISION.
PROGRAM-ID. Main35Merge.
*> ============================================================
*> 35-merge : 多源CDR合并 (Multi-Source CDR Merge)
*> Input : merge-input1.dat (BSS-A CDR)
*> merge-input2.dat (BSS-B CDR)
*> merge-input3.dat (BSS-C CDR)
*> merge-input4.dat (BSS-D CDR - enhanced)
*> merge-input5.dat (BSS-E CDR - enhanced)
*> merge-input6.dat (BSS-F CDR - enhanced)
*> Output: merge-output.dat (統合CDR)
*> Report: merge-report.txt (合并处理报告)
*> Audit : merge-audit.txt (审计跟踪)
*> Stats : merge-stats.txt (合并统计)
*> Coverage: MR-N001~N009, MR-A001
*> ============================================================
*> Multi-source CDR MERGE for telecom billing mediation
*> Tests: 2-file merge, 3-file merge, duplicate keys,
*> OUTPUT PROCEDURE, unsorted input handling,
*> source tagging, dedup logic, conflict resolution,
*> source validation, merge statistics
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT FILE-IN1 ASSIGN TO "merge-input1.dat"
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS FS-IN1.
SELECT FILE-IN2 ASSIGN TO "merge-input2.dat"
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS FS-IN2.
SELECT FILE-IN3 ASSIGN TO "merge-input3.dat"
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS FS-IN3.
SELECT FILE-OUT ASSIGN TO "merge-output.dat"
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS FS-OUT.
SELECT FILE-WORK ASSIGN TO "merge-work.tmp"
FILE STATUS IS FS-WORK.
SELECT FILE-REPORT ASSIGN TO "merge-report.txt"
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS FS-REPORT.
SELECT FILE-AUDIT ASSIGN TO "merge-audit.txt"
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS FS-AUDIT.
SELECT FILE-STATS ASSIGN TO "merge-stats.txt"
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS FS-STATS.
*> Enhanced input files for source-tagged merge
SELECT FILE-IN4 ASSIGN TO "merge-input4.dat"
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS FS-IN4.
SELECT FILE-IN5 ASSIGN TO "merge-input5.dat"
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS FS-IN5.
SELECT FILE-IN6 ASSIGN TO "merge-input6.dat"
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS FS-IN6.
*> Enhanced work file with source tagging
SELECT FILE-WORK2 ASSIGN TO "merge-work2.tmp"
FILE STATUS IS FS-WORK2.
DATA DIVISION.
FILE SECTION.
FD FILE-IN1.
01 IN1-REC.
05 IN1-KEY PIC X(10).
05 IN1-DATA PIC X(20).
05 IN1-VALUE PIC 9(05).
FD FILE-IN2.
01 IN2-REC.
05 IN2-KEY PIC X(10).
05 IN2-DATA PIC X(20).
05 IN2-VALUE PIC 9(05).
FD FILE-IN3.
01 IN3-REC.
05 IN3-KEY PIC X(10).
05 IN3-DATA PIC X(20).
05 IN3-VALUE PIC 9(05).
FD FILE-OUT.
01 OUT-REC.
05 OUT-KEY PIC X(10).
05 OUT-DATA PIC X(20).
05 OUT-VALUE PIC 9(05).
SD FILE-WORK.
01 WORK-REC.
05 WR-KEY PIC X(10).
05 WR-DATA PIC X(20).
05 WR-VALUE PIC 9(05).
FD FILE-REPORT.
01 REPORT-REC PIC X(80).
FD FILE-AUDIT.
01 AUDIT-REC PIC X(80).
FD FILE-STATS.
01 STATS-REC PIC X(80).
*> Enhanced input files with source tag
FD FILE-IN4.
01 IN4-REC.
05 IN4-KEY PIC X(10).
05 IN4-DATA PIC X(20).
05 IN4-VALUE PIC 9(05).
05 IN4-SOURCE PIC X(05).
05 IN4-TIMESTAMP PIC 9(08).
FD FILE-IN5.
01 IN5-REC.
05 IN5-KEY PIC X(10).
05 IN5-DATA PIC X(20).
05 IN5-VALUE PIC 9(05).
05 IN5-SOURCE PIC X(05).
05 IN5-TIMESTAMP PIC 9(08).
FD FILE-IN6.
01 IN6-REC.
05 IN6-KEY PIC X(10).
05 IN6-DATA PIC X(20).
05 IN6-VALUE PIC 9(05).
05 IN6-SOURCE PIC X(05).
05 IN6-TIMESTAMP PIC 9(08).
*> Enhanced work file with source tagging
SD FILE-WORK2.
01 WORK2-REC.
05 W2R-KEY PIC X(10).
05 W2R-DATA PIC X(20).
05 W2R-VALUE PIC 9(05).
05 W2R-SOURCE PIC X(05).
05 W2R-TIMESTAMP PIC 9(08).
WORKING-STORAGE SECTION.
01 WS-TELECOM-REC.
COPY "telecom/TEL-CDR.cpy".
01 WS-EOF PIC X(01) VALUE "N".
88 WS-EOF-Y VALUE "Y".
01 WS-RECORD-COUNT PIC 9(02) VALUE 0.
01 WS-TOTAL-VALUE PIC 9(07) VALUE 0.
01 WS-MERGE-SOURCE PIC X(05).
01 WS-DETAIL-LINE.
05 DL-KEY PIC X(10).
05 FILLER PIC X(02) VALUE SPACES.
05 DL-DATA PIC X(20).
05 FILLER PIC X(02) VALUE SPACES.
05 DL-VALUE PIC Z(9)9.
05 FILLER PIC X(04) VALUE SPACES.
05 DL-SOURCE PIC X(05).
01 WS-HEADER-LINE.
05 FILLER PIC X(10) VALUE "KEY ".
05 FILLER PIC X(22) VALUE "DATA ".
05 FILLER PIC X(07) VALUE "VALUE ".
05 FILLER PIC X(05) VALUE "SRC ".
*> Test data for Input 1 (BSS System A CDRs, sorted ascending)
01 TEST1-DATA.
05 FILLER PIC X(35) VALUE
"CDRA00000113800138001 00100".
05 FILLER PIC X(35) VALUE
"CDRB00000113900139001 00200".
05 FILLER PIC X(35) VALUE
"CDRD00000113700137001 00400".
01 TEST1-REDEF REDEFINES TEST1-DATA.
05 T1-ENTRY OCCURS 3 TIMES.
10 T1-KEY PIC X(10).
10 T1-DATA PIC X(20).
10 T1-VALUE PIC 9(05).
*> Test data for Input 2 (BSS System B CDRs, sorted ascending)
01 TEST2-DATA.
05 FILLER PIC X(35) VALUE
"CDRA00000213600136001 00150".
05 FILLER PIC X(35) VALUE
"CDRC00000113500135001 00300".
05 FILLER PIC X(35) VALUE
"CDRE00000113400134001 00500".
01 TEST2-REDEF REDEFINES TEST2-DATA.
05 T2-ENTRY OCCURS 3 TIMES.
10 T2-KEY PIC X(10).
10 T2-DATA PIC X(20).
10 T2-VALUE PIC 9(05).
*> Test data for Input 3 (BSS System C CDRs, sorted ascending)
01 TEST3-DATA.
05 FILLER PIC X(35) VALUE
"CDRA00000313300133001 00175".
05 FILLER PIC X(35) VALUE
"CDRB00000213200132001 00250".
05 FILLER PIC X(35) VALUE
"CDRF00000113100131001 00600".
01 TEST3-REDEF REDEFINES TEST3-DATA.
05 T3-ENTRY OCCURS 3 TIMES.
10 T3-KEY PIC X(10).
10 T3-DATA PIC X(20).
10 T3-VALUE PIC 9(05).
01 IDX PIC 9(02).
*> ============================================================
*> New WS fields for enhanced merge processing
*> ============================================================
*> FILE STATUS fields
01 FS-IN1 PIC X(02).
88 FS-IN1-OK VALUE "00".
88 FS-IN1-EOF VALUE "10".
01 FS-IN2 PIC X(02).
88 FS-IN2-OK VALUE "00".
01 FS-IN3 PIC X(02).
88 FS-IN3-OK VALUE "00".
01 FS-OUT PIC X(02).
88 FS-OUT-OK VALUE "00".
01 FS-WORK PIC X(02).
01 FS-REPORT PIC X(02).
88 FS-REPORT-OK VALUE "00".
01 FS-AUDIT PIC X(02).
88 FS-AUDIT-OK VALUE "00".
01 FS-STATS PIC X(02).
88 FS-STATS-OK VALUE "00".
01 FS-IN4 PIC X(02).
88 FS-IN4-OK VALUE "00".
01 FS-IN5 PIC X(02).
88 FS-IN5-OK VALUE "00".
01 FS-IN6 PIC X(02).
88 FS-IN6-OK VALUE "00".
01 FS-WORK2 PIC X(02).
*> Current timestamp
01 WS-CURRENT-DATE-TIME.
05 WS-CDT-DATE PIC 9(08).
05 WS-CDT-TIME PIC 9(06).
05 WS-CDT-MS PIC 9(02).
05 WS-CDT-OFFSET PIC 9(04).
05 WS-CDT-SIGN PIC X(01).
*> Audit message buffer
01 WS-AUDIT-MESSAGE PIC X(55).
*> Audit entry
01 WS-AUDIT-LINE.
05 FILLER PIC X(01) VALUE SPACE.
05 WS-AL-DATE PIC 9(08).
05 FILLER PIC X(01) VALUE SPACE.
05 WS-AL-TIME PIC 9(06).
05 FILLER PIC X(01) VALUE SPACE.
05 WS-AL-SEVERITY PIC X(01).
05 FILLER PIC X(02) VALUE SPACE.
05 WS-AL-MESSAGE PIC X(55).
01 WS-ERROR-SEVERITY PIC X(01).
88 WS-ERR-INFO VALUE "I".
88 WS-ERR-WARN VALUE "W".
88 WS-ERR-ERROR VALUE "E".
88 WS-ERR-FATAL VALUE "F".
*> Merge statistics
01 WS-MERGE-STATS.
05 WS-MS-SRC1-COUNT PIC 9(09) VALUE 0.
05 WS-MS-SRC2-COUNT PIC 9(09) VALUE 0.
05 WS-MS-SRC3-COUNT PIC 9(09) VALUE 0.
05 WS-MS-SRC4-COUNT PIC 9(09) VALUE 0.
05 WS-MS-SRC5-COUNT PIC 9(09) VALUE 0.
05 WS-MS-SRC6-COUNT PIC 9(09) VALUE 0.
05 WS-MS-TOTAL-MERGED PIC 9(09) VALUE 0.
05 WS-MS-DUP-REMOVED PIC 9(09) VALUE 0.
05 WS-MS-INVALID-COUNT PIC 9(09) VALUE 0.
05 WS-MS-HASH-TOTAL PIC 9(15) VALUE 0.
*> Detail line for enhanced merge output
01 WS-ENH-DETAIL-LINE.
05 FILLER PIC X(02) VALUE SPACE.
05 EDL-KEY PIC X(10).
05 FILLER PIC X(01) VALUE SPACE.
05 EDL-DATA PIC X(20).
05 FILLER PIC X(01) VALUE SPACE.
05 EDL-VALUE PIC Z(9)9.
05 FILLER PIC X(02) VALUE SPACE.
05 EDL-SOURCE PIC X(05).
05 FILLER PIC X(02) VALUE SPACE.
05 EDL-TIMESTAMP PIC 9(08).
*> Dedup tracking
01 WS-PREV-MERGE-KEY PIC X(10).
01 WS-PREV-MERGE-SOURCE PIC X(05).
01 WS-PREV-MERGE-TS PIC 9(08).
*> Source priority table
01 WS-SOURCE-PRIORITY.
05 WS-SP-ENTRY OCCURS 6 TIMES.
10 WS-SP-NAME PIC X(05).
10 WS-SP-RANK PIC 9(01).
*> Source names for stats
01 WS-SOURCE-NAMES.
05 FILLER PIC X(35) VALUE
"BSS-A BSS-B BSS-C BSS-D BSS-E BSS-F".
01 WS-SOURCE-NAMES-REDEF REDEFINES WS-SOURCE-NAMES.
05 WS-SN-ENTRY OCCURS 6 TIMES.
10 WS-SN-NAME PIC X(05).
*> Enhanced test data for source-tagged inputs
*> Format: key(10) + data(20) + value(5) + source(5) + timestamp(8) = 48
01 ENH4-DATA.
05 FILLER PIC X(48) VALUE
"CDRA00000113800138001 00100BSS-A 20260601".
05 FILLER PIC X(48) VALUE
"CDRB00000113900139001 00200BSS-A 20260601".
05 FILLER PIC X(48) VALUE
"CDRC00000113700137001 00300BSS-A 20260601".
01 ENH4-REDEF REDEFINES ENH4-DATA.
05 E4-ENTRY OCCURS 3 TIMES.
10 E4-KEY PIC X(10).
10 E4-DATA PIC X(20).
10 E4-VALUE PIC 9(05).
10 E4-SOURCE PIC X(05).
10 E4-TIMESTAMP PIC 9(08).
01 ENH5-DATA.
05 FILLER PIC X(48) VALUE
"CDRA00000113800138001 00150BSS-B 20260602".
05 FILLER PIC X(48) VALUE
"CDRB00000213600136001 00250BSS-B 20260602".
05 FILLER PIC X(48) VALUE
"CDRD00000113500135001 00400BSS-B 20260602".
01 ENH5-REDEF REDEFINES ENH5-DATA.
05 E5-ENTRY OCCURS 3 TIMES.
10 E5-KEY PIC X(10).
10 E5-DATA PIC X(20).
10 E5-VALUE PIC 9(05).
10 E5-SOURCE PIC X(05).
10 E5-TIMESTAMP PIC 9(08).
01 ENH6-DATA.
05 FILLER PIC X(48) VALUE
"CDRA00000113800138001 00175BSS-C 20260603".
05 FILLER PIC X(48) VALUE
"CDRB00000313400134001 00350BSS-C 20260603".
05 FILLER PIC X(48) VALUE
"CDRE00000113300133001 00500BSS-C 20260603".
01 ENH6-REDEF REDEFINES ENH6-DATA.
05 E6-ENTRY OCCURS 3 TIMES.
10 E6-KEY PIC X(10).
10 E6-DATA PIC X(20).
10 E6-VALUE PIC 9(05).
10 E6-SOURCE PIC X(05).
10 E6-TIMESTAMP PIC 9(08).
01 ENH-IDX PIC 9(02).
*> Report header templates
01 WS-RPT-HEADER1.
05 FILLER PIC X(30) VALUE
"MERGE REPORT - RUN AT ".
05 RPT1-DATE PIC 9(08).
05 FILLER PIC X(01) VALUE SPACE.
05 RPT1-TIME PIC 9(06).
01 WS-RPT-HEADER2.
05 FILLER PIC X(80) VALUE ALL "=".
PROCEDURE DIVISION.
MAIN-PROCEDURE.
OPEN OUTPUT FILE-REPORT.
*> ========================================
*> MR-N001: 2-file MERGE
*> ========================================
DISPLAY "=== MR-N001: 2-file MERGE ===".
MOVE "MR-N001: 2-file MERGE" TO REPORT-REC.
WRITE REPORT-REC.
PERFORM WRITE-HEADER.
PERFORM INIT-FILE1.
PERFORM INIT-FILE2.
MERGE FILE-WORK ON ASCENDING KEY WR-KEY
USING FILE-IN1, FILE-IN2
GIVING FILE-OUT.
PERFORM DISPLAY-MERGE-OUTPUT.
*> ========================================
*> MR-N002: 3-file MERGE
*> ========================================
DISPLAY "=== MR-N002: 3-file MERGE ===".
MOVE "MR-N002: 3-file MERGE" TO REPORT-REC.
WRITE REPORT-REC.
PERFORM WRITE-HEADER.
PERFORM INIT-FILE1.
PERFORM INIT-FILE2.
PERFORM INIT-FILE3.
MERGE FILE-WORK ON ASCENDING KEY WR-KEY
USING FILE-IN1, FILE-IN2, FILE-IN3
GIVING FILE-OUT.
PERFORM DISPLAY-MERGE-OUTPUT.
*> ========================================
*> MR-N003: Duplicate key MERGE
*> ========================================
DISPLAY "=== MR-N003: Duplicate key MERGE ===".
MOVE "MR-N003: Duplicate key MERGE" TO REPORT-REC.
WRITE REPORT-REC.
PERFORM WRITE-HEADER.
*> Create input files with overlapping keys
PERFORM INIT-DUP-FILE1.
PERFORM INIT-DUP-FILE2.
MERGE FILE-WORK ON ASCENDING KEY WR-KEY
USING FILE-IN1, FILE-IN2
GIVING FILE-OUT.
PERFORM DISPLAY-MERGE-OUTPUT.
*> ========================================
*> MR-N004: MERGE with OUTPUT PROCEDURE
*> ========================================
DISPLAY "=== MR-N004: MERGE with OUTPUT PROCEDURE ===".
MOVE "MR-N004: MERGE OUTPUT PROCEDURE" TO REPORT-REC.
WRITE REPORT-REC.
PERFORM WRITE-HEADER.
PERFORM INIT-FILE1.
PERFORM INIT-FILE2.
MERGE FILE-WORK ON ASCENDING KEY WR-KEY
USING FILE-IN1, FILE-IN2
OUTPUT PROCEDURE IS MERGE-OUTPUT-PROC.
PERFORM DISPLAY-MERGE-OUTPUT.
*> ========================================
*> MR-A001: Unsorted input (expected anomaly)
*> ========================================
DISPLAY "=== MR-A001: Unsorted input (anomaly) ===".
MOVE "MR-A001: Unsorted input" TO REPORT-REC.
WRITE REPORT-REC.
OPEN OUTPUT FILE-IN1.
MOVE "CDR-Z-0001PHONE-13800138001 00100" TO IN1-REC.
WRITE IN1-REC.
MOVE "CDR-A-0001PHONE-13900139001 00200" TO IN1-REC.
WRITE IN1-REC.
CLOSE FILE-IN1.
OPEN OUTPUT FILE-IN2.
MOVE "CDR-G-0001PHONE-13700137001 00300" TO IN2-REC.
WRITE IN2-REC.
MOVE "CDR-B-0001PHONE-13600136001 00400" TO IN2-REC.
WRITE IN2-REC.
CLOSE FILE-IN2.
MERGE FILE-WORK ON ASCENDING KEY WR-KEY
USING FILE-IN1, FILE-IN2
GIVING FILE-OUT.
DISPLAY " (Note: MERGE with unsorted input may produce"
DISPLAY " unpredictable results. This is expected."
PERFORM DISPLAY-MERGE-OUTPUT.
*> ================================================================
*> MR-N005: 3-file enhanced MERGE with source tagging
*> Uses FILE-WORK2 and source-tagged inputs
*> ================================================================
DISPLAY "=== MR-N005: 3-file source-tagged MERGE ===".
PERFORM 1000-INIT.
PERFORM INIT-FILE4.
PERFORM INIT-FILE5.
PERFORM INIT-FILE6.
MERGE FILE-WORK2 ON ASCENDING KEY W2R-KEY
USING FILE-IN4, FILE-IN5, FILE-IN6
GIVING FILE-OUT.
PERFORM DISPLAY-ENH-MERGE-OUTPUT.
DISPLAY " MR-N005: Source-tagged merge complete".
*> ================================================================
*> MR-N006: MERGE with OUTPUT PROCEDURE and source identification
*> ================================================================
DISPLAY "=== MR-N006: MERGE OUTPUT PROCEDURE with source ===".
PERFORM 1000-INIT.
PERFORM INIT-FILE4.
PERFORM INIT-FILE5.
PERFORM INIT-FILE6.
MERGE FILE-WORK2 ON ASCENDING KEY W2R-KEY
USING FILE-IN4, FILE-IN5, FILE-IN6
OUTPUT PROCEDURE IS ENH-MERGE-OUTPUT-PROC.
DISPLAY " MR-N006: Source-identified merge complete".
MOVE "MR-N006: Source-identified merge complete"
TO WS-AUDIT-MESSAGE.
MOVE "I" TO WS-ERROR-SEVERITY.
PERFORM 5000-AUDIT.
*> ================================================================
*> MR-N007: Dedup merge - same key from different sources
*> Keep newest record (highest timestamp)
*> ================================================================
DISPLAY "=== MR-N007: Dedup merge (keep newest) ===".
PERFORM 1000-INIT.
*> Create files with overlapping keys at different timestamps
PERFORM INIT-DUP-FILE4.
PERFORM INIT-DUP-FILE5.
PERFORM INIT-DUP-FILE6.
MERGE FILE-WORK2 ON ASCENDING KEY W2R-KEY
DESCENDING KEY W2R-TIMESTAMP
USING FILE-IN4, FILE-IN5, FILE-IN6
OUTPUT PROCEDURE IS DEDUP-MERGE-OUTPUT.
PERFORM WRITE-MERGE-STATS.
DISPLAY " MR-N007: Dedup merge complete".
MOVE "MR-N007: Dedup merge (keep newest) complete"
TO WS-AUDIT-MESSAGE.
MOVE "I" TO WS-ERROR-SEVERITY.
PERFORM 5000-AUDIT.
*> ================================================================
*> MR-N008: Source file validation before merge
*> ================================================================
DISPLAY "=== MR-N008: Source file validation ===".
PERFORM 1000-INIT.
PERFORM INIT-FILE4.
PERFORM INIT-FILE5.
PERFORM INIT-FILE6.
PERFORM VALIDATE-SOURCE-FILES.
IF WS-ERROR-SEVERITY NOT = "F"
MERGE FILE-WORK2 ON ASCENDING KEY W2R-KEY
USING FILE-IN4, FILE-IN5, FILE-IN6
OUTPUT PROCEDURE IS ENH-MERGE-OUTPUT-PROC
DISPLAY " MR-N008: Merge after validation complete"
ELSE
DISPLAY " MR-N008: Skipped due to validation failure"
END-IF.
MOVE "MR-N008: Source validation completed"
TO WS-AUDIT-MESSAGE.
MOVE "I" TO WS-ERROR-SEVERITY.
PERFORM 5000-AUDIT.
*> ================================================================
*> MR-N009: Conflict resolution with priority rules
*> BSS-A > BSS-B > BSS-C for conflicts
*> ================================================================
DISPLAY "=== MR-N009: Conflict resolution by priority ===".
PERFORM 1000-INIT.
PERFORM INIT-CONFLICT-FILES.
MERGE FILE-WORK2 ON ASCENDING KEY W2R-KEY
USING FILE-IN4, FILE-IN5, FILE-IN6
OUTPUT PROCEDURE IS CONFLICT-RESOLVE-OUTPUT.
PERFORM WRITE-MERGE-STATS.
DISPLAY " MR-N009: Conflict resolution complete".
MOVE "MR-N009: Conflict resolution by priority complete"
TO WS-AUDIT-MESSAGE.
MOVE "I" TO WS-ERROR-SEVERITY.
PERFORM 5000-AUDIT.
*> Close all files and finish
CLOSE FILE-REPORT.
CLOSE FILE-AUDIT.
CLOSE FILE-STATS.
DISPLAY "=== All MR-N001..N009 + A001 complete ===".
STOP RUN.
*> ================================================================
*> Existing paragraphs (preserved exactly)
*> ================================================================
WRITE-HEADER.
MOVE WS-HEADER-LINE TO REPORT-REC.
WRITE REPORT-REC.
MOVE SPACES TO REPORT-REC.
WRITE REPORT-REC.
INIT-FILE1.
OPEN OUTPUT FILE-IN1.
PERFORM VARYING IDX FROM 1 BY 1 UNTIL IDX > 3
MOVE T1-KEY(IDX) TO IN1-KEY
MOVE T1-DATA(IDX) TO IN1-DATA
MOVE T1-VALUE(IDX) TO IN1-VALUE
WRITE IN1-REC
END-PERFORM.
CLOSE FILE-IN1.
INIT-FILE2.
OPEN OUTPUT FILE-IN2.
PERFORM VARYING IDX FROM 1 BY 1 UNTIL IDX > 3
MOVE T2-KEY(IDX) TO IN2-KEY
MOVE T2-DATA(IDX) TO IN2-DATA
MOVE T2-VALUE(IDX) TO IN2-VALUE
WRITE IN2-REC
END-PERFORM.
CLOSE FILE-IN2.
INIT-FILE3.
OPEN OUTPUT FILE-IN3.
PERFORM VARYING IDX FROM 1 BY 1 UNTIL IDX > 3
MOVE T3-KEY(IDX) TO IN3-KEY
MOVE T3-DATA(IDX) TO IN3-DATA
MOVE T3-VALUE(IDX) TO IN3-VALUE
WRITE IN3-REC
END-PERFORM.
CLOSE FILE-IN3.
INIT-DUP-FILE1.
OPEN OUTPUT FILE-IN1.
MOVE "CDR-D00001" TO IN1-KEY.
MOVE "DUP-FILE1-CALL-001 " TO IN1-DATA.
MOVE 00100 TO IN1-VALUE.
WRITE IN1-REC.
MOVE "CDR-D00002" TO IN1-KEY.
MOVE "DUP-FILE1-CALL-002 " TO IN1-DATA.
MOVE 00200 TO IN1-VALUE.
WRITE IN1-REC.
CLOSE FILE-IN1.
INIT-DUP-FILE2.
OPEN OUTPUT FILE-IN2.
MOVE "CDR-D00001" TO IN2-KEY.
MOVE "DUP-FILE2-CALL-001 " TO IN2-DATA.
MOVE 00300 TO IN2-VALUE.
WRITE IN2-REC.
MOVE "CDR-D00003" TO IN2-KEY.
MOVE "DUP-FILE2-CALL-003 " TO IN2-DATA.
MOVE 00400 TO IN2-VALUE.
WRITE IN2-REC.
CLOSE FILE-IN2.
DISPLAY-MERGE-OUTPUT.
OPEN INPUT FILE-OUT.
MOVE 0 TO WS-RECORD-COUNT.
MOVE 0 TO WS-TOTAL-VALUE.
MOVE "N" TO WS-EOF.
PERFORM UNTIL WS-EOF-Y
READ FILE-OUT INTO OUT-REC
AT END
MOVE "Y" TO WS-EOF
NOT AT END
ADD 1 TO WS-RECORD-COUNT
ADD OUT-VALUE TO WS-TOTAL-VALUE
MOVE OUT-KEY TO DL-KEY
MOVE OUT-DATA TO DL-DATA
MOVE OUT-VALUE TO DL-VALUE
MOVE SPACES TO DL-SOURCE
DISPLAY " " WS-DETAIL-LINE
MOVE WS-DETAIL-LINE TO REPORT-REC
WRITE REPORT-REC
END-READ
END-PERFORM.
CLOSE FILE-OUT.
DISPLAY " Total records: " WS-RECORD-COUNT
" Total value: " WS-TOTAL-VALUE.
MOVE SPACES TO REPORT-REC.
WRITE REPORT-REC.
STRING " Total records: " WS-RECORD-COUNT
" Total value: " WS-TOTAL-VALUE
DELIMITED BY SIZE INTO REPORT-REC.
WRITE REPORT-REC.
MOVE SPACES TO REPORT-REC.
WRITE REPORT-REC.
MERGE-OUTPUT-PROC SECTION.
*> OUTPUT PROCEDURE for MERGE - adds source tagging
OPEN OUTPUT FILE-OUT.
MOVE "N" TO WS-EOF.
PERFORM UNTIL WS-EOF-Y
RETURN FILE-WORK INTO WORK-REC
AT END
MOVE "Y" TO WS-EOF
NOT AT END
MOVE WORK-REC TO OUT-REC
WRITE OUT-REC
END-RETURN
END-PERFORM.
CLOSE FILE-OUT.
*> ================================================================
*> New enhanced sections
*> ================================================================
*> ----------------------------------------------------------------
*> 1000-INIT: Initialize batch totals, open audit/stats files
*> ----------------------------------------------------------------
1000-INIT SECTION.
MOVE FUNCTION CURRENT-DATE TO WS-CURRENT-DATE-TIME.
MOVE 0 TO WS-MS-SRC1-COUNT
MOVE 0 TO WS-MS-SRC2-COUNT
MOVE 0 TO WS-MS-SRC3-COUNT
MOVE 0 TO WS-MS-SRC4-COUNT
MOVE 0 TO WS-MS-SRC5-COUNT
MOVE 0 TO WS-MS-SRC6-COUNT
MOVE 0 TO WS-MS-TOTAL-MERGED
MOVE 0 TO WS-MS-DUP-REMOVED
MOVE 0 TO WS-MS-INVALID-COUNT
MOVE 0 TO WS-MS-HASH-TOTAL
MOVE SPACES TO WS-PREV-MERGE-KEY
MOVE SPACES TO WS-PREV-MERGE-SOURCE
MOVE ZEROS TO WS-PREV-MERGE-TS
MOVE "I" TO WS-ERROR-SEVERITY.
*> Initialize source priority (lower rank = higher priority)
MOVE "BSS-A" TO WS-SP-NAME(1)
MOVE 1 TO WS-SP-RANK(1)
MOVE "BSS-B" TO WS-SP-NAME(2)
MOVE 2 TO WS-SP-RANK(2)
MOVE "BSS-C" TO WS-SP-NAME(3)
MOVE 3 TO WS-SP-RANK(3)
MOVE "BSS-D" TO WS-SP-NAME(4)
MOVE 4 TO WS-SP-RANK(4)
MOVE "BSS-E" TO WS-SP-NAME(5)
MOVE 5 TO WS-SP-RANK(5)
MOVE "BSS-F" TO WS-SP-NAME(6)
MOVE 6 TO WS-SP-RANK(6).
DISPLAY " 1000-INIT at " WS-CDT-DATE "/" WS-CDT-TIME.
OPEN OUTPUT FILE-AUDIT.
IF NOT FS-AUDIT-OK
DISPLAY "ERROR: FILE-AUDIT open failed, FS=" FS-AUDIT
MOVE "E" TO WS-ERROR-SEVERITY
END-IF.
OPEN OUTPUT FILE-STATS.
IF NOT FS-STATS-OK
DISPLAY "ERROR: FILE-STATS open failed, FS=" FS-STATS
MOVE "E" TO WS-ERROR-SEVERITY
END-IF.
MOVE "1000-INIT: Initialization complete"
TO WS-AUDIT-MESSAGE.
PERFORM 5000-AUDIT.
EXIT.
*> ----------------------------------------------------------------
*> 2000-OPEN-FILES: Enhanced file open with FILE STATUS
*> ----------------------------------------------------------------
2000-OPEN-FILES SECTION.
DISPLAY " 2000-OPEN-FILES: Opening merge files...".
OPEN OUTPUT FILE-IN4.
IF NOT FS-IN4-OK
DISPLAY "ERROR 2000: FILE-IN4 open failed, FS=" FS-IN4
MOVE "E" TO WS-ERROR-SEVERITY
PERFORM 6000-ERROR-HANDLE
END-IF.
OPEN OUTPUT FILE-IN5.
IF NOT FS-IN5-OK
DISPLAY "ERROR 2000: FILE-IN5 open failed, FS=" FS-IN5
MOVE "E" TO WS-ERROR-SEVERITY
PERFORM 6000-ERROR-HANDLE
END-IF.
OPEN OUTPUT FILE-IN6.
IF NOT FS-IN6-OK
DISPLAY "ERROR 2000: FILE-IN6 open failed, FS=" FS-IN6
MOVE "E" TO WS-ERROR-SEVERITY
PERFORM 6000-ERROR-HANDLE
END-IF.
MOVE "2000-OPEN-FILES: Enhanced files opened"
TO WS-AUDIT-MESSAGE.
PERFORM 5000-AUDIT.
EXIT.
*> ----------------------------------------------------------------
*> 3000-PROCESS: Main merge processing pipeline
*> ----------------------------------------------------------------
3000-PROCESS SECTION.
DISPLAY " 3000-PROCESS: Executing merge...".
MERGE FILE-WORK2 ON ASCENDING KEY W2R-KEY
USING FILE-IN4, FILE-IN5, FILE-IN6
OUTPUT PROCEDURE IS ENH-MERGE-OUTPUT-PROC.
MOVE "3000-PROCESS: Merge pipeline complete"
TO WS-AUDIT-MESSAGE.
PERFORM 5000-AUDIT.
EXIT.
*> ----------------------------------------------------------------
*> 4000-REPORT: Generate merge summary report
*> ----------------------------------------------------------------
4000-REPORT SECTION.
DISPLAY " 4000-REPORT: Generating merge report...".
MOVE WS-CDT-DATE TO RPT1-DATE.
MOVE WS-CDT-TIME TO RPT1-TIME.
MOVE WS-RPT-HEADER1 TO REPORT-REC.
WRITE REPORT-REC.
MOVE WS-RPT-HEADER2 TO REPORT-REC.
WRITE REPORT-REC.
MOVE "4000-REPORT: Merge report generated"
TO WS-AUDIT-MESSAGE.
PERFORM 5000-AUDIT.
EXIT.
*> ----------------------------------------------------------------
*> 5000-AUDIT: Write audit entry with timestamp/severity
*> ----------------------------------------------------------------
5000-AUDIT SECTION.
MOVE FUNCTION CURRENT-DATE TO WS-CURRENT-DATE-TIME.
MOVE WS-CDT-DATE TO WS-AL-DATE.
MOVE WS-CDT-TIME TO WS-AL-TIME.
MOVE WS-ERROR-SEVERITY TO WS-AL-SEVERITY.
IF WS-AL-SEVERITY = SPACE
MOVE "I" TO WS-AL-SEVERITY
END-IF.
MOVE WS-AUDIT-MESSAGE TO WS-AL-MESSAGE.
MOVE WS-AUDIT-LINE TO AUDIT-REC.
WRITE AUDIT-REC.
IF NOT FS-AUDIT-OK
DISPLAY "AUDIT WRITE FAILED: FS=" FS-AUDIT
END-IF.
DISPLAY " AUDIT [" WS-AL-SEVERITY "] "
WS-AL-DATE "/" WS-AL-TIME " "
WS-AL-MESSAGE.
EXIT.
*> ----------------------------------------------------------------
*> 6000-ERROR-HANDLE: Handle errors with severity levels
*> ----------------------------------------------------------------
6000-ERROR-HANDLE SECTION.
EVALUATE WS-ERROR-SEVERITY
WHEN "I"
DISPLAY " INFO: Recoverable condition"
WHEN "W"
DISPLAY " WARN: Non-critical issue detected"
PERFORM 5000-AUDIT
WHEN "E"
DISPLAY " ERROR: Processing may be affected"
PERFORM 5000-AUDIT
WHEN "F"
DISPLAY " FATAL: Aborting processing"
PERFORM 5000-AUDIT
STOP RUN
WHEN OTHER
DISPLAY " INFO: Unknown severity - continuing"
END-EVALUATE.
MOVE "I" TO WS-ERROR-SEVERITY.
EXIT.
*> ----------------------------------------------------------------
*> 9000-EXIT: Clean exit with file closure
*> ----------------------------------------------------------------
9000-EXIT SECTION.
DISPLAY " 9000-EXIT: Closing files and exiting...".
CLOSE FILE-AUDIT.
CLOSE FILE-STATS.
CLOSE FILE-REPORT.
MOVE "9000-EXIT: Normal termination" TO WS-AUDIT-MESSAGE.
MOVE "I" TO WS-ERROR-SEVERITY.
PERFORM 5000-AUDIT.
DISPLAY " 9000-EXIT: All files closed. Exiting.".
EXIT.
*> ================================================================
*> INIT-FILE4: Create enhanced input file 4 (BSS-D)
*> ================================================================
INIT-FILE4.
OPEN OUTPUT FILE-IN4.
IF NOT FS-IN4-OK
DISPLAY "ERROR INIT-FILE4: open failed, FS=" FS-IN4
MOVE "E" TO WS-ERROR-SEVERITY
PERFORM 6000-ERROR-HANDLE
END-IF.
PERFORM VARYING ENH-IDX FROM 1 BY 1 UNTIL ENH-IDX > 3
MOVE E4-KEY(ENH-IDX) TO IN4-KEY
MOVE E4-DATA(ENH-IDX) TO IN4-DATA
MOVE E4-VALUE(ENH-IDX) TO IN4-VALUE
MOVE E4-SOURCE(ENH-IDX) TO IN4-SOURCE
MOVE E4-TIMESTAMP(ENH-IDX) TO IN4-TIMESTAMP
WRITE IN4-REC
IF NOT FS-IN4-OK
DISPLAY "ERROR: FILE-IN4 write failed, FS=" FS-IN4
END-IF
END-PERFORM.
CLOSE FILE-IN4.
DISPLAY " INIT-FILE4: 3 source-tagged records written".
EXIT.
*> ================================================================
*> INIT-FILE5: Create enhanced input file 5 (BSS-E)
*> ================================================================
INIT-FILE5.
OPEN OUTPUT FILE-IN5.
IF NOT FS-IN5-OK
DISPLAY "ERROR INIT-FILE5: open failed, FS=" FS-IN5
MOVE "E" TO WS-ERROR-SEVERITY
PERFORM 6000-ERROR-HANDLE
END-IF.
PERFORM VARYING ENH-IDX FROM 1 BY 1 UNTIL ENH-IDX > 3
MOVE E5-KEY(ENH-IDX) TO IN5-KEY
MOVE E5-DATA(ENH-IDX) TO IN5-DATA
MOVE E5-VALUE(ENH-IDX) TO IN5-VALUE
MOVE E5-SOURCE(ENH-IDX) TO IN5-SOURCE
MOVE E5-TIMESTAMP(ENH-IDX) TO IN5-TIMESTAMP
WRITE IN5-REC
IF NOT FS-IN5-OK
DISPLAY "ERROR: FILE-IN5 write failed, FS=" FS-IN5
END-IF
END-PERFORM.
CLOSE FILE-IN5.
DISPLAY " INIT-FILE5: 3 source-tagged records written".
EXIT.
*> ================================================================
*> INIT-FILE6: Create enhanced input file 6 (BSS-F)
*> ================================================================
INIT-FILE6.
OPEN OUTPUT FILE-IN6.
IF NOT FS-IN6-OK
DISPLAY "ERROR INIT-FILE6: open failed, FS=" FS-IN6
MOVE "E" TO WS-ERROR-SEVERITY
PERFORM 6000-ERROR-HANDLE
END-IF.
PERFORM VARYING ENH-IDX FROM 1 BY 1 UNTIL ENH-IDX > 3
MOVE E6-KEY(ENH-IDX) TO IN6-KEY
MOVE E6-DATA(ENH-IDX) TO IN6-DATA
MOVE E6-VALUE(ENH-IDX) TO IN6-VALUE
MOVE E6-SOURCE(ENH-IDX) TO IN6-SOURCE
MOVE E6-TIMESTAMP(ENH-IDX) TO IN6-TIMESTAMP
WRITE IN6-REC
IF NOT FS-IN6-OK
DISPLAY "ERROR: FILE-IN6 write failed, FS=" FS-IN6
END-IF
END-PERFORM.
CLOSE FILE-IN6.
DISPLAY " INIT-FILE6: 3 source-tagged records written".
EXIT.
*> ================================================================
*> INIT-DUP-FILE4/DUP-FILE5/DUP-FILE6: Duplicate key files
*> ================================================================
INIT-DUP-FILE4.
OPEN OUTPUT FILE-IN4.
IF NOT FS-IN4-OK
DISPLAY "ERROR INIT-DUP4: open failed, FS=" FS-IN4
END-IF.
MOVE "CDR-CONF01" TO IN4-KEY.
MOVE "CONFLICT-CDR-001-A " TO IN4-DATA.
MOVE 00100 TO IN4-VALUE.
MOVE "BSS-D" TO IN4-SOURCE.
MOVE 20260601 TO IN4-TIMESTAMP.
WRITE IN4-REC.
MOVE "CDR-CONF02" TO IN4-KEY.
MOVE "CONFLICT-CDR-002-A " TO IN4-DATA.
MOVE 00200 TO IN4-VALUE.
MOVE "BSS-D" TO IN4-SOURCE.
MOVE 20260601 TO IN4-TIMESTAMP.
WRITE IN4-REC.
CLOSE FILE-IN4.
DISPLAY " INIT-DUP-FILE4: 2 records (1 conflict)".
EXIT.
INIT-DUP-FILE5.
OPEN OUTPUT FILE-IN5.
IF NOT FS-IN5-OK
DISPLAY "ERROR INIT-DUP5: open failed, FS=" FS-IN5
END-IF.
MOVE "CDR-CONF01" TO IN5-KEY.
MOVE "CONFLICT-CDR-001-B " TO IN5-DATA.
MOVE 00150 TO IN5-VALUE.
MOVE "BSS-E" TO IN5-SOURCE.
MOVE 20260602 TO IN5-TIMESTAMP.
WRITE IN5-REC.
MOVE "CDR-CONF03" TO IN5-KEY.
MOVE "CONFLICT-CDR-003-B " TO IN5-DATA.
MOVE 00300 TO IN5-VALUE.
MOVE "BSS-E" TO IN5-SOURCE.
MOVE 20260602 TO IN5-TIMESTAMP.
WRITE IN5-REC.
CLOSE FILE-IN5.
DISPLAY " INIT-DUP-FILE5: 2 records (1 conflict)".
EXIT.
INIT-DUP-FILE6.
OPEN OUTPUT FILE-IN6.
IF NOT FS-IN6-OK
DISPLAY "ERROR INIT-DUP6: open failed, FS=" FS-IN6
END-IF.
MOVE "CDR-CONF01" TO IN6-KEY.
MOVE "CONFLICT-CDR-001-C " TO IN6-DATA.
MOVE 00175 TO IN6-VALUE.
MOVE "BSS-F" TO IN6-SOURCE.
MOVE 20260603 TO IN6-TIMESTAMP.
WRITE IN6-REC.
MOVE "CDR-CONF04" TO IN6-KEY.
MOVE "CONFLICT-CDR-004-C " TO IN6-DATA.
MOVE 00400 TO IN6-VALUE.
MOVE "BSS-F" TO IN6-SOURCE.
MOVE 20260603 TO IN6-TIMESTAMP.
WRITE IN6-REC.
CLOSE FILE-IN6.
DISPLAY " INIT-DUP-FILE6: 2 records (1 conflict)".
EXIT.
*> ================================================================
*> INIT-CONFLICT-FILES: Create files for conflict resolution test
*> ================================================================
INIT-CONFLICT-FILES.
*> FILE-IN4 (BSS-D - highest priority)
OPEN OUTPUT FILE-IN4.
MOVE "CDR-CONF01" TO IN4-KEY.
MOVE "PRIORITY-A-VERSION " TO IN4-DATA.
MOVE 00100 TO IN4-VALUE.
MOVE "BSS-D" TO IN4-SOURCE.
MOVE 20260601 TO IN4-TIMESTAMP.
WRITE IN4-REC.
MOVE "CDR-UNIQU1" TO IN4-KEY.
MOVE "UNIQUE-A-RECORD " TO IN4-DATA.
MOVE 00200 TO IN4-VALUE.
MOVE "BSS-D" TO IN4-SOURCE.
MOVE 20260601 TO IN4-TIMESTAMP.
WRITE IN4-REC.
CLOSE FILE-IN4.
*> FILE-IN5 (BSS-E - medium priority)
OPEN OUTPUT FILE-IN5.
MOVE "CDR-CONF01" TO IN5-KEY.
MOVE "PRIORITY-B-VERSION " TO IN5-DATA.
MOVE 00150 TO IN5-VALUE.
MOVE "BSS-E" TO IN5-SOURCE.
MOVE 20260602 TO IN5-TIMESTAMP.
WRITE IN5-REC.
MOVE "CDR-CONF02" TO IN5-KEY.
MOVE "CONFLICT-TWO-B " TO IN5-DATA.
MOVE 00300 TO IN5-VALUE.
MOVE "BSS-E" TO IN5-SOURCE.
MOVE 20260602 TO IN5-TIMESTAMP.
WRITE IN5-REC.
CLOSE FILE-IN5.
*> FILE-IN6 (BSS-F - lowest priority)
OPEN OUTPUT FILE-IN6.
MOVE "CDR-CONF01" TO IN6-KEY.
MOVE "PRIORITY-C-VERSION " TO IN6-DATA.
MOVE 00175 TO IN6-VALUE.
MOVE "BSS-F" TO IN6-SOURCE.
MOVE 20260603 TO IN6-TIMESTAMP.
WRITE IN6-REC.
MOVE "CDR-CONF02" TO IN6-KEY.
MOVE "CONFLICT-TWO-C " TO IN6-DATA.
MOVE 00350 TO IN6-VALUE.
MOVE "BSS-F" TO IN6-SOURCE.
MOVE 20260603 TO IN6-TIMESTAMP.
WRITE IN6-REC.
CLOSE FILE-IN6.
DISPLAY " INIT-CONFLICT-FILES: 3 files with conflicts".
EXIT.
*> ================================================================
*> DISPLAY-ENH-MERGE-OUTPUT: Display enhanced merge output
*> ================================================================
DISPLAY-ENH-MERGE-OUTPUT.
OPEN INPUT FILE-OUT.
IF NOT FS-OUT-OK
DISPLAY "ERROR: FILE-OUT open failed, FS=" FS-OUT
EXIT
END-IF.
MOVE 0 TO WS-RECORD-COUNT.
MOVE 0 TO WS-TOTAL-VALUE.
MOVE "N" TO WS-EOF.
PERFORM UNTIL WS-EOF-Y
READ FILE-OUT INTO OUT-REC
AT END
MOVE "Y" TO WS-EOF
NOT AT END
ADD 1 TO WS-RECORD-COUNT
ADD OUT-VALUE TO WS-TOTAL-VALUE
MOVE OUT-KEY TO DL-KEY
MOVE OUT-DATA TO DL-DATA
MOVE OUT-VALUE TO DL-VALUE
MOVE "ENH" TO DL-SOURCE
DISPLAY " " WS-DETAIL-LINE
END-READ
END-PERFORM.
CLOSE FILE-OUT.
DISPLAY " Enhanced merged: " WS-RECORD-COUNT
" records, value=" WS-TOTAL-VALUE.
EXIT.
*> ================================================================
*> ENH-MERGE-OUTPUT-PROC: OUTPUT PROCEDURE with source ID
*> ================================================================
ENH-MERGE-OUTPUT-PROC SECTION.
DISPLAY " ENH-MERGE-OUTPUT-PROC: Source-identified output".
OPEN OUTPUT FILE-OUT.
IF NOT FS-OUT-OK
DISPLAY "ERROR: FILE-OUT open in OUTPUT PROC, FS=" FS-OUT
MOVE "E" TO WS-ERROR-SEVERITY
PERFORM 6000-ERROR-HANDLE
EXIT
END-IF.
MOVE 0 TO WS-MS-TOTAL-MERGED.
MOVE "N" TO WS-EOF.
PERFORM UNTIL WS-EOF-Y
RETURN FILE-WORK2 INTO WORK2-REC
AT END
MOVE "Y" TO WS-EOF
NOT AT END
ADD 1 TO WS-MS-TOTAL-MERGED
ADD W2R-VALUE TO WS-MS-HASH-TOTAL
*> Count by source
EVALUATE W2R-SOURCE
WHEN "BSS-A"
ADD 1 TO WS-MS-SRC1-COUNT
WHEN "BSS-B"
ADD 1 TO WS-MS-SRC2-COUNT
WHEN "BSS-C"
ADD 1 TO WS-MS-SRC3-COUNT
WHEN "BSS-D"
ADD 1 TO WS-MS-SRC4-COUNT
WHEN "BSS-E"
ADD 1 TO WS-MS-SRC5-COUNT
WHEN "BSS-F"
ADD 1 TO WS-MS-SRC6-COUNT
WHEN OTHER
ADD 1 TO WS-MS-INVALID-COUNT
END-EVALUATE
*> Map work record to output with source visible in data field
MOVE W2R-KEY TO OUT-KEY
MOVE W2R-DATA TO OUT-DATA(1:20)
MOVE W2R-VALUE TO OUT-VALUE
WRITE OUT-REC
IF NOT FS-OUT-OK
DISPLAY "ERROR: write failed, FS=" FS-OUT
END-IF
*> Display with source info
MOVE W2R-KEY TO EDL-KEY
MOVE W2R-DATA TO EDL-DATA
MOVE W2R-VALUE TO EDL-VALUE
MOVE W2R-SOURCE TO EDL-SOURCE
MOVE W2R-TIMESTAMP TO EDL-TIMESTAMP
DISPLAY WS-ENH-DETAIL-LINE
END-RETURN
END-PERFORM.
DISPLAY " ENH-MERGE-OUTPUT-PROC: total="
WS-MS-TOTAL-MERGED.
CLOSE FILE-OUT.
EXIT.
*> ================================================================
*> DEDUP-MERGE-OUTPUT: Dedup by key, keep newest (highest timestamp)
*> ================================================================
DEDUP-MERGE-OUTPUT SECTION.
DISPLAY " DEDUP-MERGE-OUTPUT: Deduplicating by key...".
OPEN OUTPUT FILE-OUT.
IF NOT FS-OUT-OK
DISPLAY "ERROR: FILE-OUT open in DEDUP, FS=" FS-OUT
MOVE "E" TO WS-ERROR-SEVERITY
PERFORM 6000-ERROR-HANDLE
EXIT
END-IF.
MOVE SPACES TO WS-PREV-MERGE-KEY.
MOVE 0 TO WS-MS-TOTAL-MERGED.
MOVE 0 TO WS-MS-DUP-REMOVED.
MOVE "N" TO WS-EOF.
*> Since MERGE sorts by KEY ASC and TIMESTAMP DESC,
*> the first occurrence of each key has the highest timestamp
PERFORM UNTIL WS-EOF-Y
RETURN FILE-WORK2 INTO WORK2-REC
AT END
MOVE "Y" TO WS-EOF
NOT AT END
IF W2R-KEY = WS-PREV-MERGE-KEY
*> Duplicate key - skip (already have newest)
ADD 1 TO WS-MS-DUP-REMOVED
DISPLAY " DEDUP removed: " W2R-KEY
" from " W2R-SOURCE
" timestamp=" W2R-TIMESTAMP
ELSE
*> New key - accept
MOVE W2R-KEY TO WS-PREV-MERGE-KEY
MOVE W2R-KEY TO OUT-KEY
MOVE W2R-DATA TO OUT-DATA(1:20)
MOVE W2R-VALUE TO OUT-VALUE
WRITE OUT-REC
ADD 1 TO WS-MS-TOTAL-MERGED
ADD W2R-VALUE TO WS-MS-HASH-TOTAL
DISPLAY " DEDUP kept: " W2R-KEY
" from " W2R-SOURCE
END-IF
END-RETURN
END-PERFORM.
DISPLAY " DEDUP-MERGE-OUTPUT: kept=" WS-MS-TOTAL-MERGED
" removed=" WS-MS-DUP-REMOVED.
CLOSE FILE-OUT.
EXIT.
*> ================================================================
*> VALIDATE-SOURCE-FILES: Check format of each source file
*> ================================================================
VALIDATE-SOURCE-FILES.
DISPLAY " VALIDATE-SOURCE-FILES: Checking formats...".
OPEN INPUT FILE-IN4.
IF NOT FS-IN4-OK
DISPLAY " VALIDATE: FILE-IN4 missing, FS=" FS-IN4
MOVE "E" TO WS-ERROR-SEVERITY
MOVE "VALIDATE: FILE-IN4 format check failed"
TO WS-AUDIT-MESSAGE
PERFORM 5000-AUDIT
ELSE
DISPLAY " VALIDATE: FILE-IN4 format OK"
CLOSE FILE-IN4
END-IF.
OPEN INPUT FILE-IN5.
IF NOT FS-IN5-OK
DISPLAY " VALIDATE: FILE-IN5 missing, FS=" FS-IN5
MOVE "E" TO WS-ERROR-SEVERITY
MOVE "VALIDATE: FILE-IN5 format check failed"
TO WS-AUDIT-MESSAGE
PERFORM 5000-AUDIT
ELSE
DISPLAY " VALIDATE: FILE-IN5 format OK"
CLOSE FILE-IN5
END-IF.
OPEN INPUT FILE-IN6.
IF NOT FS-IN6-OK
DISPLAY " VALIDATE: FILE-IN6 missing, FS=" FS-IN6
MOVE "E" TO WS-ERROR-SEVERITY
MOVE "VALIDATE: FILE-IN6 format check failed"
TO WS-AUDIT-MESSAGE
PERFORM 5000-AUDIT
ELSE
DISPLAY " VALIDATE: FILE-IN6 format OK"
CLOSE FILE-IN6
END-IF.
MOVE "VALIDATE: All source files validated"
TO WS-AUDIT-MESSAGE.
MOVE "I" TO WS-ERROR-SEVERITY.
PERFORM 5000-AUDIT.
EXIT.
*> ================================================================
*> CONFLICT-RESOLVE-OUTPUT: Resolve conflicts by source priority
*> ================================================================
CONFLICT-RESOLVE-OUTPUT SECTION.
DISPLAY " CONFLICT-RESOLVE-OUTPUT: Resolving conflicts...".
OPEN OUTPUT FILE-OUT.
IF NOT FS-OUT-OK
DISPLAY "ERROR: FILE-OUT open, FS=" FS-OUT
EXIT
END-IF.
MOVE SPACES TO WS-PREV-MERGE-KEY.
MOVE 0 TO WS-MS-TOTAL-MERGED.
MOVE 0 TO WS-MS-DUP-REMOVED.
MOVE "N" TO WS-EOF.
*> Since MERGE sorts by KEY, and we resolve by source priority:
*> For each key, keep the record from the highest priority source
*> MERGE produces interleaved output, so we process sequentially
PERFORM UNTIL WS-EOF-Y
RETURN FILE-WORK2 INTO WORK2-REC
AT END
MOVE "Y" TO WS-EOF
NOT AT END
IF W2R-KEY NOT = WS-PREV-MERGE-KEY
*> New key - accept and set as current
IF WS-PREV-MERGE-KEY NOT = SPACES
PERFORM WRITE-RESOLVED-RECORD
END-IF
MOVE W2R-KEY TO WS-PREV-MERGE-KEY
MOVE W2R-SOURCE TO WS-PREV-MERGE-SOURCE
MOVE W2R-TIMESTAMP TO WS-PREV-MERGE-TS
MOVE WORK2-REC TO OUT-REC
ELSE
*> Same key - conflict resolution
ADD 1 TO WS-MS-DUP-REMOVED
*> Check if this source has higher priority (lower rank)
PERFORM VARYING ENH-IDX FROM 1 BY 1
UNTIL ENH-IDX > 6
IF WS-PREV-MERGE-SOURCE =
WS-SP-NAME(ENH-IDX)
MOVE ENH-IDX TO IDX
END-IF
END-PERFORM
PERFORM VARYING ENH-IDX FROM 1 BY 1
UNTIL ENH-IDX > 6
IF W2R-SOURCE = WS-SP-NAME(ENH-IDX)
*> If current source has lower rank (higher priority),
*> replace the output record
IF ENH-IDX < IDX
MOVE W2R-SOURCE
TO WS-PREV-MERGE-SOURCE
MOVE W2R-TIMESTAMP
TO WS-PREV-MERGE-TS
MOVE WORK2-REC TO OUT-REC
DISPLAY " CONFLICT: "
W2R-KEY " "
W2R-SOURCE
" wins over "
WS-PREV-MERGE-SOURCE
ELSE
DISPLAY " CONFLICT: "
W2R-KEY " "
WS-PREV-MERGE-SOURCE
" keeps over "
W2R-SOURCE
END-IF
END-IF
END-PERFORM
END-IF
END-RETURN
END-PERFORM.
*> Write last record
IF WS-PREV-MERGE-KEY NOT = SPACES
PERFORM WRITE-RESOLVED-RECORD
END-IF.
DISPLAY " CONFLICT-RESOLVE: total=" WS-MS-TOTAL-MERGED
" conflicts-resolved=" WS-MS-DUP-REMOVED.
CLOSE FILE-OUT.
EXIT.
*> ================================================================
*> WRITE-RESOLVED-RECORD: Write a resolved merge record
*> ================================================================
WRITE-RESOLVED-RECORD.
WRITE OUT-REC.
IF NOT FS-OUT-OK
DISPLAY "ERROR: write failed, FS=" FS-OUT
ELSE
ADD 1 TO WS-MS-TOTAL-MERGED
ADD OUT-VALUE TO WS-MS-HASH-TOTAL
MOVE OUT-KEY TO EDL-KEY
MOVE OUT-DATA TO EDL-DATA
MOVE OUT-VALUE TO EDL-VALUE
MOVE WS-PREV-MERGE-SOURCE TO EDL-SOURCE
MOVE WS-PREV-MERGE-TS TO EDL-TIMESTAMP
DISPLAY " RESOLVED: " WS-ENH-DETAIL-LINE
END-IF.
EXIT.
*> ================================================================
*> WRITE-MERGE-STATS: Write merge statistics
*> ================================================================
WRITE-MERGE-STATS.
DISPLAY " WRITE-MERGE-STATS: Writing merge statistics...".
MOVE SPACES TO STATS-REC.
STRING "=== MERGE STATISTICS ==="
DELIMITED BY SIZE INTO STATS-REC.
WRITE STATS-REC.
MOVE SPACES TO STATS-REC.
STRING "Source A (BSS-D) = " WS-MS-SRC1-COUNT
DELIMITED BY SIZE INTO STATS-REC.
WRITE STATS-REC.
MOVE SPACES TO STATS-REC.
STRING "Source B (BSS-E) = " WS-MS-SRC2-COUNT
DELIMITED BY SIZE INTO STATS-REC.
WRITE STATS-REC.
MOVE SPACES TO STATS-REC.
STRING "Source C (BSS-F) = " WS-MS-SRC3-COUNT
DELIMITED BY SIZE INTO STATS-REC.
WRITE STATS-REC.
MOVE SPACES TO STATS-REC.
STRING "Source D (BSS-D) = " WS-MS-SRC4-COUNT
DELIMITED BY SIZE INTO STATS-REC.
WRITE STATS-REC.
MOVE SPACES TO STATS-REC.
STRING "Source E (BSS-E) = " WS-MS-SRC5-COUNT
DELIMITED BY SIZE INTO STATS-REC.
WRITE STATS-REC.
MOVE SPACES TO STATS-REC.
STRING "Source F (BSS-F) = " WS-MS-SRC6-COUNT
DELIMITED BY SIZE INTO STATS-REC.
WRITE STATS-REC.
MOVE SPACES TO STATS-REC.
STRING "Total merged = " WS-MS-TOTAL-MERGED
DELIMITED BY SIZE INTO STATS-REC.
WRITE STATS-REC.
MOVE SPACES TO STATS-REC.
STRING "Duplicates removed = " WS-MS-DUP-REMOVED
DELIMITED BY SIZE INTO STATS-REC.
WRITE STATS-REC.
MOVE SPACES TO STATS-REC.
STRING "Invalid records = " WS-MS-INVALID-COUNT
DELIMITED BY SIZE INTO STATS-REC.
WRITE STATS-REC.
MOVE SPACES TO STATS-REC.
STRING "Hash total (value) = " WS-MS-HASH-TOTAL
DELIMITED BY SIZE INTO STATS-REC.
WRITE STATS-REC.
DISPLAY " STATS: src1=" WS-MS-SRC1-COUNT
" src2=" WS-MS-SRC2-COUNT
" src3=" WS-MS-SRC3-COUNT
" total=" WS-MS-TOTAL-MERGED
" dup-removed=" WS-MS-DUP-REMOVED.
EXIT.