Add train deactivation feature and import train number management

- Introduced DEACTIVATED status for trains, allowing staff to park trains indefinitely.
- Implemented methods to deactivate and reactivate trains in the TrainBuilderService.
- Added UI components for train deactivation and reactivation in TrainBuilderDetailPage.
- Created a dropdown setting for admin-managed import train numbers, with corresponding migrations.
- Updated yard code length to accommodate soft-delete suffix.
- Enhanced train status handling to include DEACTIVATED state.
This commit is contained in:
Marshal
2026-07-20 07:04:23 +00:00
parent ab355d0e16
commit 771aa2a605
20 changed files with 467 additions and 36 deletions

View File

@@ -1283,7 +1283,8 @@ export class TrainSchedulingService {
}
if (
builtTrain.status === Freight.TrainStatus.OutOfService ||
builtTrain.status === Freight.TrainStatus.UnderMaintenance
builtTrain.status === Freight.TrainStatus.UnderMaintenance ||
builtTrain.status === Freight.TrainStatus.Deactivated
) {
throw new ConflictException(
`Train ${builtTrain.code} is ${builtTrain.status.toLowerCase().replace(/_/g, ' ')}`,
@@ -5219,7 +5220,11 @@ export class TrainSchedulingService {
const trains = await this.dataSource.getRepository(Train).find({
where: {
status: Not(
In([Freight.TrainStatus.OutOfService, Freight.TrainStatus.UnderMaintenance]),
In([
Freight.TrainStatus.OutOfService,
Freight.TrainStatus.UnderMaintenance,
Freight.TrainStatus.Deactivated,
]),
),
},
relations: {
@@ -5619,8 +5624,8 @@ export class TrainSchedulingService {
* Re-derive a built train's lifecycle status from its schedules after one of
* them changes: any DISPATCHED schedule → IN_SERVICE; any DRAFT/SCHEDULED →
* SCHEDULED; otherwise AVAILABLE. `moveToYardId` relocates the train (arrival
* at destination). Manually parked trains (UNDER_MAINTENANCE / OUT_OF_SERVICE)
* keep their status — staff own that flag, not the scheduler.
* at destination). Manually parked trains (UNDER_MAINTENANCE / OUT_OF_SERVICE
* / DEACTIVATED) keep their status — staff own that flag, not the scheduler.
*/
private async syncBuiltTrainAfterScheduleChange(
manager: EntityManager,