Configure a calculation rule

TL;DR

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

SymptomLikely cause
Nothing matchesA condition in the same group excludes it; groups are OR, conditions are AND
Matches everythingAn empty filter set matches all of that type
Amount has the wrong signCompare the signed base × rate, or fixed amount, with the screen's display convention
Charged twiceAnother active rule overlaps. Rules are additive, with no priority
Figures did not moveA filter or impact edit does not re-queue the way activation does

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.

About this document
  • Type
    guide
  • Status
    active
  • Updated
    2026-09-14
  • Created
    2026-09-13