@fleetbase/fleetops-engine 0.6.48 → 0.6.50
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/addon/components/customer/create-order-form.hbs +2 -2
- package/addon/components/customer/form.hbs +2 -2
- package/addon/components/customer/order-form.hbs +2 -2
- package/addon/components/customer/orders.hbs +2 -2
- package/addon/components/display-place.hbs +2 -2
- package/addon/components/driver/details.hbs +5 -1
- package/addon/components/driver/form.hbs +11 -1
- package/addon/components/fleet-listing-panel.hbs +2 -2
- package/addon/components/fleet-listing-panel.js +10 -0
- package/addon/components/map/google-live-map.js +18 -75
- package/addon/components/map/leaflet-live-map.hbs +187 -37
- package/addon/components/map/leaflet-live-map.js +184 -20
- package/addon/components/modals/order-change-destination.hbs +46 -0
- package/addon/components/modals/order-change-destination.js +106 -0
- package/addon/components/modals/stop-activity.hbs +28 -0
- package/addon/components/modals/stop-activity.js +52 -0
- package/addon/components/modals/update-order-activity.hbs +45 -3
- package/addon/components/modals/update-order-activity.js +143 -5
- package/addon/components/orchestrator/phase-builder.hbs +21 -0
- package/addon/components/orchestrator/phase-builder.js +13 -0
- package/addon/components/orchestrator/resource-panel.hbs +0 -10
- package/addon/components/orchestrator/resource-panel.js +2 -4
- package/addon/components/orchestrator-workbench.js +1 -0
- package/addon/components/order/activity-list.hbs +2 -2
- package/addon/components/order/activity-timeline.hbs +31 -29
- package/addon/components/order/details/activity.hbs +3 -3
- package/addon/components/order/details/activity.js +11 -0
- package/addon/components/order/details/documents.js +2 -0
- package/addon/components/order/details/purchase-rate.hbs +2 -2
- package/addon/components/order/details/route.hbs +11 -3
- package/addon/components/order/details/route.js +91 -14
- package/addon/components/order/details/tracking.hbs +101 -72
- package/addon/components/order/details/tracking.js +149 -2
- package/addon/components/order/form/details.hbs +3 -3
- package/addon/components/order/form/documents.js +11 -4
- package/addon/components/order/form/route.hbs +108 -104
- package/addon/components/order/form/route.js +37 -1
- package/addon/components/order/form/service-rate.hbs +2 -2
- package/addon/components/order/form.hbs +2 -2
- package/addon/components/order-config-manager/activity-flow.hbs +4 -1
- package/addon/components/order-config-manager/activity-flow.js +178 -12
- package/addon/components/place/address.js +1 -1
- package/addon/components/route-list.hbs +17 -17
- package/addon/components/route-list.js +42 -10
- package/addon/components/service-rate/details.hbs +41 -0
- package/addon/components/service-rate/form.hbs +118 -0
- package/addon/components/service-rate/form.js +55 -0
- package/addon/components/vehicle/form.js +1 -1
- package/addon/components/vehicle/pill.hbs +1 -1
- package/addon/components/widget/fleet-ops-key-metrics.hbs +19 -17
- package/addon/components/widget/fleet-ops-key-metrics.js +26 -0
- package/addon/components/widget/fuel-efficiency.hbs +26 -0
- package/addon/components/widget/fuel-efficiency.js +43 -0
- package/addon/components/widget/geofence-violations.hbs +44 -0
- package/addon/components/widget/geofence-violations.js +55 -0
- package/addon/components/widget/issues-insights.hbs +43 -0
- package/addon/components/widget/issues-insights.js +62 -0
- package/addon/components/widget/kpi-active-orders.hbs +10 -0
- package/addon/components/widget/kpi-active-orders.js +5 -0
- package/addon/components/widget/kpi-aov.hbs +10 -0
- package/addon/components/widget/kpi-aov.js +5 -0
- package/addon/components/widget/kpi-distance.hbs +10 -0
- package/addon/components/widget/kpi-distance.js +5 -0
- package/addon/components/widget/kpi-drivers-online.hbs +10 -0
- package/addon/components/widget/kpi-drivers-online.js +5 -0
- package/addon/components/widget/kpi-earnings.hbs +10 -0
- package/addon/components/widget/kpi-earnings.js +5 -0
- package/addon/components/widget/kpi-open-issues.hbs +11 -0
- package/addon/components/widget/kpi-open-issues.js +5 -0
- package/addon/components/widget/kpi-tile.hbs +59 -0
- package/addon/components/widget/kpi-tile.js +168 -0
- package/addon/components/widget/live-fleet.hbs +122 -0
- package/addon/components/widget/live-fleet.js +365 -0
- package/addon/components/widget/maintenance-overview.hbs +45 -0
- package/addon/components/widget/maintenance-overview.js +40 -0
- package/addon/components/widget/on-time-delivery.hbs +27 -0
- package/addon/components/widget/on-time-delivery.js +73 -0
- package/addon/components/widget/operations-pulse.hbs +51 -0
- package/addon/components/widget/operations-pulse.js +173 -0
- package/addon/components/widget/orders-by-status.hbs +26 -0
- package/addon/components/widget/orders-by-status.js +54 -0
- package/addon/components/widget/revenue-trend.hbs +34 -0
- package/addon/components/widget/revenue-trend.js +67 -0
- package/addon/components/widget/top-drivers.hbs +44 -0
- package/addon/components/widget/top-drivers.js +54 -0
- package/addon/controllers/management/vehicles/index/new.js +1 -1
- package/addon/controllers/operations/orders/index/details.js +4 -4
- package/addon/controllers/operations/orders/index.js +14 -0
- package/addon/controllers/settings/routing.js +26 -0
- package/addon/extension.js +172 -3
- package/addon/helpers/place-address-html.js +2 -2
- package/addon/routes/operations/service-rates/index.js +1 -1
- package/addon/services/geofence.js +163 -19
- package/addon/services/leaflet-contextmenu-manager.js +27 -0
- package/addon/services/map-adapter/google.js +13 -2
- package/addon/services/vehicle-actions.js +1 -1
- package/addon/styles/fleetops-engine.css +205 -88
- package/addon/templates/maintenance/equipment/index.hbs +1 -1
- package/addon/templates/maintenance/parts/index.hbs +1 -1
- package/addon/templates/maintenance/schedules/index.hbs +1 -1
- package/addon/templates/management/vehicles/index.hbs +1 -1
- package/addon/templates/settings/avatars.hbs +1 -1
- package/addon/templates/settings/custom-fields.hbs +1 -1
- package/addon/templates/settings/map.hbs +1 -1
- package/addon/templates/settings/navigator-app.hbs +1 -1
- package/addon/templates/settings/notifications.hbs +1 -1
- package/addon/templates/settings/orchestrator.hbs +1 -1
- package/addon/templates/settings/payments/index.hbs +1 -1
- package/addon/templates/settings/payments/onboard.hbs +1 -1
- package/addon/templates/settings/routing.hbs +22 -2
- package/addon/templates/settings/scheduling.hbs +1 -1
- package/addon/utils/fleet-ops-options.js +2 -1
- package/addon/utils/live-map-card-content.js +171 -0
- package/addon/utils/normalize-order-config-flow.js +41 -0
- package/addon/utils/place-address-html.js +3 -2
- package/addon/utils/route-visualization.js +54 -7
- package/app/components/modals/order-change-destination.js +1 -0
- package/app/components/modals/stop-activity.js +1 -0
- package/app/components/widget/fuel-efficiency.js +1 -0
- package/app/components/widget/geofence-violations.js +1 -0
- package/app/components/widget/issues-insights.js +1 -0
- package/app/components/widget/kpi-active-orders.js +1 -0
- package/app/components/widget/kpi-aov.js +1 -0
- package/app/components/widget/kpi-distance.js +1 -0
- package/app/components/widget/kpi-drivers-online.js +1 -0
- package/app/components/widget/kpi-earnings.js +1 -0
- package/app/components/widget/kpi-open-issues.js +1 -0
- package/app/components/widget/kpi-tile.js +1 -0
- package/app/components/widget/live-fleet.js +1 -0
- package/app/components/widget/maintenance-overview.js +1 -0
- package/app/components/widget/on-time-delivery.js +1 -0
- package/app/components/widget/operations-pulse.js +1 -0
- package/app/components/widget/orders-by-status.js +1 -0
- package/app/components/widget/revenue-trend.js +1 -0
- package/app/components/widget/top-drivers.js +1 -0
- package/app/utils/live-map-card-content.js +1 -0
- package/composer.json +1 -1
- package/extension.json +1 -1
- package/package.json +3 -3
- package/pnpm-workspace.yaml +1 -0
- package/server/config/telematics.php +111 -1
- package/server/migrations/2026_05_18_000001_add_license_expiry_to_drivers_table.php +25 -0
- package/server/migrations/2026_05_21_000001_add_geographic_rules_to_service_rate_fees_table.php +37 -0
- package/server/migrations/2026_05_25_000001_add_endpoint_tracking_refs_to_payloads_table.php +50 -0
- package/server/migrations/2026_05_27_000001_default_driver_vehicle_statuses_to_available.php +48 -0
- package/server/resources/views/labels/default.php +57 -49
- package/server/resources/views/labels/waypoint-label.php +27 -20
- package/server/seeders/Testing/Concerns/SeedsTestingData.php +183 -0
- package/server/seeders/Testing/ConnectivitySeeder.php +213 -0
- package/server/seeders/Testing/FleetSeeder.php +341 -0
- package/server/seeders/Testing/MaintenanceSeeder.php +238 -0
- package/server/seeders/Testing/NetworkSeeder.php +250 -0
- package/server/seeders/Testing/OrdersSeeder.php +198 -0
- package/server/seeders/Testing/TestingSeeder.php +40 -0
- package/server/seeders/{VroomOrchestrationSeeder.php → Testing/VroomOrchestrationSeeder.php} +29 -22
- package/server/src/Console/Commands/AuditCustomerUserConflicts.php +75 -0
- package/server/src/Console/Commands/ProcessOperationalAlerts.php +279 -0
- package/server/src/Exceptions/CustomerUserConflictException.php +13 -0
- package/server/src/Http/Controllers/Api/v1/ContactController.php +17 -2
- package/server/src/Http/Controllers/Api/v1/CustomerController.php +876 -0
- package/server/src/Http/Controllers/Api/v1/DriverController.php +1 -1
- package/server/src/Http/Controllers/Api/v1/OrderConfigController.php +54 -0
- package/server/src/Http/Controllers/Api/v1/OrderController.php +98 -70
- package/server/src/Http/Controllers/Api/v1/ServiceAreaController.php +2 -2
- package/server/src/Http/Controllers/Api/v1/VehicleController.php +20 -3
- package/server/src/Http/Controllers/Internal/v1/AnalyticsController.php +119 -0
- package/server/src/Http/Controllers/Internal/v1/ContactController.php +19 -0
- package/server/src/Http/Controllers/Internal/v1/LiveController.php +101 -66
- package/server/src/Http/Controllers/Internal/v1/MetricsController.php +82 -3
- package/server/src/Http/Controllers/Internal/v1/OrderController.php +441 -32
- package/server/src/Http/Controllers/Internal/v1/ServiceQuoteController.php +1 -1
- package/server/src/Http/Controllers/Internal/v1/SettingController.php +46 -1
- package/server/src/Http/Controllers/Internal/v1/VehicleController.php +54 -1
- package/server/src/Http/Middleware/AuthenticateCustomerToken.php +34 -0
- package/server/src/Http/Requests/CreateCustomerOrderRequest.php +63 -0
- package/server/src/Http/Requests/CreateCustomerRequest.php +48 -0
- package/server/src/Http/Requests/CreateDriverRequest.php +1 -1
- package/server/src/Http/Requests/CreateVehicleRequest.php +25 -1
- package/server/src/Http/Requests/Internal/CreateDriverRequest.php +1 -1
- package/server/src/Http/Requests/VerifyCreateCustomerRequest.php +29 -0
- package/server/src/Http/Resources/Internal/v1/OrderConfig.php +41 -0
- package/server/src/Http/Resources/v1/Customer.php +79 -0
- package/server/src/Http/Resources/v1/Driver.php +2 -0
- package/server/src/Http/Resources/v1/Fleet.php +4 -0
- package/server/src/Http/Resources/v1/Index/Driver.php +48 -0
- package/server/src/Http/Resources/v1/Index/Vehicle.php +74 -1
- package/server/src/Http/Resources/v1/OrderConfig.php +74 -0
- package/server/src/Http/Resources/v1/Payload.php +23 -20
- package/server/src/Http/Resources/v1/ServiceArea.php +33 -19
- package/server/src/Http/Resources/v1/ServiceRateFee.php +7 -0
- package/server/src/Listeners/HandleOrderDispatched.php +2 -2
- package/server/src/Models/Contact.php +92 -15
- package/server/src/Models/Customer.php +64 -0
- package/server/src/Models/Driver.php +14 -3
- package/server/src/Models/Entity.php +2 -2
- package/server/src/Models/Order.php +29 -4
- package/server/src/Models/OrderConfig.php +14 -11
- package/server/src/Models/Payload.php +17 -1
- package/server/src/Models/ServiceRate.php +273 -1
- package/server/src/Models/ServiceRateFee.php +39 -9
- package/server/src/Models/TrackingNumber.php +8 -2
- package/server/src/Models/Vehicle.php +18 -2
- package/server/src/Models/Waypoint.php +2 -2
- package/server/src/Notifications/LateDeparture.php +48 -0
- package/server/src/Notifications/ProlongedStoppage.php +48 -0
- package/server/src/Notifications/RouteDeviation.php +48 -0
- package/server/src/Observers/ContactObserver.php +2 -0
- package/server/src/Observers/ServiceRateObserver.php +6 -6
- package/server/src/Orchestration/Engines/VroomOrchestrationEngine.php +29 -2
- package/server/src/Providers/FleetOpsServiceProvider.php +6 -0
- package/server/src/Providers/NotificationServiceProvider.php +3 -0
- package/server/src/Support/Analytics/AbstractAnalytics.php +77 -0
- package/server/src/Support/Analytics/FuelEfficiency.php +83 -0
- package/server/src/Support/Analytics/GeofenceViolations.php +63 -0
- package/server/src/Support/Analytics/IssuesInsights.php +67 -0
- package/server/src/Support/Analytics/LiveFleet.php +127 -0
- package/server/src/Support/Analytics/MaintenanceOverview.php +70 -0
- package/server/src/Support/Analytics/OnTimeDelivery.php +75 -0
- package/server/src/Support/Analytics/OperationsPulse.php +86 -0
- package/server/src/Support/Analytics/OrdersByStatus.php +64 -0
- package/server/src/Support/Analytics/RevenueTrend.php +78 -0
- package/server/src/Support/Analytics/TopDrivers.php +92 -0
- package/server/src/Support/CustomerAuth.php +98 -0
- package/server/src/Support/LabelPdf.php +52 -0
- package/server/src/Support/Metrics/AbstractMetric.php +170 -0
- package/server/src/Support/Metrics/ActiveLiveOrdersMetric.php +28 -0
- package/server/src/Support/Metrics/AvgOrderValueMetric.php +53 -0
- package/server/src/Support/Metrics/DriversOnlineMetric.php +30 -0
- package/server/src/Support/Metrics/EarningsMetric.php +30 -0
- package/server/src/Support/Metrics/FuelCostsMetric.php +30 -0
- package/server/src/Support/Metrics/MoneyMetric.php +30 -0
- package/server/src/Support/Metrics/OpenIssuesMetric.php +35 -0
- package/server/src/Support/Metrics/OrdersCanceledMetric.php +35 -0
- package/server/src/Support/Metrics/OrdersCompletedMetric.php +35 -0
- package/server/src/Support/Metrics/OrdersInProgressMetric.php +51 -0
- package/server/src/Support/Metrics/OrdersScheduledMetric.php +37 -0
- package/server/src/Support/Metrics/Registry.php +46 -0
- package/server/src/Support/Metrics/ResolvedIssuesMetric.php +35 -0
- package/server/src/Support/Metrics/TotalCustomersMetric.php +29 -0
- package/server/src/Support/Metrics/TotalDistanceTraveledMetric.php +35 -0
- package/server/src/Support/Metrics/TotalDriversMetric.php +28 -0
- package/server/src/Support/Metrics/TotalTimeTraveledMetric.php +35 -0
- package/server/src/Support/Metrics.php +46 -249
- package/server/src/Support/ResolvesOrderServiceStops.php +512 -0
- package/server/src/Support/Telematics/Providers/AfaqyProvider.php +290 -0
- package/server/src/Support/Telematics/Providers/SafeeProvider.php +333 -0
- package/server/src/Tracking/TrackingContextBuilder.php +41 -38
- package/server/src/Tracking/TrackingIntelligenceService.php +109 -9
- package/server/src/Tracking/TrackingStop.php +13 -11
- package/server/src/routes.php +50 -0
- package/server/tests/AnalyticsRoutesTest.php +41 -0
- package/server/tests/CapacityAllocationEngineTest.php +10 -10
- package/server/tests/CustomerContactIdentitySafetyTest.php +54 -0
- package/server/tests/CustomerEndpointTest.php +199 -0
- package/server/tests/DriverVehicleStatusDefaultTest.php +39 -0
- package/server/tests/LabelPdfRenderingTest.php +23 -0
- package/server/tests/LiveControllerViewportTest.php +60 -0
- package/server/tests/MetricsRegistryTest.php +84 -0
- package/server/tests/OrchestrationPayloadBuilderTest.php +2 -2
- package/server/tests/OrderConfigEndpointTest.php +86 -0
- package/server/tests/OrderFileAttachmentTest.php +20 -0
- package/server/tests/ServiceAreaZoneApiShapeTest.php +34 -0
- package/server/tests/VehicleDriverAssignmentTest.php +18 -0
- package/server/tests/VroomOrchestrationEngineTest.php +91 -0
- package/translations/en-us.yaml +38 -0
- package/server/migrations/2026_05_13_000001_repair_customer_contact_user_types.php +0 -86
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\FleetOps\Http\Resources\v1;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\Http\Resources\FleetbaseResource;
|
|
6
|
+
use Fleetbase\Support\Http;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Public, read-only projection of an OrderConfig.
|
|
10
|
+
*
|
|
11
|
+
* Exposes the activity `flow` so consumers can render status filter chips,
|
|
12
|
+
* activity labels, and progress UI without learning the internal config
|
|
13
|
+
* schema. Internal-only fields (entities JSON, version, namespace columns
|
|
14
|
+
* that aren't part of the public contract) are filtered out.
|
|
15
|
+
*/
|
|
16
|
+
class OrderConfig extends FleetbaseResource
|
|
17
|
+
{
|
|
18
|
+
/**
|
|
19
|
+
* Transform the resource into an array.
|
|
20
|
+
*
|
|
21
|
+
* @param \Illuminate\Http\Request $request
|
|
22
|
+
*/
|
|
23
|
+
public function toArray($request): array
|
|
24
|
+
{
|
|
25
|
+
return [
|
|
26
|
+
'id' => $this->when(Http::isInternalRequest(), $this->id, $this->public_id),
|
|
27
|
+
'uuid' => $this->when(Http::isInternalRequest(), $this->uuid),
|
|
28
|
+
'public_id' => $this->when(Http::isInternalRequest(), $this->public_id),
|
|
29
|
+
'company_uuid' => $this->when(Http::isInternalRequest(), $this->company_uuid),
|
|
30
|
+
'key' => $this->key,
|
|
31
|
+
'name' => $this->name,
|
|
32
|
+
'namespace' => $this->namespace,
|
|
33
|
+
'description' => $this->description,
|
|
34
|
+
'tags' => $this->tags,
|
|
35
|
+
'status' => $this->status,
|
|
36
|
+
'version' => $this->version,
|
|
37
|
+
'flow' => $this->projectFlow(),
|
|
38
|
+
'created_at' => $this->created_at,
|
|
39
|
+
'updated_at' => $this->updated_at,
|
|
40
|
+
];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Project the flow JSON into an ordered list of activities, keeping only
|
|
45
|
+
* the public-safe per-activity fields. `code` and `status` (the label)
|
|
46
|
+
* are the contract; `complete`, `color`, `details`, `pod_method`, and
|
|
47
|
+
* `require_pod` are useful UI hints that can ride along.
|
|
48
|
+
*/
|
|
49
|
+
protected function projectFlow(): array
|
|
50
|
+
{
|
|
51
|
+
$flow = $this->flow;
|
|
52
|
+
if (!is_array($flow) || empty($flow)) {
|
|
53
|
+
return [];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
$activities = [];
|
|
57
|
+
foreach ($flow as $activity) {
|
|
58
|
+
if (!is_array($activity)) {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
$activities[] = [
|
|
62
|
+
'code' => $activity['code'] ?? ($activity['key'] ?? null),
|
|
63
|
+
'status' => $activity['status'] ?? null,
|
|
64
|
+
'details' => $activity['details'] ?? null,
|
|
65
|
+
'color' => $activity['color'] ?? null,
|
|
66
|
+
'complete' => (bool) ($activity['complete'] ?? false),
|
|
67
|
+
'pod_method' => $activity['pod_method'] ?? null,
|
|
68
|
+
'require_pod' => (bool) ($activity['require_pod'] ?? false),
|
|
69
|
+
];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return $activities;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -22,26 +22,29 @@ class Payload extends FleetbaseResource
|
|
|
22
22
|
$withRouteETA = $request->has('with_route_eta');
|
|
23
23
|
|
|
24
24
|
return [
|
|
25
|
-
'id'
|
|
26
|
-
'uuid'
|
|
27
|
-
'public_id'
|
|
28
|
-
'current_waypoint_uuid'
|
|
29
|
-
'pickup_uuid'
|
|
30
|
-
'
|
|
31
|
-
'
|
|
32
|
-
'
|
|
33
|
-
'
|
|
34
|
-
'
|
|
35
|
-
'
|
|
36
|
-
'
|
|
37
|
-
'
|
|
38
|
-
'
|
|
39
|
-
'
|
|
40
|
-
'
|
|
41
|
-
'
|
|
42
|
-
'
|
|
43
|
-
'
|
|
44
|
-
'
|
|
25
|
+
'id' => $this->when(Http::isInternalRequest(), $this->id, $this->public_id),
|
|
26
|
+
'uuid' => $this->when(Http::isInternalRequest(), $this->uuid),
|
|
27
|
+
'public_id' => $this->when(Http::isInternalRequest(), $this->public_id),
|
|
28
|
+
'current_waypoint_uuid' => $this->when(Http::isInternalRequest(), $this->current_waypoint_uuid),
|
|
29
|
+
'pickup_uuid' => $this->when(Http::isInternalRequest(), $this->pickup_uuid),
|
|
30
|
+
'pickup_tracking_number_uuid' => $this->when(Http::isInternalRequest(), $this->pickup_tracking_number_uuid),
|
|
31
|
+
'dropoff_uuid' => $this->when(Http::isInternalRequest(), $this->dropoff_uuid),
|
|
32
|
+
'dropoff_tracking_number_uuid' => $this->when(Http::isInternalRequest(), $this->dropoff_tracking_number_uuid),
|
|
33
|
+
'return_uuid' => $this->when(Http::isInternalRequest(), $this->return_uuid),
|
|
34
|
+
'return_tracking_number_uuid' => $this->when(Http::isInternalRequest(), $this->return_tracking_number_uuid),
|
|
35
|
+
'current_waypoint' => $this->when(Http::isPublicRequest() && $this->currentWaypoint, data_get($this, 'currentWaypoint.public_id')),
|
|
36
|
+
'pickup' => $this->getPlace($this->pickup),
|
|
37
|
+
'dropoff' => $this->getPlace($this->dropoff),
|
|
38
|
+
'return' => new Place($this->return),
|
|
39
|
+
'waypoints' => Waypoint::collection($this->getWaypoints($withRouteETA)),
|
|
40
|
+
'entities' => Entity::collection($this->entities),
|
|
41
|
+
'cod_amount' => $this->cod_amount ?? null,
|
|
42
|
+
'cod_currency' => $this->cod_currency ?? null,
|
|
43
|
+
'cod_payment_method' => $this->cod_payment_method ?? null,
|
|
44
|
+
'payment_method' => $this->payment_method ?? null,
|
|
45
|
+
'meta' => data_get($this, 'meta', Utils::createObject()),
|
|
46
|
+
'updated_at' => $this->updated_at,
|
|
47
|
+
'created_at' => $this->created_at,
|
|
45
48
|
];
|
|
46
49
|
}
|
|
47
50
|
|
|
@@ -17,17 +17,24 @@ class ServiceArea extends FleetbaseResource
|
|
|
17
17
|
public function toArray($request)
|
|
18
18
|
{
|
|
19
19
|
return $this->withCustomFields([
|
|
20
|
-
'id'
|
|
21
|
-
'uuid'
|
|
22
|
-
'public_id'
|
|
23
|
-
'name'
|
|
24
|
-
'type'
|
|
25
|
-
'center'
|
|
26
|
-
'border'
|
|
27
|
-
'zones'
|
|
28
|
-
'
|
|
29
|
-
'
|
|
30
|
-
'
|
|
20
|
+
'id' => $this->when(Http::isInternalRequest(), $this->id, $this->public_id),
|
|
21
|
+
'uuid' => $this->when(Http::isInternalRequest(), $this->uuid),
|
|
22
|
+
'public_id' => $this->when(Http::isInternalRequest(), $this->public_id),
|
|
23
|
+
'name' => $this->name,
|
|
24
|
+
'type' => $this->type,
|
|
25
|
+
'center' => $this->location,
|
|
26
|
+
'border' => $this->border,
|
|
27
|
+
'zones' => $this->whenLoaded('zones', fn () => Zone::collection($this->zones)),
|
|
28
|
+
'color' => $this->color,
|
|
29
|
+
'stroke_color' => $this->stroke_color,
|
|
30
|
+
'trigger_on_entry' => $this->trigger_on_entry,
|
|
31
|
+
'trigger_on_exit' => $this->trigger_on_exit,
|
|
32
|
+
'dwell_threshold_minutes' => $this->dwell_threshold_minutes,
|
|
33
|
+
'speed_limit_kmh' => $this->speed_limit_kmh,
|
|
34
|
+
'country' => $this->country,
|
|
35
|
+
'status' => $this->status,
|
|
36
|
+
'updated_at' => $this->updated_at,
|
|
37
|
+
'created_at' => $this->created_at,
|
|
31
38
|
]);
|
|
32
39
|
}
|
|
33
40
|
|
|
@@ -39,14 +46,21 @@ class ServiceArea extends FleetbaseResource
|
|
|
39
46
|
public function toWebhookPayload()
|
|
40
47
|
{
|
|
41
48
|
return [
|
|
42
|
-
'id'
|
|
43
|
-
'name'
|
|
44
|
-
'type'
|
|
45
|
-
'center'
|
|
46
|
-
'border'
|
|
47
|
-
'
|
|
48
|
-
'
|
|
49
|
-
'
|
|
49
|
+
'id' => $this->public_id,
|
|
50
|
+
'name' => $this->name,
|
|
51
|
+
'type' => $this->type,
|
|
52
|
+
'center' => $this->location,
|
|
53
|
+
'border' => $this->border,
|
|
54
|
+
'color' => $this->color,
|
|
55
|
+
'stroke_color' => $this->stroke_color,
|
|
56
|
+
'trigger_on_entry' => $this->trigger_on_entry,
|
|
57
|
+
'trigger_on_exit' => $this->trigger_on_exit,
|
|
58
|
+
'dwell_threshold_minutes' => $this->dwell_threshold_minutes,
|
|
59
|
+
'speed_limit_kmh' => $this->speed_limit_kmh,
|
|
60
|
+
'country' => $this->country,
|
|
61
|
+
'status' => $this->status,
|
|
62
|
+
'updated_at' => $this->updated_at,
|
|
63
|
+
'created_at' => $this->created_at,
|
|
50
64
|
];
|
|
51
65
|
}
|
|
52
66
|
}
|
|
@@ -20,6 +20,13 @@ class ServiceRateFee extends FleetbaseResource
|
|
|
20
20
|
'id' => $this->when(Http::isInternalRequest(), $this->id),
|
|
21
21
|
'uuid' => $this->when(Http::isInternalRequest(), $this->uuid),
|
|
22
22
|
'service_rate_uuid' => $this->when(Http::isInternalRequest(), $this->service_rate_uuid),
|
|
23
|
+
'service_area_uuid' => $this->when(Http::isInternalRequest(), $this->service_area_uuid),
|
|
24
|
+
'zone_uuid' => $this->when(Http::isInternalRequest(), $this->zone_uuid),
|
|
25
|
+
'service_area' => $this->whenLoaded('serviceArea', fn () => new ServiceArea($this->serviceArea)),
|
|
26
|
+
'zone' => $this->whenLoaded('zone', fn () => new Zone($this->zone)),
|
|
27
|
+
'label' => $this->label,
|
|
28
|
+
'priority' => $this->priority,
|
|
29
|
+
'is_fallback' => (bool) $this->is_fallback,
|
|
23
30
|
'fee' => $this->fee,
|
|
24
31
|
'currency' => $this->currency,
|
|
25
32
|
'min' => $this->min,
|
|
@@ -69,11 +69,11 @@ class HandleOrderDispatched implements ShouldQueue
|
|
|
69
69
|
return;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
$drivers = Driver::where(['status' => '
|
|
72
|
+
$drivers = Driver::where(['status' => 'available', 'online' => 1])
|
|
73
73
|
->whereHas('company', function ($q) {
|
|
74
74
|
$q->whereHas('users', function ($q) {
|
|
75
75
|
$q->whereHas('driver', function ($q) {
|
|
76
|
-
$q->where(['status' => '
|
|
76
|
+
$q->where(['status' => 'available', 'online' => 1]);
|
|
77
77
|
$q->whereNull('deleted_at');
|
|
78
78
|
});
|
|
79
79
|
});
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
namespace Fleetbase\FleetOps\Models;
|
|
4
4
|
|
|
5
5
|
use Fleetbase\Casts\Json;
|
|
6
|
+
use Fleetbase\FleetOps\Exceptions\CustomerUserConflictException;
|
|
6
7
|
use Fleetbase\FleetOps\Exceptions\UserAlreadyExistsException;
|
|
7
8
|
use Fleetbase\FleetOps\Support\Utils;
|
|
8
9
|
use Fleetbase\Models\CompanyUser;
|
|
@@ -319,7 +320,12 @@ class Contact extends Model
|
|
|
319
320
|
// Check if user already exist with email or phone number
|
|
320
321
|
$existingUser = null;
|
|
321
322
|
if ($contact->email || $contact->phone) {
|
|
322
|
-
$existingUser = User::where(
|
|
323
|
+
$existingUser = User::where(function ($query) use ($contact) {
|
|
324
|
+
$query->where('company_uuid', $contact->company_uuid)
|
|
325
|
+
->orWhereHas('companyUsers', function ($query) use ($contact) {
|
|
326
|
+
$query->where('company_uuid', $contact->company_uuid);
|
|
327
|
+
});
|
|
328
|
+
})
|
|
323
329
|
->where(function ($query) use ($contact) {
|
|
324
330
|
if ($contact->email) {
|
|
325
331
|
$query->where('email', $contact->email);
|
|
@@ -335,15 +341,15 @@ class Contact extends Model
|
|
|
335
341
|
}
|
|
336
342
|
|
|
337
343
|
if ($existingUser) {
|
|
344
|
+
if ($contact->isCustomer()) {
|
|
345
|
+
$contact->assertCustomerUserCanBeAssigned($existingUser);
|
|
346
|
+
}
|
|
347
|
+
|
|
338
348
|
// Check if existing user belongs to another contact
|
|
339
349
|
$existingUserContact = Contact::where(['user_uuid' => $existingUser->uuid, 'company_uuid' => $contact->company_uuid])->whereHas('user')->first();
|
|
340
350
|
if ($existingUserContact) {
|
|
341
351
|
throw new UserAlreadyExistsException('User already exists, try to assigning the user to this contact.', $existingUser);
|
|
342
352
|
} else {
|
|
343
|
-
if ($contact->isCustomer()) {
|
|
344
|
-
$contact->normalizeCustomerUser($existingUser);
|
|
345
|
-
}
|
|
346
|
-
|
|
347
353
|
// Assign the user to this contact instead
|
|
348
354
|
$contact->setAttribute('user_uuid', $existingUser->uuid);
|
|
349
355
|
if ($update) {
|
|
@@ -423,13 +429,7 @@ class Contact extends Model
|
|
|
423
429
|
return null;
|
|
424
430
|
}
|
|
425
431
|
|
|
426
|
-
|
|
427
|
-
if ($quiet) {
|
|
428
|
-
$user->forceFill(['type' => 'customer'])->saveQuietly();
|
|
429
|
-
} else {
|
|
430
|
-
$user->setType('customer');
|
|
431
|
-
}
|
|
432
|
-
}
|
|
432
|
+
$this->assertCustomerUserCanBeAssigned($user);
|
|
433
433
|
|
|
434
434
|
$this->loadMissing('company');
|
|
435
435
|
if ($this->company) {
|
|
@@ -463,7 +463,7 @@ class Contact extends Model
|
|
|
463
463
|
public function repairCustomerTypeInvariant(bool $quiet = false): ?User
|
|
464
464
|
{
|
|
465
465
|
if (!$this->isCustomer()) {
|
|
466
|
-
$this->
|
|
466
|
+
return $this->getUser();
|
|
467
467
|
}
|
|
468
468
|
|
|
469
469
|
$user = $this->getUser();
|
|
@@ -512,8 +512,17 @@ class Contact extends Model
|
|
|
512
512
|
// Load company
|
|
513
513
|
$this->loadMissing('company');
|
|
514
514
|
|
|
515
|
-
if ($this->isCustomer()
|
|
516
|
-
$
|
|
515
|
+
if ($this->isCustomer()) {
|
|
516
|
+
$this->assertCustomerUserCanBeAssigned($user);
|
|
517
|
+
|
|
518
|
+
$existingUserContact = static::where(['user_uuid' => $user->uuid, 'company_uuid' => $this->company_uuid])
|
|
519
|
+
->whereNot('uuid', $this->uuid)
|
|
520
|
+
->whereHas('user')
|
|
521
|
+
->first();
|
|
522
|
+
|
|
523
|
+
if ($existingUserContact) {
|
|
524
|
+
throw new UserAlreadyExistsException('User already exists, try to assigning the user to this contact.', $user);
|
|
525
|
+
}
|
|
517
526
|
}
|
|
518
527
|
|
|
519
528
|
// Assing to company
|
|
@@ -551,6 +560,74 @@ class Contact extends Model
|
|
|
551
560
|
return $this;
|
|
552
561
|
}
|
|
553
562
|
|
|
563
|
+
public function assertCustomerIdentityIsAvailable(): void
|
|
564
|
+
{
|
|
565
|
+
if (!$this->isCustomer()) {
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
$assignedUser = $this->getAssignedUserWithoutTypeScope();
|
|
570
|
+
if ($assignedUser) {
|
|
571
|
+
$this->assertCustomerUserCanBeAssigned($assignedUser);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
$matchedUser = $this->findExistingUserByIdentity();
|
|
575
|
+
if ($matchedUser && $matchedUser->uuid !== $this->user_uuid) {
|
|
576
|
+
$this->assertCustomerUserCanBeAssigned($matchedUser);
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
public function assertCustomerUserCanBeAssigned(User $user): void
|
|
581
|
+
{
|
|
582
|
+
if ($user->type === 'customer') {
|
|
583
|
+
return;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
throw new CustomerUserConflictException(static::customerUserConflictMessage($user), $user);
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
public static function customerUserConflictMessage(?User $user = null): string
|
|
590
|
+
{
|
|
591
|
+
$field = $user?->email ? 'email' : ($user?->phone ? 'phone number' : 'user account');
|
|
592
|
+
|
|
593
|
+
return 'This ' . $field . ' belongs to an existing staff user and cannot be used for a customer account.';
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
private function findExistingUserByIdentity(): ?User
|
|
597
|
+
{
|
|
598
|
+
if (!$this->email && !$this->phone) {
|
|
599
|
+
return null;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
return User::where(function ($query) {
|
|
603
|
+
$query->where('company_uuid', $this->company_uuid)
|
|
604
|
+
->orWhereHas('companyUsers', function ($query) {
|
|
605
|
+
$query->where('company_uuid', $this->company_uuid);
|
|
606
|
+
});
|
|
607
|
+
})
|
|
608
|
+
->where(function ($query) {
|
|
609
|
+
if ($this->email) {
|
|
610
|
+
$query->where('email', $this->email);
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
if ($this->phone) {
|
|
614
|
+
$method = $this->email ? 'orWhere' : 'where';
|
|
615
|
+
$query->{$method}('phone', Utils::formatPhoneNumber($this->phone));
|
|
616
|
+
}
|
|
617
|
+
})
|
|
618
|
+
->whereNull('deleted_at')
|
|
619
|
+
->first();
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
private function getAssignedUserWithoutTypeScope(): ?User
|
|
623
|
+
{
|
|
624
|
+
if (!Str::isUuid($this->user_uuid)) {
|
|
625
|
+
return null;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
return User::where('uuid', $this->user_uuid)->first();
|
|
629
|
+
}
|
|
630
|
+
|
|
554
631
|
public function syncWithUser(): bool
|
|
555
632
|
{
|
|
556
633
|
$updates = [];
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\FleetOps\Models;
|
|
4
|
+
|
|
5
|
+
use Illuminate\Database\Eloquent\Builder;
|
|
6
|
+
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
7
|
+
use Illuminate\Support\Str;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Fleet-Ops customer.
|
|
11
|
+
*
|
|
12
|
+
* A thin specialization of {@see Contact} that is scoped to rows with
|
|
13
|
+
* `type='customer'` and forces that type on create. This is what the public
|
|
14
|
+
* customer API surface (`/v1/customers/...`) operates on.
|
|
15
|
+
*
|
|
16
|
+
* Mirrors {@see \Fleetbase\Storefront\Models\Customer} but lives directly in
|
|
17
|
+
* FleetOps so that customer auth + customer-scoped orders work without the
|
|
18
|
+
* Storefront publishable-key + Store/Network gating.
|
|
19
|
+
*/
|
|
20
|
+
class Customer extends Contact
|
|
21
|
+
{
|
|
22
|
+
/**
|
|
23
|
+
* The key to use in the payload responses.
|
|
24
|
+
*/
|
|
25
|
+
protected string $payloadKey = 'customer';
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Boot the model.
|
|
29
|
+
*/
|
|
30
|
+
protected static function boot()
|
|
31
|
+
{
|
|
32
|
+
parent::boot();
|
|
33
|
+
|
|
34
|
+
static::creating(function ($model) {
|
|
35
|
+
$model->type = 'customer';
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
static::addGlobalScope('type', function (Builder $builder) {
|
|
39
|
+
$builder->where('type', 'customer');
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Orders owned by this customer.
|
|
45
|
+
*/
|
|
46
|
+
public function orders(): HasMany
|
|
47
|
+
{
|
|
48
|
+
return $this->hasMany(Order::class, 'customer_uuid')
|
|
49
|
+
->whereNull('deleted_at')
|
|
50
|
+
->withoutGlobalScopes();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Find a customer by either a `customer_xxx` or `contact_xxx` public id.
|
|
55
|
+
*/
|
|
56
|
+
public static function findFromCustomerId(string $publicId): ?self
|
|
57
|
+
{
|
|
58
|
+
if (Str::startsWith($publicId, 'customer')) {
|
|
59
|
+
$publicId = Str::replaceFirst('customer', 'contact', $publicId);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return static::where('public_id', $publicId)->first();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -97,6 +97,7 @@ class Driver extends Model
|
|
|
97
97
|
'signup_token_used',
|
|
98
98
|
'avatar_url',
|
|
99
99
|
'drivers_license_number',
|
|
100
|
+
'license_expiry',
|
|
100
101
|
'location',
|
|
101
102
|
'heading',
|
|
102
103
|
'bearing',
|
|
@@ -118,6 +119,15 @@ class Driver extends Model
|
|
|
118
119
|
'time_window_end',
|
|
119
120
|
];
|
|
120
121
|
|
|
122
|
+
/**
|
|
123
|
+
* Set attributes and defaults.
|
|
124
|
+
*
|
|
125
|
+
* @var array
|
|
126
|
+
*/
|
|
127
|
+
protected $attributes = [
|
|
128
|
+
'status' => 'available',
|
|
129
|
+
];
|
|
130
|
+
|
|
121
131
|
/**
|
|
122
132
|
* The attributes that are guarded and not mass assignable.
|
|
123
133
|
*
|
|
@@ -141,6 +151,7 @@ class Driver extends Model
|
|
|
141
151
|
'location' => Point::class,
|
|
142
152
|
'online' => 'boolean',
|
|
143
153
|
'meta' => Json::class,
|
|
154
|
+
'license_expiry' => 'date',
|
|
144
155
|
// Orchestrator
|
|
145
156
|
'skills' => Json::class,
|
|
146
157
|
'max_travel_time' => 'integer',
|
|
@@ -593,9 +604,9 @@ class Driver extends Model
|
|
|
593
604
|
/**
|
|
594
605
|
* Set the driver status attribute.
|
|
595
606
|
*/
|
|
596
|
-
public function setStatusAttribute(?string $status = '
|
|
607
|
+
public function setStatusAttribute(?string $status = 'available'): void
|
|
597
608
|
{
|
|
598
|
-
$this->attributes['status'] = $status;
|
|
609
|
+
$this->attributes['status'] = $status === null || $status === 'active' ? 'available' : $status;
|
|
599
610
|
}
|
|
600
611
|
|
|
601
612
|
/**
|
|
@@ -852,7 +863,7 @@ class Driver extends Model
|
|
|
852
863
|
'user_uuid' => $user->uuid,
|
|
853
864
|
'drivers_license_number' => $driversLicenseNumber,
|
|
854
865
|
'country' => $country,
|
|
855
|
-
'status' => '
|
|
866
|
+
'status' => 'available',
|
|
856
867
|
'location' => Utils::parsePointToWkt(new Point(0, 0)),
|
|
857
868
|
]);
|
|
858
869
|
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
namespace Fleetbase\FleetOps\Models;
|
|
4
4
|
|
|
5
|
-
use Barryvdh\DomPDF\Facade\Pdf;
|
|
6
5
|
use Fleetbase\Casts\Json;
|
|
7
6
|
use Fleetbase\Casts\PolymorphicType;
|
|
7
|
+
use Fleetbase\FleetOps\Support\LabelPdf;
|
|
8
8
|
use Fleetbase\FleetOps\Support\Utils;
|
|
9
9
|
use Fleetbase\FleetOps\Traits\HasTrackingNumber;
|
|
10
10
|
use Fleetbase\FleetOps\Traits\PayloadAccessors;
|
|
@@ -142,7 +142,7 @@ class Entity extends Model
|
|
|
142
142
|
*/
|
|
143
143
|
public function pdfLabel()
|
|
144
144
|
{
|
|
145
|
-
return
|
|
145
|
+
return LabelPdf::fromHtml($this->label());
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
/**
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
namespace Fleetbase\FleetOps\Models;
|
|
4
4
|
|
|
5
|
-
use Barryvdh\DomPDF\Facade\Pdf;
|
|
6
5
|
use Fleetbase\Casts\Json;
|
|
7
6
|
use Fleetbase\Casts\PolymorphicType;
|
|
8
7
|
use Fleetbase\FleetOps\Events\OrderCanceled;
|
|
@@ -10,6 +9,7 @@ use Fleetbase\FleetOps\Events\OrderCompleted;
|
|
|
10
9
|
use Fleetbase\FleetOps\Events\OrderDispatched;
|
|
11
10
|
use Fleetbase\FleetOps\Events\OrderDriverAssigned;
|
|
12
11
|
use Fleetbase\FleetOps\Flow\Activity;
|
|
12
|
+
use Fleetbase\FleetOps\Support\LabelPdf;
|
|
13
13
|
use Fleetbase\FleetOps\Support\OrderTracker;
|
|
14
14
|
use Fleetbase\FleetOps\Support\Utils;
|
|
15
15
|
use Fleetbase\FleetOps\Traits\HasTrackingNumber;
|
|
@@ -275,7 +275,32 @@ class Order extends Model
|
|
|
275
275
|
*/
|
|
276
276
|
public function pdfLabel()
|
|
277
277
|
{
|
|
278
|
-
return
|
|
278
|
+
return LabelPdf::fromHtml($this->label());
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
public function attachFiles($uploads): self
|
|
282
|
+
{
|
|
283
|
+
$ids = collect($uploads)
|
|
284
|
+
->map(function ($upload) {
|
|
285
|
+
if (is_string($upload)) {
|
|
286
|
+
return $upload;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return data_get($upload, 'uuid') ?? data_get($upload, 'id');
|
|
290
|
+
})
|
|
291
|
+
->filter()
|
|
292
|
+
->unique()
|
|
293
|
+
->values();
|
|
294
|
+
|
|
295
|
+
if ($ids->isEmpty()) {
|
|
296
|
+
return $this;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
\Fleetbase\Models\File::whereIn('uuid', $ids)->get()->each(function ($file) {
|
|
300
|
+
$file->setKey($this);
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
return $this;
|
|
279
304
|
}
|
|
280
305
|
|
|
281
306
|
/**
|
|
@@ -1991,11 +2016,11 @@ class Order extends Model
|
|
|
1991
2016
|
return collect();
|
|
1992
2017
|
}
|
|
1993
2018
|
|
|
1994
|
-
$drivers = Driver::where(['status' => '
|
|
2019
|
+
$drivers = Driver::where(['status' => 'available', 'online' => 1])
|
|
1995
2020
|
->whereHas('company', function ($q) {
|
|
1996
2021
|
$q->whereHas('users', function ($q) {
|
|
1997
2022
|
$q->whereHas('driver', function ($q) {
|
|
1998
|
-
$q->where(['status' => '
|
|
2023
|
+
$q->where(['status' => 'available', 'online' => 1]);
|
|
1999
2024
|
$q->whereNull('deleted_at');
|
|
2000
2025
|
});
|
|
2001
2026
|
});
|
|
@@ -458,28 +458,31 @@ class OrderConfig extends Model
|
|
|
458
458
|
/**
|
|
459
459
|
* Resolves an OrderConfig from a given identifier or an array of identifiers within an optional company context.
|
|
460
460
|
*
|
|
461
|
-
* @param string|array $orderConfigIdentifier the identifier(s) for the OrderConfig (namespace, public_id, or key)
|
|
461
|
+
* @param string|array $orderConfigIdentifier the identifier(s) for the OrderConfig (uuid, namespace, public_id, or key)
|
|
462
462
|
* @param Company|null $company the company context, if any, to narrow down the search
|
|
463
463
|
*
|
|
464
464
|
* @return OrderConfig|null the found OrderConfig or null if none found
|
|
465
465
|
*/
|
|
466
466
|
public static function resolveFromIdentifier($orderConfigIdentifier, ?Company $company = null): ?OrderConfig
|
|
467
467
|
{
|
|
468
|
-
$
|
|
468
|
+
$companyUuid = $company instanceof Company ? $company->uuid : session('company');
|
|
469
|
+
$identifiers = is_array($orderConfigIdentifier) ? $orderConfigIdentifier : [$orderConfigIdentifier];
|
|
470
|
+
$identifiers = collect($identifiers)->filter(fn ($identifier) => filled($identifier))->values();
|
|
471
|
+
|
|
472
|
+
if ($identifiers->isEmpty()) {
|
|
473
|
+
return static::default($company);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
foreach ($identifiers as $identifier) {
|
|
477
|
+
$query = static::query();
|
|
469
478
|
|
|
470
|
-
if ($company instanceof Company) {
|
|
471
|
-
$query->where('company_uuid', $company->uuid);
|
|
472
|
-
} else {
|
|
473
|
-
$companyUuid = session('company');
|
|
474
479
|
if ($companyUuid) {
|
|
475
480
|
$query->where('company_uuid', $companyUuid);
|
|
476
481
|
}
|
|
477
|
-
}
|
|
478
482
|
|
|
479
|
-
$identifiers = is_array($orderConfigIdentifier) ? $orderConfigIdentifier : [$orderConfigIdentifier];
|
|
480
|
-
foreach ($identifiers as $identifier) {
|
|
481
483
|
$orderConfig = $query->where(function ($query) use ($identifier) {
|
|
482
|
-
$query->where('
|
|
484
|
+
$query->where('uuid', $identifier)
|
|
485
|
+
->orWhere('namespace', $identifier)
|
|
483
486
|
->orWhere('public_id', $identifier)
|
|
484
487
|
->orWhere('key', $identifier);
|
|
485
488
|
})->first();
|
|
@@ -489,7 +492,7 @@ class OrderConfig extends Model
|
|
|
489
492
|
}
|
|
490
493
|
}
|
|
491
494
|
|
|
492
|
-
return
|
|
495
|
+
return null;
|
|
493
496
|
}
|
|
494
497
|
|
|
495
498
|
/**
|
|
@@ -61,7 +61,23 @@ class Payload extends Model
|
|
|
61
61
|
*
|
|
62
62
|
* @var array
|
|
63
63
|
*/
|
|
64
|
-
protected $fillable = [
|
|
64
|
+
protected $fillable = [
|
|
65
|
+
'_key',
|
|
66
|
+
'company_uuid',
|
|
67
|
+
'pickup_uuid',
|
|
68
|
+
'pickup_tracking_number_uuid',
|
|
69
|
+
'dropoff_uuid',
|
|
70
|
+
'dropoff_tracking_number_uuid',
|
|
71
|
+
'return_uuid',
|
|
72
|
+
'return_tracking_number_uuid',
|
|
73
|
+
'current_waypoint_uuid',
|
|
74
|
+
'meta',
|
|
75
|
+
'payment_method',
|
|
76
|
+
'cod_amount',
|
|
77
|
+
'cod_currency',
|
|
78
|
+
'cod_payment_method',
|
|
79
|
+
'type',
|
|
80
|
+
];
|
|
65
81
|
|
|
66
82
|
/**
|
|
67
83
|
* The attributes that should be cast to native types.
|