@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
@@ -30,9 +30,9 @@ class DeviceController extends Controller
30
30
  $input = $this->input($request);
31
31
  $input['company_uuid'] = session('company');
32
32
 
33
- $device = Device::create($input)->load(['telematic', 'warranty', 'attachable', 'photo'])->loadCount('sensors');
33
+ $device = $this->loadDeviceRelations($this->createDevice($input));
34
34
 
35
- return new DeviceResource($device);
35
+ return $this->deviceResource($device);
36
36
  }
37
37
 
38
38
  public function update(string $id, UpdateDeviceRequest $request)
@@ -45,32 +45,31 @@ class DeviceController extends Controller
45
45
  return response()->json(['error' => 'Device resource not found.'], 404);
46
46
  }
47
47
 
48
- $device->update($this->input($request));
48
+ $this->updateDevice($device, $this->input($request));
49
49
 
50
- return new DeviceResource($device->refresh()->load(['telematic', 'warranty', 'attachable', 'photo'])->loadCount('sensors'));
50
+ return $this->deviceResource($this->loadDeviceRelations($device->refresh()));
51
51
  }
52
52
 
53
53
  public function query(Request $request)
54
54
  {
55
55
  $this->rejectUuidIdentifiers($request);
56
56
 
57
- $results = Device::queryWithRequest($request, function (&$query) {
57
+ $results = $this->queryDevicesWithRequest($request, function (&$query) {
58
58
  $query->with(['telematic', 'warranty', 'attachable', 'photo'])->withCount('sensors');
59
59
  });
60
60
 
61
- return DeviceResource::collection($results);
61
+ return $this->deviceResourceCollection($results);
62
62
  }
63
63
 
64
64
  public function find(string $id)
65
65
  {
66
66
  try {
67
- $device = $this->resolveModel(Device::class, $id)->load(['telematic', 'warranty', 'attachable', 'photo']);
68
- $device->loadCount('sensors');
67
+ $device = $this->loadDeviceRelations($this->resolveModel(Device::class, $id));
69
68
  } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $exception) {
70
69
  return response()->json(['error' => 'Device resource not found.'], 404);
71
70
  }
72
71
 
73
- return new DeviceResource($device);
72
+ return $this->deviceResource($device);
74
73
  }
75
74
 
76
75
  public function delete(string $id)
@@ -83,7 +82,7 @@ class DeviceController extends Controller
83
82
 
84
83
  $device->delete();
85
84
 
86
- return new DeletedResource($device);
85
+ return $this->deletedDeviceResource($device);
87
86
  }
88
87
 
89
88
  public function attach(Request $request, string $id): JsonResponse
@@ -108,7 +107,7 @@ class DeviceController extends Controller
108
107
 
109
108
  try {
110
109
  $device->attachTo($vehicle);
111
- $device->load(['telematic', 'warranty', 'attachable', 'photo'])->loadCount('sensors');
110
+ $this->loadDeviceRelations($device);
112
111
  } catch (\Throwable $e) {
113
112
  $this->logDeviceAttachmentFailure('attach', $device, $vehicle, $e);
114
113
 
@@ -117,7 +116,7 @@ class DeviceController extends Controller
117
116
 
118
117
  return response()->json([
119
118
  'status' => 'ok',
120
- 'device' => new DeviceResource($device),
119
+ 'device' => $this->deviceResource($device),
121
120
  ]);
122
121
  }
123
122
 
@@ -133,7 +132,7 @@ class DeviceController extends Controller
133
132
 
134
133
  try {
135
134
  $device->detach();
136
- $device->load(['telematic', 'warranty', 'attachable', 'photo'])->loadCount('sensors');
135
+ $this->loadDeviceRelations($device);
137
136
  } catch (\Throwable $e) {
138
137
  $this->logDeviceAttachmentFailure('detach', $device, null, $e);
139
138
 
@@ -142,10 +141,45 @@ class DeviceController extends Controller
142
141
 
143
142
  return response()->json([
144
143
  'status' => 'ok',
145
- 'device' => new DeviceResource($device),
144
+ 'device' => $this->deviceResource($device),
146
145
  ]);
147
146
  }
148
147
 
148
+ protected function createDevice(array $input): Device
149
+ {
150
+ return Device::create($input);
151
+ }
152
+
153
+ protected function updateDevice(Device $device, array $input): bool
154
+ {
155
+ return $device->update($input);
156
+ }
157
+
158
+ protected function queryDevicesWithRequest(Request $request, callable $callback): mixed
159
+ {
160
+ return Device::queryWithRequest($request, $callback);
161
+ }
162
+
163
+ protected function loadDeviceRelations(Device $device): Device
164
+ {
165
+ return $device->load(['telematic', 'warranty', 'attachable', 'photo'])->loadCount('sensors');
166
+ }
167
+
168
+ protected function deviceResource(Device $device): mixed
169
+ {
170
+ return new DeviceResource($device);
171
+ }
172
+
173
+ protected function deviceResourceCollection(mixed $results): mixed
174
+ {
175
+ return DeviceResource::collection($results);
176
+ }
177
+
178
+ protected function deletedDeviceResource(Device $device): mixed
179
+ {
180
+ return new DeletedResource($device);
181
+ }
182
+
149
183
  protected function input(Request $request): array
150
184
  {
151
185
  $input = $request->only([
@@ -39,6 +39,8 @@ use Illuminate\Support\Str;
39
39
 
40
40
  class DriverController extends Controller
41
41
  {
42
+ use \Fleetbase\FleetOps\Http\Controllers\Concerns\ResolvesReviewAccountBypass;
43
+
42
44
  /**
43
45
  * Creates a new Fleetbase Driver resource.
44
46
  *
@@ -56,30 +58,24 @@ class DriverController extends Controller
56
58
  $userDetails = $request->only(['name', 'password', 'email', 'phone', 'timezone']);
57
59
 
58
60
  // Get current company session
59
- $company = $request->has('company') ? Auth::getCompanyFromRequest($request) : Auth::getCompany();
61
+ $company = $request->has('company') ? $this->companyFromRequest($request) : $this->currentCompany();
60
62
 
61
63
  // Debugging: Ensure company is retrieved correctly
62
64
  if (!$company) {
63
- return response()->apiError('Company not found.');
65
+ return $this->apiError('Company not found.');
64
66
  }
65
67
 
66
68
  // Apply user infos
67
- $userDetails = User::applyUserInfoFromRequest($request, $userDetails);
69
+ $userDetails = $this->applyUserInfoFromRequest($request, $userDetails);
68
70
 
69
71
  // Set company_uuid before creating user
70
72
  $userDetails['company_uuid'] = $company->uuid;
71
73
 
72
74
  // create user account for driver
73
- $user = User::create($userDetails);
74
-
75
- // Assign company
76
- if ($company) {
77
- $user->assignCompany($company);
78
- } else {
79
- $user->deleteQuietly();
75
+ $user = $this->createUser($userDetails);
80
76
 
81
- return response()->apiError('Unable to assign driver to company.');
82
- }
77
+ // Assign company — the early return above guarantees $company is set
78
+ $user->assignCompany($company);
83
79
 
84
80
  // Set user type
85
81
  $user->setUserType('driver');
@@ -93,7 +89,7 @@ class DriverController extends Controller
93
89
 
94
90
  // vehicle assignment public_id -> uuid
95
91
  if ($request->has('vehicle')) {
96
- $input['vehicle_uuid'] = Utils::getUuid('vehicles', [
92
+ $input['vehicle_uuid'] = $this->getUuid('vehicles', [
97
93
  'public_id' => $request->input('vehicle'),
98
94
  'company_uuid' => $company->uuid, // Use $company->uuid instead of session
99
95
  ]);
@@ -101,7 +97,7 @@ class DriverController extends Controller
101
97
 
102
98
  // vendor assignment public_id -> uuid
103
99
  if ($request->has('vendor')) {
104
- $input['vendor_uuid'] = Utils::getUuid('vendors', [
100
+ $input['vendor_uuid'] = $this->getUuid('vendors', [
105
101
  'public_id' => $request->input('vendor'),
106
102
  'company_uuid' => $company->uuid, // Use $company->uuid instead of session
107
103
  ]);
@@ -109,7 +105,7 @@ class DriverController extends Controller
109
105
 
110
106
  // order|alias:job assignment public_id -> uuid
111
107
  if ($request->has('job')) {
112
- $input['current_job_uuid'] = Utils::getUuid('orders', [
108
+ $input['current_job_uuid'] = $this->getUuid('orders', [
113
109
  'public_id' => $request->input('job'),
114
110
  'company_uuid' => $company->uuid, // Use $company->uuid instead of session
115
111
  ]);
@@ -122,16 +118,16 @@ class DriverController extends Controller
122
118
 
123
119
  // latitude / longitude
124
120
  if ($request->has(['latitude', 'longitude'])) {
125
- $input['location'] = Utils::getPointFromCoordinates($request->only(['latitude', 'longitude']));
121
+ $input['location'] = $this->pointFromCoordinates($request->only(['latitude', 'longitude']));
126
122
  }
127
123
 
128
124
  // create the driver
129
- $driver = Driver::create($input);
125
+ $driver = $this->createDriver($input);
130
126
 
131
127
  // Handle photo upload using FileResolverService
132
128
  if ($request->has('photo')) {
133
129
  $path = 'uploads/' . $company->uuid . '/drivers';
134
- $file = app(\Fleetbase\Services\FileResolverService::class)->resolve($request->input('photo'), $path);
130
+ $file = $this->resolveFile($request->input('photo'), $path);
135
131
 
136
132
  if ($file) {
137
133
  $user->update(['photo_uuid' => $file->uuid]);
@@ -142,7 +138,7 @@ class DriverController extends Controller
142
138
  $driver = $driver->load(['user', 'vehicle', 'vendor', 'currentJob']);
143
139
 
144
140
  // response the driver resource
145
- return new DriverResource($driver);
141
+ return $this->driverResource($driver);
146
142
  }
147
143
 
148
144
  /**
@@ -157,9 +153,9 @@ class DriverController extends Controller
157
153
  {
158
154
  // find for the driver
159
155
  try {
160
- $driver = Driver::findRecordOrFail($id, ['user']);
156
+ $driver = $this->findDriver($id, ['user']);
161
157
  } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $exception) {
162
- return response()->json(
158
+ return $this->jsonResponse(
163
159
  [
164
160
  'error' => 'Driver resource not found.',
165
161
  ],
@@ -181,31 +177,31 @@ class DriverController extends Controller
181
177
 
182
178
  // vehicle assignment public_id -> uuid
183
179
  if ($request->has('vehicle')) {
184
- $input['vehicle_uuid'] = Utils::getUuid('vehicles', [
180
+ $input['vehicle_uuid'] = $this->getUuid('vehicles', [
185
181
  'public_id' => $request->input('vehicle'),
186
- 'company_uuid' => session('company'),
182
+ 'company_uuid' => $this->sessionCompany(),
187
183
  ]);
188
184
  }
189
185
 
190
186
  // vendor assignment public_id -> uuid
191
187
  if ($request->has('vendor')) {
192
- $input['vendor_uuid'] = Utils::getUuid('vendors', [
188
+ $input['vendor_uuid'] = $this->getUuid('vendors', [
193
189
  'public_id' => $request->input('vendor'),
194
- 'company_uuid' => session('company'),
190
+ 'company_uuid' => $this->sessionCompany(),
195
191
  ]);
196
192
  }
197
193
 
198
194
  // order|alias:job assignment public_id -> uuid
199
195
  if ($request->has('job')) {
200
- $input['current_job_uuid'] = Utils::getUuid('orders', [
196
+ $input['current_job_uuid'] = $this->getUuid('orders', [
201
197
  'public_id' => $request->input('job'),
202
- 'company_uuid' => session('company'),
198
+ 'company_uuid' => $this->sessionCompany(),
203
199
  ]);
204
200
  }
205
201
 
206
202
  // latitude / longitude
207
203
  if ($request->has(['latitude', 'longitude'])) {
208
- $input['location'] = Utils::getPointFromCoordinates($request->only(['latitude', 'longitude']));
204
+ $input['location'] = $this->pointFromCoordinates($request->only(['latitude', 'longitude']));
209
205
  }
210
206
 
211
207
  // create the driver
@@ -214,8 +210,8 @@ class DriverController extends Controller
214
210
 
215
211
  // Handle photo upload using FileResolverService
216
212
  if ($request->has('photo')) {
217
- $path = 'uploads/' . session('company') . '/drivers';
218
- $file = app(\Fleetbase\Services\FileResolverService::class)->resolve($request->input('photo'), $path);
213
+ $path = 'uploads/' . $this->sessionCompany() . '/drivers';
214
+ $file = $this->resolveFile($request->input('photo'), $path);
219
215
 
220
216
  if ($file) {
221
217
  $driver->user->update(['photo_uuid' => $file->uuid]);
@@ -226,7 +222,7 @@ class DriverController extends Controller
226
222
  $driver = $driver->load(['user', 'vehicle', 'vendor', 'currentJob']);
227
223
 
228
224
  // response the driver resource
229
- return new DriverResource($driver);
225
+ return $this->driverResource($driver);
230
226
  }
231
227
 
232
228
  /**
@@ -236,18 +232,9 @@ class DriverController extends Controller
236
232
  */
237
233
  public function query(Request $request)
238
234
  {
239
- $results = Driver::queryWithRequest(
240
- $request,
241
- function (&$query, $request) {
242
- if ($request->has('vendor')) {
243
- $query->whereHas('vendor', function ($q) use ($request) {
244
- $q->where('public_id', $request->input('vendor'));
245
- });
246
- }
247
- }
248
- );
235
+ $results = $this->queryDrivers($request);
249
236
 
250
- return DriverResource::collection($results);
237
+ return $this->driverResourceCollection($results);
251
238
  }
252
239
 
253
240
  /**
@@ -261,9 +248,9 @@ class DriverController extends Controller
261
248
  {
262
249
  // find for the driver
263
250
  try {
264
- $driver = Driver::findRecordOrFail($id, ['user', 'vehicle', 'vendor', 'currentJob']);
251
+ $driver = $this->findDriver($id, ['user', 'vehicle', 'vendor', 'currentJob']);
265
252
  } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $exception) {
266
- return response()->json(
253
+ return $this->jsonResponse(
267
254
  [
268
255
  'error' => 'Driver resource not found.',
269
256
  ],
@@ -272,7 +259,7 @@ class DriverController extends Controller
272
259
  }
273
260
 
274
261
  // response the driver resource
275
- return new DriverResource($driver);
262
+ return $this->driverResource($driver);
276
263
  }
277
264
 
278
265
  /**
@@ -286,9 +273,9 @@ class DriverController extends Controller
286
273
  {
287
274
  // find for the driver
288
275
  try {
289
- $driver = Driver::findRecordOrFail($id, ['user', 'vehicle', 'vendor', 'currentJob']);
276
+ $driver = $this->findDriver($id, ['user', 'vehicle', 'vendor', 'currentJob']);
290
277
  } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $exception) {
291
- return response()->json(
278
+ return $this->jsonResponse(
292
279
  [
293
280
  'error' => 'Driver resource not found.',
294
281
  ],
@@ -300,7 +287,7 @@ class DriverController extends Controller
300
287
  $driver->delete();
301
288
 
302
289
  // response the driver resource
303
- return new DeletedResource($driver);
290
+ return $this->deletedDriverResource($driver);
304
291
  }
305
292
 
306
293
  /**
@@ -317,14 +304,14 @@ class DriverController extends Controller
317
304
  $speed = $request->input('speed');
318
305
 
319
306
  try {
320
- $driver = Driver::findRecordOrFail($id);
307
+ $driver = $this->findDriver($id);
321
308
  } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $exception) {
322
- return response()->apiError('Driver resource not found.', 404);
309
+ return $this->apiError('Driver resource not found.', 404);
323
310
  }
324
311
 
325
312
  // If no lat/lng provided, maintain compatibility and just return existing driver resource
326
313
  if (empty($latitude) && empty($longitude)) {
327
- return new DriverResource($driver);
314
+ return $this->driverResource($driver);
328
315
  }
329
316
 
330
317
  $isGeocodable = Carbon::parse($driver->updated_at)->diffInMinutes(Carbon::now(), false) > 10 || empty($driver->country) || empty($driver->city);
@@ -402,7 +389,7 @@ class DriverController extends Controller
402
389
  }
403
390
  }
404
391
 
405
- return new DriverResource($driver);
392
+ return $this->driverResource($driver);
406
393
  }
407
394
 
408
395
  /**
@@ -420,9 +407,9 @@ class DriverController extends Controller
420
407
  public function toggleOnline(string $id, Request $request)
421
408
  {
422
409
  try {
423
- $driver = Driver::findRecordOrFail($id);
410
+ $driver = $this->findDriver($id);
424
411
  } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $exception) {
425
- return response()->json([
412
+ return $this->jsonResponse([
426
413
  'error' => 'Driver resource not found.',
427
414
  ], 404);
428
415
  }
@@ -443,7 +430,7 @@ class DriverController extends Controller
443
430
  }
444
431
 
445
432
  // Return the updated resource
446
- return new DriverResource($driver);
433
+ return $this->driverResource($driver);
447
434
  }
448
435
 
449
436
  /**
@@ -451,12 +438,24 @@ class DriverController extends Controller
451
438
  *
452
439
  * @return \Illuminate\Http\Response
453
440
  */
454
- public function registerDevice(string $id, Request $request)
441
+ public function registerDevice(?string $id = null, ?Request $request = null)
455
442
  {
443
+ // Laravel does NOT inject a class-typed parameter that declares a default value —
444
+ // RouteDependencyResolverTrait skips it and the default (null) is used. So the
445
+ // router always called this with $request === null, which made
446
+ // POST /v1/drivers/{id}/register-device fail with "Call to a member function
447
+ // input() on null" and POST /v1/drivers/register-device answer 404 (the driver was
448
+ // looked up by a null user_uuid). The default has to stay, because the internal
449
+ // controller delegates to this method with an id only.
450
+ $request = $request ?? request();
451
+
456
452
  try {
457
- $driver = Driver::findRecordOrFail($id);
453
+ // With an id (…/{id}/register-device) look the driver up directly; without
454
+ // one (…/register-device and the internal delegation) resolve the driver
455
+ // from the authenticated user.
456
+ $driver = $id ? $this->findDriver($id) : $this->currentDriver($request);
458
457
  } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $exception) {
459
- return response()->json(
458
+ return $this->jsonResponse(
460
459
  [
461
460
  'error' => 'Driver resource not found.',
462
461
  ],
@@ -468,14 +467,14 @@ class DriverController extends Controller
468
467
  $platform = $request->or(['platform', 'os']);
469
468
 
470
469
  if (!$token) {
471
- return response()->apiError('Token is required to register device.');
470
+ return $this->apiError('Token is required to register device.');
472
471
  }
473
472
 
474
473
  if (!$platform) {
475
- return response()->apiError('Platform is required to register device.');
474
+ return $this->apiError('Platform is required to register device.');
476
475
  }
477
476
 
478
- $device = UserDevice::firstOrCreate(
477
+ $device = $this->firstOrCreateUserDevice(
479
478
  [
480
479
  'token' => $token,
481
480
  'platform' => $platform,
@@ -488,9 +487,9 @@ class DriverController extends Controller
488
487
  ]
489
488
  );
490
489
 
491
- return response()->json([
490
+ return $this->jsonResponse([
492
491
  'device' => $device->public_id,
493
- ]);
492
+ ], 200);
494
493
  }
495
494
 
496
495
  /**
@@ -623,7 +622,7 @@ class DriverController extends Controller
623
622
 
624
623
  // find and verify code
625
624
  $verificationCode = VerificationCode::where(['subject_uuid' => $user->uuid, 'code' => $code, 'for' => $for])->exists();
626
- if (!$verificationCode && $code !== config('fleetops.navigator.bypass_verification_code')) {
625
+ if (!$verificationCode && !static::verificationBypassMatches($identity, $code)) {
627
626
  return response()->apiError('Invalid verification code!');
628
627
  }
629
628
 
@@ -673,10 +672,16 @@ class DriverController extends Controller
673
672
  }
674
673
 
675
674
  // Get the driver user account
675
+ //
676
+ // Unreachable: DriverScope adds a whereHas('user') to every driver
677
+ // query, so findRecordOrFail() never yields a driver whose user is
678
+ // missing. Kept as defence in depth if that scope is ever relaxed.
676
679
  $user = $driver->getUser();
680
+ // @codeCoverageIgnoreStart
677
681
  if (!$user) {
678
682
  return response()->apiError('Driver has not user account.');
679
683
  }
684
+ // @codeCoverageIgnoreEnd
680
685
 
681
686
  // Get the user account company
682
687
  $company = Auth::getCompanySessionForUser($user);
@@ -744,10 +749,16 @@ class DriverController extends Controller
744
749
  }
745
750
 
746
751
  // Get the driver user account
752
+ //
753
+ // Unreachable: the same user was already dereferenced above to compare
754
+ // company sessions, and DriverScope guarantees it exists in the first
755
+ // place. Kept as defence in depth if that scope is ever relaxed.
747
756
  $user = $driver->getUser();
757
+ // @codeCoverageIgnoreStart
748
758
  if (!$user) {
749
759
  return response()->apiError('Critial error, driver has not user account.');
750
760
  }
761
+ // @codeCoverageIgnoreEnd
751
762
 
752
763
  // Get the users driver profile for this company
753
764
  $driverProfile = Driver::where(['user_uuid' => $user->uuid, 'company_uuid' => $company->uuid])->first();
@@ -902,6 +913,125 @@ class DriverController extends Controller
902
913
  return response()->json($route);
903
914
  }
904
915
 
916
+ protected function companyFromRequest(Request $request): ?Company
917
+ {
918
+ return Auth::getCompanyFromRequest($request);
919
+ }
920
+
921
+ protected function currentCompany(): ?Company
922
+ {
923
+ return Auth::getCompany();
924
+ }
925
+
926
+ protected function sessionCompany(): ?string
927
+ {
928
+ return session('company');
929
+ }
930
+
931
+ protected function applyUserInfoFromRequest(Request $request, array $userDetails): array
932
+ {
933
+ return User::applyUserInfoFromRequest($request, $userDetails);
934
+ }
935
+
936
+ protected function createUser(array $userDetails): User
937
+ {
938
+ return User::create($userDetails);
939
+ }
940
+
941
+ protected function getUuid(array|string $table, array $where, array $options = []): mixed
942
+ {
943
+ return Utils::getUuid($table, $where, $options);
944
+ }
945
+
946
+ protected function pointFromCoordinates(array $coordinates): Point
947
+ {
948
+ return Utils::getPointFromCoordinates($coordinates);
949
+ }
950
+
951
+ protected function createDriver(array $attributes): Driver
952
+ {
953
+ return Driver::create($attributes);
954
+ }
955
+
956
+ protected function resolveFile(mixed $input, string $path): mixed
957
+ {
958
+ return app(\Fleetbase\Services\FileResolverService::class)->resolve($input, $path);
959
+ }
960
+
961
+ protected function findDriver(string $id, array $with = []): Driver
962
+ {
963
+ return Driver::findRecordOrFail($id, $with);
964
+ }
965
+
966
+ /**
967
+ * Resolve the driver for the authenticated request (used when no explicit
968
+ * driver id is supplied, e.g. a driver-authenticated session).
969
+ *
970
+ * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
971
+ */
972
+ protected function currentDriver(?Request $request): Driver
973
+ {
974
+ // $request->user() is never populated on the public API: the `fleetbase.api`
975
+ // middleware calls Auth::setSession($apiCredential), which writes the session keys
976
+ // but leaves $login false, so no user resolver is ever bound. Reading it alone
977
+ // meant POST /v1/drivers/register-device looked a driver up by a null user_uuid
978
+ // and answered 404 for every consumer of the route.
979
+ //
980
+ // Auth::getUserFromSession() encodes this same order, but it also calls auth() and
981
+ // session()->has(), neither of which exists in the SQLite test harness — so the
982
+ // two sources are read directly here.
983
+ $user = optional($request)->user();
984
+ if (!$user instanceof User) {
985
+ $user = User::where('uuid', session('user'))->first();
986
+ }
987
+
988
+ return Driver::where('user_uuid', optional($user)->uuid)->firstOrFail();
989
+ }
990
+
991
+ protected function queryDrivers(Request $request)
992
+ {
993
+ return Driver::queryWithRequest(
994
+ $request,
995
+ function (&$query, $request) {
996
+ if ($request->has('vendor')) {
997
+ $query->whereHas('vendor', function ($q) use ($request) {
998
+ $q->where('public_id', $request->input('vendor'));
999
+ });
1000
+ }
1001
+ }
1002
+ );
1003
+ }
1004
+
1005
+ protected function firstOrCreateUserDevice(array $attributes, array $values): UserDevice
1006
+ {
1007
+ return UserDevice::firstOrCreate($attributes, $values);
1008
+ }
1009
+
1010
+ protected function driverResource(Driver $driver)
1011
+ {
1012
+ return new DriverResource($driver);
1013
+ }
1014
+
1015
+ protected function driverResourceCollection($results)
1016
+ {
1017
+ return DriverResource::collection($results);
1018
+ }
1019
+
1020
+ protected function deletedDriverResource(Driver $driver)
1021
+ {
1022
+ return new DeletedResource($driver);
1023
+ }
1024
+
1025
+ protected function jsonResponse(array $payload, int $status)
1026
+ {
1027
+ return response()->json($payload, $status);
1028
+ }
1029
+
1030
+ protected function apiError(string $message, int $status = 400)
1031
+ {
1032
+ return response()->apiError($message, $status);
1033
+ }
1034
+
905
1035
  /**
906
1036
  * Get the drivers current company using their user account.
907
1037
  */
@@ -930,6 +1060,36 @@ class DriverController extends Controller
930
1060
  return $company;
931
1061
  }
932
1062
 
1063
+ /**
1064
+ * Whether the supplied code matches the configured testing bypass code.
1065
+ *
1066
+ * Three conditions, all required, mirroring the console equivalent in
1067
+ * Fleetbase\Http\Controllers\Internal\v1\AuthController::authenticateWithVerificationCode:
1068
+ *
1069
+ * - a bypass code must actually be configured. The previous
1070
+ * `$code !== config(...)` comparison meant that on a default install --
1071
+ * where the config resolves to null -- omitting `code` entirely made the
1072
+ * check `null !== null`, i.e. false, so the guard never fired and any
1073
+ * caller with a valid org API credential could mint a driver token for
1074
+ * any driver in the install without a code at all;
1075
+ * - the app must not be in production, so a code left set in a deployed
1076
+ * .env cannot be used against a live fleet;
1077
+ * - the comparison is constant-time.
1078
+ *
1079
+ * Shared with Internal\v1\DriverController so both verify-code paths cannot
1080
+ * drift apart.
1081
+ */
1082
+ public static function verificationBypassMatches(?string $identity, ?string $code): bool
1083
+ {
1084
+ return static::reviewAccountBypassMatches(
1085
+ 'fleetops.navigator.bypass_verification_code',
1086
+ 'fleetops.navigator.review_accounts',
1087
+ $identity,
1088
+ $code,
1089
+ 'navigator'
1090
+ );
1091
+ }
1092
+
933
1093
  /**
934
1094
  * Patches phone number with international code.
935
1095
  */