mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 07:10:57 +00:00
133 lines
4.5 KiB
TypeScript
133 lines
4.5 KiB
TypeScript
import { ConflictException, Injectable, NotFoundException } from '@nestjs/common';
|
|
|
|
import { CreateLocomotiveDto } from './dto/create-locomotive.dto';
|
|
import { FilterLocomotivesDto } from './dto/filter-locomotives.dto';
|
|
import { UpdateLocomotiveDto } from './dto/update-locomotive.dto';
|
|
|
|
import {
|
|
Locomotive,
|
|
type LocomotiveStatus,
|
|
type LocomotiveType,
|
|
} from './entities/locomotive.entity';
|
|
import { LocomotivesRepository } from './locomotives.repository';
|
|
|
|
@Injectable()
|
|
export class LocomotivesService {
|
|
constructor(private readonly locomotivesRepository: LocomotivesRepository) {}
|
|
|
|
findAll(filter: FilterLocomotivesDto): Promise<Locomotive[]> {
|
|
return this.locomotivesRepository.findAll({
|
|
where: {
|
|
...(filter.status ? { status: filter.status as LocomotiveStatus } : {}),
|
|
...(filter.locomotiveType
|
|
? { locomotiveType: filter.locomotiveType as LocomotiveType }
|
|
: {}),
|
|
...(filter.currentYardId ? { currentYardId: filter.currentYardId } : {}),
|
|
},
|
|
relations: { currentYard: true },
|
|
order: { code: 'ASC' },
|
|
});
|
|
}
|
|
|
|
/** 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 ${code} already exists`);
|
|
}
|
|
|
|
return this.locomotivesRepository.create({
|
|
code,
|
|
name: dto.name?.trim() || null,
|
|
locomotiveType: dto.locomotiveType as LocomotiveType,
|
|
status: dto.status as LocomotiveStatus,
|
|
currentYardId: dto.currentYardId ?? null,
|
|
maxPullWeightTons:
|
|
dto.maxPullWeightTons ?? LocomotivesService.DEFAULT_MAX_PULL_WEIGHT_TONS,
|
|
maxTrainLengthMeters: dto.maxTrainLengthMeters,
|
|
powerKw: dto.powerKw ?? null,
|
|
tractionForceKn: dto.tractionForceKn ?? null,
|
|
maxSpeedKmh: dto.maxSpeedKmh ?? null,
|
|
});
|
|
}
|
|
|
|
async findById(id: string): Promise<Locomotive> {
|
|
const locomotive = await this.locomotivesRepository.findById(id, {
|
|
relations: { currentYard: true },
|
|
});
|
|
|
|
if (!locomotive) {
|
|
throw new NotFoundException(`Locomotive ${id} not found`);
|
|
}
|
|
|
|
return locomotive;
|
|
}
|
|
|
|
async update(id: string, dto: UpdateLocomotiveDto): Promise<Locomotive> {
|
|
const locomotive = await this.findById(id);
|
|
|
|
if (dto.code && dto.code !== locomotive.code) {
|
|
const [existing] = await this.locomotivesRepository.findAll({ where: { code: dto.code } });
|
|
if (existing && existing.id !== id) {
|
|
throw new ConflictException(`Locomotive code ${dto.code} already exists`);
|
|
}
|
|
}
|
|
|
|
const updated = await this.locomotivesRepository.update(id, {
|
|
...dto,
|
|
locomotiveType:
|
|
dto.locomotiveType === undefined ? locomotive.locomotiveType : dto.locomotiveType as LocomotiveType,
|
|
status: dto.status === undefined ? locomotive.status : dto.status as LocomotiveStatus,
|
|
currentYardId:
|
|
dto.currentYardId === undefined
|
|
? locomotive.currentYardId
|
|
: (dto.currentYardId ?? null),
|
|
name: dto.name === undefined ? locomotive.name : dto.name?.trim() || null,
|
|
powerKw: dto.powerKw === undefined ? locomotive.powerKw : dto.powerKw ?? null,
|
|
tractionForceKn:
|
|
dto.tractionForceKn === undefined ? locomotive.tractionForceKn : dto.tractionForceKn ?? null,
|
|
maxSpeedKmh:
|
|
dto.maxSpeedKmh === undefined ? locomotive.maxSpeedKmh : dto.maxSpeedKmh ?? null,
|
|
});
|
|
|
|
if (!updated) {
|
|
throw new NotFoundException(`Locomotive ${id} not found`);
|
|
}
|
|
|
|
return updated;
|
|
}
|
|
|
|
async decommission(id: string): Promise<Locomotive> {
|
|
await this.findById(id);
|
|
|
|
const updated = await this.locomotivesRepository.update(id, {
|
|
status: 'OUT_OF_SERVICE',
|
|
});
|
|
|
|
if (!updated) {
|
|
throw new NotFoundException(`Locomotive ${id} not found`);
|
|
}
|
|
|
|
return updated;
|
|
}
|
|
}
|