fix(operations): last-mile assign until load fully trucked + 40ft cap

Assign was gated on any truck assigned, blocking multi-truck
deliveries. Gate on remaining containers (or bulk tonnage) instead, show
covered/total in the modal, cap a 40ft container to one truck with no
size mixing (mirrors assertTruckLoad), and lock arrived/departed rows.
This commit is contained in:
Hagernesh
2026-07-25 10:29:14 +00:00
parent d4695ba9eb
commit a544bebc51
10 changed files with 492 additions and 34 deletions

View File

@@ -37,6 +37,14 @@ function fmtDate(iso: string | null) {
return new Date(iso).toLocaleDateString();
}
const UNIT_LABEL_PLURAL: Record<string, string> = {
container: 'Containers',
truck: 'Trucks',
ton: 'Tons',
item: 'Items',
};
const unitLabelPlural = (unitLabel?: string) => UNIT_LABEL_PLURAL[unitLabel ?? 'container'] ?? 'Containers';
const money = (amount: number, currency: string) =>
`${Number(amount).toLocaleString()} ${currency === 'ETB' ? 'Birr (ETB)' : currency}`;
@@ -72,8 +80,11 @@ function FeeCard({ fee }: { fee: FeePreview }) {
<Row label="Period" value={`${fmtDate(fee.startDate)}${fmtDate(fee.endDate)}${fee.endIsOpen ? ' (today)' : ''}`} />
<Row label="Elapsed days" value={String(fee.elapsedDays)} />
<Row label="Chargeable days" value={`${fee.chargeableDays} (after ${fee.freeDays} free)`} />
<Row label="Containers" value={String(fee.containerCount ?? 1)} />
<Row label="Billable units" value={`${fee.billableUnits ?? fee.chargeableDays} container-day(s)`} />
<Row label={unitLabelPlural(fee.unitLabel)} value={String(fee.containerCount ?? 1)} />
<Row
label="Billable units"
value={`${fee.billableUnits ?? fee.chargeableDays} ${fee.unitLabel ?? 'container'}-day(s)`}
/>
{(fee.tiers ?? []).map((tier) => (
<Row
key={`${tier.appliedFromDay}-${tier.appliedToDay}-${tier.ratePerDay}`}