Sixième Étoile — Documentation

Cost Model

Fuel resolution chain (CollectAPI → FuelPriceCache → default), toll resolution (Google Routes → TollGuru → estimate), the CostBreakdown structure, and RSE compliance staffing costs.

The cost model feeds TripAnalysis.costBreakdown — a per-segment breakdown used to compute the internal cost, margin, and ProfitabilityIndicator displayed in the back-office. None of the cost components are directly added to the client-facing price; they exist for profitability analysis only.

CostBreakdown Structure

interface CostBreakdown {
  fuel:          FuelCostComponent;
  tolls:         TollCostComponent;
  wear:          WearCostComponent;
  driver:        DriverCostComponent;
  parking:       ParkingCostComponent;
  zoneSurcharges?: ZoneSurcharges;
  tco?:          TcoCostComponent;  // TCO if vehicle data available
  total:         number;
}

total = fuel + tolls + wear + driver + parking. Zone surcharges and TCO are additive when present.


Fuel Cost

Fuel price resolution chain

The engine resolves the price per liter in this order, stopping at the first available result:

PrioritySourceMechanism
1CollectAPI (real-time)HTTP request to CollectAPI with GPS coordinates; returns prices per country/region
2FuelPriceCache (database)Most recent FuelPriceCache row for the resolved country; stale after 48 h
3Organization overrideOrganizationPricingSettings.fuelPricePerLiter
4Built-in defaultsDEFAULT_FUEL_PRICES in constants.ts

Default fuel prices:

Fuel typeDefault (€/L)
DIESEL1.789
GASOLINE1.899
LPG0.999
ELECTRIC0.25

CollectAPI timeout: 4 000 ms (REALTIME_API_TIMEOUT_MS). A cache hit with less than 48 hours of age satisfies the request without an API call. The per-request in-memory cache (TTL 60 s) prevents duplicate calls within a single pricing calculation for multi-waypoint excursions.

Fuel consumption resolution chain

The liters-per-100-km figure resolves via a separate four-level chain:

PrioritySource
1Vehicle.fuelConsumption (specific vehicle, if assigned)
2VehicleCategory.fuelConsumption
3OrganizationPricingSettings.fuelConsumptionL100km
4Built-in default: 8.0 L/100 km

Fuel cost formula

litersUsed = (distanceKm / 100) × consumptionL100km
fuelCost   = litersUsed × pricePerLiter

Toll Cost

Toll resolution chain

PrioritySourceNotes
1Google Routes APIParses travelAdvisory.tollInfo.estimatedPrice from the v2 response
2TollGuru APIFallback when Google returns no toll data; supports LIGHT/HEAVY weight classes
3Flat rate estimatedistanceKm × tollCostPerKm (default 0.15 €/km)

Toll results are cached in the TollCalculationCache table for 24 hours (keyed on coordinate hash to 4 decimal places ≈ 11 m precision). TollCostComponent.isFromCache flags cache hits.

For ELECTRIC fuel type, the engine remaps to GASOLINE for the Google Routes API (which may not return toll data for electric vehicles).

Toll cost formula (fallback only)

tollCost = distanceKm × tollCostPerKm

Wear Cost

Vehicle mechanical wear modeled as a flat rate per km:

wearCost = distanceKm × wearCostPerKm

Default: 0.10 €/km (DEFAULT_COST_PARAMETERS.wearCostPerKm). Overridden by OrganizationPricingSettings.wearCostPerKm.


Driver Cost

Driver time valued at an hourly rate:

driverCost = (durationMinutes / 60) × driverHourlyCost

Default: 25.00 €/h (DEFAULT_COST_PARAMETERS.driverHourlyCost). Overridden by OrganizationPricingSettings.driverHourlyCost.

For HEAVY vehicles with RSE mandatory breaks, the extra break minutes are included in the totalDurationMinutes fed into the driver cost calculation.


TCO (Total Cost of Ownership)

When full vehicle and category TCO data is available, a TcoCostComponent is added:

interface TcoCostComponent {
  amount: number;
  distanceKm: number;
  depreciation: { amount: number; ratePerKm: number; method: "LINEAR" | "DECLINING_BALANCE" };
  maintenance:  { amount: number; ratePerKm: number };
  insurance:    { amount: number; ratePerKm: number };
  totalRatePerKm: number;
  source: "VEHICLE" | "CATEGORY";
}

TCO complements the wear cost; when TCO is present, tco.total provides a more accurate amortisation figure than the flat wearCostPerKm rate.


Zone Surcharges

Fixed surcharges defined per zone are collected after route resolution:

interface ZoneSurcharges {
  pickup:  ZoneSurchargeComponent | null;
  dropoff: ZoneSurchargeComponent | null;
  total:   number;
}

Each ZoneSurchargeComponent aggregates parkingSurcharge + accessFee for the zone. If pickup and dropoff resolve to the same zone, the surcharge is counted only once.


RSE Compliance Staffing Costs

When integrateComplianceIntoPricing() detects a long-distance or multi-day mission, it attaches a CompliancePlan to TripAnalysis:

Plan typeTriggerCost impact
DOUBLE_CREWTrip exceeds single-driver daily hours limitSecond driver cost added to totalInternalCost
RELAY_DRIVERLong-haul trip requiring driver relayRelay positioning cost added
MULTI_DAYTrip spans multiple calendar daysDriver accommodation + per-diem costs added
NONENo compliance issueNo extra cost

The staffing plan selection policy is configurable (OrganizationPricingSettings.staffingSelectionPolicy):

PolicyBehaviour
CHEAPESTSelects the staffing arrangement with the lowest total cost
FASTESTMinimises total trip duration
PREFER_INTERNALPrefers internal drivers over external relay drivers

Staffing costs inflate TripAnalysis.totalInternalCost but are not added to the client price. They affect the profitability indicator.


Profitability Indicator

type ProfitabilityIndicator = "green" | "orange" | "red";

// Thresholds (configurable):
//   green:  marginPercent ≥ greenMarginThreshold  (default 20 %)
//   orange: marginPercent ≥ orangeMarginThreshold (default 0 %)
//   red:    marginPercent < orangeMarginThreshold
marginPercent = ((price - internalCost) / price) × 100

Both greenMarginThreshold and orangeMarginThreshold are configurable in OrganizationPricingSettings.


Short-trip pricing

Below shortTripThresholdKm (configurable), the engine applies a shortTripMultiplier to offset the fixed overhead costs per trip. A minimumTripPriceHt floor can also be set to guarantee a minimum revenue.

FieldEffect
minimumTripPriceHtPrice floor (HT) regardless of formula result
shortTripThresholdKmDistance below which the short-trip multiplier applies
shortTripMultiplierFactor applied to base price for short trips

See also

Was this page helpful?

On this page