@fleetbase/fleetops-engine 0.6.52 → 0.6.54
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/device/details.hbs +106 -135
- package/addon/components/device/details.js +174 -1
- package/addon/components/device/panel-header.hbs +2 -2
- package/addon/components/layout/fleet-ops-sidebar/operations-monitor.hbs +201 -0
- package/addon/components/layout/fleet-ops-sidebar/operations-monitor.js +654 -0
- package/addon/components/layout/fleet-ops-sidebar.hbs +19 -233
- package/addon/components/layout/fleet-ops-sidebar.js +364 -395
- package/addon/components/maintenance-schedule/form.js +1 -0
- package/addon/components/order/form/details.hbs +1 -43
- package/addon/components/order/form/details.js +18 -53
- package/addon/components/order/form/orchestrator-constraints.hbs +40 -0
- package/addon/components/order/form/orchestrator-constraints.js +61 -0
- package/addon/components/order/form/payload.js +50 -2
- package/addon/components/order/form/route.js +15 -0
- package/addon/components/order/form/service-rate.hbs +62 -11
- package/addon/components/order/form/service-rate.js +124 -2
- package/addon/components/order/form.hbs +2 -0
- package/addon/components/telematic/details.hbs +7 -1
- package/addon/components/telematic/form.js +16 -8
- package/addon/components/work-order/details.hbs +5 -1
- package/addon/components/work-order/form.hbs +26 -4
- package/addon/components/work-order/form.js +5 -1
- package/addon/controllers/connectivity/devices/index/details/events.js +244 -1
- package/addon/controllers/connectivity/devices/index/details/sensors.js +199 -0
- package/addon/controllers/connectivity/devices/index/details/vehicle.js +74 -0
- package/addon/controllers/connectivity/devices/index/details.js +12 -0
- package/addon/controllers/connectivity/devices/index.js +4 -1
- package/addon/controllers/connectivity/telematics/details/attachments.js +220 -54
- package/addon/controllers/connectivity/telematics/details/devices.js +90 -41
- package/addon/controllers/connectivity/telematics/details/events.js +39 -11
- package/addon/controllers/connectivity/telematics/details/sensors.js +39 -19
- package/addon/controllers/maintenance/index.js +100 -0
- package/addon/controllers/maintenance/work-orders/index.js +18 -1
- package/addon/controllers/management/fuel-transactions/index.js +1 -1
- package/addon/controllers/management/index.js +88 -0
- package/addon/controllers/settings/index.js +142 -0
- package/addon/extension.js +21 -0
- package/addon/routes/analytics/index.js +3 -0
- package/addon/routes/connectivity/devices/index/details/events.js +37 -1
- package/addon/routes/connectivity/devices/index/details/sensors.js +35 -0
- package/addon/routes/connectivity/devices/index/details/vehicle.js +7 -0
- package/addon/routes/connectivity/devices/index.js +3 -0
- package/addon/routes/connectivity/telematics/details/attachments.js +72 -9
- package/addon/routes/connectivity/telematics/details/devices.js +4 -0
- package/addon/routes/connectivity/telematics/details/sensors.js +1 -0
- package/addon/routes/connectivity/telematics/details.js +1 -1
- package/addon/routes/connectivity/telematics/edit.js +1 -1
- package/addon/routes/maintenance/index.js +3 -0
- package/addon/routes/maintenance/work-orders/index.js +3 -0
- package/addon/routes/settings/index.js +3 -0
- package/addon/routes.js +2 -0
- package/addon/services/order-creation.js +54 -1
- package/addon/services/order-validation.js +3 -2
- package/addon/services/service-rate-actions.js +1 -0
- package/addon/styles/fleetops-engine.css +1821 -6
- package/addon/templates/analytics/index.hbs +14 -0
- package/addon/templates/analytics/reports/index.hbs +4 -4
- package/addon/templates/connectivity/devices/index/details/events.hbs +85 -1
- package/addon/templates/connectivity/devices/index/details/sensors.hbs +73 -0
- package/addon/templates/connectivity/devices/index/details/vehicle.hbs +84 -0
- package/addon/templates/connectivity/telematics/details/attachments.hbs +198 -121
- package/addon/templates/connectivity/telematics/details/devices.hbs +4 -1
- package/addon/templates/connectivity/telematics/details/events.hbs +4 -1
- package/addon/templates/connectivity/telematics/details/sensors.hbs +3 -0
- package/addon/templates/maintenance/index.hbs +113 -0
- package/addon/templates/management/fuel-transactions/index/details.hbs +1 -1
- package/addon/templates/management/index.hbs +109 -73
- package/addon/templates/management/vehicles/index/edit.hbs +1 -1
- package/addon/templates/operations/orders/index.hbs +1 -1
- package/addon/templates/operations/service-rates/index.hbs +1 -1
- package/addon/templates/settings/index.hbs +83 -0
- package/addon/templates/settings/routing.hbs +2 -2
- package/addon/utils/fleet-ops-options.js +38 -0
- package/app/components/order/form/orchestrator-constraints.js +1 -0
- package/app/controllers/connectivity/devices/index/details/sensors.js +1 -0
- package/app/controllers/connectivity/devices/index/details/vehicle.js +1 -0
- package/app/controllers/maintenance/index.js +1 -0
- package/app/controllers/management/index.js +1 -0
- package/app/controllers/settings/index.js +1 -0
- package/app/routes/analytics/index.js +1 -0
- package/app/routes/connectivity/devices/index/details/sensors.js +1 -0
- package/app/routes/connectivity/devices/index/details/vehicle.js +1 -0
- package/app/routes/maintenance/index.js +1 -0
- package/app/routes/settings/index.js +1 -0
- package/app/templates/analytics/index.js +1 -0
- package/app/templates/connectivity/devices/index/details/sensors.js +1 -0
- package/app/templates/connectivity/devices/index/details/vehicle.js +1 -0
- package/app/templates/maintenance/index.js +1 -0
- package/app/templates/management/index.js +1 -0
- package/app/templates/settings/index.js +1 -0
- package/composer.json +1 -1
- package/extension.json +1 -1
- package/package.json +3 -3
- package/server/migrations/2025_08_28_054930_create_work_orders_table.php +1 -0
- package/server/migrations/2026_06_15_000001_normalize_device_attachable_vehicle_morph_types.php +30 -0
- package/server/migrations/2026_06_18_000001_add_category_to_work_orders_table.php +32 -0
- package/server/seeders/Testing/MaintenanceSeeder.php +5 -4
- package/server/src/Console/Commands/FixInvalidPolymorphicRelationTypeNamespaces.php +1 -0
- package/server/src/Console/Commands/ProcessMaintenanceTriggers.php +1 -0
- package/server/src/Console/Commands/SyncTelematics.php +89 -0
- package/server/src/Exceptions/TelematicProviderException.php +13 -2
- package/server/src/Http/Controllers/Api/v1/OrderController.php +6 -21
- package/server/src/Http/Controllers/Internal/v1/DeviceController.php +112 -11
- package/server/src/Http/Controllers/Internal/v1/DeviceEventController.php +16 -5
- package/server/src/Http/Controllers/Internal/v1/FleetController.php +9 -0
- package/server/src/Http/Controllers/Internal/v1/HubController.php +300 -0
- package/server/src/Http/Controllers/Internal/v1/LiveController.php +177 -0
- package/server/src/Http/Controllers/Internal/v1/MaintenanceScheduleController.php +1 -0
- package/server/src/Http/Controllers/Internal/v1/OrderController.php +4 -32
- package/server/src/Http/Controllers/Internal/v1/SearchController.php +506 -0
- package/server/src/Http/Controllers/Internal/v1/ServiceQuoteController.php +4 -4
- package/server/src/Http/Controllers/Internal/v1/TelematicController.php +1 -1
- package/server/src/Http/Controllers/Internal/v1/VehicleController.php +94 -10
- package/server/src/Http/Filter/DeviceEventFilter.php +44 -0
- package/server/src/Http/Filter/DeviceFilter.php +131 -0
- package/server/src/Http/Filter/DriverFilter.php +6 -0
- package/server/src/Http/Filter/SensorFilter.php +125 -0
- package/server/src/Http/Filter/VehicleFilter.php +19 -0
- package/server/src/Http/Requests/CreateDriverRequest.php +14 -13
- package/server/src/Http/Requests/Internal/CreateDriverRequest.php +1 -0
- package/server/src/Http/Resources/v1/Driver.php +11 -2
- package/server/src/Http/Resources/v1/WorkOrder.php +1 -0
- package/server/src/Jobs/FinalizeApiOrderCreation.php +47 -0
- package/server/src/Jobs/FinalizeInternalOrderCreation.php +35 -0
- package/server/src/Jobs/NotifyBulkAssignedDriver.php +47 -0
- package/server/src/Jobs/SyncTelematicDevicesJob.php +181 -66
- package/server/src/Models/Device.php +15 -1
- package/server/src/Models/DeviceEvent.php +1 -1
- package/server/src/Models/Driver.php +17 -1
- package/server/src/Models/Sensor.php +15 -2
- package/server/src/Models/Telematic.php +1 -1
- package/server/src/Models/Vehicle.php +5 -1
- package/server/src/Models/WorkOrder.php +5 -2
- package/server/src/Observers/DriverObserver.php +3 -3
- package/server/src/Observers/FleetObserver.php +23 -0
- package/server/src/Observers/VehicleObserver.php +3 -3
- package/server/src/Providers/FleetOpsServiceProvider.php +12 -0
- package/server/src/Support/LiveCacheService.php +1 -1
- package/server/src/Support/Telematics/Providers/AfaqyProvider.php +188 -28
- package/server/src/Support/Telematics/Providers/SafeeProvider.php +44 -3
- package/server/src/Support/Telematics/TelematicService.php +330 -30
- package/server/src/routes.php +10 -0
- package/server/tests/DeviceFilterTest.php +36 -0
- package/server/tests/HubRoutesTest.php +62 -0
- package/server/tests/OperationsMonitorEndpointTest.php +38 -0
- package/server/tests/OrderQueuedClosureRegressionTest.php +36 -0
- package/server/tests/TelematicsHardeningTest.php +455 -3
- package/server/tests/VehicleDriverAssignmentTest.php +27 -0
- package/translations/ar-ae.yml +1 -1
- package/translations/en-us.yaml +1 -0
- package/translations/vi-vn.yaml +1 -1
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\FleetOps\Console\Commands;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\FleetOps\Jobs\SyncTelematicDevicesJob;
|
|
6
|
+
use Fleetbase\FleetOps\Models\Telematic;
|
|
7
|
+
use Fleetbase\FleetOps\Support\Telematics\TelematicProviderRegistry;
|
|
8
|
+
use Illuminate\Console\Command;
|
|
9
|
+
use Illuminate\Support\Facades\Cache;
|
|
10
|
+
|
|
11
|
+
class SyncTelematics extends Command
|
|
12
|
+
{
|
|
13
|
+
protected $signature = 'fleetops:sync-telematics
|
|
14
|
+
{--provider=* : Limit polling to one or more provider keys}
|
|
15
|
+
{--limit=500 : Maximum provider units to fetch per page}
|
|
16
|
+
{--sync-webhook-providers : Include providers that support webhooks}
|
|
17
|
+
{--no-lock : Skip process locking}';
|
|
18
|
+
|
|
19
|
+
protected $description = 'Poll active telematics providers for device snapshots and positional telemetry.';
|
|
20
|
+
|
|
21
|
+
public function handle(TelematicProviderRegistry $registry): int
|
|
22
|
+
{
|
|
23
|
+
$useLock = !$this->option('no-lock');
|
|
24
|
+
$lock = null;
|
|
25
|
+
|
|
26
|
+
if ($useLock) {
|
|
27
|
+
$lock = Cache::lock('fleetops:sync-telematics', 600);
|
|
28
|
+
if (!$lock->get()) {
|
|
29
|
+
$this->warn('Another telematics sync run appears to be in progress.');
|
|
30
|
+
|
|
31
|
+
return self::SUCCESS;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
$providerKeys = $this->pollableProviderKeys($registry);
|
|
37
|
+
if (empty($providerKeys)) {
|
|
38
|
+
$this->info('No pollable telematics providers found.');
|
|
39
|
+
|
|
40
|
+
return self::SUCCESS;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
$query = Telematic::withoutGlobalScopes()
|
|
44
|
+
->whereIn('provider', $providerKeys)
|
|
45
|
+
->whereIn('status', ['active', 'connected'])
|
|
46
|
+
->whereNotNull('company_uuid');
|
|
47
|
+
|
|
48
|
+
$queued = 0;
|
|
49
|
+
$query->orderBy('id')->chunkById(100, function ($telematics) use (&$queued) {
|
|
50
|
+
foreach ($telematics as $telematic) {
|
|
51
|
+
SyncTelematicDevicesJob::dispatch($telematic, [
|
|
52
|
+
'limit' => (int) $this->option('limit'),
|
|
53
|
+
]);
|
|
54
|
+
$queued++;
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
$this->info("Queued {$queued} telematics sync job(s).");
|
|
59
|
+
|
|
60
|
+
return self::SUCCESS;
|
|
61
|
+
} finally {
|
|
62
|
+
if ($lock) {
|
|
63
|
+
$lock->release();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
protected function pollableProviderKeys(TelematicProviderRegistry $registry): array
|
|
69
|
+
{
|
|
70
|
+
$requestedProviders = array_filter((array) $this->option('provider'));
|
|
71
|
+
$includeWebhookProviders = (bool) $this->option('sync-webhook-providers');
|
|
72
|
+
|
|
73
|
+
return $registry->all()
|
|
74
|
+
->filter(function ($descriptor) use ($requestedProviders, $includeWebhookProviders) {
|
|
75
|
+
if (!empty($requestedProviders) && !in_array($descriptor->key, $requestedProviders, true)) {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (!$descriptor->supportsDiscovery) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return $includeWebhookProviders || !$descriptor->supportsWebhooks;
|
|
84
|
+
})
|
|
85
|
+
->keys()
|
|
86
|
+
->values()
|
|
87
|
+
->all();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
namespace Fleetbase\FleetOps\Exceptions;
|
|
4
4
|
|
|
5
|
-
use Exception;
|
|
6
|
-
|
|
7
5
|
/**
|
|
8
6
|
* Class TelematicProviderException.
|
|
9
7
|
*
|
|
@@ -11,4 +9,17 @@ use Exception;
|
|
|
11
9
|
*/
|
|
12
10
|
class TelematicProviderException extends \Exception
|
|
13
11
|
{
|
|
12
|
+
protected array $context;
|
|
13
|
+
|
|
14
|
+
public function __construct(string $message = '', array $context = [], int $code = 0, ?\Throwable $previous = null)
|
|
15
|
+
{
|
|
16
|
+
parent::__construct($message, $code, $previous);
|
|
17
|
+
|
|
18
|
+
$this->context = $context;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public function context(): array
|
|
22
|
+
{
|
|
23
|
+
return $this->context;
|
|
24
|
+
}
|
|
14
25
|
}
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
namespace Fleetbase\FleetOps\Http\Controllers\Api\v1;
|
|
4
4
|
|
|
5
5
|
use Fleetbase\FleetOps\Events\OrderDispatchFailed;
|
|
6
|
-
use Fleetbase\FleetOps\Events\OrderReady;
|
|
7
6
|
use Fleetbase\FleetOps\Events\OrderStarted;
|
|
8
7
|
use Fleetbase\FleetOps\Exceptions\CustomerUserConflictException;
|
|
9
8
|
use Fleetbase\FleetOps\Exceptions\UserAlreadyExistsException;
|
|
@@ -14,6 +13,7 @@ use Fleetbase\FleetOps\Http\Requests\UpdateOrderRequest;
|
|
|
14
13
|
use Fleetbase\FleetOps\Http\Resources\v1\DeletedResource;
|
|
15
14
|
use Fleetbase\FleetOps\Http\Resources\v1\Order as OrderResource;
|
|
16
15
|
use Fleetbase\FleetOps\Http\Resources\v1\Proof as ProofResource;
|
|
16
|
+
use Fleetbase\FleetOps\Jobs\FinalizeApiOrderCreation;
|
|
17
17
|
use Fleetbase\FleetOps\Models\Contact;
|
|
18
18
|
use Fleetbase\FleetOps\Models\Driver;
|
|
19
19
|
use Fleetbase\FleetOps\Models\Entity;
|
|
@@ -335,26 +335,11 @@ class OrderController extends Controller
|
|
|
335
335
|
// Determine if order should be dispatched on creation
|
|
336
336
|
$shouldDispatch = $request->boolean('dispatch') && $integratedVendorOrder === null;
|
|
337
337
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
$
|
|
342
|
-
|
|
343
|
-
// set driving distance and time
|
|
344
|
-
$order->setPreliminaryDistanceAndTime();
|
|
345
|
-
|
|
346
|
-
// if service quote attached purchase
|
|
347
|
-
$order->purchaseServiceQuote($serviceQuote);
|
|
348
|
-
|
|
349
|
-
// dispatch if flagged true
|
|
350
|
-
if ($shouldDispatch) {
|
|
351
|
-
$order->dispatchWithActivity();
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
// Trigger order created event
|
|
355
|
-
event(new OrderReady($order));
|
|
356
|
-
})
|
|
357
|
-
->afterCommit();
|
|
338
|
+
FinalizeApiOrderCreation::dispatch(
|
|
339
|
+
$order->uuid,
|
|
340
|
+
$serviceQuote instanceof ServiceQuote ? $serviceQuote->uuid : null,
|
|
341
|
+
$shouldDispatch
|
|
342
|
+
)->afterCommit();
|
|
358
343
|
|
|
359
344
|
// response the driver resource
|
|
360
345
|
return new OrderResource($order);
|
|
@@ -5,8 +5,10 @@ namespace Fleetbase\FleetOps\Http\Controllers\Internal\v1;
|
|
|
5
5
|
use Fleetbase\FleetOps\Http\Controllers\FleetOpsController;
|
|
6
6
|
use Fleetbase\FleetOps\Models\Device;
|
|
7
7
|
use Fleetbase\FleetOps\Models\Vehicle;
|
|
8
|
+
use Fleetbase\FleetOps\Support\Utils;
|
|
8
9
|
use Illuminate\Http\JsonResponse;
|
|
9
10
|
use Illuminate\Http\Request;
|
|
11
|
+
use Illuminate\Support\Facades\Log;
|
|
10
12
|
|
|
11
13
|
class DeviceController extends FleetOpsController
|
|
12
14
|
{
|
|
@@ -42,6 +44,31 @@ class DeviceController extends FleetOpsController
|
|
|
42
44
|
if ($request->filled('device_id')) {
|
|
43
45
|
$query->where('device_id', 'like', '%' . $request->input('device_id') . '%');
|
|
44
46
|
}
|
|
47
|
+
|
|
48
|
+
if ($request->filled('connection_status')) {
|
|
49
|
+
$statuses = Utils::arrayFrom($request->input('connection_status'));
|
|
50
|
+
|
|
51
|
+
$query->where(function ($statusQuery) use ($statuses) {
|
|
52
|
+
foreach ($statuses as $status) {
|
|
53
|
+
match ($status) {
|
|
54
|
+
'online' => $statusQuery->orWhere('last_online_at', '>=', now()->subMinutes(10)),
|
|
55
|
+
'recently_offline' => $statusQuery->orWhereBetween('last_online_at', [now()->subMinutes(60), now()->subMinutes(10)]),
|
|
56
|
+
'offline' => $statusQuery->orWhereBetween('last_online_at', [now()->subDay(), now()->subMinutes(60)]),
|
|
57
|
+
'long_offline' => $statusQuery->orWhere('last_online_at', '<', now()->subDay()),
|
|
58
|
+
'never_connected' => $statusQuery->orWhereNull('last_online_at'),
|
|
59
|
+
default => null,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if ($request->filled('last_online_at')) {
|
|
66
|
+
static::applyDateFilter($query, 'last_online_at', $request->input('last_online_at'));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if ($request->filled('updated_at')) {
|
|
70
|
+
static::applyDateFilter($query, 'updated_at', $request->input('updated_at'));
|
|
71
|
+
}
|
|
45
72
|
}
|
|
46
73
|
|
|
47
74
|
/**
|
|
@@ -64,11 +91,30 @@ class DeviceController extends FleetOpsController
|
|
|
64
91
|
'vehicle' => 'required_without:attachable_uuid|nullable|string',
|
|
65
92
|
]);
|
|
66
93
|
|
|
67
|
-
$
|
|
68
|
-
$
|
|
94
|
+
$vehicleId = $request->input('vehicle') ?? $request->input('attachable_uuid');
|
|
95
|
+
$device = $this->resolveDevice($id);
|
|
96
|
+
$vehicle = $this->resolveVehicle($vehicleId);
|
|
97
|
+
|
|
98
|
+
if (!$device) {
|
|
99
|
+
$this->logDeviceAttachmentLookupFailure('attach', 'device', $id, $vehicleId);
|
|
100
|
+
|
|
101
|
+
return response()->error('Device not found or not available for this organization.', 404);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (!$vehicle) {
|
|
105
|
+
$this->logDeviceAttachmentLookupFailure('attach', 'vehicle', $id, $vehicleId);
|
|
106
|
+
|
|
107
|
+
return response()->error('Vehicle not found or not available for this organization.', 404);
|
|
108
|
+
}
|
|
69
109
|
|
|
70
|
-
|
|
71
|
-
|
|
110
|
+
try {
|
|
111
|
+
$device->attachTo($vehicle);
|
|
112
|
+
$device->load(['telematic', 'warranty', 'attachable']);
|
|
113
|
+
} catch (\Throwable $e) {
|
|
114
|
+
$this->logDeviceAttachmentFailure('attach', $device, $vehicle, $e);
|
|
115
|
+
|
|
116
|
+
return response()->error('Unable to attach device to vehicle. Please try again or contact support.', 500);
|
|
117
|
+
}
|
|
72
118
|
|
|
73
119
|
return response()->json([
|
|
74
120
|
'status' => 'ok',
|
|
@@ -81,9 +127,22 @@ class DeviceController extends FleetOpsController
|
|
|
81
127
|
*/
|
|
82
128
|
public function detach(string $id): JsonResponse
|
|
83
129
|
{
|
|
84
|
-
$device = $this->
|
|
85
|
-
|
|
86
|
-
|
|
130
|
+
$device = $this->resolveDevice($id);
|
|
131
|
+
|
|
132
|
+
if (!$device) {
|
|
133
|
+
$this->logDeviceAttachmentLookupFailure('detach', 'device', $id, null);
|
|
134
|
+
|
|
135
|
+
return response()->error('Device not found or not available for this organization.', 404);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
try {
|
|
139
|
+
$device->detach();
|
|
140
|
+
$device->load(['telematic', 'warranty', 'attachable']);
|
|
141
|
+
} catch (\Throwable $e) {
|
|
142
|
+
$this->logDeviceAttachmentFailure('detach', $device, null, $e);
|
|
143
|
+
|
|
144
|
+
return response()->error('Unable to detach device from vehicle. Please try again or contact support.', 500);
|
|
145
|
+
}
|
|
87
146
|
|
|
88
147
|
return response()->json([
|
|
89
148
|
'status' => 'ok',
|
|
@@ -91,21 +150,63 @@ class DeviceController extends FleetOpsController
|
|
|
91
150
|
]);
|
|
92
151
|
}
|
|
93
152
|
|
|
94
|
-
protected function
|
|
153
|
+
protected function resolveDevice(string $id): ?Device
|
|
95
154
|
{
|
|
96
155
|
return Device::where(function ($query) use ($id) {
|
|
97
156
|
$query->where('uuid', $id)->orWhere('public_id', $id);
|
|
98
157
|
})
|
|
99
158
|
->where('company_uuid', session('company'))
|
|
100
|
-
->
|
|
159
|
+
->first();
|
|
101
160
|
}
|
|
102
161
|
|
|
103
|
-
protected function
|
|
162
|
+
protected function resolveVehicle(?string $id): ?Vehicle
|
|
104
163
|
{
|
|
164
|
+
if (!$id) {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
|
|
105
168
|
return Vehicle::where(function ($query) use ($id) {
|
|
106
169
|
$query->where('uuid', $id)->orWhere('public_id', $id);
|
|
107
170
|
})
|
|
108
171
|
->where('company_uuid', session('company'))
|
|
109
|
-
->
|
|
172
|
+
->first();
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
protected static function applyDateFilter($query, string $column, string|array $value): void
|
|
176
|
+
{
|
|
177
|
+
$dates = Utils::dateRange($value);
|
|
178
|
+
|
|
179
|
+
if (is_array($dates)) {
|
|
180
|
+
$query->whereBetween($column, $dates);
|
|
181
|
+
} else {
|
|
182
|
+
$query->whereDate($column, $dates);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
protected function logDeviceAttachmentLookupFailure(string $action, string $missingResource, string $deviceId, ?string $vehicleId): void
|
|
187
|
+
{
|
|
188
|
+
Log::warning('Device attachment lookup failed', [
|
|
189
|
+
'action' => $action,
|
|
190
|
+
'missing_resource' => $missingResource,
|
|
191
|
+
'device_id' => $deviceId,
|
|
192
|
+
'vehicle_id' => $vehicleId,
|
|
193
|
+
'company_uuid' => session('company'),
|
|
194
|
+
'request_id' => request()->headers->get('X-Request-ID') ?? request()->headers->get('X-Correlation-ID'),
|
|
195
|
+
]);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
protected function logDeviceAttachmentFailure(string $action, Device $device, ?Vehicle $vehicle, \Throwable $exception): void
|
|
199
|
+
{
|
|
200
|
+
Log::error('Device attachment failed', [
|
|
201
|
+
'action' => $action,
|
|
202
|
+
'device_uuid' => $device->uuid,
|
|
203
|
+
'device_id' => $device->public_id,
|
|
204
|
+
'vehicle_uuid' => $vehicle?->uuid,
|
|
205
|
+
'vehicle_id' => $vehicle?->public_id,
|
|
206
|
+
'company_uuid' => session('company'),
|
|
207
|
+
'request_id' => request()->headers->get('X-Request-ID') ?? request()->headers->get('X-Correlation-ID'),
|
|
208
|
+
'exception_class' => get_class($exception),
|
|
209
|
+
'exception' => $exception->getMessage(),
|
|
210
|
+
]);
|
|
110
211
|
}
|
|
111
212
|
}
|
|
@@ -4,6 +4,7 @@ namespace Fleetbase\FleetOps\Http\Controllers\Internal\v1;
|
|
|
4
4
|
|
|
5
5
|
use Fleetbase\FleetOps\Http\Controllers\FleetOpsController;
|
|
6
6
|
use Fleetbase\FleetOps\Models\DeviceEvent;
|
|
7
|
+
use Fleetbase\FleetOps\Support\Utils;
|
|
7
8
|
use Illuminate\Http\JsonResponse;
|
|
8
9
|
|
|
9
10
|
class DeviceEventController extends FleetOpsController
|
|
@@ -32,11 +33,21 @@ class DeviceEventController extends FleetOpsController
|
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
if ($request->filled('processed')) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
36
|
+
$states = Utils::arrayFrom($request->input('processed'));
|
|
37
|
+
|
|
38
|
+
if (!$states) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
$query->where(function ($query) use ($states) {
|
|
43
|
+
foreach ($states as $state) {
|
|
44
|
+
match ($state) {
|
|
45
|
+
'processed' => $query->orWhereNotNull('processed_at'),
|
|
46
|
+
'unprocessed' => $query->orWhereNull('processed_at'),
|
|
47
|
+
default => null,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
});
|
|
40
51
|
}
|
|
41
52
|
}
|
|
42
53
|
|
|
@@ -11,6 +11,7 @@ use Fleetbase\FleetOps\Models\Fleet;
|
|
|
11
11
|
use Fleetbase\FleetOps\Models\FleetDriver;
|
|
12
12
|
use Fleetbase\FleetOps\Models\FleetVehicle;
|
|
13
13
|
use Fleetbase\FleetOps\Models\Vehicle;
|
|
14
|
+
use Fleetbase\FleetOps\Support\LiveCacheService;
|
|
14
15
|
use Fleetbase\Http\Requests\ExportRequest;
|
|
15
16
|
use Fleetbase\Http\Requests\ImportRequest;
|
|
16
17
|
use Illuminate\Http\Request;
|
|
@@ -121,6 +122,8 @@ class FleetController extends FleetOpsController
|
|
|
121
122
|
'driver_uuid' => $driver->uuid,
|
|
122
123
|
])->delete();
|
|
123
124
|
|
|
125
|
+
LiveCacheService::invalidate('operations-monitor');
|
|
126
|
+
|
|
124
127
|
return response()->json([
|
|
125
128
|
'status' => 'ok',
|
|
126
129
|
'deleted' => $deleted,
|
|
@@ -153,6 +156,8 @@ class FleetController extends FleetOpsController
|
|
|
153
156
|
]);
|
|
154
157
|
}
|
|
155
158
|
|
|
159
|
+
LiveCacheService::invalidate('operations-monitor');
|
|
160
|
+
|
|
156
161
|
return response()->json([
|
|
157
162
|
'status' => 'ok',
|
|
158
163
|
'exists' => $exists,
|
|
@@ -178,6 +183,8 @@ class FleetController extends FleetOpsController
|
|
|
178
183
|
'vehicle_uuid' => $vehicle->uuid,
|
|
179
184
|
])->delete();
|
|
180
185
|
|
|
186
|
+
LiveCacheService::invalidate('operations-monitor');
|
|
187
|
+
|
|
181
188
|
return response()->json([
|
|
182
189
|
'status' => 'ok',
|
|
183
190
|
'deleted' => $deleted,
|
|
@@ -210,6 +217,8 @@ class FleetController extends FleetOpsController
|
|
|
210
217
|
]);
|
|
211
218
|
}
|
|
212
219
|
|
|
220
|
+
LiveCacheService::invalidate('operations-monitor');
|
|
221
|
+
|
|
213
222
|
return response()->json([
|
|
214
223
|
'status' => 'ok',
|
|
215
224
|
'exists' => $exists,
|