@fleetbase/fleetops-engine 0.6.57 → 0.6.59
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.
- package/README.md +3 -0
- package/addon/components/customer/form.hbs +0 -49
- package/addon/components/entity/card.hbs +1 -0
- package/addon/components/modals/order-label.hbs +1 -1
- package/addon/components/place/form.hbs +1 -1
- package/addon/services/entity-actions.js +32 -0
- package/addon/styles/fleetops-engine.css +0 -1
- package/composer.json +15 -3
- package/extension.json +1 -1
- package/index.js +7 -1
- package/package.json +3 -2
- package/phpunit.xml.dist +4 -4
- package/pnpm-workspace.yaml +2 -1
- package/scripts/coverage-file-runner.php +240 -0
- package/scripts/coverage-runner.php +52 -0
- package/scripts/coverage-summary.php +149 -0
- package/scripts/pest-bootstrap.php +411 -0
- package/scripts/pest-file-runner.php +94 -0
- package/scripts/pest-runner.php +119 -0
- package/server/resources/views/labels/entity-label.php +4 -4
- package/server/src/Casts/MultiPolygon.php +8 -3
- package/server/src/Casts/OrderConfigEntities.php +10 -3
- package/server/src/Casts/Point.php +10 -6
- package/server/src/Casts/Polygon.php +5 -2
- package/server/src/Console/Commands/AssignCustomerRoles.php +28 -6
- package/server/src/Console/Commands/AssignDriverRoles.php +36 -6
- package/server/src/Console/Commands/AuditCustomerUserConflicts.php +6 -1
- package/server/src/Console/Commands/DispatchAdhocOrders.php +12 -2
- package/server/src/Console/Commands/FixCustomerCompanies.php +46 -11
- package/server/src/Console/Commands/FixDriverCompanies.php +18 -3
- package/server/src/Console/Commands/FixLegacyOrderConfigs.php +31 -6
- package/server/src/Console/Commands/ProcessMaintenanceTriggers.php +94 -42
- package/server/src/Console/Commands/PurgeUnpurchasedServiceQuotes.php +42 -12
- package/server/src/Console/Commands/ReplayVehicleLocations.php +120 -55
- package/server/src/Console/Commands/SendDriverNotification.php +25 -4
- package/server/src/Console/Commands/SendMaintenanceReminders.php +43 -23
- package/server/src/Console/Commands/SimulateOrderRouteNavigation.php +36 -6
- package/server/src/Console/Commands/TrackOrderDistanceAndTime.php +6 -1
- package/server/src/Events/DriverLocationChanged.php +1 -1
- package/server/src/Events/DriverSimulatedLocationChanged.php +1 -1
- package/server/src/Events/EntityActivityChanged.php +1 -1
- package/server/src/Events/EntityCompleted.php +1 -1
- package/server/src/Events/EntityDriverAssigned.php +1 -1
- package/server/src/Events/FuelProviderTransactionImported.php +1 -1
- package/server/src/Events/FuelProviderTransactionMatched.php +1 -1
- package/server/src/Events/FuelProviderTransactionUnmatched.php +1 -1
- package/server/src/Events/FuelReportCreatedFromProvider.php +1 -1
- package/server/src/Events/GeofenceDwelled.php +1 -1
- package/server/src/Events/GeofenceEntered.php +1 -1
- package/server/src/Events/GeofenceExited.php +1 -1
- package/server/src/Events/VehicleLocationChanged.php +1 -1
- package/server/src/Events/WaypointActivityChanged.php +1 -1
- package/server/src/Events/WaypointCompleted.php +1 -1
- package/server/src/Exceptions/IntegratedVendorException.php +2 -2
- package/server/src/Exceptions/TelematicRateLimitExceededException.php +1 -1
- package/server/src/Http/Controllers/Api/v1/ContactController.php +89 -22
- package/server/src/Http/Controllers/Api/v1/CustomerController.php +296 -97
- package/server/src/Http/Controllers/Api/v1/DeviceController.php +48 -14
- package/server/src/Http/Controllers/Api/v1/DriverController.php +168 -63
- package/server/src/Http/Controllers/Api/v1/EntityController.php +112 -66
- package/server/src/Http/Controllers/Api/v1/EquipmentController.php +40 -10
- package/server/src/Http/Controllers/Api/v1/FleetController.php +54 -14
- package/server/src/Http/Controllers/Api/v1/FuelReportController.php +54 -14
- package/server/src/Http/Controllers/Api/v1/FuelTransactionController.php +36 -11
- package/server/src/Http/Controllers/Api/v1/GeofenceController.php +39 -21
- package/server/src/Http/Controllers/Api/v1/IssueController.php +54 -14
- package/server/src/Http/Controllers/Api/v1/LabelController.php +61 -22
- package/server/src/Http/Controllers/Api/v1/NavigatorController.php +21 -5
- package/server/src/Http/Controllers/Api/v1/OrderConfigController.php +35 -5
- package/server/src/Http/Controllers/Api/v1/OrderController.php +388 -203
- package/server/src/Http/Controllers/Api/v1/PartController.php +40 -10
- package/server/src/Http/Controllers/Api/v1/PayloadController.php +90 -30
- package/server/src/Http/Controllers/Api/v1/PlaceController.php +188 -91
- package/server/src/Http/Controllers/Api/v1/PurchaseRateController.php +100 -36
- package/server/src/Http/Controllers/Api/v1/ServiceAreaController.php +96 -26
- package/server/src/Http/Controllers/Api/v1/ServiceQuoteController.php +169 -81
- package/server/src/Http/Controllers/Api/v1/ServiceRateController.php +104 -75
- package/server/src/Http/Controllers/Api/v1/TrackingNumberController.php +83 -14
- package/server/src/Http/Controllers/Api/v1/TrackingStatusController.php +66 -16
- package/server/src/Http/Controllers/Api/v1/VehicleController.php +121 -67
- package/server/src/Http/Controllers/Api/v1/VendorController.php +54 -14
- package/server/src/Http/Controllers/Api/v1/WorkOrderController.php +47 -12
- package/server/src/Http/Controllers/Api/v1/ZoneController.php +84 -24
- package/server/src/Http/Controllers/Internal/v1/AnalyticsController.php +15 -5
- package/server/src/Http/Controllers/Internal/v1/ContactController.php +113 -28
- package/server/src/Http/Controllers/Internal/v1/CustomerController.php +36 -11
- package/server/src/Http/Controllers/Internal/v1/DeviceController.php +9 -4
- package/server/src/Http/Controllers/Internal/v1/DriverController.php +167 -69
- package/server/src/Http/Controllers/Internal/v1/EquipmentController.php +18 -3
- package/server/src/Http/Controllers/Internal/v1/FleetController.php +137 -60
- package/server/src/Http/Controllers/Internal/v1/FleetOpsLookupController.php +24 -9
- package/server/src/Http/Controllers/Internal/v1/FuelReportController.php +18 -3
- package/server/src/Http/Controllers/Internal/v1/GeocoderController.php +26 -8
- package/server/src/Http/Controllers/Internal/v1/GettingStartedController.php +12 -2
- package/server/src/Http/Controllers/Internal/v1/IntegratedVendorController.php +27 -6
- package/server/src/Http/Controllers/Internal/v1/IssueController.php +82 -29
- package/server/src/Http/Controllers/Internal/v1/MaintenanceController.php +34 -26
- package/server/src/Http/Controllers/Internal/v1/MaintenanceScheduleController.php +141 -97
- package/server/src/Http/Controllers/Internal/v1/ManifestController.php +28 -8
- package/server/src/Http/Controllers/Internal/v1/MetricsController.php +21 -12
- package/server/src/Http/Controllers/Internal/v1/MorphController.php +90 -18
- package/server/src/Http/Controllers/Internal/v1/NavigatorController.php +88 -35
- package/server/src/Http/Controllers/Internal/v1/OrchestrationController.php +149 -39
- package/server/src/Http/Controllers/Internal/v1/OrderConfigController.php +54 -18
- package/server/src/Http/Controllers/Internal/v1/OrderController.php +298 -86
- package/server/src/Http/Controllers/Internal/v1/PartController.php +18 -3
- package/server/src/Http/Controllers/Internal/v1/PaymentController.php +46 -14
- package/server/src/Http/Controllers/Internal/v1/PlaceController.php +31 -5
- package/server/src/Http/Controllers/Internal/v1/ProofController.php +88 -48
- package/server/src/Http/Controllers/Internal/v1/SearchController.php +1 -1
- package/server/src/Http/Controllers/Internal/v1/SensorController.php +6 -1
- package/server/src/Http/Controllers/Internal/v1/ServiceAreaController.php +6 -1
- package/server/src/Http/Controllers/Internal/v1/ServiceQuoteController.php +255 -105
- package/server/src/Http/Controllers/Internal/v1/SettingController.php +88 -35
- package/server/src/Http/Controllers/Internal/v1/TelematicController.php +1 -4
- package/server/src/Http/Controllers/Internal/v1/Traits/DriverSchedulingTrait.php +42 -14
- package/server/src/Http/Controllers/Internal/v1/VendorController.php +103 -33
- package/server/src/Http/Controllers/Internal/v1/WorkOrderController.php +42 -12
- package/server/src/Http/Filter/DriverFilter.php +2 -2
- package/server/src/Http/Filter/OrderFilter.php +1 -1
- package/server/src/Http/Filter/VehicleFilter.php +21 -7
- package/server/src/Http/Middleware/AuthenticateCustomerToken.php +12 -2
- package/server/src/Http/Requests/BulkDispatchRequest.php +3 -9
- package/server/src/Http/Requests/CancelOrderRequest.php +2 -6
- package/server/src/Http/Requests/CreateContactRequest.php +2 -6
- package/server/src/Http/Requests/CreateDeviceRequest.php +2 -2
- package/server/src/Http/Requests/CreateDriverRequest.php +3 -9
- package/server/src/Http/Requests/CreateEntityRequest.php +2 -6
- package/server/src/Http/Requests/CreateEquipmentRequest.php +2 -2
- package/server/src/Http/Requests/CreateFleetRequest.php +2 -6
- package/server/src/Http/Requests/CreateFuelReportRequest.php +2 -6
- package/server/src/Http/Requests/CreateFuelTransactionRequest.php +2 -2
- package/server/src/Http/Requests/CreateIssueRequest.php +2 -6
- package/server/src/Http/Requests/CreateOrderRequest.php +7 -8
- package/server/src/Http/Requests/CreatePartRequest.php +2 -2
- package/server/src/Http/Requests/CreatePayloadRequest.php +7 -9
- package/server/src/Http/Requests/CreatePlaceRequest.php +2 -6
- package/server/src/Http/Requests/CreatePurchaseRateRequest.php +2 -6
- package/server/src/Http/Requests/CreateSensorRequest.php +2 -2
- package/server/src/Http/Requests/CreateServiceAreaRequest.php +2 -6
- package/server/src/Http/Requests/CreateServiceQuoteRequest.php +2 -6
- package/server/src/Http/Requests/CreateServiceRateRequest.php +2 -6
- package/server/src/Http/Requests/CreateTrackingNumberRequest.php +2 -6
- package/server/src/Http/Requests/CreateTrackingStatusRequest.php +2 -6
- package/server/src/Http/Requests/CreateVehicleRequest.php +2 -6
- package/server/src/Http/Requests/CreateVendorRequest.php +2 -6
- package/server/src/Http/Requests/CreateWorkOrderRequest.php +2 -2
- package/server/src/Http/Requests/CreateZoneRequest.php +2 -6
- package/server/src/Http/Requests/DecodeTrackingNumberQR.php +2 -6
- package/server/src/Http/Requests/DriverSimulationRequest.php +2 -6
- package/server/src/Http/Requests/Internal/AssignOrderRequest.php +3 -7
- package/server/src/Http/Requests/Internal/CreateDriverRequest.php +4 -12
- package/server/src/Http/Requests/Internal/CreateOrderConfigRequest.php +2 -6
- package/server/src/Http/Requests/Internal/CreateOrderRequest.php +7 -8
- package/server/src/Http/Requests/Internal/FleetActionRequest.php +18 -12
- package/server/src/Http/Requests/Internal/UpdateDriverRequest.php +6 -3
- package/server/src/Http/Requests/QueryServiceQuotesRequest.php +2 -6
- package/server/src/Http/Requests/ScheduleOrderRequest.php +2 -6
- package/server/src/Http/Requests/UpdateIssueRequest.php +1 -3
- package/server/src/Http/Resources/v1/Customer.php +2 -2
- package/server/src/Http/Resources/v1/Maintenance.php +3 -4
- package/server/src/Http/Resources/v1/MaintenanceSchedule.php +3 -4
- package/server/src/Http/Resources/v1/Order.php +3 -7
- package/server/src/Http/Resources/v1/PurchaseRate.php +4 -6
- package/server/src/Http/Resources/v1/TrackingStatus.php +4 -6
- package/server/src/Http/Resources/v1/WorkOrder.php +3 -4
- package/server/src/Imports/ContactImport.php +10 -1
- package/server/src/Imports/DriverImport.php +10 -1
- package/server/src/Imports/EquipmentImport.php +6 -1
- package/server/src/Imports/FleetImport.php +10 -1
- package/server/src/Imports/FuelReportImport.php +10 -1
- package/server/src/Imports/IssueImport.php +10 -1
- package/server/src/Imports/MaintenanceImport.php +6 -1
- package/server/src/Imports/MaintenanceScheduleImport.php +6 -1
- package/server/src/Imports/PartImport.php +6 -1
- package/server/src/Imports/PlaceImport.php +10 -1
- package/server/src/Imports/VehicleImport.php +10 -1
- package/server/src/Imports/VendorImport.php +10 -1
- package/server/src/Imports/WorkOrderImport.php +6 -1
- package/server/src/Integrations/Lalamove/Lalamove.php +3 -7
- package/server/src/Integrations/Lalamove/LalamoveServiceType.php +5 -8
- package/server/src/Jobs/CheckGeofenceDwell.php +41 -16
- package/server/src/Jobs/FinalizeApiOrderCreation.php +17 -2
- package/server/src/Jobs/FinalizeInternalOrderCreation.php +11 -1
- package/server/src/Jobs/NotifyBulkAssignedDriver.php +29 -16
- package/server/src/Jobs/ProcessAllocationJob.php +59 -25
- package/server/src/Jobs/ReplayPositions.php +17 -10
- package/server/src/Jobs/SendPositionReplay.php +18 -7
- package/server/src/Jobs/SimulateDrivingRoute.php +14 -3
- package/server/src/Jobs/SyncFuelProviderTransactionsJob.php +12 -2
- package/server/src/Listeners/HandleDeliveryCompletion.php +11 -1
- package/server/src/Listeners/HandleGeofenceDwelled.php +6 -1
- package/server/src/Listeners/HandleGeofenceEntered.php +4 -2
- package/server/src/Listeners/HandleGeofenceExited.php +6 -1
- package/server/src/Listeners/HandleOrderCanceled.php +18 -3
- package/server/src/Listeners/HandleOrderDispatchFailed.php +12 -2
- package/server/src/Listeners/HandleOrderDispatched.php +61 -26
- package/server/src/Listeners/HandleOrderDriverAssigned.php +12 -2
- package/server/src/Listeners/HandleUserRemovedFromCompany.php +19 -6
- package/server/src/Listeners/NotifyDriverOnShiftChange.php +24 -4
- package/server/src/Listeners/NotifyOrderEvent.php +11 -6
- package/server/src/Models/Contact.php +6 -7
- package/server/src/Models/Device.php +26 -3
- package/server/src/Models/Driver.php +0 -6
- package/server/src/Models/Entity.php +4 -4
- package/server/src/Models/Equipment.php +1 -1
- package/server/src/Models/FuelReport.php +5 -1
- package/server/src/Models/IntegratedVendor.php +2 -2
- package/server/src/Models/Issue.php +5 -1
- package/server/src/Models/MaintenanceSchedule.php +25 -10
- package/server/src/Models/Order.php +18 -15
- package/server/src/Models/OrderConfig.php +1 -1
- package/server/src/Models/Payload.php +9 -16
- package/server/src/Models/Place.php +20 -13
- package/server/src/Models/ServiceArea.php +3 -6
- package/server/src/Models/ServiceQuote.php +5 -0
- package/server/src/Models/ServiceRate.php +13 -6
- package/server/src/Models/Telematic.php +2 -2
- package/server/src/Models/TrackingNumber.php +55 -10
- package/server/src/Models/TrackingStatus.php +24 -4
- package/server/src/Models/Waypoint.php +44 -10
- package/server/src/Models/Zone.php +3 -6
- package/server/src/Notifications/DriverArrivedAtGeofence.php +1 -1
- package/server/src/Notifications/OrderDispatched.php +3 -9
- package/server/src/Notifications/OrderPing.php +3 -9
- package/server/src/Observers/CategoryObserver.php +6 -1
- package/server/src/Observers/CompanyObserver.php +5 -0
- package/server/src/Observers/CompanyUserObserver.php +12 -2
- package/server/src/Observers/DriverObserver.php +19 -4
- package/server/src/Observers/FleetObserver.php +6 -1
- package/server/src/Observers/PurchaseRateObserver.php +66 -11
- package/server/src/Observers/ServiceAreaObserver.php +12 -2
- package/server/src/Observers/ServiceRateObserver.php +21 -6
- package/server/src/Observers/TrackingNumberObserver.php +19 -4
- package/server/src/Observers/UserObserver.php +6 -1
- package/server/src/Observers/VehicleObserver.php +27 -7
- package/server/src/Observers/WorkOrderObserver.php +27 -7
- package/server/src/Orchestration/Engines/DriverAssignmentEngine.php +8 -3
- package/server/src/Orchestration/Support/OrchestrationPayloadBuilder.php +5 -3
- package/server/src/Providers/FleetOpsServiceProvider.php +12 -0
- package/server/src/Providers/NotificationServiceProvider.php +6 -0
- package/server/src/Support/Ai/Capabilities/AssetStatusCapability.php +36 -26
- package/server/src/Support/Ai/Capabilities/CreateOrderPreviewCapability.php +18 -5
- package/server/src/Support/Ai/Capabilities/OrderInsightsCapability.php +6 -1
- package/server/src/Support/Ai/Capabilities/SearchResourcesCapability.php +26 -6
- package/server/src/Support/Analytics/FuelEfficiency.php +9 -3
- package/server/src/Support/Analytics/FuelProviderSummary.php +14 -5
- package/server/src/Support/Analytics/GeofenceViolations.php +40 -20
- package/server/src/Support/Analytics/IssuesInsights.php +38 -18
- package/server/src/Support/Analytics/MaintenanceOverview.php +51 -21
- package/server/src/Support/Analytics/OnTimeDelivery.php +3 -2
- package/server/src/Support/Analytics/OperationsPulse.php +59 -35
- package/server/src/Support/Analytics/OrdersByStatus.php +12 -7
- package/server/src/Support/Analytics/RevenueTrend.php +16 -6
- package/server/src/Support/Analytics/TopDrivers.php +3 -2
- package/server/src/Support/FleetOps.php +109 -104
- package/server/src/Support/Geocoding.php +52 -14
- package/server/src/Support/GeofenceIntersectionService.php +47 -27
- package/server/src/Support/LiveOrderQuery.php +6 -1
- package/server/src/Support/Metrics/ActiveRevenueQuery.php +3 -2
- package/server/src/Support/Metrics/FuelCostsMetric.php +6 -1
- package/server/src/Support/ResolvesOrderServiceStops.php +10 -0
- package/server/src/Support/Telematics/Providers/GeotabProvider.php +9 -4
- package/server/src/Support/Utils.php +122 -16
- package/server/src/Tracking/Providers/GoogleRoutesTrackingProvider.php +6 -1
- package/server/src/Tracking/Providers/OsrmTrackingProvider.php +11 -6
- package/server/src/Tracking/TrackingOptions.php +6 -1
- package/server/src/Tracking/TrackingProviderManager.php +2 -3
- package/server/src/Tracking/TrackingProviderRegistry.php +8 -4
- package/server/src/Traits/PayloadAccessors.php +6 -1
- package/server/src/routes.php +23 -27
- package/server/tests/AiOperationalQueryCapabilityTest.php +457 -1
- package/server/tests/AiPreviewCapabilityContractsTest.php +180 -0
- package/server/tests/AnalyticsRoutesTest.php +384 -3
- package/server/tests/AnalyticsWidgetContractsTest.php +740 -0
- package/server/tests/ApiContactControllerContractsTest.php +284 -0
- package/server/tests/ApiCustomerControllerContractsTest.php +962 -0
- package/server/tests/ApiDriverControllerContractsTest.php +571 -0
- package/server/tests/ApiEntityControllerContractsTest.php +329 -0
- package/server/tests/ApiEquipmentControllerContractsTest.php +239 -0
- package/server/tests/ApiFleetControllerContractsTest.php +176 -0
- package/server/tests/ApiFuelReportControllerContractsTest.php +217 -0
- package/server/tests/ApiIssueControllerContractsTest.php +217 -0
- package/server/tests/ApiOrderControllerContractsTest.php +1030 -0
- package/server/tests/ApiPartControllerContractsTest.php +251 -0
- package/server/tests/ApiPayloadControllerContractsTest.php +314 -0
- package/server/tests/ApiPlaceControllerContractsTest.php +541 -0
- package/server/tests/ApiPurchaseRateControllerContractsTest.php +283 -0
- package/server/tests/ApiServiceAreaZoneControllerContractsTest.php +442 -0
- package/server/tests/ApiServiceQuoteControllerContractsTest.php +322 -0
- package/server/tests/ApiTrackingNumberControllerContractsTest.php +225 -0
- package/server/tests/ApiTrackingStatusControllerContractsTest.php +254 -0
- package/server/tests/ApiVehicleControllerContractsTest.php +368 -0
- package/server/tests/ApiVendorControllerContractsTest.php +199 -0
- package/server/tests/AssetAndPlaceSearchContractsTest.php +220 -0
- package/server/tests/BackendSmallModelContractsTest.php +354 -0
- package/server/tests/CapacityAllocationEngineTest.php +56 -0
- package/server/tests/CommandContractsTest.php +2695 -0
- package/server/tests/CompactResourceSerializationTest.php +2745 -0
- package/server/tests/ControllerFilterContractsTest.php +1273 -0
- package/server/tests/ControllerHelperContractsTest.php +1740 -0
- package/server/tests/ControllerSerializationContractsTest.php +141 -0
- package/server/tests/CoverageSummaryScriptTest.php +93 -0
- package/server/tests/CustomerContactIdentitySafetyTest.php +1 -6
- package/server/tests/CustomerEndpointTest.php +166 -1
- package/server/tests/DriverFilterExecutionTest.php +263 -0
- package/server/tests/DriverGeofenceProcessingTest.php +153 -0
- package/server/tests/DriverResourceSerializationTest.php +245 -0
- package/server/tests/DriverSchedulingTraitContractsTest.php +259 -0
- package/server/tests/EventContractsTest.php +1259 -0
- package/server/tests/ExceptionContractsTest.php +81 -0
- package/server/tests/ExpansionContractsTest.php +242 -0
- package/server/tests/ExportCoverageTest.php +116 -0
- package/server/tests/Feature/Http/Api/ContactControllerPhotoAndDeleteTest.php +199 -0
- package/server/tests/Feature/Http/Api/CustomerControllerHelperSeamsTest.php +831 -0
- package/server/tests/Feature/Http/Api/DeviceControllerContractsTest.php +347 -0
- package/server/tests/Feature/Http/Api/DeviceControllerCrudTest.php +176 -0
- package/server/tests/Feature/Http/Api/DriverControllerAuthFlowsTest.php +451 -0
- package/server/tests/Feature/Http/Api/DriverControllerHelpersTest.php +240 -0
- package/server/tests/Feature/Http/Api/DriverControllerLookupTest.php +186 -0
- package/server/tests/Feature/Http/Api/DriverControllerOrganizationsTest.php +112 -0
- package/server/tests/Feature/Http/Api/DriverControllerSessionHelpersTest.php +207 -0
- package/server/tests/Feature/Http/Api/DriverControllerSwitchOrgAndGeofenceTest.php +329 -0
- package/server/tests/Feature/Http/Api/DriverControllerTrackTest.php +383 -0
- package/server/tests/Feature/Http/Api/EntityControllerHelpersTest.php +150 -0
- package/server/tests/Feature/Http/Api/FuelTransactionControllerContractsTest.php +352 -0
- package/server/tests/Feature/Http/Api/GeofenceControllerContractsTest.php +364 -0
- package/server/tests/Feature/Http/Api/LabelControllerSubjectsTest.php +148 -0
- package/server/tests/Feature/Http/Api/OrderConfigControllerTest.php +112 -0
- package/server/tests/Feature/Http/Api/OrderControllerCreateTest.php +279 -0
- package/server/tests/Feature/Http/Api/OrderControllerIntegratedVendorTest.php +295 -0
- package/server/tests/Feature/Http/Api/OrderControllerLifecycleActionsTest.php +279 -0
- package/server/tests/Feature/Http/Api/OrderControllerLookupHelpersTest.php +207 -0
- package/server/tests/Feature/Http/Api/OrderControllerNearbyFiltersTest.php +282 -0
- package/server/tests/Feature/Http/Api/OrderControllerPersistenceHelpersTest.php +216 -0
- package/server/tests/Feature/Http/Api/OrderControllerQueryFiltersTest.php +184 -0
- package/server/tests/Feature/Http/Api/OrderControllerStartActivityTest.php +663 -0
- package/server/tests/Feature/Http/Api/PayloadControllerHelpersTest.php +134 -0
- package/server/tests/Feature/Http/Api/PlaceAndServiceQuoteSeamsTest.php +479 -0
- package/server/tests/Feature/Http/Api/PurchaseRateControllerHelpersTest.php +176 -0
- package/server/tests/Feature/Http/Api/PurchaseRateControllerOrderCreationTest.php +268 -0
- package/server/tests/Feature/Http/Api/SensorControllerCrudTest.php +239 -0
- package/server/tests/Feature/Http/Api/ServiceAreaControllerBorderAndSeamsTest.php +187 -0
- package/server/tests/Feature/Http/Api/ServiceQuoteControllerQueryTest.php +405 -0
- package/server/tests/Feature/Http/Api/ServiceQuoteControllerVendorBridgeTest.php +212 -0
- package/server/tests/Feature/Http/Api/ServiceRateControllerContractsTest.php +263 -0
- package/server/tests/Feature/Http/Api/SmallApiControllerHelpersTest.php +272 -0
- package/server/tests/Feature/Http/Api/TrackingNumberControllerHelpersTest.php +154 -0
- package/server/tests/Feature/Http/Api/TrackingStatusControllerHelpersTest.php +165 -0
- package/server/tests/Feature/Http/Api/VehicleControllerTrackingTest.php +483 -0
- package/server/tests/Feature/Http/Api/WorkOrderControllerContractsTest.php +326 -0
- package/server/tests/Feature/Http/Api/WorkOrderControllerHelpersTest.php +130 -0
- package/server/tests/Feature/Http/Api/ZoneControllerBordersAndSeamsTest.php +294 -0
- package/server/tests/Feature/Http/FleetOpsRouteRegistrationTest.php +189 -0
- package/server/tests/Feature/Http/Internal/AnalyticsControllerSeamsTest.php +53 -0
- package/server/tests/Feature/Http/Internal/ContactControllerContractsTest.php +240 -0
- package/server/tests/Feature/Http/Internal/ContactControllerCustomerGuardsTest.php +128 -0
- package/server/tests/Feature/Http/Internal/ContactControllerEndpointsTest.php +294 -0
- package/server/tests/Feature/Http/Internal/CustomerControllerCredentialsTest.php +196 -0
- package/server/tests/Feature/Http/Internal/DeviceControllerContractsTest.php +370 -0
- package/server/tests/Feature/Http/Internal/DeviceControllerExportAndFiltersTest.php +151 -0
- package/server/tests/Feature/Http/Internal/DriverControllerContractsTest.php +1109 -0
- package/server/tests/Feature/Http/Internal/DriverControllerCreateRecordTest.php +233 -0
- package/server/tests/Feature/Http/Internal/DriverControllerExistingUserAdoptionTest.php +710 -0
- package/server/tests/Feature/Http/Internal/DriverControllerHelpersTest.php +218 -0
- package/server/tests/Feature/Http/Internal/FleetAssignmentsAndTriggersTest.php +198 -0
- package/server/tests/Feature/Http/Internal/FleetOpsLookupControllerDbTest.php +90 -0
- package/server/tests/Feature/Http/Internal/HubControllerTest.php +206 -0
- package/server/tests/Feature/Http/Internal/IssueControllerContractsTest.php +404 -0
- package/server/tests/Feature/Http/Internal/IssueControllerExportImportTest.php +118 -0
- package/server/tests/Feature/Http/Internal/LiveControllerEndpointsTest.php +246 -0
- package/server/tests/Feature/Http/Internal/LiveControllerTest.php +778 -0
- package/server/tests/Feature/Http/Internal/MaintenanceScheduleControllerContractsTest.php +263 -0
- package/server/tests/Feature/Http/Internal/MaintenanceScheduleControllerSurfacesTest.php +214 -0
- package/server/tests/Feature/Http/Internal/MetricsControllerContractsTest.php +249 -0
- package/server/tests/Feature/Http/Internal/MetricsControllerHelpersTest.php +66 -0
- package/server/tests/Feature/Http/Internal/MorphControllerHelpersTest.php +125 -0
- package/server/tests/Feature/Http/Internal/NavigatorControllerHelpersTest.php +201 -0
- package/server/tests/Feature/Http/Internal/OrchestrationControllerContractsTest.php +928 -0
- package/server/tests/Feature/Http/Internal/OrchestrationControllerHelpersTest.php +214 -0
- package/server/tests/Feature/Http/Internal/OrchestrationControllerImportOrdersTest.php +340 -0
- package/server/tests/Feature/Http/Internal/OrderConfigControllerContractsTest.php +314 -0
- package/server/tests/Feature/Http/Internal/OrderControllerActivityFlowsTest.php +663 -0
- package/server/tests/Feature/Http/Internal/OrderControllerCapturePhotoTest.php +507 -0
- package/server/tests/Feature/Http/Internal/OrderControllerContractsTest.php +1742 -0
- package/server/tests/Feature/Http/Internal/OrderControllerCreateRecordTest.php +488 -0
- package/server/tests/Feature/Http/Internal/OrderControllerHelperSeamsTest.php +298 -0
- package/server/tests/Feature/Http/Internal/OrderControllerHelpersTest.php +267 -0
- package/server/tests/Feature/Http/Internal/OrderControllerImportFromFilesTest.php +179 -0
- package/server/tests/Feature/Http/Internal/OrderControllerUpstreamNotFoundTest.php +80 -0
- package/server/tests/Feature/Http/Internal/PaymentControllerPaymentsTest.php +154 -0
- package/server/tests/Feature/Http/Internal/PlaceControllerTest.php +252 -0
- package/server/tests/Feature/Http/Internal/PositionControllerReplayMetricsTest.php +163 -0
- package/server/tests/Feature/Http/Internal/ProofControllerContractsTest.php +219 -0
- package/server/tests/Feature/Http/Internal/SearchControllerEndpointTest.php +151 -0
- package/server/tests/Feature/Http/Internal/ServiceQuoteControllerHelpersTest.php +208 -0
- package/server/tests/Feature/Http/Internal/ServiceQuoteControllerQueryRecordTest.php +217 -0
- package/server/tests/Feature/Http/Internal/ServiceQuoteControllerVendorBridgeTest.php +239 -0
- package/server/tests/Feature/Http/Internal/ServiceQuotePreliminaryQueryTest.php +271 -0
- package/server/tests/Feature/Http/Internal/SettingControllerHelpersTest.php +133 -0
- package/server/tests/Feature/Http/Internal/SmallInternalControllersTest.php +180 -0
- package/server/tests/Feature/Http/Internal/TelematicControllerEndpointsTest.php +417 -0
- package/server/tests/Feature/Http/Internal/VehicleControllerEndpointsTest.php +361 -0
- package/server/tests/Feature/Http/Internal/VendorControllerEndpointsTest.php +203 -0
- package/server/tests/Feature/Http/Internal/WorkOrderAndConfigSurfacesTest.php +289 -0
- package/server/tests/Feature/Http/Internal/WorkOrderControllerContractsTest.php +199 -0
- package/server/tests/Feature/Http/TelematicWebhookIngestTest.php +343 -0
- package/server/tests/Feature/Http/Telematics/TelematicWebhookControllerProcessingTest.php +254 -0
- package/server/tests/FleetOpsSupportContractsTest.php +187 -0
- package/server/tests/FlespiProviderContractsTest.php +244 -0
- package/server/tests/FlowResourceTest.php +295 -0
- package/server/tests/FuelProviderConnectionControllerContractsTest.php +303 -0
- package/server/tests/FuelProviderImplementationTest.php +753 -0
- package/server/tests/FuelProviderRegistryTest.php +7 -9
- package/server/tests/FuelProviderResourceContractsTest.php +171 -0
- package/server/tests/FuelProviderTransactionControllerContractsTest.php +181 -0
- package/server/tests/GeofenceIntersectionServiceContractsTest.php +164 -0
- package/server/tests/HOSConstraintContractsTest.php +128 -0
- package/server/tests/HubAndGettingStartedContractsTest.php +158 -0
- package/server/tests/ImportContractsTest.php +191 -0
- package/server/tests/InternalCustomerControllerContractsTest.php +238 -0
- package/server/tests/InternalFleetControllerContractsTest.php +389 -0
- package/server/tests/InternalImportExportControllerContractsTest.php +289 -0
- package/server/tests/InternalMetricsControllerContractsTest.php +69 -0
- package/server/tests/InternalPlaceWorkOrderControllerContractsTest.php +207 -0
- package/server/tests/InternalServiceQuoteCheckoutControllerContractsTest.php +470 -0
- package/server/tests/InternalVendorControllerContractsTest.php +331 -0
- package/server/tests/InventoryTelemetryModelContractsTest.php +516 -0
- package/server/tests/IssueTimelineContractsTest.php +191 -0
- package/server/tests/LabelPdfRenderingTest.php +57 -0
- package/server/tests/LalamoveIntegrationContractsTest.php +167 -0
- package/server/tests/LiveOrderQueryTest.php +140 -19
- package/server/tests/LookupAndGeocoderControllerContractsTest.php +357 -0
- package/server/tests/MaintainableTraitContractsTest.php +245 -0
- package/server/tests/MaintenanceScheduleControllerContractsTest.php +101 -0
- package/server/tests/MaintenanceWarrantyContractsTest.php +237 -0
- package/server/tests/ManifestControllerContractsTest.php +310 -0
- package/server/tests/MetricsRegistryTest.php +596 -10
- package/server/tests/MiddlewareContractsTest.php +150 -0
- package/server/tests/ModelAccessorContractsTest.php +3201 -0
- package/server/tests/MorphControllerContractsTest.php +410 -0
- package/server/tests/NavigatorControllerContractsTest.php +206 -0
- package/server/tests/NotificationAndMailContractsTest.php +677 -0
- package/server/tests/ObserverContractsTest.php +1414 -0
- package/server/tests/OperationalAlgorithmContractsTest.php +852 -0
- package/server/tests/OperationsMonitorEndpointTest.php +2 -1
- package/server/tests/OrchestrationPayloadBuilderTest.php +87 -0
- package/server/tests/OrderActivityFlowRegressionTest.php +354 -7
- package/server/tests/OrderDispatchListenerContractsTest.php +577 -0
- package/server/tests/OrderFilterExecutionTest.php +244 -0
- package/server/tests/OrderQueuedClosureRegressionTest.php +2 -1
- package/server/tests/PaymentControllerContractsTest.php +199 -0
- package/server/tests/PointResolutionTest.php +54 -0
- package/server/tests/ProcessAllocationJobContractsTest.php +224 -0
- package/server/tests/ProofAndSensorControllerContractsTest.php +44 -0
- package/server/tests/ProviderContractsTest.php +409 -0
- package/server/tests/PublicApiControllerInputContractsTest.php +294 -0
- package/server/tests/QueueJobContractsTest.php +764 -0
- package/server/tests/ReportSchemaContractsTest.php +271 -0
- package/server/tests/RequestContractsTest.php +966 -0
- package/server/tests/RouteRegistrationExecutionTest.php +178 -0
- package/server/tests/RouteSequencingEngineTest.php +179 -0
- package/server/tests/RulesAndCastsTest.php +246 -0
- package/server/tests/SamsaraProviderContractsTest.php +272 -0
- package/server/tests/SearchControllerContractsTest.php +311 -0
- package/server/tests/ServiceAreaZoneApiShapeTest.php +8 -9
- package/server/tests/ServiceRateAlgorithmWeightVariablesTest.php +1 -1
- package/server/tests/ServiceRateRouteValidationTest.php +76 -0
- package/server/tests/SettingControllerContractsTest.php +410 -0
- package/server/tests/SmallControllerContractsTest.php +456 -0
- package/server/tests/SupportAnalyticsCustomerAuthContractsTest.php +221 -0
- package/server/tests/SupportJobAndAiCoverageTest.php +812 -0
- package/server/tests/SupportServiceContractsTest.php +287 -0
- package/server/tests/SupportValueObjectsTest.php +155 -0
- package/server/tests/TelematicControllerContractsTest.php +185 -0
- package/server/tests/TelematicProviderRegistryTest.php +167 -0
- package/server/tests/TelematicServiceHelperContractsTest.php +315 -0
- package/server/tests/TelematicWebhookControllerContractsTest.php +253 -0
- package/server/tests/TelematicsHardeningTest.php +666 -105
- package/server/tests/TrackingIntelligenceTest.php +709 -26
- package/server/tests/TrackingNumberTraitContractsTest.php +106 -0
- package/server/tests/Unit/Casts/SpatialCastBranchesTest.php +75 -0
- package/server/tests/Unit/Console/AssignCustomerRolesCommandTest.php +102 -0
- package/server/tests/Unit/Console/AssignDriverRolesCommandTest.php +113 -0
- package/server/tests/Unit/Console/Commands/FixLegacyOrderConfigsHelpersTest.php +108 -0
- package/server/tests/Unit/Console/Commands/ProcessOperationalAlertsCommandTest.php +265 -0
- package/server/tests/Unit/Console/Commands/ReplayVehicleLocationsCommandTest.php +320 -0
- package/server/tests/Unit/Console/Commands/SimulateGeofenceEventsCommandTest.php +207 -0
- package/server/tests/Unit/Console/FixCommandsAndMaintenanceControllerTest.php +256 -0
- package/server/tests/Unit/Console/FleetOpsCommandsTest.php +198 -0
- package/server/tests/Unit/Console/ReplayVehicleLocationsCommandTest.php +252 -0
- package/server/tests/Unit/Console/SendMaintenanceRemindersTest.php +212 -0
- package/server/tests/Unit/Console/SimulateGeofenceEventsCommandTest.php +232 -0
- package/server/tests/Unit/Console/SyncTelematicsCommandTest.php +136 -0
- package/server/tests/Unit/Constraints/HOSConstraintTest.php +158 -0
- package/server/tests/Unit/Events/EventModelRecordTest.php +93 -0
- package/server/tests/Unit/Events/OrderDispatchFailedTest.php +34 -0
- package/server/tests/Unit/Exports/ExportCollectionsTest.php +142 -0
- package/server/tests/Unit/Exports/OperationalExportMappingTest.php +651 -0
- package/server/tests/Unit/Exports/VehicleExportTest.php +284 -0
- package/server/tests/Unit/Flow/EventFiringTest.php +95 -0
- package/server/tests/Unit/Http/Api/QueryWithRequestSeamsTest.php +198 -0
- package/server/tests/Unit/Http/Api/SensorInputTest.php +95 -0
- package/server/tests/Unit/Http/Filter/DeviceFilterTest.php +199 -0
- package/server/tests/Unit/Http/Filter/EmptyValueGuardsTest.php +66 -0
- package/server/tests/Unit/Http/Filter/FilterDateRangesTest.php +72 -0
- package/server/tests/Unit/Http/Filter/FuelProviderTransactionFilterTest.php +172 -0
- package/server/tests/Unit/Http/Filter/InternalRelationUuidLookupTest.php +135 -0
- package/server/tests/Unit/Http/Filter/IssueFilterTest.php +129 -0
- package/server/tests/Unit/Http/Filter/PartFilterTest.php +173 -0
- package/server/tests/Unit/Http/Internal/ControllerDelegationSeamsTest.php +136 -0
- package/server/tests/Unit/Http/Internal/ControllerExcelSeamsTest.php +89 -0
- package/server/tests/Unit/Http/Middleware/SetupDriverSessionTest.php +32 -0
- package/server/tests/Unit/Http/Requests/CreateFuelReportRequestTest.php +47 -0
- package/server/tests/Unit/Http/Requests/FleetActionRequestTest.php +80 -0
- package/server/tests/Unit/Http/Requests/RequestAuthorizationTest.php +50 -0
- package/server/tests/Unit/Http/Resources/CustomerResourceTest.php +108 -0
- package/server/tests/Unit/Http/Resources/EntityCustomerTypeTest.php +35 -0
- package/server/tests/Unit/Http/Resources/FleetResourceTest.php +102 -0
- package/server/tests/Unit/Http/Resources/IndexOrderResourceTest.php +210 -0
- package/server/tests/Unit/Http/Resources/IndexVehicleResourceTest.php +194 -0
- package/server/tests/Unit/Http/Resources/MaintenanceResourcesTest.php +182 -0
- package/server/tests/Unit/Http/Resources/OrderAndDriverResourceTest.php +121 -0
- package/server/tests/Unit/Http/Resources/OrderConfigResourceTest.php +47 -0
- package/server/tests/Unit/Http/Resources/PayloadResourceTest.php +111 -0
- package/server/tests/Unit/Http/Resources/RelationResourceFallbacksTest.php +32 -0
- package/server/tests/Unit/Http/Resources/ResourceRelationResolutionTest.php +55 -0
- package/server/tests/Unit/Http/Resources/TrackingNumberResourceTest.php +174 -0
- package/server/tests/Unit/Http/Resources/WaypointResourceTest.php +295 -0
- package/server/tests/Unit/Http/Resources/WorkOrderResourceTest.php +164 -0
- package/server/tests/Unit/Imports/ImportDelegationTest.php +151 -0
- package/server/tests/Unit/Integrations/Lalamove/LalamoveDeliveryStopTest.php +79 -0
- package/server/tests/Unit/Integrations/Lalamove/LalamoveLifecycleTest.php +211 -0
- package/server/tests/Unit/Integrations/Lalamove/LalamoveQuoteAndServiceOrderTest.php +381 -0
- package/server/tests/Unit/Integrations/Lalamove/LalamoveServiceTypeTest.php +51 -0
- package/server/tests/Unit/Integrations/LalamoveQuotationTest.php +194 -0
- package/server/tests/Unit/Integrations/LalamoveResponseHandlingTest.php +58 -0
- package/server/tests/Unit/Jobs/GeofenceDwellAndBulkNotifyTest.php +183 -0
- package/server/tests/Unit/Jobs/ReplayPositionsTest.php +57 -0
- package/server/tests/Unit/Jobs/SimulateWaypointReachedTest.php +92 -0
- package/server/tests/Unit/Listeners/HandleGeofenceEnteredTest.php +256 -0
- package/server/tests/Unit/Listeners/HandleOrderDispatchFailedListenerTest.php +101 -0
- package/server/tests/Unit/Listeners/HandleOrderDispatchedConcreteTest.php +203 -0
- package/server/tests/Unit/Listeners/HandleOrderDispatchedHelpersTest.php +186 -0
- package/server/tests/Unit/Listeners/HandleUserRemovedFromCompanyTest.php +65 -0
- package/server/tests/Unit/Listeners/ListenerDelegationSeamsTest.php +83 -0
- package/server/tests/Unit/Models/AssetTest.php +469 -0
- package/server/tests/Unit/Models/ContactCustomerUserTest.php +370 -0
- package/server/tests/Unit/Models/ContactTest.php +577 -0
- package/server/tests/Unit/Models/DeviceEventTest.php +481 -0
- package/server/tests/Unit/Models/DeviceLastPositionDefaultTest.php +128 -0
- package/server/tests/Unit/Models/DriverModelHelpersTest.php +268 -0
- package/server/tests/Unit/Models/DriverTest.php +401 -0
- package/server/tests/Unit/Models/EntityTest.php +171 -0
- package/server/tests/Unit/Models/EquipmentTest.php +434 -0
- package/server/tests/Unit/Models/FleetTest.php +153 -0
- package/server/tests/Unit/Models/FuelProviderTransactionTest.php +82 -0
- package/server/tests/Unit/Models/FuelReportImportAndLabelsTest.php +193 -0
- package/server/tests/Unit/Models/ImportRowFallbackSeamsTest.php +100 -0
- package/server/tests/Unit/Models/IntegratedVendorLifecycleTest.php +203 -0
- package/server/tests/Unit/Models/IntegratedVendorTest.php +135 -0
- package/server/tests/Unit/Models/IssueTest.php +160 -0
- package/server/tests/Unit/Models/MaintenanceScheduleTest.php +319 -0
- package/server/tests/Unit/Models/MaintenanceTest.php +277 -0
- package/server/tests/Unit/Models/MaintenanceWorkOrderImportTest.php +161 -0
- package/server/tests/Unit/Models/ManifestStopTest.php +121 -0
- package/server/tests/Unit/Models/ManifestTest.php +163 -0
- package/server/tests/Unit/Models/ModelLookupFallbackSeamsTest.php +149 -0
- package/server/tests/Unit/Models/OrderConfigTest.php +341 -0
- package/server/tests/Unit/Models/OrderDynamicContractsTest.php +190 -0
- package/server/tests/Unit/Models/OrderPayloadConfigAndDistanceTest.php +426 -0
- package/server/tests/Unit/Models/OrderPayloadRouteTest.php +227 -0
- package/server/tests/Unit/Models/OrderPurchaseAndDriversTest.php +188 -0
- package/server/tests/Unit/Models/OrderTest.php +917 -0
- package/server/tests/Unit/Models/PartTest.php +399 -0
- package/server/tests/Unit/Models/PayloadTest.php +710 -0
- package/server/tests/Unit/Models/PayloadWaypointsAndEntitiesTest.php +317 -0
- package/server/tests/Unit/Models/PlaceCreationAndImportTest.php +384 -0
- package/server/tests/Unit/Models/PlaceGeocodingResultsTest.php +253 -0
- package/server/tests/Unit/Models/PlaceSharedAndGeocodingTest.php +271 -0
- package/server/tests/Unit/Models/PlaceTest.php +589 -0
- package/server/tests/Unit/Models/PositionTest.php +49 -0
- package/server/tests/Unit/Models/RouteTest.php +55 -0
- package/server/tests/Unit/Models/SensorReadingsTest.php +168 -0
- package/server/tests/Unit/Models/SensorTest.php +284 -0
- package/server/tests/Unit/Models/ServiceAreaGeometryTest.php +129 -0
- package/server/tests/Unit/Models/ServiceAreaTest.php +125 -0
- package/server/tests/Unit/Models/ServiceQuoteTest.php +617 -0
- package/server/tests/Unit/Models/ServiceRateFeeTest.php +73 -0
- package/server/tests/Unit/Models/ServiceRatePersistenceAndServicabilityTest.php +428 -0
- package/server/tests/Unit/Models/ServiceRateTest.php +533 -0
- package/server/tests/Unit/Models/SmallModelSurfacesTest.php +294 -0
- package/server/tests/Unit/Models/TrackingNumberTest.php +199 -0
- package/server/tests/Unit/Models/TrackingStatusTest.php +131 -0
- package/server/tests/Unit/Models/VehicleDeviceTest.php +115 -0
- package/server/tests/Unit/Models/VehiclePositionsAndImportTest.php +220 -0
- package/server/tests/Unit/Models/VehicleTest.php +266 -0
- package/server/tests/Unit/Models/VendorRelationsAndImportTest.php +107 -0
- package/server/tests/Unit/Models/WarrantyTest.php +187 -0
- package/server/tests/Unit/Models/WaypointTest.php +366 -0
- package/server/tests/Unit/Models/WorkOrderTest.php +272 -0
- package/server/tests/Unit/Models/ZoneTest.php +83 -0
- package/server/tests/Unit/Notifications/MonitoringNotificationsTest.php +136 -0
- package/server/tests/Unit/Notifications/OrderAssignedChannelsTest.php +53 -0
- package/server/tests/Unit/Notifications/OrderDispatchedChannelsTest.php +81 -0
- package/server/tests/Unit/Notifications/OrderFailedChannelsTest.php +73 -0
- package/server/tests/Unit/Notifications/OrderPingChannelsTest.php +69 -0
- package/server/tests/Unit/Notifications/TerminalOrderNotificationsTest.php +185 -0
- package/server/tests/Unit/Observers/FleetOpsCompanyUserAndServiceAreaObserversTest.php +133 -0
- package/server/tests/Unit/Observers/ObserverHelperExecutionTest.php +135 -0
- package/server/tests/Unit/Observers/ObserverListenerSeamsTest.php +267 -0
- package/server/tests/Unit/Observers/PurchaseRateObserverAndOrderJobsTest.php +169 -0
- package/server/tests/Unit/Orchestration/Engines/DriverAssignmentEngineTest.php +393 -0
- package/server/tests/Unit/Orchestration/Engines/VroomOrchestrationEngineLifecycleTest.php +397 -0
- package/server/tests/Unit/Orchestration/OrchestrationEngineRegistryTest.php +45 -0
- package/server/tests/Unit/Orchestration/VroomEngineTransportAndSettingsTest.php +253 -0
- package/server/tests/Unit/Providers/FleetOpsAiRegistrationTest.php +59 -0
- package/server/tests/Unit/Rules/ResolvableVehicleTest.php +85 -0
- package/server/tests/Unit/Support/Ai/AssetStatusCapabilityQueriesTest.php +120 -0
- package/server/tests/Unit/Support/Ai/Capabilities/CreateOrderPreviewCapabilityTest.php +385 -0
- package/server/tests/Unit/Support/Ai/Capabilities/OrderInsightsCapabilityTest.php +226 -0
- package/server/tests/Unit/Support/Ai/Capabilities/SearchResourcesCapabilityTest.php +237 -0
- package/server/tests/Unit/Support/AiCapabilityPermissionsTest.php +124 -0
- package/server/tests/Unit/Support/AlgoEdgeBranchesTest.php +24 -0
- package/server/tests/Unit/Support/Analytics/GeofenceViolationsTest.php +109 -0
- package/server/tests/Unit/Support/Analytics/LiveFleetTest.php +205 -0
- package/server/tests/Unit/Support/Analytics/MaintenanceOverviewTest.php +236 -0
- package/server/tests/Unit/Support/Analytics/OnTimeDeliveryAndTopDriversTest.php +250 -0
- package/server/tests/Unit/Support/CreateOrderPreviewDraftingTest.php +235 -0
- package/server/tests/Unit/Support/CustomerAuthTest.php +132 -0
- package/server/tests/Unit/Support/FuelEfficiencyAndCanceledHandlersTest.php +164 -0
- package/server/tests/Unit/Support/FuelProviderRegistryResolutionTest.php +51 -0
- package/server/tests/Unit/Support/FuelProviderServiceMatchingTest.php +280 -0
- package/server/tests/Unit/Support/GeocodingInjectedClientTest.php +268 -0
- package/server/tests/Unit/Support/GeocodingLocateTest.php +32 -0
- package/server/tests/Unit/Support/GeofenceIntersectionServiceTest.php +188 -0
- package/server/tests/Unit/Support/GettingStartedTest.php +164 -0
- package/server/tests/Unit/Support/GuardReturnSeamsTest.php +172 -0
- package/server/tests/Unit/Support/IntegratedVendorsResolverTest.php +250 -0
- package/server/tests/Unit/Support/IssuesInsightsAndAllocationJobTest.php +156 -0
- package/server/tests/Unit/Support/MagicAccessorSeamsTest.php +54 -0
- package/server/tests/Unit/Support/MaintainableAndOperationalAlertsTest.php +215 -0
- package/server/tests/Unit/Support/Metrics/AvgOrderValueMetricTest.php +308 -0
- package/server/tests/Unit/Support/Metrics/CountMetricsTest.php +280 -0
- package/server/tests/Unit/Support/Metrics/FuelCostsMetricTest.php +102 -0
- package/server/tests/Unit/Support/Metrics/MetricQuerySeamsTest.php +129 -0
- package/server/tests/Unit/Support/Metrics/OrdersScheduledMetricTest.php +146 -0
- package/server/tests/Unit/Support/MoreQuerySeamsTest.php +410 -0
- package/server/tests/Unit/Support/OperationalQueryDistributionTest.php +152 -0
- package/server/tests/Unit/Support/OperationsPulseTest.php +130 -0
- package/server/tests/Unit/Support/OptimizeOrderRouteCapabilityTest.php +147 -0
- package/server/tests/Unit/Support/OrchestrationPayloadBuilderTest.php +135 -0
- package/server/tests/Unit/Support/OrchestrationRouteAndVehicleTasksTest.php +254 -0
- package/server/tests/Unit/Support/OsrmProofAndIssueFilterTest.php +247 -0
- package/server/tests/Unit/Support/PetroAppFuelProviderTest.php +165 -0
- package/server/tests/Unit/Support/PlaceSearchRankingTest.php +191 -0
- package/server/tests/Unit/Support/QuerySeamsTest.php +309 -0
- package/server/tests/Unit/Support/ResolvesOrderServiceStopsDbTest.php +303 -0
- package/server/tests/Unit/Support/ResolvesOrderServiceStopsTest.php +382 -0
- package/server/tests/Unit/Support/SkipAndFallbackGuardsTest.php +70 -0
- package/server/tests/Unit/Support/TelematicCredentialResolutionTest.php +31 -0
- package/server/tests/Unit/Support/TelematicServiceTest.php +256 -0
- package/server/tests/Unit/Support/Telematics/Providers/AbstractProviderTest.php +154 -0
- package/server/tests/Unit/Support/Telematics/Providers/AfaqyProviderTest.php +191 -0
- package/server/tests/Unit/Support/Telematics/Providers/AfaqyProviderTransportTest.php +138 -0
- package/server/tests/Unit/Support/Telematics/Providers/GeotabProviderTest.php +329 -0
- package/server/tests/Unit/Support/Telematics/Providers/ProviderTransportSeamsTest.php +133 -0
- package/server/tests/Unit/Support/Telematics/Providers/SafeeProviderTest.php +487 -0
- package/server/tests/Unit/Support/Telematics/TelematicProviderRegistryTest.php +39 -0
- package/server/tests/Unit/Support/Telematics/TelematicServiceLifecycleTest.php +711 -0
- package/server/tests/Unit/Support/Telematics/TelematicServiceTelemetryTest.php +364 -0
- package/server/tests/Unit/Support/UtilsAdditionalTest.php +256 -0
- package/server/tests/Unit/Support/UtilsGeoMatrixAndVendorTest.php +382 -0
- package/server/tests/Unit/Tracking/TrackingContextTest.php +114 -0
- package/server/tests/Unit/Tracking/TrackingIntelligenceAndContextTest.php +477 -0
- package/server/tests/Unit/Tracking/TrackingProviderManagerFallbacksTest.php +208 -0
- package/server/tests/Unit/Traits/HasTrackingNumberTest.php +303 -0
- package/server/tests/Unit/Traits/PayloadAccessorsTest.php +150 -0
- package/server/tests/UtilsContractsTest.php +244 -0
- package/server/tests/VehicleControllerHelperContractsTest.php +488 -0
- package/server/tests/VehicleDataParsingTest.php +45 -0
- package/server/tests/VehicleDriverAssignmentTest.php +8 -9
- package/server/tests/VehicleResourceContractsTest.php +313 -0
- package/translations/bg-bg.yaml +2 -0
- package/translations/en-us.yaml +2 -0
- package/translations/es-pa.yaml +2 -0
- package/translations/fr-fr.yaml +2 -0
- package/translations/mn-mn.yaml +2 -0
- package/translations/pt-br.yaml +2 -0
- package/translations/ru-ru.yaml +2 -0
- package/server/src/Http/Controllers/Api/v1/OrganizationController.php +0 -45
- package/server/tests/DeviceFilterTest.php +0 -45
- package/server/tests/LiveControllerViewportTest.php +0 -60
|
@@ -59,30 +59,23 @@ class OrderController extends Controller
|
|
|
59
59
|
set_time_limit(180);
|
|
60
60
|
|
|
61
61
|
// get request input
|
|
62
|
-
$input = $
|
|
63
|
-
'internal_id', 'payload', 'service_quote', 'purchase_rate',
|
|
64
|
-
'adhoc', 'adhoc_distance', 'pod_method', 'pod_required',
|
|
65
|
-
'scheduled_at', 'status', 'meta', 'notes',
|
|
66
|
-
// Orchestrator constraints
|
|
67
|
-
'time_window_start', 'time_window_end',
|
|
68
|
-
'required_skills', 'orchestrator_priority',
|
|
69
|
-
]);
|
|
62
|
+
$input = $this->orderCreateInputFromRequest($request);
|
|
70
63
|
|
|
71
64
|
// Get order config
|
|
72
|
-
$orderConfig =
|
|
65
|
+
$orderConfig = $this->resolveOrderConfig($request->only(['type', 'order_config']));
|
|
73
66
|
if (!$orderConfig) {
|
|
74
|
-
return
|
|
67
|
+
return $this->apiError('Invalid order `type` or `order_config` provided.');
|
|
75
68
|
}
|
|
76
69
|
|
|
77
70
|
// Set order config to input
|
|
78
71
|
$input['order_config_uuid'] = $orderConfig->uuid;
|
|
79
|
-
$input['type'] = $orderConfig->key;
|
|
72
|
+
$input['type'] = $orderConfig->key ?? 'transport';
|
|
80
73
|
|
|
81
74
|
// make sure company is set
|
|
82
|
-
$input['company_uuid'] =
|
|
75
|
+
$input['company_uuid'] = $this->sessionCompany();
|
|
83
76
|
|
|
84
77
|
// resolve service quote if applicable
|
|
85
|
-
$serviceQuote =
|
|
78
|
+
$serviceQuote = $this->resolveServiceQuote($request);
|
|
86
79
|
$integratedVendorOrder = null;
|
|
87
80
|
|
|
88
81
|
// if service quote is applied, resolve it
|
|
@@ -97,18 +90,14 @@ class OrderController extends Controller
|
|
|
97
90
|
|
|
98
91
|
// create payload
|
|
99
92
|
if ($request->has('payload') && $request->isArray('payload')) {
|
|
100
|
-
$payload =
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
$hasDropoffField = array_key_exists('dropoff', $payloadInput);
|
|
109
|
-
$hasReturnField = array_key_exists('return', $payloadInput);
|
|
110
|
-
$hasWaypointsField = array_key_exists('waypoints', $payloadInput);
|
|
111
|
-
$hasRouteEndpointFields = $hasPickupField || $hasDropoffField || $hasReturnField;
|
|
93
|
+
$payload = $this->newPayload();
|
|
94
|
+
[
|
|
95
|
+
'entities' => $entities,
|
|
96
|
+
'waypoints' => $waypoints,
|
|
97
|
+
'pickup' => $pickup,
|
|
98
|
+
'dropoff' => $dropoff,
|
|
99
|
+
'return' => $return,
|
|
100
|
+
] = $this->payloadShapeFromArray($request->input('payload'));
|
|
112
101
|
|
|
113
102
|
if ($pickup) {
|
|
114
103
|
$payload->setPickup($pickup, [
|
|
@@ -140,22 +129,23 @@ class OrderController extends Controller
|
|
|
140
129
|
|
|
141
130
|
$input['payload_uuid'] = $payload->uuid;
|
|
142
131
|
} elseif ($request->isString('payload')) {
|
|
143
|
-
$input['payload_uuid'] =
|
|
132
|
+
$input['payload_uuid'] = $this->getUuid('payloads', [
|
|
144
133
|
'public_id' => $request->input('payload'),
|
|
145
|
-
'company_uuid' =>
|
|
134
|
+
'company_uuid' => $this->sessionCompany(),
|
|
146
135
|
]);
|
|
147
136
|
unset($input['payload']);
|
|
148
137
|
}
|
|
149
138
|
|
|
150
139
|
// create a payload if missing payload[] but has pickup/dropoff/etc
|
|
151
140
|
if ($request->missing('payload')) {
|
|
152
|
-
$payload =
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
141
|
+
$payload = $this->newPayload();
|
|
142
|
+
[
|
|
143
|
+
'entities' => $entities,
|
|
144
|
+
'waypoints' => $waypoints,
|
|
145
|
+
'pickup' => $pickup,
|
|
146
|
+
'dropoff' => $dropoff,
|
|
147
|
+
'return' => $return,
|
|
148
|
+
] = $this->payloadShapeFromRequest($request);
|
|
159
149
|
|
|
160
150
|
if ($pickup) {
|
|
161
151
|
$payload->setPickup($pickup, [
|
|
@@ -190,7 +180,7 @@ class OrderController extends Controller
|
|
|
190
180
|
|
|
191
181
|
// driver assignment
|
|
192
182
|
if ($request->has('driver') && $integratedVendorOrder === null) {
|
|
193
|
-
$driver =
|
|
183
|
+
$driver = $this->findDriverByPublicId($request->input('driver'));
|
|
194
184
|
if ($driver) {
|
|
195
185
|
$input['driver_assigned_uuid'] = $driver->uuid;
|
|
196
186
|
// set vehicle assignmend from driver
|
|
@@ -202,19 +192,19 @@ class OrderController extends Controller
|
|
|
202
192
|
|
|
203
193
|
// driver assignment
|
|
204
194
|
if ($request->has('vehicle') && $integratedVendorOrder === null) {
|
|
205
|
-
$input['vehicle_assigned_uuid'] =
|
|
195
|
+
$input['vehicle_assigned_uuid'] = $this->getUuid('vehicles', [
|
|
206
196
|
'public_id' => $request->input('vehicle'),
|
|
207
|
-
'company_uuid' =>
|
|
197
|
+
'company_uuid' => $this->sessionCompany(),
|
|
208
198
|
]);
|
|
209
199
|
}
|
|
210
200
|
|
|
211
201
|
// facilitator assignment
|
|
212
202
|
if ($request->has('facilitator') && $integratedVendorOrder === null) {
|
|
213
|
-
$facilitator =
|
|
203
|
+
$facilitator = $this->getUuid(
|
|
214
204
|
['contacts', 'vendors', 'integrated_vendors'],
|
|
215
205
|
[
|
|
216
206
|
'public_id' => $request->input('facilitator'),
|
|
217
|
-
'company_uuid' =>
|
|
207
|
+
'company_uuid' => $this->sessionCompany(),
|
|
218
208
|
],
|
|
219
209
|
[
|
|
220
210
|
'with_table' => true,
|
|
@@ -223,11 +213,11 @@ class OrderController extends Controller
|
|
|
223
213
|
|
|
224
214
|
if (is_array($facilitator)) {
|
|
225
215
|
$input['facilitator_uuid'] = Utils::get($facilitator, 'uuid');
|
|
226
|
-
$input['facilitator_type'] =
|
|
216
|
+
$input['facilitator_type'] = $this->getModelClassName(Utils::get($facilitator, 'table'));
|
|
227
217
|
}
|
|
228
218
|
} elseif ($integratedVendorOrder) {
|
|
229
219
|
$input['facilitator_uuid'] = $serviceQuote->integratedVendor->uuid;
|
|
230
|
-
$input['facilitator_type'] =
|
|
220
|
+
$input['facilitator_type'] = $this->getModelClassName('integrated_vendors');
|
|
231
221
|
}
|
|
232
222
|
|
|
233
223
|
// customer assignment
|
|
@@ -235,11 +225,11 @@ class OrderController extends Controller
|
|
|
235
225
|
$customer = $request->input('customer');
|
|
236
226
|
|
|
237
227
|
if (is_string($customer)) {
|
|
238
|
-
$customer =
|
|
228
|
+
$customer = $this->getUuid(
|
|
239
229
|
['contacts', 'vendors'],
|
|
240
230
|
[
|
|
241
231
|
'public_id' => $customer,
|
|
242
|
-
'company_uuid' =>
|
|
232
|
+
'company_uuid' => $this->sessionCompany(),
|
|
243
233
|
],
|
|
244
234
|
[
|
|
245
235
|
'with_table' => true,
|
|
@@ -248,29 +238,29 @@ class OrderController extends Controller
|
|
|
248
238
|
|
|
249
239
|
if (is_array($customer)) {
|
|
250
240
|
$input['customer_uuid'] = Utils::get($customer, 'uuid');
|
|
251
|
-
$input['customer_type'] =
|
|
241
|
+
$input['customer_type'] = $this->getModelClassName(Utils::get($customer, 'table'));
|
|
252
242
|
}
|
|
253
243
|
} elseif (is_array($customer)) {
|
|
254
244
|
// create customer from input
|
|
255
245
|
$customer = Arr::only($customer, ['internal_id', 'name', 'title', 'email', 'phone', 'meta']);
|
|
256
246
|
|
|
257
247
|
try {
|
|
258
|
-
$customerCandidate =
|
|
248
|
+
$customerCandidate = $this->newCustomerContact([
|
|
259
249
|
...$customer,
|
|
260
|
-
'company_uuid' =>
|
|
250
|
+
'company_uuid' => $this->sessionCompany(),
|
|
261
251
|
'type' => 'customer',
|
|
262
252
|
]);
|
|
263
253
|
$customerCandidate->assertCustomerIdentityIsAvailable();
|
|
264
254
|
|
|
265
|
-
$customer =
|
|
255
|
+
$customer = $this->firstOrCreateCustomerContact(
|
|
266
256
|
[
|
|
267
|
-
'company_uuid' =>
|
|
257
|
+
'company_uuid' => $this->sessionCompany(),
|
|
268
258
|
'email' => $customer['email'],
|
|
269
259
|
'type' => 'customer',
|
|
270
260
|
],
|
|
271
261
|
[
|
|
272
262
|
...$customer,
|
|
273
|
-
'company_uuid' =>
|
|
263
|
+
'company_uuid' => $this->sessionCompany(),
|
|
274
264
|
'type' => 'customer',
|
|
275
265
|
]
|
|
276
266
|
);
|
|
@@ -282,22 +272,13 @@ class OrderController extends Controller
|
|
|
282
272
|
return response()->apiError('Failed to find or create customer for order.');
|
|
283
273
|
}
|
|
284
274
|
|
|
285
|
-
if (Str::isUuid($customer)) {
|
|
286
|
-
$customer = Contact::where('uuid', $customer)->first();
|
|
287
|
-
}
|
|
288
|
-
|
|
289
275
|
if ($customer instanceof Contact) {
|
|
290
276
|
$input['customer_uuid'] = $customer->uuid;
|
|
291
|
-
$input['customer_type'] =
|
|
277
|
+
$input['customer_type'] = $this->getModelClassName($customer);
|
|
292
278
|
}
|
|
293
279
|
}
|
|
294
280
|
}
|
|
295
281
|
|
|
296
|
-
// if no type is set its default to transport
|
|
297
|
-
if (!isset($input['type'])) {
|
|
298
|
-
$input['type'] = 'transport';
|
|
299
|
-
}
|
|
300
|
-
|
|
301
282
|
// if no status is set its default to `created`
|
|
302
283
|
if (!isset($input['status'])) {
|
|
303
284
|
$input['status'] = 'created';
|
|
@@ -319,7 +300,7 @@ class OrderController extends Controller
|
|
|
319
300
|
}
|
|
320
301
|
|
|
321
302
|
// create the order
|
|
322
|
-
$order =
|
|
303
|
+
$order = $this->createOrder($input);
|
|
323
304
|
|
|
324
305
|
// if it's integrated vendor order apply to meta
|
|
325
306
|
if ($integratedVendorOrder) {
|
|
@@ -335,14 +316,14 @@ class OrderController extends Controller
|
|
|
335
316
|
// Determine if order should be dispatched on creation
|
|
336
317
|
$shouldDispatch = $request->boolean('dispatch') && $integratedVendorOrder === null;
|
|
337
318
|
|
|
338
|
-
|
|
319
|
+
$this->dispatchFinalizeApiOrderCreation(
|
|
339
320
|
$order->uuid,
|
|
340
321
|
$serviceQuote instanceof ServiceQuote ? $serviceQuote->uuid : null,
|
|
341
322
|
$shouldDispatch
|
|
342
|
-
)
|
|
323
|
+
);
|
|
343
324
|
|
|
344
325
|
// response the driver resource
|
|
345
|
-
return
|
|
326
|
+
return $this->orderResource($order);
|
|
346
327
|
}
|
|
347
328
|
|
|
348
329
|
/**
|
|
@@ -358,7 +339,7 @@ class OrderController extends Controller
|
|
|
358
339
|
|
|
359
340
|
// find for the order
|
|
360
341
|
try {
|
|
361
|
-
$order =
|
|
342
|
+
$order = $this->findOrder($id, ['trackingNumber', 'driverAssigned', 'purchaseRate.serviceQuote.items', 'customer', 'facilitator']);
|
|
362
343
|
} catch (ModelNotFoundException $exception) {
|
|
363
344
|
return response()->json(
|
|
364
345
|
[
|
|
@@ -369,23 +350,20 @@ class OrderController extends Controller
|
|
|
369
350
|
}
|
|
370
351
|
|
|
371
352
|
// get request input
|
|
372
|
-
$input = $
|
|
373
|
-
'internal_id', 'payload', 'adhoc', 'adhoc_distance',
|
|
374
|
-
'pod_method', 'pod_required', 'scheduled_at', 'meta', 'type', 'status', 'notes',
|
|
375
|
-
// Orchestrator constraints
|
|
376
|
-
'time_window_start', 'time_window_end',
|
|
377
|
-
'required_skills', 'orchestrator_priority',
|
|
378
|
-
]);
|
|
353
|
+
$input = $this->orderUpdateInputFromRequest($request);
|
|
379
354
|
|
|
380
355
|
// update payload if new input or change payload by id
|
|
381
356
|
if ($request->isArray('payload')) {
|
|
382
|
-
$payload
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
357
|
+
$payload = data_get($order, 'payload', $this->newPayload());
|
|
358
|
+
[
|
|
359
|
+
'entities' => $entities,
|
|
360
|
+
'waypoints' => $waypoints,
|
|
361
|
+
'pickup' => $pickup,
|
|
362
|
+
'dropoff' => $dropoff,
|
|
363
|
+
'return' => $return,
|
|
364
|
+
'has_waypoints_field' => $hasWaypointsField,
|
|
365
|
+
'has_route_endpoint_fields' => $hasRouteEndpointFields,
|
|
366
|
+
] = $this->payloadShapeFromArray($request->input('payload'));
|
|
389
367
|
|
|
390
368
|
// if no pickup and dropoff extract from waypoints
|
|
391
369
|
if (empty($pickup) && empty($dropoff) && count($waypoints)) {
|
|
@@ -425,27 +403,25 @@ class OrderController extends Controller
|
|
|
425
403
|
|
|
426
404
|
$input['payload_uuid'] = $payload->uuid;
|
|
427
405
|
} elseif ($request->has('payload')) {
|
|
428
|
-
$input['payload_uuid'] =
|
|
406
|
+
$input['payload_uuid'] = $this->getUuid('payloads', [
|
|
429
407
|
'public_id' => $request->input('payload'),
|
|
430
|
-
'company_uuid' =>
|
|
408
|
+
'company_uuid' => $this->sessionCompany(),
|
|
431
409
|
]);
|
|
432
410
|
unset($input['payload']);
|
|
433
411
|
}
|
|
434
412
|
|
|
435
413
|
// create a payload if missing payload[] but has pickup/dropoff/etc
|
|
436
414
|
if ($request->missing('payload')) {
|
|
437
|
-
$payload
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
$hasWaypointsField = $request->exists('waypoints');
|
|
448
|
-
$hasRouteEndpointFields = $hasPickupField || $hasDropoffField || $hasReturnField;
|
|
415
|
+
$payload = data_get($order, 'payload', $this->newPayload());
|
|
416
|
+
[
|
|
417
|
+
'entities' => $entities,
|
|
418
|
+
'waypoints' => $waypoints,
|
|
419
|
+
'pickup' => $pickup,
|
|
420
|
+
'dropoff' => $dropoff,
|
|
421
|
+
'return' => $return,
|
|
422
|
+
'has_waypoints_field' => $hasWaypointsField,
|
|
423
|
+
'has_route_endpoint_fields' => $hasRouteEndpointFields,
|
|
424
|
+
] = $this->payloadShapeFromRequest($request);
|
|
449
425
|
|
|
450
426
|
// if no pickup and dropoff extract from waypoints
|
|
451
427
|
if (empty($pickup) && empty($dropoff) && count($waypoints)) {
|
|
@@ -488,27 +464,27 @@ class OrderController extends Controller
|
|
|
488
464
|
|
|
489
465
|
// driver assignment
|
|
490
466
|
if ($request->has('driver')) {
|
|
491
|
-
$input['driver_assigned_uuid'] =
|
|
467
|
+
$input['driver_assigned_uuid'] = $this->getUuid('drivers', [
|
|
492
468
|
'public_id' => $request->input('driver'),
|
|
493
|
-
'company_uuid' =>
|
|
469
|
+
'company_uuid' => $this->sessionCompany(),
|
|
494
470
|
]);
|
|
495
471
|
}
|
|
496
472
|
|
|
497
473
|
// vehicle assignment
|
|
498
474
|
if ($request->has('vehicle')) {
|
|
499
|
-
$input['vehicle_assigned_uuid'] =
|
|
475
|
+
$input['vehicle_assigned_uuid'] = $this->getUuid('vehicles', [
|
|
500
476
|
'public_id' => $request->input('vehicle'),
|
|
501
|
-
'company_uuid' =>
|
|
477
|
+
'company_uuid' => $this->sessionCompany(),
|
|
502
478
|
]);
|
|
503
479
|
}
|
|
504
480
|
|
|
505
481
|
// facilitator assignment
|
|
506
482
|
if ($request->has('facilitator')) {
|
|
507
|
-
$facilitator =
|
|
483
|
+
$facilitator = $this->getUuid(
|
|
508
484
|
['contacts', 'vendors'],
|
|
509
485
|
[
|
|
510
486
|
'public_id' => $request->input('facilitator'),
|
|
511
|
-
'company_uuid' =>
|
|
487
|
+
'company_uuid' => $this->sessionCompany(),
|
|
512
488
|
],
|
|
513
489
|
[
|
|
514
490
|
'with_table' => true,
|
|
@@ -517,17 +493,17 @@ class OrderController extends Controller
|
|
|
517
493
|
|
|
518
494
|
if (is_array($facilitator)) {
|
|
519
495
|
$input['facilitator_uuid'] = Utils::get($facilitator, 'uuid');
|
|
520
|
-
$input['facilitator_type'] =
|
|
496
|
+
$input['facilitator_type'] = $this->getModelClassName(Utils::get($facilitator, 'table'));
|
|
521
497
|
}
|
|
522
498
|
}
|
|
523
499
|
|
|
524
500
|
// customer assignment
|
|
525
501
|
if ($request->has('customer')) {
|
|
526
|
-
$customer =
|
|
502
|
+
$customer = $this->getUuid(
|
|
527
503
|
['contacts', 'vendors'],
|
|
528
504
|
[
|
|
529
505
|
'public_id' => $request->input('customer'),
|
|
530
|
-
'company_uuid' =>
|
|
506
|
+
'company_uuid' => $this->sessionCompany(),
|
|
531
507
|
],
|
|
532
508
|
[
|
|
533
509
|
'with_table' => true,
|
|
@@ -536,12 +512,12 @@ class OrderController extends Controller
|
|
|
536
512
|
|
|
537
513
|
if (is_array($customer)) {
|
|
538
514
|
$input['customer_uuid'] = Utils::get($customer, 'uuid');
|
|
539
|
-
$input['customer_type'] =
|
|
515
|
+
$input['customer_type'] = $this->getModelClassName(Utils::get($customer, 'table'));
|
|
540
516
|
}
|
|
541
517
|
}
|
|
542
518
|
|
|
543
519
|
// If adding a service quote for a purchase
|
|
544
|
-
$serviceQuote =
|
|
520
|
+
$serviceQuote = $this->resolveServiceQuote($request);
|
|
545
521
|
if ($serviceQuote) {
|
|
546
522
|
$order->purchaseServiceQuote($serviceQuote);
|
|
547
523
|
}
|
|
@@ -565,7 +541,56 @@ class OrderController extends Controller
|
|
|
565
541
|
$order->load(['trackingNumber', 'trackingStatuses', 'driverAssigned', 'vehicleAssigned', 'purchaseRate.serviceQuote.items', 'customer', 'facilitator']);
|
|
566
542
|
|
|
567
543
|
// response the order resource
|
|
568
|
-
return
|
|
544
|
+
return $this->orderResource($order);
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
protected function orderCreateInputFromRequest(Request $request): array
|
|
548
|
+
{
|
|
549
|
+
return $request->only([
|
|
550
|
+
'internal_id', 'payload', 'service_quote', 'purchase_rate',
|
|
551
|
+
'adhoc', 'adhoc_distance', 'pod_method', 'pod_required',
|
|
552
|
+
'scheduled_at', 'status', 'meta', 'notes',
|
|
553
|
+
// Orchestrator constraints
|
|
554
|
+
'time_window_start', 'time_window_end',
|
|
555
|
+
'required_skills', 'orchestrator_priority',
|
|
556
|
+
]);
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
protected function orderUpdateInputFromRequest(Request $request): array
|
|
560
|
+
{
|
|
561
|
+
return $request->only([
|
|
562
|
+
'internal_id', 'payload', 'adhoc', 'adhoc_distance',
|
|
563
|
+
'pod_method', 'pod_required', 'scheduled_at', 'meta', 'type', 'status', 'notes',
|
|
564
|
+
// Orchestrator constraints
|
|
565
|
+
'time_window_start', 'time_window_end',
|
|
566
|
+
'required_skills', 'orchestrator_priority',
|
|
567
|
+
]);
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
protected function payloadShapeFromRequest(Request $request): array
|
|
571
|
+
{
|
|
572
|
+
return $this->payloadShapeFromArray($request->only(['pickup', 'dropoff', 'return', 'waypoints', 'entities']));
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
protected function payloadShapeFromArray(array $payloadInput): array
|
|
576
|
+
{
|
|
577
|
+
$hasPickupField = array_key_exists('pickup', $payloadInput);
|
|
578
|
+
$hasDropoffField = array_key_exists('dropoff', $payloadInput);
|
|
579
|
+
$hasReturnField = array_key_exists('return', $payloadInput);
|
|
580
|
+
$hasWaypointsField = array_key_exists('waypoints', $payloadInput);
|
|
581
|
+
|
|
582
|
+
return [
|
|
583
|
+
'entities' => data_get($payloadInput, 'entities', []),
|
|
584
|
+
'waypoints' => data_get($payloadInput, 'waypoints', []),
|
|
585
|
+
'pickup' => data_get($payloadInput, 'pickup'),
|
|
586
|
+
'dropoff' => data_get($payloadInput, 'dropoff'),
|
|
587
|
+
'return' => data_get($payloadInput, 'return'),
|
|
588
|
+
'has_pickup_field' => $hasPickupField,
|
|
589
|
+
'has_dropoff_field' => $hasDropoffField,
|
|
590
|
+
'has_return_field' => $hasReturnField,
|
|
591
|
+
'has_waypoints_field' => $hasWaypointsField,
|
|
592
|
+
'has_route_endpoint_fields' => $hasPickupField || $hasDropoffField || $hasReturnField,
|
|
593
|
+
];
|
|
569
594
|
}
|
|
570
595
|
|
|
571
596
|
/**
|
|
@@ -699,6 +724,15 @@ class OrderController extends Controller
|
|
|
699
724
|
}
|
|
700
725
|
|
|
701
726
|
// request wants to find orders nearby a driver ?
|
|
727
|
+
//
|
|
728
|
+
// Unreachable in full: `Utils::isCoordinates()` resolves a
|
|
729
|
+
// `driver_*` public id to that driver's location, so the
|
|
730
|
+
// coordinates branch above consumes every driver that has one.
|
|
731
|
+
// What reaches here is a driver with no stored location, and the
|
|
732
|
+
// distance query below then raises on the null point rather than
|
|
733
|
+
// completing — see the "without a stored location" case in
|
|
734
|
+
// OrderControllerNearbyFiltersTest.
|
|
735
|
+
// @codeCoverageIgnoreStart
|
|
702
736
|
if ($addedNearbyQuery === false && is_string($nearby) && Str::startsWith($nearby, 'driver_')) {
|
|
703
737
|
$driver = Driver::where('public_id', $nearby)->first();
|
|
704
738
|
|
|
@@ -727,6 +761,7 @@ class OrderController extends Controller
|
|
|
727
761
|
$addedNearbyQuery = true;
|
|
728
762
|
}
|
|
729
763
|
}
|
|
764
|
+
// @codeCoverageIgnoreEnd
|
|
730
765
|
|
|
731
766
|
// if is a string like address string
|
|
732
767
|
if ($addedNearbyQuery === false && is_string($nearby)) {
|
|
@@ -772,9 +807,9 @@ class OrderController extends Controller
|
|
|
772
807
|
{
|
|
773
808
|
// find for the order
|
|
774
809
|
try {
|
|
775
|
-
$order =
|
|
810
|
+
$order = $this->findOrder($id, ['trackingNumber', 'trackingStatuses', 'driverAssigned', 'vehicleAssigned', 'purchaseRate.serviceQuote.items', 'customer', 'facilitator']);
|
|
776
811
|
} catch (ModelNotFoundException $exception) {
|
|
777
|
-
return
|
|
812
|
+
return $this->jsonResponse(
|
|
778
813
|
[
|
|
779
814
|
'error' => 'Order resource not found.',
|
|
780
815
|
],
|
|
@@ -783,7 +818,7 @@ class OrderController extends Controller
|
|
|
783
818
|
}
|
|
784
819
|
|
|
785
820
|
// response the order resource
|
|
786
|
-
return
|
|
821
|
+
return $this->orderResource($order);
|
|
787
822
|
}
|
|
788
823
|
|
|
789
824
|
/**
|
|
@@ -795,9 +830,9 @@ class OrderController extends Controller
|
|
|
795
830
|
{
|
|
796
831
|
// find for the driver
|
|
797
832
|
try {
|
|
798
|
-
$order =
|
|
833
|
+
$order = $this->findOrder($id);
|
|
799
834
|
} catch (ModelNotFoundException $exception) {
|
|
800
|
-
return
|
|
835
|
+
return $this->jsonResponse(
|
|
801
836
|
[
|
|
802
837
|
'error' => 'Order resource not found.',
|
|
803
838
|
],
|
|
@@ -809,7 +844,7 @@ class OrderController extends Controller
|
|
|
809
844
|
$order->delete();
|
|
810
845
|
|
|
811
846
|
// response the order resource
|
|
812
|
-
return
|
|
847
|
+
return $this->deletedOrderResource($order);
|
|
813
848
|
}
|
|
814
849
|
|
|
815
850
|
/**
|
|
@@ -821,9 +856,9 @@ class OrderController extends Controller
|
|
|
821
856
|
{
|
|
822
857
|
// find the order
|
|
823
858
|
try {
|
|
824
|
-
$order =
|
|
859
|
+
$order = $this->findOrder($id);
|
|
825
860
|
} catch (ModelNotFoundException $exception) {
|
|
826
|
-
return
|
|
861
|
+
return $this->jsonResponse(
|
|
827
862
|
[
|
|
828
863
|
'error' => 'Order resource not found.',
|
|
829
864
|
],
|
|
@@ -836,12 +871,12 @@ class OrderController extends Controller
|
|
|
836
871
|
$origin = $order->payload->pickup ?? $order->payload->waypoints->first();
|
|
837
872
|
$destination = $order->payload->dropoff ?? $order->payload->waypoints->firstWhere('current_waypoint_uuid', $order->current_waypoint_uuid);
|
|
838
873
|
|
|
839
|
-
$matrix =
|
|
874
|
+
$matrix = $this->drivingDistanceAndTime($origin, $destination);
|
|
840
875
|
|
|
841
876
|
$order->update(['distance' => $matrix->distance, 'time' => $matrix->time]);
|
|
842
877
|
|
|
843
878
|
// response distance and time matrix
|
|
844
|
-
return
|
|
879
|
+
return $this->jsonResponse($matrix);
|
|
845
880
|
}
|
|
846
881
|
|
|
847
882
|
/**
|
|
@@ -852,9 +887,9 @@ class OrderController extends Controller
|
|
|
852
887
|
public function dispatchOrder(string $id)
|
|
853
888
|
{
|
|
854
889
|
try {
|
|
855
|
-
$order =
|
|
890
|
+
$order = $this->findOrder($id, ['trackingNumber', 'trackingStatuses', 'driverAssigned', 'vehicleAssigned', 'purchaseRate.serviceQuote.items', 'customer', 'facilitator']);
|
|
856
891
|
} catch (ModelNotFoundException $exception) {
|
|
857
|
-
return
|
|
892
|
+
return $this->jsonResponse(
|
|
858
893
|
[
|
|
859
894
|
'error' => 'Order resource not found.',
|
|
860
895
|
],
|
|
@@ -863,17 +898,17 @@ class OrderController extends Controller
|
|
|
863
898
|
}
|
|
864
899
|
|
|
865
900
|
if (!$order->hasDriverAssigned && !$order->adhoc) {
|
|
866
|
-
return
|
|
901
|
+
return $this->apiError('No driver assigned to dispatch!');
|
|
867
902
|
}
|
|
868
903
|
|
|
869
904
|
if ($order->dispatched) {
|
|
870
|
-
return
|
|
905
|
+
return $this->apiError('Order has already been dispatched!');
|
|
871
906
|
}
|
|
872
907
|
|
|
873
908
|
$order->dispatch();
|
|
874
909
|
$order->insertDispatchActivity();
|
|
875
910
|
|
|
876
|
-
return
|
|
911
|
+
return $this->orderResource($order);
|
|
877
912
|
}
|
|
878
913
|
|
|
879
914
|
/**
|
|
@@ -889,14 +924,13 @@ class OrderController extends Controller
|
|
|
889
924
|
$timeInput = $request->input('time');
|
|
890
925
|
|
|
891
926
|
// get the default tz
|
|
892
|
-
$
|
|
893
|
-
$defaultTz = data_get($company, 'timezone', config('app.timezone'));
|
|
927
|
+
$defaultTz = $this->defaultCompanyTimezone();
|
|
894
928
|
$timezoneInput = $request->input('timezone', $defaultTz);
|
|
895
929
|
|
|
896
930
|
try {
|
|
897
|
-
$order =
|
|
931
|
+
$order = $this->findOrder($id);
|
|
898
932
|
} catch (ModelNotFoundException $exception) {
|
|
899
|
-
return
|
|
933
|
+
return $this->jsonResponse(
|
|
900
934
|
[
|
|
901
935
|
'error' => 'Order resource not found.',
|
|
902
936
|
],
|
|
@@ -919,7 +953,7 @@ class OrderController extends Controller
|
|
|
919
953
|
$order->scheduled_at = $date;
|
|
920
954
|
$order->save();
|
|
921
955
|
|
|
922
|
-
return
|
|
956
|
+
return $this->orderResource($order);
|
|
923
957
|
}
|
|
924
958
|
|
|
925
959
|
/**
|
|
@@ -934,7 +968,7 @@ class OrderController extends Controller
|
|
|
934
968
|
$assignAdhocDriver = $request->input('assign');
|
|
935
969
|
|
|
936
970
|
try {
|
|
937
|
-
$order =
|
|
971
|
+
$order = $this->findOrder($id, ['payload.waypoints', 'driverAssigned']);
|
|
938
972
|
} catch (ModelNotFoundException $exception) {
|
|
939
973
|
return response()->json(
|
|
940
974
|
[
|
|
@@ -954,10 +988,10 @@ class OrderController extends Controller
|
|
|
954
988
|
}
|
|
955
989
|
|
|
956
990
|
/** @var \Fleetbase\Models\Driver */
|
|
957
|
-
$driver =
|
|
991
|
+
$driver = $this->findDriverByUuid($order->driver_assigned_uuid);
|
|
958
992
|
|
|
959
993
|
/** @var \Fleetbase\Models\Payload */
|
|
960
|
-
$payload =
|
|
994
|
+
$payload = $this->findPayloadByUuid($order->payload_uuid);
|
|
961
995
|
|
|
962
996
|
if ($order->adhoc && !$driver) {
|
|
963
997
|
return response()->apiError('You must send driver to accept adhoc order.');
|
|
@@ -1031,7 +1065,7 @@ class OrderController extends Controller
|
|
|
1031
1065
|
// if string $id
|
|
1032
1066
|
if (!$order) {
|
|
1033
1067
|
try {
|
|
1034
|
-
$order =
|
|
1068
|
+
$order = $this->findOrder($id, [
|
|
1035
1069
|
'driverAssigned',
|
|
1036
1070
|
'payload.entities',
|
|
1037
1071
|
'payload.pickup',
|
|
@@ -1048,9 +1082,16 @@ class OrderController extends Controller
|
|
|
1048
1082
|
}
|
|
1049
1083
|
|
|
1050
1084
|
// if no order found
|
|
1085
|
+
//
|
|
1086
|
+
// Unreachable: findOrder() above is typed `: Order`, so it either returns
|
|
1087
|
+
// an order or throws — it never yields null. This is independent of the
|
|
1088
|
+
// upstream findByIdOrFail defect and stays unreachable after that is
|
|
1089
|
+
// fixed; the catch above is what becomes live then, not this guard.
|
|
1090
|
+
// @codeCoverageIgnoreStart
|
|
1051
1091
|
if (!$order) {
|
|
1052
1092
|
return response()->apiError('Order resource not found.', 404);
|
|
1053
1093
|
}
|
|
1094
|
+
// @codeCoverageIgnoreEnd
|
|
1054
1095
|
|
|
1055
1096
|
// if order is still status of `created` trigger started flag
|
|
1056
1097
|
if ($order->status === 'created') {
|
|
@@ -1086,7 +1127,7 @@ class OrderController extends Controller
|
|
|
1086
1127
|
|
|
1087
1128
|
$order->dispatch();
|
|
1088
1129
|
|
|
1089
|
-
return
|
|
1130
|
+
return $this->orderResource($order);
|
|
1090
1131
|
}
|
|
1091
1132
|
|
|
1092
1133
|
/** @var \Fleetbase\LaravelMysqlSpatial\Types\Point */
|
|
@@ -1116,7 +1157,7 @@ class OrderController extends Controller
|
|
|
1116
1157
|
$order->complete($this->resolveProof($proof));
|
|
1117
1158
|
}
|
|
1118
1159
|
|
|
1119
|
-
return
|
|
1160
|
+
return $this->orderResource($order->refresh());
|
|
1120
1161
|
}
|
|
1121
1162
|
|
|
1122
1163
|
if (!$order->started && in_array($order->status, ['created', 'dispatched'], true)) {
|
|
@@ -1132,7 +1173,7 @@ class OrderController extends Controller
|
|
|
1132
1173
|
$order->driverAssigned?->unassignCurrentJob();
|
|
1133
1174
|
$order->cancel();
|
|
1134
1175
|
|
|
1135
|
-
return
|
|
1176
|
+
return $this->orderResource($order->refresh());
|
|
1136
1177
|
}
|
|
1137
1178
|
|
|
1138
1179
|
if (Utils::isActivity($activity) && $activity->completesOrder()) {
|
|
@@ -1144,7 +1185,7 @@ class OrderController extends Controller
|
|
|
1144
1185
|
}
|
|
1145
1186
|
}
|
|
1146
1187
|
|
|
1147
|
-
return
|
|
1188
|
+
return $this->orderResource($order->refresh());
|
|
1148
1189
|
}
|
|
1149
1190
|
|
|
1150
1191
|
/**
|
|
@@ -1157,7 +1198,7 @@ class OrderController extends Controller
|
|
|
1157
1198
|
$waypointId = $request->input('waypoint');
|
|
1158
1199
|
|
|
1159
1200
|
try {
|
|
1160
|
-
$order =
|
|
1201
|
+
$order = $this->findOrder($id, [
|
|
1161
1202
|
'payload.pickup',
|
|
1162
1203
|
'payload.dropoff',
|
|
1163
1204
|
'payload.return',
|
|
@@ -1215,9 +1256,9 @@ class OrderController extends Controller
|
|
|
1215
1256
|
public function completeOrder(string $id)
|
|
1216
1257
|
{
|
|
1217
1258
|
try {
|
|
1218
|
-
$order =
|
|
1259
|
+
$order = $this->findOrder($id);
|
|
1219
1260
|
} catch (ModelNotFoundException $exception) {
|
|
1220
|
-
return
|
|
1261
|
+
return $this->jsonResponse(
|
|
1221
1262
|
[
|
|
1222
1263
|
'error' => 'Order resource not found.',
|
|
1223
1264
|
],
|
|
@@ -1247,7 +1288,7 @@ class OrderController extends Controller
|
|
|
1247
1288
|
$order->insertActivity($activity, $location);
|
|
1248
1289
|
$order->notifyCompleted();
|
|
1249
1290
|
|
|
1250
|
-
return
|
|
1291
|
+
return $this->orderResource($order);
|
|
1251
1292
|
}
|
|
1252
1293
|
|
|
1253
1294
|
/**
|
|
@@ -1258,9 +1299,9 @@ class OrderController extends Controller
|
|
|
1258
1299
|
public function cancelOrder(string $id)
|
|
1259
1300
|
{
|
|
1260
1301
|
try {
|
|
1261
|
-
$order =
|
|
1302
|
+
$order = $this->findOrder($id);
|
|
1262
1303
|
} catch (ModelNotFoundException $exception) {
|
|
1263
|
-
return
|
|
1304
|
+
return $this->jsonResponse(
|
|
1264
1305
|
[
|
|
1265
1306
|
'error' => 'Order resource not found.',
|
|
1266
1307
|
],
|
|
@@ -1270,7 +1311,7 @@ class OrderController extends Controller
|
|
|
1270
1311
|
|
|
1271
1312
|
$order->cancel();
|
|
1272
1313
|
|
|
1273
|
-
return
|
|
1314
|
+
return $this->orderResource($order);
|
|
1274
1315
|
}
|
|
1275
1316
|
|
|
1276
1317
|
/**
|
|
@@ -1282,7 +1323,7 @@ class OrderController extends Controller
|
|
|
1282
1323
|
public function setDestination(string $id, string $placeId)
|
|
1283
1324
|
{
|
|
1284
1325
|
try {
|
|
1285
|
-
$order =
|
|
1326
|
+
$order = $this->findOrder($id, [
|
|
1286
1327
|
'payload.pickup',
|
|
1287
1328
|
'payload.dropoff',
|
|
1288
1329
|
'payload.return',
|
|
@@ -1309,7 +1350,7 @@ class OrderController extends Controller
|
|
|
1309
1350
|
// Persist destination choice
|
|
1310
1351
|
$this->setPayloadCurrentServiceStop($payload, $stop);
|
|
1311
1352
|
|
|
1312
|
-
return
|
|
1353
|
+
return $this->orderResource($order->refresh());
|
|
1313
1354
|
}
|
|
1314
1355
|
|
|
1315
1356
|
/**
|
|
@@ -1320,14 +1361,14 @@ class OrderController extends Controller
|
|
|
1320
1361
|
public function optimize(string $id)
|
|
1321
1362
|
{
|
|
1322
1363
|
try {
|
|
1323
|
-
$order =
|
|
1364
|
+
$order = $this->findOrder($id);
|
|
1324
1365
|
} catch (ModelNotFoundException $e) {
|
|
1325
|
-
return
|
|
1366
|
+
return $this->apiError('Order resource not found.', 404);
|
|
1326
1367
|
}
|
|
1327
1368
|
|
|
1328
1369
|
// do this code
|
|
1329
1370
|
|
|
1330
|
-
return
|
|
1371
|
+
return $this->orderResource($order);
|
|
1331
1372
|
}
|
|
1332
1373
|
|
|
1333
1374
|
/**
|
|
@@ -1340,17 +1381,17 @@ class OrderController extends Controller
|
|
|
1340
1381
|
set_time_limit(280);
|
|
1341
1382
|
|
|
1342
1383
|
try {
|
|
1343
|
-
$order =
|
|
1384
|
+
$order = $this->findOrder($id);
|
|
1344
1385
|
$data = $order->tracker()->toArray($request->only(['provider', 'fallbacks', 'traffic_enabled']));
|
|
1345
1386
|
|
|
1346
|
-
return
|
|
1387
|
+
return $this->jsonResponse($data);
|
|
1347
1388
|
} catch (ModelNotFoundException $e) {
|
|
1348
|
-
return
|
|
1389
|
+
return $this->apiError('Order resource not found.', 404);
|
|
1349
1390
|
} catch (\Throwable $e) {
|
|
1350
|
-
return
|
|
1391
|
+
return $this->apiError('An error occured trying to track order.', 404);
|
|
1351
1392
|
}
|
|
1352
1393
|
|
|
1353
|
-
return
|
|
1394
|
+
return $this->apiError('An error occured trying to track order.', 404);
|
|
1354
1395
|
}
|
|
1355
1396
|
|
|
1356
1397
|
/**
|
|
@@ -1361,17 +1402,17 @@ class OrderController extends Controller
|
|
|
1361
1402
|
public function etaData(Request $request, string $id)
|
|
1362
1403
|
{
|
|
1363
1404
|
try {
|
|
1364
|
-
$order =
|
|
1405
|
+
$order = $this->findOrder($id);
|
|
1365
1406
|
$data = $order->tracker()->eta($request->only(['provider', 'fallbacks', 'traffic_enabled']));
|
|
1366
1407
|
|
|
1367
|
-
return
|
|
1408
|
+
return $this->jsonResponse($data);
|
|
1368
1409
|
} catch (ModelNotFoundException $e) {
|
|
1369
|
-
return
|
|
1410
|
+
return $this->apiError('Order resource not found.', 404);
|
|
1370
1411
|
} catch (\Throwable $e) {
|
|
1371
|
-
return
|
|
1412
|
+
return $this->apiError('An error occured trying to track order.', 404);
|
|
1372
1413
|
}
|
|
1373
1414
|
|
|
1374
|
-
return
|
|
1415
|
+
return $this->apiError('An error occured trying to track order.', 404);
|
|
1375
1416
|
}
|
|
1376
1417
|
|
|
1377
1418
|
/**
|
|
@@ -1387,26 +1428,26 @@ class OrderController extends Controller
|
|
|
1387
1428
|
$type = $subjectId ? strtok($subjectId, '_') : null;
|
|
1388
1429
|
|
|
1389
1430
|
if (!$code) {
|
|
1390
|
-
return
|
|
1431
|
+
return $this->apiError('No QR code data to capture.');
|
|
1391
1432
|
}
|
|
1392
1433
|
|
|
1393
1434
|
// Load Order
|
|
1394
1435
|
try {
|
|
1395
|
-
$order =
|
|
1436
|
+
$order = $this->findOrder($id, ['payload.pickup', 'payload.dropoff', 'payload.return', 'payload.waypoints', 'payload.waypointMarkers.place']);
|
|
1396
1437
|
} catch (ModelNotFoundException $e) {
|
|
1397
|
-
return
|
|
1438
|
+
return $this->apiError('Order resource not found.', 404);
|
|
1398
1439
|
}
|
|
1399
1440
|
|
|
1400
1441
|
// Resolve subject
|
|
1401
1442
|
$subject = $this->resolveSubject($order, $type, $subjectId);
|
|
1402
1443
|
if (!$subject) {
|
|
1403
|
-
return
|
|
1444
|
+
return $this->apiError('Unable to capture QR code data.');
|
|
1404
1445
|
}
|
|
1405
1446
|
|
|
1406
1447
|
// validate
|
|
1407
1448
|
if ($subject && $code === $subject->uuid) {
|
|
1408
1449
|
// create verification proof
|
|
1409
|
-
$proof =
|
|
1450
|
+
$proof = $this->createProof([
|
|
1410
1451
|
'company_uuid' => session('company'),
|
|
1411
1452
|
'order_uuid' => $order->uuid,
|
|
1412
1453
|
'subject_uuid' => $subject->uuid,
|
|
@@ -1416,10 +1457,10 @@ class OrderController extends Controller
|
|
|
1416
1457
|
'data' => $data,
|
|
1417
1458
|
]);
|
|
1418
1459
|
|
|
1419
|
-
return
|
|
1460
|
+
return $this->proofResource($proof);
|
|
1420
1461
|
}
|
|
1421
1462
|
|
|
1422
|
-
return
|
|
1463
|
+
return $this->apiError('Unable to validate QR code data.');
|
|
1423
1464
|
}
|
|
1424
1465
|
|
|
1425
1466
|
/**
|
|
@@ -1437,24 +1478,24 @@ class OrderController extends Controller
|
|
|
1437
1478
|
$type = $subjectId ? strtok($subjectId, '_') : null;
|
|
1438
1479
|
|
|
1439
1480
|
if (!$signature) {
|
|
1440
|
-
return
|
|
1481
|
+
return $this->apiError('No signature data to capture.');
|
|
1441
1482
|
}
|
|
1442
1483
|
|
|
1443
1484
|
// Load Order
|
|
1444
1485
|
try {
|
|
1445
|
-
$order =
|
|
1486
|
+
$order = $this->findOrder($id);
|
|
1446
1487
|
} catch (ModelNotFoundException $e) {
|
|
1447
|
-
return
|
|
1488
|
+
return $this->apiError('Order resource not found.', 404);
|
|
1448
1489
|
}
|
|
1449
1490
|
|
|
1450
1491
|
// Resolve subject
|
|
1451
1492
|
$subject = $this->resolveSubject($order, $type, $subjectId);
|
|
1452
1493
|
if (!$subject) {
|
|
1453
|
-
return
|
|
1494
|
+
return $this->apiError('Unable to capture signature data.');
|
|
1454
1495
|
}
|
|
1455
1496
|
|
|
1456
1497
|
// create proof instance
|
|
1457
|
-
$proof =
|
|
1498
|
+
$proof = $this->createProof([
|
|
1458
1499
|
'company_uuid' => session('company'),
|
|
1459
1500
|
'order_uuid' => $order->uuid,
|
|
1460
1501
|
'subject_uuid' => $subject->uuid,
|
|
@@ -1468,10 +1509,10 @@ class OrderController extends Controller
|
|
|
1468
1509
|
$path = 'uploads/' . session('company') . '/signatures/' . $proof->public_id . '.png';
|
|
1469
1510
|
|
|
1470
1511
|
// upload signature
|
|
1471
|
-
|
|
1512
|
+
$this->putStorage($disk, $path, base64_decode(str_replace('data:image/png;base64,', '', $signature)));
|
|
1472
1513
|
|
|
1473
1514
|
// create file record for upload
|
|
1474
|
-
$file =
|
|
1515
|
+
$file = $this->createFile([
|
|
1475
1516
|
'company_uuid' => session('company'),
|
|
1476
1517
|
'uploader_uuid' => session('user'),
|
|
1477
1518
|
'name' => basename($path),
|
|
@@ -1488,7 +1529,7 @@ class OrderController extends Controller
|
|
|
1488
1529
|
$proof->file_uuid = $file->uuid;
|
|
1489
1530
|
$proof->save();
|
|
1490
1531
|
|
|
1491
|
-
return
|
|
1532
|
+
return $this->proofResource($proof);
|
|
1492
1533
|
}
|
|
1493
1534
|
|
|
1494
1535
|
/**
|
|
@@ -1552,7 +1593,7 @@ class OrderController extends Controller
|
|
|
1552
1593
|
} catch (ValidationException $e) {
|
|
1553
1594
|
$errorMessage = collect($e->errors())->flatten()->first();
|
|
1554
1595
|
|
|
1555
|
-
return
|
|
1596
|
+
return $this->apiError($errorMessage, 422);
|
|
1556
1597
|
}
|
|
1557
1598
|
|
|
1558
1599
|
// Determine storage disk & bucket
|
|
@@ -1581,26 +1622,32 @@ class OrderController extends Controller
|
|
|
1581
1622
|
// Normalize into one array
|
|
1582
1623
|
$incoming = array_merge($rawInputs, $base64Inputs);
|
|
1583
1624
|
|
|
1625
|
+
// Defensive only: the validate() above already requires `photos` to be a
|
|
1626
|
+
// non-empty array whose every element is an upload or a decodable base64
|
|
1627
|
+
// string, and each of those survives the filter, so this cannot be empty.
|
|
1628
|
+
// Kept in case those rules are relaxed.
|
|
1629
|
+
// @codeCoverageIgnoreStart
|
|
1584
1630
|
if (empty($incoming)) {
|
|
1585
|
-
return
|
|
1631
|
+
return $this->apiError('No photo data to capture.');
|
|
1586
1632
|
}
|
|
1633
|
+
// @codeCoverageIgnoreEnd
|
|
1587
1634
|
|
|
1588
1635
|
// Load Order
|
|
1589
1636
|
try {
|
|
1590
|
-
$order =
|
|
1637
|
+
$order = $this->findOrder($id, ['payload.pickup', 'payload.dropoff', 'payload.return', 'payload.waypoints', 'payload.waypointMarkers.place']);
|
|
1591
1638
|
} catch (ModelNotFoundException $e) {
|
|
1592
|
-
return
|
|
1639
|
+
return $this->apiError('Order resource not found.', 404);
|
|
1593
1640
|
}
|
|
1594
1641
|
|
|
1595
1642
|
// Resolve subject
|
|
1596
1643
|
$subject = $this->resolveSubject($order, $type, $subjectId);
|
|
1597
1644
|
if (!$subject) {
|
|
1598
|
-
return
|
|
1645
|
+
return $this->apiError('Unable to capture photo as proof.');
|
|
1599
1646
|
}
|
|
1600
1647
|
|
|
1601
1648
|
// 5) Loop through each item, create Proof + File
|
|
1602
1649
|
foreach ($incoming as $item) {
|
|
1603
|
-
$proof =
|
|
1650
|
+
$proof = $this->createProof([
|
|
1604
1651
|
'company_uuid' => session('company'),
|
|
1605
1652
|
'order_uuid' => $order->uuid,
|
|
1606
1653
|
'subject_uuid' => $subject->uuid,
|
|
@@ -1621,7 +1668,7 @@ class OrderController extends Controller
|
|
|
1621
1668
|
}
|
|
1622
1669
|
|
|
1623
1670
|
// Return the last Proof resource created
|
|
1624
|
-
return
|
|
1671
|
+
return $this->proofResource($proof);
|
|
1625
1672
|
}
|
|
1626
1673
|
|
|
1627
1674
|
/**
|
|
@@ -1649,9 +1696,9 @@ class OrderController extends Controller
|
|
|
1649
1696
|
$company = session('company');
|
|
1650
1697
|
$path = "uploads/{$company}/photos/{$proof->public_id}.{$extension}";
|
|
1651
1698
|
|
|
1652
|
-
|
|
1699
|
+
$this->putStorage($disk, $path, $contents);
|
|
1653
1700
|
|
|
1654
|
-
return
|
|
1701
|
+
return $this->createFile([
|
|
1655
1702
|
'company_uuid' => $company,
|
|
1656
1703
|
'uploader_uuid' => session('user'),
|
|
1657
1704
|
'name' => basename($path),
|
|
@@ -1726,9 +1773,9 @@ class OrderController extends Controller
|
|
|
1726
1773
|
public function proofs(Request $request, string $id, ?string $subjectId = null)
|
|
1727
1774
|
{
|
|
1728
1775
|
try {
|
|
1729
|
-
$order =
|
|
1776
|
+
$order = $this->findOrder($id);
|
|
1730
1777
|
} catch (ModelNotFoundException $e) {
|
|
1731
|
-
return
|
|
1778
|
+
return $this->apiError('Order resource not found.', 404);
|
|
1732
1779
|
}
|
|
1733
1780
|
|
|
1734
1781
|
$subject = $order;
|
|
@@ -1738,23 +1785,12 @@ class OrderController extends Controller
|
|
|
1738
1785
|
}
|
|
1739
1786
|
|
|
1740
1787
|
if (!$subject) {
|
|
1741
|
-
return
|
|
1788
|
+
return $this->apiError('Unable to retrieve proof of delivery for subject.');
|
|
1742
1789
|
}
|
|
1743
1790
|
|
|
1744
|
-
$
|
|
1745
|
-
'company_uuid' => session('company'),
|
|
1746
|
-
'order_uuid' => $order->uuid,
|
|
1747
|
-
]);
|
|
1791
|
+
$proofs = $this->proofsForSubject($order, $subject);
|
|
1748
1792
|
|
|
1749
|
-
|
|
1750
|
-
if ($order->uuid !== $subject->uuid) {
|
|
1751
|
-
$proofsQuery->where('subject_uuid', $subject->uuid);
|
|
1752
|
-
}
|
|
1753
|
-
|
|
1754
|
-
// get proofs
|
|
1755
|
-
$proofs = $proofsQuery->get();
|
|
1756
|
-
|
|
1757
|
-
return ProofResource::collection($proofs);
|
|
1793
|
+
return $this->proofResourceCollection($proofs);
|
|
1758
1794
|
}
|
|
1759
1795
|
|
|
1760
1796
|
/**
|
|
@@ -1776,9 +1812,9 @@ class OrderController extends Controller
|
|
|
1776
1812
|
public function getEditableEntityFields(string $id, Request $request)
|
|
1777
1813
|
{
|
|
1778
1814
|
try {
|
|
1779
|
-
$order =
|
|
1815
|
+
$order = $this->findOrder($id);
|
|
1780
1816
|
} catch (ModelNotFoundException $e) {
|
|
1781
|
-
return
|
|
1817
|
+
return $this->apiError('Order resource not found.', 404);
|
|
1782
1818
|
}
|
|
1783
1819
|
|
|
1784
1820
|
// Define settings as array
|
|
@@ -1788,12 +1824,12 @@ class OrderController extends Controller
|
|
|
1788
1824
|
$orderConfigId = data_get($order, 'order_config_uuid');
|
|
1789
1825
|
|
|
1790
1826
|
// Get entity editing settings
|
|
1791
|
-
$savedEntityEditingSettings =
|
|
1827
|
+
$savedEntityEditingSettings = $this->entityEditingSettings();
|
|
1792
1828
|
if ($orderConfigId && $savedEntityEditingSettings) {
|
|
1793
1829
|
$entityEditingSettings = data_get($savedEntityEditingSettings, $orderConfigId, []);
|
|
1794
1830
|
}
|
|
1795
1831
|
|
|
1796
|
-
return
|
|
1832
|
+
return $this->jsonResponse($entityEditingSettings);
|
|
1797
1833
|
}
|
|
1798
1834
|
|
|
1799
1835
|
/**
|
|
@@ -1804,16 +1840,165 @@ class OrderController extends Controller
|
|
|
1804
1840
|
public function orderComments(string $id)
|
|
1805
1841
|
{
|
|
1806
1842
|
try {
|
|
1807
|
-
$order =
|
|
1843
|
+
$order = $this->findOrder($id);
|
|
1808
1844
|
$order->loadMissing('comments');
|
|
1809
1845
|
|
|
1810
|
-
return
|
|
1846
|
+
return $this->commentResourceCollection($order->comments);
|
|
1811
1847
|
} catch (ModelNotFoundException $e) {
|
|
1812
|
-
return
|
|
1848
|
+
return $this->apiError('Order resource not found.', 404);
|
|
1813
1849
|
} catch (\Throwable $e) {
|
|
1814
|
-
return
|
|
1850
|
+
return $this->apiError('An error occured trying to get order comments.', 404);
|
|
1851
|
+
}
|
|
1852
|
+
|
|
1853
|
+
return $this->apiError('An error occured trying to get order comments.', 404);
|
|
1854
|
+
}
|
|
1855
|
+
|
|
1856
|
+
protected function findOrder(string $id, array $with = [], array $withCount = []): Order
|
|
1857
|
+
{
|
|
1858
|
+
return Order::findRecordOrFail($id, $with, $withCount);
|
|
1859
|
+
}
|
|
1860
|
+
|
|
1861
|
+
protected function resolveOrderConfig(array $input): ?OrderConfig
|
|
1862
|
+
{
|
|
1863
|
+
return OrderConfig::resolveFromIdentifier($input);
|
|
1864
|
+
}
|
|
1865
|
+
|
|
1866
|
+
protected function resolveServiceQuote(Request $request): ?ServiceQuote
|
|
1867
|
+
{
|
|
1868
|
+
return ServiceQuote::resolveFromRequest($request);
|
|
1869
|
+
}
|
|
1870
|
+
|
|
1871
|
+
protected function newPayload(): Payload
|
|
1872
|
+
{
|
|
1873
|
+
return new Payload();
|
|
1874
|
+
}
|
|
1875
|
+
|
|
1876
|
+
protected function findDriverByPublicId(string $publicId): ?Driver
|
|
1877
|
+
{
|
|
1878
|
+
return Driver::where(['public_id' => $publicId, 'company_uuid' => session('company')])->first();
|
|
1879
|
+
}
|
|
1880
|
+
|
|
1881
|
+
protected function findDriverByUuid(?string $uuid): ?Driver
|
|
1882
|
+
{
|
|
1883
|
+
return Driver::where('uuid', $uuid)->withoutGlobalScopes()->first();
|
|
1884
|
+
}
|
|
1885
|
+
|
|
1886
|
+
protected function findPayloadByUuid(?string $uuid): ?Payload
|
|
1887
|
+
{
|
|
1888
|
+
return Payload::where('uuid', $uuid)->withoutGlobalScopes()->with(['waypoints', 'waypointMarkers', 'entities'])->first();
|
|
1889
|
+
}
|
|
1890
|
+
|
|
1891
|
+
protected function sessionCompany(): ?string
|
|
1892
|
+
{
|
|
1893
|
+
return session('company');
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1896
|
+
protected function getUuid(array|string $table, array $where, array $options = []): mixed
|
|
1897
|
+
{
|
|
1898
|
+
return Utils::getUuid($table, $where, $options);
|
|
1899
|
+
}
|
|
1900
|
+
|
|
1901
|
+
protected function getModelClassName(mixed $tableOrModel): ?string
|
|
1902
|
+
{
|
|
1903
|
+
return Utils::getModelClassName($tableOrModel);
|
|
1904
|
+
}
|
|
1905
|
+
|
|
1906
|
+
protected function newCustomerContact(array $attributes): Contact
|
|
1907
|
+
{
|
|
1908
|
+
return new Contact($attributes);
|
|
1909
|
+
}
|
|
1910
|
+
|
|
1911
|
+
protected function firstOrCreateCustomerContact(array $attributes, array $values): Contact
|
|
1912
|
+
{
|
|
1913
|
+
return Contact::firstOrCreate($attributes, $values);
|
|
1914
|
+
}
|
|
1915
|
+
|
|
1916
|
+
protected function defaultCompanyTimezone(): string
|
|
1917
|
+
{
|
|
1918
|
+
return data_get(Auth::getCompany(), 'timezone', config('app.timezone'));
|
|
1919
|
+
}
|
|
1920
|
+
|
|
1921
|
+
protected function createOrder(array $input): Order
|
|
1922
|
+
{
|
|
1923
|
+
return Order::create($input);
|
|
1924
|
+
}
|
|
1925
|
+
|
|
1926
|
+
protected function dispatchFinalizeApiOrderCreation(string $orderUuid, ?string $serviceQuoteUuid, bool $shouldDispatch): void
|
|
1927
|
+
{
|
|
1928
|
+
FinalizeApiOrderCreation::dispatch($orderUuid, $serviceQuoteUuid, $shouldDispatch)->afterCommit();
|
|
1929
|
+
}
|
|
1930
|
+
|
|
1931
|
+
protected function drivingDistanceAndTime(mixed $origin, mixed $destination): mixed
|
|
1932
|
+
{
|
|
1933
|
+
return Utils::getDrivingDistanceAndTime($origin, $destination);
|
|
1934
|
+
}
|
|
1935
|
+
|
|
1936
|
+
protected function createProof(array $input): Proof
|
|
1937
|
+
{
|
|
1938
|
+
return Proof::create($input);
|
|
1939
|
+
}
|
|
1940
|
+
|
|
1941
|
+
protected function createFile(array $input): File
|
|
1942
|
+
{
|
|
1943
|
+
return File::create($input);
|
|
1944
|
+
}
|
|
1945
|
+
|
|
1946
|
+
protected function putStorage(string $disk, string $path, string $contents): void
|
|
1947
|
+
{
|
|
1948
|
+
Storage::disk($disk)->put($path, $contents);
|
|
1949
|
+
}
|
|
1950
|
+
|
|
1951
|
+
protected function proofsForSubject(Order $order, mixed $subject)
|
|
1952
|
+
{
|
|
1953
|
+
$proofsQuery = Proof::where([
|
|
1954
|
+
'company_uuid' => session('company'),
|
|
1955
|
+
'order_uuid' => $order->uuid,
|
|
1956
|
+
]);
|
|
1957
|
+
|
|
1958
|
+
if ($order->uuid !== $subject->uuid) {
|
|
1959
|
+
$proofsQuery->where('subject_uuid', $subject->uuid);
|
|
1815
1960
|
}
|
|
1816
1961
|
|
|
1817
|
-
return
|
|
1962
|
+
return $proofsQuery->get();
|
|
1963
|
+
}
|
|
1964
|
+
|
|
1965
|
+
protected function entityEditingSettings(): mixed
|
|
1966
|
+
{
|
|
1967
|
+
return Setting::where('key', 'fleet-ops.entity-editing-settings')->value('value');
|
|
1968
|
+
}
|
|
1969
|
+
|
|
1970
|
+
protected function orderResource(Order $order)
|
|
1971
|
+
{
|
|
1972
|
+
return new OrderResource($order);
|
|
1973
|
+
}
|
|
1974
|
+
|
|
1975
|
+
protected function deletedOrderResource(Order $order)
|
|
1976
|
+
{
|
|
1977
|
+
return new DeletedResource($order);
|
|
1978
|
+
}
|
|
1979
|
+
|
|
1980
|
+
protected function proofResource(Proof $proof)
|
|
1981
|
+
{
|
|
1982
|
+
return new ProofResource($proof);
|
|
1983
|
+
}
|
|
1984
|
+
|
|
1985
|
+
protected function proofResourceCollection($proofs)
|
|
1986
|
+
{
|
|
1987
|
+
return ProofResource::collection($proofs);
|
|
1988
|
+
}
|
|
1989
|
+
|
|
1990
|
+
protected function commentResourceCollection($comments)
|
|
1991
|
+
{
|
|
1992
|
+
return CommentResource::collection($comments);
|
|
1993
|
+
}
|
|
1994
|
+
|
|
1995
|
+
protected function jsonResponse(mixed $payload, int $status = 200)
|
|
1996
|
+
{
|
|
1997
|
+
return response()->json($payload, $status);
|
|
1998
|
+
}
|
|
1999
|
+
|
|
2000
|
+
protected function apiError(string $message, int $status = 400)
|
|
2001
|
+
{
|
|
2002
|
+
return response()->apiError($message, $status);
|
|
1818
2003
|
}
|
|
1819
2004
|
}
|