Rules. ## Naming Conventions in Rules **RULWORK** The **DATA DIVISION** coding for your Rule will be inserted into the LINKAGE SECTION of online MMP's, within the TWA (cont.) area. MAGEC will generate a group item above your coding. The group item will be a Cobol level 03; therefore your *work (cont.) fields should be Cobol level 04 and greater*. Since your Business Rule might very well be inserted into many programs, and since several Business Rules might very (cont.) well be inserted into any one program, you should abide by certain conventions in naming your work fields. We (cont.) suggest: eeeee--dddddddddd where: **eeeee** — = the Element name **--** — = two dashes separate the Element name prefix from the remainder of the dataname **dddddddddd** — = up to 23 characters of valid Cobol dataname This scheme will avoid conflicts between multiple Business Rules, thanks to the Element name prefix. It will avoid (cont.) conflicts with the datanames within the generated Element definition copybook, thanks to the two dashes. It will also (cont.) avoid conflicts with standard datanames generated into all MMP's by MAGEC, and with datanames the programmer is likely (cont.) to define in normal customization. **RULPROC** and **RULDELT** The **PROCEDURE DIVISION** coding should also conform to certain conventions in order to avoid similar conflicts as (cont.) were described for Data Division coding. We suggest a naming scheme for paragraph names, as: BB6nn-eeeee--pppppppppp where: **nn** — = any 2-digit sequence number **eeeee** — = the 5-character Element name **--** — = two dashes separate the Element name from the remainder of the procedure name **pppppppppp** — = up to 17 characters of valid Cobol procedure name ## Conditional MAGECINC's You will likely find many occasions to code the -MAGECINC command into your Business Rule coding. One of the obvious (cont.) situations where -MAGECINC's will be needed is when you are doing I/O on your Procedure Division logic. You will need (cont.) to include the Element definition copybook(s) into the Data Division in order to provide the area to read into and (cont.) write from. This introduces an opportunity for error. Since your Rule will likely be inserted into several MMP's, there is the (cont.) distinct possibliity that one or more of them will already be including that same copybook, resulting in duplicate (cont.) datanames and compiler errors. In order to avoid this error we recommend that you always make your -MAGECINC's (cont.) "conditional", that is: code them so that they will be expanded only if they have not been expanded elsewhere in the (cont.) same program. That is done using the -IFUNIQUE command, as: -IFUNIQUE -MAGECINC member/modifier The -IFUNIQUE command must immediately precede the -MAGECINC, as shown above. It applies to the member named in the (cont.) -MAGECINC which immediately follows it.. You can use as many of the -IFUNIQUE and as many -MAGECINC commands in one (cont.) Rule, or in one program, as you need. The -IFUNIQUE works even if another -MAGECINC for the same member appears physically behind this one in the program. (cont.) The -IFUNIQUE feature is not limited only to Business Rules, it can be used anywhere, but it is particularly useful in (cont.) Business Rules. ## Restrictions in Rules Since your Rules will be inserted into many programs you should abide by certain restrictions when coding them. This is necessary to avoid tying the Rule to one particular program or screen. Never code **references to screen fields**, except for the four standard fields which MAGEC forces all screens to include. They are: SFUNCT function code - 6 characters SKEY free-form key - 31 characters SCOMPL completion message - 40 characters SERRMSG error message area - 240 characters This includes all the associated attribute, color, highlighiting, position, and error flag fields for them. You can, however, refer to screen fields indirectly using MAGEC's symbolic screen field references. Never code **references to datanames** except those that are either: 1) defined in the RULWORK code for this Rule. 2) defined as standard fields in all MMP's. 3) defined in the Element (cont.) copybook for the Element this Rule is associated with. 4) Cobol special registers available to all (cont.) programs. Never code** references to paragraph names** except those that are either: 1) defined in this RULPROC logic. 2) generated into all MMP's by MAGEC. Never **GO TO** paragraph names except those that are both: 1) within the BB600 through BB699 routine. 2) defined in either every MMP, or within this RULPROC logic. To** exit **the RULPROC logic you should GO TO BB699-EXIT. ## Setting Default Values SInce the RULPROC coding is inserted into the MMP as the last process before the data is actually updated to the (cont.) database, you will find that this is a handy facility for testing for "null" values in fields and setting default (cont.) values for them. This gives the DBA control over default values and relieves the application programmers from that (cont.) chore. The result is more consistent handling of data across many applications. ## Preventing Updates The most obvious purpose for Business Rules is to prevent data from being placed onto the database unless it passes (cont.) stringent validation requirements. These validations can involve cross-field, or even, cross-file, comparisons. The (cont.) RULPROC logic is inserted just before the actual database update in the generated MMP's; therefore it can set an error (cont.) flag to cause the MMP to bypass the update and issue an error message instead. You do that by (cont.) coding: MOVE 'xxx' TO ERROR-NUMBER PERFORM CA100-LOAD-ERR-CODE-TBL THRU CA199-EXIT. where: **xxx** — = the (alphanumeric) number of the error message you wish to have issued. That is exactly how it is done in the customization editing that a programmer does for an MMP, except that s/he would (cont.) usually also set the screen field's error flag for the screen field being edited. In the Business Rules, you are (cont.) editing database fields, not screen fields. All of the screen data has been moved to the database before your RULPROC (cont.) logic was invoked. You can; however, set the attributes for the four standard MAGEC screen fields, and you can make use (cont.) of MAGEC's symbolic screen field referencing discussed later in this section. ## Creating "Master" Record In some instances you might wish to automatically generate a "master record" when a "detail record" is added, if no (cont.) master record already exists. A possible example: generate an invoice header when the first invoice line item is added, (cont.) fill in default values into the header. Just as you can do I/O to read the master record, you can do I/O to add it if (cont.) it does not exist. If you do add a new master record, it might also be helpful for you to alter the function code on (cont.) the screen (SFUNCT) to the one which will display that new master record; the default logic ot the MMP's will then (cont.) display the screen with the "data ADDED to database" message in SCOMPL, and the new function code in SFUNCT, ready for (cont.) the operator to press ENTER to display the master record's data or to update it. ## Assigning Keys In some cases, you might wish to control the key value for new records added to a file by accessing a control file to (cont.) obtain the next available key value. This relieves the application users from having to determine a new key and gives (cont.) you, the DBA, control of new keys added. The new key values might be check digit'ed numbers. The Business Rules are a handy place to accomplish the setting of the new key into the new record. You can access a (cont.) control file, or record, by coding a standard I/O call. You can also call a subroutine, if you happen to have one which (cont.) assigns key values. If you had a Journal Entry file whose key was Voucher Number, you might have many different programs which could add (cont.) new Journal Entries. Because of your Business Rule logic to assign Voucher Numbers (perhaps by calling a subroutine), (cont.) none of the MMP's or their authors had to bother themselves with "how to assign a Voucher Number" and you are assured (cont.) that all Voucher Numbers are assigned correctly (or, at least, uniformly). # Referential Integrity ## Deletion Rules Another feature, related to Business Rules, is called "Deletion Rules". This enables the DBA to specify logic to be (cont.) triggered (invoked) whenever a record (containing the specified element) is to be deleted. The restrictions which apply to the Procedure Division coding for a Business Rule (RULPROC) also apply to the coding of (cont.) a Deletion Rule (RULDELT). Please refer to the previous topic in this chapter for full descriptions. The only (cont.) difference is that the modifier RULDELT is used instead of RULPROC. Any work areas needed for the RULDELT logic are to (cont.) be defined in the RULWORK coding, just as they are for RULPROC. Do not define the same work field twice since all three (cont.) of these members (RULWORK, RULPROC, and RULDELT) will be inserted into each MMP which updates the specified (cont.) element. To add a Deletion Rule for the CUS01 element, you would use the command: RULADD CUS01/RULDELT The code that you provide for RULDELT will be inserted into the generated MMP's in the BB400-EDIT-FOR-DELETE paragraph. (cont.) **The exit from that routine is BB499-EXIT**. In all other respects the RULDELT coding must follow exactly the same (cont.) restrictions as apply to RULPROC. You can do virtually any type of processing in the RULDELT logic, including I/O and complex field content or value (cont.) checking. Deletion Rules can serve several very important functions associated with ensuring referential (cont.) integrity. ## Prevent Deletion (Restrict) In the RULDELT code you could, perhaps, test for the existence of subordinate items (e.g. test for existence of (cont.) invoices on file for a customer you are about to delete) and, if found, set the ERROR-FOUND condition to prevent the (cont.) deletion from taking place. Another reason you might wish to prevent the deletion of an item is because of certain data item contents. For example, (cont.) if the customer's balance is not zero. You might even wish to prevent deletion of certain cirtical records based on (cont.) their ID, e.g.: customer numbers 00001 through 00100 may not be deleted, ever. You can test for PF keys in this logic. You might even wish to create a Deletion Rule which states that customer numbers 00001 thru 00100 *can *be deleted if you press PF14 (or some other key). ## Auto Delete (Cascade) Another possibility would be to automatically delete any invoices for the customer about to be deleted. ## Alter References (Nullify) Another scenario involves not deleting the invoices, but rather, modifying them so that they now reference a different (cont.) customer. One possibility is to have them reference a "dummy" customer number that is used for miscellaneous "walk-in" (cont.) business. ## Other Processes Many other types of processing are possible in the RULDELT logic. Some examples of them are: Control Record Update You could update a control record, perhaps the salesman's record to reflect one less customer. Master Deletion When deleting the last invoice for a customer you might wish to delete the customer's master record. Audit Trail Generation You might wish to generate a record on a log file whenever certain data is deleted. There is virtually no limit to the types of processing you might wish to apply in the Deletion Rules. Remember, it will (cont.) be invoked just prior to to standard MMP logic to delete a record. If you set the ERROR-FOUND condition (usually by (cont.) performing CA100-LOAD-ERR-CODE-TBL) then the delete will not be done. As an example: IF CUS01-BALANCE GREATER THAN ZERO MOVE 'xxx' TO ERROR-NUMBER PERFORM CA100-LOAD-ERR-CODE-TBL THRU CA199-EXIT. where: **xxx** — = the (alphanumeric) number of the error message you wish to have issued. # Symbolic Screen Field References ## In Business Rules As discussed earlier, you should never directly reference screen fields from within a Business Rule or Referential (cont.) Integrity Rule. This is because your Rules will likely be inserted into several programs (MMP's) and you have no way of (cont.) knowing what name the screen field associated with a given database field might have, or even that there is a screen (cont.) field associated with that database field. This restriction presents an inconvenience in that it would be helpful, and more consistent with the way MAGEC screens (cont.) tend to behave, if you could access the screen fields -- especially the error flags and attribute bytes. This would (cont.) enable you to use MAGEC's standard error handling features which highlight error fields and home the cursor to them, or (cont.) to display values in screen fields, or to manipulate attributes and position the cursor. Fortunately, there is a way you can do all these things from your Rules. Though you must not refer to any screen fields (cont.) (except for the four standard fields, as noted earlier) directly by their Screen Field dataname, you can refer to them (cont.) indirectly using symbolics based upon the database field's dataname. Such symbolic references are coded using the (cont.) database name enclosed in at-signs (@). For example: ``` MOVE ATUADHNF TO @CUS01-AMOUNT-DUE@A. MOVE @CUS01-AMOUNT-DUE@-POSN TO TWA-MSK-CUR-AD-OT. ``` would set the attribute for the screen field associated with the database field "CUS01-AMOUNT-DUE" to high-intensity, (cont.) unprotected; and it would position the cursor to that screen field. In the application developer's generated MMP, this (cont.) code would be translated into: ``` MOVE ATUADHNF TO SFIELDA. ``` ``` MOVE SFIELD-POSN TO TWA-MSK-CUR-AD-OT. ``` assuming, of course, that the name of the screen field associated with CUS01-AMOUNT-DUE was 'SFIELD'. That screen field (cont.) dataname might well be different in several programs which each reference this database field; the translation would, (cont.) automatically, be adjusted accordingly. This allows you to refer to screen fields without having to know their (cont.) names. If the database field in question happens to be an arrayed field (it has an OCCURS clause), then you must include the occurrence number (maximum of 3 digits) within the at-sign brackets, e.g.: ``` MOVE ATSADHNF TO @CUS01-ADDR (2)@A. ``` Notice that the expression within the at-sign brackets is converted into the screen field's dataname, without any of (cont.) the suffixes appended. You can code the desired suffix immediately behind the closing at-sign (no space between them) (cont.) to reference any of the datanames in the screen definition. You could refer to the "Screen Painting" and "Color 3270" (cont.) chapters of the *Programmer's Reference Guidel* for detailed discussions of the datanames in the screen mask copybook. (cont.) Here is a quick review: Assuming that the screen field has a dataname of "SFIELD", the possible datanames found in the copybook would be: SFIELD — the screen field itself, implied or explicitly PIC X(nn). SFIELDA — the attribute byte SFIELDE — the error byte for this field SFIELD-ED — the Cobol edit picture, redefining SFIELD (if a numeric field) SFIELD-POSN — the screen position of the start of this field SFIELD-COLOR — the 7-color code (if a 7-color field) SFIELDH — the extended highlight code (if a 7-color field) SFIELD-JULIAN-DATE the julian equivalent (if a date field) SFIELD-DAY-OF-WEEK the day of week code (if a date field) SFIELD-N — the numeric value (if a numeric field) SFIELD-YY — the year (if a date field) SFIELD-MM — the month (if a date field) Next: https://magec.com/DOC/markdown/db09.md.txt