*> ============================================================ *> 30-keybreak-other : 通话状态检测 (Call State Detect) *> Input : FILE-IN.DAT Output: FILE-OUT.DAT + FILE-AUDIT.DAT *> 2-level key detect, overflow, page control, hash totals, *> error severity, call state, group min/max/avg, grand total *> ============================================================ IDENTIFICATION DIVISION. PROGRAM-ID. KeyBreakOther. ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT FILE-IN ASSIGN TO "FILE-IN.DAT" ORGANIZATION IS LINE SEQUENTIAL FILE STATUS IS FS-IN. SELECT FILE-OUT ASSIGN TO "FILE-OUT.DAT" ORGANIZATION IS LINE SEQUENTIAL FILE STATUS IS FS-OUT. SELECT FILE-AUDIT ASSIGN TO "FILE-AUDIT.DAT" ORGANIZATION IS LINE SEQUENTIAL FILE STATUS IS FS-AUDIT. DATA DIVISION. FILE SECTION. FD FILE-IN. 01 FILE-IN-REC. 05 IN-KEY PIC X(10). 05 IN-DATA PIC X(30). FD FILE-OUT. 01 FILE-OUT-REC PIC X(120). FD FILE-AUDIT. 01 FILE-AUDIT-REC PIC X(80). WORKING-STORAGE SECTION. 01 WS-TELECOM-REC. COPY "telecom/TEL-BILLING.cpy". 01 FS-IN PIC X(2). 01 FS-OUT PIC X(2). 01 FS-AUDIT PIC X(2). 01 WS-STATUS. 05 WS-EOF-FLAG PIC X VALUE 'N'. 88 WS-EOF VALUE 'Y' FALSE 'N'. 05 WS-FIRST-REC PIC X VALUE 'Y'. 88 WS-FIRST VALUE 'Y' FALSE 'N'. 01 WS-PREV-KEY PIC X(10). 01 WS-CURRENT-KEY PIC X(10). 01 WS-PREV-SUBKEY PIC X(5). 01 WS-CURRENT-SUBKEY PIC X(5). 01 WS-CALL-STATE PIC X(10) VALUE 'INITIAL'. 01 WS-DATE-TIME. 05 WS-DATE PIC X(10). 05 WS-TIME PIC X(10). 01 WS-TIMESTAMP PIC X(21). 01 WS-MARKER-LINE. 05 FILLER PIC X(20) VALUE '*** KEY CHANGE TO: '. 05 WS-MARKER-KEY PIC X(10). 05 FILLER PIC X(5) VALUE ' ***'. 05 FILLER PIC X(2) VALUE ' ['. 05 WS-MARKER-TS PIC X(21). 05 FILLER PIC X(2) VALUE '] '. 05 WS-MARKER-SEQ PIC Z(9)9. 01 WS-SUB-MARKER. 05 FILLER PIC X(20) VALUE '--- SUB KEY CHANGE: '. 05 WS-SUB-MARK-KEY PIC X(5). 05 FILLER PIC X(5) VALUE ' ---'. 05 FILLER PIC X(2) VALUE ' ['. 05 WS-SUB-MARK-TS PIC X(21). 05 FILLER PIC X(2) VALUE '] '. 05 WS-SUB-MARK-SEQ PIC Z(9)9. 01 WS-GROUP-HEADER. 05 FILLER PIC X(16) VALUE '>>> GROUP START: '. 05 WS-GH-KEY PIC X(10). 05 FILLER PIC X(2) VALUE ' ['. 05 WS-GH-TS PIC X(21). 05 FILLER PIC X(2) VALUE ']'. 01 WS-DATA-OUT. 05 OUT-KEY PIC X(10). 05 FILLER PIC X VALUE SPACE. 05 OUT-DATA PIC X(30). 05 FILLER PIC X(2) VALUE SPACE. 05 OUT-STATE PIC X(10). 01 WS-RECORDS-READ PIC 9(5) VALUE 0. 01 WS-RECORDS-WRITTEN PIC 9(5) VALUE 0. 01 WS-KEY-CHANGES PIC 9(5) VALUE 0. 01 WS-SUB-CHANGES PIC 9(5) VALUE 0. 01 WS-GROUPS-TOTAL PIC 9(5) VALUE 0. 01 WS-SUBGROUPS-TOTAL PIC 9(5) VALUE 0. 01 WS-MARKER-SEQ-NUM PIC 9(5) VALUE 0. 01 WS-GROUP-COUNT PIC 9(5) VALUE 0. 01 WS-GROUP-DUR PIC 9(10) VALUE 0. 01 WS-GROUP-MIN PIC 9(10) VALUE 9999999999. 01 WS-GROUP-MAX PIC 9(10) VALUE 0. 01 WS-GROUP-AVG PIC 9(10)V99. 01 WS-SUBGROUP-COUNT PIC 9(5) VALUE 0. 01 WS-SUBGROUP-DUR PIC 9(10) VALUE 0. 01 WS-SUBGROUP-MIN PIC 9(10) VALUE 9999999999. 01 WS-SUBGROUP-MAX PIC 9(10) VALUE 0. 01 WS-SUBGROUP-AVG PIC 9(10)V99. 01 WS-GRAND-COUNT PIC 9(7) VALUE 0. 01 WS-GRAND-DUR PIC 9(12) VALUE 0. 01 WS-GROUP-FOOTER. 05 FILLER PIC X(14) VALUE '<<< GROUP END:'. 05 WS-GF-KEY PIC X(10). 05 FILLER PIC X(6) VALUE ' CNT='. 05 WS-GF-COUNT PIC Z(9)9. 05 FILLER PIC X(5) VALUE ' DUR='. 05 WS-GF-DUR PIC Z(9)9. 05 FILLER PIC X(5) VALUE ' MIN='. 05 WS-GF-MIN PIC Z(9)9. 05 FILLER PIC X(5) VALUE ' MAX='. 05 WS-GF-MAX PIC Z(9)9. 05 FILLER PIC X(5) VALUE ' AVG='. 05 WS-GF-AVG PIC Z(9)9.99. 01 WS-SUBGROUP-FOOTER. 05 FILLER PIC X(16) VALUE '... SUB END:'. 05 WS-SGF-SUBKEY PIC X(5). 05 FILLER PIC X(6) VALUE ' CNT='. 05 WS-SGF-COUNT PIC Z(9)9. 05 FILLER PIC X(5) VALUE ' DUR='. 05 WS-SGF-DUR PIC Z(9)9. 05 FILLER PIC X(5) VALUE ' MIN='. 05 WS-SGF-MIN PIC Z(9)9. 05 FILLER PIC X(5) VALUE ' MAX='. 05 WS-SGF-MAX PIC Z(9)9. 05 FILLER PIC X(5) VALUE ' AVG='. 05 WS-SGF-AVG PIC Z(9)9.99. 01 WS-GRAND-TOTAL-LINE. 05 FILLER PIC X(20) VALUE 'GRAND TOTAL: GROUPS='. 05 WS-GT-GROUPS PIC Z(9)9. 05 FILLER PIC X(6) VALUE ' RECS='. 05 WS-GT-RECS PIC Z(9)9. 05 FILLER PIC X(6) VALUE ' CHGS='. 05 WS-GT-CHGS PIC Z(9)9. 05 FILLER PIC X(6) VALUE ' SUB='. 05 WS-GT-SUB PIC Z(9)9. 05 FILLER PIC X(6) VALUE ' DUR='. 05 WS-GT-DUR PIC Z(11)9. 01 WS-PAGE-CONTROL. 05 WS-LINE-COUNT PIC 9(3) VALUE 0. 05 WS-PAGE-LENGTH PIC 9(3) VALUE 60. 05 WS-PAGE-NUM PIC 9(3) VALUE 1. 01 WS-PAGE-HEADER. 05 FILLER PIC X(6) VALUE 'PAGE '. 05 WS-PH-PAGE PIC Z(9)9. 05 FILLER PIC X(50) VALUE ' KEY BREAK DETECTION REPORT [TELECOM BILLING]'. 01 WS-OVERFLOW-FLAG PIC X VALUE 'N'. 88 WS-OVERFLOW VALUE 'Y' FALSE 'N'. 01 WS-MAX-TOTAL PIC 9(10) VALUE 9999999999. 01 WS-OVERFLOW-THRESH PIC 9(10) VALUE 9990000000. 01 WS-HASH-IN PIC 9(12) VALUE 0. 01 WS-HASH-OUT PIC 9(12) VALUE 0. 01 WS-HASH-VERIFIED PIC X(3) VALUE 'NO '. 88 WS-HASH-OK VALUE 'YES'. 01 WS-SEVERITY PIC X(10). 01 WS-ERROR-MSG PIC X(60). 01 WS-BATCH-TOTALS. 05 WS-ERROR-COUNT PIC 9(5) VALUE 0. 05 WS-WARN-COUNT PIC 9(5) VALUE 0. 01 WS-BATCH-ID PIC 9(5) VALUE 1. 01 WS-BATCH-DATE PIC X(10). 01 WS-BATCH-TIME PIC X(10). 01 WS-AUDIT-LINE. 05 AU-TIMESTAMP PIC X(21). 05 FILLER PIC X VALUE SPACE. 05 AU-TYPE PIC X(10). 05 FILLER PIC X VALUE SPACE. 05 AU-KEY PIC X(10). 05 FILLER PIC X VALUE SPACE. 05 AU-VALUE PIC Z(9)9. 05 FILLER PIC X VALUE SPACE. 05 AU-STATUS PIC X(20). 01 WS-TEMP-DUR PIC 9(10). PROCEDURE DIVISION. *> 1000-INIT-SECTION: initialize program state 1000-INIT-SECTION SECTION. 1000-INIT-PROC. MOVE FUNCTION CURRENT-DATE (1:10) TO WS-DATE MOVE FUNCTION CURRENT-DATE (12:8) TO WS-TIME STRING WS-DATE ' ' WS-TIME INTO WS-TIMESTAMP MOVE WS-DATE TO WS-BATCH-DATE MOVE WS-TIME TO WS-BATCH-TIME DISPLAY '[TIMESTAMP] ' WS-TIMESTAMP DISPLAY '[STATUS ] KeyBreakOther STARTED' DISPLAY '[BATCH ] ID=' WS-BATCH-ID DISPLAY ' DATE=' WS-BATCH-DATE DISPLAY ' TIME=' WS-BATCH-TIME DISPLAY ' ' PERFORM 2000-OPEN-FILES-SECTION . *> 2000-OPEN-FILES-SECTION: open all files with status check 2000-OPEN-FILES-SECTION SECTION. 2000-OPEN-FILES-PROC. DISPLAY '[FILE ] Opening FILE-IN.DAT...' OPEN INPUT FILE-IN IF FS-IN NOT = '00' DISPLAY '[FATAL ] FILE-IN open failed FS=' FS-IN STOP RUN END-IF DISPLAY '[OK ] FILE-IN opened, status=' FS-IN DISPLAY '[FILE ] Opening FILE-OUT.DAT...' OPEN OUTPUT FILE-OUT IF FS-OUT NOT = '00' DISPLAY '[FATAL ] FILE-OUT open failed FS=' FS-OUT STOP RUN END-IF DISPLAY '[OK ] FILE-OUT opened, status=' FS-OUT DISPLAY '[FILE ] Opening FILE-AUDIT.DAT...' OPEN OUTPUT FILE-AUDIT IF FS-AUDIT NOT = '00' DISPLAY '[WARNING ] FILE-AUDIT open failed FS=' FS-AUDIT MOVE 'WARNING' TO WS-SEVERITY MOVE 'AUDIT file unavailable, continuing' TO WS-ERROR-MSG PERFORM 6000-ERROR-HANDLE-SECTION ELSE DISPLAY '[OK ] FILE-AUDIT opened, status=' FS-AUDIT MOVE WS-TIMESTAMP TO AU-TIMESTAMP MOVE 'START' TO AU-TYPE MOVE 'BATCH' TO AU-KEY MOVE WS-BATCH-ID TO AU-VALUE MOVE 'OK' TO AU-STATUS WRITE FILE-AUDIT-REC FROM WS-AUDIT-LINE END-IF DISPLAY ' ' PERFORM 3000-PROCESS-SECTION . *> 3000-PROCESS-SECTION: main processing loop 3000-PROCESS-SECTION SECTION. 3000-PROCESS-PROC. DISPLAY '[PROCESS ] === KEY CHANGE DETECTION ===' DISPLAY '[PROCESS ] Processing sorted FILE-IN records...' DISPLAY ' ' PERFORM UNTIL WS-EOF PERFORM 3100-READ-INPUT-SECTION IF NOT WS-EOF PERFORM 3200-VALIDATE-SECTION PERFORM 3300-APPLY-RULES-SECTION PERFORM 3400-WRITE-OUTPUT-SECTION END-IF END-PERFORM . *> 3100-READ-INPUT-SECTION 3100-READ-INPUT-SECTION SECTION. 3100-READ-INPUT-PROC. READ FILE-IN INTO FILE-IN-REC AT END SET WS-EOF TO TRUE DISPLAY '[EOF ] FILE-IN end reached' NOT AT END ADD 1 TO WS-RECORDS-READ IF FS-IN NOT = '00' MOVE 'ERROR' TO WS-SEVERITY STRING 'FILE-IN read FS=' FS-IN INTO WS-ERROR-MSG PERFORM 6000-ERROR-HANDLE-SECTION END-IF END-READ . *> 3200-VALIDATE-SECTION 3200-VALIDATE-SECTION SECTION. 3200-VALIDATE-PROC. IF IN-KEY = SPACES MOVE 'WARNING' TO WS-SEVERITY MOVE 'Empty IN-KEY detected' TO WS-ERROR-MSG PERFORM 6000-ERROR-HANDLE-SECTION END-IF IF IN-DATA = SPACES MOVE 'WARNING' TO WS-SEVERITY MOVE 'Empty IN-DATA detected' TO WS-ERROR-MSG PERFORM 6000-ERROR-HANDLE-SECTION END-IF . *> 3300-APPLY-RULES-SECTION: key-change + sub-key + stats + page ctl 3300-APPLY-RULES-SECTION SECTION. 3300-APPLY-RULES-PROC. MOVE IN-KEY TO WS-CURRENT-KEY MOVE IN-DATA (1:5) TO WS-CURRENT-SUBKEY MOVE FUNCTION CURRENT-DATE (1:10) TO WS-DATE MOVE FUNCTION CURRENT-DATE (12:8) TO WS-TIME STRING WS-DATE ' ' WS-TIME INTO WS-TIMESTAMP *> ORIGINAL LOGIC: Key change detection on IN-KEY IF WS-FIRST MOVE WS-CURRENT-KEY TO WS-PREV-KEY MOVE WS-CURRENT-SUBKEY TO WS-PREV-SUBKEY PERFORM WRITE-CHANGE-MARKER PERFORM WRITE-SUB-MARKER PERFORM WRITE-GROUP-HEADER MOVE 'N' TO WS-FIRST-REC MOVE 'ACTIVE' TO WS-CALL-STATE ELSE IF WS-CURRENT-KEY NOT = WS-PREV-KEY MOVE 'ENDED' TO WS-CALL-STATE PERFORM WRITE-GROUP-FOOTER PERFORM WRITE-SUBGROUP-FOOTER ADD 1 TO WS-KEY-CHANGES MOVE WS-CURRENT-KEY TO WS-PREV-KEY PERFORM WRITE-CHANGE-MARKER MOVE WS-CURRENT-SUBKEY TO WS-PREV-SUBKEY PERFORM WRITE-SUB-MARKER PERFORM WRITE-GROUP-HEADER PERFORM INIT-GROUP-ACCUM PERFORM INIT-SUBGROUP-ACCUM MOVE 'CHANGE' TO WS-CALL-STATE ELSE IF WS-CURRENT-SUBKEY NOT = WS-PREV-SUBKEY PERFORM WRITE-SUBGROUP-FOOTER ADD 1 TO WS-SUB-CHANGES MOVE WS-CURRENT-SUBKEY TO WS-PREV-SUBKEY PERFORM WRITE-SUB-MARKER PERFORM INIT-SUBGROUP-ACCUM MOVE 'CHANGE' TO WS-CALL-STATE END-IF END-IF END-IF *> Accumulate group statistics ADD 1 TO WS-GROUP-COUNT ADD 1 TO WS-SUBGROUP-COUNT ADD 1 TO WS-GRAND-COUNT ADD 1 TO WS-MARKER-SEQ-NUM MOVE 100 TO WS-TEMP-DUR IF IN-DATA (26:5) NOT = SPACES COMPUTE WS-TEMP-DUR = FUNCTION NUMVAL(IN-DATA (26:5)) IF WS-TEMP-DUR = 0 MOVE 100 TO WS-TEMP-DUR END-IF END-IF ADD WS-TEMP-DUR TO WS-GROUP-DUR ADD WS-TEMP-DUR TO WS-SUBGROUP-DUR ADD WS-TEMP-DUR TO WS-GRAND-DUR IF WS-TEMP-DUR < WS-GROUP-MIN MOVE WS-TEMP-DUR TO WS-GROUP-MIN END-IF IF WS-TEMP-DUR > WS-GROUP-MAX MOVE WS-TEMP-DUR TO WS-GROUP-MAX END-IF IF WS-TEMP-DUR < WS-SUBGROUP-MIN MOVE WS-TEMP-DUR TO WS-SUBGROUP-MIN END-IF IF WS-TEMP-DUR > WS-SUBGROUP-MAX MOVE WS-TEMP-DUR TO WS-SUBGROUP-MAX END-IF *> Hash total + overflow checks COMPUTE WS-HASH-IN = WS-HASH-IN + WS-TEMP-DUR IF WS-HASH-IN > WS-MAX-TOTAL COMPUTE WS-HASH-IN = WS-HASH-IN - WS-MAX-TOTAL SET WS-OVERFLOW TO TRUE MOVE 'WARNING' TO WS-SEVERITY MOVE 'Hash total overflow - wrapped' TO WS-ERROR-MSG PERFORM 6000-ERROR-HANDLE-SECTION END-IF IF WS-GROUP-DUR > WS-OVERFLOW-THRESH SET WS-OVERFLOW TO TRUE MOVE 'WARNING' TO WS-SEVERITY STRING 'Group duration overflow KEY=' WS-PREV-KEY INTO WS-ERROR-MSG PERFORM 6000-ERROR-HANDLE-SECTION END-IF *> Page break control ADD 1 TO WS-LINE-COUNT IF WS-LINE-COUNT >= WS-PAGE-LENGTH ADD 1 TO WS-PAGE-NUM MOVE 0 TO WS-LINE-COUNT PERFORM WRITE-PAGE-HEADER END-IF . *> 3400-WRITE-OUTPUT-SECTION: data record + audit trail 3400-WRITE-OUTPUT-SECTION SECTION. 3400-WRITE-OUTPUT-PROC. *> ORIGINAL: write key + data record MOVE IN-KEY TO OUT-KEY MOVE IN-DATA TO OUT-DATA MOVE WS-CALL-STATE TO OUT-STATE WRITE FILE-OUT-REC FROM WS-DATA-OUT IF FS-OUT NOT = '00' MOVE 'FATAL' TO WS-SEVERITY STRING 'FILE-OUT write FS=' FS-OUT INTO WS-ERROR-MSG PERFORM 6000-ERROR-HANDLE-SECTION END-IF ADD 1 TO WS-RECORDS-WRITTEN ADD 1 TO WS-HASH-OUT MOVE WS-TIMESTAMP TO AU-TIMESTAMP MOVE 'RECORD' TO AU-TYPE MOVE IN-KEY TO AU-KEY MOVE WS-RECORDS-READ TO AU-VALUE MOVE 'OK' TO AU-STATUS IF FS-AUDIT = '00' WRITE FILE-AUDIT-REC FROM WS-AUDIT-LINE END-IF . *> 4000-REPORT-SECTION: summary display and grand totals 4000-REPORT-SECTION SECTION. 4000-REPORT-PROC. DISPLAY ' ' DISPLAY '=== SUMMARY ===' DISPLAY ' Records read: ' WS-RECORDS-READ DISPLAY ' Records written: ' WS-RECORDS-WRITTEN DISPLAY ' Key changes: ' WS-KEY-CHANGES DISPLAY ' Sub-key changes: ' WS-SUB-CHANGES DISPLAY ' Groups total: ' WS-GROUPS-TOTAL DISPLAY ' Sub-groups total:' WS-SUBGROUPS-TOTAL DISPLAY ' Grand duration: ' WS-GRAND-DUR DISPLAY ' Overflows: ' WS-OVERFLOW-FLAG DISPLAY ' Page count: ' WS-PAGE-NUM DISPLAY ' Hash input: ' WS-HASH-IN DISPLAY ' Hash output: ' WS-HASH-OUT IF WS-HASH-IN = WS-HASH-OUT MOVE 'YES' TO WS-HASH-VERIFIED DISPLAY ' HASH: VERIFICATION PASSED' ELSE DISPLAY ' HASH: VERIFICATION FAILED' END-IF IF WS-GRAND-COUNT NOT = WS-RECORDS-READ MOVE 'ERROR' TO WS-SEVERITY STRING 'GRAND TOTAL MISMATCH read=' WS-RECORDS-READ ' count=' WS-GRAND-COUNT INTO WS-ERROR-MSG PERFORM 6000-ERROR-HANDLE-SECTION DISPLAY ' ** GRAND TOTAL VERIFY FAILED **' ELSE DISPLAY ' ** Grand total verified OK **' END-IF DISPLAY ' Output: FILE-OUT.DAT Audit: FILE-AUDIT.DAT' . *> 5000-AUDIT-SECTION: audit log finish 5000-AUDIT-SECTION SECTION. 5000-AUDIT-PROC. MOVE WS-TIMESTAMP TO AU-TIMESTAMP MOVE 'END' TO AU-TYPE MOVE 'BATCH' TO AU-KEY MOVE WS-BATCH-ID TO AU-VALUE STRING 'REC=' WS-RECORDS-READ ' CHG=' WS-KEY-CHANGES ' SUB=' WS-SUB-CHANGES INTO AU-STATUS IF FS-AUDIT = '00' WRITE FILE-AUDIT-REC FROM WS-AUDIT-LINE END-IF DISPLAY ' ' DISPLAY '[AUDIT ] Batch=' WS-BATCH-ID DISPLAY ' Recs=' WS-RECORDS-READ DISPLAY ' Chgs=' WS-KEY-CHANGES DISPLAY ' Sub =' WS-SUB-CHANGES DISPLAY ' Err =' WS-ERROR-COUNT DISPLAY ' Warn=' WS-WARN-COUNT . *> 6000-ERROR-HANDLE-SECTION: handle errors by severity 6000-ERROR-HANDLE-SECTION SECTION. 6000-ERROR-HANDLE-PROC. DISPLAY '[TIMESTAMP] ' WS-TIMESTAMP DISPLAY '[' WS-SEVERITY '] ' WS-ERROR-MSG IF WS-SEVERITY = 'FATAL' PERFORM 9000-EXIT-SECTION STOP RUN ELSE IF WS-SEVERITY = 'ERROR' ADD 1 TO WS-ERROR-COUNT ELSE IF WS-SEVERITY = 'WARNING' ADD 1 TO WS-WARN-COUNT END-IF END-IF END-IF . *> 9000-EXIT-SECTION: clean up and exit 9000-EXIT-SECTION SECTION. 9000-EXIT-PROC. MOVE FUNCTION CURRENT-DATE (1:10) TO WS-DATE MOVE FUNCTION CURRENT-DATE (12:8) TO WS-TIME STRING WS-DATE ' ' WS-TIME INTO WS-TIMESTAMP IF WS-RECORDS-READ > 0 PERFORM WRITE-GROUP-FOOTER PERFORM WRITE-SUBGROUP-FOOTER PERFORM WRITE-GRAND-TOTAL END-IF PERFORM 4000-REPORT-SECTION PERFORM 5000-AUDIT-SECTION CLOSE FILE-IN FILE-OUT IF FS-AUDIT = '00' CLOSE FILE-AUDIT END-IF DISPLAY ' ' DISPLAY '[TIMESTAMP] ' WS-TIMESTAMP DISPLAY '[STATUS ] KeyBreakOther COMPLETED' STOP RUN . *> WRITE-CHANGE-MARKER — ORIGINAL enhanced with timestamp+seq WRITE-CHANGE-MARKER SECTION. WRITE-CHANGE-MARKER-PROC. ADD 1 TO WS-GROUPS-TOTAL MOVE WS-PREV-KEY TO WS-MARKER-KEY MOVE WS-TIMESTAMP TO WS-MARKER-TS MOVE WS-MARKER-SEQ-NUM TO WS-MARKER-SEQ WRITE FILE-OUT-REC FROM WS-MARKER-LINE IF FS-OUT NOT = '00' DISPLAY '[WARNING ] Marker write FS=' FS-OUT END-IF DISPLAY '[CHANGE ] Key -> ''' WS-PREV-KEY ''' SEQ=' WS-MARKER-SEQ-NUM . *> WRITE-SUB-MARKER — sub-key change marker WRITE-SUB-MARKER SECTION. WRITE-SUB-MARKER-PROC. ADD 1 TO WS-SUBGROUPS-TOTAL MOVE WS-PREV-SUBKEY TO WS-SUB-MARK-KEY MOVE WS-TIMESTAMP TO WS-SUB-MARK-TS MOVE WS-MARKER-SEQ-NUM TO WS-SUB-MARK-SEQ WRITE FILE-OUT-REC FROM WS-SUB-MARKER IF FS-OUT NOT = '00' DISPLAY '[WARNING ] Sub-marker write FS=' FS-OUT END-IF DISPLAY '[SUBCHANGE] Sub-key -> ''' WS-PREV-SUBKEY ''' SEQ=' WS-MARKER-SEQ-NUM . *> WRITE-GROUP-HEADER WRITE-GROUP-HEADER SECTION. WRITE-GROUP-HEADER-PROC. MOVE WS-PREV-KEY TO WS-GH-KEY MOVE WS-TIMESTAMP TO WS-GH-TS WRITE FILE-OUT-REC FROM WS-GROUP-HEADER IF FS-OUT NOT = '00' DISPLAY '[WARNING ] Group-header write FS=' FS-OUT END-IF ADD 1 TO WS-LINE-COUNT DISPLAY '[GROUP ] Start ''' WS-PREV-KEY '''' . *> WRITE-GROUP-FOOTER — end-of-group statistics WRITE-GROUP-FOOTER SECTION. WRITE-GROUP-FOOTER-PROC. IF WS-GROUP-COUNT > 0 COMPUTE WS-GROUP-AVG = WS-GROUP-DUR / WS-GROUP-COUNT ELSE MOVE 0 TO WS-GROUP-AVG END-IF MOVE WS-PREV-KEY TO WS-GF-KEY MOVE WS-GROUP-COUNT TO WS-GF-COUNT MOVE WS-GROUP-DUR TO WS-GF-DUR MOVE WS-GROUP-MIN TO WS-GF-MIN MOVE WS-GROUP-MAX TO WS-GF-MAX MOVE WS-GROUP-AVG TO WS-GF-AVG WRITE FILE-OUT-REC FROM WS-GROUP-FOOTER IF FS-OUT NOT = '00' DISPLAY '[WARNING ] Group-footer write FS=' FS-OUT END-IF ADD 1 TO WS-LINE-COUNT DISPLAY '[GROUP END] ''' WS-PREV-KEY '''' ' cnt=' WS-GROUP-COUNT ' dur=' WS-GROUP-DUR IF FS-AUDIT = '00' MOVE WS-TIMESTAMP TO AU-TIMESTAMP MOVE 'GROUP ' TO AU-TYPE MOVE WS-PREV-KEY TO AU-KEY MOVE WS-GROUP-COUNT TO AU-VALUE STRING 'DUR=' WS-GROUP-DUR INTO AU-STATUS WRITE FILE-AUDIT-REC FROM WS-AUDIT-LINE END-IF . *> WRITE-SUBGROUP-FOOTER — end-of-subgroup statistics WRITE-SUBGROUP-FOOTER SECTION. WRITE-SUBGROUP-FOOTER-PROC. IF WS-SUBGROUP-COUNT > 0 COMPUTE WS-SUBGROUP-AVG = WS-SUBGROUP-DUR / WS-SUBGROUP-COUNT ELSE MOVE 0 TO WS-SUBGROUP-AVG END-IF MOVE WS-PREV-SUBKEY TO WS-SGF-SUBKEY MOVE WS-SUBGROUP-COUNT TO WS-SGF-COUNT MOVE WS-SUBGROUP-DUR TO WS-SGF-DUR MOVE WS-SUBGROUP-MIN TO WS-SGF-MIN MOVE WS-SUBGROUP-MAX TO WS-SGF-MAX MOVE WS-SUBGROUP-AVG TO WS-SGF-AVG WRITE FILE-OUT-REC FROM WS-SUBGROUP-FOOTER IF FS-OUT NOT = '00' DISPLAY '[WARNING ] Subgroup-footer write FS=' FS-OUT END-IF ADD 1 TO WS-LINE-COUNT DISPLAY '[SUB END ] ''' WS-PREV-SUBKEY '''' ' cnt=' WS-SUBGROUP-COUNT ' dur=' WS-SUBGROUP-DUR IF FS-AUDIT = '00' MOVE WS-TIMESTAMP TO AU-TIMESTAMP MOVE 'SUBGRP' TO AU-TYPE MOVE WS-PREV-SUBKEY TO AU-KEY MOVE WS-SUBGROUP-COUNT TO AU-VALUE STRING 'DUR=' WS-SUBGROUP-DUR INTO AU-STATUS WRITE FILE-AUDIT-REC FROM WS-AUDIT-LINE END-IF . *> WRITE-PAGE-HEADER — page break marker WRITE-PAGE-HEADER SECTION. WRITE-PAGE-HEADER-PROC. MOVE WS-PAGE-NUM TO WS-PH-PAGE WRITE FILE-OUT-REC FROM WS-PAGE-HEADER IF FS-OUT NOT = '00' DISPLAY '[WARNING ] Page-header write FS=' FS-OUT END-IF ADD 1 TO WS-LINE-COUNT DISPLAY '[PAGE ] Page ' WS-PAGE-NUM . *> WRITE-GRAND-TOTAL WRITE-GRAND-TOTAL SECTION. WRITE-GRAND-TOTAL-PROC. MOVE WS-GROUPS-TOTAL TO WS-GT-GROUPS MOVE WS-RECORDS-READ TO WS-GT-RECS MOVE WS-KEY-CHANGES TO WS-GT-CHGS MOVE WS-SUB-CHANGES TO WS-GT-SUB MOVE WS-GRAND-DUR TO WS-GT-DUR WRITE FILE-OUT-REC FROM WS-GRAND-TOTAL-LINE IF FS-OUT NOT = '00' DISPLAY '[WARNING ] Grand-total write FS=' FS-OUT END-IF ADD 1 TO WS-LINE-COUNT DISPLAY '[GRAND ] groups=' WS-GROUPS-TOTAL ' recs=' WS-RECORDS-READ ' chgs=' WS-KEY-CHANGES ' sub=' WS-SUB-CHANGES ' dur=' WS-GRAND-DUR IF FS-AUDIT = '00' MOVE WS-TIMESTAMP TO AU-TIMESTAMP MOVE 'GRAND ' TO AU-TYPE MOVE 'TOTAL' TO AU-KEY MOVE WS-RECORDS-READ TO AU-VALUE STRING 'DUR=' WS-GRAND-DUR INTO AU-STATUS WRITE FILE-AUDIT-REC FROM WS-AUDIT-LINE END-IF . *> INIT-GROUP-ACCUM INIT-GROUP-ACCUM SECTION. INIT-GROUP-ACCUM-PROC. MOVE 0 TO WS-GROUP-COUNT MOVE 0 TO WS-GROUP-DUR MOVE 9999999999 TO WS-GROUP-MIN MOVE 0 TO WS-GROUP-MAX MOVE 0 TO WS-GROUP-AVG MOVE 'N' TO WS-OVERFLOW-FLAG . *> INIT-SUBGROUP-ACCUM INIT-SUBGROUP-ACCUM SECTION. INIT-SUBGROUP-ACCUM-PROC. MOVE 0 TO WS-SUBGROUP-COUNT MOVE 0 TO WS-SUBGROUP-DUR MOVE 9999999999 TO WS-SUBGROUP-MIN MOVE 0 TO WS-SUBGROUP-MAX MOVE 0 TO WS-SUBGROUP-AVG .