Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.
import re
from typing import List, Optional, Sequence
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, assert_same_currency, money ← from money.amount ^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_compare import compare_money ← from money.compare ^1.0.0 · built alongside by fune
from .logistics_freight_rate_types import FreightRate, FuelSurcharge, FreightQuote
_ISO_DATE = re.compile(r"^\d{4}-\d{2}-\d{2}$")
def _whole(value: object) -> bool:
return isinstance(value, int) and not isinstance(value, bool)
def _in_force(valid_from: str, valid_to: Optional[str], on_date: str) -> bool:
return on_date >= valid_from and (valid_to is None or on_date <= valid_to)
def _round_up_to(grams: int, step: int) -> int:
return round_div(grams, step, "up") * step
def _charge(rate: FreightRate, rated_grams: int) -> Money:
"""The break's charge at a weight: base plus the per-kilogram element, at least the minimum."""
variable = round_div(rated_grams * rate.per_kg_minor, 1000, "half-up")
freight = money(rate.base.minor + variable, rate.base.currency)
if rate.minimum is not None and compare_money(freight, rate.minimum) < 0:
return rate.minimum
return freight
def freight_rate(
rates: Sequence[FreightRate],
fuel_surcharges: Sequence[FuelSurcharge],
zone: str,
chargeable_grams: int,
ship_date: str,
) -> FreightQuote:
"""Freight for a consignment on a caller-supplied tariff: the zone's break
covering the weight on the ship date, or a heavier break when that is
cheaper, plus the fuel surcharge in force that day."""
if not _whole(chargeable_grams) or chargeable_grams < 1:
raise ValueError("chargeableGrams must be 1 or more, received %r" % (chargeable_grams,))
if not isinstance(ship_date, str) or not _ISO_DATE.fullmatch(ship_date):
raise ValueError('shipDate must be an ISO date (YYYY-MM-DD), received "%s"' % (ship_date,))
candidates: List[FreightRate] = [
r for r in rates if r.zone == zone and _in_force(r.valid_from, r.valid_to, ship_date)
]
for rate in candidates:
if not _whole(rate.step_grams) or rate.step_grams < 1:
raise ValueError("stepGrams must be 1 or more, received %r" % (rate.step_grams,))
if not _whole(rate.per_kg_minor) or rate.per_kg_minor < 0:
raise ValueError("perKgMinor must not be negative, received %r" % (rate.per_kg_minor,))
assert_same_currency(candidates[0].base, rate.base)
covering = [
r
for r in candidates
if chargeable_grams >= r.from_grams and (r.to_grams is None or chargeable_grams <= r.to_grams)
]
if not covering:
raise ValueError(
'no freight rate for zone "%s" on %s covers %d g' % (zone, ship_date, chargeable_grams)
)
if len(covering) > 1:
raise ValueError(
'two freight rates for zone "%s" on %s cover %d g' % (zone, ship_date, chargeable_grams)
)
best = covering[0]
best_grams = _round_up_to(chargeable_grams, best.step_grams)
best_freight = _charge(best, best_grams)
# Rates per kilogram fall as weight rises, so a heavier break charged at
# its first weight can undercut the break the consignment falls in.
for rate in candidates:
if rate.from_grams <= chargeable_grams:
continue
grams = _round_up_to(rate.from_grams, rate.step_grams)
freight = _charge(rate, grams)
order = compare_money(freight, best_freight)
if order < 0 or (order == 0 and grams < best_grams):
best, best_grams, best_freight = rate, grams, freight
basis_points = 0
if len(fuel_surcharges) > 0:
found: Optional[FuelSurcharge] = None
for row in fuel_surcharges:
if not _in_force(row.valid_from, row.valid_to, ship_date):
continue
if found is None or row.valid_from > found.valid_from:
found = row
# A table that stops short of the date has usually not been updated.
if found is None:
raise ValueError("no fuel surcharge in force on %s" % ship_date)
basis_points = found.basis_points
fuel_surcharge = apply_rate(best_freight, basis_points, "half-up")
return FreightQuote(
zone=zone,
rated_grams=best_grams,
break_from_grams=best.from_grams,
freight=best_freight,
fuel_surcharge_basis_points=basis_points,
fuel_surcharge=fuel_surcharge,
total=add_money(best_freight, fuel_surcharge),
)