feat: add fuel management system backend

- FuelPurchase entity: record fuel purchases with cost tracking
- FuelConsumption entity: monthly aggregation of fuel metrics
- FuelService: record purchases, calculate stats, efficiency
- FuelController: REST API for fuel operations
- FuelModule: integrated into app
- Migration: create fuel_purchases and fuel_consumption tables

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
natib21
2026-06-30 10:07:13 +00:00
parent 360e61ac15
commit df6e417a56
9 changed files with 425 additions and 0 deletions

View File

@@ -0,0 +1,35 @@
import { BaseEntity } from '@edr/api-common';
import { Entity, Column, ManyToOne, JoinColumn, Index } from 'typeorm';
import { Vehicle } from '../../vehicles/entities/vehicle.entity';
@Entity({ name: 'fuel_consumption', schema: 'freight' })
@Index(['vehicleId', 'month'])
export class FuelConsumption extends BaseEntity {
@Column({ name: 'vehicle_id', type: 'uuid' })
vehicleId!: string;
@ManyToOne(() => Vehicle, { eager: false })
@JoinColumn({ name: 'vehicle_id' })
vehicle!: Vehicle;
@Column({ name: 'month', type: 'date' })
month!: Date;
@Column({ name: 'total_liters', type: 'numeric', precision: 10, scale: 2 })
totalLiters!: number;
@Column({ name: 'total_cost', type: 'numeric', precision: 14, scale: 2 })
totalCost!: number;
@Column({ name: 'total_distance_km', type: 'numeric', precision: 10, scale: 2 })
totalDistanceKm!: number;
@Column({ name: 'fuel_efficiency_km_per_l', type: 'numeric', precision: 10, scale: 2, nullable: true })
fuelEfficiencyKmPerL?: number;
@Column({ name: 'number_of_purchases', type: 'integer', default: 0 })
numberOfPurchases!: number;
@Column({ name: 'average_cost_per_liter', type: 'numeric', precision: 10, scale: 2, nullable: true })
averageCostPerLiter?: number;
}

View File

@@ -0,0 +1,51 @@
import { BaseEntity } from '@edr/api-common';
import { Entity, Column, ManyToOne, JoinColumn } from 'typeorm';
import { Vehicle } from '../../vehicles/entities/vehicle.entity';
export enum PaymentMethod {
CASH = 'CASH',
CARD = 'CARD',
FUEL_CARD = 'FUEL_CARD',
TRANSFER = 'TRANSFER',
CHEQUE = 'CHEQUE',
}
@Entity({ name: 'fuel_purchases', schema: 'freight' })
export class FuelPurchase extends BaseEntity {
@Column({ name: 'vehicle_id', type: 'uuid' })
vehicleId!: string;
@ManyToOne(() => Vehicle, { eager: false })
@JoinColumn({ name: 'vehicle_id' })
vehicle!: Vehicle;
@Column({ name: 'purchase_date', type: 'timestamptz' })
purchaseDate!: Date;
@Column({ name: 'liters', type: 'numeric', precision: 10, scale: 2 })
liters!: number;
@Column({ name: 'cost_per_liter', type: 'numeric', precision: 10, scale: 2 })
costPerLiter!: number;
@Column({ name: 'total_cost', type: 'numeric', precision: 14, scale: 2 })
totalCost!: number;
@Column({ name: 'fuel_station', nullable: true })
fuelStation?: string;
@Column({ name: 'payment_method', type: 'varchar', default: PaymentMethod.CASH })
paymentMethod!: PaymentMethod;
@Column({ name: 'odometer_reading', type: 'numeric', nullable: true })
odometerReading?: number;
@Column({ name: 'driver_id', type: 'uuid', nullable: true })
driverId?: string;
@Column({ name: 'receipt_number', nullable: true })
receiptNumber?: string;
@Column({ type: 'text', nullable: true })
notes?: string;
}