Sourced Promo Code Field, Historical Reporting and Line-Level Restrictions
Marketing maintains a promo code on each item in custitem_promo_code. Sales order lines carry custcol_promo_code, a custom transaction column field sourced from the item field with Store Value checked, and the field definition has not changed since go-live. Finance's saved search, Promo Revenue by Code, joins to the item and groups on custitem_promo_code. After marketing bulk-updated 1,800 item promo codes, last year's promo revenue report changed, even though the order records still show the original codes on each line. Separately, orders created by an integration through a RESTlet have a blank custcol_promo_code on every line. The Australian subsidiary also wants only its pricing team to be able to change promo codes on order lines, and has asked for that restriction to survive someone importing orders through the UI.
1. Explain why the historical report changed while the order lines kept their original values, and what you would change.
Read the worked answer
The order lines did not change; the report is not reading them.
The saved search groups on custitem_promo_code, which is reached through the item join. That is the item's current value. When marketing updated 1,800 items, every historical order line pointing at those items began reporting the new code. Meanwhile custcol_promo_code on the transaction still holds the value captured when the line was saved, which is exactly what Store Value is for.
Fix the reporting layer, not the field:
- Rebuild the saved search to group on the transaction column field
custcol_promo_codedirectly, using the Sales Order line as the record type or as the transaction columns of the search. Do not join to the item for promo code unless you genuinely want the current item code. - Treat this as a general review item. Any finance report that groups on a sourcing source field instead of the stored snapshot has the same defect, and the same 1,800-record update would have hit all of them at once.
- If a report must show both, expose them as separate columns with unambiguous labels, current item code and code at time of sale.
One diagnostic worth running before changing anything: confirm Store Value is actually checked on the field and that historical lines are populated, because an unchecked field would produce a similar symptom at the transaction level and would need a different fix, namely designing a snapshot rather than repairing the search.
2. Why do RESTlet-created order lines have a blank promo code, and what is the reliable fix?
Read the worked answer
Field sourcing is not a server-side guarantee. Sourcing runs as part of the record editing experience, and a record.create from a RESTlet sets the item and the other fields you provide; it does not replay the UI's sourcing chain for every dependent column. With dynamic mode off, the record also is not recalculated as fields are set. The result is a saved order with populated items and an empty promo column.
Reliable fix, in order of preference:
- Set the value explicitly in the integration. When building each line, read the item's
custitem_promo_codefrom the item data the integration already has, or from one batched item search, and assigncustcol_promo_codeon the line. This is the only approach that is guaranteed regardless of how the record is created. - Add a
beforeSubmituser event on Sales Order that backfills a blankcustcol_promo_codefrom the item before commit. This catches RESTlets, CSV imports, and any future channel, and it runs before the record is written, so the stored snapshot is correct. - Add a validation or exception report for blank promo codes so gaps surface instead of silently skewing revenue reporting.
What not to do: turn on dynamic mode broadly to force recalculation. It increases processing cost on every setValue and still does not define sourcing behaviour for every field type, so the blank lines can return. Explicit assignment plus a server-side backfill is boring and correct.
3. How would you restrict promo code editing to the Australian pricing team, given that transaction column fields have no per-role edit restriction?
Read the worked answer
There is no field-level role restriction on a transaction column field, so the restriction has to be composed from what the platform does offer. The client-side piece alone is not enough, because client scripts are advisory and an import can bypass them.
Layered answer:
- Server-side enforcement. A
beforeSubmituser event on Sales Order compares the submitted line values against the stored record. If the promo code changed and the executing user's role is not in the pricing role set, throw an error. This is the authoritative control; it catches UI edits, CSV imports with scripts enabled, and RESTlet writes. - Client-side usability. A client script disables or makes read-only the column for other roles, so people do not fill in a value that will later be rejected. Nice to have, never the only control.
- Form-level presentation. A subsidiary-specific custom form with the field set to disabled for general use, with the pricing team's preferred form left editable. This reduces accidental edits but does not enforce anything by itself.
- Fallback if line-level granularity is not essential. A custom segment with role restrictions gives real per-role control, but it classifies the transaction, not the individual line, so it is a different reporting model.
Also decide what a legitimate correction looks like, since the pricing team will need one. An approval workflow or a dedicated correction role keeps the control meaningful instead of pushing users to request administrator edits.