Functional Weave
Code in Rust

retail.price-per-unit@1.0.0

README.md

3,093 bytes · view raw

# retail.price-per-unit

The unit price on a shelf-edge label: what one kilogram, one litre, one metre
or one item of the product costs, so shoppers can compare packs of different
sizes. `unitPrice(£1.50, "500", "g", "kg")` is £3.00.

## Which unit (UK)

The Price Marking Order 2004 (SI 2004/102) requires a unit price alongside
the selling price for most goods sold loose or in pre-set quantities, and
defines it as the final price, VAT included, per kilogram, litre, metre,
square metre or cubic metre, or per item for goods sold by number.

- **Until 5 April 2026**, Schedule 1 of the Order let listed products use
  other units: per 10 g or 10 ml (herbs, spices, make-up), per 100 g or 100 ml
  (biscuits, coffee, soft drinks, sauces and many more), per 75 cl for wine,
  per 50 kg for coal.
- **From 6 April 2026**, the Price Marking (Amendment) Order 2024 (SI
  2024/1055, commencement moved from 1 October 2025 by SI 2025/592) omits
  Schedule 1. The unit price is per item for goods sold by number, per
  kilogram for goods marked only by weight, per litre for goods marked only by
  volume, and otherwise per kilogram, litre, metre, square metre or cubic metre.
  The deposit (for example a deposit return scheme charge) is excluded.

This function does not decide which unit a product needs; that depends on the
product and on the date, and the caller's product data knows both. It takes
the unit as `per` and does the arithmetic exactly. `100g`, `10g`, `100mL`,
`10mL` and `75cL` stay available for labels printed under the old Schedule 1,
for shelf labels outside Great Britain, and for voluntary extra prices.

## Arithmetic

The pack quantity is converted to the unit of `per` with `units.convert`,
which is exact rational arithmetic, to 12 decimal places (so 8 oz is exactly
226.796185 g). The price is then divided by that quantity in exact integer
arithmetic and rounded once, half up, to the minor unit: 6 rolls for £1.00 is
16.67p, shown as 17p. There is no floating point anywhere, so £4.00 per pound
is 882p per kg in every language.

## Edge cases

- `unit` `"item"` goes with `per` `"item"` only, and the other way round.
- A quantity of zero, or one so small it converts to 0 at 12 decimal places,
  is an error; so is a negative price. A free item's unit price is 0.
- Mass and volume do not convert into each other: pricing 500 g per litre is
  an error from `units.convert`. Where the law lets a product be sold by
  weight or volume, pass whichever the pack is marked with.

## Sources

- The Price Marking Order 2004, SI 2004/102, article 1 (definition of "unit
  price") and Schedule 1, as made:
  https://www.legislation.gov.uk/uksi/2004/102/article/1/made and
  https://www.legislation.gov.uk/uksi/2004/102/schedule/1/made
- The Price Marking (Amendment) Order 2024, SI 2024/1055 (new definition of
  "unit price", Schedule 1 omitted):
  https://www.legislation.gov.uk/uksi/2024/1055/made
- The Price Marking (Amendment) Order 2025, SI 2025/592, article 2(2)
  (commencement moved to 6 April 2026):
  https://www.legislation.gov.uk/uksi/2025/592/body/made