Sales Partner, Territory & Commission Structure
How a sale is attributed to the people and territory that produced it, and how commission is computed and reported — not paid
1. Requirements
1.1 Functional requirements
- Maintain three independent hierarchical or flat master records that a sale can be attributed to: a Territory (geographic/market hierarchy), a Sales Person (an internal individual, optionally linked to one employee record, organized in its own hierarchy), and a Sales Partner (an external referring organization, with its own public-facing profile page and a flat commission rate).
- Let a Customer carry defaults — a template sales team, a default territory, a default referring Sales Partner, and a default commission rate — that are copied onto every new Quotation or Sales Order raised for that customer, without the customer record itself being re-referenced afterward.
- Let a Sales Team — one or more Sales Person rows, each with an allocated percentage of the sale and its own commission rate — be attached directly to a Quotation, Sales Order, or Sales Invoice, and require the allocated percentages across the team to sum to exactly 100% whenever a team is present at all.
- Compute, on every document carrying a commission rate, the portion of its value eligible for commission (excluding any line explicitly flagged out) and the resulting total commission at the document’s own commission rate.
- Compute, per Sales Person on the sales team, an allocated amount (their percentage share of the commission-eligible value) and, independently, an incentive figure from that person’s own row-level commission rate — a second rate distinct from the document-level one tied to a referring Sales Partner.
- Let a Territory, Sales Person, or Sales Partner carry one or more sales targets — a quantity or amount goal per item group per fiscal year, spread across the year by a configurable monthly distribution — purely for after-the-fact variance reporting.
- Report commission and target-attainment figures by document, by Sales Partner, and by Sales Person, and report actual sales against target by Territory, Sales Person, and Sales Partner.
1.2 Non-functional requirements
- Attribution without re-entry: a customer’s usual sales team, territory, and referring partner should not need to be picked again on every new document.
- Reporting reads stored figures, never recomputes them: every commission and target-variance report queries fields already computed and saved at document-submission time.
- Disabled-person safety: a Sales Person marked disabled cannot be newly added to a sales team, though rows already saved against one are not retroactively altered.
1.3 Constraints
- Nothing in this structure pays a commission. Everything described here computes and reports an eligible amount, an allocation, and an incentive figure as document fields — turning any of that into an actual payment or accounting settlement to a Sales Partner or Sales Person is not implemented anywhere in this scope.
- Target-vs-actual reporting is read-only analysis; no target here blocks, warns on, or otherwise gates anything at transaction time.
- A single settings switch controls whether the commission and sales-team sections are even shown on the relevant document forms — it does not gate whether the underlying computation runs.
2. High-Level Design
2.1 Component diagram
2.2 Attribution and computation flow
- A customer’s defaults are copied, not referenced. Selecting a customer on a new Quotation or Sales Order copies that customer’s own sales team rows, default territory, default referring Sales Partner, and default commission rate onto the new document’s own fields — editable independently from then on. A Quotation additionally carries its own referring-partner field, which, if set, overrides the commission rate on the Sales Order created from it.
- Commission is computed at save time, on any document whose schema carries a
commission_ratefield: the eligible amount is the sum of every line’s net amount, excluding any line explicitly flagged out of eligibility, and the total commission is that eligible amount at the document’s own rate. - Contribution is computed alongside it, on any document carrying a sales team: each row’s allocated amount is its percentage share of the same eligible amount, and its incentive figure — if the row carries its own commission rate — is that allocated amount at that row’s rate, a second rate independent of the document-level one tied to a referring partner.
- Reporting reads what was already computed. Commission-summary reports query the document’s stored
total_commission(or, per-person, the team row’s storedallocated_amount/incentives) directly — no report recomputes commission from line items. - Target-variance reporting is a separate, read-only join. A Territory, Sales Person, or Sales Partner’s Target Detail rows (a quantity or amount goal per item group per fiscal year, spread across the year by a configured monthly distribution) are compared against actual submitted document totals for the same period — weighted by allocated percentage when scoped to Sales Person — to produce a target/achieved/variance figure per period, with no feedback into the transactional documents themselves.
3. Deep Dive
3.1 Data model
Territory — a nested hierarchy (parent/child), carrying an optional territory-manager reference and its own Target Detail rows. Copied onto a document as a plain default from the customer, or set directly.
Sales Person — a nested hierarchy of individuals, each optionally linked to exactly one employee record (enforced one-to-one) and carrying an enabled/disabled flag and its own Target Detail rows. A disabled Sales Person cannot be newly assigned to a sales team, but existing rows referencing one already saved are left untouched. A Sales Person already linked from a Customer’s default sales team cannot itself be deleted.
Sales Partner — a flat, website-facing record (it generates its own public profile page) representing an external referring organization: a territory, a flat commission rate, a partner-type classification (Sales Partner Type — a bare label with no behavior of its own), and its own Target Detail rows.
Sales Team row — a child row, not an independent record, attached to a Customer (as a template), a Quotation, a Sales Order, or a Sales Invoice: a Sales Person reference, an allocated percentage, an own commission rate, and two figures computed at save time — allocated amount and incentives.
Target Detail row — a child row attached to a Territory, Sales Person, or Sales Partner: an item group, a fiscal year, a target quantity or amount, and a monthly-distribution profile used only to spread that target across the periods a variance report breaks it into. It has no relationship to any transactional document until a report joins it against one.
3.2 Commission and contribution arithmetic
amount_eligible_for_commission = sum(line.base_net_amount for line in items if line.grant_commission)
total_commission = amount_eligible_for_commission x commission_rate / 100
# per Sales Team row:
allocated_amount = amount_eligible_for_commission x row.allocated_percentage / 100
incentives = allocated_amount x row.commission_rate / 100 (only if the row carries its own rate)
# validation at save time:
sum(row.allocated_percentage for row in sales_team) == 100 # only enforced if a sales team is present at all
The grant_commission line flag is the only lever that excludes specific lines from the eligible-amount sum; there is no equivalent exclusion at the sales-team or partner level — every enabled Sales Person on the team shares the same eligible amount, differing only by their own allocated percentage and rate.
3.3 Error handling
- Sales team percentages not summing to 100%: rejected at save time, whenever any sales team rows are present.
- A disabled Sales Person on the team: rejected at save time, naming the person.
- A Sales Person already linked to a customer’s sales team, or already an employee’s linked record: cannot be deleted, or duplicated onto a second Sales Person, respectively.
- Commission rate out of range: a commission rate outside 0–100 is rejected before the eligible-amount calculation runs.
4. Scale and Reliability
- Computation is synchronous and per-document: commission and contribution are recomputed in full on every save, touching only that document’s own lines and team rows, never a cross-document aggregate.
- Reporting cost scales with transaction volume, not master-data hierarchy size: the commission and target-variance reports query submitted transactional documents directly, not the Territory/Sales-Person tree structure.
- No enforcement path to slow down: targets are report-only and the visibility toggle only hides form sections, so there is no validation cost beyond the percentage and range checks in §3.3.
5. Trade-off Analysis
| Decision | Trade-off |
|---|---|
| Customer defaults are copied onto a new document rather than referenced live | A later change to the customer’s default sales team/partner/rate never retroactively affects documents already created — predictable, but means a customer-level correction must be reapplied document by document. |
| Two independent commission rates (document-level, tied to a referring partner; row-level, tied to a sales person) | Lets an external referral and internal incentive structure coexist without collapsing into one number — at the cost of two similarly-named rates on the same document that mean different things. |
| Commission/contribution computed and stored on the document itself, with reports reading those stored fields | Reports stay simple and fast, and always agree with what the document itself shows — at the cost of a report being unable to answer “what would commission have been under a different rate” without recomputation outside this scope. |
| Targets are pure reporting, with no enforcement tie to actual transactions | Territory/Sales-Person/Sales-Partner quotas never block or warn at transaction time — useful for after-the-fact review, useless as a real-time guardrail. |
| A single settings switch hides the commission UI without disabling the computation | A form can look like commission tracking is off while the fields are still being computed and saved underneath it — a source of confusion if the toggle is read as a functional switch rather than a display one. |
| No commission-payment mechanism in this scope | Keeps this structure purely computational and reportable, at the cost of leaving “how a Sales Partner or Sales Person is actually paid their commission” entirely outside the system as documented here. |
6. What to Revisit as the System Grows
- A real payment/settlement step for computed commission, if paying Sales Partners or Sales Persons is meant to happen inside this system rather than through a separate process entirely — nothing here creates that link today.
- Tie the visibility toggle to the computation itself, or document clearly that it is display-only, so a team that disables the commission section does not assume the underlying fields have stopped being populated.
- A line-level exclusion analogous to
grant_commissionat the sales-team level, if a future need arises to exclude one team member from a specific document’s commission split rather than only excluding specific line items from the eligible pool. - Connect target-variance results back to a transactional guardrail (a soft warning at quotation or order time when a territory or person is tracking far behind target), if this reporting-only mechanism is ever expected to influence behavior in the moment rather than only after the fact.