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 Optional
from .construction_day_rate_quote_types import DayRateQuote
from .finance_markup_price import markup_price ← from finance.markup-price ^1.0.0 · built alongside by fune
from .finance_tax_add_vat import add_vat ← from finance.tax.add-vat ^1.0.0 · built alongside by fune
from .math_round_div import round_div ← 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_amount import Money, money ← from money.amount ^1.0.0 · built alongside by fune
MAX_SAFE = 9007199254740991
def day_rate_quote(
labour_days_hundredths: int,
day_rate: Money,
materials_cost: Money,
materials_markup_basis_points: int,
vat_category: Optional[str],
on_date: str,
) -> DayRateQuote:
"""A quote from labour days, a day rate, marked-up materials and VAT.
The markup goes on the materials only: the day rate already is the price of
labour. Labour is rounded once, to the penny, from days x rate; VAT is one
rounding on the net total, as on the invoice that follows.
"""
if (
isinstance(labour_days_hundredths, bool)
or not isinstance(labour_days_hundredths, int)
or labour_days_hundredths < 0
):
raise ValueError(
"labourDaysHundredths must be a whole number of hundredths, not negative, received %r"
% (labour_days_hundredths,)
)
if day_rate.minor < 0:
raise ValueError("dayRate must not be negative, received %d" % (day_rate.minor,))
product = day_rate.minor * labour_days_hundredths
# Python would carry on, but TypeScript cannot, and all three must agree.
if product > MAX_SAFE:
raise ValueError("the labour calculation exceeds 2^53 - 1")
labour = money(round_div(product, 100, "half-up"), day_rate.currency)
materials = markup_price(materials_cost, materials_markup_basis_points, "markup", "half-up")
net = add_money(labour, materials)
if vat_category is None:
return DayRateQuote(labour=labour, materials=materials, net=net, vat=money(0, net.currency), gross=net, vat_basis_points=0)
vat = add_vat(net, "GB", vat_category, on_date)
return DayRateQuote(
labour=labour, materials=materials, net=net, vat=vat.tax, gross=vat.gross, vat_basis_points=vat.basis_points
)