mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
feat: implement 20ft container weight-pairing validation
- Added ContainerValidationService to handle 20ft weight-pairing logic. - Introduced validate20ftWeightPairing utility function to check weight differences. - Updated BookingPricingService to include overweight line details and pairing errors in price response. - Enhanced BookingTransitionService to reject submissions with unpairable 20ft containers. - Created ShipmentValidation interface for pre-submit validation of container contracts. - Integrated shipment validation into the contract booking process, providing warnings for overweight containers and hard blocks for pairing errors. - Updated front-end components to display validation results and prevent submission when errors are present.
This commit is contained in:
@@ -16,6 +16,7 @@ import { FilesService } from '../files/files.service';
|
||||
import { FileUploadSettingsService } from '../file-upload-settings/file-upload-settings.service';
|
||||
import { BookingContractService } from './booking-contract.service';
|
||||
import { BookingPricingService } from './booking-pricing.service';
|
||||
import { ContainerValidationService } from './container-validation.service';
|
||||
import { BookingsRepository } from './bookings.repository';
|
||||
import { assertBookingStatus } from './booking-status.util';
|
||||
import { clearanceCodesForBooking } from './clearance.util';
|
||||
@@ -51,6 +52,7 @@ export class BookingTransitionService {
|
||||
@Inject(forwardRef(() => ClearanceWorkflowService))
|
||||
private readonly workflowService: ClearanceWorkflowService,
|
||||
private readonly invoiceService: BookingInvoiceService,
|
||||
private readonly containerValidationService: ContainerValidationService,
|
||||
|
||||
) {}
|
||||
|
||||
@@ -58,6 +60,19 @@ export class BookingTransitionService {
|
||||
return this.bookingClearanceService.isPhasedGeneralCustomsBooking(booking);
|
||||
}
|
||||
|
||||
/** Reject submit when the booking's 20ft containers can't be balanced onto wagons. */
|
||||
private async assert20ftPairable(booking: Booking): Promise<void> {
|
||||
const violations =
|
||||
await this.containerValidationService.validate20ftPairing(booking);
|
||||
if (violations.length) {
|
||||
throw new BadRequestException(
|
||||
`Cannot submit — 20ft containers cannot be paired on wagons: ${violations
|
||||
.map((v) => v.message)
|
||||
.join(' ')}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async submit(bookingId: string): Promise<SubmitBookingResponseDto> {
|
||||
const booking = await this.bookingsService.findById(bookingId);
|
||||
assertBookingStatus(booking, ["DRAFT", "CHANGES_REQUESTED"]);
|
||||
@@ -78,6 +93,11 @@ export class BookingTransitionService {
|
||||
requiresDirectorApproval: false,
|
||||
});
|
||||
|
||||
// 20ft weight-pairing hard block: two 20ft on a wagon must differ ≤ the cap.
|
||||
// If no balanced pairing exists the booking cannot proceed (overweight only
|
||||
// warns; this rejects). An odd leftover 20ft is fine — it goes to consolidation.
|
||||
await this.assert20ftPairable(booking);
|
||||
|
||||
const stored = booking.pricingBreakdown as {
|
||||
lineItems?: PriceLineItemDto[];
|
||||
totalAmount?: number;
|
||||
@@ -158,6 +178,7 @@ export class BookingTransitionService {
|
||||
hardBlocked: computed.hardBlocked,
|
||||
requiresDirectorApproval: false,
|
||||
});
|
||||
await this.assert20ftPairable(booking);
|
||||
|
||||
await this.pricingService.createPricingSnapshots(
|
||||
bookingId,
|
||||
|
||||
Reference in New Issue
Block a user