@fleetbase/fleetops-engine 0.6.51 → 0.6.53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -2
- package/addon/components/cell/telematic-provider.hbs +16 -0
- package/addon/components/cell/telematic-provider.js +36 -0
- package/addon/components/cell/telematic-status.hbs +1 -0
- package/addon/components/cell/telematic-status.js +39 -0
- package/addon/components/device/manager.hbs +5 -6
- package/addon/components/device/manager.js +12 -15
- package/addon/components/driver/details.hbs +1 -1
- package/addon/components/fleet/vehicle-listing.js +1 -0
- package/addon/components/fuel-integration/form.hbs +200 -0
- package/addon/components/fuel-integration/form.js +242 -0
- package/addon/components/fuel-integration/hub.hbs +154 -0
- package/addon/components/fuel-integration/hub.js +165 -0
- package/addon/components/fuel-integration/matching-priority.hbs +76 -0
- package/addon/components/fuel-integration/matching-priority.js +145 -0
- package/addon/components/fuel-report/details.hbs +13 -1
- package/addon/components/issue/details.hbs +3 -57
- package/addon/components/issue/details.js +0 -96
- package/addon/components/layout/fleet-ops-sidebar/operations-monitor.hbs +201 -0
- package/addon/components/layout/fleet-ops-sidebar/operations-monitor.js +589 -0
- package/addon/components/layout/fleet-ops-sidebar.hbs +19 -233
- package/addon/components/layout/fleet-ops-sidebar.js +287 -376
- package/addon/components/maintenance-schedule/form.js +1 -0
- package/addon/components/map/drawer/device-event-listing.hbs +12 -2
- package/addon/components/map/drawer/driver-listing.hbs +14 -1
- package/addon/components/map/drawer/place-listing.hbs +14 -1
- package/addon/components/map/drawer/position-listing.hbs +12 -2
- package/addon/components/map/drawer/vehicle-listing.hbs +14 -1
- package/addon/components/modals/assigned-orders.hbs +40 -0
- package/addon/components/modals/attach-device.hbs +4 -3
- package/addon/components/modals/attach-telematic-device.hbs +25 -0
- package/addon/components/modals/attach-telematic-device.js +3 -0
- package/addon/components/modals/driver-assign-order.hbs +7 -58
- package/addon/components/modals/driver-assign-vehicle.hbs +10 -2
- package/addon/components/modals/fleet-assign-driver.hbs +18 -0
- package/addon/components/modals/fleet-assign-driver.js +3 -0
- package/addon/components/modals/fleet-assign-vehicle.hbs +18 -0
- package/addon/components/modals/fleet-assign-vehicle.js +3 -0
- package/addon/components/modals/telematic-connection-diagnostics.hbs +75 -0
- package/addon/components/modals/telematic-connection-diagnostics.js +287 -0
- package/addon/components/modals/vehicle-details.hbs +6 -1
- package/addon/components/modals/vehicle-form.hbs +8 -1
- package/addon/components/order/card.hbs +106 -0
- package/addon/components/order/card.js +257 -0
- package/addon/components/order/form/payload.js +3 -1
- package/addon/components/order/form/service-rate.hbs +2 -0
- package/addon/components/service-rate/form.hbs +3 -2
- package/addon/components/telematic/details.hbs +98 -87
- package/addon/components/telematic/details.js +230 -1
- package/addon/components/telematic/form.hbs +303 -72
- package/addon/components/telematic/form.js +519 -3
- package/addon/components/telematic/hub.hbs +149 -0
- package/addon/components/telematic/hub.js +142 -0
- package/addon/components/telematic/settings.hbs +152 -0
- package/addon/components/telematic/settings.js +45 -0
- package/addon/components/telematic/tab-empty-state.hbs +29 -0
- package/addon/components/telematic/tab-empty-state.js +33 -0
- package/addon/components/vehicle/details.hbs +6 -1
- package/addon/components/vehicle/form.hbs +2 -1
- package/addon/components/widget/fuel-providers.hbs +43 -0
- package/addon/components/widget/fuel-providers.js +27 -0
- package/addon/controllers/connectivity/devices/index/details.js +27 -1
- package/addon/controllers/connectivity/devices/index.js +18 -1
- package/addon/controllers/connectivity/fuel-providers/details/sync.js +18 -0
- package/addon/controllers/connectivity/fuel-providers/details/transactions.js +24 -0
- package/addon/controllers/connectivity/fuel-providers/details.js +69 -0
- package/addon/controllers/connectivity/fuel-providers/edit.js +24 -0
- package/addon/controllers/connectivity/fuel-providers/index.js +177 -0
- package/addon/controllers/connectivity/fuel-providers/new.js +37 -0
- package/addon/controllers/connectivity/telematics/details/attachments.js +247 -0
- package/addon/controllers/connectivity/telematics/details/devices.js +368 -0
- package/addon/controllers/connectivity/telematics/details/events.js +244 -0
- package/addon/controllers/connectivity/telematics/details/index.js +3 -0
- package/addon/controllers/connectivity/telematics/details/logs.js +43 -0
- package/addon/controllers/connectivity/telematics/details/sensors.js +270 -0
- package/addon/controllers/connectivity/telematics/details.js +149 -0
- package/addon/controllers/connectivity/telematics/{index/edit.js → edit.js} +15 -4
- package/addon/controllers/connectivity/telematics/index.js +25 -5
- package/addon/controllers/connectivity/telematics/{index/new.js → new.js} +8 -2
- package/addon/controllers/maintenance/index.js +100 -0
- package/addon/controllers/management/drivers/index/details.js +78 -1
- package/addon/controllers/management/drivers/index.js +39 -0
- package/addon/controllers/management/fleets/index/details.js +23 -1
- package/addon/controllers/management/fleets/index.js +6 -1
- package/addon/controllers/management/fuel-reports/index.js +37 -1
- package/addon/controllers/management/fuel-transactions/index/details.js +70 -0
- package/addon/controllers/management/fuel-transactions/index.js +240 -0
- package/addon/controllers/management/index.js +88 -0
- package/addon/controllers/management/vehicles/index/details.js +32 -0
- package/addon/controllers/management/vehicles/index.js +26 -0
- package/addon/controllers/operations/orders/index.js +4 -0
- package/addon/controllers/settings/index.js +142 -0
- package/addon/controllers/settings/payments/index.js +5 -0
- package/addon/extension.js +31 -0
- package/addon/routes/analytics/index.js +3 -0
- package/addon/routes/connectivity/devices/index.js +3 -0
- package/addon/routes/connectivity/fuel-providers/details/index.js +7 -0
- package/addon/routes/connectivity/fuel-providers/details/matching.js +7 -0
- package/addon/routes/connectivity/fuel-providers/details/settings.js +7 -0
- package/addon/routes/connectivity/fuel-providers/details/sync.js +18 -0
- package/addon/routes/connectivity/fuel-providers/details/transactions.js +14 -0
- package/addon/routes/connectivity/fuel-providers/details.js +18 -0
- package/addon/routes/connectivity/fuel-providers/edit.js +18 -0
- package/addon/routes/connectivity/fuel-providers/index.js +20 -0
- package/addon/routes/connectivity/fuel-providers/new.js +3 -0
- package/addon/routes/connectivity/fuel-providers.js +3 -0
- package/addon/routes/connectivity/telematics/details/attachments.js +28 -0
- package/addon/routes/connectivity/telematics/details/devices.js +30 -0
- package/addon/routes/connectivity/telematics/details/events.js +33 -0
- package/addon/routes/connectivity/telematics/details/index.js +3 -0
- package/addon/routes/connectivity/telematics/details/logs.js +17 -0
- package/addon/routes/connectivity/telematics/details/sensors.js +29 -0
- package/addon/routes/connectivity/telematics/{index/details.js → details.js} +1 -1
- package/addon/routes/connectivity/telematics/{index/edit.js → edit.js} +1 -1
- package/addon/routes/connectivity/telematics/new.js +3 -0
- package/addon/routes/maintenance/index.js +3 -0
- package/addon/routes/maintenance/work-orders/index.js +2 -0
- package/addon/routes/management/drivers/index/details/activity.js +3 -0
- package/addon/routes/management/fuel-reports/index.js +2 -0
- package/addon/routes/management/fuel-transactions/index/details.js +18 -0
- package/addon/routes/management/fuel-transactions/index.js +21 -0
- package/addon/routes/management/fuel-transactions.js +3 -0
- package/addon/routes/settings/index.js +3 -0
- package/addon/routes.js +28 -9
- package/addon/services/device-actions.js +64 -1
- package/addon/services/device-event-actions.js +12 -1
- package/addon/services/driver-actions.js +147 -11
- package/addon/services/fleet-actions.js +66 -1
- package/addon/services/fuel-integration-actions.js +31 -0
- package/addon/services/issue-actions.js +1 -1
- package/addon/services/telematic-actions.js +9 -3
- package/addon/services/vehicle-actions.js +125 -0
- package/addon/styles/fleetops-engine.css +2237 -162
- package/addon/templates/analytics/index.hbs +14 -0
- package/addon/templates/analytics/reports/index.hbs +19 -1
- package/addon/templates/connectivity/devices/index.hbs +19 -1
- package/addon/templates/connectivity/events/index.hbs +16 -1
- package/addon/templates/connectivity/fuel-providers/details/index.hbs +38 -0
- package/addon/templates/connectivity/fuel-providers/details/matching.hbs +13 -0
- package/addon/templates/connectivity/fuel-providers/details/settings.hbs +11 -0
- package/addon/templates/connectivity/fuel-providers/details/sync.hbs +48 -0
- package/addon/templates/connectivity/fuel-providers/details/transactions.hbs +21 -0
- package/addon/templates/connectivity/fuel-providers/details.hbs +51 -0
- package/addon/templates/connectivity/fuel-providers/edit.hbs +24 -0
- package/addon/templates/connectivity/fuel-providers/index.hbs +12 -0
- package/addon/templates/connectivity/fuel-providers/new.hbs +22 -0
- package/addon/templates/connectivity/fuel-providers.hbs +1 -0
- package/addon/templates/connectivity/sensors/index.hbs +19 -1
- package/addon/templates/connectivity/telematics/details/attachments.hbs +163 -0
- package/addon/templates/connectivity/telematics/details/devices.hbs +88 -0
- package/addon/templates/connectivity/telematics/details/events.hbs +101 -0
- package/addon/templates/connectivity/telematics/{index/details → details}/index.hbs +0 -1
- package/addon/templates/connectivity/telematics/details/logs.hbs +69 -0
- package/addon/templates/connectivity/telematics/details/sensors.hbs +88 -0
- package/addon/templates/connectivity/telematics/details.hbs +53 -0
- package/addon/templates/connectivity/telematics/edit.hbs +27 -0
- package/addon/templates/connectivity/telematics/index.hbs +6 -8
- package/addon/templates/connectivity/telematics/new.hbs +24 -0
- package/addon/templates/maintenance/equipment/index.hbs +19 -1
- package/addon/templates/maintenance/index.hbs +113 -0
- package/addon/templates/maintenance/maintenances/index.hbs +15 -1
- package/addon/templates/maintenance/parts/index.hbs +19 -1
- package/addon/templates/maintenance/schedules/index.hbs +19 -1
- package/addon/templates/maintenance/work-orders/index.hbs +19 -1
- package/addon/templates/management/contacts/customers.hbs +15 -1
- package/addon/templates/management/contacts/index.hbs +19 -1
- package/addon/templates/management/drivers/index/details/activity.hbs +1 -0
- package/addon/templates/management/drivers/index.hbs +19 -1
- package/addon/templates/management/fleets/index.hbs +19 -1
- package/addon/templates/management/fuel-reports/index.hbs +19 -1
- package/addon/templates/management/fuel-transactions/index/details.hbs +73 -0
- package/addon/templates/management/fuel-transactions/index.hbs +58 -0
- package/addon/templates/management/fuel-transactions.hbs +1 -0
- package/addon/templates/management/index.hbs +109 -73
- package/addon/templates/management/issues/index.hbs +19 -1
- package/addon/templates/management/places/index.hbs +19 -1
- package/addon/templates/management/vehicles/index.hbs +19 -1
- package/addon/templates/management/vendors/index.hbs +19 -1
- package/addon/templates/management/vendors/integrated.hbs +13 -1
- package/addon/templates/operations/orders/index.hbs +19 -1
- package/addon/templates/operations/service-rates/index.hbs +19 -1
- package/addon/templates/settings/index.hbs +83 -0
- package/addon/templates/settings/payments/index.hbs +15 -1
- package/addon/templates/settings/routing.hbs +2 -2
- package/addon/utils/fleet-ops-options.js +3 -0
- package/app/components/cell/telematic-provider.js +1 -0
- package/app/components/cell/telematic-status.js +1 -0
- package/app/components/fuel-integration/form.js +1 -0
- package/app/components/fuel-integration/hub.js +1 -0
- package/app/components/fuel-integration/matching-priority.js +1 -0
- package/app/components/modals/assigned-orders.js +1 -0
- package/app/components/modals/attach-telematic-device.js +1 -0
- package/app/components/modals/fleet-assign-driver.js +1 -0
- package/app/components/modals/fleet-assign-vehicle.js +1 -0
- package/app/components/modals/telematic-connection-diagnostics.js +1 -0
- package/app/components/order/card.js +1 -0
- package/app/components/telematic/hub.js +1 -0
- package/app/components/telematic/settings.js +1 -0
- package/app/components/telematic/tab-empty-state.js +1 -0
- package/app/components/widget/fuel-providers.js +1 -0
- package/app/controllers/connectivity/fuel-providers/details/sync.js +1 -0
- package/app/controllers/connectivity/{telematics/index/details/devices.js → fuel-providers/details/transactions.js} +1 -1
- package/app/controllers/connectivity/{telematics/index → fuel-providers}/details.js +1 -1
- package/app/controllers/connectivity/{telematics/index → fuel-providers}/edit.js +1 -1
- package/app/controllers/connectivity/{telematics/index/details → fuel-providers}/index.js +1 -1
- package/app/controllers/connectivity/{telematics/index → fuel-providers}/new.js +1 -1
- package/app/controllers/connectivity/telematics/details/attachments.js +1 -0
- package/app/controllers/connectivity/telematics/details/devices.js +1 -0
- package/app/controllers/connectivity/telematics/details/events.js +1 -0
- package/app/controllers/connectivity/telematics/details/index.js +1 -0
- package/app/controllers/connectivity/telematics/details/logs.js +1 -0
- package/app/controllers/connectivity/telematics/details/sensors.js +1 -0
- package/app/controllers/connectivity/telematics/details.js +1 -0
- package/app/controllers/connectivity/telematics/edit.js +1 -0
- package/app/controllers/connectivity/telematics/new.js +1 -0
- package/app/controllers/maintenance/index.js +1 -0
- package/app/controllers/management/fuel-transactions/index/details.js +1 -0
- package/app/controllers/management/fuel-transactions/index.js +1 -0
- package/app/controllers/management/index.js +1 -0
- package/app/controllers/settings/index.js +1 -0
- package/app/routes/analytics/index.js +1 -0
- package/app/routes/connectivity/{telematics/index → fuel-providers}/details/index.js +1 -1
- package/app/routes/connectivity/{telematics/index/details/events.js → fuel-providers/details/matching.js} +1 -1
- package/app/routes/connectivity/fuel-providers/details/settings.js +1 -0
- package/app/routes/connectivity/fuel-providers/details/sync.js +1 -0
- package/app/routes/connectivity/{telematics/index/details/devices.js → fuel-providers/details/transactions.js} +1 -1
- package/app/routes/connectivity/{telematics/index → fuel-providers}/details.js +1 -1
- package/app/routes/connectivity/{telematics/index → fuel-providers}/edit.js +1 -1
- package/app/routes/connectivity/fuel-providers/index.js +1 -0
- package/app/routes/connectivity/{telematics/index → fuel-providers}/new.js +1 -1
- package/app/routes/connectivity/fuel-providers.js +1 -0
- package/app/routes/connectivity/telematics/details/attachments.js +1 -0
- package/app/routes/connectivity/telematics/details/devices.js +1 -0
- package/app/routes/connectivity/telematics/details/events.js +1 -0
- package/app/routes/connectivity/telematics/details/index.js +1 -0
- package/app/routes/connectivity/telematics/details/logs.js +1 -0
- package/app/routes/connectivity/telematics/details/sensors.js +1 -0
- package/app/routes/connectivity/telematics/details.js +1 -0
- package/app/routes/connectivity/telematics/edit.js +1 -0
- package/app/routes/connectivity/telematics/new.js +1 -0
- package/app/routes/maintenance/index.js +1 -0
- package/app/routes/management/drivers/index/details/activity.js +1 -0
- package/app/routes/management/fuel-transactions/index/details.js +1 -0
- package/app/routes/management/fuel-transactions/index.js +1 -0
- package/app/routes/management/fuel-transactions.js +1 -0
- package/app/routes/settings/index.js +1 -0
- package/app/services/fuel-integration-actions.js +1 -0
- package/app/templates/analytics/index.js +1 -0
- package/app/templates/connectivity/{telematics/index → fuel-providers}/details/index.js +1 -1
- package/app/templates/connectivity/{telematics/index/details/events.js → fuel-providers/details/matching.js} +1 -1
- package/app/templates/connectivity/fuel-providers/details/settings.js +1 -0
- package/app/templates/connectivity/fuel-providers/details/sync.js +1 -0
- package/app/templates/connectivity/{telematics/index/details/devices.js → fuel-providers/details/transactions.js} +1 -1
- package/app/templates/connectivity/{telematics/index → fuel-providers}/details.js +1 -1
- package/app/templates/connectivity/{telematics/index → fuel-providers}/edit.js +1 -1
- package/app/templates/connectivity/fuel-providers/index.js +1 -0
- package/app/templates/connectivity/{telematics/index → fuel-providers}/new.js +1 -1
- package/app/templates/connectivity/fuel-providers.js +1 -0
- package/app/templates/connectivity/telematics/details/attachments.js +1 -0
- package/app/templates/connectivity/telematics/details/devices.js +1 -0
- package/app/templates/connectivity/telematics/details/events.js +1 -0
- package/app/templates/connectivity/telematics/details/index.js +1 -0
- package/app/templates/connectivity/telematics/details/logs.js +1 -0
- package/app/templates/connectivity/telematics/details/sensors.js +1 -0
- package/app/templates/connectivity/telematics/details.js +1 -0
- package/app/templates/connectivity/telematics/edit.js +1 -0
- package/app/templates/connectivity/telematics/new.js +1 -0
- package/app/templates/maintenance/index.js +1 -0
- package/app/templates/management/drivers/index/details/activity.js +1 -0
- package/app/templates/management/fuel-transactions/index/details.js +1 -0
- package/app/templates/management/fuel-transactions/index.js +1 -0
- package/app/templates/management/fuel-transactions.js +1 -0
- package/app/templates/management/index.js +1 -0
- package/app/templates/settings/index.js +1 -0
- package/assets/images/telematics/providers/afaqy.webp +0 -0
- package/assets/images/telematics/providers/default.webp +0 -0
- package/assets/images/telematics/providers/flespi.webp +0 -0
- package/assets/images/telematics/providers/geotab.webp +0 -0
- package/assets/images/telematics/providers/safee.webp +0 -0
- package/assets/images/telematics/providers/samsara.webp +0 -0
- package/composer.json +1 -1
- package/extension.json +1 -1
- package/package.json +4 -4
- package/server/config/fuel-providers.php +42 -0
- package/server/config/telematics.php +139 -130
- package/server/migrations/2026_06_06_000001_harden_device_events_telematics_contract.php +59 -0
- package/server/migrations/2026_06_08_000001_create_fuel_provider_connections_table.php +37 -0
- package/server/migrations/2026_06_08_000002_create_fuel_provider_transactions_table.php +53 -0
- package/server/migrations/2026_06_08_000003_create_fuel_provider_sync_runs_table.php +40 -0
- package/server/migrations/2026_06_10_000001_add_fuel_card_number_to_vehicles_table.php +25 -0
- package/server/migrations/2026_06_10_000002_add_vehicle_identity_columns_to_fuel_provider_transactions_table.php +39 -0
- package/server/migrations/2026_06_15_000001_normalize_device_attachable_vehicle_morph_types.php +30 -0
- package/server/src/Console/Commands/FixInvalidPolymorphicRelationTypeNamespaces.php +1 -0
- package/server/src/Contracts/FuelProvider.php +30 -0
- package/server/src/Contracts/TelematicProviderDescriptor.php +3 -1
- package/server/src/Events/FuelProviderTransactionImported.php +17 -0
- package/server/src/Events/FuelProviderTransactionMatched.php +17 -0
- package/server/src/Events/FuelProviderTransactionUnmatched.php +17 -0
- package/server/src/Events/FuelReportCreatedFromProvider.php +18 -0
- package/server/src/Http/Controllers/Internal/v1/AnalyticsController.php +6 -0
- package/server/src/Http/Controllers/Internal/v1/DeviceController.php +140 -2
- package/server/src/Http/Controllers/Internal/v1/DeviceEventController.php +44 -0
- package/server/src/Http/Controllers/Internal/v1/DriverController.php +158 -7
- package/server/src/Http/Controllers/Internal/v1/FuelProviderConnectionController.php +124 -0
- package/server/src/Http/Controllers/Internal/v1/FuelProviderSyncRunController.php +10 -0
- package/server/src/Http/Controllers/Internal/v1/FuelProviderTransactionController.php +76 -0
- package/server/src/Http/Controllers/Internal/v1/HubController.php +300 -0
- package/server/src/Http/Controllers/Internal/v1/SearchController.php +506 -0
- package/server/src/Http/Controllers/Internal/v1/SensorController.php +1 -1
- package/server/src/Http/Controllers/Internal/v1/TelematicController.php +179 -16
- package/server/src/Http/Controllers/Internal/v1/VehicleController.php +249 -0
- package/server/src/Http/Controllers/TelematicWebhookController.php +103 -19
- package/server/src/Http/Filter/DeviceFilter.php +74 -0
- package/server/src/Http/Filter/DriverFilter.php +6 -0
- package/server/src/Http/Filter/FuelProviderConnectionFilter.php +33 -0
- package/server/src/Http/Filter/FuelProviderSyncRunFilter.php +28 -0
- package/server/src/Http/Filter/FuelProviderTransactionFilter.php +59 -0
- package/server/src/Http/Filter/FuelReportFilter.php +10 -0
- package/server/src/Http/Filter/VehicleFilter.php +6 -0
- package/server/src/Http/Resources/v1/Driver.php +15 -0
- package/server/src/Http/Resources/v1/FuelProviderConnection.php +30 -0
- package/server/src/Http/Resources/v1/FuelProviderSyncRun.php +36 -0
- package/server/src/Http/Resources/v1/FuelProviderTransaction.php +54 -0
- package/server/src/Http/Resources/v1/FuelReport.php +28 -22
- package/server/src/Http/Resources/v1/Index/Driver.php +26 -20
- package/server/src/Http/Resources/v1/Index/Vehicle.php +29 -22
- package/server/src/Http/Resources/v1/Vehicle.php +17 -0
- package/server/src/Http/Resources/v1/VehicleWithoutDriver.php +2 -0
- package/server/src/Jobs/SyncFuelProviderTransactionsJob.php +57 -0
- package/server/src/Jobs/SyncTelematicDevicesJob.php +105 -17
- package/server/src/Jobs/TestTelematicConnectionJob.php +9 -22
- package/server/src/Models/Asset.php +2 -1
- package/server/src/Models/Contact.php +2 -1
- package/server/src/Models/Device.php +27 -4
- package/server/src/Models/DeviceEvent.php +40 -3
- package/server/src/Models/Driver.php +3 -2
- package/server/src/Models/Equipment.php +2 -1
- package/server/src/Models/Fleet.php +2 -1
- package/server/src/Models/FuelProviderConnection.php +60 -0
- package/server/src/Models/FuelProviderSyncRun.php +58 -0
- package/server/src/Models/FuelProviderTransaction.php +119 -0
- package/server/src/Models/FuelReport.php +16 -1
- package/server/src/Models/Part.php +2 -1
- package/server/src/Models/Sensor.php +21 -4
- package/server/src/Models/ServiceRate.php +39 -2
- package/server/src/Models/Vehicle.php +14 -2
- package/server/src/Models/Vendor.php +2 -1
- package/server/src/Providers/FleetOpsServiceProvider.php +20 -0
- package/server/src/Support/Analytics/FuelProviderSummary.php +42 -0
- package/server/src/Support/FuelProviders/FuelProviderDescriptor.php +55 -0
- package/server/src/Support/FuelProviders/FuelProviderRegistry.php +75 -0
- package/server/src/Support/FuelProviders/FuelProviderService.php +447 -0
- package/server/src/Support/FuelProviders/Providers/AbstractFuelProvider.php +98 -0
- package/server/src/Support/FuelProviders/Providers/PetroAppFuelProvider.php +167 -0
- package/server/src/Support/Telematics/Providers/AbstractProvider.php +27 -6
- package/server/src/Support/Telematics/Providers/AfaqyProvider.php +105 -38
- package/server/src/Support/Telematics/Providers/FlespiProvider.php +1 -0
- package/server/src/Support/Telematics/Providers/GeotabProvider.php +1 -0
- package/server/src/Support/Telematics/Providers/SafeeProvider.php +32 -22
- package/server/src/Support/Telematics/Providers/SamsaraProvider.php +3 -1
- package/server/src/Support/Telematics/TelematicService.php +340 -21
- package/server/src/routes.php +50 -4
- package/server/tests/FuelProviderRegistryTest.php +416 -0
- package/server/tests/HubRoutesTest.php +62 -0
- package/server/tests/ServiceRateAlgorithmWeightVariablesTest.php +44 -0
- package/server/tests/TelematicsHardeningTest.php +359 -0
- package/server/tests/VehicleDriverAssignmentTest.php +51 -0
- package/translations/ar-ae.yml +23 -1
- package/translations/bg-bg.yaml +72 -0
- package/translations/en-us.yaml +83 -0
- package/translations/es-pa.yaml +72 -0
- package/translations/fr-fr.yaml +72 -0
- package/translations/mn-mn.yaml +72 -0
- package/translations/pt-br.yaml +72 -0
- package/translations/ru-ru.yaml +72 -0
- package/translations/vi-vn.yaml +98 -1
- package/addon/controllers/connectivity/telematics/index/details/devices.js +0 -3
- package/addon/controllers/connectivity/telematics/index/details/events.js +0 -3
- package/addon/controllers/connectivity/telematics/index/details/index.js +0 -3
- package/addon/controllers/connectivity/telematics/index/details/sensors.js +0 -3
- package/addon/controllers/connectivity/telematics/index/details.js +0 -24
- package/addon/routes/connectivity/telematics/index/details/devices.js +0 -3
- package/addon/routes/connectivity/telematics/index/details/events.js +0 -3
- package/addon/routes/connectivity/telematics/index/details/index.js +0 -3
- package/addon/routes/connectivity/telematics/index/details/sensors.js +0 -3
- package/addon/routes/connectivity/telematics/index/new.js +0 -3
- package/addon/templates/connectivity/telematics/index/details/devices.hbs +0 -1
- package/addon/templates/connectivity/telematics/index/details/events.hbs +0 -1
- package/addon/templates/connectivity/telematics/index/details/sensors.hbs +0 -1
- package/addon/templates/connectivity/telematics/index/details.hbs +0 -14
- package/addon/templates/connectivity/telematics/index/edit.hbs +0 -12
- package/addon/templates/connectivity/telematics/index/new.hbs +0 -12
- package/app/controllers/connectivity/telematics/index/details/events.js +0 -1
- package/app/controllers/connectivity/telematics/index/details/sensors.js +0 -1
- package/app/routes/connectivity/telematics/index/details/sensors.js +0 -1
- package/app/templates/connectivity/telematics/index/details/sensors.js +0 -1
package/server/migrations/2026_06_15_000001_normalize_device_attachable_vehicle_morph_types.php
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
use Fleetbase\FleetOps\Models\Vehicle;
|
|
4
|
+
use Illuminate\Database\Migrations\Migration;
|
|
5
|
+
use Illuminate\Support\Facades\DB;
|
|
6
|
+
use Illuminate\Support\Facades\Schema;
|
|
7
|
+
|
|
8
|
+
return new class extends Migration {
|
|
9
|
+
public function up(): void
|
|
10
|
+
{
|
|
11
|
+
if (!Schema::hasTable('devices') || !Schema::hasColumn('devices', 'attachable_type') || !Schema::hasColumn('devices', 'attachable_uuid')) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
DB::table('devices')
|
|
16
|
+
->whereNotNull('attachable_uuid')
|
|
17
|
+
->whereIn('attachable_type', [
|
|
18
|
+
'Fleetbase\\Models\\Vehicle',
|
|
19
|
+
'\\Fleetbase\\Models\\Vehicle',
|
|
20
|
+
])
|
|
21
|
+
->update([
|
|
22
|
+
'attachable_type' => Vehicle::class,
|
|
23
|
+
]);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public function down(): void
|
|
27
|
+
{
|
|
28
|
+
// Intentionally do not restore invalid legacy morph class names.
|
|
29
|
+
}
|
|
30
|
+
};
|
|
@@ -37,6 +37,7 @@ class FixInvalidPolymorphicRelationTypeNamespaces extends Command
|
|
|
37
37
|
['model' => \Fleetbase\FleetOps\Models\Place::class, 'columns' => ['owner_type']],
|
|
38
38
|
['model' => \Fleetbase\FleetOps\Models\Entity::class, 'columns' => ['customer_type']],
|
|
39
39
|
['model' => \Fleetbase\FleetOps\Models\PurchaseRate::class, 'columns' => ['customer_type']],
|
|
40
|
+
['model' => \Fleetbase\FleetOps\Models\Device::class, 'columns' => ['attachable_type']],
|
|
40
41
|
];
|
|
41
42
|
|
|
42
43
|
foreach ($models as $modelConfig) {
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\FleetOps\Contracts;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\FleetOps\Models\FuelProviderConnection;
|
|
6
|
+
use Illuminate\Support\Carbon;
|
|
7
|
+
use Illuminate\Support\Collection;
|
|
8
|
+
|
|
9
|
+
interface FuelProvider
|
|
10
|
+
{
|
|
11
|
+
public function key(): string;
|
|
12
|
+
|
|
13
|
+
public function name(): string;
|
|
14
|
+
|
|
15
|
+
public function authenticate(FuelProviderConnection $connection): array;
|
|
16
|
+
|
|
17
|
+
public function testConnection(FuelProviderConnection $connection): array;
|
|
18
|
+
|
|
19
|
+
public function listVehicles(FuelProviderConnection $connection, array $options = []): Collection;
|
|
20
|
+
|
|
21
|
+
public function listTransactions(FuelProviderConnection $connection, Carbon $from, Carbon $to, array $options = []): Collection;
|
|
22
|
+
|
|
23
|
+
public function listStations(FuelProviderConnection $connection, array $options = []): Collection;
|
|
24
|
+
|
|
25
|
+
public function pushTrip(FuelProviderConnection $connection, array $trip): array;
|
|
26
|
+
|
|
27
|
+
public function syncVehicle(FuelProviderConnection $connection, array $vehicle): array;
|
|
28
|
+
|
|
29
|
+
public function webhookPayloadToTransaction(FuelProviderConnection $connection, array $payload): ?array;
|
|
30
|
+
}
|
|
@@ -12,6 +12,8 @@ use Fleetbase\FleetOps\Support\Utils;
|
|
|
12
12
|
*/
|
|
13
13
|
class TelematicProviderDescriptor
|
|
14
14
|
{
|
|
15
|
+
public const DEFAULT_ICON = '/engines-dist/images/telematics/providers/default.webp';
|
|
16
|
+
|
|
15
17
|
public string $key;
|
|
16
18
|
public string $label;
|
|
17
19
|
public string $type; // 'native' or 'custom'
|
|
@@ -33,7 +35,7 @@ class TelematicProviderDescriptor
|
|
|
33
35
|
$this->label = $data['label'];
|
|
34
36
|
$this->type = $data['type'] ?? 'native';
|
|
35
37
|
$this->driverClass = $data['driver_class'] ?? null;
|
|
36
|
-
$this->icon = $data['icon'] ??
|
|
38
|
+
$this->icon = $data['icon'] ?? self::DEFAULT_ICON;
|
|
37
39
|
$this->description = $data['description'] ?? null;
|
|
38
40
|
$this->docsUrl = $data['docs_url'] ?? null;
|
|
39
41
|
$this->requiredFields = $data['required_fields'] ?? [];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\FleetOps\Events;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\FleetOps\Models\FuelProviderTransaction;
|
|
6
|
+
use Illuminate\Foundation\Events\Dispatchable;
|
|
7
|
+
use Illuminate\Queue\SerializesModels;
|
|
8
|
+
|
|
9
|
+
class FuelProviderTransactionImported
|
|
10
|
+
{
|
|
11
|
+
use Dispatchable;
|
|
12
|
+
use SerializesModels;
|
|
13
|
+
|
|
14
|
+
public function __construct(public FuelProviderTransaction $transaction)
|
|
15
|
+
{
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\FleetOps\Events;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\FleetOps\Models\FuelProviderTransaction;
|
|
6
|
+
use Illuminate\Foundation\Events\Dispatchable;
|
|
7
|
+
use Illuminate\Queue\SerializesModels;
|
|
8
|
+
|
|
9
|
+
class FuelProviderTransactionMatched
|
|
10
|
+
{
|
|
11
|
+
use Dispatchable;
|
|
12
|
+
use SerializesModels;
|
|
13
|
+
|
|
14
|
+
public function __construct(public FuelProviderTransaction $transaction)
|
|
15
|
+
{
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\FleetOps\Events;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\FleetOps\Models\FuelProviderTransaction;
|
|
6
|
+
use Illuminate\Foundation\Events\Dispatchable;
|
|
7
|
+
use Illuminate\Queue\SerializesModels;
|
|
8
|
+
|
|
9
|
+
class FuelProviderTransactionUnmatched
|
|
10
|
+
{
|
|
11
|
+
use Dispatchable;
|
|
12
|
+
use SerializesModels;
|
|
13
|
+
|
|
14
|
+
public function __construct(public FuelProviderTransaction $transaction)
|
|
15
|
+
{
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\FleetOps\Events;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\FleetOps\Models\FuelProviderTransaction;
|
|
6
|
+
use Fleetbase\FleetOps\Models\FuelReport;
|
|
7
|
+
use Illuminate\Foundation\Events\Dispatchable;
|
|
8
|
+
use Illuminate\Queue\SerializesModels;
|
|
9
|
+
|
|
10
|
+
class FuelReportCreatedFromProvider
|
|
11
|
+
{
|
|
12
|
+
use Dispatchable;
|
|
13
|
+
use SerializesModels;
|
|
14
|
+
|
|
15
|
+
public function __construct(public FuelProviderTransaction $transaction, public FuelReport $fuelReport)
|
|
16
|
+
{
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -4,6 +4,7 @@ namespace Fleetbase\FleetOps\Http\Controllers\Internal\v1;
|
|
|
4
4
|
|
|
5
5
|
use Fleetbase\FleetOps\Support\Analytics\AbstractAnalytics;
|
|
6
6
|
use Fleetbase\FleetOps\Support\Analytics\FuelEfficiency;
|
|
7
|
+
use Fleetbase\FleetOps\Support\Analytics\FuelProviderSummary;
|
|
7
8
|
use Fleetbase\FleetOps\Support\Analytics\GeofenceViolations;
|
|
8
9
|
use Fleetbase\FleetOps\Support\Analytics\IssuesInsights;
|
|
9
10
|
use Fleetbase\FleetOps\Support\Analytics\LiveFleet;
|
|
@@ -64,6 +65,11 @@ class AnalyticsController extends Controller
|
|
|
64
65
|
return $this->run($request, FuelEfficiency::class, defaultDays: 90);
|
|
65
66
|
}
|
|
66
67
|
|
|
68
|
+
public function fuelProviders(Request $request)
|
|
69
|
+
{
|
|
70
|
+
return $this->run($request, FuelProviderSummary::class, defaultDays: 30);
|
|
71
|
+
}
|
|
72
|
+
|
|
67
73
|
public function issuesInsights(Request $request)
|
|
68
74
|
{
|
|
69
75
|
return $this->run($request, IssuesInsights::class);
|
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
namespace Fleetbase\FleetOps\Http\Controllers\Internal\v1;
|
|
4
4
|
|
|
5
5
|
use Fleetbase\FleetOps\Http\Controllers\FleetOpsController;
|
|
6
|
+
use Fleetbase\FleetOps\Models\Device;
|
|
7
|
+
use Fleetbase\FleetOps\Models\Vehicle;
|
|
8
|
+
use Illuminate\Http\JsonResponse;
|
|
9
|
+
use Illuminate\Http\Request;
|
|
10
|
+
use Illuminate\Support\Facades\Log;
|
|
6
11
|
|
|
7
12
|
class DeviceController extends FleetOpsController
|
|
8
13
|
{
|
|
@@ -21,7 +26,23 @@ class DeviceController extends FleetOpsController
|
|
|
21
26
|
*/
|
|
22
27
|
public static function onQueryRecord($query, $request): void
|
|
23
28
|
{
|
|
24
|
-
$query->with(['telematic', 'warranty']);
|
|
29
|
+
$query->with(['telematic', 'warranty', 'attachable']);
|
|
30
|
+
|
|
31
|
+
if ($request->filled('attachment_state')) {
|
|
32
|
+
match ($request->input('attachment_state')) {
|
|
33
|
+
'attached' => $query->whereNotNull('attachable_uuid'),
|
|
34
|
+
'unattached' => $query->whereNull('attachable_uuid'),
|
|
35
|
+
default => null,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if ($request->filled('vehicle')) {
|
|
40
|
+
$query->where('attachable_uuid', $request->input('vehicle'));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if ($request->filled('device_id')) {
|
|
44
|
+
$query->where('device_id', 'like', '%' . $request->input('device_id') . '%');
|
|
45
|
+
}
|
|
25
46
|
}
|
|
26
47
|
|
|
27
48
|
/**
|
|
@@ -32,6 +53,123 @@ class DeviceController extends FleetOpsController
|
|
|
32
53
|
*/
|
|
33
54
|
public static function onFindRecord($query, $request): void
|
|
34
55
|
{
|
|
35
|
-
$query->with(['telematic', 'warranty']);
|
|
56
|
+
$query->with(['telematic', 'warranty', 'attachable']);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Attach a device to a supported FleetOps resource.
|
|
61
|
+
*/
|
|
62
|
+
public function attach(Request $request, string $id): JsonResponse
|
|
63
|
+
{
|
|
64
|
+
$request->validate([
|
|
65
|
+
'vehicle' => 'required_without:attachable_uuid|nullable|string',
|
|
66
|
+
]);
|
|
67
|
+
|
|
68
|
+
$vehicleId = $request->input('vehicle') ?? $request->input('attachable_uuid');
|
|
69
|
+
$device = $this->resolveDevice($id);
|
|
70
|
+
$vehicle = $this->resolveVehicle($vehicleId);
|
|
71
|
+
|
|
72
|
+
if (!$device) {
|
|
73
|
+
$this->logDeviceAttachmentLookupFailure('attach', 'device', $id, $vehicleId);
|
|
74
|
+
|
|
75
|
+
return response()->error('Device not found or not available for this organization.', 404);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (!$vehicle) {
|
|
79
|
+
$this->logDeviceAttachmentLookupFailure('attach', 'vehicle', $id, $vehicleId);
|
|
80
|
+
|
|
81
|
+
return response()->error('Vehicle not found or not available for this organization.', 404);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
$device->attachTo($vehicle);
|
|
86
|
+
$device->load(['telematic', 'warranty', 'attachable']);
|
|
87
|
+
} catch (\Throwable $e) {
|
|
88
|
+
$this->logDeviceAttachmentFailure('attach', $device, $vehicle, $e);
|
|
89
|
+
|
|
90
|
+
return response()->error('Unable to attach device to vehicle. Please try again or contact support.', 500);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return response()->json([
|
|
94
|
+
'status' => 'ok',
|
|
95
|
+
'device' => $device,
|
|
96
|
+
]);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Detach a device from its current FleetOps resource.
|
|
101
|
+
*/
|
|
102
|
+
public function detach(string $id): JsonResponse
|
|
103
|
+
{
|
|
104
|
+
$device = $this->resolveDevice($id);
|
|
105
|
+
|
|
106
|
+
if (!$device) {
|
|
107
|
+
$this->logDeviceAttachmentLookupFailure('detach', 'device', $id, null);
|
|
108
|
+
|
|
109
|
+
return response()->error('Device not found or not available for this organization.', 404);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
try {
|
|
113
|
+
$device->detach();
|
|
114
|
+
$device->load(['telematic', 'warranty', 'attachable']);
|
|
115
|
+
} catch (\Throwable $e) {
|
|
116
|
+
$this->logDeviceAttachmentFailure('detach', $device, null, $e);
|
|
117
|
+
|
|
118
|
+
return response()->error('Unable to detach device from vehicle. Please try again or contact support.', 500);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return response()->json([
|
|
122
|
+
'status' => 'ok',
|
|
123
|
+
'device' => $device,
|
|
124
|
+
]);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
protected function resolveDevice(string $id): ?Device
|
|
128
|
+
{
|
|
129
|
+
return Device::where(function ($query) use ($id) {
|
|
130
|
+
$query->where('uuid', $id)->orWhere('public_id', $id);
|
|
131
|
+
})
|
|
132
|
+
->where('company_uuid', session('company'))
|
|
133
|
+
->first();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
protected function resolveVehicle(?string $id): ?Vehicle
|
|
137
|
+
{
|
|
138
|
+
if (!$id) {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return Vehicle::where(function ($query) use ($id) {
|
|
143
|
+
$query->where('uuid', $id)->orWhere('public_id', $id);
|
|
144
|
+
})
|
|
145
|
+
->where('company_uuid', session('company'))
|
|
146
|
+
->first();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
protected function logDeviceAttachmentLookupFailure(string $action, string $missingResource, string $deviceId, ?string $vehicleId): void
|
|
150
|
+
{
|
|
151
|
+
Log::warning('Device attachment lookup failed', [
|
|
152
|
+
'action' => $action,
|
|
153
|
+
'missing_resource' => $missingResource,
|
|
154
|
+
'device_id' => $deviceId,
|
|
155
|
+
'vehicle_id' => $vehicleId,
|
|
156
|
+
'company_uuid' => session('company'),
|
|
157
|
+
'request_id' => request()->headers->get('X-Request-ID') ?? request()->headers->get('X-Correlation-ID'),
|
|
158
|
+
]);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
protected function logDeviceAttachmentFailure(string $action, Device $device, ?Vehicle $vehicle, \Throwable $exception): void
|
|
162
|
+
{
|
|
163
|
+
Log::error('Device attachment failed', [
|
|
164
|
+
'action' => $action,
|
|
165
|
+
'device_uuid' => $device->uuid,
|
|
166
|
+
'device_id' => $device->public_id,
|
|
167
|
+
'vehicle_uuid' => $vehicle?->uuid,
|
|
168
|
+
'vehicle_id' => $vehicle?->public_id,
|
|
169
|
+
'company_uuid' => session('company'),
|
|
170
|
+
'request_id' => request()->headers->get('X-Request-ID') ?? request()->headers->get('X-Correlation-ID'),
|
|
171
|
+
'exception_class' => get_class($exception),
|
|
172
|
+
'exception' => $exception->getMessage(),
|
|
173
|
+
]);
|
|
36
174
|
}
|
|
37
175
|
}
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
namespace Fleetbase\FleetOps\Http\Controllers\Internal\v1;
|
|
4
4
|
|
|
5
5
|
use Fleetbase\FleetOps\Http\Controllers\FleetOpsController;
|
|
6
|
+
use Fleetbase\FleetOps\Models\DeviceEvent;
|
|
7
|
+
use Illuminate\Http\JsonResponse;
|
|
6
8
|
|
|
7
9
|
class DeviceEventController extends FleetOpsController
|
|
8
10
|
{
|
|
@@ -12,4 +14,46 @@ class DeviceEventController extends FleetOpsController
|
|
|
12
14
|
* @var string
|
|
13
15
|
*/
|
|
14
16
|
public $resource = 'device-event';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Query callback when querying record.
|
|
20
|
+
*
|
|
21
|
+
* @param \Illuminate\Database\Query\Builder $query
|
|
22
|
+
* @param Request $request
|
|
23
|
+
*/
|
|
24
|
+
public static function onQueryRecord($query, $request): void
|
|
25
|
+
{
|
|
26
|
+
$query->with(['device']);
|
|
27
|
+
|
|
28
|
+
if ($request->filled('telematic')) {
|
|
29
|
+
$query->whereHas('device', function ($deviceQuery) use ($request) {
|
|
30
|
+
$deviceQuery->where('telematic_uuid', $request->input('telematic'));
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if ($request->filled('processed')) {
|
|
35
|
+
match ($request->input('processed')) {
|
|
36
|
+
'processed' => $query->whereNotNull('processed_at'),
|
|
37
|
+
'unprocessed' => $query->whereNull('processed_at'),
|
|
38
|
+
default => null,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public function markProcessed(string $id): JsonResponse
|
|
44
|
+
{
|
|
45
|
+
$deviceEvent = DeviceEvent::where('company_uuid', session('company'))
|
|
46
|
+
->where(function ($query) use ($id) {
|
|
47
|
+
$query->where('uuid', $id)->orWhere('public_id', $id);
|
|
48
|
+
})
|
|
49
|
+
->firstOrFail();
|
|
50
|
+
|
|
51
|
+
$processed = $deviceEvent->markAsProcessed();
|
|
52
|
+
|
|
53
|
+
return response()->json([
|
|
54
|
+
'status' => 'ok',
|
|
55
|
+
'message' => $processed ? 'Event marked processed.' : 'Event was already processed.',
|
|
56
|
+
'device_event' => $deviceEvent->fresh(),
|
|
57
|
+
]);
|
|
58
|
+
}
|
|
15
59
|
}
|
|
@@ -6,12 +6,13 @@ use Fleetbase\Exceptions\FleetbaseRequestValidationException;
|
|
|
6
6
|
use Fleetbase\FleetOps\Exports\DriverExport;
|
|
7
7
|
use Fleetbase\FleetOps\Http\Controllers\Api\v1\DriverController as ApiDriverController;
|
|
8
8
|
use Fleetbase\FleetOps\Http\Controllers\FleetOpsController;
|
|
9
|
-
use Fleetbase\FleetOps\Http\Requests\Internal\AssignOrderRequest;
|
|
10
9
|
use Fleetbase\FleetOps\Http\Requests\Internal\CreateDriverRequest;
|
|
11
10
|
use Fleetbase\FleetOps\Http\Requests\Internal\UpdateDriverRequest;
|
|
11
|
+
use Fleetbase\FleetOps\Http\Resources\v1\Index\Order as IndexOrderResource;
|
|
12
12
|
use Fleetbase\FleetOps\Imports\DriverImport;
|
|
13
13
|
use Fleetbase\FleetOps\Models\Driver;
|
|
14
14
|
use Fleetbase\FleetOps\Models\Order;
|
|
15
|
+
use Fleetbase\FleetOps\Models\Vehicle;
|
|
15
16
|
use Fleetbase\FleetOps\Support\Utils;
|
|
16
17
|
use Fleetbase\Http\Requests\ExportRequest;
|
|
17
18
|
use Fleetbase\Http\Requests\ImportRequest;
|
|
@@ -21,6 +22,7 @@ use Fleetbase\Models\User;
|
|
|
21
22
|
use Fleetbase\Models\VerificationCode;
|
|
22
23
|
use Fleetbase\Support\Auth;
|
|
23
24
|
use Illuminate\Database\QueryException;
|
|
25
|
+
use Illuminate\Http\JsonResponse;
|
|
24
26
|
use Illuminate\Http\Request;
|
|
25
27
|
use Illuminate\Support\Facades\DB;
|
|
26
28
|
use Illuminate\Support\Facades\Validator;
|
|
@@ -303,7 +305,7 @@ class DriverController extends FleetOpsController
|
|
|
303
305
|
function (&$request, &$driver, &$input) {
|
|
304
306
|
$driver->load(['user'])->guard(['user_uuid']);
|
|
305
307
|
$input = collect($input);
|
|
306
|
-
$userInput = $input->only(['name', 'password', 'email', 'phone', 'avatar_uuid'])->toArray();
|
|
308
|
+
$userInput = $input->only(['name', 'password', 'email', 'phone', 'avatar_uuid'])->reject(fn ($value) => $value === null)->toArray();
|
|
307
309
|
// handle `photo_uuid`
|
|
308
310
|
if (isset($input['photo_uuid']) && Str::isUuid($input['photo_uuid'])) {
|
|
309
311
|
$userInput['avatar_uuid'] = $input['photo_uuid'];
|
|
@@ -312,9 +314,8 @@ class DriverController extends FleetOpsController
|
|
|
312
314
|
|
|
313
315
|
// Update driver user details
|
|
314
316
|
$driverUser = $driver->getUser();
|
|
315
|
-
if ($driverUser) {
|
|
317
|
+
if ($driverUser && !empty($userInput)) {
|
|
316
318
|
$driverUser->update($userInput);
|
|
317
|
-
$input['slug'] = $driverUser->slug;
|
|
318
319
|
}
|
|
319
320
|
|
|
320
321
|
// Flush cache
|
|
@@ -396,10 +397,18 @@ class DriverController extends FleetOpsController
|
|
|
396
397
|
*
|
|
397
398
|
* @return \Illuminate\Http\Response $response
|
|
398
399
|
*/
|
|
399
|
-
public function assignOrder(
|
|
400
|
+
public function assignOrder(Request $request, ?string $id = null)
|
|
400
401
|
{
|
|
401
|
-
$
|
|
402
|
-
|
|
402
|
+
$request->validate([
|
|
403
|
+
'driver' => ($id ? 'nullable' : 'required') . '|string',
|
|
404
|
+
'order' => 'required|string',
|
|
405
|
+
]);
|
|
406
|
+
|
|
407
|
+
$driverIdentifier = $id ?? $request->input('driver');
|
|
408
|
+
$orderIdentifier = $request->input('order');
|
|
409
|
+
|
|
410
|
+
$driver = $this->findDriver($driverIdentifier);
|
|
411
|
+
$order = $this->findOrder($orderIdentifier);
|
|
403
412
|
|
|
404
413
|
if ($order->hasDriverAssigned) {
|
|
405
414
|
return response()->error('A driver is already assigned to this order.');
|
|
@@ -410,13 +419,155 @@ class DriverController extends FleetOpsController
|
|
|
410
419
|
}
|
|
411
420
|
|
|
412
421
|
$order->assignDriver($driver);
|
|
422
|
+
$driver->update(['current_job_uuid' => $order->uuid]);
|
|
413
423
|
|
|
414
424
|
return response()->json([
|
|
415
425
|
'status' => 'ok',
|
|
416
426
|
'message' => 'Driver assigned',
|
|
427
|
+
'driver' => $driver->fresh(['vehicle', 'currentOrder']),
|
|
428
|
+
'order' => $order->fresh(['driverAssigned']),
|
|
429
|
+
]);
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
public function assignedOrders(string $id): JsonResponse
|
|
433
|
+
{
|
|
434
|
+
$driver = $this->findDriver($id);
|
|
435
|
+
$orders = Order::where('driver_assigned_uuid', $driver->uuid)
|
|
436
|
+
->where('company_uuid', session('company'))
|
|
437
|
+
->with(['payload', 'trackingNumber', 'orderConfig', 'driverAssigned', 'vehicleAssigned'])
|
|
438
|
+
->orderByRaw('uuid = ? desc', [$driver->current_job_uuid])
|
|
439
|
+
->latest()
|
|
440
|
+
->get();
|
|
441
|
+
|
|
442
|
+
return response()->json([
|
|
443
|
+
'status' => 'ok',
|
|
444
|
+
'driver' => $driver->fresh(['vehicle', 'currentOrder']),
|
|
445
|
+
'orders' => IndexOrderResource::collection($orders)->resolve(),
|
|
446
|
+
'current' => $driver->current_job_uuid,
|
|
447
|
+
'count' => $orders->count(),
|
|
448
|
+
]);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
public function unassignOrders(Request $request, string $id): JsonResponse
|
|
452
|
+
{
|
|
453
|
+
$request->validate([
|
|
454
|
+
'orders' => 'required|array|min:1',
|
|
455
|
+
'orders.*' => 'required|string',
|
|
456
|
+
]);
|
|
457
|
+
|
|
458
|
+
$driver = $this->findDriver($id);
|
|
459
|
+
$ids = collect($request->input('orders'))->filter()->unique()->values();
|
|
460
|
+
$orders = Order::where('driver_assigned_uuid', $driver->uuid)
|
|
461
|
+
->where('company_uuid', session('company'))
|
|
462
|
+
->where(function ($query) use ($ids) {
|
|
463
|
+
$query->whereIn('uuid', $ids)->orWhereIn('public_id', $ids);
|
|
464
|
+
})
|
|
465
|
+
->get();
|
|
466
|
+
|
|
467
|
+
if ($orders->isEmpty()) {
|
|
468
|
+
return response()->error('No assigned orders were selected for this driver.');
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
DB::transaction(function () use ($driver, $orders): void {
|
|
472
|
+
Order::whereIn('uuid', $orders->pluck('uuid'))->update([
|
|
473
|
+
'driver_assigned_uuid' => null,
|
|
474
|
+
'updated_at' => now(),
|
|
475
|
+
]);
|
|
476
|
+
|
|
477
|
+
if ($driver->current_job_uuid && $orders->contains('uuid', $driver->current_job_uuid)) {
|
|
478
|
+
$driver->update(['current_job_uuid' => null]);
|
|
479
|
+
}
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
return response()->json([
|
|
483
|
+
'status' => 'ok',
|
|
484
|
+
'message' => 'Driver unassigned from selected orders.',
|
|
485
|
+
'driver' => $driver->fresh(['vehicle', 'currentOrder']),
|
|
486
|
+
'orders' => IndexOrderResource::collection($orders->fresh(['driverAssigned', 'vehicleAssigned']))->resolve(),
|
|
487
|
+
'count' => $orders->count(),
|
|
488
|
+
]);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
public function unassignOrder(string $id): JsonResponse
|
|
492
|
+
{
|
|
493
|
+
$driver = $this->findDriver($id);
|
|
494
|
+
$order = Order::where('driver_assigned_uuid', $driver->uuid)
|
|
495
|
+
->where('company_uuid', session('company'))
|
|
496
|
+
->first() ?? $driver->getCurrentOrder();
|
|
497
|
+
|
|
498
|
+
if ($order) {
|
|
499
|
+
$order->update(['driver_assigned_uuid' => null]);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
$driver->unassignCurrentJob();
|
|
503
|
+
|
|
504
|
+
return response()->json([
|
|
505
|
+
'status' => 'ok',
|
|
506
|
+
'message' => 'Driver unassigned from order.',
|
|
507
|
+
'driver' => $driver->fresh(['vehicle', 'currentOrder']),
|
|
508
|
+
'order' => $order?->fresh(['driverAssigned']),
|
|
417
509
|
]);
|
|
418
510
|
}
|
|
419
511
|
|
|
512
|
+
public function assignVehicle(Request $request, string $id): JsonResponse
|
|
513
|
+
{
|
|
514
|
+
$request->validate(['vehicle' => 'required|string']);
|
|
515
|
+
|
|
516
|
+
$driver = $this->findDriver($id);
|
|
517
|
+
$vehicle = $this->findVehicle($request->input('vehicle'));
|
|
518
|
+
|
|
519
|
+
$driver->assignVehicle($vehicle);
|
|
520
|
+
|
|
521
|
+
return response()->json([
|
|
522
|
+
'status' => 'ok',
|
|
523
|
+
'message' => 'Vehicle assigned to driver.',
|
|
524
|
+
'driver' => $driver->fresh(['vehicle', 'currentOrder']),
|
|
525
|
+
'vehicle' => $vehicle->fresh(['driver']),
|
|
526
|
+
]);
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
public function unassignVehicle(string $id): JsonResponse
|
|
530
|
+
{
|
|
531
|
+
$driver = $this->findDriver($id);
|
|
532
|
+
$vehicle = $driver->vehicle;
|
|
533
|
+
|
|
534
|
+
$driver->update(['vehicle_uuid' => null]);
|
|
535
|
+
|
|
536
|
+
return response()->json([
|
|
537
|
+
'status' => 'ok',
|
|
538
|
+
'message' => 'Vehicle unassigned from driver.',
|
|
539
|
+
'driver' => $driver->fresh(['vehicle', 'currentOrder']),
|
|
540
|
+
'vehicle' => $vehicle?->fresh(['driver']),
|
|
541
|
+
]);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
protected function findDriver(?string $id): Driver
|
|
545
|
+
{
|
|
546
|
+
return Driver::where(function ($query) use ($id) {
|
|
547
|
+
$query->where('uuid', $id)->orWhere('public_id', $id);
|
|
548
|
+
})
|
|
549
|
+
->where('company_uuid', session('company'))
|
|
550
|
+
->firstOrFail();
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
protected function findOrder(?string $id): Order
|
|
554
|
+
{
|
|
555
|
+
return Order::where(function ($query) use ($id) {
|
|
556
|
+
$query->where('uuid', $id)->orWhere('public_id', $id);
|
|
557
|
+
})
|
|
558
|
+
->where('company_uuid', session('company'))
|
|
559
|
+
->firstOrFail();
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
protected function findVehicle(?string $id): Vehicle
|
|
563
|
+
{
|
|
564
|
+
return Vehicle::where(function ($query) use ($id) {
|
|
565
|
+
$query->where('uuid', $id)->orWhere('public_id', $id);
|
|
566
|
+
})
|
|
567
|
+
->where('company_uuid', session('company'))
|
|
568
|
+
->firstOrFail();
|
|
569
|
+
}
|
|
570
|
+
|
|
420
571
|
/**
|
|
421
572
|
* Update drivers geolocation data.
|
|
422
573
|
*
|