mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
fix(clearance): flag bookings with documents still awaiting GL approval
This commit is contained in:
@@ -620,6 +620,29 @@ export class BookingsRepository extends BaseRepository<Booking> {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Bookings (of those given) that have at least one customer document still
|
||||
* waiting on GL — PENDING or QUERIED. Includes ad-hoc `custom_*` documents,
|
||||
* which no milestone tracks, so a file added after clearance was finalized
|
||||
* still surfaces as needing review. One query for a whole queue page.
|
||||
*/
|
||||
async findBookingsWithUnreviewedDocuments(
|
||||
bookingIds: string[],
|
||||
): Promise<Set<string>> {
|
||||
if (bookingIds.length === 0) return new Set();
|
||||
const rows = (await this.dataSource
|
||||
.getRepository(BookingDocumentReview)
|
||||
.createQueryBuilder('r')
|
||||
.select('DISTINCT r.booking_id', 'bookingId')
|
||||
.where('r.booking_id IN (:...bookingIds)', { bookingIds })
|
||||
.andWhere('r.status IN (:...statuses)', {
|
||||
statuses: ['PENDING', 'QUERIED'],
|
||||
})
|
||||
.andWhere('r.deleted_at IS NULL')
|
||||
.getRawMany()) as Array<{ bookingId: string }>;
|
||||
return new Set(rows.map((r) => r.bookingId));
|
||||
}
|
||||
|
||||
findDocumentReview(
|
||||
bookingId: string,
|
||||
settingCode: string,
|
||||
|
||||
@@ -40,6 +40,9 @@ function makeService(overrides?: {
|
||||
findDocumentReviews: jest.fn().mockResolvedValue([]),
|
||||
update: jest.fn().mockResolvedValue(booking),
|
||||
findByStatuses: jest.fn().mockResolvedValue([]),
|
||||
findBookingsWithUnreviewedDocuments: jest
|
||||
.fn()
|
||||
.mockResolvedValue(new Set<string>()),
|
||||
};
|
||||
const bookingsService = {
|
||||
findById: jest.fn().mockResolvedValue(booking),
|
||||
|
||||
@@ -1175,6 +1175,19 @@ export class BookingClearanceService {
|
||||
);
|
||||
filtered.push(b);
|
||||
}
|
||||
|
||||
// A document added after clearance was finalized lands as PENDING without
|
||||
// moving the booking's status — the row would otherwise still read
|
||||
// "Clearance ready" while GL has something waiting. Ad-hoc documents are
|
||||
// tracked by no milestone, so this reads the review rows directly.
|
||||
const pending = await this.bookingsRepository.findBookingsWithUnreviewedDocuments(
|
||||
filtered.map((b) => b.id),
|
||||
);
|
||||
for (const b of filtered) {
|
||||
(b as Booking & { hasDocumentsAwaitingReview?: boolean })
|
||||
.hasDocumentsAwaitingReview = pending.has(b.id);
|
||||
}
|
||||
|
||||
const rows = await this.attachContractSummary(filtered);
|
||||
return this.narrowToYardScope(rows, user);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user