@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.
Files changed (434) 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 +40 -36
  25. package/addon/components/layout/fleet-ops-sidebar.js +61 -10
  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 +1087 -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 +30 -0
  117. package/addon/components/vehicle/form.hbs +39 -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/details.js +5 -0
  155. package/addon/controllers/operations/orders/index.js +6 -0
  156. package/addon/controllers/operations/scheduler/fleet-schedule.js +341 -0
  157. package/addon/controllers/operations/scheduler/index.js +799 -275
  158. package/addon/controllers/operations/scheduler.js +21 -0
  159. package/addon/controllers/settings/orchestrator.js +70 -0
  160. package/addon/controllers/settings/scheduling.js +155 -0
  161. package/addon/extension.js +74 -1
  162. package/addon/instance-initializers/register-vroom-allocation.js +27 -0
  163. package/addon/models/maintenance-schedule.js +61 -0
  164. package/addon/routes/maintenance/equipment/index/details.js +27 -1
  165. package/addon/routes/maintenance/equipment/index/edit.js +27 -1
  166. package/addon/routes/maintenance/maintenances/index/details/index.js +3 -0
  167. package/addon/routes/maintenance/maintenances/index/details.js +29 -0
  168. package/addon/routes/maintenance/maintenances/index/edit.js +29 -0
  169. package/addon/routes/maintenance/maintenances/index/new.js +3 -0
  170. package/addon/routes/maintenance/maintenances/index.js +23 -0
  171. package/addon/routes/maintenance/maintenances.js +3 -0
  172. package/addon/routes/maintenance/parts/index/details.js +27 -1
  173. package/addon/routes/maintenance/parts/index/edit.js +27 -1
  174. package/addon/routes/maintenance/schedules/index/details/index.js +2 -0
  175. package/addon/routes/maintenance/schedules/index/details/work-orders.js +11 -0
  176. package/addon/routes/maintenance/schedules/index/details.js +25 -0
  177. package/addon/routes/maintenance/schedules/index/edit.js +25 -0
  178. package/addon/routes/maintenance/schedules/index/new.js +2 -0
  179. package/addon/routes/maintenance/schedules/index.js +21 -0
  180. package/addon/routes/maintenance/schedules.js +2 -0
  181. package/addon/routes/maintenance/work-orders/index/details.js +27 -1
  182. package/addon/routes/maintenance/work-orders/index/edit.js +27 -1
  183. package/addon/routes/management/vehicles/index/details/maintenance-history.js +3 -0
  184. package/addon/routes/management/vehicles/index/details/schedules.js +3 -0
  185. package/addon/routes/management/vehicles/index/details/work-orders.js +3 -0
  186. package/addon/routes/operations/orchestrator.js +23 -0
  187. package/addon/routes/operations/orders/index/details/virtual.js +23 -0
  188. package/addon/routes/operations/scheduler/fleet-schedule.js +28 -0
  189. package/addon/routes/operations/scheduler/index.js +48 -26
  190. package/addon/routes/operations/scheduler.js +14 -1
  191. package/addon/routes/settings/orchestrator.js +27 -0
  192. package/addon/routes/settings/scheduling.js +3 -0
  193. package/addon/routes.js +33 -1
  194. package/addon/services/driver-actions.js +40 -7
  195. package/addon/services/driver-scheduling.js +4 -1
  196. package/addon/services/equipment-actions.js +15 -5
  197. package/addon/services/leaflet-map-manager.js +14 -6
  198. package/addon/services/maintenance-actions.js +17 -14
  199. package/addon/services/maintenance-schedule-actions.js +118 -0
  200. package/addon/services/orchestration-engine-interface.js +49 -0
  201. package/addon/services/orchestration-engine.js +74 -0
  202. package/addon/services/order-actions.js +15 -0
  203. package/addon/services/order-allocation.js +116 -0
  204. package/addon/services/part-actions.js +12 -2
  205. package/addon/services/scheduling.js +316 -0
  206. package/addon/services/vehicle-actions.js +70 -7
  207. package/addon/services/vroom-allocation-engine.js +45 -0
  208. package/addon/services/work-order-actions.js +80 -0
  209. package/addon/styles/fleetops-engine.css +1658 -0
  210. package/addon/templates/analytics/reports/index/edit.hbs +1 -1
  211. package/addon/templates/analytics/reports/index/new.hbs +1 -1
  212. package/addon/templates/application.hbs +6 -1
  213. package/addon/templates/connectivity/devices/index/details/events.hbs +0 -1
  214. package/addon/templates/connectivity/devices.hbs +0 -1
  215. package/addon/templates/connectivity/events/index/details.hbs +0 -1
  216. package/addon/templates/connectivity/events.hbs +0 -1
  217. package/addon/templates/connectivity/sensors.hbs +0 -1
  218. package/addon/templates/connectivity/telematics/index/details/devices.hbs +0 -1
  219. package/addon/templates/connectivity/telematics/index/details/events.hbs +0 -1
  220. package/addon/templates/connectivity/telematics/index/details/sensors.hbs +0 -1
  221. package/addon/templates/connectivity/telematics.hbs +0 -1
  222. package/addon/templates/connectivity/tracking.hbs +0 -1
  223. package/addon/templates/connectivity.hbs +0 -1
  224. package/addon/templates/maintenance/equipment/index/details/index.hbs +1 -2
  225. package/addon/templates/maintenance/equipment/index/details.hbs +15 -2
  226. package/addon/templates/maintenance/equipment/index/edit.hbs +12 -2
  227. package/addon/templates/maintenance/equipment/index/new.hbs +1 -2
  228. package/addon/templates/maintenance/equipment/index.hbs +48 -13
  229. package/addon/templates/maintenance/equipment.hbs +0 -1
  230. package/addon/templates/maintenance/maintenances/index/details/index.hbs +1 -0
  231. package/addon/templates/maintenance/maintenances/index/details.hbs +15 -0
  232. package/addon/templates/maintenance/maintenances/index/edit.hbs +12 -0
  233. package/addon/templates/maintenance/maintenances/index/new.hbs +11 -0
  234. package/addon/templates/maintenance/maintenances/index.hbs +14 -0
  235. package/addon/templates/maintenance/maintenances.hbs +1 -0
  236. package/addon/templates/maintenance/parts/index/details/index.hbs +1 -2
  237. package/addon/templates/maintenance/parts/index/details.hbs +15 -2
  238. package/addon/templates/maintenance/parts/index/edit.hbs +12 -2
  239. package/addon/templates/maintenance/parts/index/new.hbs +1 -2
  240. package/addon/templates/maintenance/parts/index.hbs +48 -13
  241. package/addon/templates/maintenance/parts.hbs +0 -1
  242. package/addon/templates/maintenance/schedules/index/details/index.hbs +1 -0
  243. package/addon/templates/maintenance/schedules/index/details/work-orders.hbs +39 -0
  244. package/addon/templates/maintenance/schedules/index/details.hbs +14 -0
  245. package/addon/templates/maintenance/schedules/index/edit.hbs +12 -0
  246. package/addon/templates/maintenance/schedules/index/new.hbs +11 -0
  247. package/addon/templates/maintenance/schedules/index.hbs +40 -0
  248. package/addon/templates/maintenance/schedules.hbs +1 -0
  249. package/addon/templates/maintenance/work-orders/index/details.hbs +2 -1
  250. package/addon/templates/maintenance/work-orders/index/edit.hbs +2 -4
  251. package/addon/templates/maintenance/work-orders/index/new.hbs +1 -2
  252. package/addon/templates/maintenance/work-orders.hbs +0 -1
  253. package/addon/templates/management/contacts/customers/edit.hbs +1 -2
  254. package/addon/templates/management/contacts/customers/new.hbs +1 -2
  255. package/addon/templates/management/contacts/customers.hbs +1 -1
  256. package/addon/templates/management/contacts/index/edit.hbs +1 -2
  257. package/addon/templates/management/contacts/index/new.hbs +1 -2
  258. package/addon/templates/management/drivers/index/details/orders.hbs +0 -1
  259. package/addon/templates/management/drivers/index/edit.hbs +1 -2
  260. package/addon/templates/management/drivers/index/new.hbs +1 -2
  261. package/addon/templates/management/fleets/index/edit.hbs +1 -2
  262. package/addon/templates/management/fleets/index/new.hbs +1 -2
  263. package/addon/templates/management/fleets/index.hbs +1 -2
  264. package/addon/templates/management/fuel-reports/index/edit.hbs +1 -2
  265. package/addon/templates/management/fuel-reports/index/new.hbs +1 -2
  266. package/addon/templates/management/fuel-reports/index.hbs +1 -2
  267. package/addon/templates/management/issues/index/edit.hbs +1 -2
  268. package/addon/templates/management/issues/index/new.hbs +1 -2
  269. package/addon/templates/management/issues/index.hbs +1 -2
  270. package/addon/templates/management/places/index/details/activity.hbs +0 -1
  271. package/addon/templates/management/places/index/details/comments.hbs +0 -1
  272. package/addon/templates/management/places/index/details/documents.hbs +0 -1
  273. package/addon/templates/management/places/index/details/map.hbs +0 -1
  274. package/addon/templates/management/places/index/details/operations.hbs +0 -1
  275. package/addon/templates/management/places/index/details/performance.hbs +0 -1
  276. package/addon/templates/management/places/index/details/rules.hbs +0 -1
  277. package/addon/templates/management/vehicles/index/details/equipment.hbs +0 -1
  278. package/addon/templates/management/vehicles/index/details/maintenance-history.hbs +2 -0
  279. package/addon/templates/management/vehicles/index/details/schedules.hbs +2 -0
  280. package/addon/templates/management/vehicles/index/details/work-orders.hbs +2 -0
  281. package/addon/templates/management/vehicles/index/details.hbs +1 -1
  282. package/addon/templates/management/vehicles/index/edit.hbs +1 -2
  283. package/addon/templates/management/vehicles/index/new.hbs +1 -2
  284. package/addon/templates/management/vendors/index/edit.hbs +1 -2
  285. package/addon/templates/management/vendors/index/new.hbs +1 -2
  286. package/addon/templates/management/vendors/index.hbs +1 -2
  287. package/addon/templates/management/vendors/integrated.hbs +1 -2
  288. package/addon/templates/operations/orchestrator.hbs +1 -0
  289. package/addon/templates/operations/orders/index/details/virtual.hbs +1 -0
  290. package/addon/templates/operations/orders/index.hbs +6 -1
  291. package/addon/templates/operations/scheduler/fleet-schedule.hbs +41 -0
  292. package/addon/templates/operations/scheduler/index.hbs +147 -88
  293. package/addon/templates/operations/scheduler.hbs +7 -1
  294. package/addon/templates/settings/avatars.hbs +1 -1
  295. package/addon/templates/settings/orchestrator.hbs +65 -0
  296. package/addon/templates/settings/payments/index.hbs +1 -5
  297. package/addon/templates/settings/scheduling.hbs +82 -0
  298. package/addon/utils/create-full-calendar-event-from-order.js +52 -14
  299. package/addon/utils/create-full-calendar-event-from-schedule-item.js +50 -0
  300. package/addon/utils/fleet-ops-options.js +254 -0
  301. package/addon/utils/route-colors.js +99 -0
  302. package/addon/utils/to-calendar-date.js +70 -0
  303. package/app/components/driver/schedule.js +1 -0
  304. package/app/components/maintenance/cost-panel.js +1 -0
  305. package/app/components/maintenance/panel-header.js +1 -0
  306. package/app/components/maintenance-schedule/details.js +1 -0
  307. package/app/components/maintenance-schedule/form.js +1 -0
  308. package/app/components/modals/add-driver-shift.js +1 -0
  309. package/app/components/modals/bulk-assign-orders.js +1 -0
  310. package/app/components/modals/driver-shift.js +1 -0
  311. package/app/components/modals/orchestrator-import.js +1 -0
  312. package/app/components/modals/scheduling-conflict.js +1 -0
  313. package/app/components/modals/send-work-order.js +1 -0
  314. package/app/components/modals/set-driver-availability.js +1 -0
  315. package/app/components/orchestrator/card-fields-settings.js +1 -0
  316. package/app/components/orchestrator/order-pool.js +1 -0
  317. package/app/components/orchestrator/phase-builder.js +1 -0
  318. package/app/components/orchestrator/plan-viewer.js +1 -0
  319. package/app/components/orchestrator/resource-panel.js +1 -0
  320. package/app/components/orchestrator-workbench.js +1 -0
  321. package/app/components/vehicle/details/maintenance-history.js +1 -0
  322. package/app/components/vehicle/details/schedules.js +1 -0
  323. package/app/components/vehicle/details/work-orders.js +1 -0
  324. package/app/controllers/operations/orchestrator.js +1 -0
  325. package/app/controllers/settings/orchestrator.js +1 -0
  326. package/app/controllers/settings/scheduling.js +1 -0
  327. package/app/routes/operations/orchestrator.js +1 -0
  328. package/app/routes/operations/orders/index/details/virtual.js +1 -0
  329. package/app/routes/settings/orchestrator.js +1 -0
  330. package/app/routes/settings/scheduling.js +1 -0
  331. package/app/services/maintenance-schedule-actions.js +1 -0
  332. package/app/services/orchestration-engine-interface.js +1 -0
  333. package/app/services/orchestration-engine.js +1 -0
  334. package/app/services/order-allocation.js +1 -0
  335. package/app/services/scheduling.js +1 -0
  336. package/app/services/vroom-allocation-engine.js +1 -0
  337. package/app/templates/operations/orders/index/details/virtual.js +1 -0
  338. package/app/templates/settings/scheduling.js +1 -0
  339. package/app/utils/create-full-calendar-event-from-schedule-item.js +1 -0
  340. package/app/utils/route-colors.js +1 -0
  341. package/composer.json +5 -3
  342. package/extension.json +1 -1
  343. package/package.json +6 -5
  344. package/server/config/fleetops.php +20 -1
  345. package/server/migrations/2025_08_28_054927_create_parts_table.php +2 -2
  346. package/server/migrations/2025_08_28_054932_add_public_id_to_maintenance_tables.php +45 -0
  347. package/server/migrations/2025_09_01_000001_create_maintenance_schedules_table.php +88 -0
  348. package/server/migrations/2026_04_01_000001_fix_monetary_columns_in_parts_table.php +48 -0
  349. package/server/migrations/2026_04_01_000003_add_photo_uuid_to_equipment_and_parts_tables.php +61 -0
  350. package/server/migrations/2026_04_01_000004_add_public_id_to_equipments_table.php +38 -0
  351. package/server/migrations/2026_04_01_000005_add_missing_columns_to_parts_table.php +67 -0
  352. package/server/migrations/2026_04_04_000001_add_reminder_offsets_to_maintenance_schedules.php +44 -0
  353. package/server/migrations/2026_04_08_000001_add_orchestrator_columns_to_vehicles_table.php +58 -0
  354. package/server/migrations/2026_04_08_000002_add_orchestrator_columns_to_drivers_table.php +41 -0
  355. package/server/migrations/2026_04_08_000003_add_orchestrator_columns_to_orders_table.php +38 -0
  356. package/server/migrations/2026_04_08_000004_add_orchestrator_columns_to_payloads_table.php +41 -0
  357. package/server/migrations/2026_04_08_000005_add_orchestrator_columns_to_waypoints_table.php +38 -0
  358. package/server/migrations/2026_04_09_000001_create_manifests_table.php +48 -0
  359. package/server/migrations/2026_04_09_000002_create_manifest_stops_table.php +48 -0
  360. package/server/migrations/2026_04_09_000003_add_manifest_uuid_to_orders_table.php +28 -0
  361. package/server/migrations/2026_04_13_000001_add_pod_notes_columns_to_waypoints_table.php +39 -0
  362. package/server/resources/views/mail/maintenance-schedule-reminder.blade.php +59 -0
  363. package/server/resources/views/mail/work-order-dispatched.blade.php +67 -0
  364. package/server/src/Auth/Schemas/FleetOps.php +44 -0
  365. package/server/src/Console/Commands/ProcessMaintenanceTriggers.php +150 -0
  366. package/server/src/Console/Commands/SendMaintenanceReminders.php +128 -0
  367. package/server/src/Http/Controllers/Internal/v1/DriverController.php +1 -0
  368. package/server/src/Http/Controllers/Internal/v1/EquipmentController.php +27 -0
  369. package/server/src/Http/Controllers/Internal/v1/LiveController.php +9 -2
  370. package/server/src/Http/Controllers/Internal/v1/MaintenanceController.php +165 -0
  371. package/server/src/Http/Controllers/Internal/v1/MaintenanceScheduleController.php +304 -0
  372. package/server/src/Http/Controllers/Internal/v1/ManifestController.php +138 -0
  373. package/server/src/Http/Controllers/Internal/v1/OrchestrationController.php +975 -0
  374. package/server/src/Http/Controllers/Internal/v1/OrderController.php +42 -0
  375. package/server/src/Http/Controllers/Internal/v1/PartController.php +27 -0
  376. package/server/src/Http/Controllers/Internal/v1/SettingController.php +118 -0
  377. package/server/src/Http/Controllers/Internal/v1/Traits/DriverSchedulingTrait.php +214 -0
  378. package/server/src/Http/Controllers/Internal/v1/WorkOrderController.php +68 -0
  379. package/server/src/Http/Resources/v1/Driver.php +1 -0
  380. package/server/src/Http/Resources/v1/Maintenance.php +138 -0
  381. package/server/src/Http/Resources/v1/MaintenanceSchedule.php +137 -0
  382. package/server/src/Http/Resources/v1/Orchestrator/Order.php +116 -0
  383. package/server/src/Http/Resources/v1/Order.php +7 -4
  384. package/server/src/Http/Resources/v1/Waypoint.php +7 -0
  385. package/server/src/Http/Resources/v1/WorkOrder.php +136 -0
  386. package/server/src/Imports/EquipmentImport.php +32 -0
  387. package/server/src/Imports/MaintenanceImport.php +32 -0
  388. package/server/src/Imports/MaintenanceScheduleImport.php +32 -0
  389. package/server/src/Imports/PartImport.php +32 -0
  390. package/server/src/Imports/WorkOrderImport.php +32 -0
  391. package/server/src/Jobs/ProcessAllocationJob.php +119 -0
  392. package/server/src/Listeners/HandleDeliveryCompletion.php +47 -0
  393. package/server/src/Listeners/NotifyDriverOnShiftChange.php +63 -0
  394. package/server/src/Mail/MaintenanceScheduleReminder.php +68 -0
  395. package/server/src/Mail/WorkOrderDispatched.php +58 -0
  396. package/server/src/Models/Asset.php +2 -2
  397. package/server/src/Models/Device.php +1 -1
  398. package/server/src/Models/Driver.php +82 -4
  399. package/server/src/Models/Equipment.php +62 -2
  400. package/server/src/Models/Maintenance.php +127 -9
  401. package/server/src/Models/MaintenanceSchedule.php +353 -0
  402. package/server/src/Models/Manifest.php +214 -0
  403. package/server/src/Models/ManifestStop.php +162 -0
  404. package/server/src/Models/Order.php +70 -0
  405. package/server/src/Models/OrderConfig.php +5 -2
  406. package/server/src/Models/Part.php +69 -3
  407. package/server/src/Models/Payload.php +7 -2
  408. package/server/src/Models/Place.php +1 -1
  409. package/server/src/Models/Sensor.php +1 -1
  410. package/server/src/Models/ServiceQuote.php +1 -1
  411. package/server/src/Models/Vehicle.php +20 -1
  412. package/server/src/Models/Warranty.php +1 -1
  413. package/server/src/Models/Waypoint.php +7 -1
  414. package/server/src/Models/WorkOrder.php +122 -12
  415. package/server/src/Notifications/DriverShiftChanged.php +110 -0
  416. package/server/src/Observers/WorkOrderObserver.php +107 -0
  417. package/server/src/Orchestration/Contracts/OrchestrationEngineInterface.php +63 -0
  418. package/server/src/Orchestration/Engines/DriverAssignmentEngine.php +265 -0
  419. package/server/src/Orchestration/Engines/GreedyOrchestrationEngine.php +155 -0
  420. package/server/src/Orchestration/Engines/RouteSequencingEngine.php +272 -0
  421. package/server/src/Orchestration/Engines/VroomOrchestrationEngine.php +192 -0
  422. package/server/src/Orchestration/OrchestrationEngineRegistry.php +83 -0
  423. package/server/src/Orchestration/Support/OrchestrationPayloadBuilder.php +290 -0
  424. package/server/src/Providers/EventServiceProvider.php +7 -1
  425. package/server/src/Providers/FleetOpsServiceProvider.php +42 -15
  426. package/server/src/routes.php +65 -4
  427. package/translations/ar-ae.yml +44 -12
  428. package/translations/bg-bg.yaml +51 -10
  429. package/translations/en-us.yaml +444 -1
  430. package/translations/fr-fr.yaml +51 -10
  431. package/translations/mn-mn.yaml +51 -10
  432. package/translations/pt-br.yaml +51 -10
  433. package/translations/ru-ru.yaml +51 -10
  434. package/translations/vi-vn.yaml +48 -12
@@ -0,0 +1,70 @@
1
+ /**
2
+ * toCalendarDate
3
+ *
4
+ * Converts a UTC Date into a "fake local" Date whose **local** fields
5
+ * (getFullYear, getMonth, getDate, getHours, getMinutes, getSeconds) equal the
6
+ * wall-clock time in the given IANA timezone.
7
+ *
8
+ * Why this is needed
9
+ * ------------------
10
+ * @event-calendar/core has no timezone support (see maintainer comment:
11
+ * https://github.com/vkurko/calendar/issues/576). When the library ingests an
12
+ * event it reads the Date's **local** fields and stores them as UTC wall-clock
13
+ * values. This means the event is positioned at whatever the browser's local
14
+ * time is for the given UTC instant — which is wrong when the company timezone
15
+ * differs from the browser timezone.
16
+ *
17
+ * By constructing a Date whose local fields already equal the company-local
18
+ * wall-clock time, the library will position the event at the correct time
19
+ * regardless of the browser's timezone.
20
+ *
21
+ * Example
22
+ * -------
23
+ * UTC instant: 2026-04-06T14:30:00Z
24
+ * Company timezone: Asia/Singapore (UTC+8)
25
+ * Wall-clock time: 2026-04-06 22:30 SGT
26
+ *
27
+ * toCalendarDate(new Date('2026-04-06T14:30:00Z'), 'Asia/Singapore')
28
+ * → new Date(2026, 3, 6, 22, 30, 0) ← local fields = 22:30 on Apr 6
29
+ *
30
+ * The calendar reads the local fields (22:30, Apr 6) and positions the event
31
+ * there — correct regardless of whether the browser is UTC, UTC+8, or anything
32
+ * else.
33
+ *
34
+ * @param {Date|string|number} utcDate Any value that `new Date()` accepts.
35
+ * @param {string} timezone IANA timezone string, e.g. 'Asia/Singapore'.
36
+ * @returns {Date} A Date whose local fields equal the wall-clock time in `timezone`.
37
+ */
38
+ export default function toCalendarDate(utcDate, timezone) {
39
+ const date = utcDate instanceof Date ? utcDate : new Date(utcDate);
40
+
41
+ if (!timezone) {
42
+ // No timezone provided — return the date unchanged.
43
+ return date;
44
+ }
45
+
46
+ try {
47
+ const parts = new Intl.DateTimeFormat('en-US', {
48
+ timeZone: timezone,
49
+ year: 'numeric',
50
+ month: '2-digit',
51
+ day: '2-digit',
52
+ hour: '2-digit',
53
+ minute: '2-digit',
54
+ second: '2-digit',
55
+ hour12: false,
56
+ }).formatToParts(date);
57
+
58
+ const get = (type) => parseInt(parts.find((p) => p.type === type)?.value ?? '0', 10);
59
+
60
+ // hour12: false can return 24 for midnight — normalise to 0.
61
+ const hour = get('hour') % 24;
62
+
63
+ // Construct a Date whose LOCAL fields equal the company wall-clock time.
64
+ // The UTC fields of this Date are irrelevant; the library only reads local fields.
65
+ return new Date(get('year'), get('month') - 1, get('day'), hour, get('minute'), get('second'));
66
+ } catch {
67
+ // Intl unavailable or invalid timezone — return the original date unchanged.
68
+ return date;
69
+ }
70
+ }
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/components/driver/schedule';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/components/maintenance/cost-panel';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/components/maintenance/panel-header';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/components/maintenance-schedule/details';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/components/maintenance-schedule/form';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/components/modals/add-driver-shift';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/components/modals/bulk-assign-orders';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/components/modals/driver-shift';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/components/modals/orchestrator-import';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/components/modals/scheduling-conflict';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/components/modals/send-work-order';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/components/modals/set-driver-availability';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/components/orchestrator/card-fields-settings';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/components/orchestrator/order-pool';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/components/orchestrator/phase-builder';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/components/orchestrator/plan-viewer';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/components/orchestrator/resource-panel';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/components/orchestrator-workbench';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/components/vehicle/details/maintenance-history';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/components/vehicle/details/schedules';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/components/vehicle/details/work-orders';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/controllers/operations/orchestrator';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/controllers/settings/orchestrator';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/controllers/settings/scheduling';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/routes/operations/orchestrator';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/routes/operations/orders/index/details/virtual';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/routes/settings/orchestrator';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/routes/settings/scheduling';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/services/maintenance-schedule-actions';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/services/orchestration-engine-interface';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/services/orchestration-engine';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/services/order-allocation';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/services/scheduling';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/services/vroom-allocation-engine';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/templates/operations/orders/index/details/virtual';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/templates/settings/scheduling';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/utils/create-full-calendar-event-from-schedule-item';
@@ -0,0 +1 @@
1
+ export { default, ROUTE_COLOR_PALETTE, colorForId, darkenColor, routeStyleForStatus, waypointIconHtml } from '@fleetbase/fleetops-engine/utils/route-colors';
package/composer.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fleetbase/fleetops-api",
3
- "version": "0.6.37",
3
+ "version": "0.6.39",
4
4
  "description": "Fleet & Transport Management Extension for Fleetbase",
5
5
  "keywords": [
6
6
  "fleetbase-extension",
@@ -33,8 +33,10 @@
33
33
  "php-http/guzzle7-adapter": "^1.0",
34
34
  "php-units-of-measure/php-units-of-measure": "^2.2",
35
35
  "psr/http-factory-implementation": "*",
36
+ "rlanvin/php-rrule": "^2.6",
36
37
  "toin0u/geocoder-laravel": "^4.4",
37
- "webit/eval-math": "^1.0"
38
+ "webit/eval-math": "^1.0",
39
+ "spatie/icalendar-generator": "^2.8"
38
40
  },
39
41
  "require-dev": {
40
42
  "friendsofphp/php-cs-fixer": "^3.34.1",
@@ -94,4 +96,4 @@
94
96
  "@test:unit"
95
97
  ]
96
98
  }
97
- }
99
+ }
package/extension.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Fleet-Ops",
3
- "version": "0.6.37",
3
+ "version": "0.6.39",
4
4
  "description": "Fleet & Transport Management Extension for Fleetbase",
5
5
  "repository": "https://github.com/fleetbase/fleetops",
6
6
  "license": "AGPL-3.0-or-later",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fleetbase/fleetops-engine",
3
- "version": "0.6.37",
3
+ "version": "0.6.39",
4
4
  "description": "Fleet & Transport Management Extension for Fleetbase",
5
5
  "fleetbase": {
6
6
  "route": "fleet-ops"
@@ -42,9 +42,9 @@
42
42
  },
43
43
  "dependencies": {
44
44
  "@babel/core": "^7.23.2",
45
- "@fleetbase/ember-core": "^0.3.12",
46
- "@fleetbase/ember-ui": "^0.3.21",
47
- "@fleetbase/fleetops-data": "^0.1.25",
45
+ "@fleetbase/ember-core": "^0.3.18",
46
+ "@fleetbase/ember-ui": "^0.3.26",
47
+ "@fleetbase/fleetops-data": "^0.1.27",
48
48
  "@fleetbase/leaflet-routing-machine": "^3.2.17",
49
49
  "@fortawesome/ember-fontawesome": "^2.0.0",
50
50
  "@fortawesome/fontawesome-svg-core": "6.4.0",
@@ -69,7 +69,8 @@
69
69
  "ember-tag-input": "^3.1.0",
70
70
  "ember-wormhole": "^0.6.0",
71
71
  "leaflet-contextmenu": "^1.4.0",
72
- "leaflet-draw": "^1.0.4"
72
+ "leaflet-draw": "^1.0.4",
73
+ "xlsx": "^0.18.5"
73
74
  },
74
75
  "devDependencies": {
75
76
  "@babel/eslint-parser": "^7.22.15",
@@ -40,7 +40,26 @@ return [
40
40
  'host' => env('OSRM_HOST', 'https://router.project-osrm.org')
41
41
  ],
42
42
 
43
- /*
43
+ /*
44
+ |--------------------------------------------------------------------------
45
+ | VROOM Route Optimisation Engine
46
+ |--------------------------------------------------------------------------
47
+ |
48
+ | FleetOps ships its own self-contained VROOM engine that does NOT require
49
+ | the optional `fleetbase/vroom` extension to be installed. When the
50
+ | extension IS installed its `vroom.base_uri` config key takes precedence.
51
+ |
52
+ | API key resolution order:
53
+ | 1. Company-level setting written by the fleetbase/vroom extension UI
54
+ | 2. VROOM_API_KEY environment variable
55
+ | 3. No key (for self-hosted VROOM instances that do not require auth)
56
+ |
57
+ | To use a different engine set ORCHESTRATOR_ENGINE=greedy (built-in,
58
+ | no external service required) or register a custom engine.
59
+ |
60
+ */
61
+
62
+ /*
44
63
  |--------------------------------------------------------------------------
45
64
  | Distance Matrix Calculator
46
65
  | Options: "calculate", "google", "osrm"
@@ -30,8 +30,8 @@ return new class extends Migration {
30
30
  $table->foreignUuid('vendor_uuid')->nullable()->constrained('vendors', 'uuid')->nullOnDelete();
31
31
 
32
32
  $table->integer('quantity_on_hand')->default(0);
33
- $table->decimal('unit_cost', 12, 2)->nullable();
34
- $table->decimal('msrp', 12, 2)->nullable();
33
+ $table->bigInteger('unit_cost')->nullable(); // stored in cents
34
+ $table->bigInteger('msrp')->nullable(); // stored in cents
35
35
  $table->integer('reorder_point')->default(5);
36
36
  $table->integer('reorder_quantity')->default(10);
37
37
  $table->integer('max_stock_level')->nullable();
@@ -0,0 +1,45 @@
1
+ <?php
2
+
3
+ use Illuminate\Database\Migrations\Migration;
4
+ use Illuminate\Database\Schema\Blueprint;
5
+ use Illuminate\Support\Facades\Schema;
6
+
7
+ /**
8
+ * Adds the `public_id` column (required by the HasPublicId trait) to the four
9
+ * maintenance-related tables that were created without it.
10
+ */
11
+ return new class extends Migration {
12
+ /**
13
+ * Run the migrations.
14
+ */
15
+ public function up(): void
16
+ {
17
+ $tables = ['parts', 'equipment', 'work_orders', 'maintenances'];
18
+
19
+ foreach ($tables as $table) {
20
+ if (Schema::hasTable($table) && !Schema::hasColumn($table, 'public_id')) {
21
+ Schema::table($table, function (Blueprint $t) {
22
+ // Insert public_id right after _key to match the convention used
23
+ // in all other FleetOps tables (vehicles, drivers, orders, etc.)
24
+ $t->string('public_id', 191)->nullable()->unique()->index()->after('_key');
25
+ });
26
+ }
27
+ }
28
+ }
29
+
30
+ /**
31
+ * Reverse the migrations.
32
+ */
33
+ public function down(): void
34
+ {
35
+ $tables = ['parts', 'equipment', 'work_orders', 'maintenances'];
36
+
37
+ foreach ($tables as $table) {
38
+ if (Schema::hasTable($table) && Schema::hasColumn($table, 'public_id')) {
39
+ Schema::table($table, function (Blueprint $t) {
40
+ $t->dropColumn('public_id');
41
+ });
42
+ }
43
+ }
44
+ }
45
+ };
@@ -0,0 +1,88 @@
1
+ <?php
2
+
3
+ use Illuminate\Database\Migrations\Migration;
4
+ use Illuminate\Database\Schema\Blueprint;
5
+ use Illuminate\Support\Facades\Schema;
6
+
7
+ return new class extends Migration {
8
+ /**
9
+ * Run the migrations.
10
+ */
11
+ public function up(): void
12
+ {
13
+ Schema::create('maintenance_schedules', function (Blueprint $table) {
14
+ $table->increments('id');
15
+ $table->uuid('uuid')->index();
16
+ $table->string('_key')->nullable()->index();
17
+ $table->string('public_id', 191)->nullable()->unique()->index();
18
+ $table->foreignUuid('company_uuid')->constrained('companies', 'uuid')->cascadeOnDelete();
19
+
20
+ // The asset this schedule applies to (vehicle, equipment, etc.)
21
+ $table->string('subject_type')->nullable();
22
+ $table->uuid('subject_uuid')->nullable();
23
+ $table->index(['subject_type', 'subject_uuid']);
24
+
25
+ $table->string('name');
26
+ $table->string('type')->nullable()->index(); // oil_change, inspection, tire_rotation, etc.
27
+ $table->string('status')->default('active')->index(); // active, paused, completed
28
+
29
+ // Interval definition — one or more can be set; whichever triggers first wins
30
+ $table->string('interval_method')->nullable()->index(); // time, distance, engine_hours — the user-selected method
31
+ $table->string('interval_type')->nullable()->index(); // time, distance, engine_hours, or combined (legacy/computed)
32
+ $table->unsignedInteger('interval_value')->nullable(); // e.g. 5000
33
+ $table->string('interval_unit')->nullable(); // km, miles, days, months
34
+
35
+ // Odometer / engine-hour thresholds
36
+ $table->unsignedBigInteger('interval_distance')->nullable(); // distance in base unit (km)
37
+ $table->unsignedBigInteger('interval_engine_hours')->nullable(); // engine hours
38
+
39
+ // Baseline readings (set when schedule is created or reset after completion)
40
+ $table->unsignedBigInteger('last_service_odometer')->nullable();
41
+ $table->unsignedBigInteger('last_service_engine_hours')->nullable();
42
+ $table->timestamp('last_service_date')->nullable();
43
+
44
+ // Next-due thresholds (computed and stored for fast querying)
45
+ $table->timestamp('next_due_date')->nullable()->index();
46
+ $table->unsignedBigInteger('next_due_odometer')->nullable()->index();
47
+ $table->unsignedBigInteger('next_due_engine_hours')->nullable()->index();
48
+
49
+ // Default work order settings for auto-generation
50
+ $table->string('default_priority')->default('normal'); // low, normal, high, critical
51
+ $table->string('default_assignee_type')->nullable();
52
+ $table->uuid('default_assignee_uuid')->nullable();
53
+ $table->index(['default_assignee_type', 'default_assignee_uuid'], 'ms_default_assignee_idx');
54
+
55
+ $table->text('instructions')->nullable();
56
+ $table->json('meta')->nullable();
57
+
58
+ $table->foreignUuid('created_by_uuid')->nullable()->constrained('users', 'uuid')->nullOnDelete();
59
+ $table->foreignUuid('updated_by_uuid')->nullable()->constrained('users', 'uuid')->nullOnDelete();
60
+ $table->softDeletes();
61
+ $table->timestamps();
62
+
63
+ $table->index(['company_uuid', 'status']);
64
+ $table->index(['next_due_date', 'status']);
65
+ });
66
+
67
+ // Add schedule_uuid FK to work_orders for traceability
68
+ Schema::table('work_orders', function (Blueprint $table) {
69
+ $table->uuid('schedule_uuid')->nullable()->after('company_uuid');
70
+ $table->index('schedule_uuid');
71
+ });
72
+ }
73
+
74
+ /**
75
+ * Reverse the migrations.
76
+ */
77
+ public function down(): void
78
+ {
79
+ Schema::table('work_orders', function (Blueprint $table) {
80
+ $table->dropIndex(['schedule_uuid']);
81
+ $table->dropColumn('schedule_uuid');
82
+ });
83
+
84
+ Schema::disableForeignKeyConstraints();
85
+ Schema::dropIfExists('maintenance_schedules');
86
+ Schema::enableForeignKeyConstraints();
87
+ }
88
+ };
@@ -0,0 +1,48 @@
1
+ <?php
2
+
3
+ use Illuminate\Database\Migrations\Migration;
4
+ use Illuminate\Database\Schema\Blueprint;
5
+ use Illuminate\Support\Facades\Schema;
6
+
7
+ /**
8
+ * Fix monetary columns in the parts table.
9
+ *
10
+ * - Convert unit_cost and msrp from decimal(12,2) to integer (cents)
11
+ * to align with the Fleetbase monetary storage standard (all amounts stored as cents).
12
+ * - Add currency column for internationalisation support.
13
+ */
14
+ return new class extends Migration {
15
+ /**
16
+ * Run the migrations.
17
+ */
18
+ public function up(): void
19
+ {
20
+ Schema::table('parts', function (Blueprint $table) {
21
+ // Convert decimal monetary columns to integer (cents) — only needed on
22
+ // existing installs where the original migration used decimal(12,2).
23
+ // Fresh installs already have bigInteger from the updated create migration.
24
+ $columnType = Schema::getColumnType('parts', 'unit_cost');
25
+ if (in_array($columnType, ['decimal', 'float', 'double'])) {
26
+ $table->bigInteger('unit_cost')->nullable()->change();
27
+ $table->bigInteger('msrp')->nullable()->change();
28
+ }
29
+
30
+ // Add currency column for internationalisation if it doesn't exist yet
31
+ if (!Schema::hasColumn('parts', 'currency')) {
32
+ $table->string('currency')->nullable()->after('msrp');
33
+ }
34
+ });
35
+ }
36
+
37
+ /**
38
+ * Reverse the migrations.
39
+ */
40
+ public function down(): void
41
+ {
42
+ Schema::table('parts', function (Blueprint $table) {
43
+ $table->decimal('unit_cost', 12, 2)->nullable()->change();
44
+ $table->decimal('msrp', 12, 2)->nullable()->change();
45
+ $table->dropColumn('currency');
46
+ });
47
+ }
48
+ };
@@ -0,0 +1,61 @@
1
+ <?php
2
+
3
+ use Illuminate\Database\Migrations\Migration;
4
+ use Illuminate\Database\Schema\Blueprint;
5
+ use Illuminate\Support\Facades\Schema;
6
+
7
+ /**
8
+ * Adds the `photo_uuid` column to the `equipments` and `parts` tables.
9
+ *
10
+ * Both models have a `photo()` BelongsTo relationship to the `files` table and a
11
+ * `getPhotoUrlAttribute()` accessor, but the backing foreign key column was omitted
12
+ * from the original create migrations. This migration adds it as a nullable FK so
13
+ * existing rows are unaffected.
14
+ */
15
+ return new class extends Migration {
16
+ /**
17
+ * Run the migrations.
18
+ */
19
+ public function up(): void
20
+ {
21
+ if (Schema::hasTable('equipments') && !Schema::hasColumn('equipments', 'photo_uuid')) {
22
+ Schema::table('equipments', function (Blueprint $table) {
23
+ $table->foreignUuid('photo_uuid')
24
+ ->nullable()
25
+ ->after('warranty_uuid')
26
+ ->constrained('files', 'uuid')
27
+ ->nullOnDelete();
28
+ });
29
+ }
30
+
31
+ if (Schema::hasTable('parts') && !Schema::hasColumn('parts', 'photo_uuid')) {
32
+ Schema::table('parts', function (Blueprint $table) {
33
+ $table->foreignUuid('photo_uuid')
34
+ ->nullable()
35
+ ->after('warranty_uuid')
36
+ ->constrained('files', 'uuid')
37
+ ->nullOnDelete();
38
+ });
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Reverse the migrations.
44
+ */
45
+ public function down(): void
46
+ {
47
+ if (Schema::hasTable('equipments') && Schema::hasColumn('equipments', 'photo_uuid')) {
48
+ Schema::table('equipments', function (Blueprint $table) {
49
+ $table->dropForeign(['photo_uuid']);
50
+ $table->dropColumn('photo_uuid');
51
+ });
52
+ }
53
+
54
+ if (Schema::hasTable('parts') && Schema::hasColumn('parts', 'photo_uuid')) {
55
+ Schema::table('parts', function (Blueprint $table) {
56
+ $table->dropForeign(['photo_uuid']);
57
+ $table->dropColumn('photo_uuid');
58
+ });
59
+ }
60
+ }
61
+ };
@@ -0,0 +1,38 @@
1
+ <?php
2
+
3
+ use Illuminate\Database\Migrations\Migration;
4
+ use Illuminate\Database\Schema\Blueprint;
5
+ use Illuminate\Support\Facades\Schema;
6
+
7
+ /**
8
+ * Adds the `public_id` column to the `equipments` table on existing deployments.
9
+ *
10
+ * The original add_public_id_to_maintenance_tables migration referenced the table
11
+ * as 'equipment' (singular) instead of 'equipments' (plural, the actual table name
12
+ * used by the Equipment model). As a result the equipments table never received the
13
+ * public_id column on any database that had already run that migration, causing a
14
+ * SQLSTATE[42S22] "Unknown column 'public_id'" error whenever a new Equipment record
15
+ * was saved (HasPublicId::generatePublicId checks for uniqueness against this column).
16
+ *
17
+ * This migration is fully idempotent: it checks both that the table exists and that
18
+ * the column is absent before attempting to add it.
19
+ */
20
+ return new class extends Migration {
21
+ public function up(): void
22
+ {
23
+ if (Schema::hasTable('equipments') && !Schema::hasColumn('equipments', 'public_id')) {
24
+ Schema::table('equipments', function (Blueprint $table) {
25
+ $table->string('public_id', 191)->nullable()->unique()->index()->after('_key');
26
+ });
27
+ }
28
+ }
29
+
30
+ public function down(): void
31
+ {
32
+ if (Schema::hasTable('equipments') && Schema::hasColumn('equipments', 'public_id')) {
33
+ Schema::table('equipments', function (Blueprint $table) {
34
+ $table->dropColumn('public_id');
35
+ });
36
+ }
37
+ }
38
+ };