@fleetbase/fleetops-engine 0.6.58 → 0.6.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/RELEASE.md +36 -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/components/vehicle/details/schedules.hbs +2 -2
- package/addon/components/vehicle/details/schedules.js +7 -1
- package/addon/controllers/maintenance/schedules/index/edit.js +10 -1
- package/addon/services/entity-actions.js +32 -0
- package/addon/services/vehicle-actions.js +4 -2
- package/addon/styles/fleetops-engine.css +0 -1
- package/composer.json +8 -3
- package/extension.json +1 -1
- package/index.js +7 -1
- package/package.json +2 -1
- package/scripts/coverage-file-runner.php +240 -0
- package/scripts/coverage-runner.php +2 -1
- package/scripts/coverage-summary.php +41 -2
- package/scripts/pest-bootstrap.php +237 -3
- package/scripts/pest-file-runner.php +13 -1
- package/scripts/pest-runner.php +57 -2
- package/server/config/fleetops.php +44 -0
- package/server/config/geocoder.php +1 -1
- package/server/migrations/2026_08_08_000001_make_sku_and_provider_transaction_unique_indexes_soft_delete_aware.php +152 -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 +346 -101
- package/server/src/Http/Controllers/Api/v1/DeviceController.php +48 -14
- package/server/src/Http/Controllers/Api/v1/DriverController.php +224 -64
- 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 +73 -23
- 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 +32 -15
- 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 +92 -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/Concerns/ResolvesReviewAccountBypass.php +62 -0
- 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 +168 -70
- 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/MaintenanceScheduleFilter.php +40 -0
- 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/CreateCustomerRequest.php +9 -1
- 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 +16 -9
- package/server/src/Http/Requests/CreateFuelTransactionRequest.php +66 -3
- 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 +41 -3
- 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/TrackingNumber.php +33 -0
- 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 +26 -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/Sensor.php +24 -0
- 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 +2 -2
- 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/FuelProviders/FuelProviderService.php +10 -1
- 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/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 +24 -17
- package/server/tests/AiOperationalQueryCapabilityTest.php +457 -1
- package/server/tests/AiPreviewCapabilityContractsTest.php +180 -0
- package/server/tests/AnalyticsRoutesTest.php +380 -1
- package/server/tests/AnalyticsWidgetContractsTest.php +740 -0
- package/server/tests/ApiContactControllerContractsTest.php +284 -0
- package/server/tests/ApiCustomerControllerContractsTest.php +1130 -0
- package/server/tests/ApiDriverControllerContractsTest.php +603 -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 +2838 -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 +169 -2
- 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 +530 -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 +461 -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 +160 -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 +1167 -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/FuelProviderResourceContractsTest.php +171 -0
- package/server/tests/FuelProviderTransactionControllerContractsTest.php +198 -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 +145 -18
- 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 +1058 -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/ServiceRateRouteValidationTest.php +76 -0
- package/server/tests/SettingControllerContractsTest.php +410 -0
- package/server/tests/SmallControllerContractsTest.php +480 -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 +642 -86
- package/server/tests/TrackingIntelligenceTest.php +644 -1
- 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/MaintenanceScheduleFilterTest.php +69 -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 +68 -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 +190 -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/SensorLastPositionDefaultTest.php +130 -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/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/tests/DeviceFilterTest.php +0 -44
- package/server/tests/LiveControllerViewportTest.php +0 -52
|
@@ -19,6 +19,7 @@ use Fleetbase\FleetOps\Models\ServiceQuote;
|
|
|
19
19
|
use Fleetbase\FleetOps\Support\CustomerAuth;
|
|
20
20
|
use Fleetbase\FleetOps\Support\Utils;
|
|
21
21
|
use Fleetbase\Http\Controllers\Controller;
|
|
22
|
+
use Fleetbase\LaravelMysqlSpatial\Types\Point as SpatialPoint;
|
|
22
23
|
use Fleetbase\Models\File;
|
|
23
24
|
use Fleetbase\Models\User;
|
|
24
25
|
use Fleetbase\Models\UserDevice;
|
|
@@ -41,6 +42,8 @@ use Illuminate\Support\Str;
|
|
|
41
42
|
*/
|
|
42
43
|
class CustomerController extends Controller
|
|
43
44
|
{
|
|
45
|
+
use \Fleetbase\FleetOps\Http\Controllers\Concerns\ResolvesReviewAccountBypass;
|
|
46
|
+
|
|
44
47
|
/* ============================================================
|
|
45
48
|
| Public auth flows (API credential only, no Customer-Token)
|
|
46
49
|
* ============================================================ */
|
|
@@ -54,7 +57,7 @@ class CustomerController extends Controller
|
|
|
54
57
|
{
|
|
55
58
|
$mode = $request->input('mode', 'email');
|
|
56
59
|
$identity = $request->input('identity');
|
|
57
|
-
$isEmail =
|
|
60
|
+
$isEmail = $this->isEmail($identity);
|
|
58
61
|
|
|
59
62
|
if ($mode === 'email' && !$isEmail) {
|
|
60
63
|
return response()->apiError('Invalid email provided for identity.');
|
|
@@ -64,7 +67,7 @@ class CustomerController extends Controller
|
|
|
64
67
|
$identity = static::phone($identity);
|
|
65
68
|
}
|
|
66
69
|
|
|
67
|
-
$sessionCompany =
|
|
70
|
+
$sessionCompany = $this->sessionCompany();
|
|
68
71
|
if (!$sessionCompany) {
|
|
69
72
|
return response()->apiError('No company resolved from API credential.', 500);
|
|
70
73
|
}
|
|
@@ -80,14 +83,12 @@ class CustomerController extends Controller
|
|
|
80
83
|
// template references `$user->name`). Look up — or create — the User
|
|
81
84
|
// before sending. `create()` later backfills password + remaining fields
|
|
82
85
|
// 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();
|
|
86
|
+
$subject = $this->findActiveUserByIdentity($identity, $isEmail ? 'email' : 'phone');
|
|
86
87
|
|
|
87
88
|
if (!$subject) {
|
|
88
89
|
// `password` and `type` are guarded on User; assign type after create
|
|
89
90
|
// via setUserType (saves the row).
|
|
90
|
-
$subject =
|
|
91
|
+
$subject = $this->createUser([
|
|
91
92
|
'company_uuid' => $sessionCompany,
|
|
92
93
|
'name' => $providedName !== '' ? $providedName : $identity,
|
|
93
94
|
'email' => $isEmail ? $identity : null,
|
|
@@ -108,13 +109,13 @@ class CustomerController extends Controller
|
|
|
108
109
|
|
|
109
110
|
try {
|
|
110
111
|
if ($mode === 'email') {
|
|
111
|
-
|
|
112
|
+
$this->generateEmailVerification($subject, 'fleetops_create_customer', [
|
|
112
113
|
'subject' => config('app.name') . ' verification code',
|
|
113
114
|
'messageCallback' => fn ($verification) => 'Your ' . config('app.name') . ' verification code is ' . $verification->code,
|
|
114
115
|
'meta' => $meta,
|
|
115
116
|
]);
|
|
116
117
|
} else {
|
|
117
|
-
|
|
118
|
+
$this->generateSmsVerification($subject, 'fleetops_create_customer', [
|
|
118
119
|
'messageCallback' => fn ($verification) => 'Your ' . config('app.name') . ' verification code is ' . $verification->code,
|
|
119
120
|
'meta' => $meta,
|
|
120
121
|
]);
|
|
@@ -135,22 +136,22 @@ class CustomerController extends Controller
|
|
|
135
136
|
{
|
|
136
137
|
$code = $request->input('code');
|
|
137
138
|
$identity = $request->input('identity');
|
|
138
|
-
$isEmail =
|
|
139
|
+
$isEmail = $this->isEmail($identity);
|
|
139
140
|
if (!$isEmail) {
|
|
140
141
|
$identity = static::phone($identity);
|
|
141
142
|
}
|
|
142
143
|
|
|
143
144
|
// Verify the code is one we sent for this identity.
|
|
144
|
-
$verificationCode =
|
|
145
|
+
$verificationCode = $this->verificationCodeExists([
|
|
145
146
|
'code' => $code,
|
|
146
147
|
'for' => 'fleetops_create_customer',
|
|
147
148
|
'meta->identity' => $identity,
|
|
148
|
-
])
|
|
149
|
-
if (!$verificationCode) {
|
|
149
|
+
]);
|
|
150
|
+
if (!$verificationCode && !$this->verificationBypassMatches($identity, $code)) {
|
|
150
151
|
return response()->apiError('Invalid verification code provided.');
|
|
151
152
|
}
|
|
152
153
|
|
|
153
|
-
$sessionCompany =
|
|
154
|
+
$sessionCompany = $this->sessionCompany();
|
|
154
155
|
if (!$sessionCompany) {
|
|
155
156
|
return response()->apiError('No company resolved from API credential.', 500);
|
|
156
157
|
}
|
|
@@ -158,15 +159,15 @@ class CustomerController extends Controller
|
|
|
158
159
|
// Attach to existing User if one matches the identity, otherwise create one.
|
|
159
160
|
$user = null;
|
|
160
161
|
if ($isEmail) {
|
|
161
|
-
$user =
|
|
162
|
+
$user = $this->findActiveUserByIdentity($identity, 'email');
|
|
162
163
|
} elseif (Str::startsWith($identity, '+')) {
|
|
163
|
-
$user =
|
|
164
|
+
$user = $this->findActiveUserByIdentity($identity, 'phone');
|
|
164
165
|
}
|
|
165
166
|
|
|
166
167
|
if (!$user) {
|
|
167
168
|
// `password` and `type` are guarded on User; assign them after create
|
|
168
169
|
// (setUserType saves the type, setPasswordAttribute hashes plaintext).
|
|
169
|
-
$user =
|
|
170
|
+
$user = $this->createUser([
|
|
170
171
|
'company_uuid' => $sessionCompany,
|
|
171
172
|
'name' => $request->input('name'),
|
|
172
173
|
'email' => $isEmail ? $identity : $request->input('email'),
|
|
@@ -215,15 +216,15 @@ class CustomerController extends Controller
|
|
|
215
216
|
// Handle photo as either file id or base64 data.
|
|
216
217
|
$photo = $request->input('photo');
|
|
217
218
|
if ($photo) {
|
|
218
|
-
if (
|
|
219
|
-
$file =
|
|
219
|
+
if ($this->isPublicId($photo)) {
|
|
220
|
+
$file = $this->findFileByPublicId($photo);
|
|
220
221
|
if ($file) {
|
|
221
222
|
$input['photo_uuid'] = $file->uuid;
|
|
222
223
|
}
|
|
223
224
|
}
|
|
224
|
-
if (
|
|
225
|
+
if ($this->isBase64String($photo)) {
|
|
225
226
|
$path = implode('/', ['uploads', $sessionCompany, 'customers']);
|
|
226
|
-
$file =
|
|
227
|
+
$file = $this->createFileFromBase64($photo, $path);
|
|
227
228
|
if ($file) {
|
|
228
229
|
$input['photo_uuid'] = $file->uuid;
|
|
229
230
|
}
|
|
@@ -232,22 +233,22 @@ class CustomerController extends Controller
|
|
|
232
233
|
|
|
233
234
|
// Reuse an existing customer-Contact for this user+company if one exists
|
|
234
235
|
// (idempotent re-signup), otherwise create one.
|
|
235
|
-
$contact =
|
|
236
|
+
$contact = $this->findCustomerContact([
|
|
236
237
|
'company_uuid' => $sessionCompany,
|
|
237
238
|
'user_uuid' => $user->uuid,
|
|
238
239
|
'type' => 'customer',
|
|
239
|
-
])
|
|
240
|
+
]);
|
|
240
241
|
if ($contact) {
|
|
241
242
|
$contact->fill(array_filter($input, fn ($v) => $v !== null && $v !== ''))->save();
|
|
242
243
|
} else {
|
|
243
244
|
try {
|
|
244
|
-
$contact =
|
|
245
|
+
$contact = $this->createContact($input);
|
|
245
246
|
} catch (UserAlreadyExistsException $e) {
|
|
246
|
-
$contact =
|
|
247
|
+
$contact = $this->findCustomerContact([
|
|
247
248
|
'company_uuid' => $sessionCompany,
|
|
248
249
|
'user_uuid' => $user->uuid,
|
|
249
250
|
'type' => 'customer',
|
|
250
|
-
])
|
|
251
|
+
]);
|
|
251
252
|
if (!$contact) {
|
|
252
253
|
return response()->apiError($e->getMessage());
|
|
253
254
|
}
|
|
@@ -272,10 +273,10 @@ class CustomerController extends Controller
|
|
|
272
273
|
}
|
|
273
274
|
}
|
|
274
275
|
|
|
275
|
-
$token = $
|
|
276
|
+
$token = $this->createCustomerToken($user, $contact);
|
|
276
277
|
$contact->token = $token->plainTextToken;
|
|
277
278
|
|
|
278
|
-
return
|
|
279
|
+
return $this->customerResource($contact);
|
|
279
280
|
}
|
|
280
281
|
|
|
281
282
|
/**
|
|
@@ -293,7 +294,7 @@ class CustomerController extends Controller
|
|
|
293
294
|
}
|
|
294
295
|
|
|
295
296
|
if (is_string($input)) {
|
|
296
|
-
return
|
|
297
|
+
return $this->findPlaceByPublicId($input, $companyUuid);
|
|
297
298
|
}
|
|
298
299
|
|
|
299
300
|
if (!is_array($input)) {
|
|
@@ -309,11 +310,19 @@ class CustomerController extends Controller
|
|
|
309
310
|
return null;
|
|
310
311
|
}
|
|
311
312
|
|
|
312
|
-
return
|
|
313
|
+
return $this->createPlace(array_merge(
|
|
313
314
|
[
|
|
314
315
|
'company_uuid' => $companyUuid,
|
|
315
316
|
'owner_uuid' => $contact->uuid,
|
|
316
317
|
'owner_type' => get_class($contact),
|
|
318
|
+
// `places.location` is a NOT NULL POINT column with no database default,
|
|
319
|
+
// and $allowed above is address-only — a caller cannot supply coordinates
|
|
320
|
+
// here. Without this the insert fails with SQLSTATE[HY000] 1364 ("Field
|
|
321
|
+
// 'location' doesn't have a default value"), turning a documented signup
|
|
322
|
+
// payload into a 500. Point(0, 0) is the same placeholder the geocoding
|
|
323
|
+
// helpers fall back to when an address cannot be resolved — see
|
|
324
|
+
// Place::getGoogleAddressArray and Place::findExistingSharedPlace.
|
|
325
|
+
'location' => new SpatialPoint(0, 0),
|
|
317
326
|
],
|
|
318
327
|
$attributes,
|
|
319
328
|
));
|
|
@@ -330,20 +339,18 @@ class CustomerController extends Controller
|
|
|
330
339
|
return response()->apiError('Identity and password are required.', 400);
|
|
331
340
|
}
|
|
332
341
|
|
|
333
|
-
$user =
|
|
334
|
-
->orWhere('phone', static::phone($identity))
|
|
335
|
-
->first();
|
|
342
|
+
$user = $this->findUserForLogin($identity);
|
|
336
343
|
|
|
337
|
-
if (!$user || !$user->password ||
|
|
344
|
+
if (!$user || !$user->password || !$this->passwordMatches($password, $user->password)) {
|
|
338
345
|
return response()->apiError('Authentication failed using credentials provided.', 401);
|
|
339
346
|
}
|
|
340
347
|
|
|
341
|
-
$sessionCompany =
|
|
348
|
+
$sessionCompany = $this->sessionCompany();
|
|
342
349
|
if (!$sessionCompany) {
|
|
343
350
|
return response()->apiError('No company resolved from API credential.', 500);
|
|
344
351
|
}
|
|
345
352
|
|
|
346
|
-
$contact =
|
|
353
|
+
$contact = $this->firstOrCreateCustomerContact(
|
|
347
354
|
[
|
|
348
355
|
'user_uuid' => $user->uuid,
|
|
349
356
|
'company_uuid' => $sessionCompany,
|
|
@@ -356,10 +363,10 @@ class CustomerController extends Controller
|
|
|
356
363
|
]
|
|
357
364
|
);
|
|
358
365
|
|
|
359
|
-
$token = $
|
|
366
|
+
$token = $this->createCustomerToken($user, $contact);
|
|
360
367
|
$contact->token = $token->plainTextToken;
|
|
361
368
|
|
|
362
|
-
return
|
|
369
|
+
return $this->customerResource($contact);
|
|
363
370
|
}
|
|
364
371
|
|
|
365
372
|
/**
|
|
@@ -369,13 +376,13 @@ class CustomerController extends Controller
|
|
|
369
376
|
{
|
|
370
377
|
$phone = static::phone($request->input('phone') ?? $request->input('identity'));
|
|
371
378
|
|
|
372
|
-
$user =
|
|
379
|
+
$user = $this->findActiveUserByIdentity($phone, 'phone');
|
|
373
380
|
if (!$user) {
|
|
374
381
|
return response()->apiError('No customer with this phone number found.');
|
|
375
382
|
}
|
|
376
383
|
|
|
377
384
|
try {
|
|
378
|
-
|
|
385
|
+
$this->generateSmsVerification($user, 'fleetops_customer_login', [
|
|
379
386
|
'messageCallback' => fn ($verification) => 'Your ' . config('app.name') . ' verification code is ' . $verification->code,
|
|
380
387
|
]);
|
|
381
388
|
|
|
@@ -383,7 +390,7 @@ class CustomerController extends Controller
|
|
|
383
390
|
} catch (\Throwable $e) {
|
|
384
391
|
if ($user->email) {
|
|
385
392
|
try {
|
|
386
|
-
|
|
393
|
+
$this->generateEmailVerification($user, 'fleetops_customer_login', [
|
|
387
394
|
'subject' => config('app.name') . ' verification code',
|
|
388
395
|
'messageCallback' => fn ($verification) => 'Your ' . config('app.name') . ' verification code is ' . $verification->code,
|
|
389
396
|
]);
|
|
@@ -403,30 +410,30 @@ class CustomerController extends Controller
|
|
|
403
410
|
*/
|
|
404
411
|
public function verifyCode(Request $request)
|
|
405
412
|
{
|
|
406
|
-
$identity =
|
|
413
|
+
$identity = $this->isEmail($request->input('identity')) ? $request->input('identity') : static::phone($request->input('identity'));
|
|
407
414
|
$code = $request->input('code');
|
|
408
415
|
$for = $request->input('for', 'fleetops_customer_login');
|
|
409
416
|
|
|
410
417
|
if ($for === 'fleetops_create_customer') {
|
|
411
|
-
return $this->create($request);
|
|
418
|
+
return $this->create(CreateCustomerRequest::createFrom($request));
|
|
412
419
|
}
|
|
413
420
|
|
|
414
|
-
$user =
|
|
421
|
+
$user = $this->findUserForVerification($identity);
|
|
415
422
|
if (!$user) {
|
|
416
423
|
return response()->apiError('Unable to verify code.');
|
|
417
424
|
}
|
|
418
425
|
|
|
419
|
-
$verificationCode =
|
|
426
|
+
$verificationCode = $this->verificationCodeExists([
|
|
420
427
|
'subject_uuid' => $user->uuid,
|
|
421
428
|
'code' => $code,
|
|
422
429
|
'for' => $for,
|
|
423
|
-
])
|
|
424
|
-
if (!$verificationCode) {
|
|
430
|
+
]);
|
|
431
|
+
if (!$verificationCode && !$this->verificationBypassMatches($identity, $code)) {
|
|
425
432
|
return response()->apiError('Invalid verification code.');
|
|
426
433
|
}
|
|
427
434
|
|
|
428
|
-
$sessionCompany =
|
|
429
|
-
$contact =
|
|
435
|
+
$sessionCompany = $this->sessionCompany();
|
|
436
|
+
$contact = $this->firstOrCreateCustomerContact(
|
|
430
437
|
[
|
|
431
438
|
'user_uuid' => $user->uuid,
|
|
432
439
|
'company_uuid' => $sessionCompany,
|
|
@@ -439,10 +446,10 @@ class CustomerController extends Controller
|
|
|
439
446
|
]
|
|
440
447
|
);
|
|
441
448
|
|
|
442
|
-
$token = $
|
|
449
|
+
$token = $this->createCustomerToken($user, $contact);
|
|
443
450
|
$contact->token = $token->plainTextToken;
|
|
444
451
|
|
|
445
|
-
return
|
|
452
|
+
return $this->customerResource($contact);
|
|
446
453
|
}
|
|
447
454
|
|
|
448
455
|
/**
|
|
@@ -455,10 +462,8 @@ class CustomerController extends Controller
|
|
|
455
462
|
return response()->apiError('Identity is required.', 400);
|
|
456
463
|
}
|
|
457
464
|
|
|
458
|
-
$isEmail =
|
|
459
|
-
$user = $isEmail
|
|
460
|
-
? User::where('email', $identity)->first()
|
|
461
|
-
: User::where('phone', static::phone($identity))->first();
|
|
465
|
+
$isEmail = $this->isEmail($identity);
|
|
466
|
+
$user = $this->findUserByIdentity($isEmail ? $identity : static::phone($identity), $isEmail ? 'email' : 'phone');
|
|
462
467
|
|
|
463
468
|
if (!$user) {
|
|
464
469
|
// Don't leak account existence — return success regardless.
|
|
@@ -468,13 +473,13 @@ class CustomerController extends Controller
|
|
|
468
473
|
$meta = ['identity' => $isEmail ? $identity : static::phone($identity)];
|
|
469
474
|
try {
|
|
470
475
|
if ($isEmail) {
|
|
471
|
-
|
|
476
|
+
$this->generateEmailVerification($user, 'fleetops_customer_password_reset', [
|
|
472
477
|
'subject' => config('app.name') . ' password reset',
|
|
473
478
|
'messageCallback' => fn ($v) => 'Your ' . config('app.name') . ' password reset code is ' . $v->code,
|
|
474
479
|
'meta' => $meta,
|
|
475
480
|
]);
|
|
476
481
|
} else {
|
|
477
|
-
|
|
482
|
+
$this->generateSmsVerification($user, 'fleetops_customer_password_reset', [
|
|
478
483
|
'messageCallback' => fn ($v) => 'Your ' . config('app.name') . ' password reset code is ' . $v->code,
|
|
479
484
|
'meta' => $meta,
|
|
480
485
|
]);
|
|
@@ -501,21 +506,21 @@ class CustomerController extends Controller
|
|
|
501
506
|
return response()->apiError('Password must be at least 8 characters.', 400);
|
|
502
507
|
}
|
|
503
508
|
|
|
504
|
-
$isEmail =
|
|
509
|
+
$isEmail = $this->isEmail($identity);
|
|
505
510
|
$needle = $isEmail ? $identity : static::phone($identity);
|
|
506
511
|
|
|
507
|
-
$verificationCode =
|
|
512
|
+
$verificationCode = $this->findVerificationCode([
|
|
508
513
|
'code' => $code,
|
|
509
514
|
'for' => 'fleetops_customer_password_reset',
|
|
510
515
|
'meta->identity' => $needle,
|
|
511
|
-
])
|
|
512
|
-
|
|
516
|
+
]);
|
|
517
|
+
// $needle, not $identity: the other verify paths normalise in place, so an
|
|
518
|
+
// allowlisted phone must be compared in the same normalised form here too.
|
|
519
|
+
if (!$verificationCode && !$this->verificationBypassMatches($needle, $code)) {
|
|
513
520
|
return response()->apiError('Invalid reset code.');
|
|
514
521
|
}
|
|
515
522
|
|
|
516
|
-
$user = $isEmail
|
|
517
|
-
? User::where('email', $needle)->first()
|
|
518
|
-
: User::where('phone', $needle)->first();
|
|
523
|
+
$user = $this->findUserByIdentity($needle, $isEmail ? 'email' : 'phone');
|
|
519
524
|
if (!$user) {
|
|
520
525
|
return response()->apiError('Account not found.');
|
|
521
526
|
}
|
|
@@ -524,8 +529,11 @@ class CustomerController extends Controller
|
|
|
524
529
|
$user->password = $password;
|
|
525
530
|
$user->save();
|
|
526
531
|
// Invalidate all existing sessions for this user after a password reset.
|
|
527
|
-
$
|
|
528
|
-
|
|
532
|
+
$this->deleteUserTokens($user);
|
|
533
|
+
// Null on the testing-bypass path — there is no row to consume.
|
|
534
|
+
if ($verificationCode) {
|
|
535
|
+
$verificationCode->delete();
|
|
536
|
+
}
|
|
529
537
|
|
|
530
538
|
return response()->json(['status' => 'ok']);
|
|
531
539
|
}
|
|
@@ -539,12 +547,12 @@ class CustomerController extends Controller
|
|
|
539
547
|
*/
|
|
540
548
|
public function me()
|
|
541
549
|
{
|
|
542
|
-
$customer =
|
|
550
|
+
$customer = $this->currentCustomer();
|
|
543
551
|
if (!$customer) {
|
|
544
552
|
return response()->apiError('Not authenticated.', 401);
|
|
545
553
|
}
|
|
546
554
|
|
|
547
|
-
return
|
|
555
|
+
return $this->customerResource($customer);
|
|
548
556
|
}
|
|
549
557
|
|
|
550
558
|
/**
|
|
@@ -552,7 +560,7 @@ class CustomerController extends Controller
|
|
|
552
560
|
*/
|
|
553
561
|
public function updateMe(UpdateContactRequest $request)
|
|
554
562
|
{
|
|
555
|
-
$customer =
|
|
563
|
+
$customer = $this->currentCustomer();
|
|
556
564
|
if (!$customer) {
|
|
557
565
|
return response()->apiError('Not authenticated.', 401);
|
|
558
566
|
}
|
|
@@ -565,15 +573,15 @@ class CustomerController extends Controller
|
|
|
565
573
|
// Photo handling.
|
|
566
574
|
$photo = $request->input('photo');
|
|
567
575
|
if ($photo) {
|
|
568
|
-
if (
|
|
569
|
-
$file =
|
|
576
|
+
if ($this->isPublicId($photo)) {
|
|
577
|
+
$file = $this->findFileByPublicId($photo);
|
|
570
578
|
if ($file) {
|
|
571
579
|
$input['photo_uuid'] = $file->uuid;
|
|
572
580
|
}
|
|
573
581
|
}
|
|
574
|
-
if (
|
|
575
|
-
$path = implode('/', ['uploads',
|
|
576
|
-
$file =
|
|
582
|
+
if ($this->isBase64String($photo)) {
|
|
583
|
+
$path = implode('/', ['uploads', $this->sessionCompany(), 'customers']);
|
|
584
|
+
$file = $this->createFileFromBase64($photo, $path);
|
|
577
585
|
if ($file) {
|
|
578
586
|
$input['photo_uuid'] = $file->uuid;
|
|
579
587
|
}
|
|
@@ -597,11 +605,11 @@ class CustomerController extends Controller
|
|
|
597
605
|
'phone' => $input['phone'] ?? null,
|
|
598
606
|
], fn ($v) => $v !== null);
|
|
599
607
|
if (!empty($userUpdate)) {
|
|
600
|
-
|
|
608
|
+
$this->updateUserByUuid($customer->user_uuid, $userUpdate);
|
|
601
609
|
}
|
|
602
610
|
}
|
|
603
611
|
|
|
604
|
-
return
|
|
612
|
+
return $this->customerResource($customer->fresh());
|
|
605
613
|
}
|
|
606
614
|
|
|
607
615
|
/**
|
|
@@ -609,13 +617,13 @@ class CustomerController extends Controller
|
|
|
609
617
|
*/
|
|
610
618
|
public function logout(Request $request)
|
|
611
619
|
{
|
|
612
|
-
$customer =
|
|
620
|
+
$customer = $this->currentCustomer();
|
|
613
621
|
if (!$customer) {
|
|
614
622
|
return response()->apiError('Not authenticated.', 401);
|
|
615
623
|
}
|
|
616
624
|
|
|
617
625
|
$tokenString = $request->header(CustomerAuth::HEADER);
|
|
618
|
-
$accessToken = $tokenString ?
|
|
626
|
+
$accessToken = $tokenString ? $this->findAccessToken($tokenString) : null;
|
|
619
627
|
if ($accessToken) {
|
|
620
628
|
$accessToken->delete();
|
|
621
629
|
}
|
|
@@ -628,14 +636,14 @@ class CustomerController extends Controller
|
|
|
628
636
|
*/
|
|
629
637
|
public function logoutAll()
|
|
630
638
|
{
|
|
631
|
-
$customer =
|
|
639
|
+
$customer = $this->currentCustomer();
|
|
632
640
|
if (!$customer || !$customer->user_uuid) {
|
|
633
641
|
return response()->apiError('Not authenticated.', 401);
|
|
634
642
|
}
|
|
635
643
|
|
|
636
|
-
$user =
|
|
644
|
+
$user = $this->findUserByUuid($customer->user_uuid);
|
|
637
645
|
if ($user) {
|
|
638
|
-
$
|
|
646
|
+
$this->deleteUserTokens($user);
|
|
639
647
|
}
|
|
640
648
|
|
|
641
649
|
return response()->json(['status' => 'ok']);
|
|
@@ -646,18 +654,18 @@ class CustomerController extends Controller
|
|
|
646
654
|
*/
|
|
647
655
|
public function orders(Request $request)
|
|
648
656
|
{
|
|
649
|
-
$customer =
|
|
657
|
+
$customer = $this->currentCustomer();
|
|
650
658
|
if (!$customer) {
|
|
651
659
|
return response()->apiError('Not authenticated.', 401);
|
|
652
660
|
}
|
|
653
661
|
|
|
654
|
-
$results =
|
|
662
|
+
$results = $this->queryOrders($request, function (&$query) use ($customer) {
|
|
655
663
|
$query->where('customer_uuid', $customer->uuid)
|
|
656
664
|
->whereNull('deleted_at')
|
|
657
665
|
->withoutGlobalScopes();
|
|
658
666
|
});
|
|
659
667
|
|
|
660
|
-
return
|
|
668
|
+
return $this->orderResourceCollection($results);
|
|
661
669
|
}
|
|
662
670
|
|
|
663
671
|
/**
|
|
@@ -665,13 +673,13 @@ class CustomerController extends Controller
|
|
|
665
673
|
*/
|
|
666
674
|
public function findOrder(string $id)
|
|
667
675
|
{
|
|
668
|
-
$customer =
|
|
676
|
+
$customer = $this->currentCustomer();
|
|
669
677
|
if (!$customer) {
|
|
670
678
|
return response()->apiError('Not authenticated.', 401);
|
|
671
679
|
}
|
|
672
680
|
|
|
673
681
|
try {
|
|
674
|
-
$order =
|
|
682
|
+
$order = $this->findOrderOrFail($id);
|
|
675
683
|
} catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
|
|
676
684
|
return response()->apiError('Order not found.', 404);
|
|
677
685
|
}
|
|
@@ -680,7 +688,7 @@ class CustomerController extends Controller
|
|
|
680
688
|
return response()->apiError('Order not found.', 404);
|
|
681
689
|
}
|
|
682
690
|
|
|
683
|
-
return
|
|
691
|
+
return $this->orderResource($order);
|
|
684
692
|
}
|
|
685
693
|
|
|
686
694
|
/**
|
|
@@ -699,19 +707,18 @@ class CustomerController extends Controller
|
|
|
699
707
|
*/
|
|
700
708
|
public function createOrder(CreateCustomerOrderRequest $request)
|
|
701
709
|
{
|
|
702
|
-
$customer =
|
|
710
|
+
$customer = $this->currentCustomer();
|
|
703
711
|
if (!$customer) {
|
|
704
712
|
return response()->apiError('Not authenticated.', 401);
|
|
705
713
|
}
|
|
706
714
|
|
|
707
|
-
$sessionCompany =
|
|
715
|
+
$sessionCompany = $this->sessionCompany();
|
|
708
716
|
if (!$sessionCompany) {
|
|
709
717
|
return response()->apiError('No company resolved from API credential.', 500);
|
|
710
718
|
}
|
|
711
719
|
|
|
712
720
|
// Resolve the order config for this order. Mirrors OrderController::create.
|
|
713
|
-
$orderConfig =
|
|
714
|
-
?: OrderConfig::where('company_uuid', $sessionCompany)->first();
|
|
721
|
+
$orderConfig = $this->resolveOrderConfig($request, $sessionCompany);
|
|
715
722
|
if (!$orderConfig) {
|
|
716
723
|
return response()->apiError('No order config available for this company.', 422);
|
|
717
724
|
}
|
|
@@ -725,7 +732,7 @@ class CustomerController extends Controller
|
|
|
725
732
|
$payloadInput = (array) $request->input('payload');
|
|
726
733
|
$payloadUuid = $this->buildPayloadFromInput($payloadInput, $sessionCompany)->uuid;
|
|
727
734
|
} elseif ($request->isString('payload')) {
|
|
728
|
-
$payloadUuid =
|
|
735
|
+
$payloadUuid = $this->getUuid('payloads', [
|
|
729
736
|
'public_id' => $request->input('payload'),
|
|
730
737
|
'company_uuid' => $sessionCompany,
|
|
731
738
|
]);
|
|
@@ -736,10 +743,10 @@ class CustomerController extends Controller
|
|
|
736
743
|
}
|
|
737
744
|
}
|
|
738
745
|
|
|
739
|
-
$order =
|
|
746
|
+
$order = $this->createOrderRecord([
|
|
740
747
|
'company_uuid' => $sessionCompany,
|
|
741
748
|
'customer_uuid' => $customer->uuid,
|
|
742
|
-
'customer_type' =>
|
|
749
|
+
'customer_type' => $this->getModelClassName('contact'),
|
|
743
750
|
'payload_uuid' => $payloadUuid,
|
|
744
751
|
'order_config_uuid' => $orderConfig->uuid,
|
|
745
752
|
'type' => $orderConfig->key,
|
|
@@ -753,12 +760,12 @@ class CustomerController extends Controller
|
|
|
753
760
|
// If the customer picked a ServiceQuote up front, consume it now to
|
|
754
761
|
// lock the pricing onto the order's PurchaseRate (mirrors how
|
|
755
762
|
// OrderController::create handles `service_quote`).
|
|
756
|
-
$serviceQuote =
|
|
763
|
+
$serviceQuote = $this->resolveServiceQuote($request);
|
|
757
764
|
if ($serviceQuote instanceof ServiceQuote) {
|
|
758
765
|
$order->purchaseServiceQuote($serviceQuote);
|
|
759
766
|
}
|
|
760
767
|
|
|
761
|
-
return
|
|
768
|
+
return $this->orderResource($order->fresh(['payload', 'payload.pickup', 'payload.dropoff', 'payload.entities']));
|
|
762
769
|
}
|
|
763
770
|
|
|
764
771
|
/**
|
|
@@ -769,7 +776,7 @@ class CustomerController extends Controller
|
|
|
769
776
|
*/
|
|
770
777
|
protected function buildPayloadFromInput(array $payloadInput, string $companyUuid): Payload
|
|
771
778
|
{
|
|
772
|
-
$payload =
|
|
779
|
+
$payload = $this->newPayload();
|
|
773
780
|
$entities = data_get($payloadInput, 'entities', []);
|
|
774
781
|
$waypoints = data_get($payloadInput, 'waypoints', []);
|
|
775
782
|
$pickup = data_get($payloadInput, 'pickup');
|
|
@@ -810,16 +817,16 @@ class CustomerController extends Controller
|
|
|
810
817
|
*/
|
|
811
818
|
public function places(Request $request)
|
|
812
819
|
{
|
|
813
|
-
$customer =
|
|
820
|
+
$customer = $this->currentCustomer();
|
|
814
821
|
if (!$customer) {
|
|
815
822
|
return response()->apiError('Not authenticated.', 401);
|
|
816
823
|
}
|
|
817
824
|
|
|
818
|
-
$results =
|
|
825
|
+
$results = $this->queryPlaces($request, function (&$query) use ($customer) {
|
|
819
826
|
$query->where('owner_uuid', $customer->uuid);
|
|
820
827
|
});
|
|
821
828
|
|
|
822
|
-
return
|
|
829
|
+
return $this->placeResourceCollection($results);
|
|
823
830
|
}
|
|
824
831
|
|
|
825
832
|
/**
|
|
@@ -827,12 +834,12 @@ class CustomerController extends Controller
|
|
|
827
834
|
*/
|
|
828
835
|
public function registerDevice(Request $request)
|
|
829
836
|
{
|
|
830
|
-
$customer =
|
|
837
|
+
$customer = $this->currentCustomer();
|
|
831
838
|
if (!$customer) {
|
|
832
839
|
return response()->apiError('Not authenticated.', 401);
|
|
833
840
|
}
|
|
834
841
|
|
|
835
|
-
$device =
|
|
842
|
+
$device = $this->firstOrCreateDevice(
|
|
836
843
|
[
|
|
837
844
|
'token' => $request->input('token'),
|
|
838
845
|
'platform' => $request->input('platform', $request->input('os')),
|
|
@@ -855,6 +862,244 @@ class CustomerController extends Controller
|
|
|
855
862
|
| Helpers
|
|
856
863
|
* ============================================================ */
|
|
857
864
|
|
|
865
|
+
protected function isEmail(?string $identity): bool
|
|
866
|
+
{
|
|
867
|
+
return Utils::isEmail($identity);
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
protected function isPublicId(?string $value): bool
|
|
871
|
+
{
|
|
872
|
+
return Utils::isPublicId($value);
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
protected function isBase64String(?string $value): bool
|
|
876
|
+
{
|
|
877
|
+
return Utils::isBase64String($value);
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
protected function sessionCompany(): ?string
|
|
881
|
+
{
|
|
882
|
+
return session('company');
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
protected function currentCustomer(): ?Contact
|
|
886
|
+
{
|
|
887
|
+
return CustomerAuth::current();
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
protected function findActiveUserByIdentity(string $identity, string $column): ?User
|
|
891
|
+
{
|
|
892
|
+
return User::where($column, $identity)->whereNull('deleted_at')->withoutGlobalScopes()->first();
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
protected function findUserByIdentity(string $identity, string $column): ?User
|
|
896
|
+
{
|
|
897
|
+
return User::where($column, $identity)->first();
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
protected function findUserForLogin(string $identity): ?User
|
|
901
|
+
{
|
|
902
|
+
return User::where('email', $identity)
|
|
903
|
+
->orWhere('phone', static::phone($identity))
|
|
904
|
+
->first();
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
protected function findUserForVerification(string $identity): ?User
|
|
908
|
+
{
|
|
909
|
+
return User::where('phone', $identity)->orWhere('email', $identity)->first();
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
protected function findUserByUuid(string $uuid): ?User
|
|
913
|
+
{
|
|
914
|
+
return User::where('uuid', $uuid)->first();
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
protected function createUser(array $attributes): User
|
|
918
|
+
{
|
|
919
|
+
return User::create($attributes);
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
protected function passwordMatches(string $password, string $hash): bool
|
|
923
|
+
{
|
|
924
|
+
return Hash::check($password, $hash);
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
protected function generateEmailVerification(User $user, string $for, array $options): mixed
|
|
928
|
+
{
|
|
929
|
+
return VerificationCode::generateEmailVerificationFor($user, $for, $options);
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
protected function generateSmsVerification(User $user, string $for, array $options): mixed
|
|
933
|
+
{
|
|
934
|
+
return VerificationCode::generateSmsVerificationFor($user, $for, $options);
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
/**
|
|
938
|
+
* Whether the supplied code matches the configured testing bypass code.
|
|
939
|
+
*
|
|
940
|
+
* Three conditions, all required, mirroring the console equivalent in
|
|
941
|
+
* Fleetbase\Http\Controllers\Internal\v1\AuthController::authenticateWithVerificationCode:
|
|
942
|
+
* a bypass code must actually be configured, the app must not be running in
|
|
943
|
+
* production, and the comparison is constant-time.
|
|
944
|
+
*
|
|
945
|
+
* Fails safe by default: config/app.php resolves `env` to `production` when
|
|
946
|
+
* neither APP_ENV nor ENVIRONMENT is set, so an unconfigured install cannot
|
|
947
|
+
* be bypassed even accidentally.
|
|
948
|
+
*
|
|
949
|
+
* `!== null && !== ''` rather than `!empty()` — `!empty('0')` is false, so a
|
|
950
|
+
* configured bypass code of "0" would otherwise be silently ignored.
|
|
951
|
+
*
|
|
952
|
+
* Kept out of verificationCodeExists()/findVerificationCode() on purpose:
|
|
953
|
+
* those two are test seams that the controller contract tests override, so a
|
|
954
|
+
* policy living inside them would be stubbed away exactly where it matters.
|
|
955
|
+
*/
|
|
956
|
+
protected function verificationBypassMatches(?string $identity, ?string $code): bool
|
|
957
|
+
{
|
|
958
|
+
return static::reviewAccountBypassMatches(
|
|
959
|
+
'fleetops.customers.verification_bypass_code',
|
|
960
|
+
'fleetops.customers.review_accounts',
|
|
961
|
+
$identity,
|
|
962
|
+
$code,
|
|
963
|
+
'fleetops-customer'
|
|
964
|
+
);
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
protected function verificationCodeExists(array $attributes): bool
|
|
968
|
+
{
|
|
969
|
+
return VerificationCode::where($attributes)->exists();
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
protected function findVerificationCode(array $attributes): mixed
|
|
973
|
+
{
|
|
974
|
+
return VerificationCode::where($attributes)->first();
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
protected function findFileByPublicId(string $publicId): mixed
|
|
978
|
+
{
|
|
979
|
+
return File::where('public_id', $publicId)->first();
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
protected function createFileFromBase64(string $contents, string $path): mixed
|
|
983
|
+
{
|
|
984
|
+
return File::createFromBase64($contents, null, $path);
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
protected function findCustomerContact(array $attributes): ?Contact
|
|
988
|
+
{
|
|
989
|
+
return Contact::where($attributes)->first();
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
protected function createContact(array $attributes): Contact
|
|
993
|
+
{
|
|
994
|
+
return Contact::create($attributes);
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
protected function firstOrCreateCustomerContact(array $attributes, array $values): Contact
|
|
998
|
+
{
|
|
999
|
+
return Contact::firstOrCreate($attributes, $values);
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
protected function createCustomerToken(User $user, Contact $contact): mixed
|
|
1003
|
+
{
|
|
1004
|
+
return $user->createToken($contact->uuid);
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
protected function findPlaceByPublicId(string $publicId, string $companyUuid): ?Place
|
|
1008
|
+
{
|
|
1009
|
+
return Place::where(['public_id' => $publicId, 'company_uuid' => $companyUuid])->first();
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
protected function createPlace(array $attributes): Place
|
|
1013
|
+
{
|
|
1014
|
+
return Place::create($attributes);
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
protected function updateUserByUuid(string $uuid, array $attributes): mixed
|
|
1018
|
+
{
|
|
1019
|
+
return User::where('uuid', $uuid)->update($attributes);
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
protected function findAccessToken(string $token): mixed
|
|
1023
|
+
{
|
|
1024
|
+
return \Laravel\Sanctum\PersonalAccessToken::findToken($token);
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
protected function deleteUserTokens(User $user): void
|
|
1028
|
+
{
|
|
1029
|
+
$user->tokens()->delete();
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
protected function queryOrders(Request $request, callable $callback): mixed
|
|
1033
|
+
{
|
|
1034
|
+
return Order::queryWithRequest($request, $callback);
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
protected function findOrderOrFail(string $id): Order
|
|
1038
|
+
{
|
|
1039
|
+
return Order::findRecordOrFail($id);
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
protected function resolveOrderConfig(CreateCustomerOrderRequest $request, string $companyUuid): ?OrderConfig
|
|
1043
|
+
{
|
|
1044
|
+
return OrderConfig::resolveFromIdentifier($request->only(['type', 'order_config']))
|
|
1045
|
+
?: OrderConfig::where('company_uuid', $companyUuid)->first();
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
protected function getUuid(array|string $table, array $where, array $options = []): mixed
|
|
1049
|
+
{
|
|
1050
|
+
return Utils::getUuid($table, $where, $options);
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
protected function getModelClassName(?string $table): ?string
|
|
1054
|
+
{
|
|
1055
|
+
return Utils::getModelClassName($table);
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
protected function createOrderRecord(array $attributes): Order
|
|
1059
|
+
{
|
|
1060
|
+
return Order::create($attributes);
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
protected function resolveServiceQuote(CreateCustomerOrderRequest $request): mixed
|
|
1064
|
+
{
|
|
1065
|
+
return ServiceQuote::resolveFromRequest($request);
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
protected function newPayload(): Payload
|
|
1069
|
+
{
|
|
1070
|
+
return new Payload();
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
protected function queryPlaces(Request $request, callable $callback): mixed
|
|
1074
|
+
{
|
|
1075
|
+
return Place::queryWithRequest($request, $callback);
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
protected function firstOrCreateDevice(array $attributes, array $values): mixed
|
|
1079
|
+
{
|
|
1080
|
+
return UserDevice::firstOrCreate($attributes, $values);
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
protected function customerResource(Contact $contact): mixed
|
|
1084
|
+
{
|
|
1085
|
+
return new CustomerResource($contact);
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
protected function orderResource(Order $order): mixed
|
|
1089
|
+
{
|
|
1090
|
+
return new OrderResource($order);
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
protected function orderResourceCollection(mixed $results): mixed
|
|
1094
|
+
{
|
|
1095
|
+
return OrderResource::collection($results);
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
protected function placeResourceCollection(mixed $results): mixed
|
|
1099
|
+
{
|
|
1100
|
+
return PlaceResource::collection($results);
|
|
1101
|
+
}
|
|
1102
|
+
|
|
858
1103
|
/**
|
|
859
1104
|
* Normalize a phone number to international format (with leading `+`).
|
|
860
1105
|
*/
|