Files
edr-platform/apps/edr-freight-api/src/modules/drivers/drivers.service.ts
natib21 2424e96e74 fix
2026-07-02 14:34:22 +00:00

118 lines
3.7 KiB
TypeScript

import { Injectable, NotFoundException, ConflictException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { CreateDriverDto } from './dto/create-driver.dto';
import { UpdateDriverDto } from './dto/update-driver.dto';
import { Driver, DriverStatus } from './entities/driver.entity';
@Injectable()
export class DriversService {
constructor(
@InjectRepository(Driver)
private readonly driverRepo: Repository<Driver>,
) {}
async create(dto: CreateDriverDto): Promise<Driver> {
const existing = await this.driverRepo.findOne({
where: [
{ licenseNumber: dto.licenseNumber },
{ email: dto.email },
{ phoneNumber: dto.phoneNumber },
],
});
if (existing) {
if (existing.licenseNumber === dto.licenseNumber) {
throw new ConflictException(`Driver with license number ${dto.licenseNumber} already exists`);
}
if (existing.email === dto.email) {
throw new ConflictException(`Driver with email ${dto.email} already exists`);
}
if (existing.phoneNumber === dto.phoneNumber) {
throw new ConflictException(`Driver with phone number ${dto.phoneNumber} already exists`);
}
}
const driver = this.driverRepo.create(dto);
return this.driverRepo.save(driver);
}
async findAll(query: {
search?: string;
status?: DriverStatus | string;
page?: number;
limit?: number;
sortBy?: string;
sortOrder?: 'ASC' | 'DESC';
} = {}): Promise<Driver[]> {
const qb = this.driverRepo.createQueryBuilder('d');
if (query.search) {
qb.where(
'(d.firstName ILIKE :search OR d.lastName ILIKE :search OR d.email ILIKE :search OR d.licenseNumber ILIKE :search OR d.phoneNumber ILIKE :search)',
{ search: `%${query.search}%` },
);
}
if (query.status) {
qb.andWhere('d.status = :status', { status: query.status });
}
const sortBy = query.sortBy && ['firstName', 'lastName', 'status', 'createdAt'].includes(query.sortBy)
? query.sortBy
: 'createdAt';
const sortOrder = (query.sortOrder ?? 'DESC').toUpperCase();
return qb
.orderBy(`d.${sortBy}`, sortOrder as 'ASC' | 'DESC')
.getMany();
}
async findById(id: string): Promise<Driver> {
const driver = await this.driverRepo.findOne({ where: { id } });
if (!driver) {
throw new NotFoundException(`Driver ${id} not found`);
}
return driver;
}
async update(id: string, dto: UpdateDriverDto): Promise<Driver> {
const driver = await this.findById(id);
if (dto.licenseNumber && dto.licenseNumber !== driver.licenseNumber) {
const existing = await this.driverRepo.findOne({
where: { licenseNumber: dto.licenseNumber },
});
if (existing) {
throw new ConflictException(`Driver with license number ${dto.licenseNumber} already exists`);
}
}
if (dto.email && dto.email !== driver.email) {
const existing = await this.driverRepo.findOne({
where: { email: dto.email },
});
if (existing) {
throw new ConflictException(`Driver with email ${dto.email} already exists`);
}
}
if (dto.phoneNumber && dto.phoneNumber !== driver.phoneNumber) {
const existing = await this.driverRepo.findOne({
where: { phoneNumber: dto.phoneNumber },
});
if (existing) {
throw new ConflictException(`Driver with phone number ${dto.phoneNumber} already exists`);
}
}
Object.assign(driver, dto);
return this.driverRepo.save(driver);
}
async remove(id: string): Promise<void> {
await this.findById(id);
await this.driverRepo.softDelete(id);
}
}