Wayfinder / Case study / Documentation

Source-derived document; reported behaviour, inference and evidence gaps are identified in the text.

C05 — Business Rules and Decisions

In this document

Diagram coverage

Diagram / view Status Scope or next work
Decision-related state machine Linked 7 bounded views; 3 elements; 3 relationships.
Decision / activity branches Not yet generated Recover decision outcomes and guarded alternative branches in the diagram model.

Customer eligibility and maintenance

Customer creation is driven by the customer-entry flow. In the recovered 4GL source, input_cust() accepts the customer fields and inserts p_customer.* into customer; on successful completion it obtains the generated identifier from SQLCA.SQLERRD[2], displays that number, and returns success. An interruption using F1/CTRL-F for help or F2/CTRL-Y to leave input prevents the normal insertion path. The Java target D4_Cust.input_cust() reports equivalent insert-and-identifier behavior, but the supplied evidence does not include a complete Java D4_Cust implementation in every source range, so Java/4GL equivalence remains qualified. E0007 E0012

Customer search uses query-by-example rather than a single fixed key. The documented criteria include literal values, ranges separated by :, lists separated by |, relational operators, and ? or * wildcards. The customer query then browses matching rows with first, last, next, previous, select, and quit decisions. The Java implementation described in D4_Cust.query_customer() orders results by lname; the corresponding 4GL query evidence does not consistently show that ordering, so the ordering rule belongs to the named implementation rather than being treated as universal. Detailed query exchange and construction belong in C08. E0007 E0010

A customer update requires a selected customer number. In D4_Cust.update_customer(), the selected row is edited and an UPDATE customer ... WHERE customer_num = ? is issued unless input is interrupted. When the update is interrupted, the Java evidence says the stored row is reloaded and redisplayed, leaving the database unchanged. The 4GL source likewise restores the stored row after aborted input. Thus, an editable form and a selected identifier are necessary preconditions; neither alone proves that a database change occurred. E0007

Deletion has two reported safeguards: the user must confirm with y or Y, and the customer must not have related orders. The 4GL source describes the latter as preventing deletion when matching orders exist, while the Java target executes SELECT COUNT(*) FROM orders WHERE customer_num = ? before allowing deletion. The Java message calls these “active orders,” but the query counts all matching orders and does not visibly restrict by paid status, backlog, or another activity flag. Whether completed orders should remain a deletion barrier is unresolved and requires the business definition of “active order.” E0002 E0007

The evidence is not uniform about cancellation feedback. In the separate menu1.4gl.main program, del_cust() performs the delete only after confirmation but then unconditionally clears the form and displays “Record deleted.” A negative confirmation can therefore leave the row intact while reporting success. This is a behavior of menu1.4gl.main, not proof that D4_Cust.delete_customer() has the same defect. E0010

Order-entry decisions

The implemented D4_Orders.add_order() flow requires a customer selection or creation before order data is collected. It then accepts order-header information and line items, looks up stock by stock number and manufacturer code, retrieves description and unit price, validates quantity and price sufficiently to calculate a line total, and inserts the header and items in a transaction. The 4GL d4_orders.4gl evidence describes the same broad flow, including rollback when an insert reports failure. E0002 E0007

An order line is calculable only when a valid quantity and unit price are present. item_total() computes total_price as quantity * unit_price; when the lookup or required values are invalid, the source clears or rejects the line and returns the user to stock-number entry. The order-entry display supports up to ten items in the documented flow. The separate ordmenu.4gl.main program also maintains an array of up to ten items and renumbers item rows after edits. This capacity is an input and display limit, not evidence that the database cannot contain more than ten items. E0007 E0009

Stock selection is a lookup aid, not stock maintenance. In D4_Orders, CTRL-B can open the stock selection path while entering stock number or manufacturer code, and the selected record can populate the line. The stock menu itself is present, but D4_Stock.add_stock(), query_stock(), update_stock(), and delete_stock() each report that the option is not implemented. Consequently, selecting an existing stock record is evidenced; creating or changing stock through the current Java menu is not. E0002 E0007

The order-add transaction has explicit success and failure branches. The header is inserted, the generated order number is obtained, item rows are inserted, and commit occurs only after the required insert operations succeed. Failure of the header or item operation causes rollback in the visible branches. A broad exception handler does not visibly perform rollback itself, so the outcome of exceptions outside those branches depends on the database framework and ErrorHandler; complete atomicity is unresolved. E0012

Order totals contain a material ambiguity. D4_Orders.order_total() applies Money.valueOf(1.1d) to the line-item sum. Separately, invoice generation reportedly calculates 6.5% sales tax and 3.5% shipping, which together equal 10%. The evidence suggests an intended relationship, but does not establish whether the interactive multiplier represents both charges, whether it is display-only, or whether invoice calculation can duplicate the adjustment. Use of binary 1.1d also leaves cent-level rounding behavior dependent on Money. E0002 E0012

The source contains a separate, similarly named order program, ordmenu.4gl.main, whose Modify and Delete operations are implemented when chosen = 1. By contrast, D4_Orders.update_order() and D4_Orders.delete_order() only display “This option has not been implemented.” The implemented legacy behavior must not be attributed to the Java D4_Orders entry point. A rejected Java operation is a message, not an order state transition. E0002 E0009 E0012

The legacy order program also has conditional risks. det_ord() calls view_ord() and then unconditionally sets exist = 1, potentially restoring an order-selected condition after an empty result. In menu1.4gl.main, boundary fetches omit t_price even though privileged display later uses it. These are source-level findings concerning menu1.4gl.main, not established behavior of D4_Orders.java. E0010

State, address and reference-data validation

State entry is subject to a lookup decision. statehelp() checks whether the entered two-character state code identifies a valid state; when it does not, the source opens state_list, displays available state codes and names, and assigns the selected code back to p_customer.state. The form definitions configure the state field with UPSHIFT, but uppercase presentation or input conversion is not by itself proof of validity. The callback that connects every Java form event to validation remains partly dependent on framework evidence. E0007 E0009

Startup reference loading retains at most 50 states and 30 stock records in the Java global arrays. Records beyond those capacities are not retained for in-memory selection, and the visible loader does not establish a user-facing overflow warning. This is a runtime selection constraint, not a statement that the underlying state or stock tables contain no additional rows. E0012

Reporting decisions and thresholds

Mailing-label reporting uses query-by-example customer criteria and orders selected customers by ZIP code in the Java evidence; the 4GL report similarly prepares a customer query ordered by zipcode. Output can be directed to file, printer, or screen through print_option. File output uses a prompted filename, with labels.out reported as the default in the 4GL implementation. E0007

Accounts receivable selects orders whose paid_date is null, then groups and prints customer and order information. This provides a concrete unpaid-order rule for print_ar(); it should not be generalized to every meaning of “active order” in customer deletion. Backlog and stock-list report methods exist as menu surfaces but explicitly display that they are not implemented in the supplied Java and 4GL evidence. E0007 E0012

The recovered documentation identifies a visual threshold for item totals exceeding $500, displayed in reverse-video green. The syscolatt.unl evidence also records total_price conditions >=500 and <500, but the exact relationship between those metadata conditions and the visual rule is not independently established. The threshold should therefore be recorded as “over $500” where the help text says so, while the boundary treatment at exactly $500 remains a specific unresolved question. E0003 E0007 E0009

Security-sensitive decisions and unresolved rules

The bang() command accepts user input and passes it to _app.execute(true, Str.valueOf(cmd)); the source shows no allowlist or validation. Its effective privilege and command scope depend on the framework, but this is a consequential trust-boundary decision and is covered in C09. E0012

Customer query predicates are incorporated into SQL text after Construct.getQuery() or its 4GL equivalent produces a condition. The evidence does not show the escaping or restriction performed by Construct, so injection is not proven; nevertheless, the construction is not demonstrably equivalent to parameter binding. The specific question is whether Construct permits arbitrary predicates or safely limits them to supported query-by-example expressions. E0002 E0012

Finally, customer deletion semantics, order-total composition, report interruption handling, and the Java/4GL relationship remain consequential unresolved rules. The supplied evidence supports documenting each condition separately rather than choosing a single authoritative interpretation. Related transition and failure journeys are described in C04, record and field representations in C06, and operational configuration in C10.

Expandable topic detail

Browse all topic detail.

Browse diagrams and evidence gaps.