@fleetbase/fleetops-engine 0.2.5 → 0.2.7

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 (325) hide show
  1. package/.gitattributes +14 -0
  2. package/.php-cs-fixer.cache +1 -0
  3. package/.php-cs-fixer.php +29 -0
  4. package/LICENSE.md +16 -4
  5. package/README.md +103 -13
  6. package/addon/components/admin/visibility-controls.hbs +12 -0
  7. package/addon/components/admin/visibility-controls.js +82 -0
  8. package/addon/components/fleet-panel.js +13 -4
  9. package/addon/components/fleet-vehicle-listing.hbs +1 -1
  10. package/addon/components/layout/fleet-ops-sidebar.hbs +26 -0
  11. package/addon/components/layout/fleet-ops-sidebar.js +129 -0
  12. package/addon/engine.js +19 -0
  13. package/addon/helpers/is-section-visible.js +5 -0
  14. package/addon/routes/application.js +6 -2
  15. package/addon/routes/virtual.js +10 -0
  16. package/addon/routes.js +1 -0
  17. package/addon/templates/application.hbs +1 -19
  18. package/addon/templates/virtual.hbs +9 -0
  19. package/app/components/admin/visibility-controls.js +1 -0
  20. package/app/components/layout/fleet-ops-sidebar.js +1 -0
  21. package/app/helpers/is-section-visible.js +1 -0
  22. package/app/routes/virtual.js +1 -0
  23. package/app/templates/virtual.js +1 -0
  24. package/composer.json +85 -0
  25. package/extension.json +10 -0
  26. package/package.json +6 -6
  27. package/phpstan.neon.dist +8 -0
  28. package/phpunit.xml.dist +16 -0
  29. package/server/config/api.php +765 -0
  30. package/server/config/cache.stores.php +18 -0
  31. package/server/config/dompdf.php +242 -0
  32. package/server/config/fleetops.php +19 -0
  33. package/server/config/geocoder.php +108 -0
  34. package/server/data/globe.json +261 -0
  35. package/server/migrations/2023_04_27_053456_create_contacts_table.php +49 -0
  36. package/server/migrations/2023_04_27_053456_create_drivers_table.php +62 -0
  37. package/server/migrations/2023_04_27_053456_create_entities_table.php +67 -0
  38. package/server/migrations/2023_04_27_053456_create_fleet_drivers_table.php +39 -0
  39. package/server/migrations/2023_04_27_053456_create_fleets_table.php +47 -0
  40. package/server/migrations/2023_04_27_053456_create_fuel_reports_table.php +50 -0
  41. package/server/migrations/2023_04_27_053456_create_integrated_vendors_table.php +44 -0
  42. package/server/migrations/2023_04_27_053456_create_issues_table.php +53 -0
  43. package/server/migrations/2023_04_27_053456_create_orders_table.php +70 -0
  44. package/server/migrations/2023_04_27_053456_create_payloads_table.php +51 -0
  45. package/server/migrations/2023_04_27_053456_create_places_table.php +62 -0
  46. package/server/migrations/2023_04_27_053456_create_positions_table.php +46 -0
  47. package/server/migrations/2023_04_27_053456_create_proofs_table.php +44 -0
  48. package/server/migrations/2023_04_27_053456_create_purchase_rates_table.php +46 -0
  49. package/server/migrations/2023_04_27_053456_create_routes_table.php +40 -0
  50. package/server/migrations/2023_04_27_053456_create_service_areas_table.php +47 -0
  51. package/server/migrations/2023_04_27_053456_create_service_quote_items_table.php +42 -0
  52. package/server/migrations/2023_04_27_053456_create_service_quotes_table.php +47 -0
  53. package/server/migrations/2023_04_27_053456_create_service_rate_fees_table.php +45 -0
  54. package/server/migrations/2023_04_27_053456_create_service_rate_parcel_fees_table.php +47 -0
  55. package/server/migrations/2023_04_27_053456_create_service_rates_table.php +61 -0
  56. package/server/migrations/2023_04_27_053456_create_tracking_numbers_table.php +46 -0
  57. package/server/migrations/2023_04_27_053456_create_tracking_statuses_table.php +54 -0
  58. package/server/migrations/2023_04_27_053456_create_vehicles_table.php +84 -0
  59. package/server/migrations/2023_04_27_053456_create_vendors_table.php +56 -0
  60. package/server/migrations/2023_04_27_053456_create_waypoints_table.php +45 -0
  61. package/server/migrations/2023_04_27_053456_create_zones_table.php +46 -0
  62. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_companies_table.php +32 -0
  63. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_contacts_table.php +34 -0
  64. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_drivers_table.php +40 -0
  65. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_entities_table.php +40 -0
  66. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_fleet_drivers_table.php +34 -0
  67. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_fleets_table.php +36 -0
  68. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_fuel_reports_table.php +36 -0
  69. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_integrated_vendors_table.php +34 -0
  70. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_issues_table.php +38 -0
  71. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_orders_table.php +48 -0
  72. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_payloads_table.php +40 -0
  73. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_places_table.php +32 -0
  74. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_positions_table.php +36 -0
  75. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_proofs_table.php +34 -0
  76. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_purchase_rates_table.php +38 -0
  77. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_routes_table.php +34 -0
  78. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_service_areas_table.php +34 -0
  79. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_service_quote_items_table.php +32 -0
  80. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_service_quotes_table.php +38 -0
  81. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_service_rate_fees_table.php +32 -0
  82. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_service_rate_parcel_fees_table.php +32 -0
  83. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_service_rates_table.php +36 -0
  84. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_tracking_numbers_table.php +34 -0
  85. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_tracking_statuses_table.php +34 -0
  86. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_vehicles_table.php +36 -0
  87. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_vendors_table.php +40 -0
  88. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_waypoints_table.php +38 -0
  89. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_zones_table.php +34 -0
  90. package/server/migrations/2023_09_14_074512_update_vehicles_table.php +100 -0
  91. package/server/migrations/2023_09_14_074619_create_vehicle_devices_table.php +44 -0
  92. package/server/migrations/2023_09_26_071205_add_online_column_to_vehicles_table.php +32 -0
  93. package/server/migrations/2023_09_26_083957_create_fleet_vehicles_table.php +45 -0
  94. package/server/migrations/2023_09_27_023757_add_column_to_fleets_table.php +46 -0
  95. package/server/migrations/2023_10_05_074811_update_vehicle.php +42 -0
  96. package/server/resources/views/labels/default.php +165 -0
  97. package/server/src/Auth/Schemas/FleetOps.php +75 -0
  98. package/server/src/Casts/MultiPolygon.php +50 -0
  99. package/server/src/Casts/Point.php +109 -0
  100. package/server/src/Casts/Polygon.php +46 -0
  101. package/server/src/Console/Commands/DispatchAdhocOrders.php +137 -0
  102. package/server/src/Console/Commands/DispatchOrders.php +71 -0
  103. package/server/src/Console/Commands/TrackOrderDistanceAndTime.php +62 -0
  104. package/server/src/Events/DriverLocationChanged.php +174 -0
  105. package/server/src/Events/DriverSimulatedLocationChanged.php +183 -0
  106. package/server/src/Events/EntityDriverAssigned.php +36 -0
  107. package/server/src/Events/OrderCanceled.php +15 -0
  108. package/server/src/Events/OrderCompleted.php +15 -0
  109. package/server/src/Events/OrderDispatchFailed.php +42 -0
  110. package/server/src/Events/OrderDispatched.php +15 -0
  111. package/server/src/Events/OrderDriverAssigned.php +15 -0
  112. package/server/src/Events/OrderReady.php +15 -0
  113. package/server/src/Events/OrderStarted.php +15 -0
  114. package/server/src/Exceptions/IntegratedVendorException.php +18 -0
  115. package/server/src/Expansions/UserExpansion.php +63 -0
  116. package/server/src/Exports/ContactExport.php +56 -0
  117. package/server/src/Exports/DriverExport.php +61 -0
  118. package/server/src/Exports/FleetExport.php +53 -0
  119. package/server/src/Exports/PlaceExport.php +55 -0
  120. package/server/src/Exports/ServiceAreaExport.php +58 -0
  121. package/server/src/Exports/VehicleExport.php +57 -0
  122. package/server/src/Exports/VendorExport.php +57 -0
  123. package/server/src/Http/Controllers/Api/v1/ContactController.php +133 -0
  124. package/server/src/Http/Controllers/Api/v1/DriverController.php +691 -0
  125. package/server/src/Http/Controllers/Api/v1/EntityController.php +230 -0
  126. package/server/src/Http/Controllers/Api/v1/FleetController.php +146 -0
  127. package/server/src/Http/Controllers/Api/v1/LabelController.php +63 -0
  128. package/server/src/Http/Controllers/Api/v1/OrderController.php +1114 -0
  129. package/server/src/Http/Controllers/Api/v1/PayloadController.php +195 -0
  130. package/server/src/Http/Controllers/Api/v1/PlaceController.php +333 -0
  131. package/server/src/Http/Controllers/Api/v1/PurchaseRateController.php +199 -0
  132. package/server/src/Http/Controllers/Api/v1/ServiceAreaController.php +133 -0
  133. package/server/src/Http/Controllers/Api/v1/ServiceQuoteController.php +381 -0
  134. package/server/src/Http/Controllers/Api/v1/ServiceRateController.php +223 -0
  135. package/server/src/Http/Controllers/Api/v1/TrackingNumberController.php +146 -0
  136. package/server/src/Http/Controllers/Api/v1/TrackingStatusController.php +138 -0
  137. package/server/src/Http/Controllers/Api/v1/VehicleController.php +191 -0
  138. package/server/src/Http/Controllers/Api/v1/VendorController.php +159 -0
  139. package/server/src/Http/Controllers/Api/v1/ZoneController.php +146 -0
  140. package/server/src/Http/Controllers/FleetOpsController.php +13 -0
  141. package/server/src/Http/Controllers/Internal/v1/ContactController.php +69 -0
  142. package/server/src/Http/Controllers/Internal/v1/DriverController.php +261 -0
  143. package/server/src/Http/Controllers/Internal/v1/EntityController.php +15 -0
  144. package/server/src/Http/Controllers/Internal/v1/FleetController.php +152 -0
  145. package/server/src/Http/Controllers/Internal/v1/FleetOpsLookupController.php +80 -0
  146. package/server/src/Http/Controllers/Internal/v1/FuelReportController.php +15 -0
  147. package/server/src/Http/Controllers/Internal/v1/GeocoderController.php +96 -0
  148. package/server/src/Http/Controllers/Internal/v1/IntegratedVendorController.php +63 -0
  149. package/server/src/Http/Controllers/Internal/v1/IssueController.php +15 -0
  150. package/server/src/Http/Controllers/Internal/v1/LiveController.php +127 -0
  151. package/server/src/Http/Controllers/Internal/v1/MetricsController.php +75 -0
  152. package/server/src/Http/Controllers/Internal/v1/MorphController.php +77 -0
  153. package/server/src/Http/Controllers/Internal/v1/OrderConfigController.php +269 -0
  154. package/server/src/Http/Controllers/Internal/v1/OrderController.php +564 -0
  155. package/server/src/Http/Controllers/Internal/v1/PayloadController.php +15 -0
  156. package/server/src/Http/Controllers/Internal/v1/PlaceController.php +163 -0
  157. package/server/src/Http/Controllers/Internal/v1/ProofController.php +139 -0
  158. package/server/src/Http/Controllers/Internal/v1/PurchaseRateController.php +15 -0
  159. package/server/src/Http/Controllers/Internal/v1/RouteController.php +15 -0
  160. package/server/src/Http/Controllers/Internal/v1/ServiceAreaController.php +32 -0
  161. package/server/src/Http/Controllers/Internal/v1/ServiceQuoteController.php +345 -0
  162. package/server/src/Http/Controllers/Internal/v1/ServiceRateController.php +47 -0
  163. package/server/src/Http/Controllers/Internal/v1/SettingController.php +30 -0
  164. package/server/src/Http/Controllers/Internal/v1/TrackingNumberController.php +15 -0
  165. package/server/src/Http/Controllers/Internal/v1/TrackingStatusController.php +15 -0
  166. package/server/src/Http/Controllers/Internal/v1/VehicleController.php +65 -0
  167. package/server/src/Http/Controllers/Internal/v1/VehicleDeviceController.php +15 -0
  168. package/server/src/Http/Controllers/Internal/v1/VendorController.php +120 -0
  169. package/server/src/Http/Controllers/Internal/v1/ZoneController.php +15 -0
  170. package/server/src/Http/Filter/ContactFilter.php +86 -0
  171. package/server/src/Http/Filter/DriverFilter.php +148 -0
  172. package/server/src/Http/Filter/FleetFilter.php +108 -0
  173. package/server/src/Http/Filter/IntegratedVendorFilter.php +13 -0
  174. package/server/src/Http/Filter/OrderFilter.php +242 -0
  175. package/server/src/Http/Filter/PlaceFilter.php +111 -0
  176. package/server/src/Http/Filter/ServiceAreaFilter.php +13 -0
  177. package/server/src/Http/Filter/ServiceQuoteFilter.php +13 -0
  178. package/server/src/Http/Filter/ServiceRateFilter.php +33 -0
  179. package/server/src/Http/Filter/TrackingStatusFilter.php +43 -0
  180. package/server/src/Http/Filter/VehicleFilter.php +91 -0
  181. package/server/src/Http/Filter/VendorFilter.php +83 -0
  182. package/server/src/Http/Filter/ZoneFilter.php +13 -0
  183. package/server/src/Http/Requests/CancelOrderRequest.php +31 -0
  184. package/server/src/Http/Requests/CreateContactRequest.php +33 -0
  185. package/server/src/Http/Requests/CreateDriverRequest.php +55 -0
  186. package/server/src/Http/Requests/CreateEntityRequest.php +43 -0
  187. package/server/src/Http/Requests/CreateFleetRequest.php +32 -0
  188. package/server/src/Http/Requests/CreateOrderRequest.php +66 -0
  189. package/server/src/Http/Requests/CreatePayloadRequest.php +37 -0
  190. package/server/src/Http/Requests/CreatePlaceRequest.php +38 -0
  191. package/server/src/Http/Requests/CreatePurchaseRateRequest.php +33 -0
  192. package/server/src/Http/Requests/CreateServiceAreaRequest.php +35 -0
  193. package/server/src/Http/Requests/CreateServiceQuoteRequest.php +29 -0
  194. package/server/src/Http/Requests/CreateServiceRateRequest.php +56 -0
  195. package/server/src/Http/Requests/CreateTrackingNumberRequest.php +34 -0
  196. package/server/src/Http/Requests/CreateTrackingStatusRequest.php +42 -0
  197. package/server/src/Http/Requests/CreateVehicleRequest.php +32 -0
  198. package/server/src/Http/Requests/CreateVendorRequest.php +35 -0
  199. package/server/src/Http/Requests/CreateZoneRequest.php +35 -0
  200. package/server/src/Http/Requests/DecodeTrackingNumberQR.php +30 -0
  201. package/server/src/Http/Requests/DriverSimulationRequest.php +46 -0
  202. package/server/src/Http/Requests/Internal/AssignOrderRequest.php +31 -0
  203. package/server/src/Http/Requests/Internal/CreateDriverRequest.php +42 -0
  204. package/server/src/Http/Requests/Internal/FleetActionRequest.php +32 -0
  205. package/server/src/Http/Requests/Internal/UpdateDriverRequest.php +7 -0
  206. package/server/src/Http/Requests/QueryServiceQuotesRequest.php +41 -0
  207. package/server/src/Http/Requests/UpdateContactRequest.php +20 -0
  208. package/server/src/Http/Requests/UpdateDriverRequest.php +7 -0
  209. package/server/src/Http/Requests/UpdateEntityRequest.php +7 -0
  210. package/server/src/Http/Requests/UpdateFleetRequest.php +7 -0
  211. package/server/src/Http/Requests/UpdateOrderRequest.php +7 -0
  212. package/server/src/Http/Requests/UpdatePayloadRequest.php +7 -0
  213. package/server/src/Http/Requests/UpdatePlaceRequest.php +7 -0
  214. package/server/src/Http/Requests/UpdatePurchaseRateRequest.php +7 -0
  215. package/server/src/Http/Requests/UpdateServiceAreaRequest.php +29 -0
  216. package/server/src/Http/Requests/UpdateServiceQuoteRequest.php +29 -0
  217. package/server/src/Http/Requests/UpdateServiceRateRequest.php +29 -0
  218. package/server/src/Http/Requests/UpdateTrackingNumberRequest.php +7 -0
  219. package/server/src/Http/Requests/UpdateTrackingStatusRequest.php +32 -0
  220. package/server/src/Http/Requests/UpdateVehicleRequest.php +7 -0
  221. package/server/src/Http/Requests/UpdateVendorRequest.php +7 -0
  222. package/server/src/Http/Requests/UpdateZoneRequest.php +7 -0
  223. package/server/src/Http/Resources/Internal/v1/IntegratedVendorFacilitator.php +37 -0
  224. package/server/src/Http/Resources/Internal/v1/Vehicle.php +33 -0
  225. package/server/src/Http/Resources/Internal/v1/Waypoint.php +34 -0
  226. package/server/src/Http/Resources/v1/Contact.php +62 -0
  227. package/server/src/Http/Resources/v1/CurrentJob.php +36 -0
  228. package/server/src/Http/Resources/v1/DeletedResource.php +61 -0
  229. package/server/src/Http/Resources/v1/Driver.php +89 -0
  230. package/server/src/Http/Resources/v1/Entity.php +107 -0
  231. package/server/src/Http/Resources/v1/Fleet.php +60 -0
  232. package/server/src/Http/Resources/v1/FuelReport.php +67 -0
  233. package/server/src/Http/Resources/v1/Order.php +131 -0
  234. package/server/src/Http/Resources/v1/Payload.php +94 -0
  235. package/server/src/Http/Resources/v1/Place.php +84 -0
  236. package/server/src/Http/Resources/v1/Proof.php +36 -0
  237. package/server/src/Http/Resources/v1/PurchaseRate.php +77 -0
  238. package/server/src/Http/Resources/v1/ServiceArea.php +55 -0
  239. package/server/src/Http/Resources/v1/ServiceQuote.php +57 -0
  240. package/server/src/Http/Resources/v1/ServiceRate.php +94 -0
  241. package/server/src/Http/Resources/v1/ServiceRateFee.php +58 -0
  242. package/server/src/Http/Resources/v1/ServiceRateParcelFee.php +48 -0
  243. package/server/src/Http/Resources/v1/TrackingNumber.php +62 -0
  244. package/server/src/Http/Resources/v1/TrackingStatus.php +84 -0
  245. package/server/src/Http/Resources/v1/Vehicle.php +75 -0
  246. package/server/src/Http/Resources/v1/VehicleDevice.php +44 -0
  247. package/server/src/Http/Resources/v1/VehicleWithoutDriver.php +72 -0
  248. package/server/src/Http/Resources/v1/Vendor.php +72 -0
  249. package/server/src/Http/Resources/v1/Zone.php +60 -0
  250. package/server/src/Imports/OrdersImport.php +18 -0
  251. package/server/src/Integrations/Lalamove/Lalamove.php +678 -0
  252. package/server/src/Integrations/Lalamove/LalamoveDeliveryStop.php +97 -0
  253. package/server/src/Integrations/Lalamove/LalamoveMarket.php +123 -0
  254. package/server/src/Integrations/Lalamove/LalamoveServiceType.php +161 -0
  255. package/server/src/Jobs/SimulateDrivingRoute.php +81 -0
  256. package/server/src/Jobs/SimulateWaypointReached.php +79 -0
  257. package/server/src/Listeners/HandleOrderCanceled.php +46 -0
  258. package/server/src/Listeners/HandleOrderCreated.php +23 -0
  259. package/server/src/Listeners/HandleOrderDispatchFailed.php +35 -0
  260. package/server/src/Listeners/HandleOrderDispatched.php +108 -0
  261. package/server/src/Listeners/HandleOrderDriverAssigned.php +42 -0
  262. package/server/src/Listeners/HandleOrderReady.php +27 -0
  263. package/server/src/Listeners/HandleUserRemovedFromCompany.php +31 -0
  264. package/server/src/Models/Contact.php +239 -0
  265. package/server/src/Models/Driver.php +543 -0
  266. package/server/src/Models/Entity.php +416 -0
  267. package/server/src/Models/Fleet.php +203 -0
  268. package/server/src/Models/FleetDriver.php +73 -0
  269. package/server/src/Models/FleetVehicle.php +73 -0
  270. package/server/src/Models/FuelReport.php +125 -0
  271. package/server/src/Models/IntegratedVendor.php +219 -0
  272. package/server/src/Models/Issue.php +111 -0
  273. package/server/src/Models/Order.php +1132 -0
  274. package/server/src/Models/Payload.php +699 -0
  275. package/server/src/Models/Place.php +656 -0
  276. package/server/src/Models/Position.php +119 -0
  277. package/server/src/Models/Proof.php +94 -0
  278. package/server/src/Models/PurchaseRate.php +208 -0
  279. package/server/src/Models/Route.php +128 -0
  280. package/server/src/Models/ServiceArea.php +161 -0
  281. package/server/src/Models/ServiceQuote.php +207 -0
  282. package/server/src/Models/ServiceQuoteItem.php +46 -0
  283. package/server/src/Models/ServiceRate.php +953 -0
  284. package/server/src/Models/ServiceRateFee.php +96 -0
  285. package/server/src/Models/ServiceRateParcelFee.php +116 -0
  286. package/server/src/Models/TrackingNumber.php +310 -0
  287. package/server/src/Models/TrackingStatus.php +177 -0
  288. package/server/src/Models/Vehicle.php +452 -0
  289. package/server/src/Models/VehicleDevice.php +79 -0
  290. package/server/src/Models/Vendor.php +244 -0
  291. package/server/src/Models/Waypoint.php +226 -0
  292. package/server/src/Models/Zone.php +95 -0
  293. package/server/src/Notifications/OrderAssigned.php +140 -0
  294. package/server/src/Notifications/OrderCanceled.php +129 -0
  295. package/server/src/Notifications/OrderDispatchFailed.php +81 -0
  296. package/server/src/Notifications/OrderDispatched.php +173 -0
  297. package/server/src/Notifications/OrderPing.php +162 -0
  298. package/server/src/Notifications/OrderSplit.php +56 -0
  299. package/server/src/Observers/DriverObserver.php +34 -0
  300. package/server/src/Observers/OrderObserver.php +34 -0
  301. package/server/src/Observers/PayloadObserver.php +30 -0
  302. package/server/src/Observers/PlaceObserver.php +26 -0
  303. package/server/src/Observers/PurchaseRateObserver.php +61 -0
  304. package/server/src/Observers/ServiceAreaObserver.php +35 -0
  305. package/server/src/Observers/ServiceRateObserver.php +78 -0
  306. package/server/src/Observers/TrackingNumberObserver.php +44 -0
  307. package/server/src/Observers/UserObserver.php +20 -0
  308. package/server/src/Observers/VehicleObserver.php +66 -0
  309. package/server/src/Providers/EventServiceProvider.php +30 -0
  310. package/server/src/Providers/FleetOpsServiceProvider.php +94 -0
  311. package/server/src/Rules/ResolvablePoint.php +37 -0
  312. package/server/src/Scopes/DriverScope.php +21 -0
  313. package/server/src/Support/Algo.php +55 -0
  314. package/server/src/Support/DistanceMatrix.php +27 -0
  315. package/server/src/Support/Encoding/Polyline.php +168 -0
  316. package/server/src/Support/Flow.php +622 -0
  317. package/server/src/Support/Geocoding.php +216 -0
  318. package/server/src/Support/IntegratedVendors.php +287 -0
  319. package/server/src/Support/Metrics.php +305 -0
  320. package/server/src/Support/OSRM.php +191 -0
  321. package/server/src/Support/ParsePhone.php +21 -0
  322. package/server/src/Support/Utils.php +1145 -0
  323. package/server/src/Traits/HasTrackingNumber.php +185 -0
  324. package/server/src/routes.php +381 -0
  325. package/server/tests/Feature.php +5 -0
@@ -0,0 +1,699 @@
1
+ <?php
2
+
3
+ namespace Fleetbase\FleetOps\Models;
4
+
5
+ use Fleetbase\Casts\Json;
6
+ use Fleetbase\FleetOps\Support\Utils;
7
+ use Fleetbase\Http\Resources\Internal\v1\Payload as PayloadResource;
8
+ use Fleetbase\Models\Model;
9
+ use Fleetbase\Traits\HasApiModelBehavior;
10
+ use Fleetbase\Traits\HasMetaAttributes;
11
+ use Fleetbase\Traits\HasPublicId;
12
+ use Fleetbase\Traits\HasUuid;
13
+ use Fleetbase\Traits\TracksApiCredential;
14
+ use Grimzy\LaravelMysqlSpatial\Types\Point;
15
+ use Illuminate\Support\Str;
16
+
17
+ class Payload extends Model
18
+ {
19
+ use HasUuid;
20
+ use HasPublicId;
21
+ use HasApiModelBehavior;
22
+ use TracksApiCredential;
23
+ use HasMetaAttributes;
24
+
25
+ /**
26
+ * The database table used by the model.
27
+ *
28
+ * @var string
29
+ */
30
+ protected $table = 'payloads';
31
+
32
+ /**
33
+ * The type of public Id to generate.
34
+ *
35
+ * @var string
36
+ */
37
+ protected $publicIdType = 'payload';
38
+
39
+ /**
40
+ * Delegate a HTTP resource to use for this model.
41
+ *
42
+ * @var string
43
+ */
44
+ protected $httpResource = PayloadResource::class;
45
+
46
+ /**
47
+ * These attributes that can be queried.
48
+ *
49
+ * @var array
50
+ */
51
+ protected $searchableColumns = [];
52
+
53
+ /**
54
+ * The attributes that are mass assignable.
55
+ *
56
+ * @var array
57
+ */
58
+ protected $fillable = ['_key', 'company_uuid', 'pickup_uuid', 'dropoff_uuid', 'return_uuid', 'current_waypoint_uuid', 'meta', 'payment_method', 'cod_amount', 'cod_currency', 'cod_payment_method', 'type'];
59
+
60
+ /**
61
+ * The attributes that should be cast to native types.
62
+ *
63
+ * @var array
64
+ */
65
+ protected $casts = [
66
+ 'meta' => Json::class,
67
+ ];
68
+
69
+ /**
70
+ * Relations to load with the model.
71
+ *
72
+ * @var array
73
+ */
74
+ protected $with = ['entities', 'waypoints']; // 'pickup', 'dropoff', 'return',
75
+
76
+ /**
77
+ * Dynamic attributes that are appended to object.
78
+ *
79
+ * @var array
80
+ */
81
+ protected $appends = ['pickup_name', 'dropoff_name'];
82
+
83
+ /**
84
+ * The attributes excluded from the model's JSON form.
85
+ *
86
+ * @var array
87
+ */
88
+ protected $hidden = [];
89
+
90
+ /**
91
+ * Address/name of the dropoff location.
92
+ */
93
+ public function getDropoffNameAttribute()
94
+ {
95
+ $dropoff = $this->getDropoffOrLastWaypoint();
96
+
97
+ return $dropoff->address ?? $dropoff->name ?? $dropoff->street1 ?? null;
98
+ }
99
+
100
+ /**
101
+ * Address/name of the pickup location.
102
+ */
103
+ public function getPickupNameAttribute()
104
+ {
105
+ $pickup = $this->getPickupOrCurrentWaypoint();
106
+
107
+ return $pickup->address ?? $pickup->name ?? $pickup->street1 ?? null;
108
+ }
109
+
110
+ /**
111
+ * Entities in the payload.
112
+ */
113
+ public function entities()
114
+ {
115
+ return $this->hasMany(Entity::class);
116
+ }
117
+
118
+ /**
119
+ * Waypoint records in the payload.
120
+ */
121
+ public function waypointMarkers()
122
+ {
123
+ return $this->hasMany(Waypoint::class)->with(['place']);
124
+ }
125
+
126
+ public function getTotalEntitiesAttribute()
127
+ {
128
+ return $this->entities()->count();
129
+ }
130
+
131
+ public function getTotalWaypointsAttribute()
132
+ {
133
+ return $this->waypoints()->count();
134
+ }
135
+
136
+ /**
137
+ * The order the payload belongs to.
138
+ */
139
+ public function order()
140
+ {
141
+ return $this->hasOne(Order::class)->without(['payload']);
142
+ }
143
+
144
+ /**
145
+ * The address the shipment will be delivered to.
146
+ */
147
+ public function dropoff()
148
+ {
149
+ return $this->belongsTo(Place::class, 'dropoff_uuid')->whereNull('deleted_at')->withoutGlobalScopes();
150
+ }
151
+
152
+ /**
153
+ * The address the shipment will be delivered from.
154
+ */
155
+ public function pickup()
156
+ {
157
+ return $this->belongsTo(Place::class, 'pickup_uuid')->whereNull('deleted_at')->withoutGlobalScopes();
158
+ }
159
+
160
+ /**
161
+ * The address the shipment will be sent to upon failed delivery.
162
+ */
163
+ public function return()
164
+ {
165
+ return $this->belongsTo(Place::class)->withoutGlobalScopes();
166
+ }
167
+
168
+ /**
169
+ * The current waypoint of the payload in progress.
170
+ */
171
+ public function currentWaypoint()
172
+ {
173
+ return $this->belongsTo(Place::class, 'current_waypoint_uuid')->withoutGlobalScopes();
174
+ }
175
+
176
+ /**
177
+ * Waypoints between start and end.
178
+ *
179
+ * @return \Illuminate\Database\Eloquent\Concerns\HasManyThrough
180
+ */
181
+ public function waypoints()
182
+ {
183
+ return $this->hasManyThrough(Place::class, Waypoint::class, 'payload_uuid', 'uuid', 'uuid', 'place_uuid')->whereNull('waypoints.deleted_at')->withoutGlobalScopes();
184
+ }
185
+
186
+ /**
187
+ * Waypoints between start and end.
188
+ *
189
+ * @return \Illuminate\Database\Eloquent\Concerns\HasManyThrough
190
+ */
191
+ public function waypointsCompleted()
192
+ {
193
+ return $this->hasManyThrough(Place::class, WaypointCompleted::class, 'payload_uuid', 'uuid', 'uuid', 'place_uuid')->withoutGlobalScopes();
194
+ }
195
+
196
+ /**
197
+ * Always convert fee and rate to integer before insert.
198
+ */
199
+ public function setCodAmountAttribute($value)
200
+ {
201
+ $this->attributes['cod_amount'] = Utils::numbersOnly($value);
202
+ }
203
+
204
+ public function setEntities($entities = [])
205
+ {
206
+ if (empty($entities) || !is_array($entities)) {
207
+ return $this;
208
+ }
209
+
210
+ foreach ($entities as $attributes) {
211
+ if (isset($attributes['_import_id'])) {
212
+ $waypoint = $this->waypoints->firstWhere('_import_id', $attributes['_import_id']);
213
+
214
+ if ($waypoint) {
215
+ $attributes['destination_uuid'] = $waypoint->uuid;
216
+ }
217
+ }
218
+
219
+ // confirm destination_uuid is indeed a place record
220
+ if (isset($attributes['destination_uuid']) && Place::where('uuid', $attributes['destination_uuid'])->doesntExist()) {
221
+ // search waypoints for search_uuid if any
222
+ $destination = Place::where('meta->search_uuid', $attributes['destination_uuid'])->first();
223
+
224
+ if ($destination instanceof Place) {
225
+ $attributes['destination_uuid'] = $destination->uuid;
226
+ } else {
227
+ unset($attributes['destination_uuid']);
228
+ }
229
+ }
230
+
231
+ $entity = new Entity($attributes);
232
+
233
+ $this->entities()->save($entity);
234
+ }
235
+
236
+ return $this;
237
+ }
238
+
239
+ public function insertEntities($entities = [])
240
+ {
241
+ if (empty($entities) || !is_array($entities)) {
242
+ return $this;
243
+ }
244
+
245
+ $this->load(['waypoints']);
246
+
247
+ foreach ($entities as $attributes) {
248
+ if (isset($attributes['_import_id']) && !isset($attributes['destination_uuid'])) {
249
+ $waypoint = $this->waypoints->firstWhere('_import_id', $attributes['_import_id']);
250
+
251
+ if ($waypoint) {
252
+ $attributes['destination_uuid'] = $waypoint->uuid;
253
+ }
254
+ }
255
+
256
+ // confirm destination_uuid is indeed a place record
257
+ if (isset($attributes['destination_uuid']) && Place::where('uuid', $attributes['destination_uuid'])->doesntExist()) {
258
+ // search waypoints for search_uuid if any
259
+ $destination = Place::where('meta->search_uuid', $attributes['destination_uuid'])->first();
260
+
261
+ if ($destination instanceof Place) {
262
+ $attributes['destination_uuid'] = $destination->uuid;
263
+ } else {
264
+ unset($attributes['destination_uuid']);
265
+ }
266
+ }
267
+
268
+ Entity::insertGetUuid($attributes, $this);
269
+ }
270
+
271
+ $this->load(['entities']);
272
+
273
+ return $this;
274
+ }
275
+
276
+ public function setWaypoints($waypoints = [])
277
+ {
278
+ if (!is_array($waypoints)) {
279
+ return $this;
280
+ }
281
+
282
+ foreach ($waypoints as $index => $attributes) {
283
+ $waypoint = [];
284
+
285
+ if (Utils::isset($attributes, 'place') && is_array(Utils::get($attributes, 'place'))) {
286
+ $attributes = Utils::get($attributes, 'place');
287
+ }
288
+
289
+ if (is_array($attributes) && array_key_exists('place_uuid', $attributes) && Place::where('uuid', $attributes['place_uuid'])->exists()) {
290
+ $waypoint = [
291
+ 'place_uuid' => $attributes['place_uuid'],
292
+ 'payload_uuid' => $attributes['payload_uuid'] ?? null,
293
+ 'order' => $index,
294
+ ];
295
+ } else {
296
+ $place = Place::createFromMixed($attributes);
297
+
298
+ // if has a temporary uuid from search create meta attr for search_uuid
299
+ if ($place instanceof Place && isset($attributes['uuid']) && $place->uuid !== $attributes['uuid']) {
300
+ $place->updateMeta('search_uuid', $attributes['uuid']);
301
+ }
302
+
303
+ $waypoint['place_uuid'] = $place->uuid;
304
+ }
305
+
306
+ // set payload
307
+ $waypoint['payload_uuid'] = $this->uuid;
308
+ $waypointRecord = Waypoint::updateOrCreate($waypoint);
309
+
310
+ $this->waypointMarkers->push($waypointRecord);
311
+ }
312
+
313
+ return $this;
314
+ }
315
+
316
+ public function insertWaypoints($waypoints = [])
317
+ {
318
+ if (!is_array($waypoints)) {
319
+ return $this;
320
+ }
321
+
322
+ foreach ($waypoints as $index => $attributes) {
323
+ $waypoint = [];
324
+
325
+ if (Utils::isset($attributes, 'place') && is_array(Utils::get($attributes, 'place'))) {
326
+ $attributes = Utils::get($attributes, 'place');
327
+ }
328
+
329
+ if (is_array($attributes) && array_key_exists('place_uuid', $attributes) && Place::where('uuid', $attributes['place_uuid'])->exists()) {
330
+ $waypoint = [
331
+ 'place_uuid' => $attributes['place_uuid'],
332
+ 'payload_uuid' => $attributes['payload_uuid'] ?? null,
333
+ 'order' => $index,
334
+ ];
335
+ } else {
336
+ $placeUuid = Place::insertFromMixed($attributes);
337
+
338
+ // if has a temporary uuid from search create meta attr for search_uuid
339
+ if (Utils::isUuid($placeUuid) && isset($attributes['uuid']) && $placeUuid !== $attributes['uuid']) {
340
+ $place = Place::where('uuid', $placeUuid)->first();
341
+
342
+ if ($place instanceof Place) {
343
+ $place->updateMeta('search_uuid', $attributes['uuid']);
344
+ }
345
+ }
346
+
347
+ $waypoint['place_uuid'] = $placeUuid;
348
+ }
349
+
350
+ Waypoint::insertGetUuid($waypoint, $this);
351
+ }
352
+
353
+ return $this;
354
+ }
355
+
356
+ public function updateWaypoints($waypoints = [])
357
+ {
358
+ if (!is_array($waypoints)) {
359
+ return $this;
360
+ }
361
+
362
+ $placeIds = [];
363
+
364
+ // collect all place ids to insert
365
+ foreach ($waypoints as $index => $attributes) {
366
+ if (Utils::isset($attributes, 'place') && is_array(Utils::get($attributes, 'place'))) {
367
+ $attributes = Utils::get($attributes, 'place');
368
+ }
369
+
370
+ if (is_array($attributes) && array_key_exists('place_uuid', $attributes)) {
371
+ $placeIds[] = $attributes['place_uuid'];
372
+ } else {
373
+ $placeUuid = Place::insertFromMixed($attributes);
374
+ $placeIds[] = $placeUuid;
375
+ }
376
+ }
377
+
378
+ /** @return \Illuminate\Database\Eloquent\Collection $waypointMakers */
379
+ $waypointMakers = $this->waypointMarkers()->get();
380
+
381
+ // remove all waypoints that are not included in the placeids
382
+ $waypointMakers = $waypointMakers->filter(function ($waypointMarker) use ($placeIds) {
383
+ if (!in_array($waypointMarker->place_uuid, $placeIds)) {
384
+ $waypointMarker->delete();
385
+ }
386
+
387
+ return in_array($waypointMarker->place_uuid, $placeIds);
388
+ });
389
+
390
+ // update or create waypoint markers
391
+ foreach ($placeIds as $placeId) {
392
+ Waypoint::updateOrCreate(
393
+ [
394
+ 'payload_uuid' => $this->uuid,
395
+ 'place_uuid' => $placeId,
396
+ ],
397
+ [
398
+ 'payload_uuid' => $this->uuid,
399
+ 'place_uuid' => $placeId,
400
+ ]
401
+ );
402
+ }
403
+
404
+ return $this->refresh()->load(['waypoints']);
405
+ }
406
+
407
+ /**
408
+ * Get the payload pickup point or the first waypoint.
409
+ *
410
+ * @return \Fleetbase\Models\Place|null
411
+ */
412
+ public function getDropoffOrLastWaypoint(): ?Place
413
+ {
414
+ $this->load(['dropoff', 'waypoints']);
415
+
416
+ if ($this->dropoff instanceof Place) {
417
+ return $this->dropoff;
418
+ }
419
+
420
+ if ($this->waypoints()->count()) {
421
+ return $this->waypoints->first();
422
+ }
423
+
424
+ return null;
425
+ }
426
+
427
+ /**
428
+ * Get the payload pickup point or the first waypoint.
429
+ *
430
+ * @return \Fleetbase\Models\Place|null
431
+ */
432
+ public function getPickupOrFirstWaypoint(): ?Place
433
+ {
434
+ $this->load(['pickup', 'waypoints']);
435
+
436
+ if ($this->pickup instanceof Place) {
437
+ return $this->pickup;
438
+ }
439
+
440
+ if ($this->waypoints()->count()) {
441
+ return $this->waypoints->last();
442
+ }
443
+
444
+ return null;
445
+ }
446
+
447
+ /**
448
+ * Get the payload pickup point or the current waypoint.
449
+ *
450
+ * @return \Fleetbase\Models\Place|null
451
+ */
452
+ public function getPickupOrCurrentWaypoint(): ?Place
453
+ {
454
+ $this->load(['pickup', 'dropoff', 'waypoints']);
455
+
456
+ if ($this->pickup instanceof Place) {
457
+ return $this->pickup;
458
+ }
459
+
460
+ // special case where starting point is drivers current location
461
+ // this special case can be set in order meta `pickup_is_driver_location`
462
+ // this will start the order at the current location of the driver
463
+ if ($this->hasMeta('pickup_is_driver_location')) {
464
+ // if should use the driver location attempt to use dropoff
465
+ if ($this->dropoff instanceof Place) {
466
+ return $this->dropoff;
467
+ }
468
+ }
469
+
470
+ // use the current waypoint
471
+ // if the current waypoint isn't found fallback to first waypoint
472
+ if ($this->waypoints()->count()) {
473
+ $destination = null;
474
+
475
+ if ($this->current_waypoint_uuid) {
476
+ $destination = $this->waypoints->firstWhere('uuid', $this->current_waypoint_uuid);
477
+ }
478
+
479
+ if (!$destination) {
480
+ $destination = $this->waypoints->first();
481
+ }
482
+
483
+ return $destination;
484
+ }
485
+
486
+ return null;
487
+ }
488
+
489
+ public function getPickupRegion(): string
490
+ {
491
+ $pickup = $this->getPickupOrCurrentWaypoint();
492
+
493
+ return $pickup->country ?? $pickup->province ?? $pickup->district ?? 'SG';
494
+ }
495
+
496
+ public function getCountryCode(): string
497
+ {
498
+ $start = $this->getPickupOrCurrentWaypoint();
499
+
500
+ return $start->country;
501
+ }
502
+
503
+ public function getAllStops()
504
+ {
505
+ $stops = collect();
506
+
507
+ if ($this->pickup) {
508
+ $stops->push($this->pickup);
509
+ }
510
+
511
+ if ($this->dropoff) {
512
+ $stops->push($this->dropoff);
513
+ }
514
+
515
+ if ($this->waypoints) {
516
+ foreach ($this->waypoints as $waypoint) {
517
+ $stops->push($waypoint);
518
+ }
519
+ }
520
+
521
+ return $stops->filter();
522
+ }
523
+
524
+ /**
525
+ * Get the pickup location for the payload.
526
+ *
527
+ * @return \Grimzy\LaravelMysqlSpatial\Types\Point
528
+ */
529
+ public function getPickupLocation()
530
+ {
531
+ $pickup = $this->getPickupOrCurrentWaypoint();
532
+
533
+ return $pickup->location ?? new Point(0, 0);
534
+ }
535
+
536
+ public function getOrder()
537
+ {
538
+ if ($this->order) {
539
+ return $this->order;
540
+ }
541
+
542
+ $this->load('order');
543
+
544
+ return $this->order;
545
+ }
546
+
547
+ public function setPlace($property, $place, $save = false)
548
+ {
549
+ if (!$place) {
550
+ return;
551
+ }
552
+
553
+ $attr = $property . '_uuid';
554
+ $instance = Place::createFromMixed($place);
555
+
556
+ if ($instance) {
557
+ if (Str::isUuid($instance)) {
558
+ $this->setAttribute($attr, $instance);
559
+ } elseif ($instance instanceof Model) {
560
+ $this->setAttribute($attr, $instance->uuid);
561
+ } else {
562
+ $this->setAttribute($attr, $instance);
563
+ }
564
+ }
565
+
566
+ if ($save) {
567
+ $this->save();
568
+ }
569
+
570
+ return $this;
571
+ }
572
+
573
+ public function setPickup($place, $save = false)
574
+ {
575
+ // if using the special [driver] value, set the meta `pickup_is_driver_location`
576
+ if ($place === '[driver]') {
577
+ $this->setMeta('pickup_is_driver_location', true);
578
+
579
+ return;
580
+ }
581
+
582
+ return $this->setPlace('pickup', $place, $save);
583
+ }
584
+
585
+ public function setDropoff($place, $save = false)
586
+ {
587
+ return $this->setPlace('dropoff', $place, $save);
588
+ }
589
+
590
+ public function setReturn($place, $save = false)
591
+ {
592
+ return $this->setPlace('return', $place, $save);
593
+ }
594
+
595
+ public function getIsMultipleDropOrderAttribute()
596
+ {
597
+ return $this->waypoints && $this->waypoints->count() > 0;
598
+ }
599
+
600
+ /**
601
+ * Set the first waypoint and update activity.
602
+ *
603
+ * @param array $activity
604
+ * @param \Grimzy\LaravelMysqlSpatial\Types\Point $location
605
+ *
606
+ * @return void
607
+ */
608
+ public function setFirstWaypoint($activity = null, $location = null)
609
+ {
610
+ $destination = null;
611
+
612
+ if ($this->isMultipleDropOrder) {
613
+ $destination = $this->waypoints->first();
614
+ } else {
615
+ $destination = $this->pickup ? $this->pickup : $this->waypoints->first();
616
+ }
617
+
618
+ if (!$destination) {
619
+ return $this;
620
+ }
621
+
622
+ $this->current_waypoint_uuid = $destination->uuid;
623
+ $this->save();
624
+ $this->updateWaypointActivity($activity, $location);
625
+
626
+ return $this->load('currentWaypoint');
627
+ }
628
+
629
+ /**
630
+ * Update the current waypoint activity and it's entities.
631
+ *
632
+ * @param array $activity
633
+ * @param \Grimzy\LaravelMysqlSpatial\Types\Point $location
634
+ * @param \Fleetbase\Models\Proof|string|null $proof resolvable proof of delivery/activity
635
+ *
636
+ * @return $this
637
+ */
638
+ public function updateWaypointActivity($activity = null, $location = null, $proof = null)
639
+ {
640
+ if ($this->isMultipleDropOrder && is_array($activity) && $location) {
641
+ // update activity for the current waypoint
642
+ $currentWaypoint = $this->waypointMarkers->firstWhere('place_uuid', $this->current_waypoint_uuid);
643
+
644
+ if ($currentWaypoint) {
645
+ $currentWaypoint->insertActivity($activity['status'], $activity['details'], $location, $activity['code'], $proof);
646
+ }
647
+
648
+ // update activity for all entities for this destination/waypoint
649
+ $entities = $this->entities->where('destination_uuid', $this->current_waypoint_uuid);
650
+
651
+ foreach ($entities as $entity) {
652
+ $entity->insertActivity($activity['status'], $activity['details'], $location, $activity['code'], $proof);
653
+ }
654
+ }
655
+
656
+ return $this;
657
+ }
658
+
659
+ /**
660
+ * Set the next waypoint in sequence.
661
+ *
662
+ * @return void
663
+ */
664
+ public function setNextWaypointDestination()
665
+ {
666
+ $nextWaypoint = $this->waypointMarkers->filter(function ($waypoint) {
667
+ // dump($waypoint->place->public_id, strtolower($waypoint->status_code));
668
+ return !in_array(strtolower($waypoint->status_code), ['completed', 'canceled']) && $waypoint->place_uuid !== $this->current_waypoint_uuid;
669
+ })->first();
670
+
671
+ if (!$nextWaypoint) {
672
+ return $this;
673
+ }
674
+
675
+ $this->current_waypoint_uuid = $nextWaypoint->place_uuid;
676
+
677
+ if ($this->currentWaypoint) {
678
+ $this->currentWaypoint->refresh();
679
+ }
680
+
681
+ return $this->load('currentWaypoint');
682
+ }
683
+
684
+ public function updateOrderDistanceAndTime(): ?Order
685
+ {
686
+ // load the order
687
+ $this->load(['order']);
688
+
689
+ // get the order
690
+ $order = $this->order;
691
+
692
+ // set google matrix based distance and time
693
+ if ($order instanceof \Fleetbase\FleetOps\Models\Order) {
694
+ return $order->setDistanceAndTime();
695
+ }
696
+
697
+ return null;
698
+ }
699
+ }