Functional Weave
Code in Rust

hospitality.service-charge@1.0.0

impl/python.py

1,596 bytes · the Python implementation · view raw

Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.

from typing import Sequence

from .hospitality_service_charge_types import BillLine, ServiceCharge
from .math_round_div import RoundingMode  ← from math.round-div ^1.0.0 · built alongside by fune
from .money_add import add_money  ← from money.add ^1.0.0 · built alongside by fune
from .money_apply_rate import apply_rate  ← from money.apply-rate ^1.0.0 · built alongside by fune
from .money_sum import sum_money  ← from money.sum ^1.0.0 · built alongside by fune


def service_charge(lines: Sequence[BillLine], basis_points: int, mode: RoundingMode) -> ServiceCharge:
    """A discretionary service charge on the eligible lines of a bill.

    The rate is applied once, to the eligible total, and rounded once. Charging
    each line and adding the pennies up drifts: three 3.33 lines at 12.5% are
    0.42 each, 1.26 in all, where 12.5% of 9.99 is 1.25.
    """
    if len(lines) == 0:
        raise ValueError("a bill needs at least one line")
    if isinstance(basis_points, bool) or not isinstance(basis_points, int) or basis_points < 0 or basis_points > 10000:
        raise ValueError("basisPoints must be a whole number from 0 to 10000, received %s" % (basis_points,))
    currency = lines[0].amount.currency
    subtotal = sum_money([line.amount for line in lines], currency)
    eligible_total = sum_money([line.amount for line in lines if line.eligible], currency)
    if eligible_total.minor < 0:
        raise ValueError(
            "the eligible lines total %d, and a service charge cannot be negative" % (eligible_total.minor,)
        )
    charge = apply_rate(eligible_total, basis_points, mode)
    return ServiceCharge(
        eligible_total=eligible_total,
        basis_points=basis_points,
        charge=charge,
        subtotal=subtotal,
        total=add_money(subtotal, charge),
    )