feat: enhance cargo details handling and add document clearance features

- Improved handling of commodity selection in the cargo details form to prevent unwanted resets on re-renders.
- Added `isReefer` flag to the CreateBookingDto interface for booking-level refrigerated status.
- Introduced a new configuration file for clearance tabs to manage document clearance views.
- Implemented DocumentClearanceDetailPage for detailed review and management of clearance documents.
- Created DocumentClearanceListPage for listing and filtering clearance bookings with enhanced UI components.
This commit is contained in:
Marshal
2026-06-25 01:28:45 +00:00
parent c8377958a8
commit 23b353999a
15 changed files with 1545 additions and 799 deletions

View File

@@ -276,6 +276,12 @@ export class BookingPricingService {
allowConsolidation,
shippingLineId: booking.shippingLineId,
totalWagons,
// Bulk tonnage scales PER_TON surcharges (e.g. the bulk reefer surcharge).
// Container freight carries 0 here — its surcharges scale by container count.
bulkTons:
booking.freightType === 'BULK'
? Number(booking.cargoTotalWeightVgm ?? 0)
: 0,
containers,
};
}

View File

@@ -126,8 +126,10 @@ export class BookingsService {
paymentCurrency: string;
tradeDirection: string;
isHazardous?: boolean;
isReefer?: boolean;
isGovernment?: boolean;
shippingLineId?: string | null;
bulkTons?: number;
containers: CreateBookingContainerDto[];
}): Promise<BookingEvaluationInput> {
const containerLines =
@@ -166,10 +168,14 @@ export class BookingsService {
paymentCurrency: dto.paymentCurrency,
tradeDirection: dto.tradeDirection,
isHazardous: dto.isHazardous ?? false,
// Bulk reefer comes from the customer toggle; container reefer is derived
// from the container type and ORed in by the engine.
isReefer: dto.freightType === 'BULK' ? (dto.isReefer ?? false) : false,
isGovernment: dto.isGovernment ?? false,
allowConsolidation,
shippingLineId: dto.shippingLineId,
totalWagons,
bulkTons: dto.freightType === 'BULK' ? Number(dto.bulkTons ?? 0) : 0,
containers,
};
}
@@ -387,8 +393,10 @@ export class BookingsService {
paymentCurrency: dto.paymentCurrency,
tradeDirection,
isHazardous: dto.isHazardous,
isReefer: dto.isReefer,
isGovernment,
shippingLineId: dto.shippingLineId,
bulkTons: dto.cargoTotalWeightVgm,
containers,
});
const ruleResult = await this.ruleEngineService.evaluate(evalInput);
@@ -425,6 +433,10 @@ export class BookingsService {
shippingLineId: dto.shippingLineId,
cargoTotalWeightVgm: dto.cargoTotalWeightVgm,
isHazardous: dto.isHazardous ?? false,
// Bulk reefer is the customer's toggle; container reefer is derived from
// the container type at pricing time, so the booking-level flag stays off
// for container freight to avoid double-counting.
isReefer: dto.freightType === 'BULK' ? (dto.isReefer ?? false) : false,
paymentCurrency: dto.paymentCurrency,
pnrCode: dto.pnrCode,
financialTerms: dto.financialTerms,
@@ -586,7 +598,9 @@ export class BookingsService {
paymentCurrency: dto.paymentCurrency ?? existing.paymentCurrency,
tradeDirection,
isHazardous: dto.isHazardous ?? existing.isHazardous,
isReefer: dto.isReefer ?? existing.isReefer,
shippingLineId: dto.shippingLineId ?? existing.shippingLineId ?? undefined,
bulkTons: dto.cargoTotalWeightVgm ?? Number(existing.cargoTotalWeightVgm ?? 0),
containers,
});
@@ -606,6 +620,12 @@ export class BookingsService {
...dto,
freightType,
cargoTypeId: freightType === 'BULK' ? cargoTypeId : null,
// Booking-level reefer is only meaningful for bulk; container reefer is
// derived from the container type at pricing time.
isReefer:
freightType === 'BULK'
? (dto.isReefer ?? existing.isReefer ?? false)
: false,
priorityScore: ruleResult.priorityScore,
tradeDirection,
};

View File

@@ -306,6 +306,17 @@ export class CreateBookingDto {
@Transform(({ value }) => value === 'true' || value === true)
isHazardous?: boolean;
/**
* Booking-level refrigerated flag. For bulk freight this is the customer's
* reefer choice (containers derive reefer from the container type instead).
* ORed with per-container reefer when the REEFER surcharge is evaluated.
*/
@ApiPropertyOptional({ default: false })
@IsOptional()
@IsBoolean()
@Transform(({ value }) => value === 'true' || value === true)
isReefer?: boolean;
@ApiProperty({ enum: PAYMENT_CURRENCIES })
@IsIn([...PAYMENT_CURRENCIES])
paymentCurrency!: string;