@fleetbase/fleetops-engine 0.6.64 → 0.6.65
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/RELEASE.md +7 -5
- package/addon/components/attachment-list.hbs +65 -0
- package/addon/components/attachment-list.js +8 -0
- package/addon/components/cell/attached-vehicle.hbs +1 -1
- package/addon/components/cell/attached-vehicle.js +3 -3
- package/addon/components/cell/driver-identity.js +4 -4
- package/addon/components/cell/driver-name.hbs +1 -1
- package/addon/components/cell/translated-value.hbs +9 -0
- package/addon/components/cell/translated-value.js +57 -0
- package/addon/components/contact/card.hbs +58 -0
- package/addon/components/contact/card.js +19 -0
- package/addon/components/contact/form.hbs +1 -1
- package/addon/components/contact/panel-header.hbs +1 -1
- package/addon/components/customer/form.hbs +2 -2
- package/addon/components/device/manager.hbs +26 -28
- package/addon/components/device/manager.js +28 -2
- package/addon/components/device/panel-tabs/vehicle.hbs +13 -13
- package/addon/components/device/panel-tabs/vehicle.js +8 -0
- package/addon/components/driver/card.hbs +24 -13
- package/addon/components/driver/card.js +20 -6
- package/addon/components/driver/form.hbs +3 -3
- package/addon/components/driver/panel-header.hbs +2 -2
- package/addon/components/driver/pill.hbs +2 -2
- package/addon/components/equipment/form.js +11 -4
- package/addon/components/equipment/pill.hbs +20 -0
- package/addon/components/equipment/pill.js +3 -0
- package/addon/components/filter/multi-model.hbs +19 -0
- package/addon/components/filter/multi-model.js +90 -0
- package/addon/components/fleet/driver-listing.hbs +1 -1
- package/addon/components/fleet/vehicle-listing.hbs +1 -1
- package/addon/components/fleet-panel/driver-listing.hbs +1 -1
- package/addon/components/fleet-panel/vehicle-listing.hbs +1 -1
- package/addon/components/layout/fleet-ops-sidebar.js +9 -7
- package/addon/components/maintenance/form.js +12 -4
- package/addon/components/maintenance-schedule/form.js +13 -7
- package/addon/components/map/leaflet-live-map.hbs +52 -0
- package/addon/components/map/order-list-overlay/order.hbs +4 -4
- package/addon/components/modals/attach-equipment.hbs +22 -0
- package/addon/components/modals/attach-equipment.js +3 -0
- package/addon/components/modals/attach-telematic-device.hbs +13 -8
- package/addon/components/modals/attach-telematic-device.js +11 -1
- package/addon/components/modals/attach-trailer.hbs +30 -0
- package/addon/components/modals/attach-trailer.js +3 -0
- package/addon/components/modals/contact-form.hbs +2 -2
- package/addon/components/modals/convert-customer-to-vendor.hbs +1 -1
- package/addon/components/modals/driver-form.hbs +2 -2
- package/addon/components/modals/select-trailer.hbs +35 -0
- package/addon/components/modals/select-trailer.js +3 -0
- package/addon/components/modals/vehicle-form.hbs +2 -2
- package/addon/components/orchestrator/resource-panel.hbs +2 -2
- package/addon/components/order/customer-avatar-stack.hbs +2 -2
- package/addon/components/order/details/detail.hbs +4 -4
- package/addon/components/order/details/payload.hbs +2 -2
- package/addon/components/order/kanban-card.hbs +4 -4
- package/addon/components/order-list-overlay/order.hbs +4 -4
- package/addon/components/trailer/card.hbs +68 -0
- package/addon/components/trailer/card.js +22 -0
- package/addon/components/trailer/details/connections.hbs +57 -0
- package/addon/components/trailer/details/connections.js +59 -0
- package/addon/components/trailer/details/equipment.hbs +25 -0
- package/addon/components/trailer/details/equipment.js +52 -0
- package/addon/components/trailer/details/maintenance-history.hbs +47 -0
- package/addon/components/trailer/details/maintenance-history.js +40 -0
- package/addon/components/trailer/details/schedules.hbs +45 -0
- package/addon/components/trailer/details/schedules.js +40 -0
- package/addon/components/trailer/details/work-orders.hbs +47 -0
- package/addon/components/trailer/details/work-orders.js +40 -0
- package/addon/components/trailer/details.hbs +399 -0
- package/addon/components/trailer/details.js +118 -0
- package/addon/components/trailer/form.hbs +447 -0
- package/addon/components/trailer/form.js +165 -0
- package/addon/components/trailer/panel-header.hbs +45 -0
- package/addon/components/trailer/panel-header.js +3 -0
- package/addon/components/trailer/pill.hbs +21 -0
- package/addon/components/trailer/pill.js +3 -0
- package/addon/components/vehicle/card.hbs +42 -11
- package/addon/components/vehicle/card.js +31 -0
- package/addon/components/vehicle/details/equipment.hbs +25 -0
- package/addon/components/vehicle/details/equipment.js +55 -0
- package/addon/components/vehicle/details/trailers.hbs +35 -0
- package/addon/components/vehicle/details/trailers.js +55 -0
- package/addon/components/vehicle/form.hbs +2 -2
- package/addon/components/vehicle/panel-header.hbs +2 -2
- package/addon/components/vehicle/pill.hbs +2 -2
- package/addon/components/vendor/card.hbs +58 -0
- package/addon/components/vendor/card.js +6 -0
- package/addon/components/vendor/panel-header.hbs +2 -2
- package/addon/components/vendor/personnel-manager.hbs +2 -2
- package/addon/components/work-order/form.js +12 -4
- package/addon/controllers/connectivity/devices/index/details/vehicle.js +11 -0
- package/addon/controllers/connectivity/devices/index/details.js +3 -3
- package/addon/controllers/connectivity/devices/index.js +1 -0
- package/addon/controllers/connectivity/telematics/details/attachments.js +28 -47
- package/addon/controllers/connectivity/telematics/details/devices.js +1 -0
- package/addon/controllers/management/contacts/customers.js +4 -0
- package/addon/controllers/management/contacts/index.js +32 -0
- package/addon/controllers/management/trailers/index/details.js +119 -0
- package/addon/controllers/management/trailers/index/edit.js +67 -0
- package/addon/controllers/management/trailers/index/new.js +43 -0
- package/addon/controllers/management/trailers/index.js +599 -0
- package/addon/controllers/management/vehicles/index/details.js +16 -0
- package/addon/controllers/management/vehicles/index.js +78 -4
- package/addon/controllers/management/vendors/index.js +32 -0
- package/addon/controllers/operations/orders/index.js +3 -1
- package/addon/controllers/settings/custom-fields.js +8 -0
- package/addon/extension.js +7 -0
- package/addon/helpers/placeholder-image.js +6 -0
- package/addon/helpers/resource-image.js +10 -0
- package/addon/helpers/trailer-placeholder-image.js +6 -0
- package/addon/routes/management/trailers/index/details/connections.js +2 -0
- package/addon/routes/management/trailers/index/details/devices.js +2 -0
- package/addon/routes/management/trailers/index/details/equipment.js +2 -0
- package/addon/routes/management/trailers/index/details/index.js +2 -0
- package/addon/routes/management/trailers/index/details/maintenance-history.js +2 -0
- package/addon/routes/management/trailers/index/details/positions.js +2 -0
- package/addon/routes/management/trailers/index/details/schedules.js +2 -0
- package/addon/routes/management/trailers/index/details/work-orders.js +2 -0
- package/addon/routes/management/trailers/index/details.js +30 -0
- package/addon/routes/management/trailers/index/edit.js +23 -0
- package/addon/routes/management/trailers/index/new.js +14 -0
- package/addon/routes/management/trailers/index.js +42 -0
- package/addon/routes/management/vehicles/index/details/trailers.js +2 -0
- package/addon/routes/management/vehicles/index.js +7 -1
- package/addon/routes.js +17 -0
- package/addon/services/device-actions.js +26 -16
- package/addon/services/trailer-actions.js +394 -0
- package/addon/services/vehicle-actions.js +111 -0
- package/addon/styles/fleetops-engine.css +349 -0
- package/addon/templates/connectivity/devices/index/details/vehicle.hbs +19 -19
- package/addon/templates/connectivity/telematics/details/attachments.hbs +15 -15
- package/addon/templates/management/contacts/customers.hbs +48 -29
- package/addon/templates/management/contacts/index.hbs +52 -33
- package/addon/templates/management/trailers/index/details/connections.hbs +1 -0
- package/addon/templates/management/trailers/index/details/devices.hbs +1 -0
- package/addon/templates/management/trailers/index/details/equipment.hbs +1 -0
- package/addon/templates/management/trailers/index/details/index.hbs +1 -0
- package/addon/templates/management/trailers/index/details/maintenance-history.hbs +1 -0
- package/addon/templates/management/trailers/index/details/positions.hbs +1 -0
- package/addon/templates/management/trailers/index/details/schedules.hbs +1 -0
- package/addon/templates/management/trailers/index/details/work-orders.hbs +1 -0
- package/addon/templates/management/trailers/index/details.hbs +15 -0
- package/addon/templates/management/trailers/index/edit.hbs +12 -0
- package/addon/templates/management/trailers/index/new.hbs +11 -0
- package/addon/templates/management/trailers/index.hbs +67 -0
- package/addon/templates/management/vehicles/index/details/equipment.hbs +1 -1
- package/addon/templates/management/vehicles/index/details/trailers.hbs +1 -0
- package/addon/templates/management/vehicles/index/details.hbs +1 -1
- package/addon/templates/management/vendors/index.hbs +66 -32
- package/addon/utils/device-table-columns.js +10 -6
- package/addon/utils/live-map-card-content.js +56 -0
- package/addon/utils/placeholder-images.js +71 -0
- package/addon/utils/trailer-placeholder-image.js +11 -0
- package/app/components/attachment-list.js +1 -0
- package/app/components/cell/translated-value.js +1 -0
- package/app/components/contact/card.js +1 -0
- package/app/components/equipment/pill.js +1 -0
- package/app/components/filter/multi-model.js +1 -0
- package/app/components/modals/attach-equipment.js +1 -0
- package/app/components/modals/attach-trailer.js +1 -0
- package/app/components/modals/select-trailer.js +1 -0
- package/app/components/trailer/card.js +1 -0
- package/app/components/trailer/details/connections.js +1 -0
- package/app/components/trailer/details/equipment.js +1 -0
- package/app/components/trailer/details/maintenance-history.js +1 -0
- package/app/components/trailer/details/schedules.js +1 -0
- package/app/components/trailer/details/work-orders.js +1 -0
- package/app/components/trailer/details.js +1 -0
- package/app/components/trailer/form.js +1 -0
- package/app/components/trailer/panel-header.js +1 -0
- package/app/components/trailer/pill.js +1 -0
- package/app/components/vehicle/details/equipment.js +1 -0
- package/app/components/vehicle/details/trailers.js +1 -0
- package/app/components/vendor/card.js +1 -0
- package/app/controllers/management/trailers/index/details.js +1 -0
- package/app/controllers/management/trailers/index/edit.js +1 -0
- package/app/controllers/management/trailers/index/new.js +1 -0
- package/app/controllers/management/trailers/index.js +1 -0
- package/app/helpers/placeholder-image.js +1 -0
- package/app/helpers/resource-image.js +1 -0
- package/app/helpers/trailer-placeholder-image.js +1 -0
- package/app/routes/management/trailers/index/details/connections.js +1 -0
- package/app/routes/management/trailers/index/details/devices.js +1 -0
- package/app/routes/management/trailers/index/details/equipment.js +1 -0
- package/app/routes/management/trailers/index/details/index.js +1 -0
- package/app/routes/management/trailers/index/details/maintenance-history.js +1 -0
- package/app/routes/management/trailers/index/details/positions.js +1 -0
- package/app/routes/management/trailers/index/details/schedules.js +1 -0
- package/app/routes/management/trailers/index/details/work-orders.js +1 -0
- package/app/routes/management/trailers/index/details.js +1 -0
- package/app/routes/management/trailers/index/edit.js +1 -0
- package/app/routes/management/trailers/index/new.js +1 -0
- package/app/routes/management/trailers/index.js +1 -0
- package/app/routes/management/vehicles/index/details/trailers.js +1 -0
- package/app/services/trailer-actions.js +1 -0
- package/app/templates/management/trailers/index/details/connections.js +1 -0
- package/app/templates/management/trailers/index/details/devices.js +1 -0
- package/app/templates/management/trailers/index/details/equipment.js +1 -0
- package/app/templates/management/trailers/index/details/index.js +1 -0
- package/app/templates/management/trailers/index/details/maintenance-history.js +1 -0
- package/app/templates/management/trailers/index/details/positions.js +1 -0
- package/app/templates/management/trailers/index/details/schedules.js +1 -0
- package/app/templates/management/trailers/index/details/work-orders.js +1 -0
- package/app/templates/management/trailers/index/details.js +1 -0
- package/app/templates/management/trailers/index/edit.js +1 -0
- package/app/templates/management/trailers/index/new.js +1 -0
- package/app/templates/management/trailers/index.js +1 -0
- package/app/templates/management/vehicles/index/details/trailers.js +1 -0
- package/composer.json +1 -1
- package/extension.json +1 -1
- package/package.json +1 -1
- package/server/migrations/2026_09_03_000001_add_first_class_trailer_columns_to_assets_table.php +58 -0
- package/server/migrations/2026_09_03_000002_create_asset_connections_table.php +43 -0
- package/server/migrations/2026_09_03_000003_create_device_installations_table.php +33 -0
- package/server/src/Auth/Schemas/FleetOps.php +7 -0
- package/server/src/Events/TrailerLocationChanged.php +70 -0
- package/server/src/Exceptions/DeviceAlreadyAttachedException.php +18 -0
- package/server/src/Exports/TrailerExport.php +31 -0
- package/server/src/Http/Controllers/Api/v1/Concerns/ResolvesFleetOpsApiResources.php +8 -2
- package/server/src/Http/Controllers/Api/v1/DeviceController.php +22 -15
- package/server/src/Http/Controllers/Api/v1/EquipmentController.php +47 -0
- package/server/src/Http/Controllers/Api/v1/TrailerController.php +362 -0
- package/server/src/Http/Controllers/Api/v1/VehicleController.php +1 -0
- package/server/src/Http/Controllers/Internal/v1/DeviceController.php +3 -0
- package/server/src/Http/Controllers/Internal/v1/LiveController.php +1 -1
- package/server/src/Http/Controllers/Internal/v1/SearchController.php +16 -0
- package/server/src/Http/Controllers/Internal/v1/TrailerController.php +360 -0
- package/server/src/Http/Controllers/Internal/v1/VehicleController.php +74 -0
- package/server/src/Http/Filter/EquipmentFilter.php +51 -0
- package/server/src/Http/Filter/OrderFilter.php +15 -0
- package/server/src/Http/Filter/TrailerFilter.php +269 -0
- package/server/src/Http/Filter/VehicleFilter.php +70 -3
- package/server/src/Http/Requests/CreateDeviceRequest.php +1 -1
- package/server/src/Http/Requests/CreateEquipmentRequest.php +1 -1
- package/server/src/Http/Requests/CreateTrailerRequest.php +54 -0
- package/server/src/Http/Requests/UpdateTrailerRequest.php +7 -0
- package/server/src/Http/Resources/v1/AssetConnection.php +90 -0
- package/server/src/Http/Resources/v1/Device.php +3 -1
- package/server/src/Http/Resources/v1/Equipment.php +3 -1
- package/server/src/Http/Resources/v1/Index/Vehicle.php +10 -0
- package/server/src/Http/Resources/v1/Trailer.php +199 -0
- package/server/src/Http/Resources/v1/Vehicle.php +2 -0
- package/server/src/Http/Resources/v1/VehicleWithoutDriver.php +3 -0
- package/server/src/Imports/TrailerImport.php +33 -0
- package/server/src/Models/Asset.php +39 -10
- package/server/src/Models/AssetConnection.php +43 -0
- package/server/src/Models/Device.php +39 -8
- package/server/src/Models/DeviceInstallation.php +27 -0
- package/server/src/Models/Equipment.php +2 -0
- package/server/src/Models/Trailer.php +181 -0
- package/server/src/Models/Vehicle.php +13 -0
- package/server/src/Providers/FleetOpsServiceProvider.php +4 -2
- package/server/src/Support/Ai/FleetOpsAiQueryResources.php +22 -0
- package/server/src/Support/Reporting/FleetOpsReportSchema.php +38 -0
- package/server/src/Support/Telematics/TelematicService.php +35 -0
- package/server/src/Support/TrailerSummary.php +35 -0
- package/server/src/routes.php +29 -0
- package/server/tests/CompactResourceSerializationTest.php +36 -0
- package/server/tests/ControllerFilterContractsTest.php +29 -0
- package/server/tests/Feature/Http/Api/DeviceControllerContractsTest.php +30 -13
- package/server/tests/Feature/Http/Api/TrailerControllerLifecycleTest.php +640 -0
- package/server/tests/Feature/Http/Internal/DeviceControllerContractsTest.php +20 -5
- package/server/tests/Feature/Http/Internal/LiveControllerEndpointsTest.php +19 -0
- package/server/tests/ModelAccessorContractsTest.php +10 -0
- package/server/tests/OrderFilterExecutionTest.php +5 -0
- package/server/tests/PublicApiControllerInputContractsTest.php +11 -0
- package/server/tests/PublicFleetOpsRestEndpointsTest.php +15 -3
- package/server/tests/ReportSchemaContractsTest.php +4 -0
- package/server/tests/TelematicsHardeningTest.php +4 -2
- package/server/tests/TrailerSupportCoverageTest.php +524 -0
- package/server/tests/Unit/Http/Resources/IndexVehicleResourceTest.php +35 -0
- package/server/tests/Unit/Models/EquipmentTest.php +22 -0
- package/server/tests/Unit/Models/ModelLookupFallbackSeamsTest.php +7 -3
- package/server/tests/Unit/Models/TrailerTest.php +204 -0
- package/server/tests/Unit/Support/Telematics/TelematicServiceTelemetryTest.php +93 -0
- package/server/tests/VehicleControllerHelperContractsTest.php +14 -0
- package/translations/ar-ae.yml +396 -0
- package/translations/bg-bg.yaml +424 -0
- package/translations/en-us.yaml +423 -0
- package/translations/es-pa.yaml +425 -0
- package/translations/fr-fr.yaml +424 -0
- package/translations/mn-mn.yaml +424 -0
- package/translations/pt-br.yaml +424 -0
- package/translations/ru-ru.yaml +424 -0
- package/translations/vi-vn.yaml +435 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/trailer/form';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/trailer/panel-header';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/trailer/pill';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/vehicle/details/equipment';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/vehicle/details/trailers';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/components/vendor/card';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/controllers/management/trailers/index/details';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/controllers/management/trailers/index/edit';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/controllers/management/trailers/index/new';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/controllers/management/trailers/index';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/helpers/placeholder-image';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/helpers/resource-image';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/helpers/trailer-placeholder-image';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/routes/management/trailers/index/details/connections';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/routes/management/trailers/index/details/devices';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/routes/management/trailers/index/details/equipment';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/routes/management/trailers/index/details/index';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/routes/management/trailers/index/details/maintenance-history';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/routes/management/trailers/index/details/positions';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/routes/management/trailers/index/details/schedules';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/routes/management/trailers/index/details/work-orders';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/routes/management/trailers/index/details';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/routes/management/trailers/index/edit';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/routes/management/trailers/index/new';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/routes/management/trailers/index';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/routes/management/vehicles/index/details/trailers';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/services/trailer-actions';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/templates/management/trailers/index/details/connections';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/templates/management/trailers/index/details/devices';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/templates/management/trailers/index/details/equipment';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/templates/management/trailers/index/details/index';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/templates/management/trailers/index/details/maintenance-history';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/templates/management/trailers/index/details/positions';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/templates/management/trailers/index/details/schedules';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/templates/management/trailers/index/details/work-orders';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/templates/management/trailers/index/details';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/templates/management/trailers/index/edit';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/templates/management/trailers/index/new';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/templates/management/trailers/index';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/fleetops-engine/templates/management/vehicles/index/details/trailers';
|
package/composer.json
CHANGED
package/extension.json
CHANGED
package/package.json
CHANGED
package/server/migrations/2026_09_03_000001_add_first_class_trailer_columns_to_assets_table.php
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
use Illuminate\Database\Migrations\Migration;
|
|
4
|
+
use Illuminate\Database\Schema\Blueprint;
|
|
5
|
+
use Illuminate\Support\Facades\Schema;
|
|
6
|
+
|
|
7
|
+
return new class extends Migration {
|
|
8
|
+
public function up(): void
|
|
9
|
+
{
|
|
10
|
+
Schema::table('assets', function (Blueprint $table) {
|
|
11
|
+
// Existing Asset rows predate public identifiers. Keep this nullable so
|
|
12
|
+
// Trailer support does not rewrite unrelated historical Asset data.
|
|
13
|
+
$table->string('public_id')->nullable()->after('uuid')->unique();
|
|
14
|
+
$table->string('asset_class')->nullable()->after('type')->index();
|
|
15
|
+
$table->foreignUuid('photo_uuid')->nullable()->after('current_place_uuid')->constrained('files', 'uuid')->nullOnDelete();
|
|
16
|
+
$table->boolean('online')->nullable()->after('altitude')->index();
|
|
17
|
+
$table->timestamp('last_online_at')->nullable()->after('online')->index();
|
|
18
|
+
$table->json('telematics')->nullable()->after('attributes');
|
|
19
|
+
$table->date('purchased_at')->nullable()->after('lease_expires_at');
|
|
20
|
+
$table->decimal('length', 12, 3)->nullable();
|
|
21
|
+
$table->decimal('width', 12, 3)->nullable();
|
|
22
|
+
$table->decimal('height', 12, 3)->nullable();
|
|
23
|
+
$table->decimal('tare_weight', 12, 3)->nullable();
|
|
24
|
+
$table->decimal('gvwr', 12, 3)->nullable();
|
|
25
|
+
$table->decimal('payload_capacity', 12, 3)->nullable();
|
|
26
|
+
$table->decimal('cargo_volume', 12, 3)->nullable();
|
|
27
|
+
$table->unsignedSmallInteger('axle_count')->nullable();
|
|
28
|
+
$table->unsignedSmallInteger('tire_count')->nullable();
|
|
29
|
+
$table->unsignedSmallInteger('door_count')->nullable();
|
|
30
|
+
$table->string('body_type')->nullable()->index();
|
|
31
|
+
$table->string('coupling_type')->nullable();
|
|
32
|
+
$table->string('brake_type')->nullable();
|
|
33
|
+
$table->boolean('abs_equipped')->nullable();
|
|
34
|
+
$table->boolean('ebs_equipped')->nullable();
|
|
35
|
+
$table->boolean('refrigerated')->nullable()->index();
|
|
36
|
+
$table->decimal('temperature_min', 8, 3)->nullable();
|
|
37
|
+
$table->decimal('temperature_max', 8, 3)->nullable();
|
|
38
|
+
$table->decimal('reefer_engine_hours', 14, 2)->nullable();
|
|
39
|
+
$table->index(['company_uuid', 'asset_class', 'status'], 'assets_company_class_status_index');
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public function down(): void
|
|
44
|
+
{
|
|
45
|
+
Schema::table('assets', function (Blueprint $table) {
|
|
46
|
+
$table->dropIndex('assets_company_class_status_index');
|
|
47
|
+
$table->dropForeign(['photo_uuid']);
|
|
48
|
+
$table->dropUnique(['public_id']);
|
|
49
|
+
$table->dropColumn([
|
|
50
|
+
'public_id', 'asset_class', 'photo_uuid', 'online', 'last_online_at', 'telematics', 'purchased_at',
|
|
51
|
+
'length', 'width', 'height', 'tare_weight', 'gvwr', 'payload_capacity', 'cargo_volume',
|
|
52
|
+
'axle_count', 'tire_count', 'door_count', 'body_type', 'coupling_type', 'brake_type',
|
|
53
|
+
'abs_equipped', 'ebs_equipped', 'refrigerated', 'temperature_min', 'temperature_max',
|
|
54
|
+
'reefer_engine_hours',
|
|
55
|
+
]);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
use Illuminate\Database\Migrations\Migration;
|
|
4
|
+
use Illuminate\Database\Schema\Blueprint;
|
|
5
|
+
use Illuminate\Support\Facades\Schema;
|
|
6
|
+
|
|
7
|
+
return new class extends Migration {
|
|
8
|
+
public function up(): void
|
|
9
|
+
{
|
|
10
|
+
Schema::create('asset_connections', function (Blueprint $table) {
|
|
11
|
+
$table->bigIncrements('id');
|
|
12
|
+
$table->uuid('uuid')->unique();
|
|
13
|
+
$table->string('public_id')->unique();
|
|
14
|
+
$table->foreignUuid('company_uuid')->constrained('companies', 'uuid')->cascadeOnDelete();
|
|
15
|
+
$table->string('connector_type');
|
|
16
|
+
$table->uuid('connector_uuid');
|
|
17
|
+
$table->string('connected_type');
|
|
18
|
+
$table->uuid('connected_uuid');
|
|
19
|
+
$table->uuid('active_connected_uuid')->nullable()->unique();
|
|
20
|
+
$table->string('active_connector_position')->nullable()->unique();
|
|
21
|
+
$table->string('relationship_type')->default('towing');
|
|
22
|
+
$table->unsignedSmallInteger('position')->default(1);
|
|
23
|
+
$table->timestamp('connected_at');
|
|
24
|
+
$table->timestamp('disconnected_at')->nullable();
|
|
25
|
+
$table->string('source')->default('manual');
|
|
26
|
+
$table->string('confidence')->nullable();
|
|
27
|
+
$table->text('notes')->nullable();
|
|
28
|
+
$table->json('meta')->nullable();
|
|
29
|
+
$table->foreignUuid('created_by_uuid')->nullable()->constrained('users', 'uuid')->nullOnDelete();
|
|
30
|
+
$table->foreignUuid('updated_by_uuid')->nullable()->constrained('users', 'uuid')->nullOnDelete();
|
|
31
|
+
$table->timestamps();
|
|
32
|
+
$table->softDeletes();
|
|
33
|
+
$table->index(['company_uuid', 'connector_type', 'connector_uuid'], 'asset_connections_connector_index');
|
|
34
|
+
$table->index(['company_uuid', 'connected_type', 'connected_uuid'], 'asset_connections_connected_index');
|
|
35
|
+
$table->index(['company_uuid', 'disconnected_at'], 'asset_connections_active_index');
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public function down(): void
|
|
40
|
+
{
|
|
41
|
+
Schema::dropIfExists('asset_connections');
|
|
42
|
+
}
|
|
43
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
use Illuminate\Database\Migrations\Migration;
|
|
4
|
+
use Illuminate\Database\Schema\Blueprint;
|
|
5
|
+
use Illuminate\Support\Facades\Schema;
|
|
6
|
+
|
|
7
|
+
return new class extends Migration {
|
|
8
|
+
public function up(): void
|
|
9
|
+
{
|
|
10
|
+
Schema::create('device_installations', function (Blueprint $table) {
|
|
11
|
+
$table->bigIncrements('id');
|
|
12
|
+
$table->uuid('uuid')->unique();
|
|
13
|
+
$table->foreignUuid('company_uuid')->constrained('companies', 'uuid')->cascadeOnDelete();
|
|
14
|
+
$table->foreignUuid('device_uuid')->constrained('devices', 'uuid')->cascadeOnDelete();
|
|
15
|
+
$table->string('attachable_type');
|
|
16
|
+
$table->uuid('attachable_uuid');
|
|
17
|
+
$table->uuid('active_device_uuid')->nullable()->unique();
|
|
18
|
+
$table->timestamp('installed_at');
|
|
19
|
+
$table->timestamp('removed_at')->nullable();
|
|
20
|
+
$table->string('source')->default('manual');
|
|
21
|
+
$table->json('metadata')->nullable();
|
|
22
|
+
$table->softDeletes();
|
|
23
|
+
$table->timestamps();
|
|
24
|
+
$table->index(['company_uuid', 'attachable_type', 'attachable_uuid'], 'device_installations_attachable_index');
|
|
25
|
+
$table->index(['device_uuid', 'installed_at'], 'device_installations_history_index');
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
public function down(): void
|
|
30
|
+
{
|
|
31
|
+
Schema::dropIfExists('device_installations');
|
|
32
|
+
}
|
|
33
|
+
};
|
|
@@ -61,6 +61,10 @@ class FleetOps
|
|
|
61
61
|
'name' => 'vehicle',
|
|
62
62
|
'actions' => ['assign-driver-for', 'export', 'import'],
|
|
63
63
|
],
|
|
64
|
+
[
|
|
65
|
+
'name' => 'trailer',
|
|
66
|
+
'actions' => ['export', 'import', 'attach-vehicle-for', 'detach-vehicle-for', 'attach-device-for', 'detach-device-for', 'attach-equipment-for', 'detach-equipment-for'],
|
|
67
|
+
],
|
|
64
68
|
[
|
|
65
69
|
'name' => 'fleet',
|
|
66
70
|
'actions' => ['assign-driver-for', 'assign-vehicle-for', 'remove-driver-for', 'remove-vehicle-for', 'export', 'import'],
|
|
@@ -217,6 +221,7 @@ class FleetOps
|
|
|
217
221
|
'* fleet',
|
|
218
222
|
'* driver',
|
|
219
223
|
'* vehicle',
|
|
224
|
+
'* trailer',
|
|
220
225
|
],
|
|
221
226
|
],
|
|
222
227
|
[
|
|
@@ -294,6 +299,7 @@ class FleetOps
|
|
|
294
299
|
'* work-order',
|
|
295
300
|
'* equipment',
|
|
296
301
|
'* part',
|
|
302
|
+
'* trailer',
|
|
297
303
|
'see vehicle',
|
|
298
304
|
'list vehicle',
|
|
299
305
|
'view vehicle',
|
|
@@ -318,6 +324,7 @@ class FleetOps
|
|
|
318
324
|
'* work-order',
|
|
319
325
|
'* equipment',
|
|
320
326
|
'* part',
|
|
327
|
+
'* trailer',
|
|
321
328
|
],
|
|
322
329
|
],
|
|
323
330
|
[
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\FleetOps\Events;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\FleetOps\Models\Trailer;
|
|
6
|
+
use Illuminate\Broadcasting\Channel;
|
|
7
|
+
use Illuminate\Broadcasting\InteractsWithSockets;
|
|
8
|
+
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
|
9
|
+
use Illuminate\Foundation\Bus\Dispatchable;
|
|
10
|
+
use Illuminate\Queue\SerializesModels;
|
|
11
|
+
|
|
12
|
+
class TrailerLocationChanged implements ShouldBroadcast
|
|
13
|
+
{
|
|
14
|
+
use Dispatchable;
|
|
15
|
+
use InteractsWithSockets;
|
|
16
|
+
use SerializesModels;
|
|
17
|
+
|
|
18
|
+
public string $eventId;
|
|
19
|
+
public string $sentAt;
|
|
20
|
+
public string $companyUuid;
|
|
21
|
+
public string $trailerUuid;
|
|
22
|
+
public string $trailerId;
|
|
23
|
+
public mixed $location;
|
|
24
|
+
public mixed $altitude;
|
|
25
|
+
public mixed $heading;
|
|
26
|
+
public mixed $speed;
|
|
27
|
+
public array $additionalData;
|
|
28
|
+
|
|
29
|
+
public function __construct(Trailer $trailer, array $additionalData = [])
|
|
30
|
+
{
|
|
31
|
+
$this->eventId = uniqid('event_');
|
|
32
|
+
$this->sentAt = now()->toDateTimeString();
|
|
33
|
+
$this->companyUuid = $trailer->company_uuid;
|
|
34
|
+
$this->trailerUuid = $trailer->uuid;
|
|
35
|
+
$this->trailerId = $trailer->public_id;
|
|
36
|
+
$this->location = $trailer->location;
|
|
37
|
+
$this->altitude = $trailer->altitude;
|
|
38
|
+
$this->heading = $trailer->heading;
|
|
39
|
+
$this->speed = $trailer->speed;
|
|
40
|
+
$this->additionalData = $additionalData;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public function broadcastOn(): array
|
|
44
|
+
{
|
|
45
|
+
return [new Channel('company.' . $this->companyUuid), new Channel('trailer.' . $this->trailerId), new Channel('trailer.' . $this->trailerUuid)];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public function broadcastAs(): string
|
|
49
|
+
{
|
|
50
|
+
return 'trailer.location_changed';
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public function broadcastWith(): array
|
|
54
|
+
{
|
|
55
|
+
return [
|
|
56
|
+
'id' => $this->eventId,
|
|
57
|
+
'api_version' => config('api.version'),
|
|
58
|
+
'event' => $this->broadcastAs(),
|
|
59
|
+
'created_at' => $this->sentAt,
|
|
60
|
+
'data' => [
|
|
61
|
+
'id' => $this->trailerId,
|
|
62
|
+
'location' => $this->location,
|
|
63
|
+
'altitude' => $this->altitude,
|
|
64
|
+
'heading' => $this->heading,
|
|
65
|
+
'speed' => $this->speed,
|
|
66
|
+
'additionalData' => $this->additionalData,
|
|
67
|
+
],
|
|
68
|
+
];
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\FleetOps\Exceptions;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Thrown when a device that is already installed on one asset is attached to another
|
|
7
|
+
* without being detached first. Attaching silently used to re-home the device, which
|
|
8
|
+
* let an operator "steal" a tracker from a vehicle with no feedback.
|
|
9
|
+
*/
|
|
10
|
+
class DeviceAlreadyAttachedException extends \DomainException
|
|
11
|
+
{
|
|
12
|
+
public static function for(?string $attachedToName): self
|
|
13
|
+
{
|
|
14
|
+
$target = $attachedToName ? ' to ' . $attachedToName : ' to another asset';
|
|
15
|
+
|
|
16
|
+
return new self('Device is already attached' . $target . '. Detach it before attaching it elsewhere.');
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\FleetOps\Exports;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\FleetOps\Models\Trailer;
|
|
6
|
+
use Maatwebsite\Excel\Concerns\FromCollection;
|
|
7
|
+
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
|
|
8
|
+
use Maatwebsite\Excel\Concerns\WithHeadings;
|
|
9
|
+
use Maatwebsite\Excel\Concerns\WithMapping;
|
|
10
|
+
|
|
11
|
+
class TrailerExport implements FromCollection, WithHeadings, WithMapping, ShouldAutoSize
|
|
12
|
+
{
|
|
13
|
+
public function __construct(protected array $selections = [])
|
|
14
|
+
{
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
public function headings(): array
|
|
18
|
+
{
|
|
19
|
+
return ['ID', 'Name', 'Code', 'Type', 'Status', 'VIN', 'Plate Number', 'Serial Number', 'Make', 'Model', 'Year', 'Length', 'Width', 'Height', 'Tare Weight', 'GVWR', 'Payload Capacity', 'Cargo Volume', 'Axle Count', 'Tire Count', 'Coupling Type', 'Brake Type', 'Refrigerated', 'Measurement System', 'Odometer', 'Odometer Unit', 'Ownership Type', 'Purchased At', 'Lease Expires At', 'Notes', 'Date Created', 'Date Updated'];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public function map($trailer): array
|
|
23
|
+
{
|
|
24
|
+
return [$trailer->public_id, $trailer->name, $trailer->code, $trailer->type, $trailer->status, $trailer->vin, $trailer->plate_number, $trailer->serial_number, $trailer->make, $trailer->model, $trailer->year, $trailer->length, $trailer->width, $trailer->height, $trailer->tare_weight, $trailer->gvwr, $trailer->payload_capacity, $trailer->cargo_volume, $trailer->axle_count, $trailer->tire_count, $trailer->coupling_type, $trailer->brake_type, $trailer->refrigerated ? 'Yes' : 'No', $trailer->measurement_system, $trailer->odometer, $trailer->odometer_unit, $trailer->ownership_type, $trailer->purchased_at, $trailer->lease_expires_at, $trailer->notes, $trailer->created_at, $trailer->updated_at];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
public function collection()
|
|
28
|
+
{
|
|
29
|
+
return Trailer::where('company_uuid', session('company'))->when($this->selections, fn ($q) => $q->whereIn('uuid', $this->selections))->get();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -12,10 +12,10 @@ use Fleetbase\FleetOps\Models\FuelReport;
|
|
|
12
12
|
use Fleetbase\FleetOps\Models\Order;
|
|
13
13
|
use Fleetbase\FleetOps\Models\Part;
|
|
14
14
|
use Fleetbase\FleetOps\Models\Telematic;
|
|
15
|
+
use Fleetbase\FleetOps\Models\Trailer;
|
|
15
16
|
use Fleetbase\FleetOps\Models\Vehicle;
|
|
16
17
|
use Fleetbase\FleetOps\Models\Vendor;
|
|
17
18
|
use Fleetbase\FleetOps\Models\Warranty;
|
|
18
|
-
use Fleetbase\FleetOps\Support\Utils;
|
|
19
19
|
use Fleetbase\Models\File;
|
|
20
20
|
use Illuminate\Database\Eloquent\Model;
|
|
21
21
|
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
|
@@ -72,7 +72,10 @@ trait ResolvesFleetOpsApiResources
|
|
|
72
72
|
return [null, null];
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
$modelClass =
|
|
75
|
+
$modelClass = $this->allowedMorphTypes()[$type] ?? null;
|
|
76
|
+
if (!$modelClass) {
|
|
77
|
+
throw ValidationException::withMessages(['type' => ['Unsupported resource type.']]);
|
|
78
|
+
}
|
|
76
79
|
$model = $this->resolveModel($modelClass, $id);
|
|
77
80
|
|
|
78
81
|
return [$modelClass, $model->uuid];
|
|
@@ -166,6 +169,9 @@ trait ResolvesFleetOpsApiResources
|
|
|
166
169
|
'fleet-ops:vehicle' => Vehicle::class,
|
|
167
170
|
'vehicle' => Vehicle::class,
|
|
168
171
|
Vehicle::class => Vehicle::class,
|
|
172
|
+
'fleet-ops:trailer' => Trailer::class,
|
|
173
|
+
'trailer' => Trailer::class,
|
|
174
|
+
Trailer::class => Trailer::class,
|
|
169
175
|
'fleet-ops:driver' => Driver::class,
|
|
170
176
|
'driver' => Driver::class,
|
|
171
177
|
Driver::class => Driver::class,
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
namespace Fleetbase\FleetOps\Http\Controllers\Api\v1;
|
|
4
4
|
|
|
5
|
+
use Fleetbase\FleetOps\Exceptions\DeviceAlreadyAttachedException;
|
|
5
6
|
use Fleetbase\FleetOps\Http\Controllers\Api\v1\Concerns\ResolvesFleetOpsApiResources;
|
|
6
7
|
use Fleetbase\FleetOps\Http\Requests\CreateDeviceRequest;
|
|
7
8
|
use Fleetbase\FleetOps\Http\Requests\UpdateDeviceRequest;
|
|
@@ -9,7 +10,6 @@ use Fleetbase\FleetOps\Http\Resources\v1\DeletedResource;
|
|
|
9
10
|
use Fleetbase\FleetOps\Http\Resources\v1\Device as DeviceResource;
|
|
10
11
|
use Fleetbase\FleetOps\Models\Device;
|
|
11
12
|
use Fleetbase\FleetOps\Models\Telematic;
|
|
12
|
-
use Fleetbase\FleetOps\Models\Vehicle;
|
|
13
13
|
use Fleetbase\FleetOps\Models\Warranty;
|
|
14
14
|
use Fleetbase\FleetOps\Support\Utils;
|
|
15
15
|
use Fleetbase\Http\Controllers\Controller;
|
|
@@ -90,28 +90,34 @@ class DeviceController extends Controller
|
|
|
90
90
|
$this->rejectUuidIdentifiers($request);
|
|
91
91
|
|
|
92
92
|
$request->validate([
|
|
93
|
-
'vehicle'
|
|
93
|
+
'vehicle' => 'required_without:attachable|string|nullable',
|
|
94
|
+
'attachable' => 'required_without:vehicle|string|nullable',
|
|
95
|
+
'attachable_type' => 'nullable|in:fleet-ops:vehicle,fleet-ops:trailer,vehicle,trailer',
|
|
94
96
|
]);
|
|
95
97
|
|
|
96
|
-
$deviceId
|
|
97
|
-
$
|
|
98
|
+
$deviceId = $id;
|
|
99
|
+
$attachableId = $request->input('vehicle') ?? $request->input('attachable');
|
|
100
|
+
$attachableType = $request->filled('vehicle') ? 'fleet-ops:vehicle' : $request->input('attachable_type', 'fleet-ops:vehicle');
|
|
98
101
|
|
|
99
102
|
try {
|
|
100
|
-
$device
|
|
101
|
-
$
|
|
103
|
+
$device = $this->resolveModel(Device::class, $deviceId);
|
|
104
|
+
[$modelClass] = $this->resolveMorph($attachableType, $attachableId);
|
|
105
|
+
$attachable = $this->resolveModel($modelClass, $attachableId);
|
|
102
106
|
} catch (\Illuminate\Database\Eloquent\ModelNotFoundException $exception) {
|
|
103
|
-
$this->logDeviceAttachmentLookupFailure('attach', $deviceId, $
|
|
107
|
+
$this->logDeviceAttachmentLookupFailure('attach', $deviceId, $attachableId);
|
|
104
108
|
|
|
105
|
-
return response()->json(['error' => 'Device or
|
|
109
|
+
return response()->json(['error' => 'Device or attachable resource not found.'], 404);
|
|
106
110
|
}
|
|
107
111
|
|
|
108
112
|
try {
|
|
109
|
-
$device->attachTo($
|
|
113
|
+
$device->attachTo($attachable);
|
|
110
114
|
$this->loadDeviceRelations($device);
|
|
115
|
+
} catch (DeviceAlreadyAttachedException $e) {
|
|
116
|
+
return response()->json(['error' => $e->getMessage()], 409);
|
|
111
117
|
} catch (\Throwable $e) {
|
|
112
|
-
$this->logDeviceAttachmentFailure('attach', $device, $
|
|
118
|
+
$this->logDeviceAttachmentFailure('attach', $device, $attachable, $e);
|
|
113
119
|
|
|
114
|
-
return response()->json(['error' => 'Unable to attach device to
|
|
120
|
+
return response()->json(['error' => 'Unable to attach device to resource.'], 500);
|
|
115
121
|
}
|
|
116
122
|
|
|
117
123
|
return response()->json([
|
|
@@ -136,7 +142,7 @@ class DeviceController extends Controller
|
|
|
136
142
|
} catch (\Throwable $e) {
|
|
137
143
|
$this->logDeviceAttachmentFailure('detach', $device, null, $e);
|
|
138
144
|
|
|
139
|
-
return response()->json(['error' => 'Unable to detach device from
|
|
145
|
+
return response()->json(['error' => 'Unable to detach device from resource.'], 500);
|
|
140
146
|
}
|
|
141
147
|
|
|
142
148
|
return response()->json([
|
|
@@ -242,14 +248,15 @@ class DeviceController extends Controller
|
|
|
242
248
|
]);
|
|
243
249
|
}
|
|
244
250
|
|
|
245
|
-
protected function logDeviceAttachmentFailure(string $action, Device $device,
|
|
251
|
+
protected function logDeviceAttachmentFailure(string $action, Device $device, ?\Illuminate\Database\Eloquent\Model $attachable, \Throwable $exception): void
|
|
246
252
|
{
|
|
247
253
|
Log::error('Public API device attachment failed', [
|
|
248
254
|
'action' => $action,
|
|
249
255
|
'device_uuid' => $device->uuid,
|
|
250
256
|
'device_id' => $device->public_id,
|
|
251
|
-
'
|
|
252
|
-
'
|
|
257
|
+
'attachable_type' => $attachable ? get_class($attachable) : null,
|
|
258
|
+
'attachable_uuid' => $attachable?->uuid,
|
|
259
|
+
'attachable_id' => $attachable?->public_id,
|
|
253
260
|
'company_uuid' => session('company'),
|
|
254
261
|
'request_id' => request()->headers->get('X-Request-ID') ?? request()->headers->get('X-Correlation-ID'),
|
|
255
262
|
'exception_class' => get_class($exception),
|