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 .inventory_pallet_fit_data import PALLETS ← this capability’s own data, compiled from data/pallets.json into the same file by fune build
from .inventory_pallet_fit_types import Carton, PalletFit, PalletType
def _cartons_per_layer(length: int, width: int, a: int, b: int) -> int:
"""Cartons per layer on a ``length`` x ``width`` deck, base ``a`` x ``b``,
as the best two-block pattern: one split across the length or the width,
each block a grid with the carton one way round.
"""
best = 0
i = 0
while i * a <= length:
best = max(best, i * (width // b) + ((length - i * a) // b) * (width // a))
i += 1
j = 0
while j * b <= width:
best = max(best, j * (length // a) + ((width - j * b) // a) * (length // b))
j += 1
return best
def _positive(name: str, value: int) -> None:
if isinstance(value, bool) or not isinstance(value, int) or value <= 0:
raise ValueError("%s must be a whole number greater than zero, received %r" % (name, value))
def pallet_fit(
carton: Carton, pallet: PalletType, max_load_height_mm: int, max_load_weight_grams: Optional[int], upright: bool
) -> PalletFit:
"""The best stack of identical cartons on a UK or EUR pallet within the limits."""
_positive("lengthMm", carton.length_mm)
_positive("widthMm", carton.width_mm)
_positive("heightMm", carton.height_mm)
wg = carton.weight_grams
if isinstance(wg, bool) or not isinstance(wg, int) or wg < 0:
raise ValueError("weightGrams must be a whole number, not negative, received %r" % (wg,))
_positive("maxLoadHeightMm", max_load_height_mm)
mw = max_load_weight_grams
if mw is not None and (isinstance(mw, bool) or not isinstance(mw, int) or mw < 0):
raise ValueError("maxLoadWeightGrams must be a whole number, not negative, received %r" % (mw,))
deck = next((p for p in PALLETS if p.code == pallet), None)
if deck is None:
raise ValueError('unknown pallet "%s": expected uk or euro' % (pallet,))
l, w, h = carton.length_mm, carton.width_mm, carton.height_mm
choices = [(h, l, w)] if upright else [(h, l, w), (w, l, h), (l, w, h)]
best: Optional[PalletFit] = None
for vertical, a, b in choices:
per_layer = _cartons_per_layer(deck.length_mm, deck.width_mm, a, b)
layers = max_load_height_mm // vertical
per_pallet = per_layer * layers
limited_by = "footprint" if per_layer == 0 else "height"
if per_layer > 0 and mw is not None and wg > 0:
by_weight = mw // wg
if by_weight < per_pallet:
per_pallet = by_weight
limited_by = "weight"
fit = PalletFit(
pallet_length_mm=deck.length_mm,
pallet_width_mm=deck.width_mm,
carton_height_mm=vertical,
per_layer=per_layer,
layers=layers,
per_pallet=per_pallet,
limited_by=limited_by,
load_height_mm=0 if per_layer == 0 else -(-per_pallet // per_layer) * vertical,
load_weight_grams=per_pallet * wg,
)
if best is None or fit.per_pallet > best.per_pallet:
best = fit
assert best is not None
return best