@fleetbase/fleetops-engine 0.2.6 → 0.2.8

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 (306) hide show
  1. package/.gitattributes +14 -0
  2. package/.php-cs-fixer.php +29 -0
  3. package/LICENSE.md +16 -4
  4. package/README.md +103 -13
  5. package/composer.json +85 -0
  6. package/extension.json +10 -0
  7. package/package.json +3 -3
  8. package/phpstan.neon.dist +8 -0
  9. package/phpunit.xml.dist +16 -0
  10. package/server/config/api.php +765 -0
  11. package/server/config/cache.stores.php +18 -0
  12. package/server/config/dompdf.php +242 -0
  13. package/server/config/fleetops.php +19 -0
  14. package/server/config/geocoder.php +108 -0
  15. package/server/data/globe.json +261 -0
  16. package/server/migrations/2023_04_27_053456_create_contacts_table.php +49 -0
  17. package/server/migrations/2023_04_27_053456_create_drivers_table.php +62 -0
  18. package/server/migrations/2023_04_27_053456_create_entities_table.php +67 -0
  19. package/server/migrations/2023_04_27_053456_create_fleet_drivers_table.php +39 -0
  20. package/server/migrations/2023_04_27_053456_create_fleets_table.php +47 -0
  21. package/server/migrations/2023_04_27_053456_create_fuel_reports_table.php +50 -0
  22. package/server/migrations/2023_04_27_053456_create_integrated_vendors_table.php +44 -0
  23. package/server/migrations/2023_04_27_053456_create_issues_table.php +53 -0
  24. package/server/migrations/2023_04_27_053456_create_orders_table.php +70 -0
  25. package/server/migrations/2023_04_27_053456_create_payloads_table.php +51 -0
  26. package/server/migrations/2023_04_27_053456_create_places_table.php +62 -0
  27. package/server/migrations/2023_04_27_053456_create_positions_table.php +46 -0
  28. package/server/migrations/2023_04_27_053456_create_proofs_table.php +44 -0
  29. package/server/migrations/2023_04_27_053456_create_purchase_rates_table.php +46 -0
  30. package/server/migrations/2023_04_27_053456_create_routes_table.php +40 -0
  31. package/server/migrations/2023_04_27_053456_create_service_areas_table.php +47 -0
  32. package/server/migrations/2023_04_27_053456_create_service_quote_items_table.php +42 -0
  33. package/server/migrations/2023_04_27_053456_create_service_quotes_table.php +47 -0
  34. package/server/migrations/2023_04_27_053456_create_service_rate_fees_table.php +45 -0
  35. package/server/migrations/2023_04_27_053456_create_service_rate_parcel_fees_table.php +47 -0
  36. package/server/migrations/2023_04_27_053456_create_service_rates_table.php +61 -0
  37. package/server/migrations/2023_04_27_053456_create_tracking_numbers_table.php +46 -0
  38. package/server/migrations/2023_04_27_053456_create_tracking_statuses_table.php +54 -0
  39. package/server/migrations/2023_04_27_053456_create_vehicles_table.php +84 -0
  40. package/server/migrations/2023_04_27_053456_create_vendors_table.php +56 -0
  41. package/server/migrations/2023_04_27_053456_create_waypoints_table.php +45 -0
  42. package/server/migrations/2023_04_27_053456_create_zones_table.php +46 -0
  43. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_companies_table.php +32 -0
  44. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_contacts_table.php +34 -0
  45. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_drivers_table.php +40 -0
  46. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_entities_table.php +40 -0
  47. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_fleet_drivers_table.php +34 -0
  48. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_fleets_table.php +36 -0
  49. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_fuel_reports_table.php +36 -0
  50. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_integrated_vendors_table.php +34 -0
  51. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_issues_table.php +38 -0
  52. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_orders_table.php +48 -0
  53. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_payloads_table.php +40 -0
  54. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_places_table.php +32 -0
  55. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_positions_table.php +36 -0
  56. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_proofs_table.php +34 -0
  57. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_purchase_rates_table.php +38 -0
  58. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_routes_table.php +34 -0
  59. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_service_areas_table.php +34 -0
  60. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_service_quote_items_table.php +32 -0
  61. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_service_quotes_table.php +38 -0
  62. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_service_rate_fees_table.php +32 -0
  63. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_service_rate_parcel_fees_table.php +32 -0
  64. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_service_rates_table.php +36 -0
  65. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_tracking_numbers_table.php +34 -0
  66. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_tracking_statuses_table.php +34 -0
  67. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_vehicles_table.php +36 -0
  68. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_vendors_table.php +40 -0
  69. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_waypoints_table.php +38 -0
  70. package/server/migrations/2023_04_27_053459_add_foreign_keys_to_zones_table.php +34 -0
  71. package/server/migrations/2023_09_14_074512_update_vehicles_table.php +100 -0
  72. package/server/migrations/2023_09_14_074619_create_vehicle_devices_table.php +44 -0
  73. package/server/migrations/2023_09_26_071205_add_online_column_to_vehicles_table.php +32 -0
  74. package/server/migrations/2023_09_26_083957_create_fleet_vehicles_table.php +45 -0
  75. package/server/migrations/2023_09_27_023757_add_column_to_fleets_table.php +46 -0
  76. package/server/migrations/2023_10_05_074811_update_vehicle.php +42 -0
  77. package/server/resources/views/labels/default.php +165 -0
  78. package/server/src/Auth/Schemas/FleetOps.php +75 -0
  79. package/server/src/Casts/MultiPolygon.php +50 -0
  80. package/server/src/Casts/Point.php +109 -0
  81. package/server/src/Casts/Polygon.php +46 -0
  82. package/server/src/Console/Commands/DispatchAdhocOrders.php +137 -0
  83. package/server/src/Console/Commands/DispatchOrders.php +71 -0
  84. package/server/src/Console/Commands/TrackOrderDistanceAndTime.php +62 -0
  85. package/server/src/Events/DriverLocationChanged.php +174 -0
  86. package/server/src/Events/DriverSimulatedLocationChanged.php +183 -0
  87. package/server/src/Events/EntityDriverAssigned.php +36 -0
  88. package/server/src/Events/OrderCanceled.php +15 -0
  89. package/server/src/Events/OrderCompleted.php +15 -0
  90. package/server/src/Events/OrderDispatchFailed.php +42 -0
  91. package/server/src/Events/OrderDispatched.php +15 -0
  92. package/server/src/Events/OrderDriverAssigned.php +15 -0
  93. package/server/src/Events/OrderReady.php +15 -0
  94. package/server/src/Events/OrderStarted.php +15 -0
  95. package/server/src/Exceptions/IntegratedVendorException.php +18 -0
  96. package/server/src/Expansions/UserExpansion.php +63 -0
  97. package/server/src/Exports/ContactExport.php +56 -0
  98. package/server/src/Exports/DriverExport.php +61 -0
  99. package/server/src/Exports/FleetExport.php +53 -0
  100. package/server/src/Exports/PlaceExport.php +55 -0
  101. package/server/src/Exports/ServiceAreaExport.php +58 -0
  102. package/server/src/Exports/VehicleExport.php +57 -0
  103. package/server/src/Exports/VendorExport.php +57 -0
  104. package/server/src/Http/Controllers/Api/v1/ContactController.php +133 -0
  105. package/server/src/Http/Controllers/Api/v1/DriverController.php +691 -0
  106. package/server/src/Http/Controllers/Api/v1/EntityController.php +230 -0
  107. package/server/src/Http/Controllers/Api/v1/FleetController.php +146 -0
  108. package/server/src/Http/Controllers/Api/v1/LabelController.php +63 -0
  109. package/server/src/Http/Controllers/Api/v1/OrderController.php +1114 -0
  110. package/server/src/Http/Controllers/Api/v1/PayloadController.php +195 -0
  111. package/server/src/Http/Controllers/Api/v1/PlaceController.php +333 -0
  112. package/server/src/Http/Controllers/Api/v1/PurchaseRateController.php +199 -0
  113. package/server/src/Http/Controllers/Api/v1/ServiceAreaController.php +133 -0
  114. package/server/src/Http/Controllers/Api/v1/ServiceQuoteController.php +381 -0
  115. package/server/src/Http/Controllers/Api/v1/ServiceRateController.php +223 -0
  116. package/server/src/Http/Controllers/Api/v1/TrackingNumberController.php +146 -0
  117. package/server/src/Http/Controllers/Api/v1/TrackingStatusController.php +138 -0
  118. package/server/src/Http/Controllers/Api/v1/VehicleController.php +191 -0
  119. package/server/src/Http/Controllers/Api/v1/VendorController.php +159 -0
  120. package/server/src/Http/Controllers/Api/v1/ZoneController.php +146 -0
  121. package/server/src/Http/Controllers/FleetOpsController.php +13 -0
  122. package/server/src/Http/Controllers/Internal/v1/ContactController.php +69 -0
  123. package/server/src/Http/Controllers/Internal/v1/DriverController.php +261 -0
  124. package/server/src/Http/Controllers/Internal/v1/EntityController.php +15 -0
  125. package/server/src/Http/Controllers/Internal/v1/FleetController.php +152 -0
  126. package/server/src/Http/Controllers/Internal/v1/FleetOpsLookupController.php +80 -0
  127. package/server/src/Http/Controllers/Internal/v1/FuelReportController.php +15 -0
  128. package/server/src/Http/Controllers/Internal/v1/GeocoderController.php +96 -0
  129. package/server/src/Http/Controllers/Internal/v1/IntegratedVendorController.php +63 -0
  130. package/server/src/Http/Controllers/Internal/v1/IssueController.php +15 -0
  131. package/server/src/Http/Controllers/Internal/v1/LiveController.php +127 -0
  132. package/server/src/Http/Controllers/Internal/v1/MetricsController.php +75 -0
  133. package/server/src/Http/Controllers/Internal/v1/MorphController.php +77 -0
  134. package/server/src/Http/Controllers/Internal/v1/OrderConfigController.php +269 -0
  135. package/server/src/Http/Controllers/Internal/v1/OrderController.php +564 -0
  136. package/server/src/Http/Controllers/Internal/v1/PayloadController.php +15 -0
  137. package/server/src/Http/Controllers/Internal/v1/PlaceController.php +163 -0
  138. package/server/src/Http/Controllers/Internal/v1/ProofController.php +139 -0
  139. package/server/src/Http/Controllers/Internal/v1/PurchaseRateController.php +15 -0
  140. package/server/src/Http/Controllers/Internal/v1/RouteController.php +15 -0
  141. package/server/src/Http/Controllers/Internal/v1/ServiceAreaController.php +32 -0
  142. package/server/src/Http/Controllers/Internal/v1/ServiceQuoteController.php +345 -0
  143. package/server/src/Http/Controllers/Internal/v1/ServiceRateController.php +47 -0
  144. package/server/src/Http/Controllers/Internal/v1/SettingController.php +30 -0
  145. package/server/src/Http/Controllers/Internal/v1/TrackingNumberController.php +15 -0
  146. package/server/src/Http/Controllers/Internal/v1/TrackingStatusController.php +15 -0
  147. package/server/src/Http/Controllers/Internal/v1/VehicleController.php +65 -0
  148. package/server/src/Http/Controllers/Internal/v1/VehicleDeviceController.php +15 -0
  149. package/server/src/Http/Controllers/Internal/v1/VendorController.php +120 -0
  150. package/server/src/Http/Controllers/Internal/v1/ZoneController.php +15 -0
  151. package/server/src/Http/Filter/ContactFilter.php +86 -0
  152. package/server/src/Http/Filter/DriverFilter.php +148 -0
  153. package/server/src/Http/Filter/FleetFilter.php +108 -0
  154. package/server/src/Http/Filter/IntegratedVendorFilter.php +13 -0
  155. package/server/src/Http/Filter/OrderFilter.php +242 -0
  156. package/server/src/Http/Filter/PlaceFilter.php +111 -0
  157. package/server/src/Http/Filter/ServiceAreaFilter.php +13 -0
  158. package/server/src/Http/Filter/ServiceQuoteFilter.php +13 -0
  159. package/server/src/Http/Filter/ServiceRateFilter.php +33 -0
  160. package/server/src/Http/Filter/TrackingStatusFilter.php +43 -0
  161. package/server/src/Http/Filter/VehicleFilter.php +91 -0
  162. package/server/src/Http/Filter/VendorFilter.php +83 -0
  163. package/server/src/Http/Filter/ZoneFilter.php +13 -0
  164. package/server/src/Http/Requests/CancelOrderRequest.php +31 -0
  165. package/server/src/Http/Requests/CreateContactRequest.php +33 -0
  166. package/server/src/Http/Requests/CreateDriverRequest.php +55 -0
  167. package/server/src/Http/Requests/CreateEntityRequest.php +43 -0
  168. package/server/src/Http/Requests/CreateFleetRequest.php +32 -0
  169. package/server/src/Http/Requests/CreateOrderRequest.php +66 -0
  170. package/server/src/Http/Requests/CreatePayloadRequest.php +37 -0
  171. package/server/src/Http/Requests/CreatePlaceRequest.php +38 -0
  172. package/server/src/Http/Requests/CreatePurchaseRateRequest.php +33 -0
  173. package/server/src/Http/Requests/CreateServiceAreaRequest.php +35 -0
  174. package/server/src/Http/Requests/CreateServiceQuoteRequest.php +29 -0
  175. package/server/src/Http/Requests/CreateServiceRateRequest.php +56 -0
  176. package/server/src/Http/Requests/CreateTrackingNumberRequest.php +34 -0
  177. package/server/src/Http/Requests/CreateTrackingStatusRequest.php +42 -0
  178. package/server/src/Http/Requests/CreateVehicleRequest.php +32 -0
  179. package/server/src/Http/Requests/CreateVendorRequest.php +35 -0
  180. package/server/src/Http/Requests/CreateZoneRequest.php +35 -0
  181. package/server/src/Http/Requests/DecodeTrackingNumberQR.php +30 -0
  182. package/server/src/Http/Requests/DriverSimulationRequest.php +46 -0
  183. package/server/src/Http/Requests/Internal/AssignOrderRequest.php +31 -0
  184. package/server/src/Http/Requests/Internal/CreateDriverRequest.php +42 -0
  185. package/server/src/Http/Requests/Internal/FleetActionRequest.php +32 -0
  186. package/server/src/Http/Requests/Internal/UpdateDriverRequest.php +7 -0
  187. package/server/src/Http/Requests/QueryServiceQuotesRequest.php +41 -0
  188. package/server/src/Http/Requests/UpdateContactRequest.php +20 -0
  189. package/server/src/Http/Requests/UpdateDriverRequest.php +7 -0
  190. package/server/src/Http/Requests/UpdateEntityRequest.php +7 -0
  191. package/server/src/Http/Requests/UpdateFleetRequest.php +7 -0
  192. package/server/src/Http/Requests/UpdateOrderRequest.php +7 -0
  193. package/server/src/Http/Requests/UpdatePayloadRequest.php +7 -0
  194. package/server/src/Http/Requests/UpdatePlaceRequest.php +7 -0
  195. package/server/src/Http/Requests/UpdatePurchaseRateRequest.php +7 -0
  196. package/server/src/Http/Requests/UpdateServiceAreaRequest.php +29 -0
  197. package/server/src/Http/Requests/UpdateServiceQuoteRequest.php +29 -0
  198. package/server/src/Http/Requests/UpdateServiceRateRequest.php +29 -0
  199. package/server/src/Http/Requests/UpdateTrackingNumberRequest.php +7 -0
  200. package/server/src/Http/Requests/UpdateTrackingStatusRequest.php +32 -0
  201. package/server/src/Http/Requests/UpdateVehicleRequest.php +7 -0
  202. package/server/src/Http/Requests/UpdateVendorRequest.php +7 -0
  203. package/server/src/Http/Requests/UpdateZoneRequest.php +7 -0
  204. package/server/src/Http/Resources/Internal/v1/IntegratedVendorFacilitator.php +37 -0
  205. package/server/src/Http/Resources/Internal/v1/Vehicle.php +33 -0
  206. package/server/src/Http/Resources/Internal/v1/Waypoint.php +34 -0
  207. package/server/src/Http/Resources/v1/Contact.php +62 -0
  208. package/server/src/Http/Resources/v1/CurrentJob.php +36 -0
  209. package/server/src/Http/Resources/v1/DeletedResource.php +61 -0
  210. package/server/src/Http/Resources/v1/Driver.php +89 -0
  211. package/server/src/Http/Resources/v1/Entity.php +107 -0
  212. package/server/src/Http/Resources/v1/Fleet.php +60 -0
  213. package/server/src/Http/Resources/v1/FuelReport.php +67 -0
  214. package/server/src/Http/Resources/v1/Order.php +131 -0
  215. package/server/src/Http/Resources/v1/Payload.php +94 -0
  216. package/server/src/Http/Resources/v1/Place.php +84 -0
  217. package/server/src/Http/Resources/v1/Proof.php +36 -0
  218. package/server/src/Http/Resources/v1/PurchaseRate.php +77 -0
  219. package/server/src/Http/Resources/v1/ServiceArea.php +55 -0
  220. package/server/src/Http/Resources/v1/ServiceQuote.php +57 -0
  221. package/server/src/Http/Resources/v1/ServiceRate.php +94 -0
  222. package/server/src/Http/Resources/v1/ServiceRateFee.php +58 -0
  223. package/server/src/Http/Resources/v1/ServiceRateParcelFee.php +48 -0
  224. package/server/src/Http/Resources/v1/TrackingNumber.php +62 -0
  225. package/server/src/Http/Resources/v1/TrackingStatus.php +84 -0
  226. package/server/src/Http/Resources/v1/Vehicle.php +75 -0
  227. package/server/src/Http/Resources/v1/VehicleDevice.php +44 -0
  228. package/server/src/Http/Resources/v1/VehicleWithoutDriver.php +72 -0
  229. package/server/src/Http/Resources/v1/Vendor.php +72 -0
  230. package/server/src/Http/Resources/v1/Zone.php +60 -0
  231. package/server/src/Imports/OrdersImport.php +18 -0
  232. package/server/src/Integrations/Lalamove/Lalamove.php +678 -0
  233. package/server/src/Integrations/Lalamove/LalamoveDeliveryStop.php +97 -0
  234. package/server/src/Integrations/Lalamove/LalamoveMarket.php +123 -0
  235. package/server/src/Integrations/Lalamove/LalamoveServiceType.php +161 -0
  236. package/server/src/Jobs/SimulateDrivingRoute.php +81 -0
  237. package/server/src/Jobs/SimulateWaypointReached.php +79 -0
  238. package/server/src/Listeners/HandleOrderCanceled.php +46 -0
  239. package/server/src/Listeners/HandleOrderCreated.php +23 -0
  240. package/server/src/Listeners/HandleOrderDispatchFailed.php +35 -0
  241. package/server/src/Listeners/HandleOrderDispatched.php +108 -0
  242. package/server/src/Listeners/HandleOrderDriverAssigned.php +42 -0
  243. package/server/src/Listeners/HandleOrderReady.php +27 -0
  244. package/server/src/Listeners/HandleUserRemovedFromCompany.php +31 -0
  245. package/server/src/Models/Contact.php +239 -0
  246. package/server/src/Models/Driver.php +543 -0
  247. package/server/src/Models/Entity.php +416 -0
  248. package/server/src/Models/Fleet.php +203 -0
  249. package/server/src/Models/FleetDriver.php +73 -0
  250. package/server/src/Models/FleetVehicle.php +73 -0
  251. package/server/src/Models/FuelReport.php +125 -0
  252. package/server/src/Models/IntegratedVendor.php +219 -0
  253. package/server/src/Models/Issue.php +111 -0
  254. package/server/src/Models/Order.php +1132 -0
  255. package/server/src/Models/Payload.php +699 -0
  256. package/server/src/Models/Place.php +656 -0
  257. package/server/src/Models/Position.php +119 -0
  258. package/server/src/Models/Proof.php +94 -0
  259. package/server/src/Models/PurchaseRate.php +208 -0
  260. package/server/src/Models/Route.php +128 -0
  261. package/server/src/Models/ServiceArea.php +161 -0
  262. package/server/src/Models/ServiceQuote.php +207 -0
  263. package/server/src/Models/ServiceQuoteItem.php +46 -0
  264. package/server/src/Models/ServiceRate.php +953 -0
  265. package/server/src/Models/ServiceRateFee.php +96 -0
  266. package/server/src/Models/ServiceRateParcelFee.php +116 -0
  267. package/server/src/Models/TrackingNumber.php +310 -0
  268. package/server/src/Models/TrackingStatus.php +177 -0
  269. package/server/src/Models/Vehicle.php +452 -0
  270. package/server/src/Models/VehicleDevice.php +79 -0
  271. package/server/src/Models/Vendor.php +244 -0
  272. package/server/src/Models/Waypoint.php +226 -0
  273. package/server/src/Models/Zone.php +95 -0
  274. package/server/src/Notifications/OrderAssigned.php +140 -0
  275. package/server/src/Notifications/OrderCanceled.php +129 -0
  276. package/server/src/Notifications/OrderDispatchFailed.php +81 -0
  277. package/server/src/Notifications/OrderDispatched.php +173 -0
  278. package/server/src/Notifications/OrderPing.php +162 -0
  279. package/server/src/Notifications/OrderSplit.php +56 -0
  280. package/server/src/Observers/DriverObserver.php +34 -0
  281. package/server/src/Observers/OrderObserver.php +34 -0
  282. package/server/src/Observers/PayloadObserver.php +30 -0
  283. package/server/src/Observers/PlaceObserver.php +26 -0
  284. package/server/src/Observers/PurchaseRateObserver.php +61 -0
  285. package/server/src/Observers/ServiceAreaObserver.php +35 -0
  286. package/server/src/Observers/ServiceRateObserver.php +78 -0
  287. package/server/src/Observers/TrackingNumberObserver.php +44 -0
  288. package/server/src/Observers/UserObserver.php +20 -0
  289. package/server/src/Observers/VehicleObserver.php +66 -0
  290. package/server/src/Providers/EventServiceProvider.php +30 -0
  291. package/server/src/Providers/FleetOpsServiceProvider.php +94 -0
  292. package/server/src/Rules/ResolvablePoint.php +37 -0
  293. package/server/src/Scopes/DriverScope.php +21 -0
  294. package/server/src/Support/Algo.php +55 -0
  295. package/server/src/Support/DistanceMatrix.php +27 -0
  296. package/server/src/Support/Encoding/Polyline.php +168 -0
  297. package/server/src/Support/Flow.php +622 -0
  298. package/server/src/Support/Geocoding.php +216 -0
  299. package/server/src/Support/IntegratedVendors.php +287 -0
  300. package/server/src/Support/Metrics.php +305 -0
  301. package/server/src/Support/OSRM.php +191 -0
  302. package/server/src/Support/ParsePhone.php +21 -0
  303. package/server/src/Support/Utils.php +1145 -0
  304. package/server/src/Traits/HasTrackingNumber.php +185 -0
  305. package/server/src/routes.php +381 -0
  306. package/server/tests/Feature.php +5 -0
@@ -0,0 +1,564 @@
1
+ <?php
2
+
3
+ namespace Fleetbase\FleetOps\Http\Controllers\Internal\v1;
4
+
5
+ use Fleetbase\Exceptions\FleetbaseRequestValidationException;
6
+ use Fleetbase\FleetOps\Events\OrderDispatchFailed;
7
+ use Fleetbase\FleetOps\Events\OrderReady;
8
+ use Fleetbase\FleetOps\Events\OrderStarted;
9
+ use Fleetbase\FleetOps\Http\Controllers\FleetOpsController;
10
+ use Fleetbase\FleetOps\Http\Requests\CancelOrderRequest;
11
+ use Fleetbase\FleetOps\Imports\OrdersImport;
12
+ use Fleetbase\FleetOps\Models\Driver;
13
+ use Fleetbase\FleetOps\Models\Entity;
14
+ use Fleetbase\FleetOps\Models\Order;
15
+ use Fleetbase\FleetOps\Models\Payload;
16
+ use Fleetbase\FleetOps\Models\Place;
17
+ use Fleetbase\FleetOps\Models\ServiceQuote;
18
+ use Fleetbase\FleetOps\Models\TrackingStatus;
19
+ use Fleetbase\FleetOps\Models\Waypoint;
20
+ use Fleetbase\FleetOps\Support\Flow;
21
+ use Fleetbase\FleetOps\Support\Utils;
22
+ use Fleetbase\Http\Requests\Internal\BulkDeleteRequest;
23
+ use Fleetbase\Models\File;
24
+ use Fleetbase\Models\Type;
25
+ use Illuminate\Http\Request;
26
+ use Illuminate\Support\Facades\DB;
27
+ use Illuminate\Support\Str;
28
+ use Maatwebsite\Excel\Facades\Excel;
29
+
30
+ class OrderController extends FleetOpsController
31
+ {
32
+ /**
33
+ * The resource to query.
34
+ *
35
+ * @var string
36
+ */
37
+ public $resource = 'order';
38
+
39
+ /**
40
+ * Creates a record with request payload.
41
+ *
42
+ * @param Illuminate\Http\Request $request
43
+ *
44
+ * @return \Illuminate\Http\Response
45
+ */
46
+ public function createRecord(Request $request)
47
+ {
48
+ try {
49
+ $this->validateRequest($request);
50
+
51
+ $record = $this->model->createRecordFromRequest(
52
+ $request,
53
+ function ($request, &$input) {
54
+ $serviceQuote = ServiceQuote::resolveFromRequest($request);
55
+
56
+ // if service quote is applied, resolve it
57
+ if ($serviceQuote instanceof ServiceQuote && $serviceQuote->fromIntegratedVendor()) {
58
+ // create order with integrated vendor, then resume fleetbase order creation
59
+ try {
60
+ $integratedVendorOrder = $serviceQuote->integratedVendor->api()->createOrderFromServiceQuote($serviceQuote, $request);
61
+ } catch (\Exception $e) {
62
+ return response()->error($e->getMessage());
63
+ }
64
+
65
+ $input['integrated_vendor_order'] = $integratedVendorOrder;
66
+ }
67
+ },
68
+ function (&$request, Order &$order, &$requestInput) {
69
+ $input = $request->input('order');
70
+ $isIntegratedVendorOrder = isset($requestInput['integrated_vendor_order']);
71
+ $serviceQuote = ServiceQuote::resolveFromRequest($request);
72
+
73
+ $route = Utils::get($input, 'route');
74
+ $payload = Utils::get($input, 'payload');
75
+ $waypoints = Utils::get($input, 'payload.waypoints');
76
+ $entities = Utils::get($input, 'payload.entities');
77
+
78
+ // save order route & payload with request input
79
+ $order
80
+ ->setRoute($route)
81
+ ->setStatus('created', false)
82
+ ->insertPayload($payload)
83
+ ->insertWaypoints($waypoints)
84
+ ->insertEntities($entities);
85
+
86
+ // if it's integrated vendor order apply to meta
87
+ if ($isIntegratedVendorOrder) {
88
+ $order->updateMeta(
89
+ [
90
+ 'integrated_vendor' => Utils::get($requestInput['integrated_vendor_order'], 'metadata.integrated_vendor'),
91
+ 'integrated_vendor_order' => $requestInput['integrated_vendor_order'],
92
+ ]
93
+ );
94
+ }
95
+
96
+ // notify driver if assigned
97
+ $order->notifyDriverAssigned();
98
+
99
+ // set driving distance and time
100
+ $order->setPreliminaryDistanceAndTime();
101
+
102
+ // if service quote attached purchase
103
+ $order->purchaseServiceQuote($serviceQuote);
104
+
105
+ // dispatch if flagged true
106
+ $order->firstDispatch();
107
+
108
+ // load tracking number
109
+ $order->load(['trackingNumber']);
110
+ }
111
+ );
112
+
113
+ // Trigger order created event
114
+ event(new OrderReady($record));
115
+
116
+ return ['order' => new $this->resource($record)];
117
+ } catch (\Exception $e) {
118
+ return response()->error($e->getMessage());
119
+ } catch (\Illuminate\Database\QueryException $e) {
120
+ return response()->error($e->getMessage());
121
+ } catch (FleetbaseRequestValidationException $e) {
122
+ return response()->error($e->getErrors());
123
+ }
124
+ }
125
+
126
+ /**
127
+ * Process import files (excel,csv) into Fleetbase order data.
128
+ *
129
+ * @return \Illuminate\Http\Response
130
+ */
131
+ public function importFromFiles(Request $request)
132
+ {
133
+ $info = Utils::lookupIp();
134
+ $files = $request->input('files');
135
+ $files = File::whereIn('uuid', $files)->get();
136
+ $country = $request->input('country', Utils::or($info, ['country_name', 'region'], 'Singapore'));
137
+
138
+ $validFileTypes = ['csv', 'tsv', 'xls', 'xlsx'];
139
+ $imports = collect();
140
+
141
+ foreach ($files as $file) {
142
+ // validate file type
143
+ if (!Str::endsWith($file->path, $validFileTypes)) {
144
+ return response()->error('Invalid file uploaded, must be one of the following: ' . implode(', ', $validFileTypes));
145
+ }
146
+
147
+ try {
148
+ $data = Excel::toArray(new OrdersImport(), $file->path, 's3');
149
+ } catch (\Exception $e) {
150
+ return response()->error('Invalid file, unable to proccess.');
151
+ }
152
+
153
+ $imports = $imports->concat($data);
154
+ }
155
+
156
+ $places = collect();
157
+ $entities = collect();
158
+
159
+ foreach ($imports as $rows) {
160
+ foreach ($rows as $row) {
161
+ if (empty($row) || empty(array_values($row))) {
162
+ continue;
163
+ }
164
+
165
+ $importId = (string) Str::uuid();
166
+ $place = Place::createFromImportRow($row, $importId, $country);
167
+
168
+ if (!$place) {
169
+ continue;
170
+ }
171
+
172
+ $places[] = $place;
173
+
174
+ $items = Utils::or($row, ['items', 'entities', 'packages', 'passengers', 'products', 'services']);
175
+ $itemsDelimiter = Utils::findDelimiterFromString($items, '|');
176
+ $items = is_string($items) ? explode($itemsDelimiter, $items) : [];
177
+
178
+ foreach ($items as $itemName) {
179
+ $entity = new Entity(['name' => $itemName]);
180
+ $entity->setAttribute('destination_uuid', $place->uuid);
181
+ $entity->setAttribute('_import_id', $importId);
182
+ $entity->setMetas($place->getMeta());
183
+ $entities[] = $entity;
184
+ }
185
+ }
186
+ }
187
+
188
+ return response()->json(
189
+ [
190
+ 'entities' => $entities,
191
+ 'places' => $places,
192
+ ]
193
+ );
194
+ }
195
+
196
+ /**
197
+ * Updates a order to canceled and updates order activity.
198
+ *
199
+ * @return \Illuminate\Http\Response
200
+ */
201
+ public function bulkDelete(BulkDeleteRequest $request)
202
+ {
203
+ $ids = $request->input('ids', []);
204
+
205
+ if (!$ids) {
206
+ return response()->error('Nothing to delete.');
207
+ }
208
+
209
+ /** @var \Fleetbase\Models\Order */
210
+ $count = Order::whereIn('uuid', $ids)->count();
211
+ $deleted = Order::whereIn('uuid', $ids)->delete();
212
+
213
+ if (!$deleted) {
214
+ return response()->error('Failed to bulk delete orders.');
215
+ }
216
+
217
+ return response()->json(
218
+ [
219
+ 'status' => 'OK',
220
+ 'message' => 'Deleted ' . $count . ' orders',
221
+ ],
222
+ 200
223
+ );
224
+ }
225
+
226
+ /**
227
+ * Updates a order to canceled and updates order activity.
228
+ *
229
+ * @return \Illuminate\Http\Response
230
+ */
231
+ public function bulkCancel(BulkDeleteRequest $request)
232
+ {
233
+ /** @var \Fleetbase\Models\Order */
234
+ $orders = Order::whereIn('uuid', $request->input('ids'))->get();
235
+
236
+ $count = $orders->count();
237
+
238
+ foreach ($orders as $order) {
239
+ if ($order->status === 'canceled') {
240
+ continue;
241
+ }
242
+
243
+ $trackingStatusExists = TrackingStatus::where(['tracking_number_uuid' => $order->tracking_number_uuid, 'code' => 'CANCELED'])->exists();
244
+
245
+ if ($trackingStatusExists) {
246
+ continue;
247
+ }
248
+
249
+ $order->cancel();
250
+ }
251
+
252
+ return response()->json(
253
+ [
254
+ 'status' => 'OK',
255
+ 'message' => 'Canceled ' . $count . ' orders',
256
+ ]
257
+ );
258
+ }
259
+
260
+ /**
261
+ * Updates a order to canceled and updates order activity.
262
+ *
263
+ * @param \Fleetbase\Http\Requests\CancelOrderRequest $request
264
+ *
265
+ * @return \Illuminate\Http\Response
266
+ */
267
+ public function cancel(CancelOrderRequest $request)
268
+ {
269
+ /** @var \Fleetbase\Models\Order */
270
+ $order = Order::where('uuid', $request->input('order'))->first();
271
+
272
+ $order->cancel();
273
+
274
+ return response()->json(
275
+ [
276
+ 'status' => 'OK',
277
+ 'message' => 'Order was canceled',
278
+ 'order' => $order->uuid,
279
+ ]
280
+ );
281
+ }
282
+
283
+ /**
284
+ * Dispatches an order.
285
+ *
286
+ * @return \Illuminate\Http\Response
287
+ */
288
+ public function dispatchOrder(Request $request)
289
+ {
290
+ /**
291
+ * @var \Fleetbase\Models\Order
292
+ */
293
+ $order = Order::select(['uuid', 'driver_assigned_uuid', 'adhoc', 'dispatched', 'dispatched_at'])->where('uuid', $request->input('order'))->withoutGlobalScopes()->first();
294
+
295
+ if (!$order->hasDriverAssigned && !$order->adhoc) {
296
+ return response()->error('No driver assigned to dispatch!');
297
+ }
298
+
299
+ if ($order->dispatched) {
300
+ return response()->error('Order has already been dispatched!');
301
+ }
302
+
303
+ $order->dispatch();
304
+
305
+ return response()->json(
306
+ [
307
+ 'status' => 'OK',
308
+ 'message' => 'Order was dispatched',
309
+ 'order' => $order->uuid,
310
+ ]
311
+ );
312
+ }
313
+
314
+ /**
315
+ * Internal request for driver to start order.
316
+ *
317
+ * @return \Illuminate\Http\Response
318
+ */
319
+ public function start(Request $request)
320
+ {
321
+ /**
322
+ * @var \Fleetbase\Models\Order
323
+ */
324
+ $order = Order::where('uuid', $request->input('order'))->withoutGlobalScopes()->first();
325
+
326
+ if (!$order) {
327
+ return response()->error('Unable to find order to start.');
328
+ }
329
+
330
+ if ($order->started) {
331
+ return response()->error('Order has already been started.');
332
+ }
333
+
334
+ /**
335
+ * @var \Fleetbase\FleetOps\Models\Driver
336
+ */
337
+ $driver = Driver::where('uuid', $order->driver_assigned_uuid)->withoutGlobalScopes()->first();
338
+
339
+ /**
340
+ * @var \Fleetbase\FleetOps\Models\Payload
341
+ */
342
+ $payload = Payload::where('uuid', $order->payload_uuid)->withoutGlobalScopes()->with(['waypoints', 'waypointMarkers', 'entities'])->first();
343
+
344
+ if (!$driver) {
345
+ return response()->error('No driver assigned to order.');
346
+ }
347
+
348
+ // set order to started
349
+ $order->started = true;
350
+ $order->started_at = now();
351
+ $order->save();
352
+
353
+ // trigger start event
354
+ event(new OrderStarted($order));
355
+
356
+ // set order as drivers current order
357
+ $driver->current_job_uuid = $order->uuid;
358
+ $driver->save();
359
+
360
+ // get the next order activity
361
+ $flow = $activity = Flow::getNextActivity($order);
362
+
363
+ /**
364
+ * @var \Grimzy\LaravelMysqlSpatial\Types\Point
365
+ */
366
+ $location = $order->getLastLocation();
367
+
368
+ // if multi drop order set first destination
369
+ if ($payload->isMultipleDropOrder) {
370
+ $firstDestination = $payload->waypoints->first();
371
+
372
+ if ($firstDestination) {
373
+ $payload->current_waypoint_uuid = $firstDestination->uuid;
374
+ $payload->save();
375
+ }
376
+
377
+ // update activity for each waypoint and entity
378
+ foreach ($payload->waypointMarkers as $waypointMarker) {
379
+ $waypointMarker->insertActivity($activity['status'], $activity['details'], $location, $activity['code']);
380
+ }
381
+
382
+ foreach ($payload->entities as $entity) {
383
+ $entity->insertActivity($activity['status'], $activity['details'], $location, $activity['code']);
384
+ }
385
+ }
386
+
387
+ // update order activity
388
+ $updateActivityRequest = new Request(['activity' => $flow]);
389
+
390
+ // update activity
391
+ return $this->updateActivity($order->uuid, $updateActivityRequest);
392
+ }
393
+
394
+ /**
395
+ * Update an order activity.
396
+ *
397
+ * @return \Illuminate\Http\Response
398
+ */
399
+ public function updateActivity(string $id, Request $request)
400
+ {
401
+ $order = Order::withoutGlobalScopes()
402
+ ->where('uuid', $id)
403
+ ->with(['driverAssigned'])
404
+ ->whereNull('deleted_at')
405
+ ->orWhere('public_id', $id)
406
+ ->with(['payload.entities'])
407
+ ->first();
408
+
409
+ if (!$order) {
410
+ return response()->error('No order found.');
411
+ }
412
+
413
+ $activity = $request->input('activity');
414
+
415
+ // handle pickup/dropoff order activity update as normal
416
+ if (is_array($activity) && $activity['code'] === 'dispatched') {
417
+ // make sure driver is assigned if not trigger failed dispatch
418
+ if (!$order->hasDriverAssigned && !$order->adhoc) {
419
+ event(new OrderDispatchFailed($order, 'No driver assigned for order to dispatch to.'));
420
+
421
+ return response()->error('No driver assigned for order to dispatch to.');
422
+ }
423
+
424
+ $order->dispatch();
425
+
426
+ return response()->json(['status' => 'dispatched']);
427
+ }
428
+
429
+ if (is_array($activity) && $activity['code'] === 'completed' && $order->driverAssigned) {
430
+ // unset from driver current job
431
+ $order->driverAssigned->unassignCurrentOrder();
432
+ $order->notifyCompleted();
433
+ }
434
+
435
+ /**
436
+ * @var \Grimzy\LaravelMysqlSpatial\Types\Point
437
+ */
438
+ $location = $order->getLastLocation();
439
+
440
+ $order->setStatus($activity['code']);
441
+ $order->insertActivity($activity['status'], $activity['details'], $location, $activity['code']);
442
+
443
+ // also update for each order entities if not multiple drop order
444
+ // all entities will share the same activity status as is one drop order
445
+ if (!$order->payload->isMultipleDropOrder) {
446
+ foreach ($order->payload->entities as $entity) {
447
+ $entity->insertActivity($activity['status'], $activity['details'], $location, $activity['code']);
448
+ }
449
+ }
450
+
451
+ return response()->json(['status' => 'ok']);
452
+ }
453
+
454
+ /**
455
+ * Finds and responds with the orders next activity update based on the orders configuration.
456
+ *
457
+ * @return \Illuminate\Http\Response
458
+ */
459
+ public function nextActivity(string $id, Request $request)
460
+ {
461
+ $order = Order::withoutGlobalScopes()
462
+ ->where('uuid', $id)
463
+ ->orWhere('public_id', $id)
464
+ ->first();
465
+
466
+ if (!$order) {
467
+ return response()->error('No order found.');
468
+ }
469
+
470
+ $flow = Flow::getOrderFlow($order);
471
+
472
+ return response()->json($flow);
473
+ }
474
+
475
+ /**
476
+ * Get all status options for an order.
477
+ *
478
+ * @return \Illuminate\Http\Response
479
+ */
480
+ public function statuses()
481
+ {
482
+ $statuses = DB::table('orders')
483
+ ->select('status')
484
+ ->where('company_uuid', session('company'))
485
+ ->distinct()
486
+ ->get()
487
+ ->pluck('status')
488
+ ->filter();
489
+
490
+ return response()->json($statuses);
491
+ }
492
+
493
+ /**
494
+ * Get all order type options.
495
+ *
496
+ * @return \Illuminate\Http\Response
497
+ */
498
+ public function types()
499
+ {
500
+ $defaultTypes = collect(config('api.types.order', []))->map(
501
+ function ($attributes) {
502
+ return new Type($attributes);
503
+ }
504
+ );
505
+ $customTypes = Type::where('for', 'order')->get();
506
+
507
+ $results = collect([...$customTypes, ...$defaultTypes])
508
+ ->unique('key')
509
+ ->values();
510
+
511
+ return response()->json($results);
512
+ }
513
+
514
+ /**
515
+ * Sends back the PDF stream for an order label file.
516
+ *
517
+ * @return void
518
+ */
519
+ public function label(string $publicId, Request $request)
520
+ {
521
+ $format = $request->input('format', 'stream');
522
+ $type = $request->input('type', strtok($publicId, '_'));
523
+ $subject = null;
524
+
525
+ switch ($type) {
526
+ case 'order':
527
+ $subject = Order::where('public_id', $publicId)->orWhere('uuid', $publicId)->withoutGlobalScopes()->first();
528
+ break;
529
+
530
+ case 'waypoint':
531
+ $subject = Waypoint::where('public_id', $publicId)->orWhere('uuid', $publicId)->withoutGlobalScopes()->first();
532
+ break;
533
+
534
+ case 'entity':
535
+ $subject = Entity::where('public_id', $publicId)->orWhere('uuid', $publicId)->withoutGlobalScopes()->first();
536
+ break;
537
+ }
538
+
539
+ if (!$subject) {
540
+ return response()->error('Unable to render label.');
541
+ }
542
+
543
+ switch ($format) {
544
+ case 'pdf':
545
+ case 'stream':
546
+ default:
547
+ $stream = $subject->pdfLabelStream();
548
+
549
+ return $stream;
550
+
551
+ case 'text':
552
+ $text = $subject->pdfLabel()->output();
553
+
554
+ return response()->make($text);
555
+
556
+ case 'base64':
557
+ $base64 = base64_encode($subject->pdfLabel()->output());
558
+
559
+ return response()->json(['data' => mb_convert_encoding($base64, 'UTF-8', 'UTF-8')]);
560
+ }
561
+
562
+ return response()->error('Unable to render label.');
563
+ }
564
+ }
@@ -0,0 +1,15 @@
1
+ <?php
2
+
3
+ namespace Fleetbase\FleetOps\Http\Controllers\Internal\v1;
4
+
5
+ use Fleetbase\FleetOps\Http\Controllers\FleetOpsController;
6
+
7
+ class PayloadController extends FleetOpsController
8
+ {
9
+ /**
10
+ * The resource to query.
11
+ *
12
+ * @var string
13
+ */
14
+ public $resource = 'payload';
15
+ }