This commit is contained in:
natib21
2026-06-18 09:46:35 +00:00
parent 96ad7bd152
commit fc702f0fbe
16 changed files with 698 additions and 2 deletions

View File

@@ -0,0 +1,106 @@
import { Injectable, NotFoundException, ConflictException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { CreateVehicleDto } from './dto/create-vehicle.dto';
import { UpdateVehicleDto } from './dto/update-vehicle.dto';
import { Vehicle, VehicleStatus } from './entities/vehicle.entity';
@Injectable()
export class VehiclesService {
constructor(
@InjectRepository(Vehicle)
private readonly vehicleRepo: Repository<Vehicle>,
) {}
async create(dto: CreateVehicleDto): Promise<Vehicle> {
const existing = await this.vehicleRepo.findOne({
where: { plateNumber: dto.plateNumber },
});
if (existing) {
throw new ConflictException(
`Vehicle with plate number ${dto.plateNumber} already exists`,
);
}
const registrationNumber = `REG-${dto.vehicleType}-${Date.now()}`;
const vehicle = this.vehicleRepo.create({
...dto,
registrationNumber,
});
return this.vehicleRepo.save(vehicle);
}
async findAll(query: {
search?: string;
status?: VehicleStatus | string;
page?: number;
limit?: number;
sortBy?: string;
sortOrder?: 'ASC' | 'DESC';
} = {}): Promise<{ data: Vehicle[]; total: number; page: number; limit: number }> {
const page = query.page || 1;
const limit = query.limit || 10;
const skip = (page - 1) * limit;
let qb = this.vehicleRepo.createQueryBuilder('v');
if (query.search) {
qb = qb.where(
'v.plateNumber ILIKE :search OR v.manufacturer ILIKE :search',
{ search: `%${query.search}%` },
);
}
if (query.status) {
qb = qb.andWhere('v.status = :status', { status: query.status });
}
const sortBy = ['plateNumber', 'status', 'year', 'createdAt'].includes(
query.sortBy ?? '',
)
? query.sortBy
: 'createdAt';
const sortOrder = (query.sortOrder ?? 'DESC').toUpperCase();
const [data, total] = await qb
.orderBy(`v.${sortBy}`, sortOrder as 'ASC' | 'DESC')
.skip(skip)
.take(limit)
.getManyAndCount();
return { data, total, page, limit };
}
async findById(id: string): Promise<Vehicle> {
const vehicle = await this.vehicleRepo.findOne({ where: { id } });
if (!vehicle) {
throw new NotFoundException(`Vehicle ${id} not found`);
}
return vehicle;
}
async update(id: string, dto: UpdateVehicleDto): Promise<Vehicle> {
const vehicle = await this.findById(id);
if (dto.plateNumber && dto.plateNumber !== vehicle.plateNumber) {
const existing = await this.vehicleRepo.findOne({
where: { plateNumber: dto.plateNumber },
});
if (existing) {
throw new ConflictException(
`Vehicle with plate number ${dto.plateNumber} already exists`,
);
}
}
Object.assign(vehicle, dto);
return this.vehicleRepo.save(vehicle);
}
async remove(id: string): Promise<void> {
await this.findById(id);
await this.vehicleRepo.softDelete(id);
}
}