mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 04:50:54 +00:00
feat: enhance locomotive creation and management with optional code generation and default max pull weight
This commit is contained in:
@@ -8,10 +8,13 @@ import {
|
||||
} from '../entities/locomotive.entity';
|
||||
|
||||
export class CreateLocomotiveDto {
|
||||
@ApiProperty({ example: 'LOCO-001' })
|
||||
// Optional on input — the service auto-generates a sequential LOCO-NNN code
|
||||
// when none is supplied.
|
||||
@ApiPropertyOptional({ example: 'LOCO-001' })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(32)
|
||||
code!: string;
|
||||
code?: string;
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@@ -32,11 +35,13 @@ export class CreateLocomotiveDto {
|
||||
@IsUUID()
|
||||
currentYardId?: string;
|
||||
|
||||
@ApiProperty({ example: 3500 })
|
||||
@Transform(({ value }) => Number(value))
|
||||
// Defaults to 2500 tons when omitted (see service).
|
||||
@ApiPropertyOptional({ example: 2500, default: 2500 })
|
||||
@IsOptional()
|
||||
@Transform(({ value }) => (value === '' || value == null ? undefined : Number(value)))
|
||||
@IsNumber()
|
||||
@Min(0)
|
||||
maxPullWeightTons!: number;
|
||||
maxPullWeightTons?: number;
|
||||
|
||||
@ApiProperty({ example: 760 })
|
||||
@Transform(({ value }) => Number(value))
|
||||
|
||||
@@ -29,20 +29,40 @@ export class LocomotivesService {
|
||||
});
|
||||
}
|
||||
|
||||
async create(dto: CreateLocomotiveDto): Promise<Locomotive> {
|
||||
const [existing] = await this.locomotivesRepository.findAll({ where: { code: dto.code } });
|
||||
/** Default max pull weight (tons) applied when the caller omits it. */
|
||||
private static readonly DEFAULT_MAX_PULL_WEIGHT_TONS = 2500;
|
||||
|
||||
/**
|
||||
* Generate the next sequential locomotive code (LOCO-001, LOCO-002, …) by
|
||||
* scanning the highest existing LOCO-NNN number. Used when the caller does not
|
||||
* supply a code.
|
||||
*/
|
||||
private async generateCode(): Promise<string> {
|
||||
const all = await this.locomotivesRepository.findAll({});
|
||||
let max = 0;
|
||||
for (const loco of all) {
|
||||
const match = /^LOCO-(\d+)$/.exec(loco.code ?? '');
|
||||
if (match) max = Math.max(max, Number(match[1]));
|
||||
}
|
||||
return `LOCO-${String(max + 1).padStart(3, '0')}`;
|
||||
}
|
||||
|
||||
async create(dto: CreateLocomotiveDto): Promise<Locomotive> {
|
||||
const code = dto.code?.trim() || (await this.generateCode());
|
||||
|
||||
const [existing] = await this.locomotivesRepository.findAll({ where: { code } });
|
||||
if (existing) {
|
||||
throw new ConflictException(`Locomotive code ${dto.code} already exists`);
|
||||
throw new ConflictException(`Locomotive code ${code} already exists`);
|
||||
}
|
||||
|
||||
return this.locomotivesRepository.create({
|
||||
code: dto.code,
|
||||
code,
|
||||
name: dto.name?.trim() || null,
|
||||
locomotiveType: dto.locomotiveType as LocomotiveType,
|
||||
status: dto.status as LocomotiveStatus,
|
||||
currentYardId: dto.currentYardId ?? null,
|
||||
maxPullWeightTons: dto.maxPullWeightTons,
|
||||
maxPullWeightTons:
|
||||
dto.maxPullWeightTons ?? LocomotivesService.DEFAULT_MAX_PULL_WEIGHT_TONS,
|
||||
maxTrainLengthMeters: dto.maxTrainLengthMeters,
|
||||
powerKw: dto.powerKw ?? null,
|
||||
tractionForceKn: dto.tractionForceKn ?? null,
|
||||
|
||||
@@ -77,7 +77,10 @@ export class WagonsService {
|
||||
async update(id: string, dto: UpdateWagonDto): Promise<Wagon> {
|
||||
const wagon = await this.findById(id);
|
||||
Object.assign(wagon, dto);
|
||||
return this.wagonRepo.save(wagon);
|
||||
await this.wagonRepo.save(wagon);
|
||||
// Re-read with the relation so the response reflects the new yard label
|
||||
// instead of the stale relation object loaded before the assign.
|
||||
return this.findById(id);
|
||||
}
|
||||
|
||||
async remove(id: string): Promise<void> {
|
||||
|
||||
Reference in New Issue
Block a user