Functional Weave
Code in TypeScript

finance.markup-price@1.0.0

impl/python.py

1,599 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 .finance_markup_price_types import PricingBasis
from .math_round_div import RoundingMode, round_div  ← from math.round-div ^1.0.0 · built alongside by fune
from .money_amount import Money, money  ← from money.amount ^1.0.0 · built alongside by fune

MAX_SAFE = 9007199254740991


def markup_price(cost: Money, basis_points: int, basis: PricingBasis, mode: RoundingMode) -> Money:
    """The selling price that hits a target margin or markup on ``cost``.

    Margin divides by the price and markup by the cost, so the same 5000 basis
    points means 200.00 or 150.00 on a cost of 100.00; the basis is explicit.
    """
    if isinstance(basis_points, bool) or not isinstance(basis_points, int):
        raise TypeError("basis_points must be an integer, received %r" % (basis_points,))
    if cost.minor < 0:
        raise ValueError("cost must not be negative, received %d" % (cost.minor,))

    if basis == "markup":
        if basis_points < -10000:
            raise ValueError("a markup of %d basis points gives a negative price" % (basis_points,))
        numerator = cost.minor * (10000 + basis_points)
        denominator = 10000
    elif basis == "margin":
        if basis_points >= 10000:
            raise ValueError("a margin of %d basis points has no finite price" % (basis_points,))
        numerator = cost.minor * 10000
        denominator = 10000 - basis_points
    else:
        raise ValueError('unknown pricing basis "%s"' % (basis,))

    # Python would carry on, but TypeScript cannot, and all three must agree.
    if numerator > MAX_SAFE:
        raise ValueError("the price calculation exceeds 2^53 - 1")
    return money(round_div(numerator, denominator, mode), cost.currency)