This commit is contained in:
Marshal
2026-07-17 13:57:59 +00:00
parent 3a697e12f2
commit 6467173c76
12 changed files with 642 additions and 46 deletions

View File

@@ -475,7 +475,14 @@ export class BookingPricingService {
const wagonCount = await this.resolveWagonCount(booking);
for (const container of evalInput.containers) {
const rate = this.pickRate(liveRates, rateType, container.containerTypeId, 'USD');
const rate = this.pickRate(
liveRates,
rateType,
container.containerTypeId,
'USD',
booking.originYardId,
booking.destinationYardId,
);
if (!rate) continue;
usedRatesMap.set(rate.id, rate);
@@ -515,8 +522,15 @@ export class BookingPricingService {
}
if (lines.length === 0) {
// Bulk (and any booking with no container lines) still has to price off a
// rate configured for this leg — never one belonging to another route.
const fallback = liveRates.find(
(r) => r.rateType === rateType && r.currency === 'USD' && r.status === 'LIVE',
(r) =>
r.rateType === rateType &&
r.currency === 'USD' &&
r.status === 'LIVE' &&
r.originYardId === booking.originYardId &&
r.destinationYardId === booking.destinationYardId,
);
if (fallback) {
usedRatesMap.set(fallback.id, fallback);
@@ -711,20 +725,32 @@ export class BookingPricingService {
}
}
/**
* Base freight is quoted per leg, so a rate only applies to a booking running
* the exact origin → destination it was configured for. There is deliberately
* no route-agnostic fallback: charging a Dire Dawa price for a Mojo shipment
* because nobody configured Mojo yet is worse than surfacing no line at all.
* Within the leg, a rate scoped to the container type wins over one that
* covers every type.
*/
private pickRate(
rates: Rate[],
rateType: string,
containerTypeId: string,
currency: string,
originYardId: string,
destinationYardId: string,
): Rate | undefined {
const onLeg = rates.filter(
(r) =>
r.rateType === rateType &&
r.currency === currency &&
r.originYardId === originYardId &&
r.destinationYardId === destinationYardId,
);
return (
rates.find(
(r) =>
r.rateType === rateType &&
r.currency === currency &&
r.containerTypeId === containerTypeId,
) ??
rates.find((r) => r.rateType === rateType && r.currency === currency && !r.containerTypeId)
onLeg.find((r) => r.containerTypeId === containerTypeId) ??
onLeg.find((r) => !r.containerTypeId)
);
}