@fleetbase/fleetops-engine 0.6.37 → 0.6.39
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 +40 -36
- package/addon/components/layout/fleet-ops-sidebar.js +61 -10
- 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 +1087 -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 +30 -0
- package/addon/components/vehicle/form.hbs +39 -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/details.js +5 -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 +74 -1
- 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/orders/index/details/virtual.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 +33 -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 +80 -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/details/virtual.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/operations/orders/index/details/virtual.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/operations/orders/index/details/virtual.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 +5 -3
- 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 +58 -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 +41 -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/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/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/Payload.php +7 -2
- 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 +20 -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 +290 -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
|
@@ -113,6 +113,22 @@ class FleetOps
|
|
|
113
113
|
'name' => 'issue',
|
|
114
114
|
'actions' => ['export', 'import'],
|
|
115
115
|
],
|
|
116
|
+
[
|
|
117
|
+
'name' => 'maintenance',
|
|
118
|
+
'actions' => ['export', 'import'],
|
|
119
|
+
],
|
|
120
|
+
[
|
|
121
|
+
'name' => 'work-order',
|
|
122
|
+
'actions' => ['export', 'import'],
|
|
123
|
+
],
|
|
124
|
+
[
|
|
125
|
+
'name' => 'equipment',
|
|
126
|
+
'actions' => ['export', 'import'],
|
|
127
|
+
],
|
|
128
|
+
[
|
|
129
|
+
'name' => 'part',
|
|
130
|
+
'actions' => ['export', 'import'],
|
|
131
|
+
],
|
|
116
132
|
[
|
|
117
133
|
'name' => 'custom-field',
|
|
118
134
|
'actions' => [],
|
|
@@ -264,6 +280,23 @@ class FleetOps
|
|
|
264
280
|
'list order',
|
|
265
281
|
],
|
|
266
282
|
],
|
|
283
|
+
[
|
|
284
|
+
'name' => 'MaintenanceManager',
|
|
285
|
+
'description' => 'Policy for managing maintenance records, work orders, equipment, and parts.',
|
|
286
|
+
'permissions' => [
|
|
287
|
+
'see extension',
|
|
288
|
+
'* maintenance',
|
|
289
|
+
'* work-order',
|
|
290
|
+
'* equipment',
|
|
291
|
+
'* part',
|
|
292
|
+
'see vehicle',
|
|
293
|
+
'list vehicle',
|
|
294
|
+
'view vehicle',
|
|
295
|
+
'see driver',
|
|
296
|
+
'list driver',
|
|
297
|
+
'view driver',
|
|
298
|
+
],
|
|
299
|
+
],
|
|
267
300
|
[
|
|
268
301
|
'name' => 'OperationsAdmin',
|
|
269
302
|
'description' => 'Policy for monitoring activities, issues, and fuel reports within the fleet operations.',
|
|
@@ -276,6 +309,10 @@ class FleetOps
|
|
|
276
309
|
'* fuel-report',
|
|
277
310
|
'* issue',
|
|
278
311
|
'* place',
|
|
312
|
+
'* maintenance',
|
|
313
|
+
'* work-order',
|
|
314
|
+
'* equipment',
|
|
315
|
+
'* part',
|
|
279
316
|
],
|
|
280
317
|
],
|
|
281
318
|
[
|
|
@@ -370,6 +407,13 @@ class FleetOps
|
|
|
370
407
|
'OperationsAdmin',
|
|
371
408
|
],
|
|
372
409
|
],
|
|
410
|
+
[
|
|
411
|
+
'name' => 'Maintenance Technician',
|
|
412
|
+
'description' => 'Role for technicians responsible for managing maintenance records, work orders, equipment, and parts inventory.',
|
|
413
|
+
'policies' => [
|
|
414
|
+
'MaintenanceManager',
|
|
415
|
+
],
|
|
416
|
+
],
|
|
373
417
|
[
|
|
374
418
|
'name' => 'Driver Coordinator',
|
|
375
419
|
'description' => 'Role responsible for coordinating drivers, vehicles, and orders.',
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\FleetOps\Console\Commands;
|
|
4
|
+
|
|
5
|
+
use Carbon\Carbon;
|
|
6
|
+
use Fleetbase\FleetOps\Models\MaintenanceSchedule;
|
|
7
|
+
use Fleetbase\FleetOps\Models\Vehicle;
|
|
8
|
+
use Fleetbase\FleetOps\Models\WorkOrder;
|
|
9
|
+
use Illuminate\Console\Command;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* ProcessMaintenanceTriggers.
|
|
13
|
+
*
|
|
14
|
+
* Scans all active MaintenanceSchedule records and determines whether a
|
|
15
|
+
* preventive maintenance work order should be created based on:
|
|
16
|
+
*
|
|
17
|
+
* - Time/date thresholds (next_due_date)
|
|
18
|
+
* - Odometer thresholds (next_due_odometer vs. current vehicle odometer)
|
|
19
|
+
* - Engine-hour thresholds (next_due_engine_hours vs. current engine hours)
|
|
20
|
+
*
|
|
21
|
+
* When a schedule is triggered, a WorkOrder is automatically created from the
|
|
22
|
+
* schedule's default settings and a `maintenance.triggered` event is dispatched.
|
|
23
|
+
*
|
|
24
|
+
* Designed to run on a scheduled basis (e.g. daily via the Laravel scheduler).
|
|
25
|
+
*/
|
|
26
|
+
class ProcessMaintenanceTriggers extends Command
|
|
27
|
+
{
|
|
28
|
+
/**
|
|
29
|
+
* The name and signature of the console command.
|
|
30
|
+
*
|
|
31
|
+
* @var string
|
|
32
|
+
*/
|
|
33
|
+
protected $signature = 'fleetops:process-maintenance-triggers
|
|
34
|
+
{--sandbox : Run in sandbox database mode}
|
|
35
|
+
{--dry-run : Report triggers without creating work orders}';
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* The console command description.
|
|
39
|
+
*
|
|
40
|
+
* @var string
|
|
41
|
+
*/
|
|
42
|
+
protected $description = 'Process preventive maintenance schedule triggers and auto-create work orders';
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Execute the console command.
|
|
46
|
+
*/
|
|
47
|
+
public function handle(): void
|
|
48
|
+
{
|
|
49
|
+
date_default_timezone_set('UTC');
|
|
50
|
+
|
|
51
|
+
$sandbox = (bool) $this->option('sandbox');
|
|
52
|
+
$dryRun = (bool) $this->option('dry-run');
|
|
53
|
+
$conn = $sandbox ? 'sandbox' : 'mysql';
|
|
54
|
+
|
|
55
|
+
$this->info('Processing maintenance schedule triggers' . ($dryRun ? ' [DRY RUN]' : '') . ' at ' . Carbon::now()->toDateTimeString());
|
|
56
|
+
|
|
57
|
+
$triggered = 0;
|
|
58
|
+
|
|
59
|
+
// ------------------------------------------------------------------
|
|
60
|
+
// Load all active schedules that have at least one threshold set
|
|
61
|
+
// ------------------------------------------------------------------
|
|
62
|
+
$schedules = MaintenanceSchedule::on($conn)
|
|
63
|
+
->withoutGlobalScopes()
|
|
64
|
+
->where('status', 'active')
|
|
65
|
+
->where(function ($q) {
|
|
66
|
+
$q->whereNotNull('next_due_date')
|
|
67
|
+
->orWhereNotNull('next_due_odometer')
|
|
68
|
+
->orWhereNotNull('next_due_engine_hours');
|
|
69
|
+
})
|
|
70
|
+
->whereNull('deleted_at')
|
|
71
|
+
->with('subject')
|
|
72
|
+
->get();
|
|
73
|
+
|
|
74
|
+
foreach ($schedules as $schedule) {
|
|
75
|
+
$subject = $schedule->subject;
|
|
76
|
+
$currentOdometer = null;
|
|
77
|
+
$currentEngHours = null;
|
|
78
|
+
|
|
79
|
+
// Resolve current readings from the subject asset if it is a vehicle
|
|
80
|
+
if ($subject instanceof Vehicle) {
|
|
81
|
+
$currentOdometer = $subject->odometer;
|
|
82
|
+
$currentEngHours = $subject->engine_hours;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (!$schedule->isDue($currentOdometer, $currentEngHours)) {
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Build a human-readable reason string for logging
|
|
90
|
+
$reasons = [];
|
|
91
|
+
if ($schedule->next_due_date && now()->gte($schedule->next_due_date)) {
|
|
92
|
+
$reasons[] = 'date due ' . $schedule->next_due_date->toDateString();
|
|
93
|
+
}
|
|
94
|
+
if ($schedule->next_due_odometer && $currentOdometer !== null && $currentOdometer >= $schedule->next_due_odometer) {
|
|
95
|
+
$reasons[] = "odometer {$currentOdometer} >= {$schedule->next_due_odometer}";
|
|
96
|
+
}
|
|
97
|
+
if ($schedule->next_due_engine_hours && $currentEngHours !== null && $currentEngHours >= $schedule->next_due_engine_hours) {
|
|
98
|
+
$reasons[] = "engine hours {$currentEngHours} >= {$schedule->next_due_engine_hours}";
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
$this->line("Triggered: schedule {$schedule->public_id} ({$schedule->name}) — " . implode(', ', $reasons));
|
|
102
|
+
|
|
103
|
+
if (!$dryRun) {
|
|
104
|
+
// Check if a pending work order already exists for this schedule
|
|
105
|
+
// to avoid duplicates on repeated runs before the WO is completed
|
|
106
|
+
$existingOpen = WorkOrder::on($conn)
|
|
107
|
+
->withoutGlobalScopes()
|
|
108
|
+
->where('schedule_uuid', $schedule->uuid)
|
|
109
|
+
->whereIn('status', ['open', 'in_progress'])
|
|
110
|
+
->whereNull('deleted_at')
|
|
111
|
+
->exists();
|
|
112
|
+
|
|
113
|
+
if ($existingOpen) {
|
|
114
|
+
$this->line(' → Skipped: open work order already exists for this schedule.');
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Auto-generate a work order from the schedule defaults
|
|
119
|
+
// Generate a sequential WO code: WO-YYYYMMDD-XXXX
|
|
120
|
+
$woCount = WorkOrder::on($conn)->withoutGlobalScopes()->whereNull('deleted_at')->count() + 1;
|
|
121
|
+
$woCode = 'WO-' . now()->format('Ymd') . '-' . str_pad($woCount, 4, '0', STR_PAD_LEFT);
|
|
122
|
+
|
|
123
|
+
$workOrder = WorkOrder::on($conn)->create([
|
|
124
|
+
'company_uuid' => $schedule->company_uuid,
|
|
125
|
+
'schedule_uuid' => $schedule->uuid,
|
|
126
|
+
'subject' => $schedule->name,
|
|
127
|
+
'code' => $woCode,
|
|
128
|
+
'status' => 'open',
|
|
129
|
+
'priority' => $schedule->default_priority ?? 'normal',
|
|
130
|
+
'target_type' => $schedule->subject_type,
|
|
131
|
+
'target_uuid' => $schedule->subject_uuid,
|
|
132
|
+
'assignee_type' => $schedule->default_assignee_type,
|
|
133
|
+
'assignee_uuid' => $schedule->default_assignee_uuid,
|
|
134
|
+
'instructions' => $schedule->instructions,
|
|
135
|
+
'due_at' => $schedule->next_due_date,
|
|
136
|
+
'opened_at' => now(),
|
|
137
|
+
'created_by_uuid' => null, // system-generated
|
|
138
|
+
]);
|
|
139
|
+
|
|
140
|
+
$this->line(" → Created work order {$workOrder->public_id}");
|
|
141
|
+
|
|
142
|
+
event('maintenance.triggered', [$schedule, $workOrder]);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
$triggered++;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
$this->info("Processed {$triggered} schedule trigger(s)" . ($dryRun ? ' (dry run — no work orders created)' : '.'));
|
|
149
|
+
}
|
|
150
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\FleetOps\Console\Commands;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\FleetOps\Mail\MaintenanceScheduleReminder;
|
|
6
|
+
use Fleetbase\FleetOps\Models\MaintenanceSchedule;
|
|
7
|
+
use Illuminate\Console\Command;
|
|
8
|
+
use Illuminate\Support\Carbon;
|
|
9
|
+
use Illuminate\Support\Facades\DB;
|
|
10
|
+
use Illuminate\Support\Facades\Mail;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Sends reminder emails for upcoming maintenance schedules.
|
|
14
|
+
*
|
|
15
|
+
* Runs daily. For each active schedule that has reminder_offsets configured,
|
|
16
|
+
* it checks whether any offset threshold has been crossed (i.e. today is within
|
|
17
|
+
* N days of next_due_date) and — if no reminder has already been sent for that
|
|
18
|
+
* offset + due-date combination — sends a MaintenanceScheduleReminder email to
|
|
19
|
+
* the default assignee and records the send in maintenance_schedule_reminders.
|
|
20
|
+
*/
|
|
21
|
+
class SendMaintenanceReminders extends Command
|
|
22
|
+
{
|
|
23
|
+
/**
|
|
24
|
+
* The name and signature of the console command.
|
|
25
|
+
*
|
|
26
|
+
* @var string
|
|
27
|
+
*/
|
|
28
|
+
protected $signature = 'fleetops:send-maintenance-reminders
|
|
29
|
+
{--sandbox : Run against the sandbox database connection}
|
|
30
|
+
{--dry-run : Log which emails would be sent without actually sending}';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The console command description.
|
|
34
|
+
*
|
|
35
|
+
* @var string
|
|
36
|
+
*/
|
|
37
|
+
protected $description = 'Send reminder emails for maintenance schedules that are approaching their due date';
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Execute the console command.
|
|
41
|
+
*/
|
|
42
|
+
public function handle(): void
|
|
43
|
+
{
|
|
44
|
+
date_default_timezone_set('UTC');
|
|
45
|
+
$sandbox = (bool) $this->option('sandbox');
|
|
46
|
+
$dryRun = (bool) $this->option('dry-run');
|
|
47
|
+
$conn = $sandbox ? 'sandbox' : 'mysql';
|
|
48
|
+
|
|
49
|
+
$this->info('Sending maintenance schedule reminders' . ($dryRun ? ' [DRY RUN]' : '') . ' at ' . Carbon::now()->toDateTimeString());
|
|
50
|
+
|
|
51
|
+
$sent = 0;
|
|
52
|
+
|
|
53
|
+
// Load all active schedules that have:
|
|
54
|
+
// - a non-null next_due_date (reminders are date-based only)
|
|
55
|
+
// - a non-null reminder_offsets JSON array
|
|
56
|
+
// - a default_assignee configured
|
|
57
|
+
$schedules = MaintenanceSchedule::on($conn)
|
|
58
|
+
->withoutGlobalScopes()
|
|
59
|
+
->where('status', 'active')
|
|
60
|
+
->whereNotNull('next_due_date')
|
|
61
|
+
->whereNotNull('reminder_offsets')
|
|
62
|
+
->whereNotNull('default_assignee_uuid')
|
|
63
|
+
->whereNull('deleted_at')
|
|
64
|
+
->with(['subject', 'defaultAssignee'])
|
|
65
|
+
->get();
|
|
66
|
+
|
|
67
|
+
foreach ($schedules as $schedule) {
|
|
68
|
+
$offsets = $schedule->reminder_offsets;
|
|
69
|
+
$nextDueDate = $schedule->next_due_date;
|
|
70
|
+
|
|
71
|
+
if (empty($offsets) || !$nextDueDate) {
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Resolve the recipient email from the polymorphic defaultAssignee
|
|
76
|
+
$assignee = $schedule->defaultAssignee;
|
|
77
|
+
$email = $assignee?->email ?? null;
|
|
78
|
+
|
|
79
|
+
if (!$email) {
|
|
80
|
+
$this->line(" → Skipped schedule {$schedule->public_id}: no email on default assignee.");
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
$dueDateSnapshot = $nextDueDate->toDateString();
|
|
85
|
+
|
|
86
|
+
foreach ($offsets as $offsetDays) {
|
|
87
|
+
$offsetDays = (int) $offsetDays;
|
|
88
|
+
|
|
89
|
+
// The reminder window: today must be on or after (due_date - offset_days)
|
|
90
|
+
$reminderDate = $nextDueDate->copy()->subDays($offsetDays);
|
|
91
|
+
|
|
92
|
+
if (Carbon::today()->lt($reminderDate)) {
|
|
93
|
+
// Not yet within the reminder window for this offset
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Check whether we already sent this reminder for this cycle
|
|
98
|
+
$alreadySent = DB::connection($conn)
|
|
99
|
+
->table('maintenance_schedule_reminders')
|
|
100
|
+
->where('schedule_uuid', $schedule->uuid)
|
|
101
|
+
->where('offset_days', $offsetDays)
|
|
102
|
+
->where('due_date_snapshot', $dueDateSnapshot)
|
|
103
|
+
->exists();
|
|
104
|
+
|
|
105
|
+
if ($alreadySent) {
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
$this->line("Sending reminder: schedule {$schedule->public_id} ({$schedule->name}) — {$offsetDays} days before {$dueDateSnapshot} → {$email}");
|
|
110
|
+
|
|
111
|
+
if (!$dryRun) {
|
|
112
|
+
Mail::to($email)->send(new MaintenanceScheduleReminder($schedule, $offsetDays));
|
|
113
|
+
|
|
114
|
+
DB::connection($conn)->table('maintenance_schedule_reminders')->insert([
|
|
115
|
+
'schedule_uuid' => $schedule->uuid,
|
|
116
|
+
'offset_days' => $offsetDays,
|
|
117
|
+
'due_date_snapshot' => $dueDateSnapshot,
|
|
118
|
+
'sent_at' => Carbon::now(),
|
|
119
|
+
]);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
$sent++;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
$this->info("Sent {$sent} reminder(s)" . ($dryRun ? ' (dry run — no emails sent)' : '.'));
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
namespace Fleetbase\FleetOps\Http\Controllers\Internal\v1;
|
|
4
4
|
|
|
5
5
|
use Fleetbase\FleetOps\Http\Controllers\FleetOpsController;
|
|
6
|
+
use Fleetbase\FleetOps\Imports\EquipmentImport;
|
|
7
|
+
use Fleetbase\Http\Requests\ImportRequest;
|
|
8
|
+
use Maatwebsite\Excel\Facades\Excel;
|
|
6
9
|
|
|
7
10
|
class EquipmentController extends FleetOpsController
|
|
8
11
|
{
|
|
@@ -12,4 +15,28 @@ class EquipmentController extends FleetOpsController
|
|
|
12
15
|
* @var string
|
|
13
16
|
*/
|
|
14
17
|
public $resource = 'equipment';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Process import files (excel, csv) into Equipment records.
|
|
21
|
+
*
|
|
22
|
+
* @return \Illuminate\Http\Response
|
|
23
|
+
*/
|
|
24
|
+
public function import(ImportRequest $request)
|
|
25
|
+
{
|
|
26
|
+
$disk = $request->input('disk', config('filesystems.default'));
|
|
27
|
+
$files = $request->resolveFilesFromIds();
|
|
28
|
+
$importedCount = 0;
|
|
29
|
+
|
|
30
|
+
foreach ($files as $file) {
|
|
31
|
+
try {
|
|
32
|
+
$import = new EquipmentImport();
|
|
33
|
+
Excel::import($import, $file->path, $disk);
|
|
34
|
+
$importedCount += $import->imported;
|
|
35
|
+
} catch (\Throwable $e) {
|
|
36
|
+
return response()->error('Invalid file, unable to process.');
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return response()->json(['status' => 'ok', 'message' => 'Import completed', 'imported' => $importedCount]);
|
|
41
|
+
}
|
|
15
42
|
}
|
|
@@ -38,9 +38,16 @@ class LiveController extends Controller
|
|
|
38
38
|
->applyDirectivesForPermissions('fleet-ops list order')
|
|
39
39
|
->get();
|
|
40
40
|
|
|
41
|
-
// Loop through each order to get its current destination location
|
|
41
|
+
// Loop through each order to get its current destination location.
|
|
42
|
+
// Filter out null and 0,0 fallback coordinates — these are returned
|
|
43
|
+
// by getCurrentDestinationLocation() when an order has no dropoff or
|
|
44
|
+
// waypoint set, and would cause the location service to resolve to
|
|
45
|
+
// the ocean (0,0 = Gulf of Guinea).
|
|
42
46
|
foreach ($orders as $order) {
|
|
43
|
-
$
|
|
47
|
+
$location = $order->getCurrentDestinationLocation();
|
|
48
|
+
if ($location && !($location->getLat() == 0 && $location->getLng() == 0)) {
|
|
49
|
+
$coordinates[] = $location;
|
|
50
|
+
}
|
|
44
51
|
}
|
|
45
52
|
|
|
46
53
|
return response()->json($coordinates);
|
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
namespace Fleetbase\FleetOps\Http\Controllers\Internal\v1;
|
|
4
4
|
|
|
5
5
|
use Fleetbase\FleetOps\Http\Controllers\FleetOpsController;
|
|
6
|
+
use Fleetbase\FleetOps\Imports\MaintenanceImport;
|
|
7
|
+
use Fleetbase\FleetOps\Models\Maintenance;
|
|
8
|
+
use Fleetbase\Http\Requests\ImportRequest;
|
|
9
|
+
use Illuminate\Http\JsonResponse;
|
|
10
|
+
use Illuminate\Http\Request;
|
|
11
|
+
use Maatwebsite\Excel\Facades\Excel;
|
|
6
12
|
|
|
7
13
|
class MaintenanceController extends FleetOpsController
|
|
8
14
|
{
|
|
@@ -12,4 +18,163 @@ class MaintenanceController extends FleetOpsController
|
|
|
12
18
|
* @var string
|
|
13
19
|
*/
|
|
14
20
|
public $resource = 'maintenance';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Eager-load polymorphic relationships after create so they appear in the API response.
|
|
24
|
+
* Called automatically by HasApiControllerBehavior::createRecord() via getControllerCallback.
|
|
25
|
+
*/
|
|
26
|
+
public function onAfterCreate($request, Maintenance $record, array $input): void
|
|
27
|
+
{
|
|
28
|
+
$record->load(['maintainable', 'performedBy']);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Eager-load polymorphic relationships after update so they appear in the API response.
|
|
33
|
+
* Called automatically by HasApiControllerBehavior::updateRecord() via getControllerCallback.
|
|
34
|
+
*/
|
|
35
|
+
public function onAfterUpdate($request, Maintenance $record, array $input): void
|
|
36
|
+
{
|
|
37
|
+
$record->load(['maintainable', 'performedBy']);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Eager-load polymorphic relationships when finding record so they appear in the API response.
|
|
42
|
+
* Called automatically by HasApiControllerBehavior::findRecord() via getControllerCallback.
|
|
43
|
+
*/
|
|
44
|
+
public function onFindRecord($builder, $request): void
|
|
45
|
+
{
|
|
46
|
+
$builder->with(['maintainable', 'performedBy']);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Add a cost line item to a maintenance record.
|
|
51
|
+
* POST /maintenances/{id}/line-items.
|
|
52
|
+
*/
|
|
53
|
+
public function addLineItem(string $id, Request $request): JsonResponse
|
|
54
|
+
{
|
|
55
|
+
$maintenance = Maintenance::where('uuid', $id)
|
|
56
|
+
->orWhere('public_id', $id)
|
|
57
|
+
->firstOrFail();
|
|
58
|
+
|
|
59
|
+
$validated = $request->validate([
|
|
60
|
+
'description' => 'required|string|max:255',
|
|
61
|
+
'quantity' => 'required|numeric|min:0',
|
|
62
|
+
'unit_cost' => 'required|integer|min:0',
|
|
63
|
+
'currency' => 'nullable|string|size:3',
|
|
64
|
+
]);
|
|
65
|
+
|
|
66
|
+
$maintenance->addLineItem($validated);
|
|
67
|
+
$maintenance->refresh();
|
|
68
|
+
$this->recalculateCosts($maintenance);
|
|
69
|
+
|
|
70
|
+
return response()->json([
|
|
71
|
+
'status' => 'ok',
|
|
72
|
+
'line_items' => $maintenance->line_items,
|
|
73
|
+
'total_cost' => $maintenance->total_cost,
|
|
74
|
+
]);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Update a cost line item on a maintenance record.
|
|
79
|
+
* PUT /maintenances/{id}/line-items/{index}.
|
|
80
|
+
*/
|
|
81
|
+
public function updateLineItem(string $id, int $index, Request $request): JsonResponse
|
|
82
|
+
{
|
|
83
|
+
$maintenance = Maintenance::where('uuid', $id)
|
|
84
|
+
->orWhere('public_id', $id)
|
|
85
|
+
->firstOrFail();
|
|
86
|
+
|
|
87
|
+
$validated = $request->validate([
|
|
88
|
+
'description' => 'required|string|max:255',
|
|
89
|
+
'quantity' => 'required|numeric|min:0',
|
|
90
|
+
'unit_cost' => 'required|integer|min:0',
|
|
91
|
+
'currency' => 'nullable|string|size:3',
|
|
92
|
+
]);
|
|
93
|
+
|
|
94
|
+
$lineItems = $maintenance->line_items ?? [];
|
|
95
|
+
|
|
96
|
+
if (!isset($lineItems[$index])) {
|
|
97
|
+
return response()->json(['error' => 'Line item not found.'], 404);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
$lineItems[$index] = array_merge($lineItems[$index], $validated, [
|
|
101
|
+
'updated_at' => now(),
|
|
102
|
+
]);
|
|
103
|
+
|
|
104
|
+
$maintenance->update(['line_items' => $lineItems]);
|
|
105
|
+
$maintenance->refresh();
|
|
106
|
+
$this->recalculateCosts($maintenance);
|
|
107
|
+
|
|
108
|
+
return response()->json([
|
|
109
|
+
'status' => 'ok',
|
|
110
|
+
'line_items' => $maintenance->line_items,
|
|
111
|
+
'total_cost' => $maintenance->total_cost,
|
|
112
|
+
]);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Remove a cost line item from a maintenance record.
|
|
117
|
+
* DELETE /maintenances/{id}/line-items/{index}.
|
|
118
|
+
*/
|
|
119
|
+
public function removeLineItem(string $id, int $index): JsonResponse
|
|
120
|
+
{
|
|
121
|
+
$maintenance = Maintenance::where('uuid', $id)
|
|
122
|
+
->orWhere('public_id', $id)
|
|
123
|
+
->firstOrFail();
|
|
124
|
+
|
|
125
|
+
if (!$maintenance->removeLineItem($index)) {
|
|
126
|
+
return response()->json(['error' => 'Line item not found.'], 404);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
$maintenance->refresh();
|
|
130
|
+
$this->recalculateCosts($maintenance);
|
|
131
|
+
|
|
132
|
+
return response()->json([
|
|
133
|
+
'status' => 'ok',
|
|
134
|
+
'line_items' => $maintenance->line_items,
|
|
135
|
+
'total_cost' => $maintenance->total_cost,
|
|
136
|
+
]);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Process import files (excel, csv) into Maintenance records.
|
|
141
|
+
*
|
|
142
|
+
* @return \Illuminate\Http\Response
|
|
143
|
+
*/
|
|
144
|
+
public function import(ImportRequest $request)
|
|
145
|
+
{
|
|
146
|
+
$disk = $request->input('disk', config('filesystems.default'));
|
|
147
|
+
$files = $request->resolveFilesFromIds();
|
|
148
|
+
$importedCount = 0;
|
|
149
|
+
|
|
150
|
+
foreach ($files as $file) {
|
|
151
|
+
try {
|
|
152
|
+
$import = new MaintenanceImport();
|
|
153
|
+
Excel::import($import, $file->path, $disk);
|
|
154
|
+
$importedCount += $import->imported;
|
|
155
|
+
} catch (\Throwable $e) {
|
|
156
|
+
return response()->error('Invalid file, unable to process.');
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return response()->json(['status' => 'ok', 'message' => 'Import completed', 'imported' => $importedCount]);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Recalculate and persist parts_cost and total_cost derived from line_items.
|
|
165
|
+
* All monetary values are stored as integers (smallest currency unit, e.g. cents).
|
|
166
|
+
*/
|
|
167
|
+
protected function recalculateCosts(Maintenance $maintenance): void
|
|
168
|
+
{
|
|
169
|
+
$lineItems = $maintenance->line_items ?? [];
|
|
170
|
+
$partsCost = (int) collect($lineItems)->sum(fn ($item) => ($item['quantity'] ?? 0) * ($item['unit_cost'] ?? 0));
|
|
171
|
+
$laborCost = (int) ($maintenance->labor_cost ?? 0);
|
|
172
|
+
$tax = (int) ($maintenance->tax ?? 0);
|
|
173
|
+
$totalCost = $laborCost + $partsCost + $tax;
|
|
174
|
+
|
|
175
|
+
$maintenance->update([
|
|
176
|
+
'parts_cost' => $partsCost,
|
|
177
|
+
'total_cost' => $totalCost,
|
|
178
|
+
]);
|
|
179
|
+
}
|
|
15
180
|
}
|