@fleetbase/fleetops-engine 0.6.20 → 0.6.22
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/custom-entity/form.hbs +14 -14
- package/addon/components/device/card.hbs +1 -0
- package/addon/components/device/card.js +3 -0
- package/addon/components/device/details.hbs +92 -43
- package/addon/components/device/form.hbs +108 -60
- package/addon/components/device/form.js +36 -8
- package/addon/components/device/manager.hbs +29 -0
- package/addon/components/device/manager.js +95 -0
- package/addon/components/device/panel-header.hbs +32 -0
- package/addon/components/device/panel-header.js +3 -0
- package/addon/components/device/pill.hbs +16 -0
- package/addon/components/device/pill.js +3 -0
- package/addon/components/driver/details.hbs +4 -0
- package/addon/components/driver/details.js +19 -1
- package/addon/components/driver/form.hbs +14 -3
- package/addon/components/driver/form.js +49 -47
- package/addon/components/driver/pill.hbs +17 -0
- package/addon/components/driver/pill.js +3 -0
- package/addon/components/entity/form.hbs +7 -5
- package/addon/components/layout/fleet-ops-sidebar.js +12 -12
- package/addon/components/map/drawer/device-event-listing.hbs +64 -0
- package/addon/components/map/drawer/device-event-listing.js +181 -0
- package/addon/components/map/drawer/position-listing.hbs +100 -0
- package/addon/components/map/drawer/position-listing.js +455 -0
- package/addon/components/map/drawer.js +2 -0
- package/addon/components/map/leaflet-live-map.hbs +7 -2
- package/addon/components/modals/attach-device.hbs +18 -0
- package/addon/components/modals/attach-device.js +3 -0
- package/addon/components/order/details/detail.hbs +2 -54
- package/addon/components/order/details/detail.js +1 -0
- package/addon/components/order/details/payload.hbs +6 -4
- package/addon/components/order/details/payload.js +2 -0
- package/addon/components/order/pill.hbs +34 -0
- package/addon/components/order/pill.js +3 -0
- package/addon/components/order-config-manager/custom-fields.js +1 -1
- package/addon/components/positions-replay.hbs +339 -0
- package/addon/components/positions-replay.js +409 -0
- package/addon/components/sensor/details.hbs +64 -38
- package/addon/components/sensor/form.hbs +112 -63
- package/addon/components/sensor/form.js +36 -24
- package/addon/components/sensor/panel-header.hbs +32 -0
- package/addon/components/sensor/panel-header.js +3 -0
- package/addon/components/telematic/details.hbs +40 -16
- package/addon/components/telematic/form.hbs +63 -64
- package/addon/components/telematic/form.js +73 -4
- package/addon/components/vehicle/card.hbs +2 -2
- package/addon/components/vehicle/details.hbs +4 -0
- package/addon/components/vehicle/details.js +19 -1
- package/addon/components/vehicle/form.hbs +4 -0
- package/addon/components/vehicle/pill.hbs +34 -0
- package/addon/components/vehicle/pill.js +3 -0
- package/addon/controllers/analytics/reports/index/edit.js +1 -1
- package/addon/controllers/connectivity/devices/index/details.js +22 -1
- package/addon/controllers/connectivity/devices/index/edit.js +66 -1
- package/addon/controllers/connectivity/devices/index.js +51 -9
- package/addon/controllers/connectivity/events/index.js +65 -16
- package/addon/controllers/connectivity/sensors/index/details.js +22 -1
- package/addon/controllers/connectivity/sensors/index/edit.js +66 -1
- package/addon/controllers/connectivity/sensors/index.js +66 -6
- package/addon/controllers/connectivity/telematics/index/details.js +22 -1
- package/addon/controllers/connectivity/telematics/index/edit.js +66 -1
- package/addon/controllers/connectivity/telematics/index.js +20 -11
- package/addon/controllers/management/fleets/index/details.js +26 -21
- package/addon/controllers/management/fleets/index/edit.js +9 -6
- package/addon/controllers/management/vehicles/index/details.js +26 -13
- package/addon/controllers/settings/custom-fields.js +6 -0
- package/addon/helpers/get-fleet-ops-option-label.js +11 -0
- package/addon/routes/connectivity/devices/index/details.js +27 -1
- package/addon/routes/connectivity/devices/index/edit.js +27 -1
- package/addon/routes/connectivity/sensors/index/details.js +27 -1
- package/addon/routes/connectivity/sensors/index/edit.js +27 -1
- package/addon/routes/connectivity/telematics/index/details.js +27 -1
- package/addon/routes/connectivity/telematics/index/edit.js +27 -1
- package/addon/routes/management/drivers/index/details/positions.js +3 -0
- package/addon/routes/management/vehicles/index/details/positions.js +3 -0
- package/addon/routes.js +4 -0
- package/addon/services/movement-tracker.js +81 -30
- package/addon/services/position-playback.js +486 -0
- package/addon/services/resource-metadata.js +46 -0
- package/addon/styles/fleetops-engine.css +157 -0
- package/addon/templates/connectivity/devices/index/details/index.hbs +2 -2
- package/addon/templates/connectivity/devices/index/details.hbs +15 -2
- package/addon/templates/connectivity/devices/index/edit.hbs +1 -1
- package/addon/templates/connectivity/events/index.hbs +1 -1
- package/addon/templates/connectivity/sensors/index/details/index.hbs +2 -2
- package/addon/templates/connectivity/sensors/index/details.hbs +15 -2
- package/addon/templates/connectivity/sensors/index/edit.hbs +1 -1
- package/addon/templates/connectivity/telematics/index/details/index.hbs +2 -2
- package/addon/templates/connectivity/telematics/index/details.hbs +14 -2
- package/addon/templates/connectivity/telematics/index/edit.hbs +1 -1
- package/addon/templates/management/drivers/index/details/positions.hbs +2 -0
- package/addon/templates/management/vehicles/index/details/devices.hbs +1 -2
- package/addon/templates/management/vehicles/index/details/positions.hbs +1 -0
- package/addon/utils/fleet-ops-options.js +95 -0
- package/app/components/device/card.js +1 -0
- package/app/components/device/manager.js +1 -0
- package/app/components/device/panel-header.js +1 -0
- package/app/components/device/pill.js +1 -0
- package/app/components/driver/pill.js +1 -0
- package/app/components/map/drawer/device-event-listing.js +1 -0
- package/app/components/map/drawer/position-listing.js +1 -0
- package/app/components/modals/attach-device.js +1 -0
- package/app/components/order/pill.js +1 -0
- package/app/components/positions-replay.js +1 -0
- package/app/components/sensor/panel-header.js +1 -0
- package/app/components/vehicle/pill.js +1 -0
- package/app/helpers/get-fleet-ops-option-label.js +1 -0
- package/app/routes/management/drivers/index/details/positions.js +1 -0
- package/app/routes/management/vehicles/index/details/positions.js +1 -0
- package/app/services/position-playback.js +1 -0
- package/app/services/resource-metadata.js +1 -0
- package/app/templates/management/drivers/index/details/positions.js +1 -0
- package/app/templates/management/vehicles/index/details/positions.js +1 -0
- package/composer.json +1 -1
- package/extension.json +1 -1
- package/package.json +4 -4
- package/server/config/telematics.php +111 -0
- package/server/migrations/2025_10_27_000001_add_telematics_integration_fields.php +70 -0
- package/server/migrations/2025_10_27_171322_fix_device_column_names.php +107 -0
- package/server/migrations/2025_10_27_203023_add_company_uuid_to_device_events_table.php +28 -0
- package/server/src/Console/Commands/ReplayVehicleLocations.php +225 -0
- package/server/src/Contracts/TelematicProviderDescriptor.php +72 -0
- package/server/src/Contracts/TelematicProviderInterface.php +119 -0
- package/server/src/Exceptions/TelematicProviderException.php +14 -0
- package/server/src/Exceptions/TelematicRateLimitExceededException.php +12 -0
- package/server/src/Http/Controllers/Api/v1/DriverController.php +24 -14
- package/server/src/Http/Controllers/Api/v1/VehicleController.php +27 -7
- package/server/src/Http/Controllers/Internal/v1/DeviceController.php +22 -0
- package/server/src/Http/Controllers/Internal/v1/PositionController.php +240 -0
- package/server/src/Http/Controllers/Internal/v1/SensorController.php +11 -0
- package/server/src/Http/Controllers/Internal/v1/TelematicController.php +141 -0
- package/server/src/Http/Controllers/TelematicWebhookController.php +169 -0
- package/server/src/Http/Filter/DeviceEventFilter.php +68 -0
- package/server/src/Http/Filter/PositionFilter.php +35 -0
- package/server/src/Http/Resources/v1/Position.php +44 -0
- package/server/src/Jobs/ReplayPositions.php +64 -0
- package/server/src/Jobs/SendPositionReplay.php +65 -0
- package/server/src/Jobs/SyncTelematicDevicesJob.php +106 -0
- package/server/src/Jobs/TestTelematicConnectionJob.php +102 -0
- package/server/src/Models/Asset.php +10 -8
- package/server/src/Models/Device.php +79 -12
- package/server/src/Models/DeviceEvent.php +33 -3
- package/server/src/Models/Driver.php +28 -1
- package/server/src/Models/Maintenance.php +15 -12
- package/server/src/Models/Part.php +2 -0
- package/server/src/Models/Payload.php +0 -1
- package/server/src/Models/Place.php +4 -1
- package/server/src/Models/Position.php +27 -17
- package/server/src/Models/Sensor.php +78 -13
- package/server/src/Models/Telematic.php +116 -6
- package/server/src/Models/TrackingNumber.php +3 -1
- package/server/src/Models/Vehicle.php +8 -11
- package/server/src/Models/WorkOrder.php +8 -5
- package/server/src/Providers/FleetOpsServiceProvider.php +2 -0
- package/server/src/Support/Telematics/Providers/AbstractProvider.php +151 -0
- package/server/src/Support/Telematics/Providers/FlespiProvider.php +182 -0
- package/server/src/Support/Telematics/Providers/GeotabProvider.php +181 -0
- package/server/src/Support/Telematics/Providers/SamsaraProvider.php +177 -0
- package/server/src/Support/Telematics/TelematicProviderRegistry.php +147 -0
- package/server/src/Support/Telematics/TelematicService.php +223 -0
- package/server/src/Support/Utils.php +1 -1
- package/server/src/routes.php +24 -1
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
namespace Fleetbase\FleetOps\Models;
|
|
4
4
|
|
|
5
5
|
use Fleetbase\Casts\Json;
|
|
6
|
+
use Fleetbase\Casts\PolymorphicType;
|
|
7
|
+
use Fleetbase\FleetOps\Casts\Point;
|
|
8
|
+
use Fleetbase\LaravelMysqlSpatial\Eloquent\SpatialTrait;
|
|
9
|
+
use Fleetbase\LaravelMysqlSpatial\Types\Point as SpatialPoint;
|
|
10
|
+
use Fleetbase\Models\File;
|
|
6
11
|
use Fleetbase\Models\Model;
|
|
7
12
|
use Fleetbase\Models\User;
|
|
8
13
|
use Fleetbase\Traits\HasApiModelBehavior;
|
|
@@ -15,6 +20,8 @@ use Fleetbase\Traits\TracksApiCredential;
|
|
|
15
20
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
16
21
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
17
22
|
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
|
23
|
+
use Illuminate\Support\Arr;
|
|
24
|
+
use Illuminate\Support\Str;
|
|
18
25
|
use Spatie\Activitylog\LogOptions;
|
|
19
26
|
use Spatie\Activitylog\Traits\LogsActivity;
|
|
20
27
|
use Spatie\Sluggable\HasSlug;
|
|
@@ -37,6 +44,7 @@ class Device extends Model
|
|
|
37
44
|
use HasMetaAttributes;
|
|
38
45
|
use Searchable;
|
|
39
46
|
use HasCustomFields;
|
|
47
|
+
use SpatialTrait;
|
|
40
48
|
|
|
41
49
|
/**
|
|
42
50
|
* The database table used by the model.
|
|
@@ -57,7 +65,7 @@ class Device extends Model
|
|
|
57
65
|
*
|
|
58
66
|
* @var array
|
|
59
67
|
*/
|
|
60
|
-
protected $searchableColumns = ['name', 'model', 'serial_number', 'public_id'];
|
|
68
|
+
protected $searchableColumns = ['name', 'model', 'serial_number', 'manufacturer', 'public_id'];
|
|
61
69
|
|
|
62
70
|
/**
|
|
63
71
|
* The attributes that can be used for filtering.
|
|
@@ -74,15 +82,23 @@ class Device extends Model
|
|
|
74
82
|
protected $fillable = [
|
|
75
83
|
'company_uuid',
|
|
76
84
|
'telematic_uuid',
|
|
85
|
+
'attachable_uuid',
|
|
86
|
+
'attachable_type',
|
|
77
87
|
'warranty_uuid',
|
|
78
|
-
'
|
|
88
|
+
'photo_uuid',
|
|
89
|
+
'type',
|
|
79
90
|
'device_id',
|
|
80
|
-
'
|
|
81
|
-
'
|
|
82
|
-
'
|
|
83
|
-
'
|
|
91
|
+
'internal_id',
|
|
92
|
+
'imei',
|
|
93
|
+
'imsi',
|
|
94
|
+
'firmware_version',
|
|
95
|
+
'provider',
|
|
96
|
+
'name',
|
|
97
|
+
'model',
|
|
98
|
+
'location',
|
|
84
99
|
'manufacturer',
|
|
85
100
|
'serial_number',
|
|
101
|
+
'last_position',
|
|
86
102
|
'installation_date',
|
|
87
103
|
'last_maintenance_date',
|
|
88
104
|
'meta',
|
|
@@ -94,8 +110,6 @@ class Device extends Model
|
|
|
94
110
|
'notes',
|
|
95
111
|
'status',
|
|
96
112
|
'last_online_at',
|
|
97
|
-
'attachable_type',
|
|
98
|
-
'attachable_uuid',
|
|
99
113
|
'slug',
|
|
100
114
|
];
|
|
101
115
|
|
|
@@ -110,6 +124,7 @@ class Device extends Model
|
|
|
110
124
|
'is_online',
|
|
111
125
|
'attached_to_name',
|
|
112
126
|
'connection_status',
|
|
127
|
+
'photo_url',
|
|
113
128
|
];
|
|
114
129
|
|
|
115
130
|
/**
|
|
@@ -117,7 +132,14 @@ class Device extends Model
|
|
|
117
132
|
*
|
|
118
133
|
* @var array
|
|
119
134
|
*/
|
|
120
|
-
protected $hidden = [
|
|
135
|
+
protected $hidden = [];
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* The attributes that are spatial columns.
|
|
139
|
+
*
|
|
140
|
+
* @var array
|
|
141
|
+
*/
|
|
142
|
+
protected $spatialFields = ['last_position'];
|
|
121
143
|
|
|
122
144
|
/**
|
|
123
145
|
* The attributes that should be cast to native types.
|
|
@@ -125,9 +147,14 @@ class Device extends Model
|
|
|
125
147
|
* @var array
|
|
126
148
|
*/
|
|
127
149
|
protected $casts = [
|
|
128
|
-
'
|
|
129
|
-
'
|
|
130
|
-
'
|
|
150
|
+
'installation_date' => 'date',
|
|
151
|
+
'last_maintenance_date' => 'date',
|
|
152
|
+
'last_online_at' => 'datetime',
|
|
153
|
+
'last_position' => Point::class,
|
|
154
|
+
'meta' => Json::class,
|
|
155
|
+
'options' => Json::class,
|
|
156
|
+
'data' => Json::class,
|
|
157
|
+
'attachable_type' => PolymorphicType::class,
|
|
131
158
|
];
|
|
132
159
|
|
|
133
160
|
/**
|
|
@@ -204,6 +231,21 @@ class Device extends Model
|
|
|
204
231
|
return $this->hasMany(Sensor::class, 'device_uuid', 'uuid');
|
|
205
232
|
}
|
|
206
233
|
|
|
234
|
+
public function photo(): BelongsTo
|
|
235
|
+
{
|
|
236
|
+
return $this->belongsTo(File::class);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Get photo URL attribute.
|
|
241
|
+
*
|
|
242
|
+
* @return string
|
|
243
|
+
*/
|
|
244
|
+
public function getPhotoUrlAttribute()
|
|
245
|
+
{
|
|
246
|
+
return data_get($this, 'photo.url', 'https://flb-assets.s3.ap-southeast-1.amazonaws.com/static/image-file-icon.png');
|
|
247
|
+
}
|
|
248
|
+
|
|
207
249
|
/**
|
|
208
250
|
* Get the warranty name.
|
|
209
251
|
*/
|
|
@@ -432,4 +474,29 @@ class Device extends Model
|
|
|
432
474
|
->limit($limit)
|
|
433
475
|
->get();
|
|
434
476
|
}
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* Creates a new position for the vehicle.
|
|
480
|
+
*/
|
|
481
|
+
public function createPosition(array $attributes = [], Model|string|null $destination = null): ?Position
|
|
482
|
+
{
|
|
483
|
+
if (!isset($attributes['coordinates']) && isset($attributes['location'])) {
|
|
484
|
+
$attributes['coordinates'] = $attributes['location'];
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
if (!isset($attributes['coordinates']) && isset($attributes['latitude']) && isset($attributes['longitude'])) {
|
|
488
|
+
$attributes['coordinates'] = new SpatialPoint($attributes['latitude'], $attributes['longitude']);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// handle destination if set
|
|
492
|
+
$destinationUuid = Str::isUuid($destination) ? $destination : data_get($destination, 'uuid');
|
|
493
|
+
|
|
494
|
+
return Position::create([
|
|
495
|
+
...Arr::only($attributes, ['coordinates', 'heading', 'bearing', 'speed', 'altitude', 'order_uuid']),
|
|
496
|
+
'subject_uuid' => $this->uuid,
|
|
497
|
+
'subject_type' => $this->getMorphClass(),
|
|
498
|
+
'company_uuid' => $this->company_uuid,
|
|
499
|
+
'destination_uuid' => $destinationUuid,
|
|
500
|
+
]);
|
|
501
|
+
}
|
|
435
502
|
}
|
|
@@ -4,6 +4,7 @@ namespace Fleetbase\FleetOps\Models;
|
|
|
4
4
|
|
|
5
5
|
use Fleetbase\Casts\Json;
|
|
6
6
|
use Fleetbase\Models\Alert;
|
|
7
|
+
use Fleetbase\Models\Company;
|
|
7
8
|
use Fleetbase\Models\Model;
|
|
8
9
|
use Fleetbase\Models\User;
|
|
9
10
|
use Fleetbase\Traits\HasApiModelBehavior;
|
|
@@ -67,6 +68,7 @@ class DeviceEvent extends Model
|
|
|
67
68
|
* @var array
|
|
68
69
|
*/
|
|
69
70
|
protected $fillable = [
|
|
71
|
+
'company_uuid',
|
|
70
72
|
'device_uuid',
|
|
71
73
|
'payload',
|
|
72
74
|
'meta',
|
|
@@ -81,6 +83,7 @@ class DeviceEvent extends Model
|
|
|
81
83
|
'code',
|
|
82
84
|
'reason',
|
|
83
85
|
'comment',
|
|
86
|
+
'resolved_at',
|
|
84
87
|
'slug',
|
|
85
88
|
];
|
|
86
89
|
|
|
@@ -109,9 +112,9 @@ class DeviceEvent extends Model
|
|
|
109
112
|
* @var array
|
|
110
113
|
*/
|
|
111
114
|
protected $casts = [
|
|
112
|
-
'
|
|
113
|
-
'
|
|
114
|
-
'
|
|
115
|
+
'payload' => Json::class,
|
|
116
|
+
'meta' => Json::class,
|
|
117
|
+
'resolved_at' => 'datetime',
|
|
115
118
|
];
|
|
116
119
|
|
|
117
120
|
/**
|
|
@@ -143,6 +146,11 @@ class DeviceEvent extends Model
|
|
|
143
146
|
return LogOptions::defaults()->logAll();
|
|
144
147
|
}
|
|
145
148
|
|
|
149
|
+
public function company(): BelongsTo
|
|
150
|
+
{
|
|
151
|
+
return $this->belongsTo(Company::class, 'company_uuid', 'uuid');
|
|
152
|
+
}
|
|
153
|
+
|
|
146
154
|
public function device(): BelongsTo
|
|
147
155
|
{
|
|
148
156
|
return $this->belongsTo(Device::class, 'device_uuid', 'uuid');
|
|
@@ -498,4 +506,26 @@ class DeviceEvent extends Model
|
|
|
498
506
|
'created_at' => $this->created_at?->toISOString(),
|
|
499
507
|
];
|
|
500
508
|
}
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* Create a Position for this event’s device attachable using position data.
|
|
512
|
+
*
|
|
513
|
+
* This delegates to the shared DeviceEventHelper utility.
|
|
514
|
+
*/
|
|
515
|
+
public function createPosition(array $positionData = []): ?Position
|
|
516
|
+
{
|
|
517
|
+
if (empty($positionData)) {
|
|
518
|
+
return null;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
// Ensure device and attachable are loaded
|
|
522
|
+
$this->loadMissing('device.attachable');
|
|
523
|
+
$attachable = $this->device?->attachable;
|
|
524
|
+
|
|
525
|
+
if ($attachable && method_exists($attachable, 'createPosition')) {
|
|
526
|
+
return $attachable->createPosition($positionData);
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
return null;
|
|
530
|
+
}
|
|
501
531
|
}
|
|
@@ -8,6 +8,7 @@ use Fleetbase\FleetOps\Scopes\DriverScope;
|
|
|
8
8
|
use Fleetbase\FleetOps\Support\Utils;
|
|
9
9
|
use Fleetbase\FleetOps\Support\Utils as FleetOpsUtils;
|
|
10
10
|
use Fleetbase\LaravelMysqlSpatial\Eloquent\SpatialTrait;
|
|
11
|
+
use Fleetbase\LaravelMysqlSpatial\Types\Point as SpatialPoint;
|
|
11
12
|
use Fleetbase\Models\File;
|
|
12
13
|
use Fleetbase\Models\Model;
|
|
13
14
|
use Fleetbase\Models\User;
|
|
@@ -24,6 +25,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
|
24
25
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
25
26
|
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
|
|
26
27
|
use Illuminate\Notifications\Notifiable;
|
|
28
|
+
use Illuminate\Support\Arr;
|
|
27
29
|
use Illuminate\Support\Collection;
|
|
28
30
|
use Illuminate\Support\Facades\DB;
|
|
29
31
|
use Illuminate\Support\Str;
|
|
@@ -645,7 +647,7 @@ class Driver extends Model
|
|
|
645
647
|
$positionData = [
|
|
646
648
|
'company_uuid' => session('company', $this->company_uuid),
|
|
647
649
|
'subject_uuid' => $this->uuid,
|
|
648
|
-
'subject_type' =>
|
|
650
|
+
'subject_type' => $this->getMorphClass(),
|
|
649
651
|
'coordinates' => $this->location,
|
|
650
652
|
'altitude' => $this->altitude,
|
|
651
653
|
'heading' => $this->heading,
|
|
@@ -661,6 +663,31 @@ class Driver extends Model
|
|
|
661
663
|
return ($isFirstPosition || $isPast50Meters) ? Position::create($positionData) : null;
|
|
662
664
|
}
|
|
663
665
|
|
|
666
|
+
/**
|
|
667
|
+
* Creates a new position for the vehicle.
|
|
668
|
+
*/
|
|
669
|
+
public function createPosition(array $attributes = [], Model|string|null $destination = null): ?Position
|
|
670
|
+
{
|
|
671
|
+
if (!isset($attributes['coordinates']) && isset($attributes['location'])) {
|
|
672
|
+
$attributes['coordinates'] = $attributes['location'];
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
if (!isset($attributes['coordinates']) && isset($attributes['latitude']) && isset($attributes['longitude'])) {
|
|
676
|
+
$attributes['coordinates'] = new SpatialPoint($attributes['latitude'], $attributes['longitude']);
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
// handle destination if set
|
|
680
|
+
$destinationUuid = Str::isUuid($destination) ? $destination : data_get($destination, 'uuid');
|
|
681
|
+
|
|
682
|
+
return Position::create([
|
|
683
|
+
...Arr::only($attributes, ['coordinates', 'heading', 'bearing', 'speed', 'altitude', 'order_uuid']),
|
|
684
|
+
'subject_uuid' => $this->uuid,
|
|
685
|
+
'subject_type' => $this->getMorphClass(),
|
|
686
|
+
'company_uuid' => $this->company_uuid,
|
|
687
|
+
'destination_uuid' => $destinationUuid,
|
|
688
|
+
]);
|
|
689
|
+
}
|
|
690
|
+
|
|
664
691
|
/**
|
|
665
692
|
* Get the user relationship from the driver.
|
|
666
693
|
*/
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
namespace Fleetbase\FleetOps\Models;
|
|
4
4
|
|
|
5
5
|
use Fleetbase\Casts\Json;
|
|
6
|
+
use Fleetbase\Casts\PolymorphicType;
|
|
6
7
|
use Fleetbase\Models\Model;
|
|
7
8
|
use Fleetbase\Models\User;
|
|
8
9
|
use Fleetbase\Traits\HasApiModelBehavior;
|
|
@@ -122,18 +123,20 @@ class Maintenance extends Model
|
|
|
122
123
|
* @var array
|
|
123
124
|
*/
|
|
124
125
|
protected $casts = [
|
|
125
|
-
'scheduled_at'
|
|
126
|
-
'started_at'
|
|
127
|
-
'completed_at'
|
|
128
|
-
'odometer'
|
|
129
|
-
'engine_hours'
|
|
130
|
-
'labor_cost'
|
|
131
|
-
'parts_cost'
|
|
132
|
-
'tax'
|
|
133
|
-
'total_cost'
|
|
134
|
-
'line_items'
|
|
135
|
-
'attachments'
|
|
136
|
-
'meta'
|
|
126
|
+
'scheduled_at' => 'datetime',
|
|
127
|
+
'started_at' => 'datetime',
|
|
128
|
+
'completed_at' => 'datetime',
|
|
129
|
+
'odometer' => 'integer',
|
|
130
|
+
'engine_hours' => 'integer',
|
|
131
|
+
'labor_cost' => 'decimal:2',
|
|
132
|
+
'parts_cost' => 'decimal:2',
|
|
133
|
+
'tax' => 'decimal:2',
|
|
134
|
+
'total_cost' => 'decimal:2',
|
|
135
|
+
'line_items' => Json::class,
|
|
136
|
+
'attachments' => Json::class,
|
|
137
|
+
'meta' => Json::class,
|
|
138
|
+
'maintainable_type' => PolymorphicType::class,
|
|
139
|
+
'performed_by_type' => PolymorphicType::class,
|
|
137
140
|
];
|
|
138
141
|
|
|
139
142
|
/**
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
namespace Fleetbase\FleetOps\Models;
|
|
4
4
|
|
|
5
5
|
use Fleetbase\Casts\Json;
|
|
6
|
+
use Fleetbase\Casts\PolymorphicType;
|
|
6
7
|
use Fleetbase\FleetOps\Traits\Maintainable;
|
|
7
8
|
use Fleetbase\Models\Alert;
|
|
8
9
|
use Fleetbase\Models\File;
|
|
@@ -129,6 +130,7 @@ class Part extends Model
|
|
|
129
130
|
'msrp' => 'decimal:2',
|
|
130
131
|
'specs' => Json::class,
|
|
131
132
|
'meta' => Json::class,
|
|
133
|
+
'asset_type' => PolymorphicType::class,
|
|
132
134
|
];
|
|
133
135
|
|
|
134
136
|
/**
|
|
@@ -388,7 +388,6 @@ class Payload extends Model
|
|
|
388
388
|
} else {
|
|
389
389
|
$place = Place::createFromMixed($attributes);
|
|
390
390
|
|
|
391
|
-
|
|
392
391
|
// Store temp search UUID for traceability if present and different
|
|
393
392
|
if ($place instanceof Place && isset($attributes['uuid']) && $place->uuid !== $attributes['uuid']) {
|
|
394
393
|
$place->updateMeta('search_uuid', $attributes['uuid']);
|
|
@@ -366,6 +366,7 @@ class Place extends Model
|
|
|
366
366
|
if ($saveInstance) {
|
|
367
367
|
$place->save();
|
|
368
368
|
}
|
|
369
|
+
|
|
369
370
|
return $place;
|
|
370
371
|
}
|
|
371
372
|
|
|
@@ -554,8 +555,10 @@ class Place extends Model
|
|
|
554
555
|
}
|
|
555
556
|
|
|
556
557
|
// If has $attributes['address']
|
|
558
|
+
$address = $place['address'];
|
|
557
559
|
if (!empty($place['address'])) {
|
|
558
|
-
return static::createFromGeocodingLookup($place['address'], $saveInstance);
|
|
560
|
+
// return static::createFromGeocodingLookup($place['address'], $saveInstance);
|
|
561
|
+
return static::create(array_merge($place, static::getValuesFromGeocodingLookup($address)));
|
|
559
562
|
}
|
|
560
563
|
|
|
561
564
|
// Perform google lookup to fill address
|
|
@@ -2,11 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
namespace Fleetbase\FleetOps\Models;
|
|
4
4
|
|
|
5
|
+
use Fleetbase\Casts\PolymorphicType;
|
|
5
6
|
use Fleetbase\LaravelMysqlSpatial\Eloquent\SpatialTrait;
|
|
6
7
|
use Fleetbase\Models\Model;
|
|
7
8
|
use Fleetbase\Traits\HasApiModelBehavior;
|
|
8
9
|
use Fleetbase\Traits\HasUuid;
|
|
9
10
|
use Fleetbase\Traits\TracksApiCredential;
|
|
11
|
+
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
12
|
+
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
|
10
13
|
|
|
11
14
|
class Position extends Model
|
|
12
15
|
{
|
|
@@ -48,7 +51,16 @@ class Position extends Model
|
|
|
48
51
|
*
|
|
49
52
|
* @var array
|
|
50
53
|
*/
|
|
51
|
-
protected $appends = [];
|
|
54
|
+
protected $appends = ['latitude', 'longitude'];
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The attributes that should be cast to native types.
|
|
58
|
+
*
|
|
59
|
+
* @var array
|
|
60
|
+
*/
|
|
61
|
+
protected $casts = [
|
|
62
|
+
'subject_type' => PolymorphicType::class,
|
|
63
|
+
];
|
|
52
64
|
|
|
53
65
|
/**
|
|
54
66
|
* Get filter parameters for this model.
|
|
@@ -85,35 +97,33 @@ class Position extends Model
|
|
|
85
97
|
*/
|
|
86
98
|
protected static $logName = 'position';
|
|
87
99
|
|
|
88
|
-
|
|
89
|
-
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
|
90
|
-
*/
|
|
91
|
-
public function company()
|
|
100
|
+
public function company(): BelongsTo
|
|
92
101
|
{
|
|
93
102
|
return $this->belongsTo(\Fleetbase\Models\Company::class);
|
|
94
103
|
}
|
|
95
104
|
|
|
96
|
-
|
|
97
|
-
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
|
98
|
-
*/
|
|
99
|
-
public function order()
|
|
105
|
+
public function order(): BelongsTo
|
|
100
106
|
{
|
|
101
107
|
return $this->belongsTo(Order::class);
|
|
102
108
|
}
|
|
103
109
|
|
|
104
|
-
|
|
105
|
-
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
|
106
|
-
*/
|
|
107
|
-
public function destination()
|
|
110
|
+
public function destination(): BelongsTo
|
|
108
111
|
{
|
|
109
112
|
return $this->belongsTo(Place::class);
|
|
110
113
|
}
|
|
111
114
|
|
|
112
|
-
|
|
113
|
-
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
|
|
114
|
-
*/
|
|
115
|
-
public function subject()
|
|
115
|
+
public function subject(): MorphTo
|
|
116
116
|
{
|
|
117
117
|
return $this->morphTo(__FUNCTION__, 'subject_type', 'subject_uuid')->withoutGlobalScopes();
|
|
118
118
|
}
|
|
119
|
+
|
|
120
|
+
public function getLongitudeAttribute(): float
|
|
121
|
+
{
|
|
122
|
+
return $this->coordinates?->getLng() ?? 0;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
public function getLatitudeAttribute(): float
|
|
126
|
+
{
|
|
127
|
+
return $this->coordinates?->getLat() ?? 0;
|
|
128
|
+
}
|
|
119
129
|
}
|
|
@@ -3,7 +3,11 @@
|
|
|
3
3
|
namespace Fleetbase\FleetOps\Models;
|
|
4
4
|
|
|
5
5
|
use Fleetbase\Casts\Json;
|
|
6
|
+
use Fleetbase\FleetOps\Casts\Point;
|
|
7
|
+
use Fleetbase\LaravelMysqlSpatial\Eloquent\SpatialTrait;
|
|
8
|
+
use Fleetbase\LaravelMysqlSpatial\Types\Point as SpatialPoint;
|
|
6
9
|
use Fleetbase\Models\Alert;
|
|
10
|
+
use Fleetbase\Models\File;
|
|
7
11
|
use Fleetbase\Models\Model;
|
|
8
12
|
use Fleetbase\Models\User;
|
|
9
13
|
use Fleetbase\Traits\HasApiModelBehavior;
|
|
@@ -16,6 +20,8 @@ use Fleetbase\Traits\TracksApiCredential;
|
|
|
16
20
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
17
21
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
18
22
|
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
|
23
|
+
use Illuminate\Support\Arr;
|
|
24
|
+
use Illuminate\Support\Str;
|
|
19
25
|
use Spatie\Activitylog\LogOptions;
|
|
20
26
|
use Spatie\Activitylog\Traits\LogsActivity;
|
|
21
27
|
use Spatie\Sluggable\HasSlug;
|
|
@@ -39,6 +45,7 @@ class Sensor extends Model
|
|
|
39
45
|
use HasMetaAttributes;
|
|
40
46
|
use Searchable;
|
|
41
47
|
use HasCustomFields;
|
|
48
|
+
use SpatialTrait;
|
|
42
49
|
|
|
43
50
|
/**
|
|
44
51
|
* The database table used by the model.
|
|
@@ -77,8 +84,16 @@ class Sensor extends Model
|
|
|
77
84
|
'company_uuid',
|
|
78
85
|
'device_uuid',
|
|
79
86
|
'warranty_uuid',
|
|
87
|
+
'telematic_uuid',
|
|
88
|
+
'photo_uuid',
|
|
80
89
|
'name',
|
|
81
|
-
'
|
|
90
|
+
'type',
|
|
91
|
+
'internal_id',
|
|
92
|
+
'imei',
|
|
93
|
+
'imsi',
|
|
94
|
+
'firmware_version',
|
|
95
|
+
'serial_number',
|
|
96
|
+
'last_position',
|
|
82
97
|
'unit',
|
|
83
98
|
'min_threshold',
|
|
84
99
|
'max_threshold',
|
|
@@ -100,12 +115,9 @@ class Sensor extends Model
|
|
|
100
115
|
* @var array
|
|
101
116
|
*/
|
|
102
117
|
protected $appends = [
|
|
103
|
-
'device_name',
|
|
104
|
-
'warranty_name',
|
|
105
|
-
'attached_to_name',
|
|
106
118
|
'is_active',
|
|
107
119
|
'threshold_status',
|
|
108
|
-
'
|
|
120
|
+
'photo_url',
|
|
109
121
|
];
|
|
110
122
|
|
|
111
123
|
/**
|
|
@@ -113,7 +125,14 @@ class Sensor extends Model
|
|
|
113
125
|
*
|
|
114
126
|
* @var array
|
|
115
127
|
*/
|
|
116
|
-
protected $hidden = [
|
|
128
|
+
protected $hidden = [];
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* The attributes that are spatial columns.
|
|
132
|
+
*
|
|
133
|
+
* @var array
|
|
134
|
+
*/
|
|
135
|
+
protected $spatialFields = ['last_position'];
|
|
117
136
|
|
|
118
137
|
/**
|
|
119
138
|
* The attributes that should be cast to native types.
|
|
@@ -121,13 +140,14 @@ class Sensor extends Model
|
|
|
121
140
|
* @var array
|
|
122
141
|
*/
|
|
123
142
|
protected $casts = [
|
|
124
|
-
'min_threshold'
|
|
125
|
-
'max_threshold'
|
|
126
|
-
'threshold_inclusive'
|
|
127
|
-
'last_reading_at'
|
|
128
|
-
'report_frequency_sec'
|
|
129
|
-
'
|
|
130
|
-
'
|
|
143
|
+
'min_threshold' => 'float',
|
|
144
|
+
'max_threshold' => 'float',
|
|
145
|
+
'threshold_inclusive' => 'boolean',
|
|
146
|
+
'last_reading_at' => 'datetime',
|
|
147
|
+
'report_frequency_sec' => 'integer',
|
|
148
|
+
'last_position' => Point::class,
|
|
149
|
+
'calibration' => Json::class,
|
|
150
|
+
'meta' => Json::class,
|
|
131
151
|
];
|
|
132
152
|
|
|
133
153
|
/**
|
|
@@ -169,6 +189,11 @@ class Sensor extends Model
|
|
|
169
189
|
return LogOptions::defaults()->logAll();
|
|
170
190
|
}
|
|
171
191
|
|
|
192
|
+
public function telematic(): BelongsTo
|
|
193
|
+
{
|
|
194
|
+
return $this->belongsTo(Telematic::class, 'telematic_uuid', 'uuid');
|
|
195
|
+
}
|
|
196
|
+
|
|
172
197
|
public function device(): BelongsTo
|
|
173
198
|
{
|
|
174
199
|
return $this->belongsTo(Device::class, 'device_uuid', 'uuid');
|
|
@@ -194,12 +219,27 @@ class Sensor extends Model
|
|
|
194
219
|
return $this->morphTo();
|
|
195
220
|
}
|
|
196
221
|
|
|
222
|
+
public function photo(): BelongsTo
|
|
223
|
+
{
|
|
224
|
+
return $this->belongsTo(File::class);
|
|
225
|
+
}
|
|
226
|
+
|
|
197
227
|
public function alerts(): HasMany
|
|
198
228
|
{
|
|
199
229
|
return $this->hasMany(Alert::class, 'subject_uuid', 'uuid')
|
|
200
230
|
->where('subject_type', static::class);
|
|
201
231
|
}
|
|
202
232
|
|
|
233
|
+
/**
|
|
234
|
+
* Get photo URL attribute.
|
|
235
|
+
*
|
|
236
|
+
* @return string
|
|
237
|
+
*/
|
|
238
|
+
public function getPhotoUrlAttribute()
|
|
239
|
+
{
|
|
240
|
+
return data_get($this, 'photo.url', 'https://flb-assets.s3.ap-southeast-1.amazonaws.com/static/image-file-icon.png');
|
|
241
|
+
}
|
|
242
|
+
|
|
203
243
|
/**
|
|
204
244
|
* Get the device name.
|
|
205
245
|
*/
|
|
@@ -507,4 +547,29 @@ class Sensor extends Model
|
|
|
507
547
|
],
|
|
508
548
|
];
|
|
509
549
|
}
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* Creates a new position for the vehicle.
|
|
553
|
+
*/
|
|
554
|
+
public function createPosition(array $attributes = [], Model|string|null $destination = null): ?Position
|
|
555
|
+
{
|
|
556
|
+
if (!isset($attributes['coordinates']) && isset($attributes['location'])) {
|
|
557
|
+
$attributes['coordinates'] = $attributes['location'];
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
if (!isset($attributes['coordinates']) && isset($attributes['latitude']) && isset($attributes['longitude'])) {
|
|
561
|
+
$attributes['coordinates'] = new SpatialPoint($attributes['latitude'], $attributes['longitude']);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
// handle destination if set
|
|
565
|
+
$destinationUuid = Str::isUuid($destination) ? $destination : data_get($destination, 'uuid');
|
|
566
|
+
|
|
567
|
+
return Position::create([
|
|
568
|
+
...Arr::only($attributes, ['coordinates', 'heading', 'bearing', 'speed', 'altitude', 'order_uuid']),
|
|
569
|
+
'subject_uuid' => $this->uuid,
|
|
570
|
+
'subject_type' => $this->getMorphClass(),
|
|
571
|
+
'company_uuid' => $this->company_uuid,
|
|
572
|
+
'destination_uuid' => $destinationUuid,
|
|
573
|
+
]);
|
|
574
|
+
}
|
|
510
575
|
}
|