Files
edr-platform/apps/edr-freight-api/src/modules/vehicles/entities/vehicle.entity.ts
Hagernesh cf8a2e928d fix(warehouses): detention groups by canonical truck type
Join truck_types via vehicles.truck_type_id (normalized legacy
vehicle_type only as fallback) so type renames can't unmatch detention
rules and FK-less vehicles keep billing.
2026-07-24 11:55:05 +00:00

138 lines
4.0 KiB
TypeScript

import { Entity, Column } from 'typeorm';
import { BaseEntity } from '@edr/api-common';
/**
* Legacy classification. Truck configurations are now back-office data in
* `freight.truck_types` — register a vehicle with `truckTypeId`, not this.
*
* The `vehicle_type` COLUMN survives as a denormalised copy of the truck type's
* code because truck-detention billing groups by it in raw SQL and matches it
* against `warehouse_fee_rules.vehicle_type`. The service writes it through on
* every save; nothing should set it by hand.
*
* @deprecated use `truckTypeId` / `freight.truck_types`
*/
export enum VehicleType {
TRUCK = 'TRUCK',
VAN = 'VAN',
CAR = 'CAR',
BUS = 'BUS',
TRAILER = 'TRAILER',
TANKER = 'TANKER',
FLATBED = 'FLATBED',
}
/** Who supplies the truck. Supplier selection is deferred until EDR commits to outsourcing. */
export enum VehicleOwnership {
OWNED = 'OWNED',
OUTSOURCED = 'OUTSOURCED',
}
export enum FuelType {
PETROL = 'PETROL',
DIESEL = 'DIESEL',
ELECTRIC = 'ELECTRIC',
HYBRID = 'HYBRID',
}
export enum VehicleStatus {
ACTIVE = 'ACTIVE',
MAINTENANCE = 'MAINTENANCE',
RETIRED = 'RETIRED',
OUT_OF_SERVICE = 'OUT_OF_SERVICE',
}
export enum VehicleAvailability {
FREE = 'FREE',
BUSY = 'BUSY',
}
@Entity({ name: 'vehicles', schema: 'freight' })
export class Vehicle extends BaseEntity {
@Column({ nullable: true })
code?: string;
@Column({ name: 'plate_number', unique: true, nullable: true })
plateNumber?: string;
@Column({ name: 'power_plate_no', nullable: true })
powerPlateNo?: string;
@Column({ name: 'trailer_plate_no', nullable: true })
trailerPlateNo?: string;
@Column({ name: 'registration_number', unique: true, nullable: true })
registrationNumber?: string;
/** Denormalised `truck_types.code` — written through by the service, never set by hand. */
@Column({ name: 'vehicle_type', type: 'varchar', nullable: true })
vehicleType?: string;
@Column({ name: 'truck_type_id', type: 'uuid', nullable: true })
truckTypeId?: string | null;
@Column({ nullable: true })
manufacturer?: string;
@Column({ nullable: true })
model?: string;
@Column({ nullable: true })
year?: number;
@Column({ name: 'fuel_type', type: 'varchar', nullable: true })
fuelType?: FuelType;
@Column({ nullable: true })
capacity?: number;
@Column({ name: 'status', type: 'varchar', default: VehicleStatus.ACTIVE, nullable: true })
status?: VehicleStatus;
@Column({ name: 'availability', type: 'varchar', default: VehicleAvailability.FREE, nullable: true })
availability?: VehicleAvailability;
@Column({ type: 'text', nullable: true })
description?: string | null;
@Column({ name: 'assigned_driver_id', type: 'uuid', nullable: true })
assignedDriverId?: string;
@Column({ name: 'assigned_driver_name', nullable: true })
assignedDriverName?: string;
@Column({ name: 'estimated_distance_km', type: 'numeric', nullable: true })
estimatedDistanceKm?: number;
@Column({ name: 'actual_distance_km', type: 'numeric', nullable: true })
actualDistanceKm?: number;
@Column({ name: 'location_id', type: 'uuid', nullable: true })
locationId?: string;
// --- Haulage pricing ---
@Column({ name: 'price_per_km', type: 'numeric', precision: 14, scale: 2, nullable: true })
pricePerKm?: number;
/** Currency for pricePerKm: ETB | USD */
@Column({ name: 'currency', type: 'varchar', length: 8, default: 'ETB' })
currency?: string;
// --- Compliance / expiry tracking ---
@Column({ name: 'vin', type: 'varchar', nullable: true })
vin?: string;
/** OWNED | OUTSOURCED — see {@link VehicleOwnership}. */
@Column({ name: 'ownership', type: 'varchar', nullable: true })
ownership?: string;
@Column({ name: 'insurance_expiry', type: 'date', nullable: true })
insuranceExpiry?: string;
@Column({ name: 'registration_expiry', type: 'date', nullable: true })
registrationExpiry?: string;
@Column({ name: 'next_inspection_date', type: 'date', nullable: true })
nextInspectionDate?: string;
}