mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 16:28:12 +00:00
Backoffice UAT results addressed, packages and other updates
This commit is contained in:
@@ -153,6 +153,15 @@ export class FleetController {
|
||||
return this.service.deleteTrain(id);
|
||||
}
|
||||
|
||||
@Patch('trains/:id/restore')
|
||||
@ApiOperation({ summary: 'Restore (reactivate) a deactivated train' })
|
||||
@ApiParam({ name: 'id', description: 'Train UUID' })
|
||||
@ApiResponse({ status: 200, description: 'Train restored' })
|
||||
@ApiResponse({ status: 404, description: 'Train not found' })
|
||||
restoreTrain(@Param('id') id: string) {
|
||||
return this.service.restoreTrain(id);
|
||||
}
|
||||
|
||||
// Coach Endpoints
|
||||
@Get('coaches')
|
||||
@ApiOperation({ summary: 'List coaches with seat status summary' })
|
||||
|
||||
@@ -7,6 +7,7 @@ export class CreateTrainDto {
|
||||
@ApiPropertyOptional({ example: 'EDR', description: 'Operator ID (defaults to op_edr)' }) @IsOptional() @IsString() operatorId?: string;
|
||||
@ApiPropertyOptional({ example: 'Ethiopian-Djibouti Railway' }) @IsOptional() @IsString() operatorName?: string;
|
||||
@ApiPropertyOptional({ example: 'Addis-Djibouti Express' }) @IsOptional() @IsString() description?: string;
|
||||
@ApiPropertyOptional({ example: true, description: 'Whether the train is active' }) @IsOptional() @IsBoolean() isActive?: boolean;
|
||||
}
|
||||
|
||||
export class CreateCoachDto {
|
||||
@@ -26,6 +27,8 @@ export class CreateCoachDto {
|
||||
description: 'Beds per compartment/room. Must be even (split equally left/right). Defaults: VIP_BED=4, ECONOMY_BED=6. Only applies when bedCategory is set.',
|
||||
})
|
||||
@IsOptional() @IsInt() bedsPerRoom?: number;
|
||||
@ApiPropertyOptional({ example: 1, description: 'Sequence number for ordering coaches in the train' })
|
||||
@IsOptional() @IsInt() sequence?: number;
|
||||
}
|
||||
|
||||
export class UpdateCoachDto extends PartialType(OmitType(CreateCoachDto, ['number'] as const)) {
|
||||
@@ -66,6 +69,9 @@ export class CreateClassDto {
|
||||
@ApiProperty({ example: 'Economy' }) @IsString() name: string;
|
||||
@IsOptional() @IsString() description?: string;
|
||||
@ApiProperty({ example: 5000 }) @IsInt() baseFareMinor: number;
|
||||
@ApiPropertyOptional({ example: 0 }) @IsOptional() @IsInt() premiumMinor?: number;
|
||||
@ApiPropertyOptional({ example: 0 }) @IsOptional() @IsInt() insuranceFeeMinor?: number;
|
||||
@ApiPropertyOptional({ example: true }) @IsOptional() @IsBoolean() isActive?: boolean;
|
||||
}
|
||||
|
||||
export class UpdateClassDto {
|
||||
|
||||
@@ -224,6 +224,9 @@ export class FleetService {
|
||||
name: dto.name,
|
||||
description: dto.description,
|
||||
baseFareMinor: dto.baseFareMinor,
|
||||
...(dto.premiumMinor !== undefined && { premiumMinor: dto.premiumMinor }),
|
||||
...(dto.insuranceFeeMinor !== undefined && { insuranceFeeMinor: dto.insuranceFeeMinor }),
|
||||
...(dto.isActive !== undefined && { isActive: dto.isActive }),
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -307,34 +310,54 @@ export class FleetService {
|
||||
}
|
||||
|
||||
createTrain(dto: CreateTrainDto) {
|
||||
return this.prisma.train.create({ data: dto });
|
||||
return this.prisma.train.create({
|
||||
data: {
|
||||
number: dto.number,
|
||||
name: dto.name,
|
||||
operatorId: dto.operatorId,
|
||||
operatorName: dto.operatorName,
|
||||
description: dto.description,
|
||||
isActive: dto.isActive ?? true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async updateTrain(id: string, dto: CreateTrainDto) {
|
||||
const train = await this.prisma.train.findUnique({ where: { id } });
|
||||
if (!train) throw new NotFoundException('Train not found');
|
||||
return this.prisma.train.update({ where: { id }, data: dto });
|
||||
return this.prisma.train.update({
|
||||
where: { id },
|
||||
data: {
|
||||
number: dto.number,
|
||||
name: dto.name,
|
||||
operatorId: dto.operatorId,
|
||||
operatorName: dto.operatorName,
|
||||
description: dto.description,
|
||||
...(dto.isActive !== undefined && { isActive: dto.isActive }),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async deleteTrain(id: string) {
|
||||
const train = await this.prisma.train.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
schedules: true,
|
||||
},
|
||||
include: { schedules: true },
|
||||
});
|
||||
if (!train) throw new NotFoundException('Train not found');
|
||||
|
||||
// Check for active schedules
|
||||
if (train.schedules.length > 0) {
|
||||
throw new BadRequestException(
|
||||
`Cannot delete train. This train has ${train.schedules.length} schedule(s). Please delete the schedules first.`
|
||||
);
|
||||
}
|
||||
|
||||
return this.prisma.train.delete({ where: { id } });
|
||||
}
|
||||
|
||||
async restoreTrain(id: string) {
|
||||
const train = await this.prisma.train.findUnique({ where: { id } });
|
||||
if (!train) throw new NotFoundException('Train not found');
|
||||
return this.prisma.train.update({ where: { id }, data: { isActive: true } });
|
||||
}
|
||||
|
||||
async getCoach(id: string) {
|
||||
const coach = await this.prisma.coach.findUnique({
|
||||
where: { id },
|
||||
@@ -370,18 +393,20 @@ export class FleetService {
|
||||
throw new BadRequestException(`Invalid arrangement format "${dto.arrangement}". Use e.g. "2+2"`);
|
||||
}
|
||||
|
||||
// Get the next sequence number for this coach type
|
||||
const lastCoach = await this.prisma.coach.findFirst({
|
||||
where: { coachTypeId: dto.coachTypeId },
|
||||
orderBy: { sequence: 'desc' },
|
||||
});
|
||||
const nextSequence = (lastCoach?.sequence ?? 0) + 1;
|
||||
// Use user-provided sequence or auto-assign the next one
|
||||
let resolvedSequence = dto.sequence;
|
||||
if (resolvedSequence === undefined || resolvedSequence === null) {
|
||||
const lastCoach = await this.prisma.coach.findFirst({
|
||||
orderBy: { sequence: 'desc' },
|
||||
});
|
||||
resolvedSequence = (lastCoach?.sequence ?? 0) + 1;
|
||||
}
|
||||
|
||||
const coach = await this.prisma.coach.create({
|
||||
data: {
|
||||
coachTypeId: dto.coachTypeId,
|
||||
number: dto.number,
|
||||
sequence: nextSequence,
|
||||
sequence: resolvedSequence,
|
||||
arrangement: dto.arrangement,
|
||||
capacity: dto.capacity,
|
||||
status: dto.status || 'ACTIVE',
|
||||
|
||||
Reference in New Issue
Block a user