@fleetbase/fleetops-engine 0.6.38 → 0.6.40
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/addon/components/activity/form.hbs +2 -12
- package/addon/components/activity/logic-builder.hbs +1 -1
- package/addon/components/custom-entity/form.hbs +4 -20
- package/addon/components/device/form.hbs +3 -15
- package/addon/components/device/panel-header.hbs +13 -2
- package/addon/components/driver/details.hbs +33 -2
- package/addon/components/driver/form.hbs +42 -0
- package/addon/components/driver/panel-header.hbs +8 -1
- package/addon/components/driver/schedule.hbs +115 -76
- package/addon/components/driver/schedule.js +349 -157
- package/addon/components/driver-onboard-settings.hbs +2 -8
- package/addon/components/entity-field-editing-settings.hbs +2 -5
- package/addon/components/equipment/card.hbs +49 -0
- package/addon/components/equipment/card.js +6 -0
- package/addon/components/equipment/details.hbs +83 -44
- package/addon/components/equipment/form.hbs +111 -41
- package/addon/components/equipment/form.js +78 -10
- package/addon/components/equipment/panel-header.hbs +36 -0
- package/addon/components/equipment/panel-header.js +2 -0
- package/addon/components/fleet/driver-listing.hbs +3 -1
- package/addon/components/fleet/vehicle-listing.hbs +4 -7
- package/addon/components/fleet-panel/vehicle-listing.hbs +1 -6
- package/addon/components/fuel-report/form.hbs +1 -5
- package/addon/components/layout/fleet-ops-sidebar.hbs +43 -38
- package/addon/components/layout/fleet-ops-sidebar.js +103 -24
- package/addon/components/maintenance/cost-panel.hbs +176 -0
- package/addon/components/maintenance/cost-panel.js +241 -0
- package/addon/components/maintenance/details.hbs +123 -60
- package/addon/components/maintenance/form.hbs +138 -78
- package/addon/components/maintenance/form.js +131 -6
- package/addon/components/maintenance/panel-header.hbs +31 -0
- package/addon/components/maintenance/panel-header.js +2 -0
- package/addon/components/maintenance-schedule/details.hbs +260 -0
- package/addon/components/maintenance-schedule/details.js +158 -0
- package/addon/components/maintenance-schedule/form.hbs +287 -0
- package/addon/components/maintenance-schedule/form.js +199 -0
- package/addon/components/map/container.hbs +1 -1
- package/addon/components/map/drawer/device-event-listing.hbs +1 -1
- package/addon/components/map/drawer/driver-listing.hbs +1 -6
- package/addon/components/map/drawer/place-listing.hbs +1 -6
- package/addon/components/map/drawer/vehicle-listing.hbs +1 -6
- package/addon/components/map/drawer.hbs +8 -1
- package/addon/components/map/leaflet-live-map.hbs +2 -1
- package/addon/components/map/toolbar/visibility-control-panel.hbs +1 -1
- package/addon/components/map/toolbar.hbs +4 -29
- package/addon/components/modals/add-driver-shift.hbs +155 -0
- package/addon/components/modals/add-driver-shift.js +210 -0
- package/addon/components/modals/bulk-assign-orders.hbs +67 -0
- package/addon/components/modals/driver-shift.hbs +43 -0
- package/addon/components/modals/driver-shift.js +56 -0
- package/addon/components/modals/entity-form.hbs +5 -28
- package/addon/components/modals/orchestrator-import.hbs +351 -0
- package/addon/components/modals/orchestrator-import.js +807 -0
- package/addon/components/modals/order-config-new-status.hbs +1 -5
- package/addon/components/modals/scheduling-conflict.hbs +47 -0
- package/addon/components/modals/scheduling-conflict.js +53 -0
- package/addon/components/modals/send-work-order.hbs +91 -0
- package/addon/components/modals/send-work-order.js +3 -0
- package/addon/components/modals/service-area-form.hbs +1 -6
- package/addon/components/modals/set-driver-availability.hbs +50 -0
- package/addon/components/modals/set-driver-availability.js +57 -0
- package/addon/components/modals/update-order-activity.hbs +13 -9
- package/addon/components/modals/user-form.hbs +1 -5
- package/addon/components/modals/vehicle-form.hbs +17 -102
- package/addon/components/modals/vendor-form.hbs +15 -82
- package/addon/components/orchestrator/card-fields-settings.hbs +76 -0
- package/addon/components/orchestrator/card-fields-settings.js +134 -0
- package/addon/components/orchestrator/order-pool.hbs +264 -0
- package/addon/components/orchestrator/order-pool.js +394 -0
- package/addon/components/orchestrator/phase-builder.hbs +162 -0
- package/addon/components/orchestrator/phase-builder.js +162 -0
- package/addon/components/orchestrator/plan-viewer.hbs +278 -0
- package/addon/components/orchestrator/plan-viewer.js +342 -0
- package/addon/components/orchestrator/resource-panel.hbs +301 -0
- package/addon/components/orchestrator/resource-panel.js +106 -0
- package/addon/components/orchestrator-workbench.hbs +318 -0
- package/addon/components/orchestrator-workbench.js +1088 -0
- package/addon/components/order/details/custom-fields.hbs +10 -1
- package/addon/components/order/details/detail.hbs +37 -2
- package/addon/components/order/details/detail.js +0 -1
- package/addon/components/order/details/integrated-vendor-details.hbs +4 -4
- package/addon/components/order/details/notes.hbs +1 -7
- package/addon/components/order/details/route.hbs +1 -5
- package/addon/components/order/form/details.hbs +44 -10
- package/addon/components/order/form/details.js +57 -0
- package/addon/components/order/form/notes.hbs +1 -7
- package/addon/components/order/form/payload.hbs +1 -7
- package/addon/components/order/form/route.hbs +3 -15
- package/addon/components/order/header.hbs +1 -7
- package/addon/components/order/route-editor.hbs +4 -25
- package/addon/components/order/schedule-card.hbs +102 -95
- package/addon/components/order/schedule-card.js +8 -3
- package/addon/components/order-config-manager/details.hbs +2 -10
- package/addon/components/order-config-manager/entities.hbs +1 -7
- package/addon/components/order-config-manager.hbs +1 -6
- package/addon/components/part/card.hbs +49 -0
- package/addon/components/part/card.js +6 -0
- package/addon/components/part/details.hbs +102 -56
- package/addon/components/part/form.hbs +131 -56
- package/addon/components/part/form.js +78 -11
- package/addon/components/part/panel-header.hbs +36 -0
- package/addon/components/part/panel-header.js +2 -0
- package/addon/components/place/form.hbs +1 -7
- package/addon/components/sensor/details.hbs +1 -1
- package/addon/components/sensor/form.hbs +5 -3
- package/addon/components/sensor/panel-header.hbs +8 -1
- package/addon/components/service-area/form.hbs +1 -6
- package/addon/components/service-rate/form.hbs +12 -60
- package/addon/components/telematic/form.hbs +6 -2
- package/addon/components/vehicle/details/maintenance-history.hbs +42 -0
- package/addon/components/vehicle/details/maintenance-history.js +32 -0
- package/addon/components/vehicle/details/schedules.hbs +40 -0
- package/addon/components/vehicle/details/schedules.js +32 -0
- package/addon/components/vehicle/details/work-orders.hbs +42 -0
- package/addon/components/vehicle/details/work-orders.js +32 -0
- package/addon/components/vehicle/details.hbs +52 -0
- package/addon/components/vehicle/form.hbs +51 -0
- package/addon/components/vehicle/panel-header.hbs +19 -49
- package/addon/components/warranty/details.hbs +3 -2
- package/addon/components/warranty/form.hbs +3 -17
- package/addon/components/work-order/details.hbs +135 -40
- package/addon/components/work-order/form.hbs +178 -45
- package/addon/components/work-order/form.js +197 -4
- package/addon/components/work-order/panel-header.hbs +31 -0
- package/addon/components/work-order/panel-header.js +2 -0
- package/addon/controllers/connectivity/devices/index/details.js +1 -1
- package/addon/controllers/maintenance/equipment/index/details/index.js +0 -1
- package/addon/controllers/maintenance/equipment/index/details.js +36 -1
- package/addon/controllers/maintenance/equipment/index/edit.js +56 -1
- package/addon/controllers/maintenance/equipment/index/new.js +32 -1
- package/addon/controllers/maintenance/equipment/index.js +127 -113
- package/addon/controllers/maintenance/maintenances/index/details/index.js +3 -0
- package/addon/controllers/maintenance/maintenances/index/details.js +54 -0
- package/addon/controllers/maintenance/maintenances/index/edit.js +68 -0
- package/addon/controllers/maintenance/maintenances/index/new.js +34 -0
- package/addon/controllers/maintenance/maintenances/index.js +191 -0
- package/addon/controllers/maintenance/parts/index/details/index.js +0 -1
- package/addon/controllers/maintenance/parts/index/details.js +36 -1
- package/addon/controllers/maintenance/parts/index/edit.js +56 -1
- package/addon/controllers/maintenance/parts/index/new.js +32 -1
- package/addon/controllers/maintenance/parts/index.js +135 -113
- package/addon/controllers/maintenance/schedules/index/details.js +115 -0
- package/addon/controllers/maintenance/schedules/index/edit.js +41 -0
- package/addon/controllers/maintenance/schedules/index/new.js +33 -0
- package/addon/controllers/maintenance/schedules/index.js +280 -0
- package/addon/controllers/maintenance/work-orders/index/details.js +41 -1
- package/addon/controllers/maintenance/work-orders/index/edit.js +67 -1
- package/addon/controllers/maintenance/work-orders/index/new.js +43 -1
- package/addon/controllers/maintenance/work-orders/index.js +105 -113
- package/addon/controllers/management/drivers/index/details.js +6 -1
- package/addon/controllers/management/vehicles/index/details.js +65 -0
- package/addon/controllers/management/vehicles/index.js +18 -0
- package/addon/controllers/operations/orchestrator.js +10 -0
- package/addon/controllers/operations/orders/index.js +6 -0
- package/addon/controllers/operations/scheduler/fleet-schedule.js +341 -0
- package/addon/controllers/operations/scheduler/index.js +799 -275
- package/addon/controllers/operations/scheduler.js +21 -0
- package/addon/controllers/settings/orchestrator.js +70 -0
- package/addon/controllers/settings/scheduling.js +155 -0
- package/addon/extension.js +19 -0
- package/addon/instance-initializers/register-vroom-allocation.js +27 -0
- package/addon/models/maintenance-schedule.js +61 -0
- package/addon/routes/maintenance/equipment/index/details.js +27 -1
- package/addon/routes/maintenance/equipment/index/edit.js +27 -1
- package/addon/routes/maintenance/maintenances/index/details/index.js +3 -0
- package/addon/routes/maintenance/maintenances/index/details.js +29 -0
- package/addon/routes/maintenance/maintenances/index/edit.js +29 -0
- package/addon/routes/maintenance/maintenances/index/new.js +3 -0
- package/addon/routes/maintenance/maintenances/index.js +23 -0
- package/addon/routes/maintenance/maintenances.js +3 -0
- package/addon/routes/maintenance/parts/index/details.js +27 -1
- package/addon/routes/maintenance/parts/index/edit.js +27 -1
- package/addon/routes/maintenance/schedules/index/details/index.js +2 -0
- package/addon/routes/maintenance/schedules/index/details/work-orders.js +11 -0
- package/addon/routes/maintenance/schedules/index/details.js +25 -0
- package/addon/routes/maintenance/schedules/index/edit.js +25 -0
- package/addon/routes/maintenance/schedules/index/new.js +2 -0
- package/addon/routes/maintenance/schedules/index.js +21 -0
- package/addon/routes/maintenance/schedules.js +2 -0
- package/addon/routes/maintenance/work-orders/index/details.js +27 -1
- package/addon/routes/maintenance/work-orders/index/edit.js +27 -1
- package/addon/routes/management/vehicles/index/details/maintenance-history.js +3 -0
- package/addon/routes/management/vehicles/index/details/schedules.js +3 -0
- package/addon/routes/management/vehicles/index/details/work-orders.js +3 -0
- package/addon/routes/operations/orchestrator.js +23 -0
- package/addon/routes/operations/scheduler/fleet-schedule.js +28 -0
- package/addon/routes/operations/scheduler/index.js +48 -26
- package/addon/routes/operations/scheduler.js +14 -1
- package/addon/routes/settings/orchestrator.js +27 -0
- package/addon/routes/settings/scheduling.js +3 -0
- package/addon/routes.js +31 -1
- package/addon/services/driver-actions.js +40 -7
- package/addon/services/driver-scheduling.js +4 -1
- package/addon/services/equipment-actions.js +15 -5
- package/addon/services/leaflet-map-manager.js +14 -6
- package/addon/services/maintenance-actions.js +17 -14
- package/addon/services/maintenance-schedule-actions.js +118 -0
- package/addon/services/orchestration-engine-interface.js +49 -0
- package/addon/services/orchestration-engine.js +74 -0
- package/addon/services/order-actions.js +15 -0
- package/addon/services/order-allocation.js +116 -0
- package/addon/services/part-actions.js +12 -2
- package/addon/services/scheduling.js +316 -0
- package/addon/services/vehicle-actions.js +70 -7
- package/addon/services/vroom-allocation-engine.js +45 -0
- package/addon/services/work-order-actions.js +79 -0
- package/addon/styles/fleetops-engine.css +1658 -0
- package/addon/templates/analytics/reports/index/edit.hbs +1 -1
- package/addon/templates/analytics/reports/index/new.hbs +1 -1
- package/addon/templates/application.hbs +6 -1
- package/addon/templates/connectivity/devices/index/details/events.hbs +0 -1
- package/addon/templates/connectivity/devices.hbs +0 -1
- package/addon/templates/connectivity/events/index/details.hbs +0 -1
- package/addon/templates/connectivity/events.hbs +0 -1
- package/addon/templates/connectivity/sensors.hbs +0 -1
- 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.hbs +0 -1
- package/addon/templates/connectivity/tracking.hbs +0 -1
- package/addon/templates/connectivity.hbs +0 -1
- package/addon/templates/maintenance/equipment/index/details/index.hbs +1 -2
- package/addon/templates/maintenance/equipment/index/details.hbs +15 -2
- package/addon/templates/maintenance/equipment/index/edit.hbs +12 -2
- package/addon/templates/maintenance/equipment/index/new.hbs +1 -2
- package/addon/templates/maintenance/equipment/index.hbs +48 -13
- package/addon/templates/maintenance/equipment.hbs +0 -1
- package/addon/templates/maintenance/maintenances/index/details/index.hbs +1 -0
- package/addon/templates/maintenance/maintenances/index/details.hbs +15 -0
- package/addon/templates/maintenance/maintenances/index/edit.hbs +12 -0
- package/addon/templates/maintenance/maintenances/index/new.hbs +11 -0
- package/addon/templates/maintenance/maintenances/index.hbs +14 -0
- package/addon/templates/maintenance/maintenances.hbs +1 -0
- package/addon/templates/maintenance/parts/index/details/index.hbs +1 -2
- package/addon/templates/maintenance/parts/index/details.hbs +15 -2
- package/addon/templates/maintenance/parts/index/edit.hbs +12 -2
- package/addon/templates/maintenance/parts/index/new.hbs +1 -2
- package/addon/templates/maintenance/parts/index.hbs +48 -13
- package/addon/templates/maintenance/parts.hbs +0 -1
- package/addon/templates/maintenance/schedules/index/details/index.hbs +1 -0
- package/addon/templates/maintenance/schedules/index/details/work-orders.hbs +39 -0
- package/addon/templates/maintenance/schedules/index/details.hbs +14 -0
- package/addon/templates/maintenance/schedules/index/edit.hbs +12 -0
- package/addon/templates/maintenance/schedules/index/new.hbs +11 -0
- package/addon/templates/maintenance/schedules/index.hbs +40 -0
- package/addon/templates/maintenance/schedules.hbs +1 -0
- package/addon/templates/maintenance/work-orders/index/details.hbs +2 -1
- package/addon/templates/maintenance/work-orders/index/edit.hbs +2 -4
- package/addon/templates/maintenance/work-orders/index/new.hbs +1 -2
- package/addon/templates/maintenance/work-orders.hbs +0 -1
- package/addon/templates/management/contacts/customers/edit.hbs +1 -2
- package/addon/templates/management/contacts/customers/new.hbs +1 -2
- package/addon/templates/management/contacts/customers.hbs +1 -1
- package/addon/templates/management/contacts/index/edit.hbs +1 -2
- package/addon/templates/management/contacts/index/new.hbs +1 -2
- package/addon/templates/management/drivers/index/details/orders.hbs +0 -1
- package/addon/templates/management/drivers/index/edit.hbs +1 -2
- package/addon/templates/management/drivers/index/new.hbs +1 -2
- package/addon/templates/management/fleets/index/edit.hbs +1 -2
- package/addon/templates/management/fleets/index/new.hbs +1 -2
- package/addon/templates/management/fleets/index.hbs +1 -2
- package/addon/templates/management/fuel-reports/index/edit.hbs +1 -2
- package/addon/templates/management/fuel-reports/index/new.hbs +1 -2
- package/addon/templates/management/fuel-reports/index.hbs +1 -2
- package/addon/templates/management/issues/index/edit.hbs +1 -2
- package/addon/templates/management/issues/index/new.hbs +1 -2
- package/addon/templates/management/issues/index.hbs +1 -2
- package/addon/templates/management/places/index/details/activity.hbs +0 -1
- package/addon/templates/management/places/index/details/comments.hbs +0 -1
- package/addon/templates/management/places/index/details/documents.hbs +0 -1
- package/addon/templates/management/places/index/details/map.hbs +0 -1
- package/addon/templates/management/places/index/details/operations.hbs +0 -1
- package/addon/templates/management/places/index/details/performance.hbs +0 -1
- package/addon/templates/management/places/index/details/rules.hbs +0 -1
- package/addon/templates/management/vehicles/index/details/equipment.hbs +0 -1
- package/addon/templates/management/vehicles/index/details/maintenance-history.hbs +2 -0
- package/addon/templates/management/vehicles/index/details/schedules.hbs +2 -0
- package/addon/templates/management/vehicles/index/details/work-orders.hbs +2 -0
- package/addon/templates/management/vehicles/index/details.hbs +1 -1
- package/addon/templates/management/vehicles/index/edit.hbs +1 -2
- package/addon/templates/management/vehicles/index/new.hbs +1 -2
- package/addon/templates/management/vendors/index/edit.hbs +1 -2
- package/addon/templates/management/vendors/index/new.hbs +1 -2
- package/addon/templates/management/vendors/index.hbs +1 -2
- package/addon/templates/management/vendors/integrated.hbs +1 -2
- package/addon/templates/operations/orchestrator.hbs +1 -0
- package/addon/templates/operations/orders/index.hbs +6 -1
- package/addon/templates/operations/scheduler/fleet-schedule.hbs +41 -0
- package/addon/templates/operations/scheduler/index.hbs +147 -88
- package/addon/templates/operations/scheduler.hbs +7 -1
- package/addon/templates/settings/avatars.hbs +1 -1
- package/addon/templates/settings/orchestrator.hbs +65 -0
- package/addon/templates/settings/payments/index.hbs +1 -5
- package/addon/templates/settings/scheduling.hbs +82 -0
- package/addon/utils/create-full-calendar-event-from-order.js +52 -14
- package/addon/utils/create-full-calendar-event-from-schedule-item.js +50 -0
- package/addon/utils/fleet-ops-options.js +254 -0
- package/addon/utils/route-colors.js +99 -0
- package/addon/utils/to-calendar-date.js +70 -0
- package/app/components/driver/schedule.js +1 -0
- package/app/components/maintenance/cost-panel.js +1 -0
- package/app/components/maintenance/panel-header.js +1 -0
- package/app/components/maintenance-schedule/details.js +1 -0
- package/app/components/maintenance-schedule/form.js +1 -0
- package/app/components/modals/add-driver-shift.js +1 -0
- package/app/components/modals/bulk-assign-orders.js +1 -0
- package/app/components/modals/driver-shift.js +1 -0
- package/app/components/modals/orchestrator-import.js +1 -0
- package/app/components/modals/scheduling-conflict.js +1 -0
- package/app/components/modals/send-work-order.js +1 -0
- package/app/components/modals/set-driver-availability.js +1 -0
- package/app/components/orchestrator/card-fields-settings.js +1 -0
- package/app/components/orchestrator/order-pool.js +1 -0
- package/app/components/orchestrator/phase-builder.js +1 -0
- package/app/components/orchestrator/plan-viewer.js +1 -0
- package/app/components/orchestrator/resource-panel.js +1 -0
- package/app/components/orchestrator-workbench.js +1 -0
- package/app/components/vehicle/details/maintenance-history.js +1 -0
- package/app/components/vehicle/details/schedules.js +1 -0
- package/app/components/vehicle/details/work-orders.js +1 -0
- package/app/controllers/operations/orchestrator.js +1 -0
- package/app/controllers/settings/orchestrator.js +1 -0
- package/app/controllers/settings/scheduling.js +1 -0
- package/app/routes/operations/orchestrator.js +1 -0
- package/app/routes/settings/orchestrator.js +1 -0
- package/app/routes/settings/scheduling.js +1 -0
- package/app/services/maintenance-schedule-actions.js +1 -0
- package/app/services/orchestration-engine-interface.js +1 -0
- package/app/services/orchestration-engine.js +1 -0
- package/app/services/order-allocation.js +1 -0
- package/app/services/scheduling.js +1 -0
- package/app/services/vroom-allocation-engine.js +1 -0
- package/app/templates/settings/scheduling.js +1 -0
- package/app/utils/create-full-calendar-event-from-schedule-item.js +1 -0
- package/app/utils/route-colors.js +1 -0
- package/composer.json +4 -2
- package/extension.json +1 -1
- package/package.json +6 -5
- package/server/config/fleetops.php +20 -1
- package/server/migrations/2025_08_28_054927_create_parts_table.php +2 -2
- package/server/migrations/2025_08_28_054932_add_public_id_to_maintenance_tables.php +45 -0
- package/server/migrations/2025_09_01_000001_create_maintenance_schedules_table.php +88 -0
- package/server/migrations/2026_04_01_000001_fix_monetary_columns_in_parts_table.php +48 -0
- package/server/migrations/2026_04_01_000003_add_photo_uuid_to_equipment_and_parts_tables.php +61 -0
- package/server/migrations/2026_04_01_000004_add_public_id_to_equipments_table.php +38 -0
- package/server/migrations/2026_04_01_000005_add_missing_columns_to_parts_table.php +67 -0
- package/server/migrations/2026_04_04_000001_add_reminder_offsets_to_maintenance_schedules.php +44 -0
- package/server/migrations/2026_04_08_000001_add_orchestrator_columns_to_vehicles_table.php +53 -0
- package/server/migrations/2026_04_08_000002_add_orchestrator_columns_to_drivers_table.php +41 -0
- package/server/migrations/2026_04_08_000003_add_orchestrator_columns_to_orders_table.php +38 -0
- package/server/migrations/2026_04_08_000004_add_orchestrator_columns_to_payloads_table.php +38 -0
- package/server/migrations/2026_04_08_000005_add_orchestrator_columns_to_waypoints_table.php +38 -0
- package/server/migrations/2026_04_09_000001_create_manifests_table.php +48 -0
- package/server/migrations/2026_04_09_000002_create_manifest_stops_table.php +48 -0
- package/server/migrations/2026_04_09_000003_add_manifest_uuid_to_orders_table.php +28 -0
- package/server/migrations/2026_04_13_000001_add_pod_notes_columns_to_waypoints_table.php +39 -0
- package/server/migrations/2026_04_14_000001_drop_redundant_capacity_columns_from_payloads_table.php +42 -0
- package/server/migrations/2026_04_14_000002_rename_capacity_columns_on_vehicles_table.php +48 -0
- package/server/resources/views/mail/maintenance-schedule-reminder.blade.php +59 -0
- package/server/resources/views/mail/work-order-dispatched.blade.php +67 -0
- package/server/src/Auth/Schemas/FleetOps.php +44 -0
- package/server/src/Console/Commands/ProcessMaintenanceTriggers.php +150 -0
- package/server/src/Console/Commands/SendMaintenanceReminders.php +128 -0
- package/server/src/Http/Controllers/Api/v1/OrderController.php +15 -2
- package/server/src/Http/Controllers/Api/v1/VehicleController.php +18 -2
- package/server/src/Http/Controllers/Internal/v1/DriverController.php +1 -0
- package/server/src/Http/Controllers/Internal/v1/EquipmentController.php +27 -0
- package/server/src/Http/Controllers/Internal/v1/LiveController.php +9 -2
- package/server/src/Http/Controllers/Internal/v1/MaintenanceController.php +165 -0
- package/server/src/Http/Controllers/Internal/v1/MaintenanceScheduleController.php +304 -0
- package/server/src/Http/Controllers/Internal/v1/ManifestController.php +138 -0
- package/server/src/Http/Controllers/Internal/v1/OrchestrationController.php +975 -0
- package/server/src/Http/Controllers/Internal/v1/OrderController.php +42 -0
- package/server/src/Http/Controllers/Internal/v1/PartController.php +27 -0
- package/server/src/Http/Controllers/Internal/v1/SettingController.php +118 -0
- package/server/src/Http/Controllers/Internal/v1/Traits/DriverSchedulingTrait.php +214 -0
- package/server/src/Http/Controllers/Internal/v1/WorkOrderController.php +68 -0
- package/server/src/Http/Resources/v1/Driver.php +1 -0
- package/server/src/Http/Resources/v1/Maintenance.php +138 -0
- package/server/src/Http/Resources/v1/MaintenanceSchedule.php +137 -0
- package/server/src/Http/Resources/v1/Orchestrator/Order.php +116 -0
- package/server/src/Http/Resources/v1/Order.php +7 -4
- package/server/src/Http/Resources/v1/Waypoint.php +7 -0
- package/server/src/Http/Resources/v1/WorkOrder.php +136 -0
- package/server/src/Imports/EquipmentImport.php +32 -0
- package/server/src/Imports/MaintenanceImport.php +32 -0
- package/server/src/Imports/MaintenanceScheduleImport.php +32 -0
- package/server/src/Imports/PartImport.php +32 -0
- package/server/src/Imports/WorkOrderImport.php +32 -0
- package/server/src/Jobs/ProcessAllocationJob.php +119 -0
- package/server/src/Listeners/HandleDeliveryCompletion.php +47 -0
- package/server/src/Listeners/NotifyDriverOnShiftChange.php +63 -0
- package/server/src/Mail/MaintenanceScheduleReminder.php +68 -0
- package/server/src/Mail/WorkOrderDispatched.php +58 -0
- package/server/src/Models/Asset.php +2 -2
- package/server/src/Models/Device.php +1 -1
- package/server/src/Models/Driver.php +82 -4
- package/server/src/Models/Equipment.php +62 -2
- package/server/src/Models/Maintenance.php +127 -9
- package/server/src/Models/MaintenanceSchedule.php +353 -0
- package/server/src/Models/Manifest.php +214 -0
- package/server/src/Models/ManifestStop.php +162 -0
- package/server/src/Models/Order.php +70 -0
- package/server/src/Models/OrderConfig.php +5 -2
- package/server/src/Models/Part.php +69 -3
- package/server/src/Models/Place.php +1 -1
- package/server/src/Models/Sensor.php +1 -1
- package/server/src/Models/ServiceQuote.php +1 -1
- package/server/src/Models/Vehicle.php +18 -1
- package/server/src/Models/Warranty.php +1 -1
- package/server/src/Models/Waypoint.php +7 -1
- package/server/src/Models/WorkOrder.php +122 -12
- package/server/src/Notifications/DriverShiftChanged.php +110 -0
- package/server/src/Observers/WorkOrderObserver.php +107 -0
- package/server/src/Orchestration/Contracts/OrchestrationEngineInterface.php +63 -0
- package/server/src/Orchestration/Engines/DriverAssignmentEngine.php +265 -0
- package/server/src/Orchestration/Engines/GreedyOrchestrationEngine.php +155 -0
- package/server/src/Orchestration/Engines/RouteSequencingEngine.php +272 -0
- package/server/src/Orchestration/Engines/VroomOrchestrationEngine.php +192 -0
- package/server/src/Orchestration/OrchestrationEngineRegistry.php +83 -0
- package/server/src/Orchestration/Support/OrchestrationPayloadBuilder.php +380 -0
- package/server/src/Providers/EventServiceProvider.php +7 -1
- package/server/src/Providers/FleetOpsServiceProvider.php +42 -15
- package/server/src/routes.php +65 -4
- package/translations/ar-ae.yml +44 -12
- package/translations/bg-bg.yaml +51 -10
- package/translations/en-us.yaml +444 -1
- package/translations/fr-fr.yaml +51 -10
- package/translations/mn-mn.yaml +51 -10
- package/translations/pt-br.yaml +51 -10
- package/translations/ru-ru.yaml +51 -10
- package/translations/vi-vn.yaml +48 -12
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\FleetOps\Jobs;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\FleetOps\Models\Driver;
|
|
6
|
+
use Fleetbase\FleetOps\Models\Order;
|
|
7
|
+
use Fleetbase\FleetOps\Models\Vehicle;
|
|
8
|
+
use Fleetbase\FleetOps\Orchestration\OrchestrationEngineRegistry;
|
|
9
|
+
use Fleetbase\Models\Setting;
|
|
10
|
+
use Illuminate\Bus\Queueable;
|
|
11
|
+
use Illuminate\Contracts\Queue\ShouldQueue;
|
|
12
|
+
use Illuminate\Foundation\Bus\Dispatchable;
|
|
13
|
+
use Illuminate\Queue\InteractsWithQueue;
|
|
14
|
+
use Illuminate\Queue\SerializesModels;
|
|
15
|
+
use Illuminate\Support\Facades\Log;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* ProcessAllocationJob.
|
|
19
|
+
*
|
|
20
|
+
* Dispatched asynchronously when auto-allocation is triggered (e.g. on order
|
|
21
|
+
* creation or on delivery completion when auto_reallocate_on_complete is
|
|
22
|
+
* enabled). The job runs the active allocation engine and commits all
|
|
23
|
+
* assignments automatically.
|
|
24
|
+
*
|
|
25
|
+
* The job is idempotent — if an order has already been assigned by the time
|
|
26
|
+
* the job runs, it is silently skipped.
|
|
27
|
+
*
|
|
28
|
+
* @example Dispatching from a listener:
|
|
29
|
+
* ProcessAllocationJob::dispatch($companyUuid, $orderIds);
|
|
30
|
+
*/
|
|
31
|
+
class ProcessAllocationJob implements ShouldQueue
|
|
32
|
+
{
|
|
33
|
+
use Dispatchable;
|
|
34
|
+
use InteractsWithQueue;
|
|
35
|
+
use Queueable;
|
|
36
|
+
use SerializesModels;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Maximum number of retry attempts before the job is marked as failed.
|
|
40
|
+
*/
|
|
41
|
+
public int $tries = 3;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @param string $companyUuid the company to run allocation for
|
|
45
|
+
* @param array $orderIds Optional list of order public_ids to allocate.
|
|
46
|
+
* If empty, all unassigned orders are used.
|
|
47
|
+
*/
|
|
48
|
+
public function __construct(
|
|
49
|
+
protected string $companyUuid,
|
|
50
|
+
protected array $orderIds = [],
|
|
51
|
+
) {
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public function handle(OrchestrationEngineRegistry $registry): void
|
|
55
|
+
{
|
|
56
|
+
$ordersQuery = Order::where('company_uuid', $this->companyUuid)
|
|
57
|
+
->whereNull('driver_assigned_uuid')
|
|
58
|
+
->whereNotIn('status', ['completed', 'cancelled'])
|
|
59
|
+
->with(['payload.dropoff', 'payload.waypoints']);
|
|
60
|
+
|
|
61
|
+
if (!empty($this->orderIds)) {
|
|
62
|
+
$ordersQuery->whereIn('public_id', $this->orderIds);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
$orders = $ordersQuery->get();
|
|
66
|
+
|
|
67
|
+
if ($orders->isEmpty()) {
|
|
68
|
+
Log::info("[ProcessAllocationJob] No unassigned orders for company {$this->companyUuid}.");
|
|
69
|
+
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
$vehicles = Vehicle::where('company_uuid', $this->companyUuid)
|
|
74
|
+
->with(['driver' => fn ($q) => $q->where('online', true)])
|
|
75
|
+
->get()
|
|
76
|
+
->filter(fn ($v) => $v->driver !== null);
|
|
77
|
+
|
|
78
|
+
if ($vehicles->isEmpty()) {
|
|
79
|
+
Log::info("[ProcessAllocationJob] No available vehicles for company {$this->companyUuid}.");
|
|
80
|
+
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
$engineId = Setting::lookup('fleetops.orchestrator_engine', 'greedy');
|
|
85
|
+
$engine = $registry->resolve($engineId);
|
|
86
|
+
|
|
87
|
+
$result = $engine->allocate($orders, $vehicles, [
|
|
88
|
+
'max_travel_time' => Setting::lookup('fleetops.allocation_max_travel_time', 3600),
|
|
89
|
+
'balance_workload' => Setting::lookup('fleetops.allocation_balance_workload', false),
|
|
90
|
+
]);
|
|
91
|
+
|
|
92
|
+
foreach ($result['assignments'] as $assignment) {
|
|
93
|
+
$order = Order::where('public_id', $assignment['order_id'])->first();
|
|
94
|
+
$driver = Driver::where('public_id', $assignment['driver_id'])->first();
|
|
95
|
+
|
|
96
|
+
if (!$order || !$driver) {
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Skip if already assigned (idempotency guard)
|
|
101
|
+
if ($order->driver_assigned_uuid) {
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
$order->driver_assigned_uuid = $driver->uuid;
|
|
106
|
+
$order->save();
|
|
107
|
+
$order->firstDispatchWithActivity();
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
Log::info(
|
|
111
|
+
sprintf(
|
|
112
|
+
'[ProcessAllocationJob] Committed %d assignments, %d unassigned for company %s.',
|
|
113
|
+
count($result['assignments']),
|
|
114
|
+
count($result['unassigned']),
|
|
115
|
+
$this->companyUuid
|
|
116
|
+
)
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\FleetOps\Listeners;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\FleetOps\Events\OrderCompleted;
|
|
6
|
+
use Fleetbase\FleetOps\Jobs\ProcessAllocationJob;
|
|
7
|
+
use Fleetbase\Models\Setting;
|
|
8
|
+
use Illuminate\Contracts\Queue\ShouldQueue;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* HandleDeliveryCompletion.
|
|
12
|
+
*
|
|
13
|
+
* Listens for the OrderCompleted event and dispatches a new allocation run
|
|
14
|
+
* when the 'auto_reallocate_on_complete' setting is enabled.
|
|
15
|
+
*
|
|
16
|
+
* This closes the re-allocation loop: as drivers complete deliveries and
|
|
17
|
+
* become available, the engine automatically picks up the next batch of
|
|
18
|
+
* unassigned orders without dispatcher intervention.
|
|
19
|
+
*
|
|
20
|
+
* The listener is registered in EventServiceProvider alongside the existing
|
|
21
|
+
* HandleOrderDispatched and HandleOrderReady listeners.
|
|
22
|
+
*/
|
|
23
|
+
class HandleDeliveryCompletion implements ShouldQueue
|
|
24
|
+
{
|
|
25
|
+
/**
|
|
26
|
+
* Handle the OrderCompleted event.
|
|
27
|
+
*/
|
|
28
|
+
public function handle(OrderCompleted $event): void
|
|
29
|
+
{
|
|
30
|
+
$order = $event->order ?? null;
|
|
31
|
+
|
|
32
|
+
if (!$order) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
$companyUuid = $order->company_uuid;
|
|
37
|
+
|
|
38
|
+
// Only re-allocate if the setting is enabled for this company
|
|
39
|
+
if (!Setting::lookup('fleetops.auto_reallocate_on_complete', false)) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Dispatch the allocation job asynchronously so it does not block
|
|
44
|
+
// the order completion response.
|
|
45
|
+
ProcessAllocationJob::dispatch($companyUuid);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\FleetOps\Listeners;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\FleetOps\Models\Driver;
|
|
6
|
+
use Fleetbase\FleetOps\Notifications\DriverShiftChanged;
|
|
7
|
+
use Fleetbase\Models\Schedule;
|
|
8
|
+
use Fleetbase\Models\ScheduleItem;
|
|
9
|
+
use Fleetbase\Models\Setting;
|
|
10
|
+
use Illuminate\Contracts\Queue\ShouldQueue;
|
|
11
|
+
use Illuminate\Queue\InteractsWithQueue;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Listener: NotifyDriverOnShiftChange.
|
|
15
|
+
*
|
|
16
|
+
* Fires after a ScheduleItem is created or updated. Checks the company-level
|
|
17
|
+
* `notify_drivers_on_shift_change` scheduling setting and, if enabled, sends
|
|
18
|
+
* a DriverShiftChanged mail notification to the driver who owns the schedule.
|
|
19
|
+
*/
|
|
20
|
+
class NotifyDriverOnShiftChange implements ShouldQueue
|
|
21
|
+
{
|
|
22
|
+
use InteractsWithQueue;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Handle the event.
|
|
26
|
+
*
|
|
27
|
+
* @param object $event Either ScheduleItemCreated or ScheduleItemUpdated
|
|
28
|
+
*/
|
|
29
|
+
public function handle($event): void
|
|
30
|
+
{
|
|
31
|
+
/** @var ScheduleItem $scheduleItem */
|
|
32
|
+
$scheduleItem = $event->scheduleItem ?? null;
|
|
33
|
+
if (!$scheduleItem instanceof ScheduleItem) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Load the parent schedule to find the subject (driver)
|
|
38
|
+
/** @var Schedule|null $schedule */
|
|
39
|
+
$schedule = $scheduleItem->schedule()->with('subject')->first();
|
|
40
|
+
if (!$schedule) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Only proceed if the subject is a Driver
|
|
45
|
+
$subject = $schedule->subject;
|
|
46
|
+
if (!$subject instanceof Driver) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Check the company-level scheduling setting
|
|
51
|
+
$settings = Setting::lookupFromCompany('fleet-ops.scheduling-settings', []);
|
|
52
|
+
$shouldNotify = (bool) data_get($settings, 'notify_drivers_on_shift_change', false);
|
|
53
|
+
if (!$shouldNotify) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Determine if this is a new shift or an update
|
|
58
|
+
$isNew = $event instanceof \Fleetbase\Events\ScheduleItemCreated;
|
|
59
|
+
|
|
60
|
+
// Send the notification to the driver
|
|
61
|
+
$subject->notify(new DriverShiftChanged($scheduleItem, $isNew));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\FleetOps\Mail;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\FleetOps\Models\MaintenanceSchedule;
|
|
6
|
+
use Illuminate\Bus\Queueable;
|
|
7
|
+
use Illuminate\Mail\Mailable;
|
|
8
|
+
use Illuminate\Mail\Mailables\Content;
|
|
9
|
+
use Illuminate\Mail\Mailables\Envelope;
|
|
10
|
+
use Illuminate\Queue\SerializesModels;
|
|
11
|
+
|
|
12
|
+
class MaintenanceScheduleReminder extends Mailable
|
|
13
|
+
{
|
|
14
|
+
use Queueable;
|
|
15
|
+
use SerializesModels;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The maintenance schedule this reminder is for.
|
|
19
|
+
*/
|
|
20
|
+
public MaintenanceSchedule $schedule;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* How many days before the due date this reminder is firing.
|
|
24
|
+
*/
|
|
25
|
+
public int $offsetDays;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Create a new message instance.
|
|
29
|
+
*/
|
|
30
|
+
public function __construct(MaintenanceSchedule $schedule, int $offsetDays)
|
|
31
|
+
{
|
|
32
|
+
$this->schedule = $schedule;
|
|
33
|
+
$this->offsetDays = $offsetDays;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Get the message envelope.
|
|
38
|
+
*/
|
|
39
|
+
public function envelope(): Envelope
|
|
40
|
+
{
|
|
41
|
+
$subject = 'Maintenance Reminder: ' . $this->schedule->name;
|
|
42
|
+
|
|
43
|
+
if ($this->schedule->subject) {
|
|
44
|
+
$assetName = $this->schedule->subject->name
|
|
45
|
+
?? $this->schedule->subject->display_name
|
|
46
|
+
?? $this->schedule->subject->public_id;
|
|
47
|
+
$subject .= ' — ' . $assetName;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return new Envelope(subject: $subject);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Get the message content definition.
|
|
55
|
+
*/
|
|
56
|
+
public function content(): Content
|
|
57
|
+
{
|
|
58
|
+
return new Content(
|
|
59
|
+
markdown: 'fleetops::mail.maintenance-schedule-reminder',
|
|
60
|
+
with: [
|
|
61
|
+
'schedule' => $this->schedule,
|
|
62
|
+
'assignee' => $this->schedule->defaultAssignee,
|
|
63
|
+
'subject' => $this->schedule->subject,
|
|
64
|
+
'offsetDays' => $this->offsetDays,
|
|
65
|
+
]
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\FleetOps\Mail;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\FleetOps\Models\WorkOrder;
|
|
6
|
+
use Illuminate\Bus\Queueable;
|
|
7
|
+
use Illuminate\Mail\Mailable;
|
|
8
|
+
use Illuminate\Mail\Mailables\Content;
|
|
9
|
+
use Illuminate\Mail\Mailables\Envelope;
|
|
10
|
+
use Illuminate\Queue\SerializesModels;
|
|
11
|
+
|
|
12
|
+
class WorkOrderDispatched extends Mailable
|
|
13
|
+
{
|
|
14
|
+
use Queueable;
|
|
15
|
+
use SerializesModels;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The work order being dispatched.
|
|
19
|
+
*/
|
|
20
|
+
public WorkOrder $workOrder;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Create a new message instance.
|
|
24
|
+
*/
|
|
25
|
+
public function __construct(WorkOrder $workOrder)
|
|
26
|
+
{
|
|
27
|
+
$this->workOrder = $workOrder;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Get the message envelope.
|
|
32
|
+
*/
|
|
33
|
+
public function envelope(): Envelope
|
|
34
|
+
{
|
|
35
|
+
$subject = 'Work Order #' . $this->workOrder->public_id;
|
|
36
|
+
|
|
37
|
+
if ($this->workOrder->subject) {
|
|
38
|
+
$subject .= ': ' . $this->workOrder->subject;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return new Envelope(subject: $subject);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Get the message content definition.
|
|
46
|
+
*/
|
|
47
|
+
public function content(): Content
|
|
48
|
+
{
|
|
49
|
+
return new Content(
|
|
50
|
+
markdown: 'fleetops::mail.work-order-dispatched',
|
|
51
|
+
with: [
|
|
52
|
+
'workOrder' => $this->workOrder,
|
|
53
|
+
'assignee' => $this->workOrder->assignee,
|
|
54
|
+
'target' => $this->workOrder->target,
|
|
55
|
+
]
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -210,12 +210,12 @@ class Asset extends Model
|
|
|
210
210
|
|
|
211
211
|
public function assignedTo(): MorphTo
|
|
212
212
|
{
|
|
213
|
-
return $this->morphTo();
|
|
213
|
+
return $this->morphTo(__FUNCTION__, 'assigned_to_type', 'assigned_to_uuid');
|
|
214
214
|
}
|
|
215
215
|
|
|
216
216
|
public function operator(): MorphTo
|
|
217
217
|
{
|
|
218
|
-
return $this->morphTo();
|
|
218
|
+
return $this->morphTo(__FUNCTION__, 'operator_type', 'operator_uuid');
|
|
219
219
|
}
|
|
220
220
|
|
|
221
221
|
public function category(): BelongsTo
|
|
@@ -11,6 +11,9 @@ use Fleetbase\LaravelMysqlSpatial\Eloquent\SpatialTrait;
|
|
|
11
11
|
use Fleetbase\LaravelMysqlSpatial\Types\Point as SpatialPoint;
|
|
12
12
|
use Fleetbase\Models\File;
|
|
13
13
|
use Fleetbase\Models\Model;
|
|
14
|
+
use Fleetbase\Models\Schedule;
|
|
15
|
+
use Fleetbase\Models\ScheduleAvailability;
|
|
16
|
+
use Fleetbase\Models\ScheduleItem;
|
|
14
17
|
use Fleetbase\Models\User;
|
|
15
18
|
use Fleetbase\Traits\HasApiModelBehavior;
|
|
16
19
|
use Fleetbase\Traits\HasApiModelCache;
|
|
@@ -25,6 +28,8 @@ use Illuminate\Database\Eloquent\Builder;
|
|
|
25
28
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
26
29
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
27
30
|
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
|
|
31
|
+
use Illuminate\Database\Eloquent\Relations\MorphMany;
|
|
32
|
+
use Illuminate\Database\Eloquent\Relations\MorphOne;
|
|
28
33
|
use Illuminate\Notifications\Notifiable;
|
|
29
34
|
use Illuminate\Support\Arr;
|
|
30
35
|
use Illuminate\Support\Collection;
|
|
@@ -105,6 +110,12 @@ class Driver extends Model
|
|
|
105
110
|
'slug',
|
|
106
111
|
'status',
|
|
107
112
|
'meta,',
|
|
113
|
+
// Orchestrator
|
|
114
|
+
'skills',
|
|
115
|
+
'max_travel_time',
|
|
116
|
+
'max_distance',
|
|
117
|
+
'time_window_start',
|
|
118
|
+
'time_window_end',
|
|
108
119
|
];
|
|
109
120
|
|
|
110
121
|
/**
|
|
@@ -127,9 +138,13 @@ class Driver extends Model
|
|
|
127
138
|
* @var array
|
|
128
139
|
*/
|
|
129
140
|
protected $casts = [
|
|
130
|
-
'location'
|
|
131
|
-
'online'
|
|
132
|
-
'meta'
|
|
141
|
+
'location' => Point::class,
|
|
142
|
+
'online' => 'boolean',
|
|
143
|
+
'meta' => Json::class,
|
|
144
|
+
// Orchestrator
|
|
145
|
+
'skills' => Json::class,
|
|
146
|
+
'max_travel_time' => 'integer',
|
|
147
|
+
'max_distance' => 'integer',
|
|
133
148
|
];
|
|
134
149
|
|
|
135
150
|
/**
|
|
@@ -300,6 +315,69 @@ class Driver extends Model
|
|
|
300
315
|
return $this->hasMany(\Fleetbase\Models\UserDevice::class, 'user_uuid', 'user_uuid');
|
|
301
316
|
}
|
|
302
317
|
|
|
318
|
+
/**
|
|
319
|
+
* Get all schedules assigned to this driver.
|
|
320
|
+
* The driver acts as the polymorphic `subject` on the Schedule model.
|
|
321
|
+
*/
|
|
322
|
+
public function schedules(): MorphMany
|
|
323
|
+
{
|
|
324
|
+
// Explicit FK columns required — Fleetbase uses *_uuid not *_id
|
|
325
|
+
return $this->morphMany(Schedule::class, 'subject', 'subject_type', 'subject_uuid');
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Get all individual schedule items (shifts) assigned to this driver.
|
|
330
|
+
* The driver acts as the polymorphic `assignee` on the ScheduleItem model.
|
|
331
|
+
*/
|
|
332
|
+
public function scheduleItems(): MorphMany
|
|
333
|
+
{
|
|
334
|
+
// Explicit FK columns required — Fleetbase uses *_uuid not *_id
|
|
335
|
+
return $this->morphMany(ScheduleItem::class, 'assignee', 'assignee_type', 'assignee_uuid');
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* The driver's current active shift — the ScheduleItem whose window
|
|
340
|
+
* contains the current timestamp and whose status is 'scheduled' or 'active'.
|
|
341
|
+
*
|
|
342
|
+
* Exposed as an eager-loadable MorphOne so the order scheduler route can
|
|
343
|
+
* request it via with: ['currentShift'] without triggering an N+1 query.
|
|
344
|
+
* The FullCalendar resource timeline uses this to render shift-window
|
|
345
|
+
* background events for each driver resource row.
|
|
346
|
+
*/
|
|
347
|
+
public function currentShift(): MorphOne
|
|
348
|
+
{
|
|
349
|
+
return $this->morphOne(ScheduleItem::class, 'assignee', 'assignee_type', 'assignee_uuid')
|
|
350
|
+
->whereIn('status', ['scheduled', 'active'])
|
|
351
|
+
->where('start_at', '<=', now())
|
|
352
|
+
->where('end_at', '>=', now())
|
|
353
|
+
->latest('start_at');
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Get the active schedule item (shift) for a given date.
|
|
358
|
+
* Used by OrchestrationPayloadBuilder to inject time_window constraints.
|
|
359
|
+
*/
|
|
360
|
+
public function activeShiftFor(?\DateTimeInterface $date = null): ?ScheduleItem
|
|
361
|
+
{
|
|
362
|
+
$date = $date ?? now();
|
|
363
|
+
|
|
364
|
+
return $this->scheduleItems()
|
|
365
|
+
->whereDate('start_at', $date)
|
|
366
|
+
->whereIn('status', ['pending', 'active'])
|
|
367
|
+
->orderBy('start_at')
|
|
368
|
+
->first();
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Get all availability records (time-off, preferred hours) for this driver.
|
|
373
|
+
* The driver acts as the polymorphic `subject` on the ScheduleAvailability model.
|
|
374
|
+
*/
|
|
375
|
+
public function availabilities(): MorphMany
|
|
376
|
+
{
|
|
377
|
+
// Explicit FK columns required — Fleetbase uses *_uuid not *_id
|
|
378
|
+
return $this->morphMany(ScheduleAvailability::class, 'subject', 'subject_type', 'subject_uuid');
|
|
379
|
+
}
|
|
380
|
+
|
|
303
381
|
/**
|
|
304
382
|
* Get avatar url.
|
|
305
383
|
*/
|
|
@@ -364,7 +442,7 @@ class Driver extends Model
|
|
|
364
442
|
function ($option) {
|
|
365
443
|
$key = str_replace(['.svg', '.png'], '', $option);
|
|
366
444
|
|
|
367
|
-
return [$key => Utils::
|
|
445
|
+
return [$key => Utils::assetFromFleetbase('static/driver-icons/' . $option)];
|
|
368
446
|
}
|
|
369
447
|
);
|
|
370
448
|
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
namespace Fleetbase\FleetOps\Models;
|
|
4
4
|
|
|
5
5
|
use Fleetbase\Casts\Json;
|
|
6
|
+
use Fleetbase\Casts\Money;
|
|
7
|
+
use Fleetbase\FleetOps\Support\Utils;
|
|
6
8
|
use Fleetbase\Models\File;
|
|
7
9
|
use Fleetbase\Models\Model;
|
|
8
10
|
use Fleetbase\Models\User;
|
|
@@ -87,6 +89,7 @@ class Equipment extends Model
|
|
|
87
89
|
'equipable_uuid',
|
|
88
90
|
'purchased_at',
|
|
89
91
|
'purchase_price',
|
|
92
|
+
'currency',
|
|
90
93
|
'meta',
|
|
91
94
|
'slug',
|
|
92
95
|
];
|
|
@@ -119,7 +122,8 @@ class Equipment extends Model
|
|
|
119
122
|
*/
|
|
120
123
|
protected $casts = [
|
|
121
124
|
'purchased_at' => 'date',
|
|
122
|
-
|
|
125
|
+
// Money values
|
|
126
|
+
'purchase_price' => Money::class,
|
|
123
127
|
'meta' => Json::class,
|
|
124
128
|
];
|
|
125
129
|
|
|
@@ -184,7 +188,7 @@ class Equipment extends Model
|
|
|
184
188
|
|
|
185
189
|
public function equipable(): MorphTo
|
|
186
190
|
{
|
|
187
|
-
return $this->morphTo();
|
|
191
|
+
return $this->morphTo(__FUNCTION__, 'equipable_type', 'equipable_uuid');
|
|
188
192
|
}
|
|
189
193
|
|
|
190
194
|
public function maintenances(): HasMany
|
|
@@ -480,4 +484,60 @@ class Equipment extends Model
|
|
|
480
484
|
|
|
481
485
|
return null;
|
|
482
486
|
}
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* Create an Equipment instance from an import row.
|
|
490
|
+
*
|
|
491
|
+
* Monetary values (purchase_price) must be supplied in cents (integers).
|
|
492
|
+
* The Money cast will strip non-numeric characters before storage.
|
|
493
|
+
*
|
|
494
|
+
* @param array $row Associative array from the import spreadsheet
|
|
495
|
+
* @param bool $saveInstance Whether to persist the record immediately
|
|
496
|
+
*/
|
|
497
|
+
public static function createFromImport(array $row, bool $saveInstance = false): Equipment
|
|
498
|
+
{
|
|
499
|
+
$row = array_filter($row);
|
|
500
|
+
|
|
501
|
+
$name = Utils::or($row, ['name']);
|
|
502
|
+
$code = Utils::or($row, ['code', 'internal_id']);
|
|
503
|
+
$type = Utils::or($row, ['type'], 'equipment');
|
|
504
|
+
$status = Utils::or($row, ['status'], 'operational');
|
|
505
|
+
$serialNumber = Utils::or($row, ['serial_number', 'serial']);
|
|
506
|
+
$manufacturer = Utils::or($row, ['manufacturer', 'make', 'brand']);
|
|
507
|
+
$model = Utils::or($row, ['model', 'equipment_model']);
|
|
508
|
+
$purchasePrice = Utils::or($row, ['purchase_price', 'price', 'cost']);
|
|
509
|
+
$currency = Utils::or($row, ['currency'], 'USD');
|
|
510
|
+
$purchasedAt = Utils::or($row, ['purchased_at', 'purchase_date']);
|
|
511
|
+
$warrantyName = Utils::or($row, ['warranty_name', 'warranty']);
|
|
512
|
+
|
|
513
|
+
$equipment = new static([
|
|
514
|
+
'company_uuid' => session('company'),
|
|
515
|
+
'name' => $name,
|
|
516
|
+
'code' => $code,
|
|
517
|
+
'type' => $type,
|
|
518
|
+
'status' => $status,
|
|
519
|
+
'serial_number' => $serialNumber,
|
|
520
|
+
'manufacturer' => $manufacturer,
|
|
521
|
+
'model' => $model,
|
|
522
|
+
'purchase_price' => $purchasePrice,
|
|
523
|
+
'currency' => strtoupper($currency ?? 'USD'),
|
|
524
|
+
'purchased_at' => $purchasedAt ? \Carbon\Carbon::parse($purchasedAt) : null,
|
|
525
|
+
]);
|
|
526
|
+
|
|
527
|
+
// Attempt to resolve warranty by name
|
|
528
|
+
if ($warrantyName) {
|
|
529
|
+
$warranty = Warranty::where('company_uuid', session('company'))
|
|
530
|
+
->where('name', 'like', '%' . $warrantyName . '%')
|
|
531
|
+
->first();
|
|
532
|
+
if ($warranty) {
|
|
533
|
+
$equipment->warranty_uuid = $warranty->uuid;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
if ($saveInstance === true) {
|
|
538
|
+
$equipment->save();
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
return $equipment;
|
|
542
|
+
}
|
|
483
543
|
}
|