from .math_round_div import round_div from .retail_volumetric_weight_types import ChargeableWeight def _whole(value: object) -> bool: return isinstance(value, int) and not isinstance(value, bool) def chargeable_weight( length_mm: int, width_mm: int, height_mm: int, actual_grams: int, divisor: int, round_up_to_grams: int, ) -> ChargeableWeight: """The weight a carrier charges on: the greater of actual and volumetric, rounded up to the carrier's billing step. mm³ / (cm³ per kg) is exactly grams, so everything stays in integers. """ for d in (length_mm, width_mm, height_mm): if not _whole(d) or d < 1: raise ValueError("dimensions must be 1 mm or more, received %r" % (d,)) if not _whole(actual_grams) or actual_grams < 0: raise ValueError("actualGrams must not be negative, received %r" % (actual_grams,)) if not _whole(divisor) or divisor < 1: raise ValueError("divisor must be 1 or more, received %r" % (divisor,)) if not _whole(round_up_to_grams) or round_up_to_grams < 1: raise ValueError("roundUpToGrams must be 1 or more, received %r" % (round_up_to_grams,)) volumetric_grams = round_div(length_mm * width_mm * height_mm, divisor, "up") heavier = max(actual_grams, volumetric_grams) return ChargeableWeight( actual_grams=actual_grams, volumetric_grams=volumetric_grams, chargeable_grams=round_div(heavier, round_up_to_grams, "up") * round_up_to_grams, basis="volumetric" if volumetric_grams > actual_grams else "actual", )