Book 5, Chapter 18 — Vehicles & Tracking¶
1. Purpose¶
Every truck, cab, trailer and delivery vehicle the company owns lives in one central register: the Vehicle Center. This chapter documents that register and the metadata around it — the master record of a vehicle, its tracking hardware (GPS/immobiliser device and its SIM card), which state it is currently in (live and moving, offline, sitting in the garage, or unallocated to any branch/driver), how articulated trucks are split into a cab (the powered unit with the driver) and a trailer (the load body) and paired together, and the financial side of a vehicle as a depreciating asset.
In plain terms, this module answers questions a fleet manager asks daily:
- Where are my vehicles right now, and which ones have gone dark (offline)? → the Live Tracking map and Offline Vehicles screen.
- Which vehicles are parked in the garage and for how long? → Garaged Vehicles.
- Which vehicles have no driver / no branch and are earning nothing? → Unallocated Vehicles (with a "penalize" action).
- Which trailer is hooked to which cab today, and what's the history? → Trucks & Trailers (cab-trailer assignments).
- What is each vehicle worth now, and how much has it depreciated? → Amortization Schedules and the vehicle's own depreciation fields.
- What did this vehicle cost me and how far did it travel this period? → the Vehicle Expenses and Mileage reports.
The vehicle record created here is the operational source that every other fleet module consumes: Fuel (Ch19), Tyres (Ch20), Service/Route-compliance/geofencing (Ch21) and inbound logistics/inspections (Ch22) all point back to a vehicles row. It is also the operational side of a Fixed Asset (Book 4, Ch16): a fixed-asset record can be polymorphically linked to a Vehicle, and Vehicle is one of only three wired linkable types.
2. Users & roles¶
The whole Fleet Management sidebar tree is gated at the top by role_id == 1 (super-admin) OR the permission fleet-management-module___view (fleet.blade.php:1). Individual leaves are gated further. Two permission-check styles coexist in the nav:
- Legacy style —
isset($my_permissions['<key>']), keys shapedresource___action(triple underscore). Examples:vehicles-overview___view,vehicles-overview___listing,vehicle-suppliers___view,vehicle-models___view,vehicle-command-center___view,vehicle-command-center___exemption-schedules,vehicle-command-center-custom-schedules___view. - Modern style — the
can("<action>", "<resource>")Blade helper. Examples below.
| Screen / action | Route name | Gate (as coded in fleet.blade.php) |
|---|---|---|
| Live Tracking (map) | vehicle-overview-all |
vehicles-overview___view (:85) |
| Offline Vehicles | offline-vehicles.index |
can("view","offline-vehicles") (:93) |
| Garaged Vehicles | garaged-vehicles.index |
can("view","garaged-vehicles") (:101) |
| Unallocated Vehicles | unallocated-vehicles.index |
can("view","unallocated-vehicles") (:109) |
| Vehicle Center (register) | vehicles.index |
vehicles-overview___listing (:259) |
| Trucks & Trailers | cab-trailer-assignments.index |
can("view","trucks-trailers") (:267) |
| Control Centre (command center) | vehicle-command-center |
vehicle-command-center___view (:622) |
| Exemption Schedules | exemption-schedules |
vehicle-command-center___exemption-schedules (:629) |
| Custom Schedules | custom-schedules |
vehicle-command-center-custom-schedules___view (:637) |
| Assets → Amortization / Settings | vehicle-amortization-schedules.index, vehicle-expenses.settings |
can("view","vehicle-expenses") (:645) |
| Reports → Expenses / Mileage | vehicle-center.expenseReport, vehicle-center.mileageReport |
can("view","vehicle-center-reports") (:667) |
| Set Up (group) | — | vehicle-suppliers___view OR vehicle-models___view (:689) |
| Vehicle Suppliers | vehicle-suppliers.index |
vehicle-suppliers___view (:696) |
| Vehicle Models | vehicle-models.index |
vehicle-models___view (:705) |
| Tracking Devices | tracking-devices.index |
can('view','tracking-devices') (:714) |
| Vehicle Offline Report | vehicles.offline-diagnostic-report |
can('view','vehicle-offline-report') (:723) |
| Utility (group) | — | can('view','vehicle-utility') (:732) |
| Update Vehicle Route | vehicles.utils |
(inside Utility group) (:739) |
| Update SIM Number | vehicles-update-sim |
(inside Utility group) (:745) |
All admin fleet routes sit behind the AdminLoggedIn and ip-blocker middleware group (fleet.php:30). Immobilisation notifications specifically target users whose role slug is fleet-manager (Vehicle.php:611), the operational role that acts on the command center / route-compliance immobilisations.
Note the nav is defensively inconsistent: line 82 contains a bug — bare string literals
"tyre-management","trucks-trailers","offline-vehicles"are truthy, so that wrapper<li>is always markedactive. It is cosmetic (highlight state) and does not affect access.
3. Processes¶
3.1 Vehicle master record (the register)¶
A vehicle is created/edited through VehicleController (the vehicles.index route family) and the register lists all vehicles. The master row (vehicles table, create_vehicles_table.php) carries identity (license_plate_number UNIQUE, vin UNIQUE, name, vehicle_type_id, vehicle_model_id), physical spec (unladen_weight, max_load_capacity, axle_count, tyre_count, fuel_tank_capacity), onboarding baselines (onboarding_mileage, onboarding_fuel and their dates), tracking-hardware pointers (device_name, sim_card_number, later tracking_device_id, flespi_device_id), assignment (branch_id, driver_id, later turn_boy_id, primary_responsibility), and financials (acquisition_date, acquisition_price, plus later resale/depreciation fields). The model is App\Vehicle (top-level namespace, not App\Models), uses SoftDeletes and Spatie activity logging that tracks changes to primary_responsibility, driver_id, turn_boy_id, branch_id, garage_status (Vehicle.php:275-287).
3.2 Vehicle lifecycle / state¶
State is not a single enum column; it is derived from several booleans and relations:
is_trailer/is_truck_cab(boolean casts,Vehicle.php:92-93) — classify a unit as a trailer or a powered cab.garage_status(boolean cast,:94) —GARAGE_STATUS_ACTIVE = false(on road) vsGARAGE_STATUS_IN_GARAGE = true(Vehicle.php:68-71). "Garaged" vehicles are those withgarage_status = true.- Online/offline — derived from
lastTelemetryfreshness against themax-vehicle-telemetry-age-limit-minutessetting (default 5 min):getIsOnlineAttribute()andgetLastHeartBeatAttribute()(Vehicle.php:914-955). A vehicle with a tracker but stale telemetry surfaces on Offline Vehicles (persisted via theoffline_vehiclestable /OfflineVehiclemodel,create_offline_vehicles_table.php). - Unallocated — no
driver_id/branch_idassignment (Unallocated Vehicles screen; penalize action viaChairmanDashboardController::penalizeUnassignedVehicle,fleet.php:86). - Immobilised —
switch_off_statusisoff/ontoggled byactivateImmobilizer()/deactivateImmobilizer()(Vehicle.php:598,784); events recorded invehicle_immobilizations. - Soft-deleted / sold —
deleted_atset, or aVehicleSaleDetail(saleDetail(),Vehicle.php:328) recorded on disposal.
stateDiagram-v2
[*] --> Onboarded: create vehicle (plate, VIN, model, onboarding mileage)
Onboarded --> Unallocated: no driver / branch
Unallocated --> Allocated: assign driver + branch
Allocated --> Online: tracker reports fresh telemetry (<5 min)
Online --> Offline: telemetry stale / device dark
Offline --> Online: telemetry resumes
Allocated --> Garaged: garage_status = true (in workshop)
Garaged --> Allocated: garage_status = false
Online --> Immobilised: activateImmobilizer() (switch_off_status=off)
Immobilised --> Online: deactivateImmobilizer() (switch_off_status=on)
Allocated --> Sold: VehicleSaleDetail + soft delete
Sold --> [*]
state "Cab/Trailer" as CT
Allocated --> CT: is_truck_cab / is_trailer
note right of CT
Cab and Trailer paired via
CabTrailerAssignment (is_active)
end note
3.3 Cab ↔ Trailer assignment¶
Articulated trucks are modelled as two vehicles rows: a cab (is_truck_cab = true) and a trailer (is_trailer = true). CabTrailerAssignmentController (fleet.php:151-166) drives the Trucks & Trailers screen with separate cab and trailer tabs (trailersIndex, cabsIndex) fed by AJAX data endpoints (cabs-data, trailers-data).
- Assign (
POST /assign) links a trailer to a cab, creating aCabTrailerAssignment(cab_vehicle_id,trailer_vehicle_id,is_active). - Unassign / bulk-unassign (
POST /unassign,/bulk-unassign) end the active link. - Move (
POST /move) re-hooks a trailer to a different cab. - Mark not trailer (
POST /mark-not-trailer/{vehicle},/bulk-mark-not-trailer) corrects mis-classified vehicles. - History (
GET /history/{vehicle}) readsCabTrailerAssignmentHistory. - Available cabs / trailers helpers expose assignable units.
Relationship methods on the Vehicle model formalise the pairing: assignedTrailers() (active assignments where this vehicle is the cab), assignedCab() (active assignment where this vehicle is the trailer), allAssignments(), cabAssignments(), assignmentHistory(), cabAssignmentHistory() (Vehicle.php:1022-1050). Business rules: a trailer is available only when it has no active cab (isAvailableForAssignment(), :1068); canBeAssignedTo(Vehicle $cab) requires is_trailer on this and is_truck_cab on the target and rejects re-assigning to the same cab (:1076). A trailer's effective driver/turnboy is inherited from its cab (getEffectiveDriver(), getEffectiveTurnboy(), :1090-1104). An API cleanup exists for orphaned assignments (api.php:135-136).
3.4 Tracking devices & SIM management¶
A tracking device is a device type (not a physical unit): tracking_devices has just name, on_command, off_command (create_tracking_devices_table.php:14-19). The same migration adds the tracking_device_id FK onto vehicles (:22-24). TrackingDevicesController drives the Tracking Devices setup screen. The Vehicle links via tracker() (belongsTo TrackingDevice, Vehicle.php:468), plus helpers scopeWithTracker(), hasTracker(), scopeForLiveOverview() (which requires a tracker, excludes trailers and soft-deleted, :481-487).
Physical connectivity is split across three columns/tables: the vehicle's flespi_device_id (the ID in the Flespi telematics gateway), device_name, and sim_card_number. Two dedicated tables model SIMs: device_sim_cards and sim_card_to_devices (create_device_sim_cards_table.php, create_sim_card_to_devices_table.php). The Update SIM Number utility (vehicles-update-sim, nav :745) is the operational tool to correct a vehicle's SIM. assignFlespiDeviceIdIfMissing() (Vehicle.php:1162-1213) safely back-fills a flespi_device_id only when the vehicle has none and no other vehicle owns that ID (guards against duplicate device assignment).
Immobilisation is the operational payload of the tracker. activateImmobilizer() / deactivateImmobilizer() (Vehicle.php:534-912) branch on tracker->id to send device-specific Flespi commands: tracker 22 = Teltonika FMB920 (single output outputs1); trackers 501/692/1339 = FMB130/140/150 (buzzer-then-cut two-step, outputs2 for 1339, outputs3 otherwise). Speed-gated: if the vehicle is moving faster than the threshold, a PendingImmobilization row is queued and executed once speed drops (:565-580). Each cut writes a VehicleImmobilization event (vehicle_id, causer_id, reason, source_type/source_id, triggered_at) and toggles switch_off_status. The 501-family cut completes asynchronously via the CompleteTracker501Immobilization job after a configurable delay (setting TRACKER_501_IMMOBILIZATION_DELAY_SECONDS, default 90, :689-693).
3.5 Vehicle assets — amortization schedules¶
The Assets menu (can("view","vehicle-expenses")) exposes Amortization Schedules and a Settings page. Routes: VehicleAmortizationController@index/show/writeoff/indexData under prefix vehicle-expenses (fleet.php:169-177), and VehicleExpensesSettingsController@index/update for settings (:175-176).
This is a fleet-local, vehicle-scoped depreciation system, distinct from Book 4 Fixed Assets. VehicleAssetAmortization belongs directly to a Vehicle (vehicle_id FK, VehicleAssetAmortization.php:44-47), and carries asset_type, asset_description, asset_reference_id, asset_reference_type, purchase_cost, purchase_date, salvage_value, total_quantity/remaining_quantity, unit_cost, depreciation_method, useful_life_months, expected_service_distance, status, created_by (:16-31). Period entries are VehicleAssetAmortizationEntry (entries(), :53). A write-off action (amortization-schedules/{id}/writeoff) closes a schedule.
Separately, the Vehicle master row itself carries straight-line-style depreciation fields used by reports (not the amortization schedule): acquisition_price, acquisition_mileage, resale_basis (mileage|years, constants Vehicle.php:73-75), resale_mileage, resale_years, resale_price, depreciation_rate, purchase_type. calculateDepreciationRate() computes (acquisition − resale) / (remaining km | years) (:109-149); depreciationCostForPeriod() and financialPosition() give per-period cost and live book value (:154-273).
3.6 Reports — expenses & mileage; command center¶
VehicleCentreController drives the reports (fleet.php:65-74): Expense Report (expenseReport/expenseReportData) aggregates VehicleCost (the vehicle's expenses() HasMany, Vehicle.php:973) against VehicleRevenue (revenues()); Mileage Report (mileageReport, mileageReportData, mileageReportDailyBreakdown, mileageReportExport) reads telemetry/odometer distance. A per-vehicle drill-down is vehicle-center.show (:73). Current mileage resolves from telemetry when flespi_device_id is set, else from the newest fuel entry's end_shift_mileage (getCurrentMileageAttribute, :374-381; odometer variant currentOdometerMileage(), :184-193).
The Control Centre (VehicleCommandContoller, route vehicle-command-center) plus Exemption Schedules and Custom Schedules (VehicleExemptionSchedule, VehicleCustomSchedule models) govern when automated immobilisation is suppressed or scheduled — the policy layer over the immobilisation mechanics in §3.4. (Route-compliance/geofencing violations that trigger immobilisation are Ch21.)
4. Tables touched & key data¶
| Table | Role | Key columns (verbatim) |
|---|---|---|
vehicles |
master register | license_plate_number (unique), vin (unique), vehicle_type_id, vehicle_model_id, branch_id, driver_id, turn_boy_id, is_trailer, is_truck_cab, garage_status, tracking_device_id, flespi_device_id, device_name, sim_card_number, switch_off_status, onboarding_mileage, acquisition_price/_date, resale_basis/_mileage/_years/_price, depreciation_rate, primary_responsibility |
vehicle_models |
model catalogue | default service_interval, vehicle_service_sequence_id (Vehicle falls back to these) |
vehicle_makes |
make catalogue | — |
vehicle_types |
type catalogue (App\Model\VehicleType) |
— |
vehicle_suppliers |
supplier catalogue | contact + lat/lng (two create migrations: 2024-01-14 and 2025-03-19) |
supplier_vehicle_types |
supplier↔type pivot | — |
tracking_devices |
device-type catalogue | name, on_command, off_command |
device_sim_cards, sim_card_to_devices |
SIM inventory + mapping | — |
vehicle_telematics_data, vehicle_telematics |
raw telemetry stream | mileage, speed, latitude, longitude, timestamp, connection_status (via VehicleLastTelemetry) |
offline_vehicles |
offline-state cache | vehicle_id (HasOne offlineVehicle()) |
cab_trailer_assignments |
active/historic cab↔trailer link | cab_vehicle_id, trailer_vehicle_id, is_active |
cab_trailer_assignment_histories |
assignment audit | cab_vehicle_id, trailer_vehicle_id |
vehicle_immobilizations |
immobilisation events | vehicle_id, causer_id, reason, source_type, source_id, triggered_at, switch_on_date, switch_on_by, time, speed |
vehicle_exemption_schedules, vehicle_custom_schedules |
command-center schedules | — |
vehicle_asset_amortizations + _entries |
fleet-local depreciation schedules | vehicle_id, asset_type, purchase_cost, salvage_value, depreciation_method, useful_life_months, expected_service_distance, remaining_quantity, status |
vehicle_costs, vehicle_revenues, vehicle_center_expense_types |
expense/revenue report source | — |
Misspellings / oddities to note verbatim: the command-center controller class is VehicleCommandContoller (missing an "r"). The immobilization/immobilisation spelling is mixed across code (US immobiliz* in model/table names, UK immobilis* in some method names and route-compliance routes). The Vehicle model lives in the bare App\ namespace (App\Vehicle), while most sibling models live under App\Models.
5. Interactions with other modules¶
Fixed Assets seam (Book 4, Ch16) — the CRITICAL seam. A FixedAsset links to a domain record polymorphically via assetable_type / assetable_id, resolved by the assetable() morphTo (FixedAsset.php:320-322). The set of linkable types is the enum App\Enums\FixedAssetLinkableModel, and Vehicle is one of only three cases — Vehicle = 'App\Vehicle', Device = 'App\Models\Device', PropertyUnit = 'App\Models\PropertyUnit' (FixedAssetLinkableModel.php:14-16). Crucially, Vehicle is the only fully-wired case: only Vehicle has a populated fieldMap() — name <- license_plate_number, serial_no <- vin (FixedAssetLinkableModel.php:37-45); Device and PropertyUnit have empty maps marked TODO. FixedAsset::assetableLabel() special-cases the Vehicle type (FixedAsset.php:363). So when Fixed Assets onboards a vehicle, it copies the plate as the asset name and the VIN as the serial number from this module's vehicles row — making this chapter the operational source of that fixed asset.
Important disambiguation: the fleet Amortization Schedules (vehicle_asset_amortizations, §3.5) are NOT the Fixed-Asset depreciation. VehicleAssetAmortization has NO assetable relation — it belongs to a Vehicle directly. The Vehicle side of the Fixed-Asset seam would be the inverse of FixedAsset::assetable (a morphOne/morphMany back to Vehicle) — see §7 for the confirmation gap on whether the Vehicle model declares that inverse.
Consuming modules (documented in their own chapters, cross-referenced here):
- Fuel (Ch19): fuelEntries() / latestFuelEntry() HasMany to NewFuelEntry (Vehicle.php:358-366); mileage falls back to fuel end_shift_mileage.
- Tyres (Ch20): currentTyreFits(), tyreFits(), tyreMovements(), getCurrentTyres(), hasAllTyresFitted() (Vehicle.php:985-1019); axle_count/tyre_count/VehicleAxleTyreMapping provide the fitment geometry.
- Service / Route-compliance / Geofencing (Ch21): serviceRecords(), serviceIntervals(), serviceSequence() (with model-level fallbacks, :407-441); route-compliance and carton-truck/idle geofencing routes live in the same fleet.php file but immobilise via the mechanics in §3.4.
- Inbound logistics / inspections (Ch22): scopeAvailableForGrnSelection() limits GRN/collection selection to non-garaged vehicles (Vehicle.php:396-400); VehicleInspection* models.
- Sales dispatch (Ch2): deliveries() HasMany DeliverySchedule (:313) and statuses() / getCurrentStatusAttribute (not_assigned vs task comment, :348-356) express whether a vehicle is currently on a delivery task.
- Consumables: getLatestMileageReading() reads ConsumableConsumption / ConsumableIssuance mileage (:1120-1156).
6. Alternatives & variants¶
- Legacy vs modern controller: both
VehicleController.phpandVehicleControllerOld.phpexist; the "Old" file is a superseded implementation of the register. Similarly the Fuel Management sidebar block is fully commented out (fleet.blade.php:777-846) — fuel moved to its own module (Ch19). - Legacy vs modern permission style: the register/live-tracking/command-center leaves still use the legacy
$my_permissions['x___y']checks, while newer leaves (offline/garaged/unallocated, trucks-trailers, assets, reports, tracking-devices) use the moderncan()helper — a partially-migrated authorization surface. - Telemetry vs fuel mileage: vehicles with a
flespi_device_idread live telemetry mileage; vehicles without one fall back to fuel-entryend_shift_mileage(getCurrentMileageAttribute,:374). So an untracked vehicle still has an approximate mileage in reports. - Two/three depreciation representations: the vehicle-row straight-line fields (
depreciation_rate, resale basis) vs theVehicleAssetAmortizationschedule vs Book-4FixedAssetdepreciation — three overlapping representations of "what is this vehicle worth". Reports use the vehicle-row fields; the Assets menu uses the amortization schedules. - Tracker hardware variants: immobilisation command payloads differ per device (
22,501,692,1339) and FMB150 (1339) is special-cased tooutputs2after a Flespi hardware change (Vehicle.php:656-673,828-846) — a hardware-driven branch, not a tenant flag. - Trailers have no independent driver: driver/turnboy for a trailer are always inherited from the paired cab (
getEffectiveDriver()), so trailer-level assignment fields may be null by design.
7. Open questions to confirm¶
CODE-PROVEN¶
- Vehicle master lives in
App\Vehicle(top-level namespace), soft-deletes, activity-logsprimary_responsibility,driver_id,turn_boy_id,branch_id,garage_status(Vehicle.php:57-59,275-287). license_plate_numberandvinare UNIQUE onvehicles(create_vehicles_table.php:16-17).- Cab/trailer are two vehicle rows linked by
CabTrailerAssignment(cab_vehicle_id, trailer_vehicle_id, is_active); trailer availability requires no active cab (Vehicle.php:1022-1088). tracking_devicesis a device-type catalogue withon_command/off_command, and addstracking_device_idFK tovehicles(create_tracking_devices_table.php:14-24).- Immobilisation branches on
tracker->id(22 / 501 / 692 / 1339) and speed-gates viaPendingImmobilization(Vehicle.php:534-735). - Fixed-Asset seam:
FixedAsset::assetable()morphTo;FixedAssetLinkableModel::Vehicle = 'App\Vehicle'is the only case with a non-emptyfieldMap()(name<-license_plate_number,serial_no<-vin) (FixedAssetLinkableModel.php:14-45,FixedAsset.php:320-371). - The fleet Amortization Schedule (
VehicleAssetAmortization) belongs directly toVehicleand is NOT the polymorphic fixed-asset link (VehicleAssetAmortization.php:16-47).
INFERENCE (needs confirmation)¶
- The precise queries defining "Offline", "Garaged" and "Unallocated" lists were not read in full (I read the models/routes, not the three
Fleet\*Controller::indexbodies). Offline is inferred from telemetry-freshness helpers; Garaged fromgarage_status = true; Unallocated from null driver/branch — confirm againstOfflineVehicleController,GaragedVehicleController,UnallocatedVehicleController. - Whether the Vehicle model declares the inverse of the Fixed-Asset morph (e.g. a
fixedAsset()/morphOne(FixedAsset::class,'assetable')method) was not found inVehicle.php; the seam is proven from theFixedAssetside only. Confirm whether Vehicle exposes the inverse relation or whether the link is read only from FixedAsset. - The exact contents of
VehicleCommandContoller,VehicleExpensesSettingsController(which settings keys), and thewriteofflogic were not read — confirm the settings keys and write-off side-effects. - SIM tables
device_sim_cards/sim_card_to_devicesschema and howvehicles-update-simwrites them were not read line-by-line — confirm which column is authoritative (vehicles.sim_card_numbervs the SIM tables). - The
vehicles-overview___listingvsvehicles-overview___viewsplit (register vs map) is taken from the nav; confirm the controller-level authorization matches.
8. Source references¶
bizwiz/resources/views/admin/includes/sidebar_includes/fleet.blade.php:1,82,85,93,101,109,259,267,622,629,637,645,667,689,696,705,714,723,732,739,745,777-846bizwiz/routes/modules/fleet.php:30,65-74,79-86,151-166,169-177bizwiz/routes/modules/api.php:135-136,532bizwiz/app/Vehicle.php:57-103,109-273,275-287,313-366,374-400,443-492,519-527,534-912,914-966,968-1019,1022-1112,1120-1213bizwiz/app/Models/VehicleAssetAmortization.php:16-53bizwiz/app/Models/CabTrailerAssignment.php,CabTrailerAssignmentHistory.php,TrackingDevice.php,OfflineVehicle.php,VehicleLastTelemetry.php,VehicleImmobilization.php,VehicleAssetAmortizationEntry.phpbizwiz/app/Enums/FixedAssetLinkableModel.php:14-45bizwiz/app/Models/FixedAsset.php:21-22,295-377bizwiz/app/Http/Controllers/Admin/:VehicleController.php,VehicleControllerOld.php,CabTrailerAssignmentController.php,TrackingDevicesController.php,VehicleAmortizationController.php,VehicleExpensesSettingsController.php,VehicleCentreController.php,VehicleCommandContoller.php,Fleet/{Offline,Garaged,Unallocated}VehicleController.php,VehicleUtils.phpbizwiz/database/migrations/:2023_11_29_132911_create_vehicles_table.php,2025_02_22_125352_create_tracking_devices_table.php,2024_11_15_100313_create_device_sim_cards_table.php,2024_11_15_101011_create_sim_card_to_devices_table.php,2025_03_14_124249_create_offline_vehicles_table.php,2024_06_20_133631_create_vehicle_immobilizations_table.php,2024_07_15_153345_create_vehicle_exemption_schedules_table.php,2024_07_28_113703_create_vehicle_custom_schedules_table.php,2025_06_09_090038_create_vehicle_costs_table.php,2025_04_13_100739_create_vehicle_center_expense_types_table.php