From ad5caddf6060eb70931a21fd0fd9f8fe9f9abb2d Mon Sep 17 00:00:00 2001 From: ghost2023 Date: Fri, 21 Aug 2026 15:54:53 +0300 Subject: [PATCH] feat(wagons): filter list by last-maintenance date range Adds maintenanceFrom/maintenanceTo to ListWagonsQueryDto and applies them in WagonsService.buildListQuery as a correlated subquery against wagon_status_logs (last flip to MAINTENANCE), mirroring the existing createdFrom/createdTo range filter. Both ends inclusive, whole days. --- .../wagons/dto/list-wagons-query.dto.ts | 14 +++++++++++++ .../src/modules/wagons/wagons.service.ts | 21 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/apps/edr-freight-api/src/modules/wagons/dto/list-wagons-query.dto.ts b/apps/edr-freight-api/src/modules/wagons/dto/list-wagons-query.dto.ts index 4f48c2a8b..1e2db1631 100644 --- a/apps/edr-freight-api/src/modules/wagons/dto/list-wagons-query.dto.ts +++ b/apps/edr-freight-api/src/modules/wagons/dto/list-wagons-query.dto.ts @@ -91,4 +91,18 @@ export class ListWagonsQueryDto { @IsOptional() @IsDateString() createdTo?: string; + + @ApiPropertyOptional({ + description: 'Last maintenance flip on or after this day (YYYY-MM-DD)', + }) + @IsOptional() + @IsDateString() + maintenanceFrom?: string; + + @ApiPropertyOptional({ + description: 'Last maintenance flip on or before this day (YYYY-MM-DD)', + }) + @IsOptional() + @IsDateString() + maintenanceTo?: string; } diff --git a/apps/edr-freight-api/src/modules/wagons/wagons.service.ts b/apps/edr-freight-api/src/modules/wagons/wagons.service.ts index f2c76e283..034418ef6 100644 --- a/apps/edr-freight-api/src/modules/wagons/wagons.service.ts +++ b/apps/edr-freight-api/src/modules/wagons/wagons.service.ts @@ -90,6 +90,27 @@ export class WagonsService { }); } + // Last-maintenance range, both ends inclusive. There's no column to + // compare directly — "last maintenance" is the latest status-log flip to + // MAINTENANCE (see attachStatusDates below), so this mirrors that same + // MAX(...) FILTER(...) as a correlated subquery against the same table. + if (query.maintenanceFrom) { + qb.andWhere( + `(SELECT MAX(l.created_at) FROM freight.wagon_status_logs l + WHERE l.wagon_id = w.id AND l.to_status = '${WagonStatus.Maintenance}') + >= CAST(:maintenanceFrom AS date)`, + { maintenanceFrom: query.maintenanceFrom }, + ); + } + if (query.maintenanceTo) { + qb.andWhere( + `(SELECT MAX(l.created_at) FROM freight.wagon_status_logs l + WHERE l.wagon_id = w.id AND l.to_status = '${WagonStatus.Maintenance}') + < CAST(:maintenanceTo AS date) + INTERVAL '1 day'`, + { maintenanceTo: query.maintenanceTo }, + ); + } + // Search matches the wagon number or either run number. if (search) { qb.andWhere(