mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-28 07:51:02 +00:00
enhance gate pass and freight payment handling in train scheduling
- Updated the logic in to ensure that a booking only earns its gate pass once the freight charges are settled. - Added logging for bookings that have not settled freight payment when securing gate passes. - Modified seeders to ensure that bookings have associated company profiles to prevent data inconsistencies. - Updated freight permissions to include new clearance actions for bookings. - Enhanced the UI to reflect changes in the clearance process, including new shipment request pages and improved status handling in the clearance action panel. - Adjusted the contract clearance list to accommodate both customs contracts and shipment bookings. - Improved the handling of GENERAL contracts in various components to ensure proper booking flow and visibility.
This commit is contained in:
@@ -1655,6 +1655,13 @@ export class TrainSchedulingService {
|
||||
* clearance views still reading that milestone (older deployed builds) see
|
||||
* the gate pass as done. Drop once every clearance-api deployment reads
|
||||
* ImportDjiboutiOperation.gatepassGrantedAt directly.
|
||||
*
|
||||
* A booking only earns its gate pass once the customer has settled the freight
|
||||
* charges (FREIGHT_PAYMENT_SETTLED). The gate pass itself is secured per train
|
||||
* schedule, so an unpaid booking must not ride a paid neighbour's grant: it
|
||||
* keeps GATEPASS_GRANTED pending — and therefore cannot upload T1 — while the
|
||||
* train and its paid bookings proceed. Re-securing the gate pass after payment
|
||||
* settles picks the booking up; so does any later call to this bridge.
|
||||
*/
|
||||
private async completeGatepassMilestoneForSchedule(
|
||||
scheduleId: string,
|
||||
@@ -1666,20 +1673,49 @@ export class TrainSchedulingService {
|
||||
if (bookings.length === 0) return;
|
||||
|
||||
const milestoneRepo = this.dataSource.getRepository(ClearanceMilestone);
|
||||
const bookingIds = bookings.map((b) => b.id);
|
||||
const rows = await milestoneRepo.find({
|
||||
where: {
|
||||
bookingId: In(bookings.map((b) => b.id)),
|
||||
milestoneCode: 'GATEPASS_GRANTED',
|
||||
bookingId: In(bookingIds),
|
||||
milestoneCode: In(['GATEPASS_GRANTED', 'FREIGHT_PAYMENT_SETTLED']),
|
||||
},
|
||||
});
|
||||
|
||||
const paidBookingIds = new Set(
|
||||
rows
|
||||
.filter(
|
||||
(r) => r.milestoneCode === 'FREIGHT_PAYMENT_SETTLED' && r.status === 'COMPLETED',
|
||||
)
|
||||
.map((r) => r.bookingId),
|
||||
);
|
||||
// A booking whose payment settled through a path that never wrote the
|
||||
// milestone still counts as paid — the clearance views self-heal the row on
|
||||
// read, and the gate pass must not lag behind that.
|
||||
for (const booking of bookings) {
|
||||
if (booking.paymentStatus === 'PAID' || booking.status === 'PAID') {
|
||||
paidBookingIds.add(booking.id);
|
||||
}
|
||||
}
|
||||
|
||||
const skipped: string[] = [];
|
||||
for (const row of rows) {
|
||||
if (row.milestoneCode !== 'GATEPASS_GRANTED') continue;
|
||||
if (row.status === 'COMPLETED') continue;
|
||||
if (!row.bookingId || !paidBookingIds.has(row.bookingId)) {
|
||||
skipped.push(row.bookingId ?? '(unknown)');
|
||||
continue;
|
||||
}
|
||||
row.status = 'COMPLETED';
|
||||
row.triggeredAt = securedAt;
|
||||
row.metadata = { ...(row.metadata ?? {}), gatepassAt: securedAt.toISOString() };
|
||||
await milestoneRepo.save(row);
|
||||
}
|
||||
|
||||
if (skipped.length > 0) {
|
||||
this.logger.warn(
|
||||
`Gate pass secured for schedule ${scheduleId}, but ${skipped.length} booking(s) have not settled freight payment and stay pending: ${skipped.join(', ')}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async markImportReadyForLoading(scheduleId: string, dto: ImportDjiboutiActionDto = {}) {
|
||||
|
||||
Reference in New Issue
Block a user