Design cost centres, budgets and rules

Approval rules

Who approves what, above which value, in which order.

A rule says: when this is true, do that. Everything a customer calls an approval workflow is built from rows of that shape.

Before you begin. Pick the model first — read Approval models and write the customer's policy down as a table of value bands before you open a screen. Rules built one at a time, reactively, produce a matrix nobody can reason about within six months.

The three parts of a rule

PartOptions
Conditionalways, constantLimit, a role or permission check, availableBudget, personalLimit
EffectpendingOrder (route for signature), prevent (refuse), sendEmail (notify)
ScopeOne cost centre, or none — which makes the rule global

Scope is the part that decides how a policy is expressed, so be deliberate about it:

  • Global rules (no cost centre) apply to every submit. "Everything over €1,000 needs a signature" is one global rule and needs no cost-centre modelling at all.
  • Cost-centre rules apply only to lines booked against that centre. "The maintenance budget is hard-capped, the workshop's is not" is two rules on two cost centres.

Value bands

The standard shape. One rule per band, each with a constantLimit condition and pendingOrder as the effect, each naming its approver.

BandConditionApprover
over €1,000constantLimit = 1000Cost-centre owner
over €10,000constantLimit = 10000Geschäftsführung

A €12,000 cart matches both rules, so both signatures are collected — that is how a chain is built. There is no separate chain object; the chain is what several matching rules produce.

Two things to get right:

  • Bands overlap on purpose. Do not write the second rule as "between €1,000 and €10,000". A €12,000 order needs the site manager's view too.
  • The top band has no ceiling on its approver. If every approver has a personal limit and none of them covers the largest possible order, requests above it have nowhere to go.

Budget conditions

availableBudget fires when the line would exceed what is left on the cost centre it is booked to. Pair it with:

  • pendingOrder for a soft limit — the overrun happens, somebody signs for it.
  • prevent for a hard limit — the submit is refused.
  • sendEmail for notify only — the order goes through and the owner is told.

personalLimit fires when the value exceeds the individual buyer's own ceiling. See Buyer spend limits for how that interacts with everything above.

Both of these are answered by the Cost Centers app, which is why they behave correctly against held-but-not-yet-confirmed money: a request awaiting signature has already reduced the available budget.

Product-group and category rules

There is no product condition on a rule, and adding one would be the wrong shape. Express it through the cost centre instead:

  1. Restrict the cost centre so that the product, category or catalogue in question can only be booked to it — see Cost centres.
  2. Scope the approval rule to that cost centre.

So "every purchase of Arbeitsschutz needs the safety officer's approval" becomes: a category restriction pointing safety equipment at KST-9200, plus a rule on KST-9200 with an always condition and the safety officer as approver.

This is more setup than a product field would be, and it is worth it. The allocation and the authority stay one decision instead of two that can disagree.

Parallel steps

Two approvers who both must decide, neither waiting for the other, are two rules matching the same submit with different approvers. Both open at once; the request converts to an order when both are settled; either rejection ends it.

Use it where the two people answer different questions — the cost-centre owner on need, the controller on the budget line. Where one of them never rejects anything, use sendEmail and keep them off the critical path.

Deputies and escalation

Neither lives on the rule.

Deputies are on the cost centre. A deputy may decide anything the owner may, under their own name. Set at least one on every cost centre before you go live — not after the first holiday.

Escalation is time-based, so it is configured as a waiting period rather than a condition: how long a decision may sit before a reminder goes out, and how long before the open decision moves to the next band's approver. Three working days for the reminder and five for the move is a workable starting point for a Mittelstand customer; shorten it for anything with a machine standing still behind it.

Escalation is a backstop, not a holiday plan. Set it up and skip the deputies and you have given the managing director every consumables approval in August. Deputies first.

Configure them

  1. Open the Approval Workflows app and create one rule per row of the table you wrote.
  2. Set the condition and its value.
  3. Set the effect. pendingOrder for anything that should still be possible; prevent only where an overrun is genuinely forbidden.
  4. Set the scope — leave the cost centre empty for a company-wide rule.
  5. Name the approver. For cost-centre-scoped rules this is usually the cost centre's owner rather than a named person, so the rule survives a reorganisation.
  6. Set the escalation waiting period.

What to check

Test three carts as a buyer at that customer, not as yourself:

  • Under every threshold — the order is created directly and the budget is consumed in one movement. No request appears.
  • Over one threshold — a purchase request appears, the approver is notified, and the budget shows the amount as held.
  • Over a prevent rule — the submit is refused with a reason the buyer can act on, and nothing is created.

If a cart that should have been refused produced an order, the rule's scope is wrong: check whether you scoped it to a cost centre the test line was not booked to.

Next