iVendNextDevelopers Request a sandbox

A price list worked out from another, kept in step — the recipe

A shop wants one price list to follow another: the selling list is one and a half times the buying list, or the wholesale list is nine tenths of the retail list, and when the source price changes the derived price changes by itself. iVendNext's price list has no formula, and a selling pricing rule is the wrong tool (it is a promotion, chapter 4). This recipe builds it as an outside app on the event feed that writes the derived list's item prices. It is for an iVendNext developer who has made an outside app before (chapter 5).

Reference implementation: samples/s26_derived_prices/ — Derived price lists.

When to use it. A list that is a fixed multiple of another, plus an optional amount, rounded the way the shop prices. Not for a price that depends on the customer, the quantity or the day: those are promotions and pricing rules.

Steps

  1. Keep the formula in the shop. Your manifest's own record type holds one rule per derived list (below). The shop edits it in Desk; your service reads every rule at each pass.
  2. Follow Item Price on the feed (recipe). The shop's feed registration follows Item Price. One saved price writes several events (item_price.after_insert, .on_update, .on_change): read the row again for each, which is cheap, and write only when the target is wrong.
  3. Work the price out in decimal arithmetic. rate = round(source × factor + offset) to the rule's step (0.01, 0.05, 0.5 or 1) in its direction (nearest, half up; up; down), then never below the floor, at the rule's decimal places (the shop's currency precision: the shop sizes every price from that system-wide setting, which your service's user may not read, so the rule carries it). Never in binary floating point: 66.67 × 1.5 is 100.005, which is 100.01, and a float rounds it to 100.00.
  4. Stamp what you write. The target row your service makes carries PP-DPL ⟨rule⟩ ⟨source row⟩ in its note. Find the row by that stamp before every write: a replayed event updates the same row, and an unchanged price is not written at all.
  5. Never overwrite a person's price. A row on the target list that is still selling and lacks your rule's stamp is a person's price (or another rule's), and so is a stamped row that someone other than your service changed last (its modified by). Leave both as they are and list them. Find your own row by its stamp alone, so that when someone corrects the source's item or unit your row moves with it.
  6. Carry a change down a chain yourself. Your own writes make no event for you (the feed's contract), so after writing list B, apply the rules whose source is B. Refuse a rule that would close a loop, and two rules writing one list.
  7. A deleted source price ends its rows; it never deletes them. A source price made for one customer, supplier or batch is no longer a source either. The feed sends item_price.deleted (read on a sandbox, 2026-10-16). Give each row made from that source an end date of yesterday (valid upto), moving its valid from back when it is later, and carry the end date down the chain.
  8. Work every price out again when a rule is new, changed, or back from being switched off. Keep a fingerprint of each rule's numbers, and forget it while the rule is off; when it changes, page through the source list, saving the page cursor after each page, so a crash resumes where it stopped.
  9. Reconcile every night, read-only. Every target price against its source: a missing price, a wrong price, a row whose source is gone and still sells, and every person's price listed apart. It never changes anything: a difference in price is a person's decision.

The rule

One record per derived list, of your own type ⟨PREFIX⟩ Rule, named by a short name (it is written in each price's note): enabled · the source price list · the target price list · the factor · an amount added after it (may be below 0) · round to (0.01, 0.05, 0.5, 1) · rounding (nearest, up, down) · never below · decimal places (the shop's currency precision, 2 by default). The service refuses, and reports, a rule whose lists are in two currencies, whose step or floor is finer than its decimal places, or whose target another rule writes.

What the shop needs from you

Bounds — tell the customer

Tell the customer

Before you build, agree in writing: the formula (factor and amount), the rounding step and direction, the floor, and who may overwrite a derived price by hand (a person's price is kept until they remove it).

Technical notes

Needs this serves

This page in the kit