Program 1 is responsible for reading the transaction records from the file TB17TD.DAT. This file contains 4 types of records, as described in the Program Overview. These records must be validated to ensure that the subsequent programs can correctly process the data. Valid records are written to a valid transactions file (TB17VF) but records containing invalid data are printed on an error report (TRANSACTION FILE ERROR REPORT) along with an error code (or codes for multiple errors) to indicate why the record was rejected.
Program initiation Program 1 run is controlled by a main paragraph ( CONTROL-PARAGRAPH) which begins by first setting up the error report print out (INITIAL-PARAGRAPH). This involves acquiring the system date, printing report title and column headers (PRINT-HEADERS), and setting page number to 1. Also, the first record is read (as a prime read). Following this, the record is modified such that any lower case letters used in the record type, customer code check digit (if "x"), or for issue or return records, part number check digit (if "x"), are converted to upper case letters, performed by the paragraph MAKE-CHARS-UPPCASE.The record type is then used as a flag to direct the program logic since different record types require different validation procedures. The main iteration of the program is performed by MAIN-PROCESS, which loops until the end of TB17TD.DAT is reached. This paragraph begins by performing the validation procedure VALIDATE-FIELDS. This paragraph returns a flag that will mark the record as either valid or invalid, thus determining whether to write the record to the valid file or to print the record on the error report.
Record validation VALIDATE-FIELDS initially tests the customer code since this is common to all record types. For this reason, the record is read into a WORKING-STORAGE item (line 000730) that gives a general definition to the record type and customer code. The customer code digits is first tested to ensure that it contains only numeric data, since the modulo 11 test cannot be performed otherwise. If the digit does contain non-numeric data, a flag ( CUS-CODE-NOT-NUMERIC)is set to true and the modulo 11 test is not performed.To perform the modulo 11 test the paragraph MOD-CHECK is used. First, the variable MOD-DIGIT-SIZE must be set to 4 (rather than 5, used when for checking part number codes). The customer code check digit is also moved to an item (MOD-CHK) used by the MOD-CHECK paragraph. The reason for this being that the same paragraph can be used to test both 4 and 5 digit codes. Lastly, the customer code digits are move to a table (CC-DIGITS) that allows for each individual digit of the code to be accessed as a single element of this table. To test the customer check digit, MOD-CHECK calculates what the check digit should be and compares it with the check digit from the record. To calculate the check digit, an increasing subscript (using a PERFORM VARYING... loop) is used to sequentially access each code digit and multiple it by the appropriate weight, also contained within a table (CC-TABLE). The products are added to produce a sum that is divided by 11. The remainder of this division is then subtracted from 11, unless the remainder is zero (where calculated check digit is set to zero) or 1 (where calculated check digit is set to 'X'). Because the check digit can either be numeric or alphabetic, the check digit item is redefined in WORKING-STORAGE as a level 01 item (as W-CHK) to allow storage of 'X', and as a level 03 (as W-CHK-NO; PIC 9 defined). The calculated check digit is then compared to that in MOD-CHK (from the record) and either a "N" or "Y" character is moved to a flag (MOD-FLAG) for either correct or incorrect check digit, respectively. MOD-CHK is described in the comment on line 1240 as a pseudo flag because the contents of MOD-CHK are then moved to the actual customer code modulo fail flag (CUS-CODE-MOD-FLAG) when the logic returns to VALIDATE-FIELDS. When testing the part number check digit, the contents of MOD-CHK are moved to the actual part number modulo fail flag (PART-NO-MOD-FLAG). The modulo test for part number, the same checking procedure MOD-CHECK is used as above, except that the sum of products is calculated for a 5 digit number, hence using different tables (PN-DIGITS and PN-WEIGHT-TAB). The different calculating methods for either customer code or part number are distinguished using an IF..THEN statement that tests the digit size (set in MOD-DIGIT-SIZE). The remaining tests performed by VALIDATE-FIELDS are the specific to the record type. This is coded uses the EVALUATE statement (rather than nested IF..THEN statements) for reasons of clarity. The record type flag is tested: When the record type indicates an issue or return record, the part number is tested in the same way as customer code was tested, establishing flags for numeric or non-numeric part number, and correct check digit. The quantity field is also tested for numeric or non-numeric status. When the record is a creation record the name and address fields are tested to ensure that they contain data other than spaces, or spaces with " ; " delimiters. The balance and credit limit fields are tested to ensure that they contain numeric data. Since deletion type records have no further fields and so require no further validation, the last condition tested is whether a record type is NOT a deletion type. This test will determine if a record has an unrecognised record type, i.e. any character other than "I", "R", "C" or "D". When this is the case the unrecognised record type flag is set to true. The last function of VALIDATE-FIELDS is to test all the individual test flags. If any of these flags are true then the main validation flag (INVALID-REC-FLAG) is set to true. The logic returns to MAIN-PROCESS where the decision is made, either to write the record to the valid file, or print it on the error report (lines 003300 to 003340). This decision depends on the main validation flag returned by VALIDATE-FIELDS.
Error record printing When a record is labelled as invalid the paragraph PRINT-ERROR-RECORD is executed. Firstly, the record type and customer code are move to the appropriate print fields. Since different record types require different further print fields a series of IF..THEN statements are employed. Depending on the record type, specific paragraphs are executed (SET-IR-PRINT or SET-C-PRINT), or alternatively setting the appropriate unused print fields Issue and return records have the part number moved to an appropriate print item. The quantity field is defined in WORKING-STORAGE to zero-suppress numeric data (line 002030). However, if this data is non-numeric (a reason for the record being rejected), then the quantity print item must be re-defined in WORKING-STORAGE at level 03 to allow alphabetic data to be printed (line 002020; IR-QUANT-NN). The same problem for balance and credit limit in creation records is solved in this manner. To improve the readability of the report, hyphens are placed into the unused name and address print fields so that the error codes that appear at the end of the printed line can more easily be associated with the relevant customer code. The unused balance and credit limit fields are zero filled and so will appear blank, having been defined in WORKING-STORAGE as BLANK WHEN ZERO. Deletion records also zero fill balance and credit limit fields in addition to the unused quantity field (defined as BLANK WHEN ZERO). The name and address fields are filled with hyphens. Creation records zero fill the quantity field and move balance and credit limit to appropriate fields, with the balance print item defined with a floating negative sign to display any negative balance. Name and address are move to appropriate print fields without any modification. The address print item contains enough room for 30 characters of the address. If this is exceeded the address is truncated since it is felt unnecessary in this error report to fully display the address (unlike in reports produced by Program 2 and Program 4). After each print field has had the appropriate data set to each print field, the error codes must be set to the error code print item. This action is performed by the paragraph SET-ERROR-CODES. To allow for the possibility that a record may have more than one error, then error code print item is defined as a table that can hold up to 4 error codes (the maximum possible). Each error flag is test in turn. When a flag is true, the appropriate error code is added to the print item and 1 added to the subscript number.
After the error codes have been set the record is then tested to determine if it is an unrecognised record type. This is because unrecognised records have their own form of print fields (with a separate print group definition in WORKING-STORAGE). As such, these records are printed to show record type character (erroneous), customer code, and the rest of the record is printed as a single field. The error code "U" is displayed but no other error codes. The paragraph PRINT-TYPE-X sets up the print items. To avoid blank (space filled) lines in the transaction file being read as unrecognised record types, being printed as an error and also adding to total record count and error record count tallies, the IF..THEN statement at the start of PRINT-TYPE-X tests for spaces (line 005890). If this is the case, then 1 is subtracted from record and error record counters and the print is skipped. The PRINT-ERROR-RECORD then prints either then unknown record type (when the flag NOT-REC-TYPE is true) or prints the recognised record type. Following this, 1 is added to the line number and the line number is tested. When it is greater than 50 a new page is started and PRINT-HEADERS executed. Logic then returns to the MAIN-PROCESS paragraph where all validity flags are reset to false in readiness for the next record to be read from transaction file.
Program termination When the end of the transaction file is reached, the end of file flag is set to true and the logic exits from the MAIN-PROCESS loop and thus enters TERMINATING-PARAGRAPH. Now the accumulated totals are printed for total records read and total error records printed. The count of records read is done within the READ statement. The count of error records is done at line 004530 when the record is signalled for printing on the error report. Following this, there are printed a key to record type abbreviations, a key to the error codes, and a message stating "END OF REPORT". To ensure that the printed footers will not be printed over 2 pages, the line number is tested to ensure that line number is not greater than 36. If so, a new page is started. All new pages are preceded with a blank line to give an upper margin on the print out. This paragraph is also responsible for closing the transaction file and printer. Logic returns to CONTROL-PARAGRAPH where the run is stopped.
Program limitations Duplication of creation and deletion type records can lead to minor problems in Program 3 (see Program 3 limitations). It is not possible to deal with such duplications in Program 1 since the records are not yet sorted. A solution could be coded in Program 2 (see Program 2 limitations). |