feat: add wagon performance report and export functionality

- Implemented  for Excel download of wagon performance report sections, including column width adjustment and timestamped filenames.
- Created  to compute derived wagon performance figures based on movements and status logs, ensuring consistency with API data.
- Enhanced  with new fields for tracking last movement and statistics window days for improved reporting capabilities.
This commit is contained in:
marshalyordanos
2026-09-03 23:25:19 +03:00
parent 380ba4c4c9
commit eaa006a932
12 changed files with 3038 additions and 48 deletions

View File

@@ -29,6 +29,12 @@ export interface Wagon {
/** Latest status-log flip to MAINTENANCE / to AVAILABLE (list endpoint only). */
lastMaintenanceAt?: string | null;
lastAvailableAt?: string | null;
/** Newest wagon_movements arrival — the idle clock's start (list endpoint only). */
lastMovedAt?: string | null;
/** Loaded / empty / total moves inside `statsWindowDays` (list endpoint only). */
loadsInWindow?: number;
movesInWindow?: number;
emptyMovesInWindow?: number;
currentYardId: string | null;
currentYard?: { id: string; label?: string; code?: string } | null;
/** Odd EXPORT run (Ethiopia → Djibouti); null when the wagon is not on a run. */
@@ -55,6 +61,8 @@ export interface WagonListFilters {
* the latest status-log flip to MAINTENANCE, not a stored column. */
maintenanceFrom?: string;
maintenanceTo?: string;
/** Window (days) the per-row load/move counts cover. Does not filter rows. */
statsWindowDays?: number;
/** Only read by `getPaged`. */
page?: number;
pageSize?: number;
@@ -73,6 +81,8 @@ const wagonListQuery = (filters: WagonListFilters): string => {
if (filters.createdTo) params.set('createdTo', filters.createdTo);
if (filters.maintenanceFrom) params.set('maintenanceFrom', filters.maintenanceFrom);
if (filters.maintenanceTo) params.set('maintenanceTo', filters.maintenanceTo);
if (filters.statsWindowDays)
params.set('statsWindowDays', String(filters.statsWindowDays));
if (filters.page) params.set('page', String(filters.page));
if (filters.pageSize) params.set('pageSize', String(filters.pageSize));
const qs = params.toString();
@@ -101,6 +111,8 @@ export interface WagonMovementRecord {
note: string | null;
createdAt: string;
wagon?: { id: string; wagonNumber?: string } | null;
/** The booking's human reference, joined at read time. Null when unloaded. */
bookingReference?: string | null;
}
/** One row of the wagon status audit trail. Returned newest first by the API. */