Configure a calculation rule
Build a rule from scratch, preview it, activate it, and confirm what it recalculated.
Goal: add a rule that books a cost or a revenue against the right account, for the right transactions, over the right period.
Prerequisites: read calculation rules first, especially how filters combine and the sign convention. Preview the arithmetic with the signed source values.
Activating a rule changes stored figures. It queues recalculation across its window, so a wide window on a busy type is real work. Decide the window before you activate, not after.
Steps
1. Start from an existing rule. There is no clone button, but an existing rule is the best specification of what a working one looks like. See learn from existing rules.
2. Create it inactive. Add from /contributionmargin/calculationrules. A new rule is created with activated = 0 and with the activation window from calculationrules.startdate and calculationrules.enddate in config/settings.json, so it does nothing until you say so. Name it for what it does and the period it covers: the seeded rules end their name with the period label for exactly this reason.
3. Pick the transaction type. In Basic settings. It decides which fields you can filter on and which transaction the impact attaches to. A payment fee belongs on the prepayment; its refund belongs on the credit memo.
Saving Basic settings, including a name-only edit, deletes the rule's stored impacts and deactivates it. Record its old type, account and window first so you can refresh affected orders.
4. Add filters. Three sections, edited separately: Filters header, Filters lines and Filters lines non inventory. Conditions inside a group are AND; groups are OR. Four operators only: ==, !=, >, <. Leave a filter set empty to match everything of that type.
Remember that header filters gate the whole transaction while line filters gate only line impacts. A header charge on a transaction where every line failed is correct.
5. Define the impact. In the Impact section: fixed or percentage; header, line or non-inventory line. A percentage is field_value * percentage / 100. A rule may carry several impact entries, and they add up: the seeded UK import duty rule is -3.5% of each line's ex-VAT amount plus a fixed 1.25 on the header.
Check the sign with actual inputs. A fixed cost keeps the entered sign. The refund seed uses a negative percentage on a negative credit-memo header to produce a positive cost. See the worked sign example.
6. Preview. The Preview box on the detail view takes comma-separated transaction ids and shows what the rule would book for each. It ignores the activated status and does enforce the date filtering, so an inactive rule can be tested and a transaction outside the window correctly returns nothing. It stores nothing.
Use representative ids, including one that should not match. Preview proves only the transactions you chose.
7. Activate over the window. Activation settings, then Edit. This is the step that queues recalculation: one calculate batch per day in the window, capped at today. The screen reports how many days it tried to queue and how many it actually queued; fewer queued means those days were already in the queue.
8. Verify. Watch the batches drain at /system/batches, then read the rule's detail view again: Impact rows counts what the rule has booked, per impact table. Pick one transaction inside the window and one outside, and confirm which moved.
Expected result
A rule that books the intended amount, on the intended transactions, over the intended period, with the old and new affected ranges checked. Editing an existing rule can remove impacts outside its new window; use recalculate margin to repair those per-order totals. Refresh expected totals separately when required.
Troubleshooting
| Symptom | Likely cause |
|---|---|
| Nothing matches | A condition in the same group excludes it; groups are OR, conditions are AND |
| Matches everything | An empty filter set matches all of that type |
| Amount has the wrong sign | Compare the signed base × rate, or fixed amount, with the screen's display convention |
| Charged twice | Another active rule overlaps. Rules are additive, with no priority |
| Figures did not move | A filter or impact edit does not re-queue the way activation does |
Related
Evidence
Behaviour as cited in calculation rules. Section names and the preview's own description read off the running application at /contributionmargin/calculationrules/detail/<id> and templates/main/contributionmargin/calculationrules_detail.tpl. New-rule defaults from app/http/contributionmargin/calculationrules.php and config/settings.json. The worked impact example is the seeded importduty_gb rule in config/seed/cm_calculationrules/rules.json. Basis: code-checked against the current implementation, exercised against the local application.
- Type
guide - Status
active - Updated
2026-09-14 - Created
2026-09-13