mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 15:48:11 +00:00
changes
This commit is contained in:
@@ -581,66 +581,50 @@ export class RuleEngineService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Cargo securing / lashing — sold per cargo kind, like the customs clearance
|
||||
* fee. Container bookings bill each container line at its own container
|
||||
* type's lashing rate (PER_CONTAINER × boxes, or PER_WAGON × the wagons the
|
||||
* line occupies); bulk bookings bill the type-less rate (PER_TON × tonnage,
|
||||
* or PER_WAGON × the wagons the bulk occupies). An unconfigured rate simply
|
||||
* bills nothing — same leniency as hazard/reefer.
|
||||
* Cargo securing / lashing — BULK only, sold per trade direction, optionally
|
||||
* narrowed to one leaf commodity (the commodity-scoped rate wins over the
|
||||
* commodity-wide catch-all). Bills PER_TON × tonnage or PER_WAGON × the
|
||||
* wagons the bulk occupies. Container bookings never incur lashing, and an
|
||||
* unconfigured rate simply bills nothing — same leniency as hazard/reefer.
|
||||
*/
|
||||
private lashingCharges(
|
||||
input: BookingEvaluationInput,
|
||||
liveRates: Rate[],
|
||||
): AppliedCargoModifier[] {
|
||||
const modifiers: AppliedCargoModifier[] = [];
|
||||
const lashingRates = liveRates.filter(
|
||||
(r) => r.trigger === 'LASHING' && r.currency === 'USD',
|
||||
if (input.containers.length > 0) return modifiers; // bulk-only service
|
||||
|
||||
const onDirection = liveRates.filter(
|
||||
(r) =>
|
||||
r.trigger === 'LASHING' &&
|
||||
r.currency === 'USD' &&
|
||||
!r.containerTypeId &&
|
||||
r.tradeDirection === input.tradeDirection,
|
||||
);
|
||||
if (lashingRates.length === 0) return modifiers;
|
||||
|
||||
const push = (rate: Rate, billedQty: number): void => {
|
||||
const rateValue = Number(rate.rateValue);
|
||||
const amount =
|
||||
rate.rateUnit === 'FLAT' ? rateValue : billedQty * rateValue;
|
||||
if (!(amount > 0)) return;
|
||||
modifiers.push({
|
||||
rateId: rate.id,
|
||||
surchargeCode: this.surchargeCode(rate),
|
||||
triggerValue: rate.rateUnit === 'FLAT' ? 1 : billedQty,
|
||||
calculatedAmount: amount,
|
||||
currency: rate.currency,
|
||||
unitPriceUsd: rateValue,
|
||||
billingUnit: rate.rateUnit,
|
||||
});
|
||||
};
|
||||
|
||||
if (input.containers.length > 0) {
|
||||
for (const container of input.containers) {
|
||||
const qty = Number(container.quantity || 0);
|
||||
if (!(qty > 0)) continue;
|
||||
const rate = lashingRates.find(
|
||||
(r) => r.containerTypeId === container.containerTypeId,
|
||||
);
|
||||
if (!rate) continue;
|
||||
const billedQty =
|
||||
rate.rateUnit === 'PER_WAGON'
|
||||
? Math.ceil(qty * (container.wagonsPerUnit ?? 1))
|
||||
: qty;
|
||||
push(rate, billedQty);
|
||||
}
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
// Bulk — the type-less rate covers the whole booking.
|
||||
const rate = lashingRates.find((r) => !r.containerTypeId);
|
||||
const rate =
|
||||
(input.cargoTypeId
|
||||
? onDirection.find((r) => r.cargoTypeId === input.cargoTypeId)
|
||||
: undefined) ?? onDirection.find((r) => !r.cargoTypeId);
|
||||
if (!rate) return modifiers;
|
||||
|
||||
const billedQty =
|
||||
rate.rateUnit === 'PER_TON'
|
||||
? Math.max(0, Number(input.bulkTons ?? 0))
|
||||
: rate.rateUnit === 'PER_WAGON'
|
||||
? Math.max(0, Number(input.bulkWagons ?? 0))
|
||||
: 1;
|
||||
push(rate, billedQty);
|
||||
const rateValue = Number(rate.rateValue);
|
||||
const amount = rate.rateUnit === 'FLAT' ? rateValue : billedQty * rateValue;
|
||||
if (!(amount > 0)) return modifiers;
|
||||
modifiers.push({
|
||||
rateId: rate.id,
|
||||
surchargeCode: this.surchargeCode(rate),
|
||||
triggerValue: rate.rateUnit === 'FLAT' ? 1 : billedQty,
|
||||
calculatedAmount: amount,
|
||||
currency: rate.currency,
|
||||
unitPriceUsd: rateValue,
|
||||
billingUnit: rate.rateUnit,
|
||||
});
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user