feat: full wagon cancel, leg board, wagon dates

feat(freight): editable train leg times, SL invoice payer
This commit is contained in:
Marshal
2026-08-15 10:12:37 +00:00
parent c9c2d4dcb3
commit dc38e843a6
31 changed files with 1619 additions and 217 deletions

View File

@@ -121,8 +121,46 @@ export class WagonsService {
* (yard workspace, coupling pickers) walk the pages client-side — see
* `wagonService.listAll` in the backoffice.
*/
findAll(query: ListWagonsQueryDto = {}): Promise<PaginatedResponse<Wagon>> {
return paginateQuery(this.buildListQuery(query), query, { defaultPageSize: 10 });
async findAll(query: ListWagonsQueryDto = {}): Promise<PaginatedResponse<Wagon>> {
const page = await paginateQuery(this.buildListQuery(query), query, { defaultPageSize: 10 });
await this.attachStatusDates(page.items);
return page;
}
/**
* Latest status-flip dates from the audit log, for the wagons desk columns:
* when the wagon last went to MAINTENANCE and when it last became AVAILABLE.
* One grouped query per page; null when the log has no such flip.
*/
private async attachStatusDates(wagons: Wagon[]): Promise<void> {
if (!wagons.length) return;
const rows: Array<{
wagonId: string;
lastMaintenanceAt: Date | null;
lastAvailableAt: Date | null;
}> = await this.dataSource
.getRepository(WagonStatusLog)
.createQueryBuilder('l')
.select('l.wagon_id', 'wagonId')
.addSelect(
`MAX(l.created_at) FILTER (WHERE l.to_status = '${WagonStatus.Maintenance}')`,
'lastMaintenanceAt',
)
.addSelect(
`MAX(l.created_at) FILTER (WHERE l.to_status = '${WagonStatus.Available}')`,
'lastAvailableAt',
)
.where('l.wagon_id IN (:...ids)', { ids: wagons.map((w) => w.id) })
.groupBy('l.wagon_id')
.getRawMany();
const byId = new Map(rows.map((r) => [r.wagonId, r]));
for (const w of wagons) {
const r = byId.get(w.id);
Object.assign(w, {
lastMaintenanceAt: r?.lastMaintenanceAt ?? null,
lastAvailableAt: r?.lastAvailableAt ?? null,
});
}
}
async findById(id: string): Promise<Wagon> {