@fleetbase/fleetops-engine 0.6.68 → 0.6.70
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/RELEASE.md +44 -9
- package/addon/components/admin/telematics-settings.hbs +143 -0
- package/addon/components/admin/telematics-settings.js +145 -0
- package/addon/components/contact/form.hbs +13 -2
- package/addon/components/customer/details.hbs +17 -17
- package/addon/components/customer/form.hbs +13 -2
- package/addon/components/customer/form.js +0 -56
- package/addon/components/driver/details.hbs +13 -19
- package/addon/components/driver/form.hbs +20 -35
- package/addon/components/driver/form.js +0 -58
- package/addon/components/fuel-integration/hub.hbs +1 -1
- package/addon/components/layout/fleet-ops-sidebar.js +37 -17
- package/addon/components/map/leaflet-live-map.hbs +4 -242
- package/addon/components/map/leaflet-live-map.js +2 -1
- package/addon/components/map/marker-card/driver.hbs +57 -0
- package/addon/components/map/marker-card/driver.js +3 -0
- package/addon/components/map/marker-card/vehicle.hbs +78 -0
- package/addon/components/map/marker-card/vehicle.js +3 -0
- package/addon/components/modals/driver-form.hbs +2 -2
- package/addon/components/modals/reset-profile-credentials.hbs +23 -0
- package/addon/components/modals/reset-profile-credentials.js +70 -0
- package/addon/components/profile-identity-hint.hbs +13 -0
- package/addon/components/profile-identity-hint.js +49 -0
- package/addon/components/telematic/hub.hbs +1 -1
- package/addon/components/widget/live-fleet.hbs +8 -40
- package/addon/controllers/analytics/reports/index.js +5 -0
- package/addon/controllers/connectivity/devices/index.js +4 -0
- package/addon/controllers/connectivity/fuel-providers/index.js +6 -4
- package/addon/controllers/connectivity/sensors/index.js +4 -0
- package/addon/controllers/connectivity/telematics/index.js +4 -0
- package/addon/controllers/maintenance/equipment/index.js +11 -4
- package/addon/controllers/maintenance/inspection-forms/index.js +2 -2
- package/addon/controllers/maintenance/inspection-submissions/index.js +8 -2
- package/addon/controllers/maintenance/maintenances/index.js +4 -0
- package/addon/controllers/maintenance/parts/index.js +11 -4
- package/addon/controllers/maintenance/schedules/index.js +17 -4
- package/addon/controllers/maintenance/work-orders/index.js +11 -4
- package/addon/controllers/management/contacts/index.js +4 -0
- package/addon/controllers/management/drivers/index.js +8 -0
- package/addon/controllers/management/fleets/index.js +4 -0
- package/addon/controllers/management/fuel-reports/index.js +4 -0
- package/addon/controllers/management/fuel-transactions/index.js +9 -7
- package/addon/controllers/management/issues/index.js +4 -0
- package/addon/controllers/management/places/index.js +4 -0
- package/addon/controllers/management/vehicles/index.js +4 -0
- package/addon/controllers/management/vendors/index.js +4 -0
- package/addon/controllers/operations/orders/index/details.js +30 -1
- package/addon/controllers/operations/orders/index.js +7 -0
- package/addon/controllers/operations/service-rates/index.js +3 -0
- package/addon/controllers/settings/index.js +13 -0
- package/addon/controllers/settings/telematics.js +113 -0
- package/addon/extension.js +42 -8
- package/addon/routes/analytics/index.js +14 -1
- package/addon/routes/analytics/reports/index/details.js +1 -1
- package/addon/routes/analytics/reports/index/edit.js +1 -1
- package/addon/routes/analytics/reports/index/new.js +14 -1
- package/addon/routes/analytics/reports.js +14 -1
- package/addon/routes/connectivity/devices/index/new.js +14 -1
- package/addon/routes/connectivity/devices.js +14 -1
- package/addon/routes/connectivity/events.js +14 -1
- package/addon/routes/connectivity/fuel-providers/details/transactions.js +12 -0
- package/addon/routes/connectivity/fuel-providers/details.js +9 -0
- package/addon/routes/connectivity/fuel-providers/edit.js +9 -0
- package/addon/routes/connectivity/fuel-providers/new.js +14 -1
- package/addon/routes/connectivity/fuel-providers.js +14 -1
- package/addon/routes/connectivity/sensors/index/new.js +14 -1
- package/addon/routes/connectivity/sensors.js +14 -1
- package/addon/routes/connectivity/telematics/new.js +14 -1
- package/addon/routes/connectivity/telematics.js +14 -1
- package/addon/routes/connectivity/tracking.js +14 -1
- package/addon/routes/maintenance/equipment/index/details.js +2 -2
- package/addon/routes/maintenance/equipment/index/edit.js +2 -2
- package/addon/routes/maintenance/equipment/index/new.js +14 -1
- package/addon/routes/maintenance/equipment.js +14 -1
- package/addon/routes/maintenance/index.js +14 -1
- package/addon/routes/maintenance/inspection-forms/index/details.js +10 -1
- package/addon/routes/maintenance/inspection-forms/index/edit.js +10 -1
- package/addon/routes/maintenance/inspection-forms/index/new.js +14 -1
- package/addon/routes/maintenance/inspection-forms.js +14 -1
- package/addon/routes/maintenance/inspection-submissions/index/details.js +10 -1
- package/addon/routes/maintenance/inspection-submissions/index/edit.js +10 -1
- package/addon/routes/maintenance/inspection-submissions/index/new.js +14 -1
- package/addon/routes/maintenance/inspection-submissions.js +14 -1
- package/addon/routes/maintenance/maintenances/index/details.js +2 -2
- package/addon/routes/maintenance/maintenances/index/edit.js +2 -2
- package/addon/routes/maintenance/maintenances/index/new.js +14 -1
- package/addon/routes/maintenance/maintenances.js +14 -1
- package/addon/routes/maintenance/parts/index/details.js +2 -2
- package/addon/routes/maintenance/parts/index/edit.js +2 -2
- package/addon/routes/maintenance/parts/index/new.js +14 -1
- package/addon/routes/maintenance/parts.js +14 -1
- package/addon/routes/maintenance/schedules/index/details.js +2 -2
- package/addon/routes/maintenance/schedules/index/edit.js +2 -2
- package/addon/routes/maintenance/schedules/index/new.js +15 -1
- package/addon/routes/maintenance/schedules.js +15 -1
- package/addon/routes/maintenance/work-orders/index/details.js +2 -2
- package/addon/routes/maintenance/work-orders/index/edit.js +2 -2
- package/addon/routes/maintenance/work-orders/index/new.js +14 -1
- package/addon/routes/maintenance/work-orders.js +14 -1
- package/addon/routes/management/fuel-transactions/index/details.js +9 -0
- package/addon/routes/management/fuel-transactions.js +14 -1
- package/addon/routes/management/index.js +13 -0
- package/addon/routes/management/trailers.js +16 -0
- package/addon/routes/management/vendors/integrated/details.js +14 -1
- package/addon/routes/management/vendors/integrated/edit.js +14 -1
- package/addon/routes/management/vendors/integrated/new.js +14 -1
- package/addon/routes/management/vendors/integrated.js +14 -1
- package/addon/routes/operations/orders.js +40 -1
- package/addon/routes/operations/routes/index/details.js +14 -1
- package/addon/routes/operations/routes/index/new.js +13 -0
- package/addon/routes/operations/routes.js +14 -1
- package/addon/routes/operations/service-rates/index/new.js +11 -0
- package/addon/routes/operations/service-rates.js +14 -1
- package/addon/routes/settings/avatars.js +14 -1
- package/addon/routes/settings/custom-fields.js +14 -1
- package/addon/routes/settings/map.js +14 -1
- package/addon/routes/settings/notifications.js +11 -0
- package/addon/routes/settings/orchestrator.js +1 -1
- package/addon/routes/settings/payments/index.js +1 -1
- package/addon/routes/settings/routing.js +14 -1
- package/addon/routes/settings/scheduling.js +14 -1
- package/addon/routes/settings/telematics.js +21 -0
- package/addon/routes/virtual.js +11 -0
- package/addon/routes.js +1 -0
- package/addon/services/contact-actions.js +50 -89
- package/addon/services/driver-actions.js +98 -0
- package/addon/templates/settings/telematics.hbs +70 -0
- package/addon/utils/profile-login-actions.js +172 -0
- package/app/components/admin/telematics-settings.js +1 -0
- package/app/components/{modals/reset-customer-credentials.js → map/marker-card/driver.js} +1 -1
- package/app/components/map/marker-card/vehicle.js +1 -0
- package/app/components/modals/reset-profile-credentials.js +1 -0
- package/app/components/profile-identity-hint.js +1 -0
- package/app/controllers/settings/telematics.js +1 -0
- package/app/routes/settings/telematics.js +1 -0
- package/app/templates/settings/telematics.js +1 -0
- package/composer.json +2 -2
- package/docs/AFAQY.md +1 -1
- package/docs/TELEMATICS_QUEUES.md +1 -1
- package/docs/TELEMETRY_ARCHITECTURE.md +72 -1
- package/extension.json +1 -1
- package/package.json +3 -3
- package/scripts/pest-bootstrap.php +12 -0
- package/server/config/telemetry.php +12 -0
- package/server/migrations/2026_09_21_000001_convert_profile_only_users_to_managed_accounts.php +132 -0
- package/server/migrations/2026_09_23_000001_add_retention_index_to_device_events.php +40 -0
- package/server/migrations/2026_09_23_000002_add_retention_index_to_positions.php +40 -0
- package/server/migrations/2026_09_23_000003_add_retention_index_to_telematic_sync_runs.php +40 -0
- package/server/resources/views/mail/driver-credentials.blade.php +21 -0
- package/server/src/Auth/Schemas/FleetOps.php +104 -5
- package/server/src/Console/Commands/DrainTelematicInbox.php +3 -13
- package/server/src/Console/Commands/FixCustomerCompanies.php +1 -1
- package/server/src/Console/Commands/FixDriverCompanies.php +1 -1
- package/server/src/Console/Commands/ProcessOperationalAlerts.php +3 -3
- package/server/src/Console/Commands/PruneTelematicsData.php +318 -0
- package/server/src/Exceptions/ProfileIdentityConflictException.php +34 -0
- package/server/src/Http/Controllers/Api/v1/CustomerController.php +14 -0
- package/server/src/Http/Controllers/Api/v1/DriverController.php +56 -39
- package/server/src/Http/Controllers/Api/v1/OrchestrationController.php +9 -0
- package/server/src/Http/Controllers/FleetOpsController.php +21 -0
- package/server/src/Http/Controllers/Internal/v1/AnalyticsController.php +11 -0
- package/server/src/Http/Controllers/Internal/v1/ContactController.php +16 -17
- package/server/src/Http/Controllers/Internal/v1/CustomerController.php +54 -4
- package/server/src/Http/Controllers/Internal/v1/DeviceController.php +13 -0
- package/server/src/Http/Controllers/Internal/v1/DeviceEventController.php +11 -0
- package/server/src/Http/Controllers/Internal/v1/DriverController.php +204 -162
- package/server/src/Http/Controllers/Internal/v1/FleetOpsLookupController.php +47 -0
- package/server/src/Http/Controllers/Internal/v1/FuelProviderConnectionController.php +13 -0
- package/server/src/Http/Controllers/Internal/v1/FuelProviderTransactionController.php +15 -0
- package/server/src/Http/Controllers/Internal/v1/FuelReportController.php +9 -3
- package/server/src/Http/Controllers/Internal/v1/InspectionFormController.php +15 -0
- package/server/src/Http/Controllers/Internal/v1/LiveController.php +16 -0
- package/server/src/Http/Controllers/Internal/v1/MaintenanceController.php +15 -0
- package/server/src/Http/Controllers/Internal/v1/MaintenanceScheduleController.php +15 -0
- package/server/src/Http/Controllers/Internal/v1/ManifestController.php +15 -0
- package/server/src/Http/Controllers/Internal/v1/MetricsController.php +11 -0
- package/server/src/Http/Controllers/Internal/v1/NavigatorController.php +42 -1
- package/server/src/Http/Controllers/Internal/v1/OrchestrationController.php +12 -0
- package/server/src/Http/Controllers/Internal/v1/OrderController.php +178 -27
- package/server/src/Http/Controllers/Internal/v1/PaymentController.php +13 -0
- package/server/src/Http/Controllers/Internal/v1/RadarController.php +19 -0
- package/server/src/Http/Controllers/Internal/v1/ServiceAreaController.php +9 -3
- package/server/src/Http/Controllers/Internal/v1/SettingController.php +465 -14
- package/server/src/Http/Controllers/Internal/v1/TelematicController.php +21 -0
- package/server/src/Http/Controllers/Internal/v1/TrailerController.php +21 -0
- package/server/src/Http/Controllers/Internal/v1/VehicleController.php +21 -0
- package/server/src/Http/Controllers/Internal/v1/VendorController.php +17 -0
- package/server/src/Http/Controllers/Internal/v1/WorkOrderController.php +11 -0
- package/server/src/Http/Requests/CreateDriverRequest.php +6 -2
- package/server/src/Http/Requests/Internal/CreateDriverRequest.php +9 -18
- package/server/src/Http/Resources/v1/Contact.php +3 -0
- package/server/src/Http/Resources/v1/Driver.php +3 -0
- package/server/src/Jobs/DispatchTelematicsRetentionJobs.php +70 -0
- package/server/src/Jobs/PruneTelematicsDataJob.php +74 -0
- package/server/src/Listeners/NotifyDriverOnShiftChange.php +3 -3
- package/server/src/Mail/CustomerCredentialsMail.php +1 -1
- package/server/src/Mail/DriverCredentialsMail.php +55 -0
- package/server/src/Models/Contact.php +55 -90
- package/server/src/Models/Sensor.php +3 -5
- package/server/src/Observers/ContactObserver.php +2 -22
- package/server/src/Observers/DriverObserver.php +5 -6
- package/server/src/Orchestration/Engines/VroomOrchestrationEngine.php +9 -1
- package/server/src/Providers/FleetOpsServiceProvider.php +18 -0
- package/server/src/Support/Ai/Capabilities/AbstractFleetOpsAICapability.php +62 -5
- package/server/src/Support/Ai/Capabilities/AssetStatusCapability.php +24 -5
- package/server/src/Support/Ai/Capabilities/CreateOrderPreviewCapability.php +6 -2
- package/server/src/Support/Ai/Capabilities/OrderInsightsCapability.php +40 -7
- package/server/src/Support/Ai/Capabilities/SearchResourcesCapability.php +86 -24
- package/server/src/Support/Ai/FleetOpsAiConsoleCommands.php +122 -0
- package/server/src/Support/Ai/Tools/CreateOrderTool.php +86 -0
- package/server/src/Support/Ai/Tools/ImportOrdersTool.php +53 -0
- package/server/src/Support/Ai/Tools/OptimizeOrderRouteTool.php +70 -0
- package/server/src/Support/Ai/Tools/SearchResourcesTool.php +73 -0
- package/server/src/Support/Analytics/LiveFleet.php +18 -2
- package/server/src/Support/Authorization.php +103 -0
- package/server/src/Support/Database/TableIndexes.php +66 -0
- package/server/src/Support/OrderTracker.php +2 -2
- package/server/src/Support/ProfileAccountManager.php +405 -0
- package/server/src/Support/Reporting/FleetOpsReportSchema.php +476 -116
- package/server/src/Support/Telematics/Retention/RetentionPolicy.php +300 -0
- package/server/src/Support/Telematics/Retention/TelemetryActivity.php +40 -0
- package/server/src/Support/Telematics/TelematicService.php +12 -2
- package/server/src/Support/Telematics/Telemetry/Ingestor.php +4 -2
- package/server/src/Tracking/TrackingIntelligenceService.php +1 -1
- package/server/src/Tracking/TrackingOptions.php +2 -2
- package/server/src/Traits/AuthorizesMethods.php +37 -0
- package/server/src/routes.php +14 -1
- package/server/tests/AiOperationalQueryCapabilityTest.php +1 -0
- package/server/tests/AnalyticsRoutesTest.php +29 -2
- package/server/tests/ApiCustomerControllerContractsTest.php +21 -0
- package/server/tests/ApiDriverControllerContractsTest.php +102 -20
- package/server/tests/CommandContractsTest.php +4 -4
- package/server/tests/ControllerHelperContractsTest.php +3 -11
- package/server/tests/Feature/Http/AfaqyRealtimeIngestionTest.php +21 -1
- package/server/tests/Feature/Http/Api/DriverControllerAuthFlowsTest.php +36 -0
- package/server/tests/Feature/Http/Api/DriverControllerSessionHelpersTest.php +19 -6
- package/server/tests/Feature/Http/Api/ProfileOnlyUserConversionMigrationTest.php +201 -0
- package/server/tests/Feature/Http/Api/TelematicsRetentionIndexMigrationTest.php +115 -0
- package/server/tests/Feature/Http/Internal/ContactControllerEndpointsTest.php +6 -4
- package/server/tests/Feature/Http/Internal/CustomerControllerCredentialsTest.php +6 -2
- package/server/tests/Feature/Http/Internal/DriverControllerContractsTest.php +23 -0
- package/server/tests/Feature/Http/Internal/DriverControllerCreateRecordTest.php +42 -17
- package/server/tests/Feature/Http/Internal/DriverControllerExistingUserAdoptionTest.php +168 -277
- package/server/tests/Feature/Http/Internal/DriverControllerLoginManagementTest.php +716 -0
- package/server/tests/Feature/Http/Internal/OrderControllerContractsTest.php +10 -3
- package/server/tests/Feature/Http/Internal/OrderControllerImportFromFilesTest.php +18 -0
- package/server/tests/Feature/Http/Internal/OrderControllerTenantScopingTest.php +411 -0
- package/server/tests/Feature/Http/Internal/OrderControllerUpstreamNotFoundTest.php +8 -20
- package/server/tests/Feature/Http/Internal/SettingControllerHelpersTest.php +71 -0
- package/server/tests/Feature/Http/Internal/TelematicsStorageDeadlinesTest.php +119 -0
- package/server/tests/InternalCustomerControllerContractsTest.php +32 -1
- package/server/tests/InternalImportExportControllerContractsTest.php +5 -8
- package/server/tests/ModelAccessorContractsTest.php +82 -20
- package/server/tests/NavigatorControllerContractsTest.php +36 -4
- package/server/tests/NotificationAndMailContractsTest.php +31 -0
- package/server/tests/ObserverContractsTest.php +28 -3
- package/server/tests/OrchestratorConsumableApiTest.php +42 -0
- package/server/tests/ProviderContractsTest.php +10 -0
- package/server/tests/ReportSchemaContractsTest.php +120 -6
- package/server/tests/RequestContractsTest.php +19 -11
- package/server/tests/SettingControllerContractsTest.php +429 -18
- package/server/tests/SmallControllerContractsTest.php +8 -5
- package/server/tests/Support/PruneTelematicsDataProbe.php +55 -0
- package/server/tests/SupportJobAndAiCoverageTest.php +3 -3
- package/server/tests/TelematicControllerContractsTest.php +22 -4
- package/server/tests/Unit/Console/Commands/ProcessOperationalAlertsCommandTest.php +2 -2
- package/server/tests/Unit/Console/PruneTelematicsDataCommandTest.php +353 -0
- package/server/tests/Unit/Jobs/DispatchTelematicsRetentionJobsTest.php +114 -0
- package/server/tests/Unit/Jobs/PruneTelematicsDataJobTest.php +60 -0
- package/server/tests/Unit/Models/ContactCustomerUserTest.php +90 -14
- package/server/tests/Unit/Models/ContactTest.php +48 -5
- package/server/tests/Unit/Models/SensorTest.php +2 -2
- package/server/tests/Unit/Models/SmallModelSurfacesTest.php +31 -32
- package/server/tests/Unit/Observers/ObserverListenerSeamsTest.php +7 -2
- package/server/tests/Unit/Orchestration/VroomEngineTransportAndSettingsTest.php +20 -0
- package/server/tests/Unit/Providers/FleetOpsAiRegistrationTest.php +15 -2
- package/server/tests/Unit/Support/Ai/AssetStatusCapabilityQueriesTest.php +42 -0
- package/server/tests/Unit/Support/Ai/Capabilities/OrderInsightsCapabilityTest.php +19 -1
- package/server/tests/Unit/Support/Ai/Capabilities/SearchResourcesCapabilityTest.php +85 -1
- package/server/tests/Unit/Support/Ai/FleetOpsAiConsoleCommandsTest.php +31 -0
- package/server/tests/Unit/Support/Ai/Tools/FleetOpsAiToolsTest.php +246 -0
- package/server/tests/Unit/Support/AiCapabilityPermissionsTest.php +3 -3
- package/server/tests/Unit/Support/Analytics/LiveFleetTest.php +6 -0
- package/server/tests/Unit/Support/AuthorizationTest.php +142 -0
- package/server/tests/Unit/Support/MaintainableAndOperationalAlertsTest.php +12 -1
- package/server/tests/Unit/Support/MoreQuerySeamsTest.php +11 -2
- package/server/tests/Unit/Support/ProfileAccountManagerTest.php +643 -0
- package/server/tests/Unit/Support/Telematics/Retention/RetentionPolicyTest.php +190 -0
- package/server/tests/Unit/Support/Telematics/Retention/TelemetryActivityTest.php +68 -0
- package/server/tests/Unit/Tracking/TrackingOptionsCompanySettingsTest.php +109 -0
- package/translations/en-us.yaml +85 -2
- package/translations/uk-ua.yaml +3475 -0
- package/addon/components/modals/reset-customer-credentials.hbs +0 -18
- package/addon/components/modals/reset-customer-credentials.js +0 -55
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
namespace Fleetbase\FleetOps\Http\Controllers\Internal\v1;
|
|
4
4
|
|
|
5
|
+
use Fleetbase\Attributes\SkipAuthorizationCheck;
|
|
5
6
|
use Fleetbase\Exceptions\FleetbaseRequestValidationException;
|
|
6
7
|
use Fleetbase\FleetOps\Events\EntityActivityChanged;
|
|
7
8
|
use Fleetbase\FleetOps\Events\EntityCompleted;
|
|
@@ -39,6 +40,7 @@ use Fleetbase\Models\File;
|
|
|
39
40
|
use Fleetbase\Models\Type;
|
|
40
41
|
use Fleetbase\Support\Auth;
|
|
41
42
|
use Fleetbase\Support\TemplateString;
|
|
43
|
+
use Illuminate\Database\Eloquent\Builder;
|
|
42
44
|
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
|
43
45
|
use Illuminate\Database\QueryException;
|
|
44
46
|
use Illuminate\Http\Request;
|
|
@@ -52,6 +54,20 @@ use Maatwebsite\Excel\Facades\Excel;
|
|
|
52
54
|
class OrderController extends FleetOpsController
|
|
53
55
|
{
|
|
54
56
|
use ResolvesOrderServiceStops;
|
|
57
|
+
/**
|
|
58
|
+
* Permissions for methods AuthorizationGuard cannot map to a schema action (see FleetOpsController).
|
|
59
|
+
*
|
|
60
|
+
* @var array<string, string|string[]>
|
|
61
|
+
*/
|
|
62
|
+
protected array $methodPermissions = [
|
|
63
|
+
'editOrderRoute' => 'update-route-for order',
|
|
64
|
+
'importFromFiles' => 'import order',
|
|
65
|
+
'bulkCancel' => 'cancel order',
|
|
66
|
+
'bulkDispatch' => 'dispatch order',
|
|
67
|
+
'bulkAssignDriver' => 'assign-driver-for order',
|
|
68
|
+
'dispatchOrder' => 'dispatch order',
|
|
69
|
+
'scheduleOrder' => 'schedule order',
|
|
70
|
+
];
|
|
55
71
|
|
|
56
72
|
/**
|
|
57
73
|
* The resource to query.
|
|
@@ -266,6 +282,7 @@ class OrderController extends FleetOpsController
|
|
|
266
282
|
*
|
|
267
283
|
* @return Response
|
|
268
284
|
*/
|
|
285
|
+
#[SkipAuthorizationCheck]
|
|
269
286
|
public function editOrderRoute(string $id, Request $request)
|
|
270
287
|
{
|
|
271
288
|
$pickup = $request->input('pickup');
|
|
@@ -336,12 +353,14 @@ class OrderController extends FleetOpsController
|
|
|
336
353
|
*
|
|
337
354
|
* @return \Illuminate\Http\Response
|
|
338
355
|
*/
|
|
356
|
+
#[SkipAuthorizationCheck]
|
|
339
357
|
public function importFromFiles(Request $request)
|
|
340
358
|
{
|
|
341
359
|
$info = Utils::lookupIp();
|
|
342
360
|
$disk = $request->input('disk', config('filesystems.default'));
|
|
343
361
|
$files = $request->input('files');
|
|
344
|
-
|
|
362
|
+
/** @var \Illuminate\Database\Eloquent\Collection<int, File> $files */
|
|
363
|
+
$files = $this->scopedToCompany(File::whereIn('uuid', $files))->get();
|
|
345
364
|
$country = $request->input('country', Utils::or($info, ['country_name', 'region'], 'Singapore'));
|
|
346
365
|
|
|
347
366
|
$validFileTypes = ['csv', 'tsv', 'xls', 'xlsx'];
|
|
@@ -407,6 +426,7 @@ class OrderController extends FleetOpsController
|
|
|
407
426
|
*
|
|
408
427
|
* @return \Illuminate\Http\Response
|
|
409
428
|
*/
|
|
429
|
+
#[SkipAuthorizationCheck]
|
|
410
430
|
public function bulkCancel(Request $request)
|
|
411
431
|
{
|
|
412
432
|
$request->validate([
|
|
@@ -452,6 +472,7 @@ class OrderController extends FleetOpsController
|
|
|
452
472
|
*
|
|
453
473
|
* @return \Illuminate\Http\Response
|
|
454
474
|
*/
|
|
475
|
+
#[SkipAuthorizationCheck]
|
|
455
476
|
public function bulkDispatch(BulkDispatchRequest $request)
|
|
456
477
|
{
|
|
457
478
|
/** @var Order */
|
|
@@ -500,6 +521,7 @@ class OrderController extends FleetOpsController
|
|
|
500
521
|
*
|
|
501
522
|
* @return \Illuminate\Http\Response
|
|
502
523
|
*/
|
|
524
|
+
#[SkipAuthorizationCheck]
|
|
503
525
|
public function bulkAssignDriver(Request $request)
|
|
504
526
|
{
|
|
505
527
|
// Validate Inputs
|
|
@@ -513,7 +535,13 @@ class OrderController extends FleetOpsController
|
|
|
513
535
|
}
|
|
514
536
|
|
|
515
537
|
// Prepare Order UUID Collection
|
|
516
|
-
|
|
538
|
+
//
|
|
539
|
+
// Resolved through the company-scoped lookup so ids naming another
|
|
540
|
+
// organization's orders are dropped here rather than being assigned,
|
|
541
|
+
// counted in the response and queued for notification.
|
|
542
|
+
$orderUuids = $this->ordersByUuid(collect($data['ids'])->unique()->values()->all())
|
|
543
|
+
->pluck('uuid')
|
|
544
|
+
->values();
|
|
517
545
|
|
|
518
546
|
// Bulk Update Inside A Transaction
|
|
519
547
|
$this->runTransaction(function () use ($orderUuids, $driver): void {
|
|
@@ -545,8 +573,14 @@ class OrderController extends FleetOpsController
|
|
|
545
573
|
*/
|
|
546
574
|
public function cancel(CancelOrderRequest $request)
|
|
547
575
|
{
|
|
548
|
-
/** @var Order */
|
|
576
|
+
/** @var Order|null */
|
|
549
577
|
$order = $this->findOrderByUuid($request->input('order'));
|
|
578
|
+
if (!$order) {
|
|
579
|
+
// `exists:orders,uuid` on the form request is a global existence
|
|
580
|
+
// check, so a known uuid belonging to another organization reaches
|
|
581
|
+
// here and must be rejected rather than dereferenced.
|
|
582
|
+
return $this->errorResponse('No order found to cancel.');
|
|
583
|
+
}
|
|
550
584
|
|
|
551
585
|
$order->cancel();
|
|
552
586
|
|
|
@@ -564,6 +598,7 @@ class OrderController extends FleetOpsController
|
|
|
564
598
|
*
|
|
565
599
|
* @return \Illuminate\Http\Response
|
|
566
600
|
*/
|
|
601
|
+
#[SkipAuthorizationCheck]
|
|
567
602
|
public function dispatchOrder(Request $request)
|
|
568
603
|
{
|
|
569
604
|
/**
|
|
@@ -599,9 +634,39 @@ class OrderController extends FleetOpsController
|
|
|
599
634
|
);
|
|
600
635
|
}
|
|
601
636
|
|
|
637
|
+
/**
|
|
638
|
+
* Constrain a tenant-owned lookup to the company the caller is acting for.
|
|
639
|
+
*
|
|
640
|
+
* The order-lifecycle actions on this controller receive their target as a
|
|
641
|
+
* caller-supplied identifier in the request body or query string rather than
|
|
642
|
+
* as a bound route parameter, so nothing upstream narrows these queries to
|
|
643
|
+
* the caller's tenant: `fleetbase.protected` only checks that the caller
|
|
644
|
+
* holds the named RBAC capability, never which company the record belongs to.
|
|
645
|
+
*
|
|
646
|
+
* A missing company session fails the query closed instead of letting it run
|
|
647
|
+
* unbounded across every tenant.
|
|
648
|
+
*/
|
|
649
|
+
protected function scopedToCompany(Builder $query): Builder
|
|
650
|
+
{
|
|
651
|
+
$companyUuid = $this->sessionCompany();
|
|
652
|
+
if (!$companyUuid) {
|
|
653
|
+
$query->whereRaw('1 = 0');
|
|
654
|
+
|
|
655
|
+
return $query;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
return $query->where($query->getModel()->qualifyColumn('company_uuid'), $companyUuid);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
/**
|
|
662
|
+
* @return \Illuminate\Database\Eloquent\Collection<int, Order>
|
|
663
|
+
*/
|
|
602
664
|
protected function ordersByUuid(array $ids)
|
|
603
665
|
{
|
|
604
|
-
|
|
666
|
+
/** @var \Illuminate\Database\Eloquent\Collection<int, Order> $orders */
|
|
667
|
+
$orders = $this->scopedToCompany(Order::whereIn('uuid', $ids))->get();
|
|
668
|
+
|
|
669
|
+
return $orders;
|
|
605
670
|
}
|
|
606
671
|
|
|
607
672
|
protected function trackingStatusExists(?string $trackingNumberUuid, string $code): bool
|
|
@@ -611,7 +676,10 @@ class OrderController extends FleetOpsController
|
|
|
611
676
|
|
|
612
677
|
protected function findDriverByUuid(string $uuid): ?Driver
|
|
613
678
|
{
|
|
614
|
-
|
|
679
|
+
/** @var Driver|null $driver */
|
|
680
|
+
$driver = $this->scopedToCompany(Driver::whereUuid($uuid))->first();
|
|
681
|
+
|
|
682
|
+
return $driver;
|
|
615
683
|
}
|
|
616
684
|
|
|
617
685
|
protected function driverDisplayName(Driver $driver): string
|
|
@@ -630,17 +698,47 @@ class OrderController extends FleetOpsController
|
|
|
630
698
|
|
|
631
699
|
protected function findOrderByUuid(string $uuid): ?Order
|
|
632
700
|
{
|
|
633
|
-
|
|
701
|
+
/** @var Order|null $order */
|
|
702
|
+
$order = $this->scopedToCompany(Order::where('uuid', $uuid))->first();
|
|
703
|
+
|
|
704
|
+
return $order;
|
|
634
705
|
}
|
|
635
706
|
|
|
636
|
-
|
|
707
|
+
/**
|
|
708
|
+
* Resolve an order by uuid or public_id, constrained to the caller's company.
|
|
709
|
+
*
|
|
710
|
+
* The identifier match is grouped so the company constraint applies to both
|
|
711
|
+
* arms — ungrouped it would read as `uuid = ? OR (public_id = ? AND
|
|
712
|
+
* company_uuid = ?)` and still resolve another organization's orders.
|
|
713
|
+
*
|
|
714
|
+
* The identifier is whatever the caller put in the request, so anything
|
|
715
|
+
* that is not a non-empty string resolves to no order rather than raising.
|
|
716
|
+
*
|
|
717
|
+
* @param array<int, string> $with
|
|
718
|
+
*/
|
|
719
|
+
protected function findOrderById(mixed $id, array $with = []): ?Order
|
|
637
720
|
{
|
|
638
|
-
|
|
721
|
+
if (!is_string($id) || $id === '') {
|
|
722
|
+
return null;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
/** @var Order|null $order */
|
|
726
|
+
$order = $this->scopedToCompany(Order::query())
|
|
727
|
+
->where(function (Builder $query) use ($id) {
|
|
728
|
+
$query->where('uuid', $id)->orWhere('public_id', $id);
|
|
729
|
+
})
|
|
730
|
+
->with($with)
|
|
731
|
+
->first();
|
|
732
|
+
|
|
733
|
+
return $order;
|
|
639
734
|
}
|
|
640
735
|
|
|
641
736
|
protected function findOrderRouteForEdit(string $uuid): ?Order
|
|
642
737
|
{
|
|
643
|
-
|
|
738
|
+
/** @var Order|null $order */
|
|
739
|
+
$order = $this->scopedToCompany(Order::where('uuid', $uuid))->with(['payload'])->first();
|
|
740
|
+
|
|
741
|
+
return $order;
|
|
644
742
|
}
|
|
645
743
|
|
|
646
744
|
protected function orderResponse(Order $order): array
|
|
@@ -650,7 +748,7 @@ class OrderController extends FleetOpsController
|
|
|
650
748
|
|
|
651
749
|
protected function assignDriverToOrders($orderUuids, Driver $driver): void
|
|
652
750
|
{
|
|
653
|
-
Order::whereIn('uuid', $orderUuids)->update([
|
|
751
|
+
$this->scopedToCompany(Order::whereIn('uuid', $orderUuids))->update([
|
|
654
752
|
'driver_assigned_uuid' => $driver->uuid,
|
|
655
753
|
'updated_at' => now(),
|
|
656
754
|
]);
|
|
@@ -739,17 +837,28 @@ class OrderController extends FleetOpsController
|
|
|
739
837
|
|
|
740
838
|
protected function findOrderForStart(?string $uuid): ?Order
|
|
741
839
|
{
|
|
742
|
-
|
|
840
|
+
/** @var Order|null $order */
|
|
841
|
+
$order = $this->scopedToCompany(Order::where('uuid', $uuid)->withoutGlobalScopes())->first();
|
|
842
|
+
|
|
843
|
+
return $order;
|
|
743
844
|
}
|
|
744
845
|
|
|
745
846
|
protected function findDriverForStart(?string $uuid): ?Driver
|
|
746
847
|
{
|
|
747
|
-
|
|
848
|
+
/** @var Driver|null $driver */
|
|
849
|
+
$driver = $this->scopedToCompany(Driver::where('uuid', $uuid)->withoutGlobalScopes())->first();
|
|
850
|
+
|
|
851
|
+
return $driver;
|
|
748
852
|
}
|
|
749
853
|
|
|
750
854
|
protected function findPayloadForStart(?string $uuid): ?Payload
|
|
751
855
|
{
|
|
752
|
-
|
|
856
|
+
/** @var Payload|null $payload */
|
|
857
|
+
$payload = $this->scopedToCompany(Payload::where('uuid', $uuid)->withoutGlobalScopes())
|
|
858
|
+
->with(['waypoints', 'waypointMarkers', 'entities'])
|
|
859
|
+
->first();
|
|
860
|
+
|
|
861
|
+
return $payload;
|
|
753
862
|
}
|
|
754
863
|
|
|
755
864
|
protected function dispatchDomainEvent(object $event): object
|
|
@@ -771,7 +880,7 @@ class OrderController extends FleetOpsController
|
|
|
771
880
|
*/
|
|
772
881
|
public function updateActivity(string $id, Request $request)
|
|
773
882
|
{
|
|
774
|
-
$order =
|
|
883
|
+
$order = $this->findOrderById($id, [
|
|
775
884
|
'driverAssigned',
|
|
776
885
|
'payload.entities',
|
|
777
886
|
'payload.pickup',
|
|
@@ -882,9 +991,8 @@ class OrderController extends FleetOpsController
|
|
|
882
991
|
*/
|
|
883
992
|
public function nextActivity(string $id, Request $request)
|
|
884
993
|
{
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
} catch (ModelNotFoundException $e) {
|
|
994
|
+
$order = $this->findOrderById($id);
|
|
995
|
+
if (!$order) {
|
|
888
996
|
return response()->error('No order found.');
|
|
889
997
|
}
|
|
890
998
|
|
|
@@ -935,7 +1043,7 @@ class OrderController extends FleetOpsController
|
|
|
935
1043
|
*/
|
|
936
1044
|
public function setDestination(string $id, string $placeId)
|
|
937
1045
|
{
|
|
938
|
-
$order =
|
|
1046
|
+
$order = $this->findOrderById($id, [
|
|
939
1047
|
'payload.pickup',
|
|
940
1048
|
'payload.dropoff',
|
|
941
1049
|
'payload.return',
|
|
@@ -1013,7 +1121,7 @@ class OrderController extends FleetOpsController
|
|
|
1013
1121
|
return response()->error($errorMessage, 422);
|
|
1014
1122
|
}
|
|
1015
1123
|
|
|
1016
|
-
$order =
|
|
1124
|
+
$order = $this->findOrderById($id, ['payload.pickup', 'payload.dropoff', 'payload.return', 'payload.waypoints', 'payload.waypointMarkers.place']);
|
|
1017
1125
|
if (!$order) {
|
|
1018
1126
|
return response()->error('No order found.');
|
|
1019
1127
|
}
|
|
@@ -1214,7 +1322,14 @@ class OrderController extends FleetOpsController
|
|
|
1214
1322
|
}
|
|
1215
1323
|
|
|
1216
1324
|
if (is_string($proof)) {
|
|
1217
|
-
|
|
1325
|
+
/** @var Proof|null $resolved */
|
|
1326
|
+
$resolved = $this->scopedToCompany(Proof::query())
|
|
1327
|
+
->where(function (Builder $query) use ($proof) {
|
|
1328
|
+
$query->where('public_id', $proof)->orWhere('uuid', $proof);
|
|
1329
|
+
})
|
|
1330
|
+
->first();
|
|
1331
|
+
|
|
1332
|
+
return $resolved;
|
|
1218
1333
|
}
|
|
1219
1334
|
|
|
1220
1335
|
return null;
|
|
@@ -1419,7 +1534,12 @@ class OrderController extends FleetOpsController
|
|
|
1419
1534
|
|
|
1420
1535
|
protected function findOrderForDriverPing(string $id): Order
|
|
1421
1536
|
{
|
|
1422
|
-
|
|
1537
|
+
$order = $this->findOrderById($id, ['driverAssigned']);
|
|
1538
|
+
if (!$order) {
|
|
1539
|
+
throw new ModelNotFoundException();
|
|
1540
|
+
}
|
|
1541
|
+
|
|
1542
|
+
return $order;
|
|
1423
1543
|
}
|
|
1424
1544
|
|
|
1425
1545
|
protected function sendDriverPing(Driver $driver, Order $order): void
|
|
@@ -1692,7 +1812,10 @@ class OrderController extends FleetOpsController
|
|
|
1692
1812
|
|
|
1693
1813
|
protected function findOrderForProofs(string $id): ?Order
|
|
1694
1814
|
{
|
|
1695
|
-
|
|
1815
|
+
/** @var Order|null $order */
|
|
1816
|
+
$order = $this->scopedToCompany(Order::where('uuid', $id))->first();
|
|
1817
|
+
|
|
1818
|
+
return $order;
|
|
1696
1819
|
}
|
|
1697
1820
|
|
|
1698
1821
|
protected function findWaypointProofSubject(Order $order, string $subjectId): ?Waypoint
|
|
@@ -1708,7 +1831,10 @@ class OrderController extends FleetOpsController
|
|
|
1708
1831
|
|
|
1709
1832
|
protected function findEntityProofSubject(string $subjectId): ?Entity
|
|
1710
1833
|
{
|
|
1711
|
-
|
|
1834
|
+
/** @var Entity|null $entity */
|
|
1835
|
+
$entity = $this->scopedToCompany(Entity::where('uuid', $subjectId)->withoutGlobalScopes())->first();
|
|
1836
|
+
|
|
1837
|
+
return $entity;
|
|
1712
1838
|
}
|
|
1713
1839
|
|
|
1714
1840
|
protected function proofsForSubject(Order $order, Order|Waypoint|Entity $subject)
|
|
@@ -1772,14 +1898,26 @@ class OrderController extends FleetOpsController
|
|
|
1772
1898
|
return new OrderResource($order);
|
|
1773
1899
|
}
|
|
1774
1900
|
|
|
1901
|
+
/**
|
|
1902
|
+
* Find the order a tracking number belongs to, for the public Track Order page.
|
|
1903
|
+
*
|
|
1904
|
+
* Deliberately NOT company-scoped, unlike the lifecycle lookups above. The
|
|
1905
|
+
* `fleet-ops/lookup` route is public: the tracking page is used by recipients who
|
|
1906
|
+
* have no session, and the tracking number itself is what grants access. Scoping
|
|
1907
|
+
* it to the session company made every lookup from that page fail, because there
|
|
1908
|
+
* is no company to scope to.
|
|
1909
|
+
*/
|
|
1775
1910
|
protected function findOrderByTrackingNumber(string $trackingNumber): ?Order
|
|
1776
1911
|
{
|
|
1777
|
-
|
|
1912
|
+
/** @var Order|null $order */
|
|
1913
|
+
$order = Order::whereHas(
|
|
1778
1914
|
'trackingNumber',
|
|
1779
1915
|
function ($query) use ($trackingNumber) {
|
|
1780
1916
|
$query->where('tracking_number', $trackingNumber);
|
|
1781
1917
|
}
|
|
1782
1918
|
)->first();
|
|
1919
|
+
|
|
1920
|
+
return $order;
|
|
1783
1921
|
}
|
|
1784
1922
|
|
|
1785
1923
|
/**
|
|
@@ -1789,6 +1927,7 @@ class OrderController extends FleetOpsController
|
|
|
1789
1927
|
*
|
|
1790
1928
|
* @return \Illuminate\Http\Response
|
|
1791
1929
|
*/
|
|
1930
|
+
#[SkipAuthorizationCheck]
|
|
1792
1931
|
public function scheduleOrder(Request $request)
|
|
1793
1932
|
{
|
|
1794
1933
|
$orderId = $request->input('order');
|
|
@@ -1824,13 +1963,25 @@ class OrderController extends FleetOpsController
|
|
|
1824
1963
|
|
|
1825
1964
|
protected function findOrderForSchedule(?string $id): ?Order
|
|
1826
1965
|
{
|
|
1827
|
-
return
|
|
1966
|
+
return $this->findOrderById($id);
|
|
1828
1967
|
}
|
|
1829
1968
|
|
|
1969
|
+
/**
|
|
1970
|
+
* Resolve a driver by uuid or public_id, constrained to the caller's company.
|
|
1971
|
+
*
|
|
1972
|
+
* The identifier match is grouped so the company constraint applies to both
|
|
1973
|
+
* arms — ungrouped it would read as `uuid = ? OR (public_id = ? AND
|
|
1974
|
+
* company_uuid = ?)` and still resolve another organization's drivers.
|
|
1975
|
+
*/
|
|
1830
1976
|
protected function findDriverForSchedule(string $id): ?Driver
|
|
1831
1977
|
{
|
|
1832
|
-
|
|
1833
|
-
|
|
1978
|
+
/** @var Driver|null $driver */
|
|
1979
|
+
$driver = $this->scopedToCompany(Driver::query())
|
|
1980
|
+
->where(function (Builder $query) use ($id) {
|
|
1981
|
+
$query->where('uuid', $id)->orWhere('public_id', $id);
|
|
1982
|
+
})
|
|
1834
1983
|
->first();
|
|
1984
|
+
|
|
1985
|
+
return $driver;
|
|
1835
1986
|
}
|
|
1836
1987
|
}
|
|
@@ -4,6 +4,7 @@ namespace Fleetbase\FleetOps\Http\Controllers\Internal\v1;
|
|
|
4
4
|
|
|
5
5
|
use Fleetbase\FleetOps\Models\PurchaseRate;
|
|
6
6
|
use Fleetbase\FleetOps\Support\Payment;
|
|
7
|
+
use Fleetbase\FleetOps\Traits\AuthorizesMethods;
|
|
7
8
|
use Fleetbase\Http\Controllers\Controller;
|
|
8
9
|
use Fleetbase\Http\Resources\FleetbaseResource;
|
|
9
10
|
use Fleetbase\Support\Auth;
|
|
@@ -12,6 +13,18 @@ use Illuminate\Support\Str;
|
|
|
12
13
|
|
|
13
14
|
class PaymentController extends Controller
|
|
14
15
|
{
|
|
16
|
+
use AuthorizesMethods;
|
|
17
|
+
|
|
18
|
+
public function __construct()
|
|
19
|
+
{
|
|
20
|
+
$this->authorizeMethods([
|
|
21
|
+
'hasStripeConnectAccount' => 'view payments',
|
|
22
|
+
'getStripeAccount' => 'onboard payments',
|
|
23
|
+
'getStripeAccountSession' => 'onboard payments',
|
|
24
|
+
'getCompanyReceivedPayments' => 'view payments',
|
|
25
|
+
]);
|
|
26
|
+
}
|
|
27
|
+
|
|
15
28
|
/**
|
|
16
29
|
* Checks if the currently authenticated company has an associated Stripe Connect account.
|
|
17
30
|
*
|
|
@@ -19,6 +19,7 @@ use Fleetbase\FleetOps\Support\Radar\RadarAgenda;
|
|
|
19
19
|
use Fleetbase\FleetOps\Support\Radar\RadarBriefing;
|
|
20
20
|
use Fleetbase\FleetOps\Support\Radar\RadarItemState;
|
|
21
21
|
use Fleetbase\FleetOps\Support\Radar\RadarRules;
|
|
22
|
+
use Fleetbase\FleetOps\Traits\AuthorizesMethods;
|
|
22
23
|
use Fleetbase\Http\Controllers\Controller;
|
|
23
24
|
use Fleetbase\Models\Alert;
|
|
24
25
|
use Fleetbase\Models\CompanyUser;
|
|
@@ -42,6 +43,24 @@ use Illuminate\Support\Carbon;
|
|
|
42
43
|
*/
|
|
43
44
|
class RadarController extends Controller
|
|
44
45
|
{
|
|
46
|
+
use AuthorizesMethods;
|
|
47
|
+
|
|
48
|
+
public function __construct()
|
|
49
|
+
{
|
|
50
|
+
$this->authorizeMethods([
|
|
51
|
+
'extendShift' => ['update driver', 'update vehicle'],
|
|
52
|
+
'acknowledge' => ['update driver', 'update vehicle'],
|
|
53
|
+
'snooze' => ['update driver', 'update vehicle'],
|
|
54
|
+
'wake' => ['update driver', 'update vehicle'],
|
|
55
|
+
'assign' => ['update driver', 'update vehicle'],
|
|
56
|
+
'plan' => ['update driver', 'update vehicle'],
|
|
57
|
+
'resolve' => ['update driver', 'update vehicle'],
|
|
58
|
+
'bulk' => ['update driver', 'update vehicle'],
|
|
59
|
+
'storeNotice' => ['update driver', 'update vehicle'],
|
|
60
|
+
'destroyNotice' => ['update driver', 'update vehicle'],
|
|
61
|
+
]);
|
|
62
|
+
}
|
|
63
|
+
|
|
45
64
|
public const RESOLVED_WINDOW_DAYS = 7;
|
|
46
65
|
public const SNOOZE_MAX_DAYS = 90;
|
|
47
66
|
|
|
@@ -7,6 +7,7 @@ use Fleetbase\FleetOps\Http\Controllers\FleetOpsController;
|
|
|
7
7
|
use Fleetbase\FleetOps\Models\ServiceArea;
|
|
8
8
|
use Fleetbase\Http\Requests\ExportRequest;
|
|
9
9
|
use Illuminate\Http\Request;
|
|
10
|
+
use Illuminate\Support\Arr;
|
|
10
11
|
use Illuminate\Support\Str;
|
|
11
12
|
use Maatwebsite\Excel\Facades\Excel;
|
|
12
13
|
|
|
@@ -21,11 +22,16 @@ class ServiceAreaController extends FleetOpsController
|
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* Handle post save transactions.
|
|
25
|
+
*
|
|
26
|
+
* Reads the custom field values from the payload the base controller already extracted
|
|
27
|
+
* rather than from the raw request: Ember Data sends the resource under a camelCase root
|
|
28
|
+
* (`serviceArea`), so `$request->array('service_area.custom_field_values')` was always empty and no
|
|
29
|
+
* custom field value was ever persisted for this resource.
|
|
24
30
|
*/
|
|
25
|
-
public function afterSave(Request $request, ServiceArea $serviceArea)
|
|
31
|
+
public function afterSave(Request $request, ServiceArea $serviceArea, array $input = [])
|
|
26
32
|
{
|
|
27
|
-
$customFieldValues = $
|
|
28
|
-
if ($customFieldValues) {
|
|
33
|
+
$customFieldValues = Arr::get($input, 'custom_field_values');
|
|
34
|
+
if (is_array($customFieldValues) && $customFieldValues) {
|
|
29
35
|
$serviceArea->syncCustomFieldValues($customFieldValues);
|
|
30
36
|
}
|
|
31
37
|
}
|