*> ============================================================ *> main-06-branch-evaluate.cbl : 套餐类型判定 (EVALUATE Plan) *> Input : plan-record (套餐代码记录) *> Output: FILE-A (套餐P01: 基本套餐) *> FILE-B (套餐P02: 商务套餐) *> FILE-C (套餐P03: 无限套餐) *> FILE-D (套餐P04: 家庭套餐) *> FILE-E (套餐P05: 学生套餐) *> FILE-F (套餐P06: 老人套餐) *> FILE-G (套餐P07: 企业套餐) *> FILE-OTHER (未定义套餐 → 异常处理) *> Coverage: B-N006~N009, B-A002, B-R001 *> ============================================================ IDENTIFICATION DIVISION. PROGRAM-ID. BranchEval. 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-A ASSIGN TO "FILE-A.DAT" ORGANIZATION IS LINE SEQUENTIAL FILE STATUS IS FS-A. SELECT FILE-B ASSIGN TO "FILE-B.DAT" ORGANIZATION IS LINE SEQUENTIAL FILE STATUS IS FS-B. SELECT FILE-C ASSIGN TO "FILE-C.DAT" ORGANIZATION IS LINE SEQUENTIAL FILE STATUS IS FS-C. SELECT FILE-D ASSIGN TO "FILE-D.DAT" ORGANIZATION IS LINE SEQUENTIAL FILE STATUS IS FS-D. SELECT FILE-E ASSIGN TO "FILE-E.DAT" ORGANIZATION IS LINE SEQUENTIAL FILE STATUS IS FS-E. SELECT FILE-F ASSIGN TO "FILE-F.DAT" ORGANIZATION IS LINE SEQUENTIAL FILE STATUS IS FS-F. SELECT FILE-G ASSIGN TO "FILE-G.DAT" ORGANIZATION IS LINE SEQUENTIAL FILE STATUS IS FS-G. SELECT FILE-OTHER ASSIGN TO "FILE-OTHER.DAT" ORGANIZATION IS LINE SEQUENTIAL FILE STATUS IS FS-OTHER. SELECT FILE-AUDIT ASSIGN TO "audit-report.txt" 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-DATA1 PIC X(20). 05 IN-DATA2 PIC 9(10). FD FILE-A. 01 FILE-A-REC. 05 A-KEY PIC X(10). 05 FILLER PIC X VALUE SPACE. 05 A-DATA1 PIC X(20). 05 FILLER PIC X VALUE SPACE. 05 A-DATA2 PIC 9(10). FD FILE-B. 01 FILE-B-REC. 05 B-KEY PIC X(10). 05 FILLER PIC X VALUE SPACE. 05 B-DATA1 PIC X(20). 05 FILLER PIC X VALUE SPACE. 05 B-DATA2 PIC 9(10). FD FILE-C. 01 FILE-C-REC. 05 C-KEY PIC X(10). 05 FILLER PIC X VALUE SPACE. 05 C-DATA1 PIC X(20). 05 FILLER PIC X VALUE SPACE. 05 C-DATA2 PIC 9(10). FD FILE-D. 01 FILE-D-REC. 05 D-KEY PIC X(10). 05 FILLER PIC X VALUE SPACE. 05 D-DATA1 PIC X(20). 05 FILLER PIC X VALUE SPACE. 05 D-DATA2 PIC 9(10). FD FILE-E. 01 FILE-E-REC. 05 E-KEY PIC X(10). 05 FILLER PIC X VALUE SPACE. 05 E-DATA1 PIC X(20). 05 FILLER PIC X VALUE SPACE. 05 E-DATA2 PIC 9(10). FD FILE-F. 01 FILE-F-REC. 05 F-KEY PIC X(10). 05 FILLER PIC X VALUE SPACE. 05 F-DATA1 PIC X(20). 05 FILLER PIC X VALUE SPACE. 05 F-DATA2 PIC 9(10). FD FILE-G. 01 FILE-G-REC. 05 G-KEY PIC X(10). 05 FILLER PIC X VALUE SPACE. 05 G-DATA1 PIC X(20). 05 FILLER PIC X VALUE SPACE. 05 G-DATA2 PIC 9(10). FD FILE-OTHER. 01 FILE-OTHER-REC. 05 O-KEY PIC X(10). 05 FILLER PIC X VALUE SPACE. 05 O-DATA1 PIC X(20). 05 FILLER PIC X VALUE SPACE. 05 O-DATA2 PIC 9(10). FD FILE-AUDIT. 01 FILE-AUDIT-REC PIC X(80). WORKING-STORAGE SECTION. 01 WS-TELECOM-REC. COPY "telecom/TEL-BILLING.cpy". *> File status fields 01 FS-IN PIC X(2). 01 FS-A PIC X(2). 01 FS-B PIC X(2). 01 FS-C PIC X(2). 01 FS-D PIC X(2). 01 FS-E PIC X(2). 01 FS-F PIC X(2). 01 FS-G PIC X(2). 01 FS-OTHER PIC X(2). 01 FS-AUDIT PIC X(2). *> Status flags 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'. *> Counters per tier 01 WS-COUNTERS. 05 WS-COUNT-A PIC 9(5) VALUE 0. 05 WS-COUNT-B PIC 9(5) VALUE 0. 05 WS-COUNT-C PIC 9(5) VALUE 0. 05 WS-COUNT-D PIC 9(5) VALUE 0. 05 WS-COUNT-E PIC 9(5) VALUE 0. 05 WS-COUNT-F PIC 9(5) VALUE 0. 05 WS-COUNT-G PIC 9(5) VALUE 0. 05 WS-COUNT-OTHER PIC 9(5) VALUE 0. *> Hash totals 01 WS-HASH-TOTALS. 05 WS-HASH-IN PIC 9(12) VALUE 0. 05 WS-HASH-OUT-A PIC 9(12) VALUE 0. 05 WS-HASH-OUT-B PIC 9(12) VALUE 0. 05 WS-HASH-OUT-C PIC 9(12) VALUE 0. 05 WS-HASH-OUT-D PIC 9(12) VALUE 0. 05 WS-HASH-OUT-E PIC 9(12) VALUE 0. 05 WS-HASH-OUT-F PIC 9(12) VALUE 0. 05 WS-HASH-OUT-G PIC 9(12) VALUE 0. 05 WS-HASH-OUT-OTHER PIC 9(12) VALUE 0. 05 WS-HASH-VERIFIED PIC X(3) VALUE 'NO '. 88 WS-HASH-OK VALUE 'YES'. *> Batch totals 01 WS-BATCH-TOTALS. 05 WS-RECORDS-READ PIC 9(5) VALUE 0. 05 WS-RECORDS-WRITTEN PIC 9(5) VALUE 0. 05 WS-ERROR-COUNT PIC 9(5) VALUE 0. 05 WS-WARN-COUNT PIC 9(5) VALUE 0. 05 WS-BATCH-DATE PIC 9(8). 05 WS-BATCH-TIME PIC 9(8). 05 WS-BATCH-TOTAL-AMT PIC 9(15) VALUE 0. 05 WS-HASH-TOTAL PIC 9(15) VALUE 0. *> Timestamp fields 01 WS-DATE-TIME. 05 WS-DATE PIC X(10). 05 WS-TIME PIC X(10). 01 WS-TIMESTAMP PIC X(20). 01 WS-DATA2-NUM PIC 9(10). 01 WS-TRUE-FALSE PIC X. 88 WS-IS-TRUE VALUE 'Y' FALSE 'N'. *> Telecom business rule fields 01 WS-PLAN-RULES. 05 WS-CALL-TYPE PIC X(10). 05 WS-DESTINATION PIC X(10). 05 WS-DURATION-CAT PIC X(10). 05 WS-DATA-CAP PIC 9(6). 05 WS-INTL-RATE PIC 9(3)V99. 05 WS-PLAN-NAME PIC X(10). 05 WS-PLAN-RATE PIC 9(5)V99. 05 WS-PEAK-FLAG PIC X. 88 WS-PEAK VALUE 'P'. 88 WS-OFF-PEAK VALUE 'O'. 05 WS-DAY-TYPE PIC X. 88 WS-WEEKDAY VALUE 'W'. 88 WS-WEEKEND VALUE 'E'. 05 WS-DOM-ROAM PIC X. 88 WS-DOMESTIC VALUE 'D'. 88 WS-ROAMING VALUE 'R'. 05 WS-MIN-CHARGE PIC 9(5)V99 VALUE 5.00. 05 WS-CAP-AMOUNT PIC 9(9)V99 VALUE 99999.99. 05 WS-FALLBACK-RATE PIC 9(5)V99 VALUE 2.00. 05 WS-PLAN-CODE PIC X(03). *> Audit fields 01 WS-AUDIT-LINE. 05 AU-TIMESTAMP PIC X(20). 05 FILLER PIC X VALUE SPACE. 05 AU-TIER PIC X(10). 05 FILLER PIC X VALUE SPACE. 05 AU-KEY PIC X(10). 05 FILLER PIC X VALUE SPACE. 05 AU-AMOUNT PIC Z(9)9. 05 FILLER PIC X VALUE SPACE. 05 AU-STATUS PIC X(15). *> Error fields 01 WS-SEVERITY PIC X(10). 01 WS-ERROR-MSG PIC X(60). PROCEDURE DIVISION. * 1000-INIT-SECTION. * 1000-INIT. MOVE FUNCTION CURRENT-DATE (1:10) TO WS-DATE MOVE FUNCTION CURRENT-DATE (12:8) TO WS-TIME MOVE FUNCTION CURRENT-DATE (1:8) TO WS-BATCH-DATE MOVE FUNCTION CURRENT-DATE (12:8) TO WS-BATCH-TIME STRING WS-DATE ' ' WS-TIME INTO WS-TIMESTAMP DISPLAY '[' WS-TIMESTAMP '] BranchEval STARTED' DISPLAY ' ' PERFORM 2000-OPEN-FILES-SECTION PERFORM 5000-AUDIT-SECTION THRU AUDIT-LOG-START . * 2000-OPEN-FILES-SECTION. * 2000-OPEN-FILES. OPEN INPUT FILE-IN IF FS-IN NOT = '00' MOVE 'FATAL' TO WS-SEVERITY STRING 'Open FILE-IN failed FS=' FS-IN INTO WS-ERROR-MSG PERFORM 6000-ERROR-HANDLE-SECTION STOP RUN END-IF OPEN OUTPUT FILE-A FILE-B FILE-C FILE-D FILE-E FILE-F FILE-G FILE-OTHER IF FS-A NOT = '00' OR FS-B NOT = '00' OR FS-C NOT = '00' OR FS-D NOT = '00' OR FS-E NOT = '00' OR FS-F NOT = '00' OR FS-G NOT = '00' OR FS-OTHER NOT = '00' MOVE 'FATAL' TO WS-SEVERITY STRING 'Open output files failed' INTO WS-ERROR-MSG PERFORM 6000-ERROR-HANDLE-SECTION STOP RUN END-IF OPEN OUTPUT FILE-AUDIT IF FS-AUDIT NOT = '00' DISPLAY 'WARNING: Audit file open failed FS=' FS-AUDIT END-IF DISPLAY 'Files opened successfully' . * 3000-PROCESS-SECTION. * 3000-PROCESS. DISPLAY 'Processing records with EVALUATE...' PERFORM UNTIL WS-EOF PERFORM 3100-READ-INPUT-SECTION IF NOT WS-EOF PERFORM 3200-VALIDATE-SECTION PERFORM 3300-APPLY-RULES-SECTION END-IF END-PERFORM . * 3100-READ-INPUT-SECTION. * 3100-READ-INPUT. READ FILE-IN INTO FILE-IN-REC AT END SET WS-EOF TO TRUE NOT AT END ADD 1 TO WS-RECORDS-READ ADD WS-DATA2-NUM TO WS-HASH-IN IF FS-IN NOT = '00' MOVE 'ERROR' TO WS-SEVERITY STRING 'Read FILE-IN FS=' FS-IN INTO WS-ERROR-MSG PERFORM 6000-ERROR-HANDLE-SECTION END-IF END-READ . * 3200-VALIDATE-SECTION. * 3200-VALIDATE. MOVE IN-DATA2 TO WS-DATA2-NUM *> Plan code validation IF IN-KEY = SPACES OR IN-KEY = LOW-VALUES MOVE 'WARNING' TO WS-SEVERITY STRING 'Empty plan code detected' INTO WS-ERROR-MSG PERFORM 6000-ERROR-HANDLE-SECTION END-IF *> Duration range validation IF WS-DATA2-NUM = 0 MOVE 'WARNING' TO WS-SEVERITY STRING 'Zero duration: ' IN-KEY INTO WS-ERROR-MSG PERFORM 6000-ERROR-HANDLE-SECTION END-IF *> Set call type and destination from DATA1 EVALUATE IN-DATA1 (1:4) WHEN 'PEAK' MOVE 'PEAK' TO WS-CALL-TYPE MOVE 'DOM' TO WS-DESTINATION WHEN 'OFFP' MOVE 'OFF-PEAK' TO WS-CALL-TYPE MOVE 'DOM' TO WS-DESTINATION WHEN 'ROAM' MOVE 'PEAK' TO WS-CALL-TYPE MOVE 'INTL' TO WS-DESTINATION WHEN 'WKND' MOVE 'OFF-PEAK' TO WS-CALL-TYPE MOVE 'DOM' TO WS-DESTINATION WHEN OTHER MOVE 'STANDARD' TO WS-CALL-TYPE MOVE 'DOM' TO WS-DESTINATION END-EVALUATE *> Duration category EVALUATE TRUE WHEN WS-DATA2-NUM <= 60 MOVE 'SHORT' TO WS-DURATION-CAT WHEN WS-DATA2-NUM <= 300 MOVE 'MEDIUM' TO WS-DURATION-CAT WHEN WS-DATA2-NUM <= 1800 MOVE 'LONG' TO WS-DURATION-CAT WHEN OTHER MOVE 'EXTENDED' TO WS-DURATION-CAT END-EVALUATE . * 3300-APPLY-RULES-SECTION. * 3300-APPLY-RULES. *> ============================================================ *> ORIGINAL EVALUATE with ALSO — 3-way preserved *> Expanded to 8-way: A, B, C, D, E, F, G, OTHER *> ============================================================ EVALUATE IN-KEY ALSO WS-DATA2-NUM WHEN 'A' ALSO ANY MOVE IN-KEY TO A-KEY MOVE IN-DATA1 TO A-DATA1 MOVE IN-DATA2 TO A-DATA2 WRITE FILE-A-REC IF FS-A NOT = '00' MOVE 'FATAL' TO WS-SEVERITY STRING 'Write FILE-A FS=' FS-A INTO WS-ERROR-MSG PERFORM 6000-ERROR-HANDLE-SECTION END-IF ADD 1 TO WS-COUNT-A ADD WS-DATA2-NUM TO WS-HASH-OUT-A ADD 1 TO WS-RECORDS-WRITTEN DISPLAY ' -> Key=''A'' routed to FILE-A' MOVE 'BASIC-P01' TO WS-PLAN-NAME WHEN 'B' ALSO ANY MOVE IN-KEY TO B-KEY MOVE IN-DATA1 TO B-DATA1 MOVE IN-DATA2 TO B-DATA2 WRITE FILE-B-REC IF FS-B NOT = '00' MOVE 'FATAL' TO WS-SEVERITY STRING 'Write FILE-B FS=' FS-B INTO WS-ERROR-MSG PERFORM 6000-ERROR-HANDLE-SECTION END-IF ADD 1 TO WS-COUNT-B ADD WS-DATA2-NUM TO WS-HASH-OUT-B ADD 1 TO WS-RECORDS-WRITTEN DISPLAY ' -> Key=''B'' routed to FILE-B' MOVE 'BUSINESS-P02' TO WS-PLAN-NAME WHEN 'C' ALSO ANY MOVE IN-KEY TO C-KEY MOVE IN-DATA1 TO C-DATA1 MOVE IN-DATA2 TO C-DATA2 WRITE FILE-C-REC IF FS-C NOT = '00' MOVE 'FATAL' TO WS-SEVERITY STRING 'Write FILE-C FS=' FS-C INTO WS-ERROR-MSG PERFORM 6000-ERROR-HANDLE-SECTION END-IF ADD 1 TO WS-COUNT-C ADD WS-DATA2-NUM TO WS-HASH-OUT-C ADD 1 TO WS-RECORDS-WRITTEN DISPLAY ' -> Key=''C'' routed to FILE-C' MOVE 'UNLIMITED-P03' TO WS-PLAN-NAME WHEN 'D' ALSO ANY MOVE IN-KEY TO D-KEY MOVE IN-DATA1 TO D-DATA1 MOVE IN-DATA2 TO D-DATA2 WRITE FILE-D-REC IF FS-D NOT = '00' MOVE 'FATAL' TO WS-SEVERITY STRING 'Write FILE-D FS=' FS-D INTO WS-ERROR-MSG PERFORM 6000-ERROR-HANDLE-SECTION END-IF ADD 1 TO WS-COUNT-D ADD WS-DATA2-NUM TO WS-HASH-OUT-D ADD 1 TO WS-RECORDS-WRITTEN DISPLAY ' -> Key=''D'' routed to FILE-D' MOVE 'FAMILY-P04' TO WS-PLAN-NAME WHEN 'E' ALSO ANY MOVE IN-KEY TO E-KEY MOVE IN-DATA1 TO E-DATA1 MOVE IN-DATA2 TO E-DATA2 WRITE FILE-E-REC IF FS-E NOT = '00' MOVE 'FATAL' TO WS-SEVERITY STRING 'Write FILE-E FS=' FS-E INTO WS-ERROR-MSG PERFORM 6000-ERROR-HANDLE-SECTION END-IF ADD 1 TO WS-COUNT-E ADD WS-DATA2-NUM TO WS-HASH-OUT-E ADD 1 TO WS-RECORDS-WRITTEN DISPLAY ' -> Key=''E'' routed to FILE-E' MOVE 'STUDENT-P05' TO WS-PLAN-NAME WHEN 'F' ALSO ANY MOVE IN-KEY TO F-KEY MOVE IN-DATA1 TO F-DATA1 MOVE IN-DATA2 TO F-DATA2 WRITE FILE-F-REC IF FS-F NOT = '00' MOVE 'FATAL' TO WS-SEVERITY STRING 'Write FILE-F FS=' FS-F INTO WS-ERROR-MSG PERFORM 6000-ERROR-HANDLE-SECTION END-IF ADD 1 TO WS-COUNT-F ADD WS-DATA2-NUM TO WS-HASH-OUT-F ADD 1 TO WS-RECORDS-WRITTEN DISPLAY ' -> Key=''F'' routed to FILE-F' MOVE 'SENIOR-P06' TO WS-PLAN-NAME WHEN 'G' ALSO ANY MOVE IN-KEY TO G-KEY MOVE IN-DATA1 TO G-DATA1 MOVE IN-DATA2 TO G-DATA2 WRITE FILE-G-REC IF FS-G NOT = '00' MOVE 'FATAL' TO WS-SEVERITY STRING 'Write FILE-G FS=' FS-G INTO WS-ERROR-MSG PERFORM 6000-ERROR-HANDLE-SECTION END-IF ADD 1 TO WS-COUNT-G ADD WS-DATA2-NUM TO WS-HASH-OUT-G ADD 1 TO WS-RECORDS-WRITTEN DISPLAY ' -> Key=''G'' routed to FILE-G' MOVE 'CORP-P07' TO WS-PLAN-NAME WHEN OTHER MOVE IN-KEY TO O-KEY MOVE IN-DATA1 TO O-DATA1 MOVE IN-DATA2 TO O-DATA2 WRITE FILE-OTHER-REC IF FS-OTHER NOT = '00' MOVE 'FATAL' TO WS-SEVERITY STRING 'Write FILE-OTHER FS=' FS-OTHER INTO WS-ERROR-MSG PERFORM 6000-ERROR-HANDLE-SECTION END-IF ADD 1 TO WS-COUNT-OTHER ADD WS-DATA2-NUM TO WS-HASH-OUT-OTHER ADD 1 TO WS-RECORDS-WRITTEN DISPLAY ' -> Key=''' IN-KEY ''' routed to FILE-OTHER' MOVE 'FALLBACK' TO WS-PLAN-NAME END-EVALUATE *> ============================================================ *> ORIGINAL EVALUATE TRUE/FALSE — preserved *> ============================================================ IF WS-DATA2-NUM > 5000 SET WS-IS-TRUE TO TRUE ELSE MOVE 'N' TO WS-TRUE-FALSE END-IF EVALUATE TRUE WHEN WS-DATA2-NUM < 1000 DISPLAY ' [EVAL TRUE] DATA2 small (< 1000)' WHEN WS-DATA2-NUM >= 1000 AND WS-DATA2-NUM <= 5000 DISPLAY ' [EVAL TRUE] DATA2 medium (1000-5000)' WHEN WS-IS-TRUE DISPLAY ' [EVAL TRUE] DATA2 large (> 5000)' WHEN OTHER DISPLAY ' [EVAL TRUE] OTHER (unexpected)' END-EVALUATE *> ============================================================ *> ORIGINAL EVALUATE multi-value WHEN — preserved *> ============================================================ EVALUATE IN-DATA1 (1:7) WHEN 'SPECIAL' WHEN 'SPECIAL' DISPLAY ' [EVAL MULTI] DATA1 starts with SPECIAL' WHEN 'HIGH' DISPLAY ' [EVAL MULTI] DATA1 starts with HIGH' WHEN OTHER DISPLAY ' [EVAL MULTI] DATA1 starts with normal' END-EVALUATE *> NEW: EVALUATE for multi-factor plan rules EVALUATE WS-CALL-TYPE ALSO WS-DESTINATION ALSO WS-DURATION-CAT WHEN 'PEAK' ALSO 'DOM' ALSO 'SHORT' DISPLAY ' [MULTI] Peak Domestic Short' WHEN 'PEAK' ALSO 'DOM' ALSO ANY DISPLAY ' [MULTI] Peak Domestic Any' WHEN 'OFF-PEAK' ALSO 'DOM' ALSO ANY DISPLAY ' [MULTI] Off-Peak Domestic Any' WHEN ANY ALSO 'INTL' ALSO ANY DISPLAY ' [MULTI] International call' WHEN OTHER DISPLAY ' [MULTI] Unmapped call combo' END-EVALUATE *> NEW: EVALUATE for data cap rules EVALUATE WS-DATA-CAP WHEN 0 THRU 1000 DISPLAY ' [DATA-CAP] Low: ' WS-DATA-CAP 'MB' WHEN 1001 THRU 5000 DISPLAY ' [DATA-CAP] Medium: ' WS-DATA-CAP 'MB' WHEN 5001 THRU 99999 DISPLAY ' [DATA-CAP] High: ' WS-DATA-CAP 'MB' WHEN OTHER DISPLAY ' [DATA-CAP] Unlimited or unknown' END-EVALUATE *> NEW: Nested EVALUATE for plan-specific business rules *> (data cap, international rates per plan tier) MOVE SPACES TO WS-PLAN-CODE EVALUATE IN-KEY WHEN 'A' MOVE 'P01' TO WS-PLAN-CODE WHEN 'B' MOVE 'P02' TO WS-PLAN-CODE WHEN 'C' MOVE 'P03' TO WS-PLAN-CODE WHEN 'D' MOVE 'P04' TO WS-PLAN-CODE WHEN 'E' MOVE 'P05' TO WS-PLAN-CODE WHEN 'F' MOVE 'P06' TO WS-PLAN-CODE WHEN 'G' MOVE 'P07' TO WS-PLAN-CODE WHEN OTHER MOVE 'P00' TO WS-PLAN-CODE END-EVALUATE EVALUATE WS-PLAN-CODE WHEN 'P01' MOVE 1000 TO WS-DATA-CAP MOVE 2.50 TO WS-INTL-RATE EVALUATE TRUE WHEN WS-DURATION-CAT = 'LONG' DISPLAY ' [P01 MAX] Basic long call' WHEN WS-DURATION-CAT = 'EXTENDED' DISPLAY ' [P01 CAP] Basic cap applied' END-EVALUATE DISPLAY ' [PLAN P01] Basic plan rules' WHEN 'P02' MOVE 5000 TO WS-DATA-CAP MOVE 1.50 TO WS-INTL-RATE EVALUATE TRUE WHEN WS-DURATION-CAT = 'LONG' DISPLAY ' [P02 DISCOUNT] Business bulk' WHEN WS-DURATION-CAT = 'EXTENDED' DISPLAY ' [P02 CAP] Business cap warning' END-EVALUATE DISPLAY ' [PLAN P02] Business plan rules' WHEN 'P03' MOVE 99999 TO WS-DATA-CAP MOVE 0.50 TO WS-INTL-RATE DISPLAY ' [PLAN P03] Unlimited - no data cap' WHEN 'P04' MOVE 8000 TO WS-DATA-CAP MOVE 1.00 TO WS-INTL-RATE EVALUATE WS-DURATION-CAT ALSO WS-DESTINATION WHEN 'LONG' ALSO 'INTL' DISPLAY ' [P04 FAM] Family intl discount' WHEN 'EXTENDED' ALSO ANY DISPLAY ' [P04 FAM] Family extended cap' WHEN OTHER DISPLAY ' [P04 FAM] Standard family rate' END-EVALUATE WHEN 'P05' MOVE 2000 TO WS-DATA-CAP MOVE 1.75 TO WS-INTL-RATE DISPLAY ' [PLAN P05] Student plan - limited cap' WHEN 'P06' MOVE 1500 TO WS-DATA-CAP MOVE 1.25 TO WS-INTL-RATE DISPLAY ' [PLAN P06] Senior plan - reduced rates' WHEN 'P07' MOVE 50000 TO WS-DATA-CAP MOVE 0.75 TO WS-INTL-RATE DISPLAY ' [PLAN P07] Corporate plan - bulk rates' WHEN OTHER MOVE 500 TO WS-DATA-CAP MOVE 3.00 TO WS-INTL-RATE DISPLAY ' [PLAN P00] Default plan - basic rates' END-EVALUATE *> NEW: EVALUATE TRUE/FALSE for weekday/weekend and domestic/roaming EVALUATE IN-DATA1 (1:4) WHEN 'PEAK' WHEN 'ROAM' SET WS-PEAK TO TRUE WHEN 'OFFP' WHEN 'WKND' SET WS-OFF-PEAK TO TRUE WHEN OTHER MOVE 'P' TO WS-PEAK-FLAG END-EVALUATE EVALUATE IN-DATA1 (1:4) WHEN 'WKND' SET WS-WEEKEND TO TRUE WHEN 'PEAK' SET WS-WEEKDAY TO TRUE WHEN 'OFFP' SET WS-WEEKDAY TO TRUE WHEN OTHER SET WS-WEEKDAY TO TRUE END-EVALUATE EVALUATE IN-DATA1 (1:4) WHEN 'ROAM' SET WS-ROAMING TO TRUE WHEN OTHER SET WS-DOMESTIC TO TRUE END-EVALUATE EVALUATE TRUE ALSO TRUE ALSO TRUE WHEN WS-PEAK ALSO WS-WEEKDAY ALSO WS-DOMESTIC DISPLAY ' [TIME/DST] Peak weekday domestic' WHEN WS-PEAK ALSO WS-WEEKEND ALSO WS-DOMESTIC DISPLAY ' [TIME/DST] Peak weekend domestic' WHEN WS-OFF-PEAK ALSO WS-WEEKDAY ALSO WS-DOMESTIC DISPLAY ' [TIME/DST] Off-peak weekday domestic' WHEN WS-OFF-PEAK ALSO WS-WEEKEND ALSO WS-DOMESTIC DISPLAY ' [TIME/DST] Off-peak weekend domestic' WHEN WS-PEAK ALSO WS-WEEKDAY ALSO WS-ROAMING DISPLAY ' [TIME/DST] Peak weekday roaming' WHEN WS-PEAK ALSO WS-WEEKEND ALSO WS-ROAMING DISPLAY ' [TIME/DST] Peak weekend roaming' WHEN WS-OFF-PEAK ALSO WS-WEEKDAY ALSO WS-ROAMING DISPLAY ' [TIME/DST] Off-peak weekday roaming' WHEN WS-OFF-PEAK ALSO WS-WEEKEND ALSO WS-ROAMING DISPLAY ' [TIME/DST] Off-peak weekend roaming' WHEN OTHER DISPLAY ' [TIME/DST] Unmapped time/destination' END-EVALUATE *> NEW: EVALUATE for peak flag EVALUATE WS-PEAK-FLAG WHEN 'P' DISPLAY ' [PEAK] Peak rate applies' WHEN 'O' DISPLAY ' [PEAK] Off-peak rate applies' WHEN OTHER DISPLAY ' [PEAK] Undefined peak flag' END-EVALUATE *> NEW: Minimum charge check using EVALUATE EVALUATE TRUE WHEN WS-PLAN-NAME = SPACES MOVE WS-FALLBACK-RATE TO WS-PLAN-RATE DISPLAY ' [MIN-CHG] Fallback rate applied' WHEN WS-PLAN-RATE < WS-MIN-CHARGE MOVE 'WARNING' TO WS-SEVERITY STRING 'Rate below min charge: ' WS-PLAN-RATE INTO WS-ERROR-MSG PERFORM 6000-ERROR-HANDLE-SECTION WHEN OTHER CONTINUE END-EVALUATE *> NEW: Cap check using EVALUATE EVALUATE TRUE WHEN WS-PLAN-RATE > WS-CAP-AMOUNT MOVE 'WARNING' TO WS-SEVERITY STRING 'Rate exceeds cap: ' WS-PLAN-RATE INTO WS-ERROR-MSG PERFORM 6000-ERROR-HANDLE-SECTION WHEN OTHER CONTINUE END-EVALUATE *> NEW: Fallback default rate - EVALUATE multiple WHEN EVALUATE WS-PLAN-NAME WHEN SPACES WHEN LOW-VALUES WHEN 'FALLBACK' MOVE WS-FALLBACK-RATE TO WS-PLAN-RATE MOVE 'STANDARD' TO WS-PLAN-NAME DISPLAY ' [FALLBACK] Default rate for unmapped' WHEN OTHER DISPLAY ' [FALLBACK] Plan ' WS-PLAN-NAME ' has valid rate' END-EVALUATE *> NEW: EVALUATE for rate lookup validation per plan EVALUATE WS-PLAN-RATE ALSO WS-PLAN-CODE WHEN 0.00 THRU 5.00 ALSO 'P01' DISPLAY ' [RATE-VAL] P01 rate: ' WS-PLAN-RATE WHEN 0.00 THRU 10.00 ALSO 'P02' DISPLAY ' [RATE-VAL] P02 rate: ' WS-PLAN-RATE WHEN 0.00 THRU 20.00 ALSO 'P03' DISPLAY ' [RATE-VAL] P03 rate: ' WS-PLAN-RATE WHEN 0.00 THRU 8.00 ALSO 'P04' DISPLAY ' [RATE-VAL] P04 rate: ' WS-PLAN-RATE WHEN 0.00 THRU 6.00 ALSO 'P05' DISPLAY ' [RATE-VAL] P05 rate: ' WS-PLAN-RATE WHEN 0.00 THRU 5.00 ALSO 'P06' DISPLAY ' [RATE-VAL] P06 rate: ' WS-PLAN-RATE WHEN 0.00 THRU 25.00 ALSO 'P07' DISPLAY ' [RATE-VAL] P07 rate: ' WS-PLAN-RATE WHEN OTHER MOVE 'WARNING' TO WS-SEVERITY STRING 'Rate ' WS-PLAN-RATE ' invalid for plan ' WS-PLAN-CODE INTO WS-ERROR-MSG PERFORM 6000-ERROR-HANDLE-SECTION END-EVALUATE *> NEW: Error severity classification using EVALUATE EVALUATE WS-ERROR-COUNT WHEN 0 DISPLAY ' [SEVERITY] No errors - clean batch' WHEN 1 THRU 5 DISPLAY ' [SEVERITY] Low error count (1-5)' WHEN 6 THRU 20 DISPLAY ' [SEVERITY] Medium error count (6-20)' WHEN 21 THRU 99999 DISPLAY ' [SEVERITY] High error count (>20)' WHEN OTHER DISPLAY ' [SEVERITY] Error count overflow' END-EVALUATE EVALUATE WS-WARN-COUNT WHEN 0 DISPLAY ' [SEVERITY] No warnings' WHEN 1 THRU 10 DISPLAY ' [SEVERITY] Low warning count (1-10)' WHEN 11 THRU 50 DISPLAY ' [SEVERITY] Medium warning count (11-50)' WHEN 51 THRU 99999 DISPLAY ' [SEVERITY] High warning count (>50)' WHEN OTHER DISPLAY ' [SEVERITY] Warning count overflow' END-EVALUATE PERFORM 5000-AUDIT-SECTION THRU AUDIT-LOG-RECORD . * 3400-WRITE-OUTPUT-SECTION. * 3400-WRITE-OUTPUT. *> Writing is handled within each EVALUATE WHEN branch . * 4000-REPORT-SECTION. * 4000-REPORT. DISPLAY ' ' DISPLAY '=== RESULTS ===' DISPLAY 'FILE-A (P01 Basic): ' WS-COUNT-A ' records' DISPLAY 'FILE-B (P02 Bus): ' WS-COUNT-B ' records' DISPLAY 'FILE-C (P03 Unlim): ' WS-COUNT-C ' records' DISPLAY 'FILE-D (P04 Fam): ' WS-COUNT-D ' records' DISPLAY 'FILE-E (P05 Stdnt): ' WS-COUNT-E ' records' DISPLAY 'FILE-F (P06 Senior): ' WS-COUNT-F ' records' DISPLAY 'FILE-G (P07 Corp): ' WS-COUNT-G ' records' DISPLAY 'FILE-OTHER: ' WS-COUNT-OTHER ' records' DISPLAY ' ' DISPLAY 'Total records read: ' WS-RECORDS-READ DISPLAY 'Total records written: ' WS-RECORDS-WRITTEN DISPLAY 'Errors: ' WS-ERROR-COUNT DISPLAY 'Warnings: ' WS-WARN-COUNT *> Hash total verification DISPLAY ' ' DISPLAY 'Hash total verification:' DISPLAY ' Input hash: ' WS-HASH-IN DISPLAY ' Out-A hash: ' WS-HASH-OUT-A DISPLAY ' Out-B hash: ' WS-HASH-OUT-B DISPLAY ' Out-C hash: ' WS-HASH-OUT-C DISPLAY ' Out-D hash: ' WS-HASH-OUT-D DISPLAY ' Out-E hash: ' WS-HASH-OUT-E DISPLAY ' Out-F hash: ' WS-HASH-OUT-F DISPLAY ' Out-G hash: ' WS-HASH-OUT-G DISPLAY ' Out-Other hash:' WS-HASH-OUT-OTHER IF WS-HASH-IN = (WS-HASH-OUT-A + WS-HASH-OUT-B + WS-HASH-OUT-C + WS-HASH-OUT-D + WS-HASH-OUT-E + WS-HASH-OUT-F + WS-HASH-OUT-G + WS-HASH-OUT-OTHER) MOVE 'YES' TO WS-HASH-VERIFIED DISPLAY ' HASH VERIFICATION: PASSED' ELSE MOVE 'NO ' TO WS-HASH-VERIFIED DISPLAY ' HASH VERIFICATION: FAILED' END-IF *> Batch control totals COMPUTE WS-BATCH-TOTAL-AMT = WS-HASH-OUT-A + WS-HASH-OUT-B + WS-HASH-OUT-C + WS-HASH-OUT-D + WS-HASH-OUT-E + WS-HASH-OUT-F + WS-HASH-OUT-G + WS-HASH-OUT-OTHER MOVE WS-HASH-IN TO WS-HASH-TOTAL DISPLAY ' ' DISPLAY 'Batch Control:' DISPLAY ' Batch Date: ' WS-BATCH-DATE DISPLAY ' Batch Time: ' WS-BATCH-TIME DISPLAY ' Total Amt: ' WS-BATCH-TOTAL-AMT DISPLAY ' Hash Total: ' WS-HASH-TOTAL . * 5000-AUDIT-SECTION. * AUDIT-LOG-START. MOVE WS-TIMESTAMP TO AU-TIMESTAMP MOVE 'START' TO AU-TIER MOVE 'PROGRAM' TO AU-KEY MOVE 0 TO AU-AMOUNT MOVE 'OK' TO AU-STATUS WRITE FILE-AUDIT-REC FROM WS-AUDIT-LINE IF FS-AUDIT NOT = '00' DISPLAY 'Audit write warning FS=' FS-AUDIT END-IF . AUDIT-LOG-RECORD. MOVE WS-TIMESTAMP TO AU-TIMESTAMP MOVE IN-KEY TO AU-TIER MOVE IN-KEY TO AU-KEY MOVE WS-DATA2-NUM TO AU-AMOUNT MOVE 'OK' TO AU-STATUS WRITE FILE-AUDIT-REC FROM WS-AUDIT-LINE IF FS-AUDIT NOT = '00' DISPLAY 'Audit write warning FS=' FS-AUDIT END-IF . AUDIT-LOG-FINISH. MOVE WS-TIMESTAMP TO AU-TIMESTAMP MOVE 'END' TO AU-TIER MOVE 'PROGRAM' TO AU-KEY MOVE WS-RECORDS-READ TO AU-AMOUNT STRING 'REC=' WS-RECORDS-READ ' ERR=' WS-ERROR-COUNT INTO AU-STATUS WRITE FILE-AUDIT-REC FROM WS-AUDIT-LINE IF FS-AUDIT NOT = '00' DISPLAY 'Audit write warning FS=' FS-AUDIT END-IF . * 6000-ERROR-HANDLE-SECTION. * 6000-ERROR-HANDLE. DISPLAY '[' WS-TIMESTAMP '] [' 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. * 9000-EXIT. 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 PERFORM 4000-REPORT-SECTION PERFORM 5000-AUDIT-SECTION THRU AUDIT-LOG-FINISH CLOSE FILE-IN FILE-A FILE-B FILE-C FILE-D FILE-E FILE-F FILE-G FILE-OTHER IF FS-AUDIT NOT = '00' CLOSE FILE-AUDIT END-IF DISPLAY '[' WS-TIMESTAMP '] BranchEval COMPLETED' .