/** * Fleet Service * Mecánicas Diesel - ERP Suite * * Business logic for fleet management. */ import { Repository, DataSource } from 'typeorm'; import { Fleet } from '../entities/fleet.entity'; import { Vehicle, VehicleStatus } from '../entities/vehicle.entity'; // DTOs export interface CreateFleetDto { name: string; code?: string; contactName?: string; contactPhone?: string; contactEmail?: string; discountLaborPct?: number; discountPartsPct?: number; creditDays?: number; creditLimit?: number; notes?: string; } export interface UpdateFleetDto { name?: string; code?: string; contactName?: string; contactPhone?: string; contactEmail?: string; discountLaborPct?: number; discountPartsPct?: number; creditDays?: number; creditLimit?: number; notes?: string; isActive?: boolean; } export class FleetService { private fleetRepository: Repository; private vehicleRepository: Repository; constructor(dataSource: DataSource) { this.fleetRepository = dataSource.getRepository(Fleet); this.vehicleRepository = dataSource.getRepository(Vehicle); } /** * Create a new fleet */ async create(tenantId: string, dto: CreateFleetDto): Promise { const fleet = this.fleetRepository.create({ tenantId, name: dto.name, code: dto.code, contactName: dto.contactName, contactPhone: dto.contactPhone, contactEmail: dto.contactEmail, discountLaborPct: dto.discountLaborPct || 0, discountPartsPct: dto.discountPartsPct || 0, creditDays: dto.creditDays || 0, creditLimit: dto.creditLimit || 0, notes: dto.notes, isActive: true, vehicleCount: 0, }); return this.fleetRepository.save(fleet); } /** * Find fleet by ID */ async findById(tenantId: string, id: string): Promise { return this.fleetRepository.findOne({ where: { id, tenantId }, }); } /** * List fleets */ async findAll( tenantId: string, pagination = { page: 1, limit: 20 } ) { const queryBuilder = this.fleetRepository.createQueryBuilder('fleet') .where('fleet.tenant_id = :tenantId', { tenantId }); const skip = (pagination.page - 1) * pagination.limit; const [data, total] = await queryBuilder .orderBy('fleet.name', 'ASC') .skip(skip) .take(pagination.limit) .getManyAndCount(); return { data, total, page: pagination.page, limit: pagination.limit, totalPages: Math.ceil(total / pagination.limit), }; } /** * Update fleet */ async update(tenantId: string, id: string, dto: UpdateFleetDto): Promise { const fleet = await this.findById(tenantId, id); if (!fleet) return null; Object.assign(fleet, dto); return this.fleetRepository.save(fleet); } /** * Deactivate fleet */ async deactivate(tenantId: string, id: string): Promise { const fleet = await this.findById(tenantId, id); if (!fleet) return false; fleet.isActive = false; await this.fleetRepository.save(fleet); return true; } /** * Get fleet with vehicle count */ async getFleetWithStats(tenantId: string, id: string): Promise<{ fleet: Fleet; vehicleCount: number; activeVehicles: number; } | null> { const fleet = await this.findById(tenantId, id); if (!fleet) return null; const [vehicleCount, activeVehicles] = await Promise.all([ this.vehicleRepository.count({ where: { tenantId, fleetId: id } }), this.vehicleRepository.count({ where: { tenantId, fleetId: id, status: VehicleStatus.ACTIVE } }), ]); return { fleet, vehicleCount, activeVehicles, }; } /** * Get active fleets */ async findActive(tenantId: string): Promise { return this.fleetRepository.find({ where: { tenantId, isActive: true }, order: { name: 'ASC' }, }); } /** * Add vehicle to fleet */ async addVehicle(tenantId: string, fleetId: string, vehicleId: string): Promise { const fleet = await this.findById(tenantId, fleetId); if (!fleet) return false; const vehicle = await this.vehicleRepository.findOne({ where: { id: vehicleId, tenantId }, }); if (!vehicle) return false; vehicle.fleetId = fleetId; await this.vehicleRepository.save(vehicle); // Update vehicle count fleet.vehicleCount = await this.vehicleRepository.count({ where: { tenantId, fleetId } }); await this.fleetRepository.save(fleet); return true; } /** * Remove vehicle from fleet */ async removeVehicle(tenantId: string, fleetId: string, vehicleId: string): Promise { const vehicle = await this.vehicleRepository.findOne({ where: { id: vehicleId, tenantId, fleetId }, }); if (!vehicle) return false; const fleet = await this.findById(tenantId, fleetId); if (!fleet) return false; vehicle.fleetId = undefined; await this.vehicleRepository.save(vehicle); // Update vehicle count fleet.vehicleCount = await this.vehicleRepository.count({ where: { tenantId, fleetId } }); await this.fleetRepository.save(fleet); return true; } }