mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 11:08:12 +00:00
feat(train-scheduling): implement container movement between wagons
- Added functionality to move containers between wagons in the train scheduling system. - Introduced API endpoint and service method to handle container movement. - Updated component to support drag-and-drop for rearranging containers. - Enhanced to allow moving containers to other wagons via a context menu. - Implemented UI feedback for container movement actions, including loading states and success/error notifications. - Updated relevant types and constants to accommodate new container movement logic. - Added tests for the rule engine to ensure proper handling of hazardous bookings.
This commit is contained in:
@@ -320,6 +320,12 @@ export class ContractBookingService {
|
||||
await this.applyWeightResults(loaded);
|
||||
}
|
||||
const computed = await this.bookingPricingService.computePriceForBooking(loaded);
|
||||
// A partially-priced booking (e.g. 40ft has a rate, 20ft has none) has
|
||||
// a positive total, so the zero-price gate below misses it — enforce
|
||||
// the pricing hard blocks first. The catch below rolls everything back.
|
||||
if (computed.hardBlocked.length > 0) {
|
||||
throw new BadRequestException(computed.hardBlocked.join('; '));
|
||||
}
|
||||
// Reject a zero-price booking outright. A total of 0 means no contract rate
|
||||
// matched the route/container (or the rate is unset), so the booking is not
|
||||
// valid to ship or invoice. The catch below rolls back the row + its lines.
|
||||
@@ -744,15 +750,20 @@ export class ContractBookingService {
|
||||
const computed = await this.bookingPricingService.computePriceForBooking(loaded);
|
||||
// A zero price means no contract rate matches — roll the cargo back so
|
||||
// the instance stays CLEARANCE_READY and can be completed again once
|
||||
// the contract rates are fixed (the clearance work is not lost).
|
||||
if (!(computed.totalAmount > 0)) {
|
||||
// the contract rates are fixed (the clearance work is not lost). A
|
||||
// pricing hard block (e.g. one of two container sizes has no rate)
|
||||
// rolls back the same way: a partially-priced total is positive but
|
||||
// the booking must not proceed.
|
||||
if (!(computed.totalAmount > 0) || computed.hardBlocked.length > 0) {
|
||||
await this.bookingsRepository.deleteContainers(booking.id);
|
||||
await this.bookingsRepository.update(booking.id, {
|
||||
cargoTotalWeightVgm: 0,
|
||||
} as never);
|
||||
throw new BadRequestException(
|
||||
'Booking price came out as 0 — no contract rate matches this ' +
|
||||
'route/cargo. Set the contract rate and try again.',
|
||||
computed.hardBlocked.length > 0
|
||||
? computed.hardBlocked.join('; ')
|
||||
: 'Booking price came out as 0 — no contract rate matches this ' +
|
||||
'route/cargo. Set the contract rate and try again.',
|
||||
);
|
||||
}
|
||||
await this.bookingsRepository.update(booking.id, {
|
||||
@@ -1896,7 +1907,10 @@ export class ContractBookingService {
|
||||
overweightSurchargeAmount,
|
||||
currency: computed.currency,
|
||||
pairingErrors,
|
||||
capacityErrors: [...scopeErrors, ...capacityErrors],
|
||||
// Pricing hard blocks (missing rate for a container size / requested
|
||||
// service) ride the capacity-errors channel so the form hard-blocks in
|
||||
// the preview instead of failing at the create call.
|
||||
capacityErrors: [...scopeErrors, ...capacityErrors, ...computed.hardBlocked],
|
||||
containerClashErrors,
|
||||
spaceErrors,
|
||||
lineItems: computed.lineItems,
|
||||
|
||||
@@ -13,6 +13,7 @@ export const INCIDENT_TYPES = [
|
||||
'CONTAINER_OPENED',
|
||||
'CONTAINER_DAMAGED',
|
||||
'FLUID_LEAKING',
|
||||
'OTHER',
|
||||
] as const;
|
||||
export type IncidentType = (typeof INCIDENT_TYPES)[number];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user