@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.
Files changed (432) hide show
  1. package/addon/components/activity/form.hbs +2 -12
  2. package/addon/components/activity/logic-builder.hbs +1 -1
  3. package/addon/components/custom-entity/form.hbs +4 -20
  4. package/addon/components/device/form.hbs +3 -15
  5. package/addon/components/device/panel-header.hbs +13 -2
  6. package/addon/components/driver/details.hbs +33 -2
  7. package/addon/components/driver/form.hbs +42 -0
  8. package/addon/components/driver/panel-header.hbs +8 -1
  9. package/addon/components/driver/schedule.hbs +115 -76
  10. package/addon/components/driver/schedule.js +349 -157
  11. package/addon/components/driver-onboard-settings.hbs +2 -8
  12. package/addon/components/entity-field-editing-settings.hbs +2 -5
  13. package/addon/components/equipment/card.hbs +49 -0
  14. package/addon/components/equipment/card.js +6 -0
  15. package/addon/components/equipment/details.hbs +83 -44
  16. package/addon/components/equipment/form.hbs +111 -41
  17. package/addon/components/equipment/form.js +78 -10
  18. package/addon/components/equipment/panel-header.hbs +36 -0
  19. package/addon/components/equipment/panel-header.js +2 -0
  20. package/addon/components/fleet/driver-listing.hbs +3 -1
  21. package/addon/components/fleet/vehicle-listing.hbs +4 -7
  22. package/addon/components/fleet-panel/vehicle-listing.hbs +1 -6
  23. package/addon/components/fuel-report/form.hbs +1 -5
  24. package/addon/components/layout/fleet-ops-sidebar.hbs +43 -38
  25. package/addon/components/layout/fleet-ops-sidebar.js +103 -24
  26. package/addon/components/maintenance/cost-panel.hbs +176 -0
  27. package/addon/components/maintenance/cost-panel.js +241 -0
  28. package/addon/components/maintenance/details.hbs +123 -60
  29. package/addon/components/maintenance/form.hbs +138 -78
  30. package/addon/components/maintenance/form.js +131 -6
  31. package/addon/components/maintenance/panel-header.hbs +31 -0
  32. package/addon/components/maintenance/panel-header.js +2 -0
  33. package/addon/components/maintenance-schedule/details.hbs +260 -0
  34. package/addon/components/maintenance-schedule/details.js +158 -0
  35. package/addon/components/maintenance-schedule/form.hbs +287 -0
  36. package/addon/components/maintenance-schedule/form.js +199 -0
  37. package/addon/components/map/container.hbs +1 -1
  38. package/addon/components/map/drawer/device-event-listing.hbs +1 -1
  39. package/addon/components/map/drawer/driver-listing.hbs +1 -6
  40. package/addon/components/map/drawer/place-listing.hbs +1 -6
  41. package/addon/components/map/drawer/vehicle-listing.hbs +1 -6
  42. package/addon/components/map/drawer.hbs +8 -1
  43. package/addon/components/map/leaflet-live-map.hbs +2 -1
  44. package/addon/components/map/toolbar/visibility-control-panel.hbs +1 -1
  45. package/addon/components/map/toolbar.hbs +4 -29
  46. package/addon/components/modals/add-driver-shift.hbs +155 -0
  47. package/addon/components/modals/add-driver-shift.js +210 -0
  48. package/addon/components/modals/bulk-assign-orders.hbs +67 -0
  49. package/addon/components/modals/driver-shift.hbs +43 -0
  50. package/addon/components/modals/driver-shift.js +56 -0
  51. package/addon/components/modals/entity-form.hbs +5 -28
  52. package/addon/components/modals/orchestrator-import.hbs +351 -0
  53. package/addon/components/modals/orchestrator-import.js +807 -0
  54. package/addon/components/modals/order-config-new-status.hbs +1 -5
  55. package/addon/components/modals/scheduling-conflict.hbs +47 -0
  56. package/addon/components/modals/scheduling-conflict.js +53 -0
  57. package/addon/components/modals/send-work-order.hbs +91 -0
  58. package/addon/components/modals/send-work-order.js +3 -0
  59. package/addon/components/modals/service-area-form.hbs +1 -6
  60. package/addon/components/modals/set-driver-availability.hbs +50 -0
  61. package/addon/components/modals/set-driver-availability.js +57 -0
  62. package/addon/components/modals/update-order-activity.hbs +13 -9
  63. package/addon/components/modals/user-form.hbs +1 -5
  64. package/addon/components/modals/vehicle-form.hbs +17 -102
  65. package/addon/components/modals/vendor-form.hbs +15 -82
  66. package/addon/components/orchestrator/card-fields-settings.hbs +76 -0
  67. package/addon/components/orchestrator/card-fields-settings.js +134 -0
  68. package/addon/components/orchestrator/order-pool.hbs +264 -0
  69. package/addon/components/orchestrator/order-pool.js +394 -0
  70. package/addon/components/orchestrator/phase-builder.hbs +162 -0
  71. package/addon/components/orchestrator/phase-builder.js +162 -0
  72. package/addon/components/orchestrator/plan-viewer.hbs +278 -0
  73. package/addon/components/orchestrator/plan-viewer.js +342 -0
  74. package/addon/components/orchestrator/resource-panel.hbs +301 -0
  75. package/addon/components/orchestrator/resource-panel.js +106 -0
  76. package/addon/components/orchestrator-workbench.hbs +318 -0
  77. package/addon/components/orchestrator-workbench.js +1088 -0
  78. package/addon/components/order/details/custom-fields.hbs +10 -1
  79. package/addon/components/order/details/detail.hbs +37 -2
  80. package/addon/components/order/details/detail.js +0 -1
  81. package/addon/components/order/details/integrated-vendor-details.hbs +4 -4
  82. package/addon/components/order/details/notes.hbs +1 -7
  83. package/addon/components/order/details/route.hbs +1 -5
  84. package/addon/components/order/form/details.hbs +44 -10
  85. package/addon/components/order/form/details.js +57 -0
  86. package/addon/components/order/form/notes.hbs +1 -7
  87. package/addon/components/order/form/payload.hbs +1 -7
  88. package/addon/components/order/form/route.hbs +3 -15
  89. package/addon/components/order/header.hbs +1 -7
  90. package/addon/components/order/route-editor.hbs +4 -25
  91. package/addon/components/order/schedule-card.hbs +102 -95
  92. package/addon/components/order/schedule-card.js +8 -3
  93. package/addon/components/order-config-manager/details.hbs +2 -10
  94. package/addon/components/order-config-manager/entities.hbs +1 -7
  95. package/addon/components/order-config-manager.hbs +1 -6
  96. package/addon/components/part/card.hbs +49 -0
  97. package/addon/components/part/card.js +6 -0
  98. package/addon/components/part/details.hbs +102 -56
  99. package/addon/components/part/form.hbs +131 -56
  100. package/addon/components/part/form.js +78 -11
  101. package/addon/components/part/panel-header.hbs +36 -0
  102. package/addon/components/part/panel-header.js +2 -0
  103. package/addon/components/place/form.hbs +1 -7
  104. package/addon/components/sensor/details.hbs +1 -1
  105. package/addon/components/sensor/form.hbs +5 -3
  106. package/addon/components/sensor/panel-header.hbs +8 -1
  107. package/addon/components/service-area/form.hbs +1 -6
  108. package/addon/components/service-rate/form.hbs +12 -60
  109. package/addon/components/telematic/form.hbs +6 -2
  110. package/addon/components/vehicle/details/maintenance-history.hbs +42 -0
  111. package/addon/components/vehicle/details/maintenance-history.js +32 -0
  112. package/addon/components/vehicle/details/schedules.hbs +40 -0
  113. package/addon/components/vehicle/details/schedules.js +32 -0
  114. package/addon/components/vehicle/details/work-orders.hbs +42 -0
  115. package/addon/components/vehicle/details/work-orders.js +32 -0
  116. package/addon/components/vehicle/details.hbs +52 -0
  117. package/addon/components/vehicle/form.hbs +51 -0
  118. package/addon/components/vehicle/panel-header.hbs +19 -49
  119. package/addon/components/warranty/details.hbs +3 -2
  120. package/addon/components/warranty/form.hbs +3 -17
  121. package/addon/components/work-order/details.hbs +135 -40
  122. package/addon/components/work-order/form.hbs +178 -45
  123. package/addon/components/work-order/form.js +197 -4
  124. package/addon/components/work-order/panel-header.hbs +31 -0
  125. package/addon/components/work-order/panel-header.js +2 -0
  126. package/addon/controllers/connectivity/devices/index/details.js +1 -1
  127. package/addon/controllers/maintenance/equipment/index/details/index.js +0 -1
  128. package/addon/controllers/maintenance/equipment/index/details.js +36 -1
  129. package/addon/controllers/maintenance/equipment/index/edit.js +56 -1
  130. package/addon/controllers/maintenance/equipment/index/new.js +32 -1
  131. package/addon/controllers/maintenance/equipment/index.js +127 -113
  132. package/addon/controllers/maintenance/maintenances/index/details/index.js +3 -0
  133. package/addon/controllers/maintenance/maintenances/index/details.js +54 -0
  134. package/addon/controllers/maintenance/maintenances/index/edit.js +68 -0
  135. package/addon/controllers/maintenance/maintenances/index/new.js +34 -0
  136. package/addon/controllers/maintenance/maintenances/index.js +191 -0
  137. package/addon/controllers/maintenance/parts/index/details/index.js +0 -1
  138. package/addon/controllers/maintenance/parts/index/details.js +36 -1
  139. package/addon/controllers/maintenance/parts/index/edit.js +56 -1
  140. package/addon/controllers/maintenance/parts/index/new.js +32 -1
  141. package/addon/controllers/maintenance/parts/index.js +135 -113
  142. package/addon/controllers/maintenance/schedules/index/details.js +115 -0
  143. package/addon/controllers/maintenance/schedules/index/edit.js +41 -0
  144. package/addon/controllers/maintenance/schedules/index/new.js +33 -0
  145. package/addon/controllers/maintenance/schedules/index.js +280 -0
  146. package/addon/controllers/maintenance/work-orders/index/details.js +41 -1
  147. package/addon/controllers/maintenance/work-orders/index/edit.js +67 -1
  148. package/addon/controllers/maintenance/work-orders/index/new.js +43 -1
  149. package/addon/controllers/maintenance/work-orders/index.js +105 -113
  150. package/addon/controllers/management/drivers/index/details.js +6 -1
  151. package/addon/controllers/management/vehicles/index/details.js +65 -0
  152. package/addon/controllers/management/vehicles/index.js +18 -0
  153. package/addon/controllers/operations/orchestrator.js +10 -0
  154. package/addon/controllers/operations/orders/index.js +6 -0
  155. package/addon/controllers/operations/scheduler/fleet-schedule.js +341 -0
  156. package/addon/controllers/operations/scheduler/index.js +799 -275
  157. package/addon/controllers/operations/scheduler.js +21 -0
  158. package/addon/controllers/settings/orchestrator.js +70 -0
  159. package/addon/controllers/settings/scheduling.js +155 -0
  160. package/addon/extension.js +19 -0
  161. package/addon/instance-initializers/register-vroom-allocation.js +27 -0
  162. package/addon/models/maintenance-schedule.js +61 -0
  163. package/addon/routes/maintenance/equipment/index/details.js +27 -1
  164. package/addon/routes/maintenance/equipment/index/edit.js +27 -1
  165. package/addon/routes/maintenance/maintenances/index/details/index.js +3 -0
  166. package/addon/routes/maintenance/maintenances/index/details.js +29 -0
  167. package/addon/routes/maintenance/maintenances/index/edit.js +29 -0
  168. package/addon/routes/maintenance/maintenances/index/new.js +3 -0
  169. package/addon/routes/maintenance/maintenances/index.js +23 -0
  170. package/addon/routes/maintenance/maintenances.js +3 -0
  171. package/addon/routes/maintenance/parts/index/details.js +27 -1
  172. package/addon/routes/maintenance/parts/index/edit.js +27 -1
  173. package/addon/routes/maintenance/schedules/index/details/index.js +2 -0
  174. package/addon/routes/maintenance/schedules/index/details/work-orders.js +11 -0
  175. package/addon/routes/maintenance/schedules/index/details.js +25 -0
  176. package/addon/routes/maintenance/schedules/index/edit.js +25 -0
  177. package/addon/routes/maintenance/schedules/index/new.js +2 -0
  178. package/addon/routes/maintenance/schedules/index.js +21 -0
  179. package/addon/routes/maintenance/schedules.js +2 -0
  180. package/addon/routes/maintenance/work-orders/index/details.js +27 -1
  181. package/addon/routes/maintenance/work-orders/index/edit.js +27 -1
  182. package/addon/routes/management/vehicles/index/details/maintenance-history.js +3 -0
  183. package/addon/routes/management/vehicles/index/details/schedules.js +3 -0
  184. package/addon/routes/management/vehicles/index/details/work-orders.js +3 -0
  185. package/addon/routes/operations/orchestrator.js +23 -0
  186. package/addon/routes/operations/scheduler/fleet-schedule.js +28 -0
  187. package/addon/routes/operations/scheduler/index.js +48 -26
  188. package/addon/routes/operations/scheduler.js +14 -1
  189. package/addon/routes/settings/orchestrator.js +27 -0
  190. package/addon/routes/settings/scheduling.js +3 -0
  191. package/addon/routes.js +31 -1
  192. package/addon/services/driver-actions.js +40 -7
  193. package/addon/services/driver-scheduling.js +4 -1
  194. package/addon/services/equipment-actions.js +15 -5
  195. package/addon/services/leaflet-map-manager.js +14 -6
  196. package/addon/services/maintenance-actions.js +17 -14
  197. package/addon/services/maintenance-schedule-actions.js +118 -0
  198. package/addon/services/orchestration-engine-interface.js +49 -0
  199. package/addon/services/orchestration-engine.js +74 -0
  200. package/addon/services/order-actions.js +15 -0
  201. package/addon/services/order-allocation.js +116 -0
  202. package/addon/services/part-actions.js +12 -2
  203. package/addon/services/scheduling.js +316 -0
  204. package/addon/services/vehicle-actions.js +70 -7
  205. package/addon/services/vroom-allocation-engine.js +45 -0
  206. package/addon/services/work-order-actions.js +79 -0
  207. package/addon/styles/fleetops-engine.css +1658 -0
  208. package/addon/templates/analytics/reports/index/edit.hbs +1 -1
  209. package/addon/templates/analytics/reports/index/new.hbs +1 -1
  210. package/addon/templates/application.hbs +6 -1
  211. package/addon/templates/connectivity/devices/index/details/events.hbs +0 -1
  212. package/addon/templates/connectivity/devices.hbs +0 -1
  213. package/addon/templates/connectivity/events/index/details.hbs +0 -1
  214. package/addon/templates/connectivity/events.hbs +0 -1
  215. package/addon/templates/connectivity/sensors.hbs +0 -1
  216. package/addon/templates/connectivity/telematics/index/details/devices.hbs +0 -1
  217. package/addon/templates/connectivity/telematics/index/details/events.hbs +0 -1
  218. package/addon/templates/connectivity/telematics/index/details/sensors.hbs +0 -1
  219. package/addon/templates/connectivity/telematics.hbs +0 -1
  220. package/addon/templates/connectivity/tracking.hbs +0 -1
  221. package/addon/templates/connectivity.hbs +0 -1
  222. package/addon/templates/maintenance/equipment/index/details/index.hbs +1 -2
  223. package/addon/templates/maintenance/equipment/index/details.hbs +15 -2
  224. package/addon/templates/maintenance/equipment/index/edit.hbs +12 -2
  225. package/addon/templates/maintenance/equipment/index/new.hbs +1 -2
  226. package/addon/templates/maintenance/equipment/index.hbs +48 -13
  227. package/addon/templates/maintenance/equipment.hbs +0 -1
  228. package/addon/templates/maintenance/maintenances/index/details/index.hbs +1 -0
  229. package/addon/templates/maintenance/maintenances/index/details.hbs +15 -0
  230. package/addon/templates/maintenance/maintenances/index/edit.hbs +12 -0
  231. package/addon/templates/maintenance/maintenances/index/new.hbs +11 -0
  232. package/addon/templates/maintenance/maintenances/index.hbs +14 -0
  233. package/addon/templates/maintenance/maintenances.hbs +1 -0
  234. package/addon/templates/maintenance/parts/index/details/index.hbs +1 -2
  235. package/addon/templates/maintenance/parts/index/details.hbs +15 -2
  236. package/addon/templates/maintenance/parts/index/edit.hbs +12 -2
  237. package/addon/templates/maintenance/parts/index/new.hbs +1 -2
  238. package/addon/templates/maintenance/parts/index.hbs +48 -13
  239. package/addon/templates/maintenance/parts.hbs +0 -1
  240. package/addon/templates/maintenance/schedules/index/details/index.hbs +1 -0
  241. package/addon/templates/maintenance/schedules/index/details/work-orders.hbs +39 -0
  242. package/addon/templates/maintenance/schedules/index/details.hbs +14 -0
  243. package/addon/templates/maintenance/schedules/index/edit.hbs +12 -0
  244. package/addon/templates/maintenance/schedules/index/new.hbs +11 -0
  245. package/addon/templates/maintenance/schedules/index.hbs +40 -0
  246. package/addon/templates/maintenance/schedules.hbs +1 -0
  247. package/addon/templates/maintenance/work-orders/index/details.hbs +2 -1
  248. package/addon/templates/maintenance/work-orders/index/edit.hbs +2 -4
  249. package/addon/templates/maintenance/work-orders/index/new.hbs +1 -2
  250. package/addon/templates/maintenance/work-orders.hbs +0 -1
  251. package/addon/templates/management/contacts/customers/edit.hbs +1 -2
  252. package/addon/templates/management/contacts/customers/new.hbs +1 -2
  253. package/addon/templates/management/contacts/customers.hbs +1 -1
  254. package/addon/templates/management/contacts/index/edit.hbs +1 -2
  255. package/addon/templates/management/contacts/index/new.hbs +1 -2
  256. package/addon/templates/management/drivers/index/details/orders.hbs +0 -1
  257. package/addon/templates/management/drivers/index/edit.hbs +1 -2
  258. package/addon/templates/management/drivers/index/new.hbs +1 -2
  259. package/addon/templates/management/fleets/index/edit.hbs +1 -2
  260. package/addon/templates/management/fleets/index/new.hbs +1 -2
  261. package/addon/templates/management/fleets/index.hbs +1 -2
  262. package/addon/templates/management/fuel-reports/index/edit.hbs +1 -2
  263. package/addon/templates/management/fuel-reports/index/new.hbs +1 -2
  264. package/addon/templates/management/fuel-reports/index.hbs +1 -2
  265. package/addon/templates/management/issues/index/edit.hbs +1 -2
  266. package/addon/templates/management/issues/index/new.hbs +1 -2
  267. package/addon/templates/management/issues/index.hbs +1 -2
  268. package/addon/templates/management/places/index/details/activity.hbs +0 -1
  269. package/addon/templates/management/places/index/details/comments.hbs +0 -1
  270. package/addon/templates/management/places/index/details/documents.hbs +0 -1
  271. package/addon/templates/management/places/index/details/map.hbs +0 -1
  272. package/addon/templates/management/places/index/details/operations.hbs +0 -1
  273. package/addon/templates/management/places/index/details/performance.hbs +0 -1
  274. package/addon/templates/management/places/index/details/rules.hbs +0 -1
  275. package/addon/templates/management/vehicles/index/details/equipment.hbs +0 -1
  276. package/addon/templates/management/vehicles/index/details/maintenance-history.hbs +2 -0
  277. package/addon/templates/management/vehicles/index/details/schedules.hbs +2 -0
  278. package/addon/templates/management/vehicles/index/details/work-orders.hbs +2 -0
  279. package/addon/templates/management/vehicles/index/details.hbs +1 -1
  280. package/addon/templates/management/vehicles/index/edit.hbs +1 -2
  281. package/addon/templates/management/vehicles/index/new.hbs +1 -2
  282. package/addon/templates/management/vendors/index/edit.hbs +1 -2
  283. package/addon/templates/management/vendors/index/new.hbs +1 -2
  284. package/addon/templates/management/vendors/index.hbs +1 -2
  285. package/addon/templates/management/vendors/integrated.hbs +1 -2
  286. package/addon/templates/operations/orchestrator.hbs +1 -0
  287. package/addon/templates/operations/orders/index.hbs +6 -1
  288. package/addon/templates/operations/scheduler/fleet-schedule.hbs +41 -0
  289. package/addon/templates/operations/scheduler/index.hbs +147 -88
  290. package/addon/templates/operations/scheduler.hbs +7 -1
  291. package/addon/templates/settings/avatars.hbs +1 -1
  292. package/addon/templates/settings/orchestrator.hbs +65 -0
  293. package/addon/templates/settings/payments/index.hbs +1 -5
  294. package/addon/templates/settings/scheduling.hbs +82 -0
  295. package/addon/utils/create-full-calendar-event-from-order.js +52 -14
  296. package/addon/utils/create-full-calendar-event-from-schedule-item.js +50 -0
  297. package/addon/utils/fleet-ops-options.js +254 -0
  298. package/addon/utils/route-colors.js +99 -0
  299. package/addon/utils/to-calendar-date.js +70 -0
  300. package/app/components/driver/schedule.js +1 -0
  301. package/app/components/maintenance/cost-panel.js +1 -0
  302. package/app/components/maintenance/panel-header.js +1 -0
  303. package/app/components/maintenance-schedule/details.js +1 -0
  304. package/app/components/maintenance-schedule/form.js +1 -0
  305. package/app/components/modals/add-driver-shift.js +1 -0
  306. package/app/components/modals/bulk-assign-orders.js +1 -0
  307. package/app/components/modals/driver-shift.js +1 -0
  308. package/app/components/modals/orchestrator-import.js +1 -0
  309. package/app/components/modals/scheduling-conflict.js +1 -0
  310. package/app/components/modals/send-work-order.js +1 -0
  311. package/app/components/modals/set-driver-availability.js +1 -0
  312. package/app/components/orchestrator/card-fields-settings.js +1 -0
  313. package/app/components/orchestrator/order-pool.js +1 -0
  314. package/app/components/orchestrator/phase-builder.js +1 -0
  315. package/app/components/orchestrator/plan-viewer.js +1 -0
  316. package/app/components/orchestrator/resource-panel.js +1 -0
  317. package/app/components/orchestrator-workbench.js +1 -0
  318. package/app/components/vehicle/details/maintenance-history.js +1 -0
  319. package/app/components/vehicle/details/schedules.js +1 -0
  320. package/app/components/vehicle/details/work-orders.js +1 -0
  321. package/app/controllers/operations/orchestrator.js +1 -0
  322. package/app/controllers/settings/orchestrator.js +1 -0
  323. package/app/controllers/settings/scheduling.js +1 -0
  324. package/app/routes/operations/orchestrator.js +1 -0
  325. package/app/routes/settings/orchestrator.js +1 -0
  326. package/app/routes/settings/scheduling.js +1 -0
  327. package/app/services/maintenance-schedule-actions.js +1 -0
  328. package/app/services/orchestration-engine-interface.js +1 -0
  329. package/app/services/orchestration-engine.js +1 -0
  330. package/app/services/order-allocation.js +1 -0
  331. package/app/services/scheduling.js +1 -0
  332. package/app/services/vroom-allocation-engine.js +1 -0
  333. package/app/templates/settings/scheduling.js +1 -0
  334. package/app/utils/create-full-calendar-event-from-schedule-item.js +1 -0
  335. package/app/utils/route-colors.js +1 -0
  336. package/composer.json +4 -2
  337. package/extension.json +1 -1
  338. package/package.json +6 -5
  339. package/server/config/fleetops.php +20 -1
  340. package/server/migrations/2025_08_28_054927_create_parts_table.php +2 -2
  341. package/server/migrations/2025_08_28_054932_add_public_id_to_maintenance_tables.php +45 -0
  342. package/server/migrations/2025_09_01_000001_create_maintenance_schedules_table.php +88 -0
  343. package/server/migrations/2026_04_01_000001_fix_monetary_columns_in_parts_table.php +48 -0
  344. package/server/migrations/2026_04_01_000003_add_photo_uuid_to_equipment_and_parts_tables.php +61 -0
  345. package/server/migrations/2026_04_01_000004_add_public_id_to_equipments_table.php +38 -0
  346. package/server/migrations/2026_04_01_000005_add_missing_columns_to_parts_table.php +67 -0
  347. package/server/migrations/2026_04_04_000001_add_reminder_offsets_to_maintenance_schedules.php +44 -0
  348. package/server/migrations/2026_04_08_000001_add_orchestrator_columns_to_vehicles_table.php +53 -0
  349. package/server/migrations/2026_04_08_000002_add_orchestrator_columns_to_drivers_table.php +41 -0
  350. package/server/migrations/2026_04_08_000003_add_orchestrator_columns_to_orders_table.php +38 -0
  351. package/server/migrations/2026_04_08_000004_add_orchestrator_columns_to_payloads_table.php +38 -0
  352. package/server/migrations/2026_04_08_000005_add_orchestrator_columns_to_waypoints_table.php +38 -0
  353. package/server/migrations/2026_04_09_000001_create_manifests_table.php +48 -0
  354. package/server/migrations/2026_04_09_000002_create_manifest_stops_table.php +48 -0
  355. package/server/migrations/2026_04_09_000003_add_manifest_uuid_to_orders_table.php +28 -0
  356. package/server/migrations/2026_04_13_000001_add_pod_notes_columns_to_waypoints_table.php +39 -0
  357. package/server/migrations/2026_04_14_000001_drop_redundant_capacity_columns_from_payloads_table.php +42 -0
  358. package/server/migrations/2026_04_14_000002_rename_capacity_columns_on_vehicles_table.php +48 -0
  359. package/server/resources/views/mail/maintenance-schedule-reminder.blade.php +59 -0
  360. package/server/resources/views/mail/work-order-dispatched.blade.php +67 -0
  361. package/server/src/Auth/Schemas/FleetOps.php +44 -0
  362. package/server/src/Console/Commands/ProcessMaintenanceTriggers.php +150 -0
  363. package/server/src/Console/Commands/SendMaintenanceReminders.php +128 -0
  364. package/server/src/Http/Controllers/Api/v1/OrderController.php +15 -2
  365. package/server/src/Http/Controllers/Api/v1/VehicleController.php +18 -2
  366. package/server/src/Http/Controllers/Internal/v1/DriverController.php +1 -0
  367. package/server/src/Http/Controllers/Internal/v1/EquipmentController.php +27 -0
  368. package/server/src/Http/Controllers/Internal/v1/LiveController.php +9 -2
  369. package/server/src/Http/Controllers/Internal/v1/MaintenanceController.php +165 -0
  370. package/server/src/Http/Controllers/Internal/v1/MaintenanceScheduleController.php +304 -0
  371. package/server/src/Http/Controllers/Internal/v1/ManifestController.php +138 -0
  372. package/server/src/Http/Controllers/Internal/v1/OrchestrationController.php +975 -0
  373. package/server/src/Http/Controllers/Internal/v1/OrderController.php +42 -0
  374. package/server/src/Http/Controllers/Internal/v1/PartController.php +27 -0
  375. package/server/src/Http/Controllers/Internal/v1/SettingController.php +118 -0
  376. package/server/src/Http/Controllers/Internal/v1/Traits/DriverSchedulingTrait.php +214 -0
  377. package/server/src/Http/Controllers/Internal/v1/WorkOrderController.php +68 -0
  378. package/server/src/Http/Resources/v1/Driver.php +1 -0
  379. package/server/src/Http/Resources/v1/Maintenance.php +138 -0
  380. package/server/src/Http/Resources/v1/MaintenanceSchedule.php +137 -0
  381. package/server/src/Http/Resources/v1/Orchestrator/Order.php +116 -0
  382. package/server/src/Http/Resources/v1/Order.php +7 -4
  383. package/server/src/Http/Resources/v1/Waypoint.php +7 -0
  384. package/server/src/Http/Resources/v1/WorkOrder.php +136 -0
  385. package/server/src/Imports/EquipmentImport.php +32 -0
  386. package/server/src/Imports/MaintenanceImport.php +32 -0
  387. package/server/src/Imports/MaintenanceScheduleImport.php +32 -0
  388. package/server/src/Imports/PartImport.php +32 -0
  389. package/server/src/Imports/WorkOrderImport.php +32 -0
  390. package/server/src/Jobs/ProcessAllocationJob.php +119 -0
  391. package/server/src/Listeners/HandleDeliveryCompletion.php +47 -0
  392. package/server/src/Listeners/NotifyDriverOnShiftChange.php +63 -0
  393. package/server/src/Mail/MaintenanceScheduleReminder.php +68 -0
  394. package/server/src/Mail/WorkOrderDispatched.php +58 -0
  395. package/server/src/Models/Asset.php +2 -2
  396. package/server/src/Models/Device.php +1 -1
  397. package/server/src/Models/Driver.php +82 -4
  398. package/server/src/Models/Equipment.php +62 -2
  399. package/server/src/Models/Maintenance.php +127 -9
  400. package/server/src/Models/MaintenanceSchedule.php +353 -0
  401. package/server/src/Models/Manifest.php +214 -0
  402. package/server/src/Models/ManifestStop.php +162 -0
  403. package/server/src/Models/Order.php +70 -0
  404. package/server/src/Models/OrderConfig.php +5 -2
  405. package/server/src/Models/Part.php +69 -3
  406. package/server/src/Models/Place.php +1 -1
  407. package/server/src/Models/Sensor.php +1 -1
  408. package/server/src/Models/ServiceQuote.php +1 -1
  409. package/server/src/Models/Vehicle.php +18 -1
  410. package/server/src/Models/Warranty.php +1 -1
  411. package/server/src/Models/Waypoint.php +7 -1
  412. package/server/src/Models/WorkOrder.php +122 -12
  413. package/server/src/Notifications/DriverShiftChanged.php +110 -0
  414. package/server/src/Observers/WorkOrderObserver.php +107 -0
  415. package/server/src/Orchestration/Contracts/OrchestrationEngineInterface.php +63 -0
  416. package/server/src/Orchestration/Engines/DriverAssignmentEngine.php +265 -0
  417. package/server/src/Orchestration/Engines/GreedyOrchestrationEngine.php +155 -0
  418. package/server/src/Orchestration/Engines/RouteSequencingEngine.php +272 -0
  419. package/server/src/Orchestration/Engines/VroomOrchestrationEngine.php +192 -0
  420. package/server/src/Orchestration/OrchestrationEngineRegistry.php +83 -0
  421. package/server/src/Orchestration/Support/OrchestrationPayloadBuilder.php +380 -0
  422. package/server/src/Providers/EventServiceProvider.php +7 -1
  423. package/server/src/Providers/FleetOpsServiceProvider.php +42 -15
  424. package/server/src/routes.php +65 -4
  425. package/translations/ar-ae.yml +44 -12
  426. package/translations/bg-bg.yaml +51 -10
  427. package/translations/en-us.yaml +444 -1
  428. package/translations/fr-fr.yaml +51 -10
  429. package/translations/mn-mn.yaml +51 -10
  430. package/translations/pt-br.yaml +51 -10
  431. package/translations/ru-ru.yaml +51 -10
  432. package/translations/vi-vn.yaml +48 -12
@@ -0,0 +1,67 @@
1
+ <x-mail-layout>
2
+ <h2 style="font-size: 18px; font-weight: 600;">
3
+ Work Order Dispatched: #{{ $workOrder->public_id }}
4
+ </h2>
5
+
6
+ @if($assignee && $assignee->name)
7
+ <p>Dear {{ $assignee->name }},</p>
8
+ @endif
9
+
10
+ <p>
11
+ A work order has been assigned to you. Please review the details below and take the necessary action.
12
+ </p>
13
+
14
+ <table style="width: 100%; border-collapse: collapse; margin-top: 16px; margin-bottom: 16px;">
15
+ <tr>
16
+ <td style="padding: 8px 0; font-weight: 600; width: 40%; vertical-align: top;">Work Order #</td>
17
+ <td style="padding: 8px 0;">{{ $workOrder->public_id }}</td>
18
+ </tr>
19
+ @if($workOrder->subject)
20
+ <tr>
21
+ <td style="padding: 8px 0; font-weight: 600; vertical-align: top;">Subject</td>
22
+ <td style="padding: 8px 0;">{{ $workOrder->subject }}</td>
23
+ </tr>
24
+ @endif
25
+ <tr>
26
+ <td style="padding: 8px 0; font-weight: 600; vertical-align: top;">Status</td>
27
+ <td style="padding: 8px 0;">{{ ucfirst(str_replace('_', ' ', $workOrder->status)) }}</td>
28
+ </tr>
29
+ <tr>
30
+ <td style="padding: 8px 0; font-weight: 600; vertical-align: top;">Priority</td>
31
+ <td style="padding: 8px 0;">{{ ucfirst($workOrder->priority) }}</td>
32
+ </tr>
33
+ @if($target)
34
+ <tr>
35
+ <td style="padding: 8px 0; font-weight: 600; vertical-align: top;">Asset / Vehicle</td>
36
+ <td style="padding: 8px 0;">{{ $target->name ?? $target->display_name ?? $target->public_id }}</td>
37
+ </tr>
38
+ @endif
39
+ @if($workOrder->due_at)
40
+ <tr>
41
+ <td style="padding: 8px 0; font-weight: 600; vertical-align: top;">Due Date</td>
42
+ <td style="padding: 8px 0;">{{ $workOrder->due_at->format('d M Y') }}</td>
43
+ </tr>
44
+ @endif
45
+ @if($workOrder->estimated_cost)
46
+ <tr>
47
+ <td style="padding: 8px 0; font-weight: 600; vertical-align: top;">Estimated Cost</td>
48
+ <td style="padding: 8px 0;">{{ number_format($workOrder->estimated_cost / 100, 2) }} {{ strtoupper($workOrder->currency ?? 'USD') }}</td>
49
+ </tr>
50
+ @endif
51
+ @if($workOrder->approved_budget)
52
+ <tr>
53
+ <td style="padding: 8px 0; font-weight: 600; vertical-align: top;">Approved Budget</td>
54
+ <td style="padding: 8px 0;">{{ number_format($workOrder->approved_budget / 100, 2) }} {{ strtoupper($workOrder->currency ?? 'USD') }}</td>
55
+ </tr>
56
+ @endif
57
+ </table>
58
+
59
+ @if($workOrder->instructions)
60
+ <p style="font-weight: 600; margin-bottom: 4px;">Instructions:</p>
61
+ <p style="white-space: pre-line;">{{ $workOrder->instructions }}</p>
62
+ @endif
63
+
64
+ <p style="margin-top: 24px; color: #6b7280; font-size: 13px;">
65
+ Please do not reply directly to this email. Contact the fleet manager if you have any questions.
66
+ </p>
67
+ </x-mail-layout>
@@ -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
+ }
@@ -55,7 +55,14 @@ class OrderController extends Controller
55
55
  set_time_limit(180);
56
56
 
57
57
  // get request input
58
- $input = $request->only(['internal_id', 'payload', 'service_quote', 'purchase_rate', 'adhoc', 'adhoc_distance', 'pod_method', 'pod_required', 'scheduled_at', 'status', 'meta', 'notes']);
58
+ $input = $request->only([
59
+ 'internal_id', 'payload', 'service_quote', 'purchase_rate',
60
+ 'adhoc', 'adhoc_distance', 'pod_method', 'pod_required',
61
+ 'scheduled_at', 'status', 'meta', 'notes',
62
+ // Orchestrator constraints
63
+ 'time_window_start', 'time_window_end',
64
+ 'required_skills', 'orchestrator_priority',
65
+ ]);
59
66
 
60
67
  // Get order config
61
68
  $orderConfig = OrderConfig::resolveFromIdentifier($request->only(['type', 'order_config']));
@@ -363,7 +370,13 @@ class OrderController extends Controller
363
370
  }
364
371
 
365
372
  // get request input
366
- $input = $request->only(['internal_id', 'payload', 'adhoc', 'adhoc_distance', 'pod_method', 'pod_required', 'scheduled_at', 'meta', 'type', 'status', 'notes']);
373
+ $input = $request->only([
374
+ 'internal_id', 'payload', 'adhoc', 'adhoc_distance',
375
+ 'pod_method', 'pod_required', 'scheduled_at', 'meta', 'type', 'status', 'notes',
376
+ // Orchestrator constraints
377
+ 'time_window_start', 'time_window_end',
378
+ 'required_skills', 'orchestrator_priority',
379
+ ]);
367
380
 
368
381
  // update payload if new input or change payload by id
369
382
  if ($request->isArray('payload')) {
@@ -26,7 +26,15 @@ class VehicleController extends Controller
26
26
  public function create(CreateVehicleRequest $request)
27
27
  {
28
28
  // get request input
29
- $input = $request->only(['status', 'make', 'model', 'year', 'trim', 'type', 'plate_number', 'vin', 'meta', 'online', 'location', 'altitude', 'heading', 'speed']);
29
+ $input = $request->only([
30
+ 'status', 'make', 'model', 'year', 'trim', 'type', 'plate_number', 'vin',
31
+ 'meta', 'online', 'location', 'altitude', 'heading', 'speed',
32
+ // Capacity
33
+ 'payload_capacity', 'payload_capacity_volume',
34
+ 'payload_capacity_pallets', 'payload_capacity_parcels',
35
+ // Orchestrator constraints
36
+ 'skills', 'max_tasks', 'time_window_start', 'time_window_end', 'return_to_depot',
37
+ ]);
30
38
 
31
39
  // make sure company is set
32
40
  $input['company_uuid'] = session('company');
@@ -97,7 +105,15 @@ class VehicleController extends Controller
97
105
  }
98
106
 
99
107
  // get request input
100
- $input = $request->only(['status', 'make', 'model', 'year', 'trim', 'type', 'plate_number', 'vin', 'meta', 'location', 'online', 'altitude', 'heading', 'speed']);
108
+ $input = $request->only([
109
+ 'status', 'make', 'model', 'year', 'trim', 'type', 'plate_number', 'vin',
110
+ 'meta', 'location', 'online', 'altitude', 'heading', 'speed',
111
+ // Capacity
112
+ 'payload_capacity', 'payload_capacity_volume',
113
+ 'payload_capacity_pallets', 'payload_capacity_parcels',
114
+ // Orchestrator constraints
115
+ 'skills', 'max_tasks', 'time_window_start', 'time_window_end', 'return_to_depot',
116
+ ]);
101
117
 
102
118
  // vendor assignment
103
119
  if ($request->has('vendor')) {
@@ -29,6 +29,7 @@ use Maatwebsite\Excel\Facades\Excel;
29
29
 
30
30
  class DriverController extends FleetOpsController
31
31
  {
32
+ use Traits\DriverSchedulingTrait;
32
33
  /**
33
34
  * The resource to query.
34
35
  *
@@ -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
- $coordinates[] = $order->getCurrentDestinationLocation();
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);