Approval rules
A rule says: when this is true, do that. Everything a customer calls an approval workflow is built from rows of that shape.
The three parts of a rule
| Part | Options |
|---|---|
| Condition | always, constantLimit, a role or permission check, availableBudget, personalLimit |
| Effect | pendingOrder (route for signature), prevent (refuse), sendEmail (notify) |
| Scope | One 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.
| Band | Condition | Approver |
|---|---|---|
| over €1,000 | constantLimit = 1000 | Cost-centre owner |
| over €10,000 | constantLimit = 10000 | Geschä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:
pendingOrderfor a soft limit — the overrun happens, somebody signs for it.preventfor a hard limit — the submit is refused.sendEmailfor 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:
- Restrict the cost centre so that the product, category or catalogue in question can only be booked to it — see Cost centres.
- 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.
Configure them
- Open the Approval Workflows app and create one rule per row of the table you wrote.
- Set the condition and its value.
- Set the effect.
pendingOrderfor anything that should still be possible;preventonly where an overrun is genuinely forbidden. - Set the scope — leave the cost centre empty for a company-wide rule.
- 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.
- 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
preventrule — 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
- Buyer spend limits — the per-person ceiling.
- The approver's path — what the rule produces.