1. Purpose

The Commercials layer turns cost into revenue. After Items are costed, a sequenced set of Rules applies commercial adjustments (markup, margin, contingency, risk allocation) to derive the Submission Values shown to the client. Submission Values can then be manually overridden before Publisher Output is generated — the final submittable artifact (PDF, Excel) sent to the client.

Commercials are the bridge between internal build-up and client-facing pricing.


2. The three Commercials entities

2.1 Rule

A single commercial adjustment rule. Rules apply in sequence; later rules stack on earlier ones. Each Rule has a type (Percentage / Lump Sum), a scope (which Items/Costs it targets), and a value.

2.2 Submission Value

The final rate or amount shown to the client for a Schedule Item. Computed by Commercials, manually overridable, one-per-Schedule-Item.

2.3 Publisher Output

The client-submittable artifact generated at publish time (PDF, Excel, etc.). Captures the final Schedule, branding, cover letter, conditions, inclusions, exclusions. Preview-vs-publish distinction: preview is a read-only render of the submission artifact accessible to estimators; publish commits it and transitions the parent Estimate to Submitted (subject to BR-019c).


3. Rule — Attributes & Behavior

AttributeTypeRequiredDefaultNotes
idUUIDgeneratedSystem-managed
namestringE.g., “Contingency 5%”, “Margin 8%”, “Risk allowance $20K”
rule_typeenumPercentage / Lump Sum. See §3.3
valuenumberFor Percentage: 0–100 (e.g., 5 for 5%). For Lump Sum: absolute amount (e.g., 20000 for $20K)
sequence_orderintegerautoApplied in ascending order (BR-070). Unique within an Estimate’s Rules
scope_targetpolymorphicSpecifies which Items/costs this Rule targets (see §3.4). Many-to-many join
scope_target_detailsJSONconditionalnullAdditional filters (e.g., if target is “Specific Item”, which Item ID; if “Categorization Option”, which option)
noteslong textnullRule rationale / assumptions
created_at / updated_attimestampsystemAudit
created_by / updated_byUser refsystemAudit

Derived attributes (computed, not stored) — see §9.


3.3 Rule Type

Enum: Percentage or Lump Sum. No Rate Adjustment type in v1 (BR-071; rate adjustments are handled via Submission Value overrides, BR-072).

TypeBehaviorExample
PercentageApplied to running total as a percentage. Stacks multiplicatively.”Margin 8%”: adds 8% of the subtotal (after prior rules)
Lump SumFixed dollar amount, distributed proportionally across in-scope Items by cost contribution”Risk allowance $20K”: split across Items as item_share = (item_cost / total_in_scope_cost) × $20K (BR-074a)

3.4 Rule Scope Targets (BR-073)

A Rule targets Items/costs by scope. Multiple scope targets can apply; a Rule can target multiple Items through different scope definitions (polymorphic join).

Confirmed v1 scope targets:

  1. All — apply to all direct costs in the Estimate
  2. Direct-only — Items structurally derived as direct (Schedule Items + their descendants, unless Indirect Cost flag overrides)
  3. Indirect-only — Items structurally derived as indirect, OR flagged with Indirect Cost flag
  4. Specific Heading (subtree) — everything nested under a chosen Heading
  5. Item Type — e.g., “all Schedule Items”, “all Provisional Items”
  6. Resource Type — e.g., “all Labour Resources” (applies to the cost of those Resources across the Estimate)
  7. Categorization Option — e.g., “all items tagged ‘Mechanical’”
  8. Code value — e.g., “all items with Workcentre = ‘Civil’”
  9. Specific Item — one-off surgical adjustment to a single Item (see A7.2, Margin/risk allocation per item)

Relationships:

  • Rule M:M Scope Target — a Rule can reference multiple scope targets (e.g., both “Direct-only” and “a specific Categorization Option” simultaneously — both must match for the Rule to apply to that Item)

3.5 Rule Application (BR-070, BR-074)

Rules apply in sequence order (ascending sequence_order). Each Rule:

  1. Evaluates its scope targets to determine which Items it applies to
  2. Computes its adjustment (Percentage of current running scope total, or fixed Lump Sum)
  3. Adds the adjustment to the running total for those Items

Rule application is sequential and compounding. Each rule applies to the running state of its scope after all prior rules in the sequence have been applied. Changing rule order changes the final totals—this is intentional and a key reason rule sequencing exists (BR-070).

No cross-rule dependencies. Each Rule takes the current running total (after all preceding Rules) and applies its adjustment independently. No Rule references another Rule; no conflict resolution.

Spread mechanics (BR-074a): When a Rule targets multiple Items (e.g., “Margin 8% on Direct costs” or Lump Sum $20K across 50 Items), the rule amount is distributed proportionally across in-scope Items based on their cost contribution to the total in-scope cost. For Percentage rules, each Item receives its proportional share of the percentage-calculated adjustment. For Lump Sum rules, each Item receives a proportional share: item_share = (item_cost / total_in_scope_cost) × lump_sum_amount. The underlying Item costs don’t change — the adjustment is applied on top, distributed proportionally by cost weight.


4. Submission Value — Attributes & Behavior

AttributeTypeRequiredDefaultNotes
idUUIDgeneratedSystem-managed
item_idItem refForeign key. One-per-Schedule-Item (1:1 relationship). Schedule Items only
computed_valuenumberResult of running all Commercials Rules on this Item (see §4.2). Stored for audit
override_valuenumbernullEstimator override (BR-072). When set, this value replaces computed_value in final submission. Audit trail preserved
final_valuenumbercomputedEither override_value (if set) or computed_value
audit_noteslong textnullEstimator-entered justification for override (e.g., “market check $875/m³”)
created_at / updated_attimestampsystemAudit
created_by / updated_byUser refsystemAudit

4.2 Submission Value Derivation

The computed_value is derived by:

  1. Starting with the Item’s total cost (from its Worksheet — see Item spec §9)
  2. Running all Rules in sequence_order that apply to this Item (per Rule scope targets)
  3. Accumulating adjustments (Percentage Rules compound; Lump Sum Rules stack additively)
  4. Storing the final computed total in computed_value

Before publish, the estimator can review and override any Submission Value (BR-072). The override is optional but auditable — if set, final_value = override_value; otherwise final_value = computed_value. Estimator provides optional notes justifying the override.


5. Publisher Output — Attributes & Behavior

AttributeTypeRequiredDefaultNotes
idUUIDgeneratedSystem-managed
estimate_idEstimate refForeign key. M:1 relationship. Only latest version kept per Estimate (BR-075)
file_typeenumPDFPDF / Excel (extensible)
generated_datetimestampsystemWhen output was generated
versionstring“v1”Admin-controlled version label (e.g., “v1”, “Final”, “Client Review”)
cover_letterlong textnullSubmission cover letter text (estimator-entered, carries forward across republishes)
conditionslong textnullGeneral conditions / terms (estimator-entered)
inclusionslong textnullWhat is included (Content Block instance or free text)
exclusionslong textnullWhat is excluded (Content Block instance or free text)
branding_configJSON{}Branding (logo, header, footer, colours, fonts). References branding template from admin config
schedule_snapshotJSONFrozen copy of the Schedule Item structure + Submission Values at time of publish (for stable output)
noteslong textnullInternal notes (e.g., “sent to client 15 Apr”)
created_at / updated_attimestampsystemAudit
created_by / updated_byUser refsystemAudit

Relationship: Publisher Output M:1 Estimate. Only the latest version is retained per Estimate (BR-075); older versions are not archived.

Submit gate (BR-019c): the Publisher Output preview is always accessible to estimators — useful for seeing the current submission state and what’s still outstanding. The final Submit action, however, is blocked while any Item in the parent Estimate has status Unpriced or Plugged. When blocked, the Submit action surfaces an anomaly list highlighting the Items that still need pricing.


6. Relationships

Inbound (things referring to Commercials entities)

FromCardinalityNotes
EstimateEstimate 1:M RuleRules belong to an Estimate’s Commercials layer
Item (Schedule)Item 1:1 Submission ValueSchedule Items only
EstimateEstimate 1:0..1 Publisher OutputLatest version only (BR-075); absent until first publish

Outbound (things Commercials entities reference)

ToCardinalityRequiredNotes
Estimate (Rule)Rule M:1 Estimate
Estimate (Publisher Output)Publisher Output M:1 Estimate
Item (Submission Value)Submission Value 1:1 ItemSchedule Items only
Scope Target (polymorphic) (Rule)Rule M:M Scope TargetCan target: Heading, Item Type, Resource Type, Categorization Option, Code, specific Item, structural (All/Direct/Indirect)

7. Validation / Invariants

  1. Unique sequence within Estimate. Every Rule’s sequence_order within an Estimate must be unique and start from 0 or 1.
  2. Rule value non-negative. value must be ≥ 0.
  3. Percentage bounds. If rule_type = Percentage, value should typically be 0–100 (but not hard-capped; allow for >100% for exceptional cases).
  4. Submission Value 1:1 Schedule Item. Every Schedule Item gets exactly one Submission Value, created atomically with the Item. Non-Schedule Items don’t have Submission Values.
  5. Final Value derivation. final_value = override_value if override_value is not null, else computed_value. Enforced at write/read time.
  6. Publisher Output latest only. Only the latest Publisher Output per Estimate is retained. Publishing a new version replaces the prior one.
  7. Audit trail on override. When override_value is set, updated_by and updated_at are recorded, and optionally audit_notes.

8. Derived / Computed Attributes

AttributeOn entityDerivationNotes
computed_valueSubmission ValueEstimate’s total_cost (from Item/Worksheet roll-up) with all applicable Rules applied in sequence (BR-070)Recomputed when Item costs change or Rules change
final_valueSubmission Valueoverride_value if set, else computed_valueRead-only; derived at query time
effective_margin_percentRule (Percentage only)(rule_value / running_total_before_rule) × 100Informational; shows actual %; rule value is the %-adjustment

9. Worked Examples

Example 1 — Sequence of three Rules stacking

Estimate total cost (from Item build-up): $100,000 (Direct)

Rules (in sequence order):

  1. Rule 1 — “Contingency 5%” (Percentage, scope: Direct-only)

    • Applies to: Direct costs ($100K)
    • Adjustment: +$5,000
    • Running total: $105,000
  2. Rule 2 — “Risk allowance $20K” (Lump Sum, scope: All)

    • Applies to: all Items
    • Adjustment: +$20,000
    • Running total: $125,000
  3. Rule 3 — “Margin 8%” (Percentage, scope: Direct-only)

    • Applies to: Direct costs (now $105K after Rule 1’s compounding)
    • Adjustment: +$8,400 (8% × $105K, not $100K)
    • Final total: $133,400

Submission Value computed: $133,400 per Schedule Item (or distributed proportionally if multiple Schedule Items were priced in parallel)

Note: Rules apply in order; each rule stacks on the running total after prior rules (BR-070, BR-074). Margin (Rule 3) applies to the compounded direct-cost state ($105K), not the original ($100K). The sequencing ensures Contingency is applied first, then Risk, then Margin on the updated base.


Example 2 — Submission Value with estimator override

Item: “Supply/install 150 m³ @ estimated $850/m³ = $127,500”

Commercials Rules applied: Margin 8% → Computed Submission Value = $137,700

Estimator’s market check: competitor quote shows $875/m³ for same work → $131,250 for 150 m³

Override action:

  • Estimator sets override_value = 131250
  • Estimator notes: “Market check Q2 2026; competitor quote dated 10 Apr”
  • final_value now reads 131250 (override takes precedence)
  • Audit trail preserved: updated_by, updated_at, audit_notes

Client sees: $131,250 on the schedule (not $137,700)


Example 3 — Publisher Output with branding & conditions

Estimate: Base offer for office fit-out, 5 Schedule Items

Publisher Output generation:

  • Captures all Schedule Item Submission Values (final) as of publish time
  • Cover letter: “Thank you for the opportunity. Below is our pricing for office fit-out works…”
  • Conditions: “This estimate is valid for 30 days. Prices exclude GST. All work is subcontracted to [Contractor names]…”
  • Inclusions: “Supply and install all finishes per specification. Site attendance during works. 24-hour rectification warranty.”
  • Exclusions: “Preliminary works. Sitewide safety/OHS. Power/water coordination with existing facilities.”
  • Branding: company logo (top), green accent colour, footer with contact details
  • Snapshot: JSON record of final Schedule structure (in case future Estimates edit Items)

Output: PDF or Excel file generated, ready to send to client. Only this version is retained (BR-075).