0193

Say It Like the Platform

testfield
fielderror
error
sales-header

Say It Like the Platform

Warehouse runs a release checklist before an order goes out the door, and when it refuses one the picker gets Ship-to code missing - no order number, no field name, nothing to click, and the German warehouse gets it in English. Business Central already knows how to say every one of those things properly: it names the field, the table and the exact document, translates itself, and even offers to open the record. Your job is to make the checklist speak like the platform.

Requirements

The starter ships a codeunit named "Release Checklist" with one public procedure - keep the name and the signature exactly:

procedure CheckReadyToShip(var SalesHeader: Record "Sales Header")

It already refuses a sales order that is not ready to ship, but every refusal is a hand-written text. Rewrite the three checks so that each refusal is the message Business Central itself raises when a record is asked to check one of its own fields.

Rules:

  1. The checks run in this order, and the first one that fails raises the error: "Ship-to Code" must not be blank; Status must be Released; "Shipment Date" must not be in the past.
  2. "In the past" means earlier than the work date, WorkDate(). The work date itself and any later date are fine. Compare against the work date, not Today - the tests first move the work date away from today's date, then set every shipment date relative to WorkDate(), and always give the document one.
  3. A blank "Ship-to Code" is reported with the platform's standard message for a field that must have a value.
  4. A Status other than Released is reported with the platform's standard message for a field that must be equal to a given value - the one that names the required value and ends by stating the current one.
  5. A past "Shipment Date" is reported with the platform's standard field message built around your own rule text: the field caption, then your text, then the table caption and the document's primary key, then a period. Your text is exactly must not be in the past; the period at the end is added by the platform, so do not add your own.
  6. A document that passes all three checks comes through unchanged: nothing on the record passed in, and nothing on the stored sales order, may differ from before the call.

All three messages carry the field caption, the table caption and the primary key of the document (Document Type and No.) automatically, which is why the checks have to run on the record itself.

What the tests check

The tests first move the work date away from today's date (to 15 January 2024), then create real sales orders and run CheckReadyToShip on them. For every refusal they generate the expected wording by asking the platform for the same field message on a copy of the same document, then compare your error text to it character for character - a hand-written message, however close, fails, and so does a rule text with a period of its own. They cover a blank Ship-to Code, a status of Open, Pending Approval or Pending Prepayment (chosen at random), a shipment date some days before the work date, and the order of the checks when several fail at once. Two documents that are ready must pass without an error - one shipping on the work date, one some days later; a check against today's date refuses both - and the first of them is re-read from the database and compared field by field with a snapshot taken before the call.

Pick object IDs in the range 50100–50199 and reference other objects by name, never by ID.

Learn More

Hint 1
The platform can already say all three things for you. A record knows its own field captions, table caption and primary key, and the Record data type has methods that raise a field-related error built from them - look through the Record methods whose names contain "Field".
Hint 2
Record.TestField(Field) raises the "must have a value" message for a blank field, and the two-argument TestField(Field, Value) raises the "must be equal to ... Current value is ..." message when the field holds something else. Both take the field itself, not its name, so the caption and the document key come for free.
Hint 3
For a rule the platform cannot know, Record.FieldError(Field, Text) composes <field caption> <your text> in <table caption> <primary key>. - compare "Shipment Date" against WorkDate() yourself, then pass a Label reading exactly 'must not be in the past' with no trailing period (the platform adds it). Keep the checks in the order Ship-to Code, Status, Shipment Date, and leave the record alone.
ALBusiness Central 28.5
Press Compile to check your code compiles — Submit runs the tests.
The code editor is desktop-only
Open this problem on a computer to write and run code. Reading the description, tests and discussion works fine here.