@fleetbase/fleetops-engine 0.6.58 → 0.6.60

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 (701) hide show
  1. package/README.md +3 -0
  2. package/RELEASE.md +36 -0
  3. package/addon/components/customer/form.hbs +0 -49
  4. package/addon/components/entity/card.hbs +1 -0
  5. package/addon/components/modals/order-label.hbs +1 -1
  6. package/addon/components/place/form.hbs +1 -1
  7. package/addon/components/vehicle/details/schedules.hbs +2 -2
  8. package/addon/components/vehicle/details/schedules.js +7 -1
  9. package/addon/controllers/maintenance/schedules/index/edit.js +10 -1
  10. package/addon/services/entity-actions.js +32 -0
  11. package/addon/services/vehicle-actions.js +4 -2
  12. package/addon/styles/fleetops-engine.css +0 -1
  13. package/composer.json +8 -3
  14. package/extension.json +1 -1
  15. package/index.js +7 -1
  16. package/package.json +2 -1
  17. package/scripts/coverage-file-runner.php +240 -0
  18. package/scripts/coverage-runner.php +2 -1
  19. package/scripts/coverage-summary.php +41 -2
  20. package/scripts/pest-bootstrap.php +237 -3
  21. package/scripts/pest-file-runner.php +13 -1
  22. package/scripts/pest-runner.php +57 -2
  23. package/server/config/fleetops.php +44 -0
  24. package/server/config/geocoder.php +1 -1
  25. package/server/migrations/2026_08_08_000001_make_sku_and_provider_transaction_unique_indexes_soft_delete_aware.php +152 -0
  26. package/server/resources/views/labels/entity-label.php +4 -4
  27. package/server/src/Casts/MultiPolygon.php +8 -3
  28. package/server/src/Casts/OrderConfigEntities.php +10 -3
  29. package/server/src/Casts/Point.php +10 -6
  30. package/server/src/Casts/Polygon.php +5 -2
  31. package/server/src/Console/Commands/AssignCustomerRoles.php +28 -6
  32. package/server/src/Console/Commands/AssignDriverRoles.php +36 -6
  33. package/server/src/Console/Commands/AuditCustomerUserConflicts.php +6 -1
  34. package/server/src/Console/Commands/DispatchAdhocOrders.php +12 -2
  35. package/server/src/Console/Commands/FixCustomerCompanies.php +46 -11
  36. package/server/src/Console/Commands/FixDriverCompanies.php +18 -3
  37. package/server/src/Console/Commands/FixLegacyOrderConfigs.php +31 -6
  38. package/server/src/Console/Commands/ProcessMaintenanceTriggers.php +94 -42
  39. package/server/src/Console/Commands/PurgeUnpurchasedServiceQuotes.php +42 -12
  40. package/server/src/Console/Commands/ReplayVehicleLocations.php +120 -55
  41. package/server/src/Console/Commands/SendDriverNotification.php +25 -4
  42. package/server/src/Console/Commands/SendMaintenanceReminders.php +43 -23
  43. package/server/src/Console/Commands/SimulateOrderRouteNavigation.php +36 -6
  44. package/server/src/Console/Commands/TrackOrderDistanceAndTime.php +6 -1
  45. package/server/src/Events/DriverLocationChanged.php +1 -1
  46. package/server/src/Events/DriverSimulatedLocationChanged.php +1 -1
  47. package/server/src/Events/EntityActivityChanged.php +1 -1
  48. package/server/src/Events/EntityCompleted.php +1 -1
  49. package/server/src/Events/EntityDriverAssigned.php +1 -1
  50. package/server/src/Events/FuelProviderTransactionImported.php +1 -1
  51. package/server/src/Events/FuelProviderTransactionMatched.php +1 -1
  52. package/server/src/Events/FuelProviderTransactionUnmatched.php +1 -1
  53. package/server/src/Events/FuelReportCreatedFromProvider.php +1 -1
  54. package/server/src/Events/GeofenceDwelled.php +1 -1
  55. package/server/src/Events/GeofenceEntered.php +1 -1
  56. package/server/src/Events/GeofenceExited.php +1 -1
  57. package/server/src/Events/VehicleLocationChanged.php +1 -1
  58. package/server/src/Events/WaypointActivityChanged.php +1 -1
  59. package/server/src/Events/WaypointCompleted.php +1 -1
  60. package/server/src/Exceptions/IntegratedVendorException.php +2 -2
  61. package/server/src/Exceptions/TelematicRateLimitExceededException.php +1 -1
  62. package/server/src/Http/Controllers/Api/v1/ContactController.php +89 -22
  63. package/server/src/Http/Controllers/Api/v1/CustomerController.php +346 -101
  64. package/server/src/Http/Controllers/Api/v1/DeviceController.php +48 -14
  65. package/server/src/Http/Controllers/Api/v1/DriverController.php +224 -64
  66. package/server/src/Http/Controllers/Api/v1/EntityController.php +112 -66
  67. package/server/src/Http/Controllers/Api/v1/EquipmentController.php +40 -10
  68. package/server/src/Http/Controllers/Api/v1/FleetController.php +54 -14
  69. package/server/src/Http/Controllers/Api/v1/FuelReportController.php +54 -14
  70. package/server/src/Http/Controllers/Api/v1/FuelTransactionController.php +36 -11
  71. package/server/src/Http/Controllers/Api/v1/GeofenceController.php +73 -23
  72. package/server/src/Http/Controllers/Api/v1/IssueController.php +54 -14
  73. package/server/src/Http/Controllers/Api/v1/LabelController.php +61 -22
  74. package/server/src/Http/Controllers/Api/v1/NavigatorController.php +32 -15
  75. package/server/src/Http/Controllers/Api/v1/OrderConfigController.php +35 -5
  76. package/server/src/Http/Controllers/Api/v1/OrderController.php +388 -203
  77. package/server/src/Http/Controllers/Api/v1/PartController.php +40 -10
  78. package/server/src/Http/Controllers/Api/v1/PayloadController.php +90 -30
  79. package/server/src/Http/Controllers/Api/v1/PlaceController.php +188 -91
  80. package/server/src/Http/Controllers/Api/v1/PurchaseRateController.php +100 -36
  81. package/server/src/Http/Controllers/Api/v1/ServiceAreaController.php +96 -26
  82. package/server/src/Http/Controllers/Api/v1/ServiceQuoteController.php +169 -81
  83. package/server/src/Http/Controllers/Api/v1/ServiceRateController.php +104 -75
  84. package/server/src/Http/Controllers/Api/v1/TrackingNumberController.php +92 -14
  85. package/server/src/Http/Controllers/Api/v1/TrackingStatusController.php +66 -16
  86. package/server/src/Http/Controllers/Api/v1/VehicleController.php +121 -67
  87. package/server/src/Http/Controllers/Api/v1/VendorController.php +54 -14
  88. package/server/src/Http/Controllers/Api/v1/WorkOrderController.php +47 -12
  89. package/server/src/Http/Controllers/Api/v1/ZoneController.php +84 -24
  90. package/server/src/Http/Controllers/Concerns/ResolvesReviewAccountBypass.php +62 -0
  91. package/server/src/Http/Controllers/Internal/v1/AnalyticsController.php +15 -5
  92. package/server/src/Http/Controllers/Internal/v1/ContactController.php +113 -28
  93. package/server/src/Http/Controllers/Internal/v1/CustomerController.php +36 -11
  94. package/server/src/Http/Controllers/Internal/v1/DeviceController.php +9 -4
  95. package/server/src/Http/Controllers/Internal/v1/DriverController.php +168 -70
  96. package/server/src/Http/Controllers/Internal/v1/EquipmentController.php +18 -3
  97. package/server/src/Http/Controllers/Internal/v1/FleetController.php +137 -60
  98. package/server/src/Http/Controllers/Internal/v1/FleetOpsLookupController.php +24 -9
  99. package/server/src/Http/Controllers/Internal/v1/FuelReportController.php +18 -3
  100. package/server/src/Http/Controllers/Internal/v1/GeocoderController.php +26 -8
  101. package/server/src/Http/Controllers/Internal/v1/GettingStartedController.php +12 -2
  102. package/server/src/Http/Controllers/Internal/v1/IntegratedVendorController.php +27 -6
  103. package/server/src/Http/Controllers/Internal/v1/IssueController.php +82 -29
  104. package/server/src/Http/Controllers/Internal/v1/MaintenanceController.php +34 -26
  105. package/server/src/Http/Controllers/Internal/v1/MaintenanceScheduleController.php +141 -97
  106. package/server/src/Http/Controllers/Internal/v1/ManifestController.php +28 -8
  107. package/server/src/Http/Controllers/Internal/v1/MetricsController.php +21 -12
  108. package/server/src/Http/Controllers/Internal/v1/MorphController.php +90 -18
  109. package/server/src/Http/Controllers/Internal/v1/NavigatorController.php +88 -35
  110. package/server/src/Http/Controllers/Internal/v1/OrchestrationController.php +149 -39
  111. package/server/src/Http/Controllers/Internal/v1/OrderConfigController.php +54 -18
  112. package/server/src/Http/Controllers/Internal/v1/OrderController.php +298 -86
  113. package/server/src/Http/Controllers/Internal/v1/PartController.php +18 -3
  114. package/server/src/Http/Controllers/Internal/v1/PaymentController.php +46 -14
  115. package/server/src/Http/Controllers/Internal/v1/PlaceController.php +31 -5
  116. package/server/src/Http/Controllers/Internal/v1/ProofController.php +88 -48
  117. package/server/src/Http/Controllers/Internal/v1/SearchController.php +1 -1
  118. package/server/src/Http/Controllers/Internal/v1/SensorController.php +6 -1
  119. package/server/src/Http/Controllers/Internal/v1/ServiceAreaController.php +6 -1
  120. package/server/src/Http/Controllers/Internal/v1/ServiceQuoteController.php +255 -105
  121. package/server/src/Http/Controllers/Internal/v1/SettingController.php +88 -35
  122. package/server/src/Http/Controllers/Internal/v1/TelematicController.php +1 -4
  123. package/server/src/Http/Controllers/Internal/v1/Traits/DriverSchedulingTrait.php +42 -14
  124. package/server/src/Http/Controllers/Internal/v1/VendorController.php +103 -33
  125. package/server/src/Http/Controllers/Internal/v1/WorkOrderController.php +42 -12
  126. package/server/src/Http/Filter/DriverFilter.php +2 -2
  127. package/server/src/Http/Filter/MaintenanceScheduleFilter.php +40 -0
  128. package/server/src/Http/Filter/OrderFilter.php +1 -1
  129. package/server/src/Http/Filter/VehicleFilter.php +21 -7
  130. package/server/src/Http/Middleware/AuthenticateCustomerToken.php +12 -2
  131. package/server/src/Http/Requests/BulkDispatchRequest.php +3 -9
  132. package/server/src/Http/Requests/CancelOrderRequest.php +2 -6
  133. package/server/src/Http/Requests/CreateContactRequest.php +2 -6
  134. package/server/src/Http/Requests/CreateCustomerRequest.php +9 -1
  135. package/server/src/Http/Requests/CreateDeviceRequest.php +2 -2
  136. package/server/src/Http/Requests/CreateDriverRequest.php +3 -9
  137. package/server/src/Http/Requests/CreateEntityRequest.php +2 -6
  138. package/server/src/Http/Requests/CreateEquipmentRequest.php +2 -2
  139. package/server/src/Http/Requests/CreateFleetRequest.php +2 -6
  140. package/server/src/Http/Requests/CreateFuelReportRequest.php +16 -9
  141. package/server/src/Http/Requests/CreateFuelTransactionRequest.php +66 -3
  142. package/server/src/Http/Requests/CreateIssueRequest.php +2 -6
  143. package/server/src/Http/Requests/CreateOrderRequest.php +7 -8
  144. package/server/src/Http/Requests/CreatePartRequest.php +41 -3
  145. package/server/src/Http/Requests/CreatePayloadRequest.php +7 -9
  146. package/server/src/Http/Requests/CreatePlaceRequest.php +2 -6
  147. package/server/src/Http/Requests/CreatePurchaseRateRequest.php +2 -6
  148. package/server/src/Http/Requests/CreateSensorRequest.php +2 -2
  149. package/server/src/Http/Requests/CreateServiceAreaRequest.php +2 -6
  150. package/server/src/Http/Requests/CreateServiceQuoteRequest.php +2 -6
  151. package/server/src/Http/Requests/CreateServiceRateRequest.php +2 -6
  152. package/server/src/Http/Requests/CreateTrackingNumberRequest.php +2 -6
  153. package/server/src/Http/Requests/CreateTrackingStatusRequest.php +2 -6
  154. package/server/src/Http/Requests/CreateVehicleRequest.php +2 -6
  155. package/server/src/Http/Requests/CreateVendorRequest.php +2 -6
  156. package/server/src/Http/Requests/CreateWorkOrderRequest.php +2 -2
  157. package/server/src/Http/Requests/CreateZoneRequest.php +2 -6
  158. package/server/src/Http/Requests/DecodeTrackingNumberQR.php +2 -6
  159. package/server/src/Http/Requests/DriverSimulationRequest.php +2 -6
  160. package/server/src/Http/Requests/Internal/AssignOrderRequest.php +3 -7
  161. package/server/src/Http/Requests/Internal/CreateDriverRequest.php +4 -12
  162. package/server/src/Http/Requests/Internal/CreateOrderConfigRequest.php +2 -6
  163. package/server/src/Http/Requests/Internal/CreateOrderRequest.php +7 -8
  164. package/server/src/Http/Requests/Internal/FleetActionRequest.php +18 -12
  165. package/server/src/Http/Requests/Internal/UpdateDriverRequest.php +6 -3
  166. package/server/src/Http/Requests/QueryServiceQuotesRequest.php +2 -6
  167. package/server/src/Http/Requests/ScheduleOrderRequest.php +2 -6
  168. package/server/src/Http/Requests/UpdateIssueRequest.php +1 -3
  169. package/server/src/Http/Resources/v1/Customer.php +2 -2
  170. package/server/src/Http/Resources/v1/Maintenance.php +3 -4
  171. package/server/src/Http/Resources/v1/MaintenanceSchedule.php +3 -4
  172. package/server/src/Http/Resources/v1/Order.php +3 -7
  173. package/server/src/Http/Resources/v1/PurchaseRate.php +4 -6
  174. package/server/src/Http/Resources/v1/TrackingNumber.php +33 -0
  175. package/server/src/Http/Resources/v1/TrackingStatus.php +4 -6
  176. package/server/src/Http/Resources/v1/WorkOrder.php +3 -4
  177. package/server/src/Imports/ContactImport.php +10 -1
  178. package/server/src/Imports/DriverImport.php +10 -1
  179. package/server/src/Imports/EquipmentImport.php +6 -1
  180. package/server/src/Imports/FleetImport.php +10 -1
  181. package/server/src/Imports/FuelReportImport.php +10 -1
  182. package/server/src/Imports/IssueImport.php +10 -1
  183. package/server/src/Imports/MaintenanceImport.php +6 -1
  184. package/server/src/Imports/MaintenanceScheduleImport.php +6 -1
  185. package/server/src/Imports/PartImport.php +6 -1
  186. package/server/src/Imports/PlaceImport.php +10 -1
  187. package/server/src/Imports/VehicleImport.php +10 -1
  188. package/server/src/Imports/VendorImport.php +10 -1
  189. package/server/src/Imports/WorkOrderImport.php +6 -1
  190. package/server/src/Integrations/Lalamove/Lalamove.php +3 -7
  191. package/server/src/Integrations/Lalamove/LalamoveServiceType.php +5 -8
  192. package/server/src/Jobs/CheckGeofenceDwell.php +41 -16
  193. package/server/src/Jobs/FinalizeApiOrderCreation.php +17 -2
  194. package/server/src/Jobs/FinalizeInternalOrderCreation.php +11 -1
  195. package/server/src/Jobs/NotifyBulkAssignedDriver.php +29 -16
  196. package/server/src/Jobs/ProcessAllocationJob.php +59 -25
  197. package/server/src/Jobs/ReplayPositions.php +17 -10
  198. package/server/src/Jobs/SendPositionReplay.php +18 -7
  199. package/server/src/Jobs/SimulateDrivingRoute.php +14 -3
  200. package/server/src/Jobs/SyncFuelProviderTransactionsJob.php +12 -2
  201. package/server/src/Listeners/HandleDeliveryCompletion.php +11 -1
  202. package/server/src/Listeners/HandleGeofenceDwelled.php +6 -1
  203. package/server/src/Listeners/HandleGeofenceEntered.php +4 -2
  204. package/server/src/Listeners/HandleGeofenceExited.php +6 -1
  205. package/server/src/Listeners/HandleOrderCanceled.php +18 -3
  206. package/server/src/Listeners/HandleOrderDispatchFailed.php +12 -2
  207. package/server/src/Listeners/HandleOrderDispatched.php +61 -26
  208. package/server/src/Listeners/HandleOrderDriverAssigned.php +12 -2
  209. package/server/src/Listeners/HandleUserRemovedFromCompany.php +19 -6
  210. package/server/src/Listeners/NotifyDriverOnShiftChange.php +24 -4
  211. package/server/src/Listeners/NotifyOrderEvent.php +11 -6
  212. package/server/src/Models/Contact.php +6 -7
  213. package/server/src/Models/Device.php +26 -3
  214. package/server/src/Models/Driver.php +0 -6
  215. package/server/src/Models/Entity.php +4 -4
  216. package/server/src/Models/Equipment.php +1 -1
  217. package/server/src/Models/FuelReport.php +26 -1
  218. package/server/src/Models/IntegratedVendor.php +2 -2
  219. package/server/src/Models/Issue.php +5 -1
  220. package/server/src/Models/MaintenanceSchedule.php +25 -10
  221. package/server/src/Models/Order.php +18 -15
  222. package/server/src/Models/OrderConfig.php +1 -1
  223. package/server/src/Models/Payload.php +9 -16
  224. package/server/src/Models/Place.php +20 -13
  225. package/server/src/Models/Sensor.php +24 -0
  226. package/server/src/Models/ServiceArea.php +3 -6
  227. package/server/src/Models/ServiceQuote.php +5 -0
  228. package/server/src/Models/ServiceRate.php +13 -6
  229. package/server/src/Models/Telematic.php +2 -2
  230. package/server/src/Models/TrackingNumber.php +55 -10
  231. package/server/src/Models/TrackingStatus.php +24 -4
  232. package/server/src/Models/Waypoint.php +44 -10
  233. package/server/src/Models/Zone.php +3 -6
  234. package/server/src/Notifications/DriverArrivedAtGeofence.php +1 -1
  235. package/server/src/Notifications/OrderDispatched.php +3 -9
  236. package/server/src/Notifications/OrderPing.php +3 -9
  237. package/server/src/Observers/CategoryObserver.php +6 -1
  238. package/server/src/Observers/CompanyObserver.php +5 -0
  239. package/server/src/Observers/CompanyUserObserver.php +12 -2
  240. package/server/src/Observers/DriverObserver.php +19 -4
  241. package/server/src/Observers/FleetObserver.php +6 -1
  242. package/server/src/Observers/PurchaseRateObserver.php +66 -11
  243. package/server/src/Observers/ServiceAreaObserver.php +12 -2
  244. package/server/src/Observers/ServiceRateObserver.php +21 -6
  245. package/server/src/Observers/TrackingNumberObserver.php +19 -4
  246. package/server/src/Observers/UserObserver.php +6 -1
  247. package/server/src/Observers/VehicleObserver.php +27 -7
  248. package/server/src/Observers/WorkOrderObserver.php +27 -7
  249. package/server/src/Orchestration/Engines/DriverAssignmentEngine.php +8 -3
  250. package/server/src/Orchestration/Support/OrchestrationPayloadBuilder.php +2 -2
  251. package/server/src/Providers/FleetOpsServiceProvider.php +12 -0
  252. package/server/src/Providers/NotificationServiceProvider.php +6 -0
  253. package/server/src/Support/Ai/Capabilities/AssetStatusCapability.php +36 -26
  254. package/server/src/Support/Ai/Capabilities/CreateOrderPreviewCapability.php +18 -5
  255. package/server/src/Support/Ai/Capabilities/OrderInsightsCapability.php +6 -1
  256. package/server/src/Support/Ai/Capabilities/SearchResourcesCapability.php +26 -6
  257. package/server/src/Support/Analytics/FuelEfficiency.php +9 -3
  258. package/server/src/Support/Analytics/FuelProviderSummary.php +14 -5
  259. package/server/src/Support/Analytics/GeofenceViolations.php +40 -20
  260. package/server/src/Support/Analytics/IssuesInsights.php +38 -18
  261. package/server/src/Support/Analytics/MaintenanceOverview.php +51 -21
  262. package/server/src/Support/Analytics/OnTimeDelivery.php +3 -2
  263. package/server/src/Support/Analytics/OperationsPulse.php +59 -35
  264. package/server/src/Support/Analytics/OrdersByStatus.php +12 -7
  265. package/server/src/Support/Analytics/RevenueTrend.php +16 -6
  266. package/server/src/Support/Analytics/TopDrivers.php +3 -2
  267. package/server/src/Support/FleetOps.php +109 -104
  268. package/server/src/Support/FuelProviders/FuelProviderService.php +10 -1
  269. package/server/src/Support/Geocoding.php +52 -14
  270. package/server/src/Support/GeofenceIntersectionService.php +47 -27
  271. package/server/src/Support/LiveOrderQuery.php +6 -1
  272. package/server/src/Support/Metrics/ActiveRevenueQuery.php +3 -2
  273. package/server/src/Support/Metrics/FuelCostsMetric.php +6 -1
  274. package/server/src/Support/ResolvesOrderServiceStops.php +10 -0
  275. package/server/src/Support/Telematics/Providers/GeotabProvider.php +9 -4
  276. package/server/src/Support/Utils.php +122 -16
  277. package/server/src/Tracking/Providers/GoogleRoutesTrackingProvider.php +6 -1
  278. package/server/src/Tracking/Providers/OsrmTrackingProvider.php +11 -6
  279. package/server/src/Tracking/TrackingProviderManager.php +2 -3
  280. package/server/src/Tracking/TrackingProviderRegistry.php +8 -4
  281. package/server/src/Traits/PayloadAccessors.php +6 -1
  282. package/server/src/routes.php +24 -17
  283. package/server/tests/AiOperationalQueryCapabilityTest.php +457 -1
  284. package/server/tests/AiPreviewCapabilityContractsTest.php +180 -0
  285. package/server/tests/AnalyticsRoutesTest.php +380 -1
  286. package/server/tests/AnalyticsWidgetContractsTest.php +740 -0
  287. package/server/tests/ApiContactControllerContractsTest.php +284 -0
  288. package/server/tests/ApiCustomerControllerContractsTest.php +1130 -0
  289. package/server/tests/ApiDriverControllerContractsTest.php +603 -0
  290. package/server/tests/ApiEntityControllerContractsTest.php +329 -0
  291. package/server/tests/ApiEquipmentControllerContractsTest.php +239 -0
  292. package/server/tests/ApiFleetControllerContractsTest.php +176 -0
  293. package/server/tests/ApiFuelReportControllerContractsTest.php +217 -0
  294. package/server/tests/ApiIssueControllerContractsTest.php +217 -0
  295. package/server/tests/ApiOrderControllerContractsTest.php +1030 -0
  296. package/server/tests/ApiPartControllerContractsTest.php +251 -0
  297. package/server/tests/ApiPayloadControllerContractsTest.php +314 -0
  298. package/server/tests/ApiPlaceControllerContractsTest.php +541 -0
  299. package/server/tests/ApiPurchaseRateControllerContractsTest.php +283 -0
  300. package/server/tests/ApiServiceAreaZoneControllerContractsTest.php +442 -0
  301. package/server/tests/ApiServiceQuoteControllerContractsTest.php +322 -0
  302. package/server/tests/ApiTrackingNumberControllerContractsTest.php +225 -0
  303. package/server/tests/ApiTrackingStatusControllerContractsTest.php +254 -0
  304. package/server/tests/ApiVehicleControllerContractsTest.php +368 -0
  305. package/server/tests/ApiVendorControllerContractsTest.php +199 -0
  306. package/server/tests/AssetAndPlaceSearchContractsTest.php +220 -0
  307. package/server/tests/BackendSmallModelContractsTest.php +354 -0
  308. package/server/tests/CapacityAllocationEngineTest.php +56 -0
  309. package/server/tests/CommandContractsTest.php +2695 -0
  310. package/server/tests/CompactResourceSerializationTest.php +2838 -0
  311. package/server/tests/ControllerFilterContractsTest.php +1273 -0
  312. package/server/tests/ControllerHelperContractsTest.php +1740 -0
  313. package/server/tests/ControllerSerializationContractsTest.php +141 -0
  314. package/server/tests/CoverageSummaryScriptTest.php +93 -0
  315. package/server/tests/CustomerContactIdentitySafetyTest.php +1 -6
  316. package/server/tests/CustomerEndpointTest.php +169 -2
  317. package/server/tests/DriverFilterExecutionTest.php +263 -0
  318. package/server/tests/DriverGeofenceProcessingTest.php +153 -0
  319. package/server/tests/DriverResourceSerializationTest.php +245 -0
  320. package/server/tests/DriverSchedulingTraitContractsTest.php +259 -0
  321. package/server/tests/EventContractsTest.php +1259 -0
  322. package/server/tests/ExceptionContractsTest.php +81 -0
  323. package/server/tests/ExpansionContractsTest.php +242 -0
  324. package/server/tests/ExportCoverageTest.php +116 -0
  325. package/server/tests/Feature/Http/Api/ContactControllerPhotoAndDeleteTest.php +199 -0
  326. package/server/tests/Feature/Http/Api/CustomerControllerHelperSeamsTest.php +831 -0
  327. package/server/tests/Feature/Http/Api/DeviceControllerContractsTest.php +347 -0
  328. package/server/tests/Feature/Http/Api/DeviceControllerCrudTest.php +176 -0
  329. package/server/tests/Feature/Http/Api/DriverControllerAuthFlowsTest.php +530 -0
  330. package/server/tests/Feature/Http/Api/DriverControllerHelpersTest.php +240 -0
  331. package/server/tests/Feature/Http/Api/DriverControllerLookupTest.php +186 -0
  332. package/server/tests/Feature/Http/Api/DriverControllerOrganizationsTest.php +112 -0
  333. package/server/tests/Feature/Http/Api/DriverControllerSessionHelpersTest.php +207 -0
  334. package/server/tests/Feature/Http/Api/DriverControllerSwitchOrgAndGeofenceTest.php +329 -0
  335. package/server/tests/Feature/Http/Api/DriverControllerTrackTest.php +383 -0
  336. package/server/tests/Feature/Http/Api/EntityControllerHelpersTest.php +150 -0
  337. package/server/tests/Feature/Http/Api/FuelTransactionControllerContractsTest.php +352 -0
  338. package/server/tests/Feature/Http/Api/GeofenceControllerContractsTest.php +461 -0
  339. package/server/tests/Feature/Http/Api/LabelControllerSubjectsTest.php +148 -0
  340. package/server/tests/Feature/Http/Api/OrderConfigControllerTest.php +112 -0
  341. package/server/tests/Feature/Http/Api/OrderControllerCreateTest.php +279 -0
  342. package/server/tests/Feature/Http/Api/OrderControllerIntegratedVendorTest.php +295 -0
  343. package/server/tests/Feature/Http/Api/OrderControllerLifecycleActionsTest.php +279 -0
  344. package/server/tests/Feature/Http/Api/OrderControllerLookupHelpersTest.php +207 -0
  345. package/server/tests/Feature/Http/Api/OrderControllerNearbyFiltersTest.php +282 -0
  346. package/server/tests/Feature/Http/Api/OrderControllerPersistenceHelpersTest.php +216 -0
  347. package/server/tests/Feature/Http/Api/OrderControllerQueryFiltersTest.php +184 -0
  348. package/server/tests/Feature/Http/Api/OrderControllerStartActivityTest.php +663 -0
  349. package/server/tests/Feature/Http/Api/PayloadControllerHelpersTest.php +134 -0
  350. package/server/tests/Feature/Http/Api/PlaceAndServiceQuoteSeamsTest.php +479 -0
  351. package/server/tests/Feature/Http/Api/PurchaseRateControllerHelpersTest.php +176 -0
  352. package/server/tests/Feature/Http/Api/PurchaseRateControllerOrderCreationTest.php +268 -0
  353. package/server/tests/Feature/Http/Api/SensorControllerCrudTest.php +239 -0
  354. package/server/tests/Feature/Http/Api/ServiceAreaControllerBorderAndSeamsTest.php +187 -0
  355. package/server/tests/Feature/Http/Api/ServiceQuoteControllerQueryTest.php +405 -0
  356. package/server/tests/Feature/Http/Api/ServiceQuoteControllerVendorBridgeTest.php +212 -0
  357. package/server/tests/Feature/Http/Api/ServiceRateControllerContractsTest.php +263 -0
  358. package/server/tests/Feature/Http/Api/SmallApiControllerHelpersTest.php +272 -0
  359. package/server/tests/Feature/Http/Api/TrackingNumberControllerHelpersTest.php +160 -0
  360. package/server/tests/Feature/Http/Api/TrackingStatusControllerHelpersTest.php +165 -0
  361. package/server/tests/Feature/Http/Api/VehicleControllerTrackingTest.php +483 -0
  362. package/server/tests/Feature/Http/Api/WorkOrderControllerContractsTest.php +326 -0
  363. package/server/tests/Feature/Http/Api/WorkOrderControllerHelpersTest.php +130 -0
  364. package/server/tests/Feature/Http/Api/ZoneControllerBordersAndSeamsTest.php +294 -0
  365. package/server/tests/Feature/Http/FleetOpsRouteRegistrationTest.php +189 -0
  366. package/server/tests/Feature/Http/Internal/AnalyticsControllerSeamsTest.php +53 -0
  367. package/server/tests/Feature/Http/Internal/ContactControllerContractsTest.php +240 -0
  368. package/server/tests/Feature/Http/Internal/ContactControllerCustomerGuardsTest.php +128 -0
  369. package/server/tests/Feature/Http/Internal/ContactControllerEndpointsTest.php +294 -0
  370. package/server/tests/Feature/Http/Internal/CustomerControllerCredentialsTest.php +196 -0
  371. package/server/tests/Feature/Http/Internal/DeviceControllerContractsTest.php +370 -0
  372. package/server/tests/Feature/Http/Internal/DeviceControllerExportAndFiltersTest.php +151 -0
  373. package/server/tests/Feature/Http/Internal/DriverControllerContractsTest.php +1167 -0
  374. package/server/tests/Feature/Http/Internal/DriverControllerCreateRecordTest.php +233 -0
  375. package/server/tests/Feature/Http/Internal/DriverControllerExistingUserAdoptionTest.php +710 -0
  376. package/server/tests/Feature/Http/Internal/DriverControllerHelpersTest.php +218 -0
  377. package/server/tests/Feature/Http/Internal/FleetAssignmentsAndTriggersTest.php +198 -0
  378. package/server/tests/Feature/Http/Internal/FleetOpsLookupControllerDbTest.php +90 -0
  379. package/server/tests/Feature/Http/Internal/HubControllerTest.php +206 -0
  380. package/server/tests/Feature/Http/Internal/IssueControllerContractsTest.php +404 -0
  381. package/server/tests/Feature/Http/Internal/IssueControllerExportImportTest.php +118 -0
  382. package/server/tests/Feature/Http/Internal/LiveControllerEndpointsTest.php +246 -0
  383. package/server/tests/Feature/Http/Internal/LiveControllerTest.php +778 -0
  384. package/server/tests/Feature/Http/Internal/MaintenanceScheduleControllerContractsTest.php +263 -0
  385. package/server/tests/Feature/Http/Internal/MaintenanceScheduleControllerSurfacesTest.php +214 -0
  386. package/server/tests/Feature/Http/Internal/MetricsControllerContractsTest.php +249 -0
  387. package/server/tests/Feature/Http/Internal/MetricsControllerHelpersTest.php +66 -0
  388. package/server/tests/Feature/Http/Internal/MorphControllerHelpersTest.php +125 -0
  389. package/server/tests/Feature/Http/Internal/NavigatorControllerHelpersTest.php +201 -0
  390. package/server/tests/Feature/Http/Internal/OrchestrationControllerContractsTest.php +928 -0
  391. package/server/tests/Feature/Http/Internal/OrchestrationControllerHelpersTest.php +214 -0
  392. package/server/tests/Feature/Http/Internal/OrchestrationControllerImportOrdersTest.php +340 -0
  393. package/server/tests/Feature/Http/Internal/OrderConfigControllerContractsTest.php +314 -0
  394. package/server/tests/Feature/Http/Internal/OrderControllerActivityFlowsTest.php +663 -0
  395. package/server/tests/Feature/Http/Internal/OrderControllerCapturePhotoTest.php +507 -0
  396. package/server/tests/Feature/Http/Internal/OrderControllerContractsTest.php +1742 -0
  397. package/server/tests/Feature/Http/Internal/OrderControllerCreateRecordTest.php +488 -0
  398. package/server/tests/Feature/Http/Internal/OrderControllerHelperSeamsTest.php +298 -0
  399. package/server/tests/Feature/Http/Internal/OrderControllerHelpersTest.php +267 -0
  400. package/server/tests/Feature/Http/Internal/OrderControllerImportFromFilesTest.php +179 -0
  401. package/server/tests/Feature/Http/Internal/OrderControllerUpstreamNotFoundTest.php +80 -0
  402. package/server/tests/Feature/Http/Internal/PaymentControllerPaymentsTest.php +154 -0
  403. package/server/tests/Feature/Http/Internal/PlaceControllerTest.php +252 -0
  404. package/server/tests/Feature/Http/Internal/PositionControllerReplayMetricsTest.php +163 -0
  405. package/server/tests/Feature/Http/Internal/ProofControllerContractsTest.php +219 -0
  406. package/server/tests/Feature/Http/Internal/SearchControllerEndpointTest.php +151 -0
  407. package/server/tests/Feature/Http/Internal/ServiceQuoteControllerHelpersTest.php +208 -0
  408. package/server/tests/Feature/Http/Internal/ServiceQuoteControllerQueryRecordTest.php +217 -0
  409. package/server/tests/Feature/Http/Internal/ServiceQuoteControllerVendorBridgeTest.php +239 -0
  410. package/server/tests/Feature/Http/Internal/ServiceQuotePreliminaryQueryTest.php +271 -0
  411. package/server/tests/Feature/Http/Internal/SettingControllerHelpersTest.php +133 -0
  412. package/server/tests/Feature/Http/Internal/SmallInternalControllersTest.php +180 -0
  413. package/server/tests/Feature/Http/Internal/TelematicControllerEndpointsTest.php +417 -0
  414. package/server/tests/Feature/Http/Internal/VehicleControllerEndpointsTest.php +361 -0
  415. package/server/tests/Feature/Http/Internal/VendorControllerEndpointsTest.php +203 -0
  416. package/server/tests/Feature/Http/Internal/WorkOrderAndConfigSurfacesTest.php +289 -0
  417. package/server/tests/Feature/Http/Internal/WorkOrderControllerContractsTest.php +199 -0
  418. package/server/tests/Feature/Http/TelematicWebhookIngestTest.php +343 -0
  419. package/server/tests/Feature/Http/Telematics/TelematicWebhookControllerProcessingTest.php +254 -0
  420. package/server/tests/FleetOpsSupportContractsTest.php +187 -0
  421. package/server/tests/FlespiProviderContractsTest.php +244 -0
  422. package/server/tests/FlowResourceTest.php +295 -0
  423. package/server/tests/FuelProviderConnectionControllerContractsTest.php +303 -0
  424. package/server/tests/FuelProviderImplementationTest.php +753 -0
  425. package/server/tests/FuelProviderResourceContractsTest.php +171 -0
  426. package/server/tests/FuelProviderTransactionControllerContractsTest.php +198 -0
  427. package/server/tests/GeofenceIntersectionServiceContractsTest.php +164 -0
  428. package/server/tests/HOSConstraintContractsTest.php +128 -0
  429. package/server/tests/HubAndGettingStartedContractsTest.php +158 -0
  430. package/server/tests/ImportContractsTest.php +191 -0
  431. package/server/tests/InternalCustomerControllerContractsTest.php +238 -0
  432. package/server/tests/InternalFleetControllerContractsTest.php +389 -0
  433. package/server/tests/InternalImportExportControllerContractsTest.php +289 -0
  434. package/server/tests/InternalMetricsControllerContractsTest.php +69 -0
  435. package/server/tests/InternalPlaceWorkOrderControllerContractsTest.php +207 -0
  436. package/server/tests/InternalServiceQuoteCheckoutControllerContractsTest.php +470 -0
  437. package/server/tests/InternalVendorControllerContractsTest.php +331 -0
  438. package/server/tests/InventoryTelemetryModelContractsTest.php +516 -0
  439. package/server/tests/IssueTimelineContractsTest.php +191 -0
  440. package/server/tests/LabelPdfRenderingTest.php +57 -0
  441. package/server/tests/LalamoveIntegrationContractsTest.php +167 -0
  442. package/server/tests/LiveOrderQueryTest.php +145 -18
  443. package/server/tests/LookupAndGeocoderControllerContractsTest.php +357 -0
  444. package/server/tests/MaintainableTraitContractsTest.php +245 -0
  445. package/server/tests/MaintenanceScheduleControllerContractsTest.php +101 -0
  446. package/server/tests/MaintenanceWarrantyContractsTest.php +237 -0
  447. package/server/tests/ManifestControllerContractsTest.php +310 -0
  448. package/server/tests/MetricsRegistryTest.php +596 -10
  449. package/server/tests/MiddlewareContractsTest.php +150 -0
  450. package/server/tests/ModelAccessorContractsTest.php +3201 -0
  451. package/server/tests/MorphControllerContractsTest.php +410 -0
  452. package/server/tests/NavigatorControllerContractsTest.php +206 -0
  453. package/server/tests/NotificationAndMailContractsTest.php +677 -0
  454. package/server/tests/ObserverContractsTest.php +1414 -0
  455. package/server/tests/OperationalAlgorithmContractsTest.php +852 -0
  456. package/server/tests/OperationsMonitorEndpointTest.php +2 -1
  457. package/server/tests/OrchestrationPayloadBuilderTest.php +87 -0
  458. package/server/tests/OrderActivityFlowRegressionTest.php +354 -7
  459. package/server/tests/OrderDispatchListenerContractsTest.php +577 -0
  460. package/server/tests/OrderFilterExecutionTest.php +244 -0
  461. package/server/tests/OrderQueuedClosureRegressionTest.php +2 -1
  462. package/server/tests/PaymentControllerContractsTest.php +199 -0
  463. package/server/tests/PointResolutionTest.php +54 -0
  464. package/server/tests/ProcessAllocationJobContractsTest.php +224 -0
  465. package/server/tests/ProofAndSensorControllerContractsTest.php +44 -0
  466. package/server/tests/ProviderContractsTest.php +409 -0
  467. package/server/tests/PublicApiControllerInputContractsTest.php +294 -0
  468. package/server/tests/QueueJobContractsTest.php +764 -0
  469. package/server/tests/ReportSchemaContractsTest.php +271 -0
  470. package/server/tests/RequestContractsTest.php +1058 -0
  471. package/server/tests/RouteRegistrationExecutionTest.php +178 -0
  472. package/server/tests/RouteSequencingEngineTest.php +179 -0
  473. package/server/tests/RulesAndCastsTest.php +246 -0
  474. package/server/tests/SamsaraProviderContractsTest.php +272 -0
  475. package/server/tests/SearchControllerContractsTest.php +311 -0
  476. package/server/tests/ServiceRateRouteValidationTest.php +76 -0
  477. package/server/tests/SettingControllerContractsTest.php +410 -0
  478. package/server/tests/SmallControllerContractsTest.php +480 -0
  479. package/server/tests/SupportAnalyticsCustomerAuthContractsTest.php +221 -0
  480. package/server/tests/SupportJobAndAiCoverageTest.php +812 -0
  481. package/server/tests/SupportServiceContractsTest.php +287 -0
  482. package/server/tests/SupportValueObjectsTest.php +155 -0
  483. package/server/tests/TelematicControllerContractsTest.php +185 -0
  484. package/server/tests/TelematicProviderRegistryTest.php +167 -0
  485. package/server/tests/TelematicServiceHelperContractsTest.php +315 -0
  486. package/server/tests/TelematicWebhookControllerContractsTest.php +253 -0
  487. package/server/tests/TelematicsHardeningTest.php +642 -86
  488. package/server/tests/TrackingIntelligenceTest.php +644 -1
  489. package/server/tests/TrackingNumberTraitContractsTest.php +106 -0
  490. package/server/tests/Unit/Casts/SpatialCastBranchesTest.php +75 -0
  491. package/server/tests/Unit/Console/AssignCustomerRolesCommandTest.php +102 -0
  492. package/server/tests/Unit/Console/AssignDriverRolesCommandTest.php +113 -0
  493. package/server/tests/Unit/Console/Commands/FixLegacyOrderConfigsHelpersTest.php +108 -0
  494. package/server/tests/Unit/Console/Commands/ProcessOperationalAlertsCommandTest.php +265 -0
  495. package/server/tests/Unit/Console/Commands/ReplayVehicleLocationsCommandTest.php +320 -0
  496. package/server/tests/Unit/Console/Commands/SimulateGeofenceEventsCommandTest.php +207 -0
  497. package/server/tests/Unit/Console/FixCommandsAndMaintenanceControllerTest.php +256 -0
  498. package/server/tests/Unit/Console/FleetOpsCommandsTest.php +198 -0
  499. package/server/tests/Unit/Console/ReplayVehicleLocationsCommandTest.php +252 -0
  500. package/server/tests/Unit/Console/SendMaintenanceRemindersTest.php +212 -0
  501. package/server/tests/Unit/Console/SimulateGeofenceEventsCommandTest.php +232 -0
  502. package/server/tests/Unit/Console/SyncTelematicsCommandTest.php +136 -0
  503. package/server/tests/Unit/Constraints/HOSConstraintTest.php +158 -0
  504. package/server/tests/Unit/Events/EventModelRecordTest.php +93 -0
  505. package/server/tests/Unit/Events/OrderDispatchFailedTest.php +34 -0
  506. package/server/tests/Unit/Exports/ExportCollectionsTest.php +142 -0
  507. package/server/tests/Unit/Exports/OperationalExportMappingTest.php +651 -0
  508. package/server/tests/Unit/Exports/VehicleExportTest.php +284 -0
  509. package/server/tests/Unit/Flow/EventFiringTest.php +95 -0
  510. package/server/tests/Unit/Http/Api/QueryWithRequestSeamsTest.php +198 -0
  511. package/server/tests/Unit/Http/Api/SensorInputTest.php +95 -0
  512. package/server/tests/Unit/Http/Filter/DeviceFilterTest.php +199 -0
  513. package/server/tests/Unit/Http/Filter/EmptyValueGuardsTest.php +66 -0
  514. package/server/tests/Unit/Http/Filter/FilterDateRangesTest.php +72 -0
  515. package/server/tests/Unit/Http/Filter/FuelProviderTransactionFilterTest.php +172 -0
  516. package/server/tests/Unit/Http/Filter/InternalRelationUuidLookupTest.php +135 -0
  517. package/server/tests/Unit/Http/Filter/IssueFilterTest.php +129 -0
  518. package/server/tests/Unit/Http/Filter/MaintenanceScheduleFilterTest.php +69 -0
  519. package/server/tests/Unit/Http/Filter/PartFilterTest.php +173 -0
  520. package/server/tests/Unit/Http/Internal/ControllerDelegationSeamsTest.php +136 -0
  521. package/server/tests/Unit/Http/Internal/ControllerExcelSeamsTest.php +89 -0
  522. package/server/tests/Unit/Http/Middleware/SetupDriverSessionTest.php +32 -0
  523. package/server/tests/Unit/Http/Requests/CreateFuelReportRequestTest.php +68 -0
  524. package/server/tests/Unit/Http/Requests/FleetActionRequestTest.php +80 -0
  525. package/server/tests/Unit/Http/Requests/RequestAuthorizationTest.php +50 -0
  526. package/server/tests/Unit/Http/Resources/CustomerResourceTest.php +108 -0
  527. package/server/tests/Unit/Http/Resources/EntityCustomerTypeTest.php +35 -0
  528. package/server/tests/Unit/Http/Resources/FleetResourceTest.php +102 -0
  529. package/server/tests/Unit/Http/Resources/IndexOrderResourceTest.php +210 -0
  530. package/server/tests/Unit/Http/Resources/IndexVehicleResourceTest.php +194 -0
  531. package/server/tests/Unit/Http/Resources/MaintenanceResourcesTest.php +182 -0
  532. package/server/tests/Unit/Http/Resources/OrderAndDriverResourceTest.php +121 -0
  533. package/server/tests/Unit/Http/Resources/OrderConfigResourceTest.php +47 -0
  534. package/server/tests/Unit/Http/Resources/PayloadResourceTest.php +111 -0
  535. package/server/tests/Unit/Http/Resources/RelationResourceFallbacksTest.php +32 -0
  536. package/server/tests/Unit/Http/Resources/ResourceRelationResolutionTest.php +55 -0
  537. package/server/tests/Unit/Http/Resources/TrackingNumberResourceTest.php +174 -0
  538. package/server/tests/Unit/Http/Resources/WaypointResourceTest.php +295 -0
  539. package/server/tests/Unit/Http/Resources/WorkOrderResourceTest.php +164 -0
  540. package/server/tests/Unit/Imports/ImportDelegationTest.php +151 -0
  541. package/server/tests/Unit/Integrations/Lalamove/LalamoveDeliveryStopTest.php +79 -0
  542. package/server/tests/Unit/Integrations/Lalamove/LalamoveLifecycleTest.php +211 -0
  543. package/server/tests/Unit/Integrations/Lalamove/LalamoveQuoteAndServiceOrderTest.php +381 -0
  544. package/server/tests/Unit/Integrations/Lalamove/LalamoveServiceTypeTest.php +51 -0
  545. package/server/tests/Unit/Integrations/LalamoveQuotationTest.php +194 -0
  546. package/server/tests/Unit/Integrations/LalamoveResponseHandlingTest.php +58 -0
  547. package/server/tests/Unit/Jobs/GeofenceDwellAndBulkNotifyTest.php +190 -0
  548. package/server/tests/Unit/Jobs/ReplayPositionsTest.php +57 -0
  549. package/server/tests/Unit/Jobs/SimulateWaypointReachedTest.php +92 -0
  550. package/server/tests/Unit/Listeners/HandleGeofenceEnteredTest.php +256 -0
  551. package/server/tests/Unit/Listeners/HandleOrderDispatchFailedListenerTest.php +101 -0
  552. package/server/tests/Unit/Listeners/HandleOrderDispatchedConcreteTest.php +203 -0
  553. package/server/tests/Unit/Listeners/HandleOrderDispatchedHelpersTest.php +186 -0
  554. package/server/tests/Unit/Listeners/HandleUserRemovedFromCompanyTest.php +65 -0
  555. package/server/tests/Unit/Listeners/ListenerDelegationSeamsTest.php +83 -0
  556. package/server/tests/Unit/Models/AssetTest.php +469 -0
  557. package/server/tests/Unit/Models/ContactCustomerUserTest.php +370 -0
  558. package/server/tests/Unit/Models/ContactTest.php +577 -0
  559. package/server/tests/Unit/Models/DeviceEventTest.php +481 -0
  560. package/server/tests/Unit/Models/DeviceLastPositionDefaultTest.php +128 -0
  561. package/server/tests/Unit/Models/DriverModelHelpersTest.php +268 -0
  562. package/server/tests/Unit/Models/DriverTest.php +401 -0
  563. package/server/tests/Unit/Models/EntityTest.php +171 -0
  564. package/server/tests/Unit/Models/EquipmentTest.php +434 -0
  565. package/server/tests/Unit/Models/FleetTest.php +153 -0
  566. package/server/tests/Unit/Models/FuelProviderTransactionTest.php +82 -0
  567. package/server/tests/Unit/Models/FuelReportImportAndLabelsTest.php +193 -0
  568. package/server/tests/Unit/Models/ImportRowFallbackSeamsTest.php +100 -0
  569. package/server/tests/Unit/Models/IntegratedVendorLifecycleTest.php +203 -0
  570. package/server/tests/Unit/Models/IntegratedVendorTest.php +135 -0
  571. package/server/tests/Unit/Models/IssueTest.php +160 -0
  572. package/server/tests/Unit/Models/MaintenanceScheduleTest.php +319 -0
  573. package/server/tests/Unit/Models/MaintenanceTest.php +277 -0
  574. package/server/tests/Unit/Models/MaintenanceWorkOrderImportTest.php +161 -0
  575. package/server/tests/Unit/Models/ManifestStopTest.php +121 -0
  576. package/server/tests/Unit/Models/ManifestTest.php +163 -0
  577. package/server/tests/Unit/Models/ModelLookupFallbackSeamsTest.php +149 -0
  578. package/server/tests/Unit/Models/OrderConfigTest.php +341 -0
  579. package/server/tests/Unit/Models/OrderDynamicContractsTest.php +190 -0
  580. package/server/tests/Unit/Models/OrderPayloadConfigAndDistanceTest.php +426 -0
  581. package/server/tests/Unit/Models/OrderPayloadRouteTest.php +227 -0
  582. package/server/tests/Unit/Models/OrderPurchaseAndDriversTest.php +188 -0
  583. package/server/tests/Unit/Models/OrderTest.php +917 -0
  584. package/server/tests/Unit/Models/PartTest.php +399 -0
  585. package/server/tests/Unit/Models/PayloadTest.php +710 -0
  586. package/server/tests/Unit/Models/PayloadWaypointsAndEntitiesTest.php +317 -0
  587. package/server/tests/Unit/Models/PlaceCreationAndImportTest.php +384 -0
  588. package/server/tests/Unit/Models/PlaceGeocodingResultsTest.php +253 -0
  589. package/server/tests/Unit/Models/PlaceSharedAndGeocodingTest.php +271 -0
  590. package/server/tests/Unit/Models/PlaceTest.php +589 -0
  591. package/server/tests/Unit/Models/PositionTest.php +49 -0
  592. package/server/tests/Unit/Models/RouteTest.php +55 -0
  593. package/server/tests/Unit/Models/SensorLastPositionDefaultTest.php +130 -0
  594. package/server/tests/Unit/Models/SensorReadingsTest.php +168 -0
  595. package/server/tests/Unit/Models/SensorTest.php +284 -0
  596. package/server/tests/Unit/Models/ServiceAreaGeometryTest.php +129 -0
  597. package/server/tests/Unit/Models/ServiceAreaTest.php +125 -0
  598. package/server/tests/Unit/Models/ServiceQuoteTest.php +617 -0
  599. package/server/tests/Unit/Models/ServiceRateFeeTest.php +73 -0
  600. package/server/tests/Unit/Models/ServiceRatePersistenceAndServicabilityTest.php +428 -0
  601. package/server/tests/Unit/Models/ServiceRateTest.php +533 -0
  602. package/server/tests/Unit/Models/SmallModelSurfacesTest.php +294 -0
  603. package/server/tests/Unit/Models/TrackingNumberTest.php +199 -0
  604. package/server/tests/Unit/Models/TrackingStatusTest.php +131 -0
  605. package/server/tests/Unit/Models/VehicleDeviceTest.php +115 -0
  606. package/server/tests/Unit/Models/VehiclePositionsAndImportTest.php +220 -0
  607. package/server/tests/Unit/Models/VehicleTest.php +266 -0
  608. package/server/tests/Unit/Models/VendorRelationsAndImportTest.php +107 -0
  609. package/server/tests/Unit/Models/WarrantyTest.php +187 -0
  610. package/server/tests/Unit/Models/WaypointTest.php +366 -0
  611. package/server/tests/Unit/Models/WorkOrderTest.php +272 -0
  612. package/server/tests/Unit/Models/ZoneTest.php +83 -0
  613. package/server/tests/Unit/Notifications/MonitoringNotificationsTest.php +136 -0
  614. package/server/tests/Unit/Notifications/OrderAssignedChannelsTest.php +53 -0
  615. package/server/tests/Unit/Notifications/OrderDispatchedChannelsTest.php +81 -0
  616. package/server/tests/Unit/Notifications/OrderFailedChannelsTest.php +73 -0
  617. package/server/tests/Unit/Notifications/OrderPingChannelsTest.php +69 -0
  618. package/server/tests/Unit/Notifications/TerminalOrderNotificationsTest.php +185 -0
  619. package/server/tests/Unit/Observers/FleetOpsCompanyUserAndServiceAreaObserversTest.php +133 -0
  620. package/server/tests/Unit/Observers/ObserverHelperExecutionTest.php +135 -0
  621. package/server/tests/Unit/Observers/ObserverListenerSeamsTest.php +267 -0
  622. package/server/tests/Unit/Observers/PurchaseRateObserverAndOrderJobsTest.php +169 -0
  623. package/server/tests/Unit/Orchestration/Engines/DriverAssignmentEngineTest.php +393 -0
  624. package/server/tests/Unit/Orchestration/Engines/VroomOrchestrationEngineLifecycleTest.php +397 -0
  625. package/server/tests/Unit/Orchestration/OrchestrationEngineRegistryTest.php +45 -0
  626. package/server/tests/Unit/Orchestration/VroomEngineTransportAndSettingsTest.php +253 -0
  627. package/server/tests/Unit/Providers/FleetOpsAiRegistrationTest.php +59 -0
  628. package/server/tests/Unit/Rules/ResolvableVehicleTest.php +85 -0
  629. package/server/tests/Unit/Support/Ai/AssetStatusCapabilityQueriesTest.php +120 -0
  630. package/server/tests/Unit/Support/Ai/Capabilities/CreateOrderPreviewCapabilityTest.php +385 -0
  631. package/server/tests/Unit/Support/Ai/Capabilities/OrderInsightsCapabilityTest.php +226 -0
  632. package/server/tests/Unit/Support/Ai/Capabilities/SearchResourcesCapabilityTest.php +237 -0
  633. package/server/tests/Unit/Support/AiCapabilityPermissionsTest.php +124 -0
  634. package/server/tests/Unit/Support/AlgoEdgeBranchesTest.php +24 -0
  635. package/server/tests/Unit/Support/Analytics/GeofenceViolationsTest.php +109 -0
  636. package/server/tests/Unit/Support/Analytics/LiveFleetTest.php +205 -0
  637. package/server/tests/Unit/Support/Analytics/MaintenanceOverviewTest.php +236 -0
  638. package/server/tests/Unit/Support/Analytics/OnTimeDeliveryAndTopDriversTest.php +250 -0
  639. package/server/tests/Unit/Support/CreateOrderPreviewDraftingTest.php +235 -0
  640. package/server/tests/Unit/Support/CustomerAuthTest.php +132 -0
  641. package/server/tests/Unit/Support/FuelEfficiencyAndCanceledHandlersTest.php +164 -0
  642. package/server/tests/Unit/Support/FuelProviderRegistryResolutionTest.php +51 -0
  643. package/server/tests/Unit/Support/FuelProviderServiceMatchingTest.php +280 -0
  644. package/server/tests/Unit/Support/GeocodingInjectedClientTest.php +268 -0
  645. package/server/tests/Unit/Support/GeocodingLocateTest.php +32 -0
  646. package/server/tests/Unit/Support/GeofenceIntersectionServiceTest.php +188 -0
  647. package/server/tests/Unit/Support/GettingStartedTest.php +164 -0
  648. package/server/tests/Unit/Support/GuardReturnSeamsTest.php +172 -0
  649. package/server/tests/Unit/Support/IntegratedVendorsResolverTest.php +250 -0
  650. package/server/tests/Unit/Support/IssuesInsightsAndAllocationJobTest.php +156 -0
  651. package/server/tests/Unit/Support/MagicAccessorSeamsTest.php +54 -0
  652. package/server/tests/Unit/Support/MaintainableAndOperationalAlertsTest.php +215 -0
  653. package/server/tests/Unit/Support/Metrics/AvgOrderValueMetricTest.php +308 -0
  654. package/server/tests/Unit/Support/Metrics/CountMetricsTest.php +280 -0
  655. package/server/tests/Unit/Support/Metrics/FuelCostsMetricTest.php +102 -0
  656. package/server/tests/Unit/Support/Metrics/MetricQuerySeamsTest.php +129 -0
  657. package/server/tests/Unit/Support/Metrics/OrdersScheduledMetricTest.php +146 -0
  658. package/server/tests/Unit/Support/MoreQuerySeamsTest.php +410 -0
  659. package/server/tests/Unit/Support/OperationalQueryDistributionTest.php +152 -0
  660. package/server/tests/Unit/Support/OperationsPulseTest.php +130 -0
  661. package/server/tests/Unit/Support/OptimizeOrderRouteCapabilityTest.php +147 -0
  662. package/server/tests/Unit/Support/OrchestrationPayloadBuilderTest.php +135 -0
  663. package/server/tests/Unit/Support/OrchestrationRouteAndVehicleTasksTest.php +254 -0
  664. package/server/tests/Unit/Support/OsrmProofAndIssueFilterTest.php +247 -0
  665. package/server/tests/Unit/Support/PetroAppFuelProviderTest.php +165 -0
  666. package/server/tests/Unit/Support/PlaceSearchRankingTest.php +191 -0
  667. package/server/tests/Unit/Support/QuerySeamsTest.php +309 -0
  668. package/server/tests/Unit/Support/ResolvesOrderServiceStopsDbTest.php +303 -0
  669. package/server/tests/Unit/Support/ResolvesOrderServiceStopsTest.php +382 -0
  670. package/server/tests/Unit/Support/SkipAndFallbackGuardsTest.php +70 -0
  671. package/server/tests/Unit/Support/TelematicCredentialResolutionTest.php +31 -0
  672. package/server/tests/Unit/Support/TelematicServiceTest.php +256 -0
  673. package/server/tests/Unit/Support/Telematics/Providers/AbstractProviderTest.php +154 -0
  674. package/server/tests/Unit/Support/Telematics/Providers/AfaqyProviderTest.php +191 -0
  675. package/server/tests/Unit/Support/Telematics/Providers/AfaqyProviderTransportTest.php +138 -0
  676. package/server/tests/Unit/Support/Telematics/Providers/GeotabProviderTest.php +329 -0
  677. package/server/tests/Unit/Support/Telematics/Providers/ProviderTransportSeamsTest.php +133 -0
  678. package/server/tests/Unit/Support/Telematics/Providers/SafeeProviderTest.php +487 -0
  679. package/server/tests/Unit/Support/Telematics/TelematicProviderRegistryTest.php +39 -0
  680. package/server/tests/Unit/Support/Telematics/TelematicServiceLifecycleTest.php +711 -0
  681. package/server/tests/Unit/Support/Telematics/TelematicServiceTelemetryTest.php +364 -0
  682. package/server/tests/Unit/Support/UtilsAdditionalTest.php +256 -0
  683. package/server/tests/Unit/Support/UtilsGeoMatrixAndVendorTest.php +382 -0
  684. package/server/tests/Unit/Tracking/TrackingContextTest.php +114 -0
  685. package/server/tests/Unit/Tracking/TrackingIntelligenceAndContextTest.php +477 -0
  686. package/server/tests/Unit/Tracking/TrackingProviderManagerFallbacksTest.php +208 -0
  687. package/server/tests/Unit/Traits/HasTrackingNumberTest.php +303 -0
  688. package/server/tests/Unit/Traits/PayloadAccessorsTest.php +150 -0
  689. package/server/tests/UtilsContractsTest.php +244 -0
  690. package/server/tests/VehicleControllerHelperContractsTest.php +488 -0
  691. package/server/tests/VehicleDataParsingTest.php +45 -0
  692. package/server/tests/VehicleResourceContractsTest.php +313 -0
  693. package/translations/bg-bg.yaml +2 -0
  694. package/translations/en-us.yaml +2 -0
  695. package/translations/es-pa.yaml +2 -0
  696. package/translations/fr-fr.yaml +2 -0
  697. package/translations/mn-mn.yaml +2 -0
  698. package/translations/pt-br.yaml +2 -0
  699. package/translations/ru-ru.yaml +2 -0
  700. package/server/tests/DeviceFilterTest.php +0 -44
  701. package/server/tests/LiveControllerViewportTest.php +0 -52
@@ -25,11 +25,21 @@ class HandleOrderDispatchFailed implements ShouldQueue
25
25
  $order = $event->getModelRecord();
26
26
 
27
27
  /** @var User */
28
- $createdBy = User::where('uuid', $order->created_by_uuid)->first();
28
+ $createdBy = $this->findUser($order->created_by_uuid);
29
29
 
30
30
  // notify driver assigned order was canceled
31
31
  if ($createdBy) {
32
- $createdBy->notify(new OrderDispatchFailedNotification($order, $event));
32
+ $this->notifyUser($createdBy, $order, $event);
33
33
  }
34
34
  }
35
+
36
+ protected function findUser(?string $uuid): ?User
37
+ {
38
+ return User::where('uuid', $uuid)->first();
39
+ }
40
+
41
+ protected function notifyUser(User $user, $order, OrderDispatchFailed $event): void
42
+ {
43
+ $user->notify(new OrderDispatchFailedNotification($order, $event));
44
+ }
35
45
  }
@@ -36,16 +36,16 @@ class HandleOrderDispatched implements ShouldQueue
36
36
 
37
37
  /* make sure driver is assigned if not trigger failed dispatch */
38
38
  if (!$order->hasDriverAssigned && !$order->adhoc) {
39
- return event(new OrderDispatchFailed($order, 'No driver assigned for order to dispatch to.'));
39
+ return $this->dispatchFailed($order, 'No driver assigned for order to dispatch to.');
40
40
  }
41
41
 
42
42
  /**
43
43
  * Check if dispatch activity already exists, if not -
44
44
  * Check for dispatch code in activity options, if there is the correct dispatch code update activity.
45
45
  **/
46
- $doesntHaveDispatchActivity = TrackingStatus::where(['code' => 'DISPATCHED', 'tracking_number_uuid' => $order->tracking_number_uuid])->doesntExist();
46
+ $doesntHaveDispatchActivity = $this->doesntHaveDispatchActivity($order);
47
47
  if ($doesntHaveDispatchActivity) {
48
- $activity = $order->config()->getDispatchActivity();
48
+ $activity = $this->getDispatchActivity($order);
49
49
  if ($activity) {
50
50
  /** update order activity */
51
51
  $location = $order->getLastLocation();
@@ -69,29 +69,11 @@ class HandleOrderDispatched implements ShouldQueue
69
69
  return;
70
70
  }
71
71
 
72
- $drivers = Driver::where(['status' => 'available', 'online' => 1])
73
- ->whereHas('company', function ($q) {
74
- $q->whereHas('users', function ($q) {
75
- $q->whereHas('driver', function ($q) {
76
- $q->where(['status' => 'available', 'online' => 1]);
77
- $q->whereNull('deleted_at');
78
- });
79
- });
80
- })
81
- ->whereNull('deleted_at')
82
- ->whereNotNull('location')->whereRaw('
83
- ST_Y(location) BETWEEN -90 AND 90
84
- AND ST_X(location) BETWEEN -180 AND 180
85
- AND NOT (ST_X(location) = 0 AND ST_Y(location) = 0)
86
- ')
87
- ->distanceSphere('location', $pickup, $distance)
88
- ->distanceSphereValue('location', $pickup)
89
- ->withoutGlobalScopes()
90
- ->get();
72
+ $drivers = $this->nearbyAvailableDrivers($pickup, $distance);
91
73
 
92
74
  return $drivers->each(function ($driver) use ($order) {
93
75
  try {
94
- $driver->notify(new OrderPing($order, $driver->distance));
76
+ $this->notifyAdhocDriver($driver, $order);
95
77
  } catch (\Exception $exception) {
96
78
  // failed to notify driver for order dispatch for reason uknown -- exit silently
97
79
  }
@@ -99,17 +81,70 @@ class HandleOrderDispatched implements ShouldQueue
99
81
  }
100
82
 
101
83
  /** @var \Fleetbase\Models\Driver */
102
- $driver = Driver::where('uuid', $order->driver_assigned_uuid)->withoutGlobalScopes()->first();
84
+ $driver = $this->findAssignedDriver($order);
103
85
 
104
86
  /* notify driver order has dispatched */
105
87
  if (!$driver) {
106
- return event(new OrderDispatchFailed($order, 'Order was dispatched, but driver was unable to be notified.'));
88
+ return $this->dispatchFailed($order, 'Order was dispatched, but driver was unable to be notified.');
107
89
  }
108
90
 
109
91
  try {
110
- $driver->notify(new OrderDispatchedNotification($order));
92
+ $this->notifyAssignedDriver($driver, $order);
111
93
  } catch (\Exception $exception) {
112
94
  // silently fail notifying driver for now
113
95
  }
114
96
  }
97
+
98
+ protected function dispatchFailed($order, string $reason): mixed
99
+ {
100
+ return event(new OrderDispatchFailed($order, $reason));
101
+ }
102
+
103
+ protected function doesntHaveDispatchActivity($order): bool
104
+ {
105
+ return TrackingStatus::where(['code' => 'DISPATCHED', 'tracking_number_uuid' => $order->tracking_number_uuid])->doesntExist();
106
+ }
107
+
108
+ protected function getDispatchActivity($order): mixed
109
+ {
110
+ return $order->config()?->getDispatchActivity();
111
+ }
112
+
113
+ protected function nearbyAvailableDrivers($pickup, int|float $distance)
114
+ {
115
+ return Driver::where(['status' => 'available', 'online' => 1])
116
+ ->whereHas('company', function ($q) {
117
+ $q->whereHas('users', function ($q) {
118
+ $q->whereHas('driver', function ($q) {
119
+ $q->where(['status' => 'available', 'online' => 1]);
120
+ $q->whereNull('deleted_at');
121
+ });
122
+ });
123
+ })
124
+ ->whereNull('deleted_at')
125
+ ->whereNotNull('location')->whereRaw('
126
+ ST_Y(location) BETWEEN -90 AND 90
127
+ AND ST_X(location) BETWEEN -180 AND 180
128
+ AND NOT (ST_X(location) = 0 AND ST_Y(location) = 0)
129
+ ')
130
+ ->distanceSphere('location', $pickup, $distance)
131
+ ->distanceSphereValue('location', $pickup)
132
+ ->withoutGlobalScopes()
133
+ ->get();
134
+ }
135
+
136
+ protected function notifyAdhocDriver(Driver $driver, $order): void
137
+ {
138
+ $driver->notify(new OrderPing($order, $driver->distance));
139
+ }
140
+
141
+ protected function findAssignedDriver($order): ?Driver
142
+ {
143
+ return Driver::where('uuid', $order->driver_assigned_uuid)->withoutGlobalScopes()->first();
144
+ }
145
+
146
+ protected function notifyAssignedDriver(Driver $driver, $order): void
147
+ {
148
+ $driver->notify(new OrderDispatchedNotification($order));
149
+ }
115
150
  }
@@ -31,12 +31,22 @@ class HandleOrderDriverAssigned implements ShouldQueue
31
31
  }
32
32
 
33
33
  /** @var Driver */
34
- $driver = Driver::where('uuid', $order->driver_assigned_uuid)->withoutGlobalScopes()->first();
34
+ $driver = $this->findAssignedDriver($order);
35
35
  $order->setRelation('driverAssigned', $driver);
36
36
 
37
37
  // notify driver order has been assigned - only if order is not adhoc
38
38
  if ($driver && $order->adhoc === false) {
39
- $driver->notify(new OrderAssigned($order));
39
+ $this->notifyAssignedDriver($driver, $order);
40
40
  }
41
41
  }
42
+
43
+ protected function findAssignedDriver(Order $order): ?Driver
44
+ {
45
+ return Driver::where('uuid', $order->driver_assigned_uuid)->withoutGlobalScopes()->first();
46
+ }
47
+
48
+ protected function notifyAssignedDriver(Driver $driver, Order $order): void
49
+ {
50
+ $driver->notify(new OrderAssigned($order));
51
+ }
42
52
  }
@@ -21,11 +21,24 @@ class HandleUserRemovedFromCompany implements ShouldQueue
21
21
  public function handle(UserRemovedFromCompany $event)
22
22
  {
23
23
  // If user has driver record assosciated to the company, remove it
24
- Driver::where(
25
- [
26
- 'company_uuid' => $event->company->uuid,
27
- 'user_uuid' => $event->user->uuid,
28
- ]
29
- )->delete();
24
+ $this->deleteDriversForCompanyUser($event->company->uuid, $event->user->uuid);
25
+ }
26
+
27
+ protected function deleteDriversForCompanyUser(string $companyUuid, string $userUuid): void
28
+ {
29
+ $this->driverQueryForCompanyUser($companyUuid, $userUuid)->delete();
30
+ }
31
+
32
+ protected function driverQueryForCompanyUser(string $companyUuid, string $userUuid): mixed
33
+ {
34
+ return $this->driverQuery([
35
+ 'company_uuid' => $companyUuid,
36
+ 'user_uuid' => $userUuid,
37
+ ]);
38
+ }
39
+
40
+ protected function driverQuery(array $criteria): mixed
41
+ {
42
+ return Driver::where($criteria);
30
43
  }
31
44
  }
@@ -36,7 +36,7 @@ class NotifyDriverOnShiftChange implements ShouldQueue
36
36
 
37
37
  // Load the parent schedule to find the subject (driver)
38
38
  /** @var Schedule|null $schedule */
39
- $schedule = $scheduleItem->schedule()->with('subject')->first();
39
+ $schedule = $this->getSchedule($scheduleItem);
40
40
  if (!$schedule) {
41
41
  return;
42
42
  }
@@ -48,16 +48,36 @@ class NotifyDriverOnShiftChange implements ShouldQueue
48
48
  }
49
49
 
50
50
  // Check the company-level scheduling setting
51
- $settings = Setting::lookupFromCompany('fleet-ops.scheduling-settings', []);
51
+ $settings = $this->getSchedulingSettings();
52
52
  $shouldNotify = (bool) data_get($settings, 'notify_drivers_on_shift_change', false);
53
53
  if (!$shouldNotify) {
54
54
  return;
55
55
  }
56
56
 
57
57
  // Determine if this is a new shift or an update
58
- $isNew = $event instanceof \Fleetbase\Events\ScheduleItemCreated;
58
+ $isNew = $this->isCreatedEvent($event);
59
59
 
60
60
  // Send the notification to the driver
61
- $subject->notify(new DriverShiftChanged($scheduleItem, $isNew));
61
+ $this->notifyDriver($subject, new DriverShiftChanged($scheduleItem, $isNew));
62
+ }
63
+
64
+ protected function getSchedule(ScheduleItem $scheduleItem): ?Schedule
65
+ {
66
+ return $scheduleItem->schedule()->with('subject')->first();
67
+ }
68
+
69
+ protected function getSchedulingSettings(): array
70
+ {
71
+ return Setting::lookupFromCompany('fleet-ops.scheduling-settings', []);
72
+ }
73
+
74
+ protected function isCreatedEvent(object $event): bool
75
+ {
76
+ return $event instanceof \Fleetbase\Events\ScheduleItemCreated;
77
+ }
78
+
79
+ protected function notifyDriver(Driver $driver, DriverShiftChanged $notification): void
80
+ {
81
+ $driver->notify($notification);
62
82
  }
63
83
  }
@@ -32,29 +32,34 @@ class NotifyOrderEvent implements ShouldQueue
32
32
  // Send a notification for order events
33
33
  if ($event instanceof \Fleetbase\FleetOps\Events\OrderCanceled) {
34
34
  $reason = $event->activity ? $event->activity->get('details') : '';
35
- NotificationRegistry::notify(OrderCanceled::class, $order, $reason, $event->waypoint);
35
+ $this->notify(OrderCanceled::class, $order, $reason, $event->waypoint);
36
36
  }
37
37
 
38
38
  if ($event instanceof \Fleetbase\FleetOps\Events\OrderCompleted) {
39
- NotificationRegistry::notify(OrderCompleted::class, $order, $event->waypoint);
39
+ $this->notify(OrderCompleted::class, $order, $event->waypoint);
40
40
  }
41
41
 
42
42
  if ($event instanceof \Fleetbase\FleetOps\Events\OrderFailed) {
43
43
  $reason = $event->activity ? $event->activity->get('details') : '';
44
- NotificationRegistry::notify(OrderFailed::class, $order, $reason, $event->waypoint);
44
+ $this->notify(OrderFailed::class, $order, $reason, $event->waypoint);
45
45
  }
46
46
 
47
47
  if ($event instanceof \Fleetbase\FleetOps\Events\OrderDispatchFailed) {
48
- NotificationRegistry::notify(OrderDispatchFailed::class, $order);
48
+ $this->notify(OrderDispatchFailed::class, $order);
49
49
  }
50
50
 
51
51
  if ($event instanceof \Fleetbase\FleetOps\Events\OrderDispatched) {
52
- NotificationRegistry::notify(OrderDispatched::class, $order, $event->waypoint);
52
+ $this->notify(OrderDispatched::class, $order, $event->waypoint);
53
53
  }
54
54
 
55
55
  if ($event instanceof \Fleetbase\FleetOps\Events\OrderDriverAssigned) {
56
- NotificationRegistry::notify(OrderAssigned::class, $order);
56
+ $this->notify(OrderAssigned::class, $order);
57
57
  }
58
58
  }
59
59
  }
60
+
61
+ protected function notify(string $notificationClass, mixed ...$arguments): void
62
+ {
63
+ NotificationRegistry::notify($notificationClass, ...$arguments);
64
+ }
60
65
  }
@@ -348,14 +348,13 @@ class Contact extends Model
348
348
  $existingUserContact = Contact::where(['user_uuid' => $existingUser->uuid, 'company_uuid' => $contact->company_uuid])->whereHas('user')->first();
349
349
  if ($existingUserContact) {
350
350
  throw new UserAlreadyExistsException('User already exists, try to assigning the user to this contact.', $existingUser);
351
- } else {
352
- // Assign the user to this contact instead
353
- $contact->setAttribute('user_uuid', $existingUser->uuid);
354
- if ($update) {
355
- $contact->update(['user_uuid' => $existingUser->uuid]);
356
- }
357
- $contact->setRelation('user', $existingUser);
358
351
  }
352
+ // Assign the user to this contact instead
353
+ $contact->setAttribute('user_uuid', $existingUser->uuid);
354
+ if ($update) {
355
+ $contact->update(['user_uuid' => $existingUser->uuid]);
356
+ }
357
+ $contact->setRelation('user', $existingUser);
359
358
 
360
359
  return $existingUser;
361
360
  }
@@ -175,6 +175,24 @@ class Device extends Model
175
175
  'attachable_type' => PolymorphicType::class,
176
176
  ];
177
177
 
178
+ /**
179
+ * Bootstrap the model.
180
+ *
181
+ * Devices require a non-null spatial `last_position` (the column is NOT NULL
182
+ * to support its spatial index), so default it to POINT(0,0) on create when
183
+ * the caller hasn't provided a position.
184
+ */
185
+ protected static function boot()
186
+ {
187
+ parent::boot();
188
+
189
+ static::creating(function (self $device) {
190
+ if (empty($device->last_position)) {
191
+ $device->last_position = new SpatialPoint(0, 0);
192
+ }
193
+ });
194
+ }
195
+
178
196
  /**
179
197
  * Properties which activity needs to be logged.
180
198
  *
@@ -345,9 +363,9 @@ class Device extends Model
345
363
  return 'recently_offline';
346
364
  } elseif ($minutesOffline <= 1440) { // 24 hours
347
365
  return 'offline';
348
- } else {
349
- return 'long_offline';
350
366
  }
367
+
368
+ return 'long_offline';
351
369
  }
352
370
 
353
371
  /**
@@ -510,12 +528,17 @@ class Device extends Model
510
528
  */
511
529
  public function getRecentEvents(int $limit = 10)
512
530
  {
513
- return $this->events()
531
+ return $this->recentEventsQuery()
514
532
  ->orderBy('created_at', 'desc')
515
533
  ->limit($limit)
516
534
  ->get();
517
535
  }
518
536
 
537
+ protected function recentEventsQuery()
538
+ {
539
+ return $this->events();
540
+ }
541
+
519
542
  /**
520
543
  * Creates a new position for the vehicle.
521
544
  */
@@ -41,7 +41,6 @@ use Spatie\Activitylog\Traits\CausesActivity;
41
41
  use Spatie\Activitylog\Traits\LogsActivity;
42
42
  use Spatie\Sluggable\HasSlug;
43
43
  use Spatie\Sluggable\SlugOptions;
44
- use WebSocket\Message\Ping;
45
44
 
46
45
  class Driver extends Model
47
46
  {
@@ -329,11 +328,6 @@ class Driver extends Model
329
328
  return $this->hasMany(Order::class, 'driver_assigned_uuid')->without(['driver']);
330
329
  }
331
330
 
332
- public function pings(): HasMany
333
- {
334
- return $this->hasMany(Ping::class);
335
- }
336
-
337
331
  public function positions(): HasMany
338
332
  {
339
333
  return $this->hasMany(Position::class, 'subject_uuid');
@@ -414,10 +414,10 @@ class Entity extends Model
414
414
  }
415
415
  }
416
416
 
417
- // confirm destination_uuid is indeed a place record
418
- if (isset($attributes['destination_uuid']) && Place::where('uuid', $attributes['destination_uuid'])->doesntExist()) {
419
- // search waypoints for search_uuid if any
420
- $destination = Place::where('meta->search_uuid', $attributes['destination_uuid'])->first();
417
+ // confirm the resolved destination is indeed a place record — temp
418
+ // search uuids from imports resolve through place metadata
419
+ if ($this->destination_uuid === null && Str::isUuid($destinationKey)) {
420
+ $destination = Place::where('meta->search_uuid', $destinationKey)->first();
421
421
 
422
422
  if ($destination instanceof Place) {
423
423
  $this->destination_uuid = $destination->uuid;
@@ -243,7 +243,7 @@ class Equipment extends Model
243
243
  $this->attributes['equipable_type'] = match ($type) {
244
244
  'fleet-ops:vehicle', 'vehicle' => Utils::getMutationType('fleet-ops:vehicle'),
245
245
  'fleet-ops:driver', 'driver' => Utils::getMutationType('fleet-ops:driver'),
246
- default => $type,
246
+ default => $type,
247
247
  };
248
248
  }
249
249
 
@@ -6,6 +6,7 @@ use Fleetbase\Casts\Json;
6
6
  use Fleetbase\FleetOps\Casts\Point;
7
7
  use Fleetbase\FleetOps\Support\Utils;
8
8
  use Fleetbase\LaravelMysqlSpatial\Eloquent\SpatialTrait;
9
+ use Fleetbase\LaravelMysqlSpatial\Types\Point as SpatialPoint;
9
10
  use Fleetbase\Models\Model;
10
11
  use Fleetbase\Models\User;
11
12
  use Fleetbase\Traits\HasApiModelBehavior;
@@ -149,6 +150,26 @@ class FuelReport extends Model
149
150
  return $this->belongsTo(User::class, 'reported_by_uuid');
150
151
  }
151
152
 
153
+ /**
154
+ * Bootstrap the model.
155
+ *
156
+ * `location` is declared nullable in CreateFuelReportRequest but the column is
157
+ * POINT NOT NULL, so a report created without one failed outright with
158
+ * SQLSTATE[HY000] 1364 "Field 'location' doesn't have a default value" — a 500 for
159
+ * a request the validator had just accepted. Mirrors Device and Sensor, which
160
+ * default their spatial columns the same way.
161
+ */
162
+ protected static function boot()
163
+ {
164
+ parent::boot();
165
+
166
+ static::creating(function (self $fuelReport) {
167
+ if (empty($fuelReport->location)) {
168
+ $fuelReport->location = new SpatialPoint(0, 0);
169
+ }
170
+ });
171
+ }
172
+
152
173
  /**
153
174
  * Get the driver's name assigned to vehicle.
154
175
  *
@@ -213,10 +234,14 @@ class FuelReport extends Model
213
234
  $latitude = Utils::or($row, ['latitude', 'lat']);
214
235
  $longitude = Utils::or($row, ['longitude', 'lng', 'long']);
215
236
 
237
+ $locationValue = data_get($row, 'location');
216
238
  if ($latitude && $longitude) {
217
239
  $location = new Point($latitude, $longitude);
240
+ } elseif (filled($locationValue)) {
241
+ $location = Utils::getPointFromMixed(Utils::arrayFrom($locationValue));
218
242
  } else {
219
- $location = Utils::getPointFromMixed(Utils::arrayFrom(data_get($row, 'location')));
243
+ // Rows without any location column fall back to the empty point below
244
+ $location = null;
220
245
  }
221
246
 
222
247
  // Resolve relations
@@ -117,7 +117,7 @@ class IntegratedVendor extends Model
117
117
  function ($model) {
118
118
  $provider = $model->provider();
119
119
 
120
- if ($provider && method_exists($provider, 'onUpdated')) {
120
+ if ($provider && method_exists($provider, 'callback')) {
121
121
  $provider->callback('onUpdated');
122
122
  }
123
123
  }
@@ -127,7 +127,7 @@ class IntegratedVendor extends Model
127
127
  function ($model) {
128
128
  $provider = $model->provider();
129
129
 
130
- if ($provider && method_exists($provider, 'onDeleted')) {
130
+ if ($provider && method_exists($provider, 'callback')) {
131
131
  $provider->callback('onDeleted');
132
132
  }
133
133
  }
@@ -331,10 +331,14 @@ class Issue extends Model
331
331
  $latitude = Utils::or($row, ['latitude', 'lat']);
332
332
  $longitude = Utils::or($row, ['longitude', 'lng', 'long']);
333
333
 
334
+ $locationValue = data_get($row, 'location');
334
335
  if ($latitude && $longitude) {
335
336
  $location = new Point($latitude, $longitude);
337
+ } elseif (filled($locationValue)) {
338
+ $location = Utils::getPointFromMixed(Utils::arrayFrom($locationValue));
336
339
  } else {
337
- $location = Utils::getPointFromMixed(Utils::arrayFrom(data_get($row, 'location')));
340
+ // Rows without any location column fall back to the empty point below
341
+ $location = null;
338
342
  }
339
343
 
340
344
  // Create issue
@@ -315,17 +315,12 @@ class MaintenanceSchedule extends Model
315
315
 
316
316
  // Attempt to resolve the subject (vehicle or equipment) by identifier
317
317
  if ($vehicleName) {
318
- $vehicle = Vehicle::findByName($vehicleName);
318
+ $vehicle = static::findImportVehicle($vehicleName);
319
319
  if ($vehicle) {
320
320
  $schedule->subject_type = Vehicle::class;
321
321
  $schedule->subject_uuid = $vehicle->uuid;
322
322
  } else {
323
- $equipment = Equipment::where('company_uuid', session('company'))
324
- ->where(function ($q) use ($vehicleName) {
325
- $q->where('name', 'like', '%' . $vehicleName . '%')
326
- ->orWhere('public_id', $vehicleName)
327
- ->orWhere('serial_number', $vehicleName);
328
- })->first();
323
+ $equipment = static::findImportEquipment($vehicleName);
329
324
  if ($equipment) {
330
325
  $schedule->subject_type = Equipment::class;
331
326
  $schedule->subject_uuid = $equipment->uuid;
@@ -335,9 +330,7 @@ class MaintenanceSchedule extends Model
335
330
 
336
331
  // Attempt to resolve default assignee (vendor) by name
337
332
  if ($vendorName) {
338
- $vendor = Vendor::where('company_uuid', session('company'))
339
- ->where('name', 'like', '%' . $vendorName . '%')
340
- ->first();
333
+ $vendor = static::findImportVendor($vendorName);
341
334
  if ($vendor) {
342
335
  $schedule->default_assignee_type = Vendor::class;
343
336
  $schedule->default_assignee_uuid = $vendor->uuid;
@@ -350,4 +343,26 @@ class MaintenanceSchedule extends Model
350
343
 
351
344
  return $schedule;
352
345
  }
346
+
347
+ protected static function findImportVehicle(string $vehicleName): ?Vehicle
348
+ {
349
+ return Vehicle::findByName($vehicleName);
350
+ }
351
+
352
+ protected static function findImportEquipment(string $vehicleName): ?Equipment
353
+ {
354
+ return Equipment::where('company_uuid', session('company'))
355
+ ->where(function ($q) use ($vehicleName) {
356
+ $q->where('name', 'like', '%' . $vehicleName . '%')
357
+ ->orWhere('public_id', $vehicleName)
358
+ ->orWhere('serial_number', $vehicleName);
359
+ })->first();
360
+ }
361
+
362
+ protected static function findImportVendor(string $vendorName): ?Vendor
363
+ {
364
+ return Vendor::where('company_uuid', session('company'))
365
+ ->where('name', 'like', '%' . $vendorName . '%')
366
+ ->first();
367
+ }
353
368
  }
@@ -932,9 +932,15 @@ class Order extends Model
932
932
 
933
933
  $result = Payload::insert($attributes);
934
934
 
935
+ // Unreachable: Laravel's connector forces PDO::ERRMODE_EXCEPTION and
936
+ // nothing here overrides it, so the insert either succeeds or throws —
937
+ // it never returns false. The fallback itself is sound (insertPayload
938
+ // regenerates the uuid and public id before delegating), just unreached.
939
+ // @codeCoverageIgnoreStart
935
940
  if (!$result) {
936
941
  return $this->createPayload($attributes);
937
942
  }
943
+ // @codeCoverageIgnoreEnd
938
944
 
939
945
  $payload = Payload::find($uuid);
940
946
 
@@ -1003,14 +1009,14 @@ class Order extends Model
1003
1009
  *
1004
1010
  * @return self the Order instance for method chaining
1005
1011
  */
1006
- public function setRoute(?array $attributes = [])
1012
+ public function setRoute(Route|array|null $attributes = [])
1007
1013
  {
1008
1014
  if (!$attributes) {
1009
1015
  return $this;
1010
1016
  }
1011
1017
 
1012
1018
  if ($attributes instanceof Route) {
1013
- $attributes->set('order_uuid', $this->order_uuid);
1019
+ $attributes->setAttribute('order_uuid', $this->uuid);
1014
1020
  $attributes->save();
1015
1021
 
1016
1022
  return $this;
@@ -1243,7 +1249,7 @@ class Order extends Model
1243
1249
  $min = Carbon::now()->subMinutes($precision);
1244
1250
  $max = Carbon::now()->addMinutes($precision);
1245
1251
 
1246
- return !$this->dispatched && Carbon::fromString($this->scheduled_at)->between($min, $max);
1252
+ return !$this->dispatched && Carbon::parse($this->scheduled_at)->between($min, $max);
1247
1253
  }
1248
1254
 
1249
1255
  /**
@@ -1734,10 +1740,16 @@ class Order extends Model
1734
1740
  }
1735
1741
 
1736
1742
  // Fetch distance/time — bail early if external call fails
1743
+ //
1744
+ // Unreachable: `getDrivingDistanceAndTime()` is typed `: DistanceMatrix`
1745
+ // and every provider path casts both fields to float before constructing
1746
+ // it, so neither the null check nor the isset check can fail.
1737
1747
  $matrix = Utils::getDrivingDistanceAndTime($origin, $destination, $options);
1748
+ // @codeCoverageIgnoreStart
1738
1749
  if (!$matrix || !isset($matrix->distance, $matrix->time)) {
1739
1750
  return $this;
1740
1751
  }
1752
+ // @codeCoverageIgnoreEnd
1741
1753
 
1742
1754
  // Only update if values changed to prevent redundant writes
1743
1755
  if ($this->distance !== $matrix->distance || $this->time !== $matrix->time) {
@@ -1777,9 +1789,9 @@ class Order extends Model
1777
1789
  * This function first attempts to load the 'orderConfig' relationship.
1778
1790
  * If 'orderConfig' is already loaded and is an instance of OrderConfig,
1779
1791
  * it returns this instance. If not, and if the 'order_config_uuid' is
1780
- * a valid UUID, it attempts to retrieve the OrderConfig by this UUID,
1781
- * including any trashed instances. If none of these conditions are met,
1782
- * it returns null.
1792
+ * The orderConfig relation already includes trashed instances, so a
1793
+ * soft-deleted config still resolves. Otherwise the company's default
1794
+ * transport config is used, and null is returned when none can be made.
1783
1795
  *
1784
1796
  * @return OrderConfig|null the OrderConfig associated with this order, or null if not found
1785
1797
  *
@@ -1795,15 +1807,6 @@ class Order extends Model
1795
1807
  return $this->orderConfig;
1796
1808
  }
1797
1809
 
1798
- if (Str::isUuid($this->order_config_uuid)) {
1799
- $orderConfig = OrderConfig::where('uuid', $this->order_config_uuid)->withTrashed()->first();
1800
- if ($orderConfig instanceof OrderConfig) {
1801
- $orderConfig->setOrderContext($this);
1802
-
1803
- return $orderConfig;
1804
- }
1805
- }
1806
-
1807
1810
  $company = $this->relationLoaded('company') ? $this->company : $this->company()->first();
1808
1811
  $orderConfig = OrderConfig::defaultOrCreate($company);
1809
1812
  if ($orderConfig instanceof OrderConfig) {