Functional Weave
Code in Rust

retail.basket-total@1.0.0

README.md

2,477 bytes · view raw

# retail.basket-total

The checkout total, from shelf prices to the amount charged, with the VAT
split an invoice or receipt needs. It invents no arithmetic: promotions are
`retail.promotion-apply`, discount sharing is `money.allocate`, VAT is
`finance.tax.remove-vat` or `finance.tax.add-vat`, and each is pinned by its
own vectors. What this function decides is the order.

## Order of operations

1. **Promotions** on the lines, best for the customer, each deal's saving
   allocated back to the lines in it.
2. **Basket discount** (a coupon, a staff discount) shared across every line
   in proportion to what the line costs after promotions, with
   `money.allocate`, so the shares add up to the discount exactly. It may not
   exceed the basket after promotions.
3. **VAT per line**, on what the line costs after both discounts, at the rate
   for its category on `onDate`. Consumer prices include VAT
   (`pricesIncludeVat` true), so VAT is extracted with `remove-vat`; trade
   prices exclude it, so it is added with `add-vat`. Either way VAT is on the
   discounted price, which is what HMRC requires for a discount given at the
   time of sale (Notice 700/7): taxing the shelf price and then taking the coupon off
   overcharges VAT.
4. **Delivery** is taxed the same way, at `deliveryTaxCategory`. In the UK,
   delivery charged by the seller of goods follows the VAT liability of the
   goods, and a basket of mixed-rate goods has to apportion it; that
   apportionment is the caller's decision (pass the category that applies, or
   split delivery across calls).
5. **Totals** are sums of the per-line figures, so the receipt lines always add
   up to the total, and the VAT summary groups them by rate, delivery included
   when it is not zero.

`total = subtotal - promotionDiscount - basketDiscount + delivery` for
VAT-inclusive prices, and `total = net + tax` always.

## Sources

- VAT on discounts: HMRC, "Business promotions (VAT Notice 700/7)", section
  7.3 (on redeeming money-off coupons, VAT is accounted for "on the amount due
  from the customer"):
  https://www.gov.uk/guidance/business-promotions-and-vat-notice-7007
- Delivery: HMRC, "Postage, delivery and direct marketing (VAT Notice
  700/24)" (delivery charged by the seller follows the goods; mixed-rate
  apportionment must be fair and justifiable, with no set method):
  https://www.gov.uk/guidance/vat-on-postage-delivery-and-direct-marketing-notice-70024
- Rates: `finance.tax.vat-rate`.