Functional Weave
Code in Rust

hospitality.service-charge@1.0.0

README.md

1,771 bytes · view raw

# hospitality.service-charge

Works out a discretionary service charge on the lines of a bill that it applies
to: 12.5% of the food, say, and not the drinks bought at the bar. It returns the
eligible total, the charge, the bill before the charge and the bill with it.

## Why it is shaped this way

- **One rounding step.** The rate is applied once, to the eligible total, and
  rounded once, in the mode the caller chooses. Charging each line and adding
  the pennies drifts: three 3.33 lines at 12.5% are 0.42 each (1.26), but
  12.5% of 9.99 is 1.25.
- **Lines say whether they are eligible.** Venues leave out different things
  (bar drinks, a corkage fee, a cake brought in), so the function does not
  guess. A discount line (negative amount) that is eligible lowers the base.
- **The rate is a basis-point integer**: 1250 is 12.5%, anything from 0 to
  10000.

## Edge cases

- No eligible lines, or a 0 rate, means a charge of 0.
- An eligible total below zero (a refund bill) is an error, not a negative
  charge.
- Every line must be in the same currency.

## Not covered

- **VAT.** HMRC treats a genuinely optional service charge as outside the
  scope of VAT, and a compulsory one as part of the price of the meal, taxed at
  the meal's rate (VAT Notice 709/1, *Catering and takeaway food*, section on
  tips and service charges: https://www.gov.uk/guidance/catering-and-take-away-food-vat-notice-7091).
  This function works out the amount only. Whether the charge is really
  optional is a fact about how the venue sells, not something it can see.
- **Who gets the money.** Under the Employment (Allocation of Tips) Act 2023,
  service charges an employer controls must be passed to workers in full and
  shared fairly; see `hospitality.tronc-allocation`.