@fleetbase/fleetops-engine 0.6.16 → 0.6.18
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/layout/fleet-ops-sidebar.hbs +25 -0
- package/addon/templates/virtual.hbs +3 -3
- package/composer.json +3 -2
- package/extension.json +1 -1
- package/package.json +1 -1
- package/server/migrations/2025_08_11_170800_add_company_index_to_routes_table.php +21 -0
- package/server/migrations/2025_08_28_054920_create_warranties_table.php +56 -0
- package/server/migrations/2025_08_28_054921_create_telematics_table.php +60 -0
- package/server/migrations/2025_08_28_054922_create_assets_table.php +94 -0
- package/server/migrations/2025_08_28_054925_create_devices_table.php +190 -0
- package/server/migrations/2025_08_28_054926_create_device_events_table.php +99 -0
- package/server/migrations/2025_08_28_054926_create_sensors_table.php +62 -0
- package/server/migrations/2025_08_28_054927_create_parts_table.php +73 -0
- package/server/migrations/2025_08_28_054929_create_equipments_table.php +58 -0
- package/server/migrations/2025_08_28_054930_create_work_orders_table.php +85 -0
- package/server/migrations/2025_08_28_054931_create_maintenances_table.php +79 -0
- package/server/migrations/2025_08_28_082002_update_vehicles_table_telematics.php +60 -0
- package/server/src/Http/Controllers/Api/v1/OrderController.php +19 -1
- package/server/src/Http/Controllers/Internal/v1/OrderController.php +31 -8
- package/server/src/Http/Resources/v1/Order.php +111 -60
- package/server/src/Models/Asset.php +548 -0
- package/server/src/Models/Contact.php +2 -0
- package/server/src/Models/Device.php +435 -0
- package/server/src/Models/DeviceEvent.php +501 -0
- package/server/src/Models/Driver.php +2 -0
- package/server/src/Models/Entity.php +27 -50
- package/server/src/Models/Equipment.php +483 -0
- package/server/src/Models/Fleet.php +2 -0
- package/server/src/Models/FuelReport.php +2 -0
- package/server/src/Models/Issue.php +2 -0
- package/server/src/Models/Maintenance.php +549 -0
- package/server/src/Models/Order.php +32 -112
- package/server/src/Models/OrderConfig.php +8 -0
- package/server/src/Models/Part.php +502 -0
- package/server/src/Models/Payload.php +101 -20
- package/server/src/Models/Place.php +10 -4
- package/server/src/Models/Sensor.php +510 -0
- package/server/src/Models/ServiceArea.php +1 -1
- package/server/src/Models/Telematic.php +336 -0
- package/server/src/Models/Vehicle.php +45 -1
- package/server/src/Models/VehicleDevice.php +1 -1
- package/server/src/Models/Vendor.php +2 -0
- package/server/src/Models/Warranty.php +413 -0
- package/server/src/Models/Waypoint.php +2 -0
- package/server/src/Models/WorkOrder.php +532 -0
- package/server/src/Support/Utils.php +5 -0
- package/server/src/Traits/HasTrackingNumber.php +64 -10
- package/server/src/Traits/Maintainable.php +307 -0
- package/server/src/Traits/PayloadAccessors.php +126 -0
|
@@ -0,0 +1,501 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\FleetOps\Models;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\Casts\Json;
|
|
6
|
+
use Fleetbase\Models\Alert;
|
|
7
|
+
use Fleetbase\Models\Model;
|
|
8
|
+
use Fleetbase\Models\User;
|
|
9
|
+
use Fleetbase\Traits\HasApiModelBehavior;
|
|
10
|
+
use Fleetbase\Traits\HasMetaAttributes;
|
|
11
|
+
use Fleetbase\Traits\HasPublicId;
|
|
12
|
+
use Fleetbase\Traits\HasUuid;
|
|
13
|
+
use Fleetbase\Traits\Searchable;
|
|
14
|
+
use Fleetbase\Traits\TracksApiCredential;
|
|
15
|
+
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
16
|
+
use Spatie\Activitylog\LogOptions;
|
|
17
|
+
use Spatie\Activitylog\Traits\LogsActivity;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Class DeviceEvent.
|
|
21
|
+
*
|
|
22
|
+
* Represents events generated by devices in the fleet management system.
|
|
23
|
+
* Events can include status changes, alerts, data transmissions, and other
|
|
24
|
+
* device-related activities.
|
|
25
|
+
*/
|
|
26
|
+
class DeviceEvent extends Model
|
|
27
|
+
{
|
|
28
|
+
use HasUuid;
|
|
29
|
+
use HasPublicId;
|
|
30
|
+
use TracksApiCredential;
|
|
31
|
+
use HasApiModelBehavior;
|
|
32
|
+
use LogsActivity;
|
|
33
|
+
use HasMetaAttributes;
|
|
34
|
+
use Searchable;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* The database table used by the model.
|
|
38
|
+
*
|
|
39
|
+
* @var string
|
|
40
|
+
*/
|
|
41
|
+
protected $table = 'device_events';
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* The type of public Id to generate.
|
|
45
|
+
*
|
|
46
|
+
* @var string
|
|
47
|
+
*/
|
|
48
|
+
protected $publicIdType = 'device_event';
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The attributes that can be queried.
|
|
52
|
+
*
|
|
53
|
+
* @var array
|
|
54
|
+
*/
|
|
55
|
+
protected $searchableColumns = ['event_type', 'message', 'public_id'];
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The attributes that can be used for filtering.
|
|
59
|
+
*
|
|
60
|
+
* @var array
|
|
61
|
+
*/
|
|
62
|
+
protected $filterParams = ['event_type', 'severity', 'device_uuid'];
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The attributes that are mass assignable.
|
|
66
|
+
*
|
|
67
|
+
* @var array
|
|
68
|
+
*/
|
|
69
|
+
protected $fillable = [
|
|
70
|
+
'device_uuid',
|
|
71
|
+
'payload',
|
|
72
|
+
'meta',
|
|
73
|
+
'location',
|
|
74
|
+
'event_type',
|
|
75
|
+
'severity',
|
|
76
|
+
'ident',
|
|
77
|
+
'protocol',
|
|
78
|
+
'provider',
|
|
79
|
+
'mileage',
|
|
80
|
+
'state',
|
|
81
|
+
'code',
|
|
82
|
+
'reason',
|
|
83
|
+
'comment',
|
|
84
|
+
'slug',
|
|
85
|
+
];
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Dynamic attributes that are appended to object.
|
|
89
|
+
*
|
|
90
|
+
* @var array
|
|
91
|
+
*/
|
|
92
|
+
protected $appends = [
|
|
93
|
+
'device_name',
|
|
94
|
+
'is_processed',
|
|
95
|
+
'age_minutes',
|
|
96
|
+
'processing_delay_minutes',
|
|
97
|
+
];
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* The attributes excluded from the model's JSON form.
|
|
101
|
+
*
|
|
102
|
+
* @var array
|
|
103
|
+
*/
|
|
104
|
+
protected $hidden = ['device'];
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* The attributes that should be cast to native types.
|
|
108
|
+
*
|
|
109
|
+
* @var array
|
|
110
|
+
*/
|
|
111
|
+
protected $casts = [
|
|
112
|
+
'data' => Json::class,
|
|
113
|
+
'occurred_at' => 'datetime',
|
|
114
|
+
'processed_at' => 'datetime',
|
|
115
|
+
];
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Properties which activity needs to be logged.
|
|
119
|
+
*
|
|
120
|
+
* @var array
|
|
121
|
+
*/
|
|
122
|
+
protected static $logAttributes = '*';
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Do not log empty changed.
|
|
126
|
+
*
|
|
127
|
+
* @var bool
|
|
128
|
+
*/
|
|
129
|
+
protected static $submitEmptyLogs = false;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* The name of the subject to log.
|
|
133
|
+
*
|
|
134
|
+
* @var string
|
|
135
|
+
*/
|
|
136
|
+
protected static $logName = 'device_event';
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Get the activity log options for the model.
|
|
140
|
+
*/
|
|
141
|
+
public function getActivitylogOptions(): LogOptions
|
|
142
|
+
{
|
|
143
|
+
return LogOptions::defaults()->logAll();
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
public function device(): BelongsTo
|
|
147
|
+
{
|
|
148
|
+
return $this->belongsTo(Device::class, 'device_uuid', 'uuid');
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
public function createdBy(): BelongsTo
|
|
152
|
+
{
|
|
153
|
+
return $this->belongsTo(User::class, 'created_by_uuid', 'uuid');
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Get the device name.
|
|
158
|
+
*/
|
|
159
|
+
public function getDeviceNameAttribute(): ?string
|
|
160
|
+
{
|
|
161
|
+
return $this->device?->name;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Check if the event has been processed.
|
|
166
|
+
*/
|
|
167
|
+
public function getIsProcessedAttribute(): bool
|
|
168
|
+
{
|
|
169
|
+
return !is_null($this->processed_at);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Get the age of the event in minutes.
|
|
174
|
+
*/
|
|
175
|
+
public function getAgeMinutesAttribute(): int
|
|
176
|
+
{
|
|
177
|
+
$startTime = $this->occurred_at ?? $this->created_at;
|
|
178
|
+
|
|
179
|
+
return $startTime->diffInMinutes(now());
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Get the processing delay in minutes.
|
|
184
|
+
*/
|
|
185
|
+
public function getProcessingDelayMinutesAttribute(): ?int
|
|
186
|
+
{
|
|
187
|
+
if (!$this->processed_at) {
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
$startTime = $this->occurred_at ?? $this->created_at;
|
|
192
|
+
|
|
193
|
+
return $startTime->diffInMinutes($this->processed_at);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Scope to get events by type.
|
|
198
|
+
*
|
|
199
|
+
* @param \Illuminate\Database\Eloquent\Builder $query
|
|
200
|
+
*
|
|
201
|
+
* @return \Illuminate\Database\Eloquent\Builder
|
|
202
|
+
*/
|
|
203
|
+
public function scopeByType($query, string $type)
|
|
204
|
+
{
|
|
205
|
+
return $query->where('event_type', $type);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Scope to get events by severity.
|
|
210
|
+
*
|
|
211
|
+
* @param \Illuminate\Database\Eloquent\Builder $query
|
|
212
|
+
*
|
|
213
|
+
* @return \Illuminate\Database\Eloquent\Builder
|
|
214
|
+
*/
|
|
215
|
+
public function scopeBySeverity($query, string $severity)
|
|
216
|
+
{
|
|
217
|
+
return $query->where('severity', $severity);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Scope to get processed events.
|
|
222
|
+
*
|
|
223
|
+
* @param \Illuminate\Database\Eloquent\Builder $query
|
|
224
|
+
*
|
|
225
|
+
* @return \Illuminate\Database\Eloquent\Builder
|
|
226
|
+
*/
|
|
227
|
+
public function scopeProcessed($query)
|
|
228
|
+
{
|
|
229
|
+
return $query->whereNotNull('processed_at');
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Scope to get unprocessed events.
|
|
234
|
+
*
|
|
235
|
+
* @param \Illuminate\Database\Eloquent\Builder $query
|
|
236
|
+
*
|
|
237
|
+
* @return \Illuminate\Database\Eloquent\Builder
|
|
238
|
+
*/
|
|
239
|
+
public function scopeUnprocessed($query)
|
|
240
|
+
{
|
|
241
|
+
return $query->whereNull('processed_at');
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Scope to get recent events.
|
|
246
|
+
*
|
|
247
|
+
* @param \Illuminate\Database\Eloquent\Builder $query
|
|
248
|
+
*
|
|
249
|
+
* @return \Illuminate\Database\Eloquent\Builder
|
|
250
|
+
*/
|
|
251
|
+
public function scopeRecent($query, int $minutes = 60)
|
|
252
|
+
{
|
|
253
|
+
return $query->where('occurred_at', '>=', now()->subMinutes($minutes));
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Scope to get critical events.
|
|
258
|
+
*
|
|
259
|
+
* @param \Illuminate\Database\Eloquent\Builder $query
|
|
260
|
+
*
|
|
261
|
+
* @return \Illuminate\Database\Eloquent\Builder
|
|
262
|
+
*/
|
|
263
|
+
public function scopeCritical($query)
|
|
264
|
+
{
|
|
265
|
+
return $query->where('severity', 'critical');
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Mark the event as processed.
|
|
270
|
+
*/
|
|
271
|
+
public function markAsProcessed(): bool
|
|
272
|
+
{
|
|
273
|
+
if ($this->is_processed) {
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
$updated = $this->update(['processed_at' => now()]);
|
|
278
|
+
|
|
279
|
+
if ($updated) {
|
|
280
|
+
activity('device_event_processed')
|
|
281
|
+
->performedOn($this)
|
|
282
|
+
->withProperties([
|
|
283
|
+
'event_type' => $this->event_type,
|
|
284
|
+
'processing_delay_minutes' => $this->processing_delay_minutes,
|
|
285
|
+
])
|
|
286
|
+
->log('Device event processed');
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return $updated;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Get a specific data field from the event.
|
|
294
|
+
*/
|
|
295
|
+
public function getData(string $field, $default = null)
|
|
296
|
+
{
|
|
297
|
+
$data = $this->data ?? [];
|
|
298
|
+
|
|
299
|
+
// Support dot notation for nested data
|
|
300
|
+
$keys = explode('.', $field);
|
|
301
|
+
$value = $data;
|
|
302
|
+
|
|
303
|
+
foreach ($keys as $key) {
|
|
304
|
+
if (is_array($value) && isset($value[$key])) {
|
|
305
|
+
$value = $value[$key];
|
|
306
|
+
} else {
|
|
307
|
+
return $default;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
return $value;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Set a specific data field in the event.
|
|
316
|
+
*/
|
|
317
|
+
public function setData(string $field, $value): bool
|
|
318
|
+
{
|
|
319
|
+
$data = $this->data ?? [];
|
|
320
|
+
|
|
321
|
+
// Support dot notation for nested data
|
|
322
|
+
$keys = explode('.', $field);
|
|
323
|
+
$current = &$data;
|
|
324
|
+
|
|
325
|
+
foreach ($keys as $i => $key) {
|
|
326
|
+
if ($i === count($keys) - 1) {
|
|
327
|
+
$current[$key] = $value;
|
|
328
|
+
} else {
|
|
329
|
+
if (!isset($current[$key]) || !is_array($current[$key])) {
|
|
330
|
+
$current[$key] = [];
|
|
331
|
+
}
|
|
332
|
+
$current = &$current[$key];
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
return $this->update(['data' => $data]);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Check if the event should trigger an alert.
|
|
341
|
+
*/
|
|
342
|
+
public function shouldTriggerAlert(): bool
|
|
343
|
+
{
|
|
344
|
+
// Define event types that should trigger alerts
|
|
345
|
+
$alertTriggerTypes = [
|
|
346
|
+
'error',
|
|
347
|
+
'warning',
|
|
348
|
+
'critical_failure',
|
|
349
|
+
'security_breach',
|
|
350
|
+
'maintenance_required',
|
|
351
|
+
'threshold_exceeded',
|
|
352
|
+
];
|
|
353
|
+
|
|
354
|
+
if (in_array($this->event_type, $alertTriggerTypes)) {
|
|
355
|
+
return true;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// Check severity
|
|
359
|
+
if (in_array($this->severity, ['high', 'critical'])) {
|
|
360
|
+
return true;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
return false;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Create an alert based on this event.
|
|
368
|
+
*/
|
|
369
|
+
public function createAlert(): ?Alert
|
|
370
|
+
{
|
|
371
|
+
if (!$this->shouldTriggerAlert()) {
|
|
372
|
+
return null;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// Check if an alert already exists for this event
|
|
376
|
+
$existingAlert = Alert::where('subject_type', static::class)
|
|
377
|
+
->where('subject_uuid', $this->uuid)
|
|
378
|
+
->where('status', 'open')
|
|
379
|
+
->first();
|
|
380
|
+
|
|
381
|
+
if ($existingAlert) {
|
|
382
|
+
return $existingAlert;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
$alert = Alert::create([
|
|
386
|
+
'company_uuid' => $this->company_uuid,
|
|
387
|
+
'type' => 'device_event',
|
|
388
|
+
'severity' => $this->severity,
|
|
389
|
+
'status' => 'open',
|
|
390
|
+
'subject_type' => static::class,
|
|
391
|
+
'subject_uuid' => $this->uuid,
|
|
392
|
+
'message' => $this->generateAlertMessage(),
|
|
393
|
+
'context' => [
|
|
394
|
+
'device_uuid' => $this->device_uuid,
|
|
395
|
+
'device_name' => $this->device_name,
|
|
396
|
+
'event_type' => $this->event_type,
|
|
397
|
+
'event_data' => $this->data,
|
|
398
|
+
'occurred_at' => $this->occurred_at,
|
|
399
|
+
],
|
|
400
|
+
'triggered_at' => $this->occurred_at ?? now(),
|
|
401
|
+
]);
|
|
402
|
+
|
|
403
|
+
return $alert;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Generate an alert message for this event.
|
|
408
|
+
*/
|
|
409
|
+
protected function generateAlertMessage(): string
|
|
410
|
+
{
|
|
411
|
+
$deviceName = $this->device_name ?? 'Unknown Device';
|
|
412
|
+
|
|
413
|
+
switch ($this->event_type) {
|
|
414
|
+
case 'error':
|
|
415
|
+
return "Device '{$deviceName}' reported an error: {$this->message}";
|
|
416
|
+
case 'warning':
|
|
417
|
+
return "Device '{$deviceName}' issued a warning: {$this->message}";
|
|
418
|
+
case 'critical_failure':
|
|
419
|
+
return "Critical failure detected on device '{$deviceName}': {$this->message}";
|
|
420
|
+
case 'security_breach':
|
|
421
|
+
return "Security breach detected on device '{$deviceName}': {$this->message}";
|
|
422
|
+
case 'maintenance_required':
|
|
423
|
+
return "Device '{$deviceName}' requires maintenance: {$this->message}";
|
|
424
|
+
case 'threshold_exceeded':
|
|
425
|
+
return "Threshold exceeded on device '{$deviceName}': {$this->message}";
|
|
426
|
+
default:
|
|
427
|
+
return "Device '{$deviceName}' event ({$this->event_type}): {$this->message}";
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Get the severity level as a numeric value for sorting.
|
|
433
|
+
*/
|
|
434
|
+
public function getSeverityLevel(): int
|
|
435
|
+
{
|
|
436
|
+
switch ($this->severity) {
|
|
437
|
+
case 'critical':
|
|
438
|
+
return 4;
|
|
439
|
+
case 'high':
|
|
440
|
+
return 3;
|
|
441
|
+
case 'medium':
|
|
442
|
+
return 2;
|
|
443
|
+
case 'low':
|
|
444
|
+
return 1;
|
|
445
|
+
default:
|
|
446
|
+
return 0;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Get events that occurred around the same time as this event.
|
|
452
|
+
*
|
|
453
|
+
* @return \Illuminate\Database\Eloquent\Collection
|
|
454
|
+
*/
|
|
455
|
+
public function getCorrelatedEvents(int $minuteWindow = 5)
|
|
456
|
+
{
|
|
457
|
+
$startTime = ($this->occurred_at ?? $this->created_at)->subMinutes($minuteWindow);
|
|
458
|
+
$endTime = ($this->occurred_at ?? $this->created_at)->addMinutes($minuteWindow);
|
|
459
|
+
|
|
460
|
+
return static::where('device_uuid', $this->device_uuid)
|
|
461
|
+
->where('uuid', '!=', $this->uuid)
|
|
462
|
+
->whereBetween('occurred_at', [$startTime, $endTime])
|
|
463
|
+
->orderBy('occurred_at')
|
|
464
|
+
->get();
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Check if this event is part of a pattern.
|
|
469
|
+
*/
|
|
470
|
+
public function isPartOfPattern(int $lookbackHours = 24, int $minimumOccurrences = 3): bool
|
|
471
|
+
{
|
|
472
|
+
$startTime = now()->subHours($lookbackHours);
|
|
473
|
+
|
|
474
|
+
$similarEvents = static::where('device_uuid', $this->device_uuid)
|
|
475
|
+
->where('event_type', $this->event_type)
|
|
476
|
+
->where('occurred_at', '>=', $startTime)
|
|
477
|
+
->count();
|
|
478
|
+
|
|
479
|
+
return $similarEvents >= $minimumOccurrences;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* Export the event data for analysis.
|
|
484
|
+
*/
|
|
485
|
+
public function exportForAnalysis(): array
|
|
486
|
+
{
|
|
487
|
+
return [
|
|
488
|
+
'event_id' => $this->public_id,
|
|
489
|
+
'device_uuid' => $this->device_uuid,
|
|
490
|
+
'device_name' => $this->device_name,
|
|
491
|
+
'event_type' => $this->event_type,
|
|
492
|
+
'severity' => $this->severity,
|
|
493
|
+
'message' => $this->message,
|
|
494
|
+
'occurred_at' => $this->occurred_at?->toISOString(),
|
|
495
|
+
'processed_at' => $this->processed_at?->toISOString(),
|
|
496
|
+
'processing_delay_minutes' => $this->processing_delay_minutes,
|
|
497
|
+
'data' => $this->data,
|
|
498
|
+
'created_at' => $this->created_at?->toISOString(),
|
|
499
|
+
];
|
|
500
|
+
}
|
|
501
|
+
}
|
|
@@ -12,6 +12,7 @@ use Fleetbase\Models\File;
|
|
|
12
12
|
use Fleetbase\Models\Model;
|
|
13
13
|
use Fleetbase\Models\User;
|
|
14
14
|
use Fleetbase\Traits\HasApiModelBehavior;
|
|
15
|
+
use Fleetbase\Traits\HasCustomFields;
|
|
15
16
|
use Fleetbase\Traits\HasInternalId;
|
|
16
17
|
use Fleetbase\Traits\HasPublicId;
|
|
17
18
|
use Fleetbase\Traits\HasUuid;
|
|
@@ -46,6 +47,7 @@ class Driver extends Model
|
|
|
46
47
|
use HasSlug;
|
|
47
48
|
use LogsActivity;
|
|
48
49
|
use CausesActivity;
|
|
50
|
+
use HasCustomFields;
|
|
49
51
|
|
|
50
52
|
/**
|
|
51
53
|
* The database table used by the model.
|
|
@@ -7,14 +7,19 @@ use Fleetbase\Casts\Json;
|
|
|
7
7
|
use Fleetbase\Casts\PolymorphicType;
|
|
8
8
|
use Fleetbase\FleetOps\Support\Utils;
|
|
9
9
|
use Fleetbase\FleetOps\Traits\HasTrackingNumber;
|
|
10
|
+
use Fleetbase\FleetOps\Traits\PayloadAccessors;
|
|
10
11
|
use Fleetbase\Models\Model;
|
|
11
12
|
use Fleetbase\Traits\HasApiModelBehavior;
|
|
13
|
+
use Fleetbase\Traits\HasCustomFields;
|
|
12
14
|
use Fleetbase\Traits\HasInternalId;
|
|
13
15
|
use Fleetbase\Traits\HasMetaAttributes;
|
|
14
16
|
use Fleetbase\Traits\HasPublicId;
|
|
15
17
|
use Fleetbase\Traits\HasUuid;
|
|
16
18
|
use Fleetbase\Traits\SendsWebhooks;
|
|
17
19
|
use Fleetbase\Traits\TracksApiCredential;
|
|
20
|
+
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
21
|
+
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
22
|
+
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
|
18
23
|
use Illuminate\Support\Carbon;
|
|
19
24
|
use Illuminate\Support\Str;
|
|
20
25
|
use Milon\Barcode\Facades\DNS2DFacade as DNS2D;
|
|
@@ -31,6 +36,8 @@ class Entity extends Model
|
|
|
31
36
|
use HasTrackingNumber;
|
|
32
37
|
use HasApiModelBehavior;
|
|
33
38
|
use HasMetaAttributes;
|
|
39
|
+
use PayloadAccessors;
|
|
40
|
+
use HasCustomFields;
|
|
34
41
|
|
|
35
42
|
/**
|
|
36
43
|
* The database table used by the model.
|
|
@@ -162,81 +169,81 @@ class Entity extends Model
|
|
|
162
169
|
}
|
|
163
170
|
|
|
164
171
|
/**
|
|
165
|
-
* @var
|
|
172
|
+
* @var BelongsTo
|
|
166
173
|
*/
|
|
167
|
-
public function photo()
|
|
174
|
+
public function photo(): BelongsTo
|
|
168
175
|
{
|
|
169
176
|
return $this->belongsTo(\Fleetbase\Models\File::class);
|
|
170
177
|
}
|
|
171
178
|
|
|
172
179
|
/**
|
|
173
|
-
* @var
|
|
180
|
+
* @var HasMany
|
|
174
181
|
*/
|
|
175
|
-
public function files()
|
|
182
|
+
public function files(): HasMany
|
|
176
183
|
{
|
|
177
184
|
return $this->hasMany(\Fleetbase\Models\File::class);
|
|
178
185
|
}
|
|
179
186
|
|
|
180
187
|
/**
|
|
181
|
-
* @var
|
|
188
|
+
* @var HasMany
|
|
182
189
|
*/
|
|
183
|
-
public function proofs()
|
|
190
|
+
public function proofs(): HasMany
|
|
184
191
|
{
|
|
185
192
|
return $this->hasMany(Proof::class, 'subject_uuid');
|
|
186
193
|
}
|
|
187
194
|
|
|
188
195
|
/**
|
|
189
|
-
* @var
|
|
196
|
+
* @var BelongsTo
|
|
190
197
|
*/
|
|
191
|
-
public function destination()
|
|
198
|
+
public function destination(): BelongsTo
|
|
192
199
|
{
|
|
193
200
|
return $this->belongsTo(Place::class);
|
|
194
201
|
}
|
|
195
202
|
|
|
196
203
|
/**
|
|
197
|
-
* @var
|
|
204
|
+
* @var BelongsTo
|
|
198
205
|
*/
|
|
199
|
-
public function payload()
|
|
206
|
+
public function payload(): BelongsTo
|
|
200
207
|
{
|
|
201
208
|
return $this->belongsTo(Payload::class)->without(['entities']);
|
|
202
209
|
}
|
|
203
210
|
|
|
204
211
|
/**
|
|
205
|
-
* @var
|
|
212
|
+
* @var BelongsTo
|
|
206
213
|
*/
|
|
207
|
-
public function supplier()
|
|
214
|
+
public function supplier(): BelongsTo
|
|
208
215
|
{
|
|
209
216
|
return $this->belongsTo(Vendor::class, 'supplier_uuid', 'uuid');
|
|
210
217
|
}
|
|
211
218
|
|
|
212
219
|
/**
|
|
213
|
-
* @var
|
|
220
|
+
* @var BelongsTo
|
|
214
221
|
*/
|
|
215
|
-
public function driver()
|
|
222
|
+
public function driver(): BelongsTo
|
|
216
223
|
{
|
|
217
224
|
return $this->belongsTo(Driver::class, 'driver_assigned_uuid');
|
|
218
225
|
}
|
|
219
226
|
|
|
220
227
|
/**
|
|
221
|
-
* @var
|
|
228
|
+
* @var BelongsTo
|
|
222
229
|
*/
|
|
223
|
-
public function company()
|
|
230
|
+
public function company(): BelongsTo
|
|
224
231
|
{
|
|
225
232
|
return $this->belongsTo(\Fleetbase\Models\Company::class);
|
|
226
233
|
}
|
|
227
234
|
|
|
228
235
|
/**
|
|
229
|
-
* @var
|
|
236
|
+
* @var BelongsTo
|
|
230
237
|
*/
|
|
231
|
-
public function trackingNumber()
|
|
238
|
+
public function trackingNumber(): BelongsTo
|
|
232
239
|
{
|
|
233
240
|
return $this->belongsTo(TrackingNumber::class);
|
|
234
241
|
}
|
|
235
242
|
|
|
236
243
|
/**
|
|
237
|
-
* @var
|
|
244
|
+
* @var MorphTo
|
|
238
245
|
*/
|
|
239
|
-
public function customer()
|
|
246
|
+
public function customer(): MorphTo
|
|
240
247
|
{
|
|
241
248
|
return $this->morphTo(__FUNCTION__, 'customer_type', 'customer_uuid')->withoutGlobalScopes();
|
|
242
249
|
}
|
|
@@ -475,34 +482,4 @@ class Entity extends Model
|
|
|
475
482
|
$this->customer_uuid = $model->uuid;
|
|
476
483
|
$this->customer_type = Utils::getMutationType($model);
|
|
477
484
|
}
|
|
478
|
-
|
|
479
|
-
public function getPayload(): ?Payload
|
|
480
|
-
{
|
|
481
|
-
$this->load('payload');
|
|
482
|
-
|
|
483
|
-
if ($this->payload instanceof Payload) {
|
|
484
|
-
return $this->payload;
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
if (Str::isUuid($this->payload_uuid)) {
|
|
488
|
-
return Payload::where('uuid', $this->payload_uuid)->first();
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
return null;
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
public function getTrashedPayload(): ?Payload
|
|
495
|
-
{
|
|
496
|
-
$payload = $this->payload()->withoutGlobalScopes()->first();
|
|
497
|
-
|
|
498
|
-
if ($payload instanceof Payload) {
|
|
499
|
-
return $payload;
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
if (Str::isUuid($this->payload_uuid)) {
|
|
503
|
-
return Payload::where('uuid', $this->payload_uuid)->withoutGlobalScopes()->first();
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
return null;
|
|
507
|
-
}
|
|
508
485
|
}
|