@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
|
@@ -54,7 +54,7 @@ class CustomerController extends Controller
|
|
|
54
54
|
{
|
|
55
55
|
$mode = $request->input('mode', 'email');
|
|
56
56
|
$identity = $request->input('identity');
|
|
57
|
-
$isEmail =
|
|
57
|
+
$isEmail = $this->isEmail($identity);
|
|
58
58
|
|
|
59
59
|
if ($mode === 'email' && !$isEmail) {
|
|
60
60
|
return response()->apiError('Invalid email provided for identity.');
|
|
@@ -64,7 +64,7 @@ class CustomerController extends Controller
|
|
|
64
64
|
$identity = static::phone($identity);
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
$sessionCompany =
|
|
67
|
+
$sessionCompany = $this->sessionCompany();
|
|
68
68
|
if (!$sessionCompany) {
|
|
69
69
|
return response()->apiError('No company resolved from API credential.', 500);
|
|
70
70
|
}
|
|
@@ -80,14 +80,12 @@ class CustomerController extends Controller
|
|
|
80
80
|
// template references `$user->name`). Look up — or create — the User
|
|
81
81
|
// before sending. `create()` later backfills password + remaining fields
|
|
82
82
|
// on this same row when the customer confirms the code.
|
|
83
|
-
$subject = $isEmail
|
|
84
|
-
? User::where('email', $identity)->whereNull('deleted_at')->withoutGlobalScopes()->first()
|
|
85
|
-
: User::where('phone', $identity)->whereNull('deleted_at')->withoutGlobalScopes()->first();
|
|
83
|
+
$subject = $this->findActiveUserByIdentity($identity, $isEmail ? 'email' : 'phone');
|
|
86
84
|
|
|
87
85
|
if (!$subject) {
|
|
88
86
|
// `password` and `type` are guarded on User; assign type after create
|
|
89
87
|
// via setUserType (saves the row).
|
|
90
|
-
$subject =
|
|
88
|
+
$subject = $this->createUser([
|
|
91
89
|
'company_uuid' => $sessionCompany,
|
|
92
90
|
'name' => $providedName !== '' ? $providedName : $identity,
|
|
93
91
|
'email' => $isEmail ? $identity : null,
|
|
@@ -108,13 +106,13 @@ class CustomerController extends Controller
|
|
|
108
106
|
|
|
109
107
|
try {
|
|
110
108
|
if ($mode === 'email') {
|
|
111
|
-
|
|
109
|
+
$this->generateEmailVerification($subject, 'fleetops_create_customer', [
|
|
112
110
|
'subject' => config('app.name') . ' verification code',
|
|
113
111
|
'messageCallback' => fn ($verification) => 'Your ' . config('app.name') . ' verification code is ' . $verification->code,
|
|
114
112
|
'meta' => $meta,
|
|
115
113
|
]);
|
|
116
114
|
} else {
|
|
117
|
-
|
|
115
|
+
$this->generateSmsVerification($subject, 'fleetops_create_customer', [
|
|
118
116
|
'messageCallback' => fn ($verification) => 'Your ' . config('app.name') . ' verification code is ' . $verification->code,
|
|
119
117
|
'meta' => $meta,
|
|
120
118
|
]);
|
|
@@ -135,22 +133,22 @@ class CustomerController extends Controller
|
|
|
135
133
|
{
|
|
136
134
|
$code = $request->input('code');
|
|
137
135
|
$identity = $request->input('identity');
|
|
138
|
-
$isEmail =
|
|
136
|
+
$isEmail = $this->isEmail($identity);
|
|
139
137
|
if (!$isEmail) {
|
|
140
138
|
$identity = static::phone($identity);
|
|
141
139
|
}
|
|
142
140
|
|
|
143
141
|
// Verify the code is one we sent for this identity.
|
|
144
|
-
$verificationCode =
|
|
142
|
+
$verificationCode = $this->verificationCodeExists([
|
|
145
143
|
'code' => $code,
|
|
146
144
|
'for' => 'fleetops_create_customer',
|
|
147
145
|
'meta->identity' => $identity,
|
|
148
|
-
])
|
|
146
|
+
]);
|
|
149
147
|
if (!$verificationCode) {
|
|
150
148
|
return response()->apiError('Invalid verification code provided.');
|
|
151
149
|
}
|
|
152
150
|
|
|
153
|
-
$sessionCompany =
|
|
151
|
+
$sessionCompany = $this->sessionCompany();
|
|
154
152
|
if (!$sessionCompany) {
|
|
155
153
|
return response()->apiError('No company resolved from API credential.', 500);
|
|
156
154
|
}
|
|
@@ -158,15 +156,15 @@ class CustomerController extends Controller
|
|
|
158
156
|
// Attach to existing User if one matches the identity, otherwise create one.
|
|
159
157
|
$user = null;
|
|
160
158
|
if ($isEmail) {
|
|
161
|
-
$user =
|
|
159
|
+
$user = $this->findActiveUserByIdentity($identity, 'email');
|
|
162
160
|
} elseif (Str::startsWith($identity, '+')) {
|
|
163
|
-
$user =
|
|
161
|
+
$user = $this->findActiveUserByIdentity($identity, 'phone');
|
|
164
162
|
}
|
|
165
163
|
|
|
166
164
|
if (!$user) {
|
|
167
165
|
// `password` and `type` are guarded on User; assign them after create
|
|
168
166
|
// (setUserType saves the type, setPasswordAttribute hashes plaintext).
|
|
169
|
-
$user =
|
|
167
|
+
$user = $this->createUser([
|
|
170
168
|
'company_uuid' => $sessionCompany,
|
|
171
169
|
'name' => $request->input('name'),
|
|
172
170
|
'email' => $isEmail ? $identity : $request->input('email'),
|
|
@@ -215,15 +213,15 @@ class CustomerController extends Controller
|
|
|
215
213
|
// Handle photo as either file id or base64 data.
|
|
216
214
|
$photo = $request->input('photo');
|
|
217
215
|
if ($photo) {
|
|
218
|
-
if (
|
|
219
|
-
$file =
|
|
216
|
+
if ($this->isPublicId($photo)) {
|
|
217
|
+
$file = $this->findFileByPublicId($photo);
|
|
220
218
|
if ($file) {
|
|
221
219
|
$input['photo_uuid'] = $file->uuid;
|
|
222
220
|
}
|
|
223
221
|
}
|
|
224
|
-
if (
|
|
222
|
+
if ($this->isBase64String($photo)) {
|
|
225
223
|
$path = implode('/', ['uploads', $sessionCompany, 'customers']);
|
|
226
|
-
$file =
|
|
224
|
+
$file = $this->createFileFromBase64($photo, $path);
|
|
227
225
|
if ($file) {
|
|
228
226
|
$input['photo_uuid'] = $file->uuid;
|
|
229
227
|
}
|
|
@@ -232,22 +230,22 @@ class CustomerController extends Controller
|
|
|
232
230
|
|
|
233
231
|
// Reuse an existing customer-Contact for this user+company if one exists
|
|
234
232
|
// (idempotent re-signup), otherwise create one.
|
|
235
|
-
$contact =
|
|
233
|
+
$contact = $this->findCustomerContact([
|
|
236
234
|
'company_uuid' => $sessionCompany,
|
|
237
235
|
'user_uuid' => $user->uuid,
|
|
238
236
|
'type' => 'customer',
|
|
239
|
-
])
|
|
237
|
+
]);
|
|
240
238
|
if ($contact) {
|
|
241
239
|
$contact->fill(array_filter($input, fn ($v) => $v !== null && $v !== ''))->save();
|
|
242
240
|
} else {
|
|
243
241
|
try {
|
|
244
|
-
$contact =
|
|
242
|
+
$contact = $this->createContact($input);
|
|
245
243
|
} catch (UserAlreadyExistsException $e) {
|
|
246
|
-
$contact =
|
|
244
|
+
$contact = $this->findCustomerContact([
|
|
247
245
|
'company_uuid' => $sessionCompany,
|
|
248
246
|
'user_uuid' => $user->uuid,
|
|
249
247
|
'type' => 'customer',
|
|
250
|
-
])
|
|
248
|
+
]);
|
|
251
249
|
if (!$contact) {
|
|
252
250
|
return response()->apiError($e->getMessage());
|
|
253
251
|
}
|
|
@@ -272,10 +270,10 @@ class CustomerController extends Controller
|
|
|
272
270
|
}
|
|
273
271
|
}
|
|
274
272
|
|
|
275
|
-
$token = $
|
|
273
|
+
$token = $this->createCustomerToken($user, $contact);
|
|
276
274
|
$contact->token = $token->plainTextToken;
|
|
277
275
|
|
|
278
|
-
return
|
|
276
|
+
return $this->customerResource($contact);
|
|
279
277
|
}
|
|
280
278
|
|
|
281
279
|
/**
|
|
@@ -293,7 +291,7 @@ class CustomerController extends Controller
|
|
|
293
291
|
}
|
|
294
292
|
|
|
295
293
|
if (is_string($input)) {
|
|
296
|
-
return
|
|
294
|
+
return $this->findPlaceByPublicId($input, $companyUuid);
|
|
297
295
|
}
|
|
298
296
|
|
|
299
297
|
if (!is_array($input)) {
|
|
@@ -309,7 +307,7 @@ class CustomerController extends Controller
|
|
|
309
307
|
return null;
|
|
310
308
|
}
|
|
311
309
|
|
|
312
|
-
return
|
|
310
|
+
return $this->createPlace(array_merge(
|
|
313
311
|
[
|
|
314
312
|
'company_uuid' => $companyUuid,
|
|
315
313
|
'owner_uuid' => $contact->uuid,
|
|
@@ -330,20 +328,18 @@ class CustomerController extends Controller
|
|
|
330
328
|
return response()->apiError('Identity and password are required.', 400);
|
|
331
329
|
}
|
|
332
330
|
|
|
333
|
-
$user =
|
|
334
|
-
->orWhere('phone', static::phone($identity))
|
|
335
|
-
->first();
|
|
331
|
+
$user = $this->findUserForLogin($identity);
|
|
336
332
|
|
|
337
|
-
if (!$user || !$user->password ||
|
|
333
|
+
if (!$user || !$user->password || !$this->passwordMatches($password, $user->password)) {
|
|
338
334
|
return response()->apiError('Authentication failed using credentials provided.', 401);
|
|
339
335
|
}
|
|
340
336
|
|
|
341
|
-
$sessionCompany =
|
|
337
|
+
$sessionCompany = $this->sessionCompany();
|
|
342
338
|
if (!$sessionCompany) {
|
|
343
339
|
return response()->apiError('No company resolved from API credential.', 500);
|
|
344
340
|
}
|
|
345
341
|
|
|
346
|
-
$contact =
|
|
342
|
+
$contact = $this->firstOrCreateCustomerContact(
|
|
347
343
|
[
|
|
348
344
|
'user_uuid' => $user->uuid,
|
|
349
345
|
'company_uuid' => $sessionCompany,
|
|
@@ -356,10 +352,10 @@ class CustomerController extends Controller
|
|
|
356
352
|
]
|
|
357
353
|
);
|
|
358
354
|
|
|
359
|
-
$token = $
|
|
355
|
+
$token = $this->createCustomerToken($user, $contact);
|
|
360
356
|
$contact->token = $token->plainTextToken;
|
|
361
357
|
|
|
362
|
-
return
|
|
358
|
+
return $this->customerResource($contact);
|
|
363
359
|
}
|
|
364
360
|
|
|
365
361
|
/**
|
|
@@ -369,13 +365,13 @@ class CustomerController extends Controller
|
|
|
369
365
|
{
|
|
370
366
|
$phone = static::phone($request->input('phone') ?? $request->input('identity'));
|
|
371
367
|
|
|
372
|
-
$user =
|
|
368
|
+
$user = $this->findActiveUserByIdentity($phone, 'phone');
|
|
373
369
|
if (!$user) {
|
|
374
370
|
return response()->apiError('No customer with this phone number found.');
|
|
375
371
|
}
|
|
376
372
|
|
|
377
373
|
try {
|
|
378
|
-
|
|
374
|
+
$this->generateSmsVerification($user, 'fleetops_customer_login', [
|
|
379
375
|
'messageCallback' => fn ($verification) => 'Your ' . config('app.name') . ' verification code is ' . $verification->code,
|
|
380
376
|
]);
|
|
381
377
|
|
|
@@ -383,7 +379,7 @@ class CustomerController extends Controller
|
|
|
383
379
|
} catch (\Throwable $e) {
|
|
384
380
|
if ($user->email) {
|
|
385
381
|
try {
|
|
386
|
-
|
|
382
|
+
$this->generateEmailVerification($user, 'fleetops_customer_login', [
|
|
387
383
|
'subject' => config('app.name') . ' verification code',
|
|
388
384
|
'messageCallback' => fn ($verification) => 'Your ' . config('app.name') . ' verification code is ' . $verification->code,
|
|
389
385
|
]);
|
|
@@ -403,30 +399,30 @@ class CustomerController extends Controller
|
|
|
403
399
|
*/
|
|
404
400
|
public function verifyCode(Request $request)
|
|
405
401
|
{
|
|
406
|
-
$identity =
|
|
402
|
+
$identity = $this->isEmail($request->input('identity')) ? $request->input('identity') : static::phone($request->input('identity'));
|
|
407
403
|
$code = $request->input('code');
|
|
408
404
|
$for = $request->input('for', 'fleetops_customer_login');
|
|
409
405
|
|
|
410
406
|
if ($for === 'fleetops_create_customer') {
|
|
411
|
-
return $this->create($request);
|
|
407
|
+
return $this->create(CreateCustomerRequest::createFrom($request));
|
|
412
408
|
}
|
|
413
409
|
|
|
414
|
-
$user =
|
|
410
|
+
$user = $this->findUserForVerification($identity);
|
|
415
411
|
if (!$user) {
|
|
416
412
|
return response()->apiError('Unable to verify code.');
|
|
417
413
|
}
|
|
418
414
|
|
|
419
|
-
$verificationCode =
|
|
415
|
+
$verificationCode = $this->verificationCodeExists([
|
|
420
416
|
'subject_uuid' => $user->uuid,
|
|
421
417
|
'code' => $code,
|
|
422
418
|
'for' => $for,
|
|
423
|
-
])
|
|
419
|
+
]);
|
|
424
420
|
if (!$verificationCode) {
|
|
425
421
|
return response()->apiError('Invalid verification code.');
|
|
426
422
|
}
|
|
427
423
|
|
|
428
|
-
$sessionCompany =
|
|
429
|
-
$contact =
|
|
424
|
+
$sessionCompany = $this->sessionCompany();
|
|
425
|
+
$contact = $this->firstOrCreateCustomerContact(
|
|
430
426
|
[
|
|
431
427
|
'user_uuid' => $user->uuid,
|
|
432
428
|
'company_uuid' => $sessionCompany,
|
|
@@ -439,10 +435,10 @@ class CustomerController extends Controller
|
|
|
439
435
|
]
|
|
440
436
|
);
|
|
441
437
|
|
|
442
|
-
$token = $
|
|
438
|
+
$token = $this->createCustomerToken($user, $contact);
|
|
443
439
|
$contact->token = $token->plainTextToken;
|
|
444
440
|
|
|
445
|
-
return
|
|
441
|
+
return $this->customerResource($contact);
|
|
446
442
|
}
|
|
447
443
|
|
|
448
444
|
/**
|
|
@@ -455,10 +451,8 @@ class CustomerController extends Controller
|
|
|
455
451
|
return response()->apiError('Identity is required.', 400);
|
|
456
452
|
}
|
|
457
453
|
|
|
458
|
-
$isEmail =
|
|
459
|
-
$user = $isEmail
|
|
460
|
-
? User::where('email', $identity)->first()
|
|
461
|
-
: User::where('phone', static::phone($identity))->first();
|
|
454
|
+
$isEmail = $this->isEmail($identity);
|
|
455
|
+
$user = $this->findUserByIdentity($isEmail ? $identity : static::phone($identity), $isEmail ? 'email' : 'phone');
|
|
462
456
|
|
|
463
457
|
if (!$user) {
|
|
464
458
|
// Don't leak account existence — return success regardless.
|
|
@@ -468,13 +462,13 @@ class CustomerController extends Controller
|
|
|
468
462
|
$meta = ['identity' => $isEmail ? $identity : static::phone($identity)];
|
|
469
463
|
try {
|
|
470
464
|
if ($isEmail) {
|
|
471
|
-
|
|
465
|
+
$this->generateEmailVerification($user, 'fleetops_customer_password_reset', [
|
|
472
466
|
'subject' => config('app.name') . ' password reset',
|
|
473
467
|
'messageCallback' => fn ($v) => 'Your ' . config('app.name') . ' password reset code is ' . $v->code,
|
|
474
468
|
'meta' => $meta,
|
|
475
469
|
]);
|
|
476
470
|
} else {
|
|
477
|
-
|
|
471
|
+
$this->generateSmsVerification($user, 'fleetops_customer_password_reset', [
|
|
478
472
|
'messageCallback' => fn ($v) => 'Your ' . config('app.name') . ' password reset code is ' . $v->code,
|
|
479
473
|
'meta' => $meta,
|
|
480
474
|
]);
|
|
@@ -501,21 +495,19 @@ class CustomerController extends Controller
|
|
|
501
495
|
return response()->apiError('Password must be at least 8 characters.', 400);
|
|
502
496
|
}
|
|
503
497
|
|
|
504
|
-
$isEmail =
|
|
498
|
+
$isEmail = $this->isEmail($identity);
|
|
505
499
|
$needle = $isEmail ? $identity : static::phone($identity);
|
|
506
500
|
|
|
507
|
-
$verificationCode =
|
|
501
|
+
$verificationCode = $this->findVerificationCode([
|
|
508
502
|
'code' => $code,
|
|
509
503
|
'for' => 'fleetops_customer_password_reset',
|
|
510
504
|
'meta->identity' => $needle,
|
|
511
|
-
])
|
|
505
|
+
]);
|
|
512
506
|
if (!$verificationCode) {
|
|
513
507
|
return response()->apiError('Invalid reset code.');
|
|
514
508
|
}
|
|
515
509
|
|
|
516
|
-
$user = $isEmail
|
|
517
|
-
? User::where('email', $needle)->first()
|
|
518
|
-
: User::where('phone', $needle)->first();
|
|
510
|
+
$user = $this->findUserByIdentity($needle, $isEmail ? 'email' : 'phone');
|
|
519
511
|
if (!$user) {
|
|
520
512
|
return response()->apiError('Account not found.');
|
|
521
513
|
}
|
|
@@ -524,7 +516,7 @@ class CustomerController extends Controller
|
|
|
524
516
|
$user->password = $password;
|
|
525
517
|
$user->save();
|
|
526
518
|
// Invalidate all existing sessions for this user after a password reset.
|
|
527
|
-
$
|
|
519
|
+
$this->deleteUserTokens($user);
|
|
528
520
|
$verificationCode->delete();
|
|
529
521
|
|
|
530
522
|
return response()->json(['status' => 'ok']);
|
|
@@ -539,12 +531,12 @@ class CustomerController extends Controller
|
|
|
539
531
|
*/
|
|
540
532
|
public function me()
|
|
541
533
|
{
|
|
542
|
-
$customer =
|
|
534
|
+
$customer = $this->currentCustomer();
|
|
543
535
|
if (!$customer) {
|
|
544
536
|
return response()->apiError('Not authenticated.', 401);
|
|
545
537
|
}
|
|
546
538
|
|
|
547
|
-
return
|
|
539
|
+
return $this->customerResource($customer);
|
|
548
540
|
}
|
|
549
541
|
|
|
550
542
|
/**
|
|
@@ -552,7 +544,7 @@ class CustomerController extends Controller
|
|
|
552
544
|
*/
|
|
553
545
|
public function updateMe(UpdateContactRequest $request)
|
|
554
546
|
{
|
|
555
|
-
$customer =
|
|
547
|
+
$customer = $this->currentCustomer();
|
|
556
548
|
if (!$customer) {
|
|
557
549
|
return response()->apiError('Not authenticated.', 401);
|
|
558
550
|
}
|
|
@@ -565,15 +557,15 @@ class CustomerController extends Controller
|
|
|
565
557
|
// Photo handling.
|
|
566
558
|
$photo = $request->input('photo');
|
|
567
559
|
if ($photo) {
|
|
568
|
-
if (
|
|
569
|
-
$file =
|
|
560
|
+
if ($this->isPublicId($photo)) {
|
|
561
|
+
$file = $this->findFileByPublicId($photo);
|
|
570
562
|
if ($file) {
|
|
571
563
|
$input['photo_uuid'] = $file->uuid;
|
|
572
564
|
}
|
|
573
565
|
}
|
|
574
|
-
if (
|
|
575
|
-
$path = implode('/', ['uploads',
|
|
576
|
-
$file =
|
|
566
|
+
if ($this->isBase64String($photo)) {
|
|
567
|
+
$path = implode('/', ['uploads', $this->sessionCompany(), 'customers']);
|
|
568
|
+
$file = $this->createFileFromBase64($photo, $path);
|
|
577
569
|
if ($file) {
|
|
578
570
|
$input['photo_uuid'] = $file->uuid;
|
|
579
571
|
}
|
|
@@ -597,11 +589,11 @@ class CustomerController extends Controller
|
|
|
597
589
|
'phone' => $input['phone'] ?? null,
|
|
598
590
|
], fn ($v) => $v !== null);
|
|
599
591
|
if (!empty($userUpdate)) {
|
|
600
|
-
|
|
592
|
+
$this->updateUserByUuid($customer->user_uuid, $userUpdate);
|
|
601
593
|
}
|
|
602
594
|
}
|
|
603
595
|
|
|
604
|
-
return
|
|
596
|
+
return $this->customerResource($customer->fresh());
|
|
605
597
|
}
|
|
606
598
|
|
|
607
599
|
/**
|
|
@@ -609,13 +601,13 @@ class CustomerController extends Controller
|
|
|
609
601
|
*/
|
|
610
602
|
public function logout(Request $request)
|
|
611
603
|
{
|
|
612
|
-
$customer =
|
|
604
|
+
$customer = $this->currentCustomer();
|
|
613
605
|
if (!$customer) {
|
|
614
606
|
return response()->apiError('Not authenticated.', 401);
|
|
615
607
|
}
|
|
616
608
|
|
|
617
609
|
$tokenString = $request->header(CustomerAuth::HEADER);
|
|
618
|
-
$accessToken = $tokenString ?
|
|
610
|
+
$accessToken = $tokenString ? $this->findAccessToken($tokenString) : null;
|
|
619
611
|
if ($accessToken) {
|
|
620
612
|
$accessToken->delete();
|
|
621
613
|
}
|
|
@@ -628,14 +620,14 @@ class CustomerController extends Controller
|
|
|
628
620
|
*/
|
|
629
621
|
public function logoutAll()
|
|
630
622
|
{
|
|
631
|
-
$customer =
|
|
623
|
+
$customer = $this->currentCustomer();
|
|
632
624
|
if (!$customer || !$customer->user_uuid) {
|
|
633
625
|
return response()->apiError('Not authenticated.', 401);
|
|
634
626
|
}
|
|
635
627
|
|
|
636
|
-
$user =
|
|
628
|
+
$user = $this->findUserByUuid($customer->user_uuid);
|
|
637
629
|
if ($user) {
|
|
638
|
-
$
|
|
630
|
+
$this->deleteUserTokens($user);
|
|
639
631
|
}
|
|
640
632
|
|
|
641
633
|
return response()->json(['status' => 'ok']);
|
|
@@ -646,18 +638,18 @@ class CustomerController extends Controller
|
|
|
646
638
|
*/
|
|
647
639
|
public function orders(Request $request)
|
|
648
640
|
{
|
|
649
|
-
$customer =
|
|
641
|
+
$customer = $this->currentCustomer();
|
|
650
642
|
if (!$customer) {
|
|
651
643
|
return response()->apiError('Not authenticated.', 401);
|
|
652
644
|
}
|
|
653
645
|
|
|
654
|
-
$results =
|
|
646
|
+
$results = $this->queryOrders($request, function (&$query) use ($customer) {
|
|
655
647
|
$query->where('customer_uuid', $customer->uuid)
|
|
656
648
|
->whereNull('deleted_at')
|
|
657
649
|
->withoutGlobalScopes();
|
|
658
650
|
});
|
|
659
651
|
|
|
660
|
-
return
|
|
652
|
+
return $this->orderResourceCollection($results);
|
|
661
653
|
}
|
|
662
654
|
|
|
663
655
|
/**
|
|
@@ -665,13 +657,13 @@ class CustomerController extends Controller
|
|
|
665
657
|
*/
|
|
666
658
|
public function findOrder(string $id)
|
|
667
659
|
{
|
|
668
|
-
$customer =
|
|
660
|
+
$customer = $this->currentCustomer();
|
|
669
661
|
if (!$customer) {
|
|
670
662
|
return response()->apiError('Not authenticated.', 401);
|
|
671
663
|
}
|
|
672
664
|
|
|
673
665
|
try {
|
|
674
|
-
$order =
|
|
666
|
+
$order = $this->findOrderOrFail($id);
|
|
675
667
|
} catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
|
|
676
668
|
return response()->apiError('Order not found.', 404);
|
|
677
669
|
}
|
|
@@ -680,7 +672,7 @@ class CustomerController extends Controller
|
|
|
680
672
|
return response()->apiError('Order not found.', 404);
|
|
681
673
|
}
|
|
682
674
|
|
|
683
|
-
return
|
|
675
|
+
return $this->orderResource($order);
|
|
684
676
|
}
|
|
685
677
|
|
|
686
678
|
/**
|
|
@@ -699,19 +691,18 @@ class CustomerController extends Controller
|
|
|
699
691
|
*/
|
|
700
692
|
public function createOrder(CreateCustomerOrderRequest $request)
|
|
701
693
|
{
|
|
702
|
-
$customer =
|
|
694
|
+
$customer = $this->currentCustomer();
|
|
703
695
|
if (!$customer) {
|
|
704
696
|
return response()->apiError('Not authenticated.', 401);
|
|
705
697
|
}
|
|
706
698
|
|
|
707
|
-
$sessionCompany =
|
|
699
|
+
$sessionCompany = $this->sessionCompany();
|
|
708
700
|
if (!$sessionCompany) {
|
|
709
701
|
return response()->apiError('No company resolved from API credential.', 500);
|
|
710
702
|
}
|
|
711
703
|
|
|
712
704
|
// Resolve the order config for this order. Mirrors OrderController::create.
|
|
713
|
-
$orderConfig =
|
|
714
|
-
?: OrderConfig::where('company_uuid', $sessionCompany)->first();
|
|
705
|
+
$orderConfig = $this->resolveOrderConfig($request, $sessionCompany);
|
|
715
706
|
if (!$orderConfig) {
|
|
716
707
|
return response()->apiError('No order config available for this company.', 422);
|
|
717
708
|
}
|
|
@@ -725,7 +716,7 @@ class CustomerController extends Controller
|
|
|
725
716
|
$payloadInput = (array) $request->input('payload');
|
|
726
717
|
$payloadUuid = $this->buildPayloadFromInput($payloadInput, $sessionCompany)->uuid;
|
|
727
718
|
} elseif ($request->isString('payload')) {
|
|
728
|
-
$payloadUuid =
|
|
719
|
+
$payloadUuid = $this->getUuid('payloads', [
|
|
729
720
|
'public_id' => $request->input('payload'),
|
|
730
721
|
'company_uuid' => $sessionCompany,
|
|
731
722
|
]);
|
|
@@ -736,10 +727,10 @@ class CustomerController extends Controller
|
|
|
736
727
|
}
|
|
737
728
|
}
|
|
738
729
|
|
|
739
|
-
$order =
|
|
730
|
+
$order = $this->createOrderRecord([
|
|
740
731
|
'company_uuid' => $sessionCompany,
|
|
741
732
|
'customer_uuid' => $customer->uuid,
|
|
742
|
-
'customer_type' =>
|
|
733
|
+
'customer_type' => $this->getModelClassName('contact'),
|
|
743
734
|
'payload_uuid' => $payloadUuid,
|
|
744
735
|
'order_config_uuid' => $orderConfig->uuid,
|
|
745
736
|
'type' => $orderConfig->key,
|
|
@@ -753,12 +744,12 @@ class CustomerController extends Controller
|
|
|
753
744
|
// If the customer picked a ServiceQuote up front, consume it now to
|
|
754
745
|
// lock the pricing onto the order's PurchaseRate (mirrors how
|
|
755
746
|
// OrderController::create handles `service_quote`).
|
|
756
|
-
$serviceQuote =
|
|
747
|
+
$serviceQuote = $this->resolveServiceQuote($request);
|
|
757
748
|
if ($serviceQuote instanceof ServiceQuote) {
|
|
758
749
|
$order->purchaseServiceQuote($serviceQuote);
|
|
759
750
|
}
|
|
760
751
|
|
|
761
|
-
return
|
|
752
|
+
return $this->orderResource($order->fresh(['payload', 'payload.pickup', 'payload.dropoff', 'payload.entities']));
|
|
762
753
|
}
|
|
763
754
|
|
|
764
755
|
/**
|
|
@@ -769,7 +760,7 @@ class CustomerController extends Controller
|
|
|
769
760
|
*/
|
|
770
761
|
protected function buildPayloadFromInput(array $payloadInput, string $companyUuid): Payload
|
|
771
762
|
{
|
|
772
|
-
$payload =
|
|
763
|
+
$payload = $this->newPayload();
|
|
773
764
|
$entities = data_get($payloadInput, 'entities', []);
|
|
774
765
|
$waypoints = data_get($payloadInput, 'waypoints', []);
|
|
775
766
|
$pickup = data_get($payloadInput, 'pickup');
|
|
@@ -810,16 +801,16 @@ class CustomerController extends Controller
|
|
|
810
801
|
*/
|
|
811
802
|
public function places(Request $request)
|
|
812
803
|
{
|
|
813
|
-
$customer =
|
|
804
|
+
$customer = $this->currentCustomer();
|
|
814
805
|
if (!$customer) {
|
|
815
806
|
return response()->apiError('Not authenticated.', 401);
|
|
816
807
|
}
|
|
817
808
|
|
|
818
|
-
$results =
|
|
809
|
+
$results = $this->queryPlaces($request, function (&$query) use ($customer) {
|
|
819
810
|
$query->where('owner_uuid', $customer->uuid);
|
|
820
811
|
});
|
|
821
812
|
|
|
822
|
-
return
|
|
813
|
+
return $this->placeResourceCollection($results);
|
|
823
814
|
}
|
|
824
815
|
|
|
825
816
|
/**
|
|
@@ -827,12 +818,12 @@ class CustomerController extends Controller
|
|
|
827
818
|
*/
|
|
828
819
|
public function registerDevice(Request $request)
|
|
829
820
|
{
|
|
830
|
-
$customer =
|
|
821
|
+
$customer = $this->currentCustomer();
|
|
831
822
|
if (!$customer) {
|
|
832
823
|
return response()->apiError('Not authenticated.', 401);
|
|
833
824
|
}
|
|
834
825
|
|
|
835
|
-
$device =
|
|
826
|
+
$device = $this->firstOrCreateDevice(
|
|
836
827
|
[
|
|
837
828
|
'token' => $request->input('token'),
|
|
838
829
|
'platform' => $request->input('platform', $request->input('os')),
|
|
@@ -855,6 +846,214 @@ class CustomerController extends Controller
|
|
|
855
846
|
| Helpers
|
|
856
847
|
* ============================================================ */
|
|
857
848
|
|
|
849
|
+
protected function isEmail(?string $identity): bool
|
|
850
|
+
{
|
|
851
|
+
return Utils::isEmail($identity);
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
protected function isPublicId(?string $value): bool
|
|
855
|
+
{
|
|
856
|
+
return Utils::isPublicId($value);
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
protected function isBase64String(?string $value): bool
|
|
860
|
+
{
|
|
861
|
+
return Utils::isBase64String($value);
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
protected function sessionCompany(): ?string
|
|
865
|
+
{
|
|
866
|
+
return session('company');
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
protected function currentCustomer(): ?Contact
|
|
870
|
+
{
|
|
871
|
+
return CustomerAuth::current();
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
protected function findActiveUserByIdentity(string $identity, string $column): ?User
|
|
875
|
+
{
|
|
876
|
+
return User::where($column, $identity)->whereNull('deleted_at')->withoutGlobalScopes()->first();
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
protected function findUserByIdentity(string $identity, string $column): ?User
|
|
880
|
+
{
|
|
881
|
+
return User::where($column, $identity)->first();
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
protected function findUserForLogin(string $identity): ?User
|
|
885
|
+
{
|
|
886
|
+
return User::where('email', $identity)
|
|
887
|
+
->orWhere('phone', static::phone($identity))
|
|
888
|
+
->first();
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
protected function findUserForVerification(string $identity): ?User
|
|
892
|
+
{
|
|
893
|
+
return User::where('phone', $identity)->orWhere('email', $identity)->first();
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
protected function findUserByUuid(string $uuid): ?User
|
|
897
|
+
{
|
|
898
|
+
return User::where('uuid', $uuid)->first();
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
protected function createUser(array $attributes): User
|
|
902
|
+
{
|
|
903
|
+
return User::create($attributes);
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
protected function passwordMatches(string $password, string $hash): bool
|
|
907
|
+
{
|
|
908
|
+
return Hash::check($password, $hash);
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
protected function generateEmailVerification(User $user, string $for, array $options): mixed
|
|
912
|
+
{
|
|
913
|
+
return VerificationCode::generateEmailVerificationFor($user, $for, $options);
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
protected function generateSmsVerification(User $user, string $for, array $options): mixed
|
|
917
|
+
{
|
|
918
|
+
return VerificationCode::generateSmsVerificationFor($user, $for, $options);
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
protected function verificationCodeExists(array $attributes): bool
|
|
922
|
+
{
|
|
923
|
+
return VerificationCode::where($attributes)->exists();
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
protected function findVerificationCode(array $attributes): mixed
|
|
927
|
+
{
|
|
928
|
+
return VerificationCode::where($attributes)->first();
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
protected function findFileByPublicId(string $publicId): mixed
|
|
932
|
+
{
|
|
933
|
+
return File::where('public_id', $publicId)->first();
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
protected function createFileFromBase64(string $contents, string $path): mixed
|
|
937
|
+
{
|
|
938
|
+
return File::createFromBase64($contents, null, $path);
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
protected function findCustomerContact(array $attributes): ?Contact
|
|
942
|
+
{
|
|
943
|
+
return Contact::where($attributes)->first();
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
protected function createContact(array $attributes): Contact
|
|
947
|
+
{
|
|
948
|
+
return Contact::create($attributes);
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
protected function firstOrCreateCustomerContact(array $attributes, array $values): Contact
|
|
952
|
+
{
|
|
953
|
+
return Contact::firstOrCreate($attributes, $values);
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
protected function createCustomerToken(User $user, Contact $contact): mixed
|
|
957
|
+
{
|
|
958
|
+
return $user->createToken($contact->uuid);
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
protected function findPlaceByPublicId(string $publicId, string $companyUuid): ?Place
|
|
962
|
+
{
|
|
963
|
+
return Place::where(['public_id' => $publicId, 'company_uuid' => $companyUuid])->first();
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
protected function createPlace(array $attributes): Place
|
|
967
|
+
{
|
|
968
|
+
return Place::create($attributes);
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
protected function updateUserByUuid(string $uuid, array $attributes): mixed
|
|
972
|
+
{
|
|
973
|
+
return User::where('uuid', $uuid)->update($attributes);
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
protected function findAccessToken(string $token): mixed
|
|
977
|
+
{
|
|
978
|
+
return \Laravel\Sanctum\PersonalAccessToken::findToken($token);
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
protected function deleteUserTokens(User $user): void
|
|
982
|
+
{
|
|
983
|
+
$user->tokens()->delete();
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
protected function queryOrders(Request $request, callable $callback): mixed
|
|
987
|
+
{
|
|
988
|
+
return Order::queryWithRequest($request, $callback);
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
protected function findOrderOrFail(string $id): Order
|
|
992
|
+
{
|
|
993
|
+
return Order::findRecordOrFail($id);
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
protected function resolveOrderConfig(CreateCustomerOrderRequest $request, string $companyUuid): ?OrderConfig
|
|
997
|
+
{
|
|
998
|
+
return OrderConfig::resolveFromIdentifier($request->only(['type', 'order_config']))
|
|
999
|
+
?: OrderConfig::where('company_uuid', $companyUuid)->first();
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
protected function getUuid(array|string $table, array $where, array $options = []): mixed
|
|
1003
|
+
{
|
|
1004
|
+
return Utils::getUuid($table, $where, $options);
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
protected function getModelClassName(?string $table): ?string
|
|
1008
|
+
{
|
|
1009
|
+
return Utils::getModelClassName($table);
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
protected function createOrderRecord(array $attributes): Order
|
|
1013
|
+
{
|
|
1014
|
+
return Order::create($attributes);
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
protected function resolveServiceQuote(CreateCustomerOrderRequest $request): mixed
|
|
1018
|
+
{
|
|
1019
|
+
return ServiceQuote::resolveFromRequest($request);
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
protected function newPayload(): Payload
|
|
1023
|
+
{
|
|
1024
|
+
return new Payload();
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
protected function queryPlaces(Request $request, callable $callback): mixed
|
|
1028
|
+
{
|
|
1029
|
+
return Place::queryWithRequest($request, $callback);
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
protected function firstOrCreateDevice(array $attributes, array $values): mixed
|
|
1033
|
+
{
|
|
1034
|
+
return UserDevice::firstOrCreate($attributes, $values);
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
protected function customerResource(Contact $contact): mixed
|
|
1038
|
+
{
|
|
1039
|
+
return new CustomerResource($contact);
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
protected function orderResource(Order $order): mixed
|
|
1043
|
+
{
|
|
1044
|
+
return new OrderResource($order);
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
protected function orderResourceCollection(mixed $results): mixed
|
|
1048
|
+
{
|
|
1049
|
+
return OrderResource::collection($results);
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
protected function placeResourceCollection(mixed $results): mixed
|
|
1053
|
+
{
|
|
1054
|
+
return PlaceResource::collection($results);
|
|
1055
|
+
}
|
|
1056
|
+
|
|
858
1057
|
/**
|
|
859
1058
|
* Normalize a phone number to international format (with leading `+`).
|
|
860
1059
|
*/
|