@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,483 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\FleetOps\Models;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\Casts\Json;
|
|
6
|
+
use Fleetbase\Models\File;
|
|
7
|
+
use Fleetbase\Models\Model;
|
|
8
|
+
use Fleetbase\Models\User;
|
|
9
|
+
use Fleetbase\Traits\HasApiModelBehavior;
|
|
10
|
+
use Fleetbase\Traits\HasCustomFields;
|
|
11
|
+
use Fleetbase\Traits\HasMetaAttributes;
|
|
12
|
+
use Fleetbase\Traits\HasPublicId;
|
|
13
|
+
use Fleetbase\Traits\HasUuid;
|
|
14
|
+
use Fleetbase\Traits\Searchable;
|
|
15
|
+
use Fleetbase\Traits\TracksApiCredential;
|
|
16
|
+
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
17
|
+
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
18
|
+
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
|
19
|
+
use Spatie\Activitylog\LogOptions;
|
|
20
|
+
use Spatie\Activitylog\Traits\LogsActivity;
|
|
21
|
+
use Spatie\Sluggable\HasSlug;
|
|
22
|
+
use Spatie\Sluggable\SlugOptions;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Class Equipment.
|
|
26
|
+
*
|
|
27
|
+
* Represents auxiliary gear that can be assigned to assets or other entities.
|
|
28
|
+
* Examples include PPE, refrigeration units, tools, liftgates, and other equipment.
|
|
29
|
+
*/
|
|
30
|
+
class Equipment extends Model
|
|
31
|
+
{
|
|
32
|
+
use HasUuid;
|
|
33
|
+
use HasPublicId;
|
|
34
|
+
use TracksApiCredential;
|
|
35
|
+
use HasApiModelBehavior;
|
|
36
|
+
use HasSlug;
|
|
37
|
+
use LogsActivity;
|
|
38
|
+
use HasMetaAttributes;
|
|
39
|
+
use Searchable;
|
|
40
|
+
use HasCustomFields;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* The database table used by the model.
|
|
44
|
+
*
|
|
45
|
+
* @var string
|
|
46
|
+
*/
|
|
47
|
+
protected $table = 'equipments';
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* The type of public Id to generate.
|
|
51
|
+
*
|
|
52
|
+
* @var string
|
|
53
|
+
*/
|
|
54
|
+
protected $publicIdType = 'equipment';
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The attributes that can be queried.
|
|
58
|
+
*
|
|
59
|
+
* @var array
|
|
60
|
+
*/
|
|
61
|
+
protected $searchableColumns = ['name', 'code', 'type', 'serial_number', 'manufacturer', 'model', 'public_id'];
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* The attributes that can be used for filtering.
|
|
65
|
+
*
|
|
66
|
+
* @var array
|
|
67
|
+
*/
|
|
68
|
+
protected $filterParams = ['type', 'status', 'manufacturer', 'warranty_uuid', 'equipable_type'];
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* The attributes that are mass assignable.
|
|
72
|
+
*
|
|
73
|
+
* @var array
|
|
74
|
+
*/
|
|
75
|
+
protected $fillable = [
|
|
76
|
+
'company_uuid',
|
|
77
|
+
'warranty_uuid',
|
|
78
|
+
'photo_uuid',
|
|
79
|
+
'name',
|
|
80
|
+
'code',
|
|
81
|
+
'type',
|
|
82
|
+
'status',
|
|
83
|
+
'serial_number',
|
|
84
|
+
'manufacturer',
|
|
85
|
+
'model',
|
|
86
|
+
'equipable_type',
|
|
87
|
+
'equipable_uuid',
|
|
88
|
+
'purchased_at',
|
|
89
|
+
'purchase_price',
|
|
90
|
+
'meta',
|
|
91
|
+
'slug',
|
|
92
|
+
];
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Dynamic attributes that are appended to object.
|
|
96
|
+
*
|
|
97
|
+
* @var array
|
|
98
|
+
*/
|
|
99
|
+
protected $appends = [
|
|
100
|
+
'warranty_name',
|
|
101
|
+
'photo_url',
|
|
102
|
+
'equipped_to_name',
|
|
103
|
+
'is_equipped',
|
|
104
|
+
'age_in_days',
|
|
105
|
+
'depreciated_value',
|
|
106
|
+
];
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* The attributes excluded from the model's JSON form.
|
|
110
|
+
*
|
|
111
|
+
* @var array
|
|
112
|
+
*/
|
|
113
|
+
protected $hidden = ['warranty', 'photo', 'equipable'];
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* The attributes that should be cast to native types.
|
|
117
|
+
*
|
|
118
|
+
* @var array
|
|
119
|
+
*/
|
|
120
|
+
protected $casts = [
|
|
121
|
+
'purchased_at' => 'date',
|
|
122
|
+
'purchase_price' => 'decimal:2',
|
|
123
|
+
'meta' => Json::class,
|
|
124
|
+
];
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Properties which activity needs to be logged.
|
|
128
|
+
*
|
|
129
|
+
* @var array
|
|
130
|
+
*/
|
|
131
|
+
protected static $logAttributes = '*';
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Do not log empty changed.
|
|
135
|
+
*
|
|
136
|
+
* @var bool
|
|
137
|
+
*/
|
|
138
|
+
protected static $submitEmptyLogs = false;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* The name of the subject to log.
|
|
142
|
+
*
|
|
143
|
+
* @var string
|
|
144
|
+
*/
|
|
145
|
+
protected static $logName = 'equipment';
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Get the options for generating the slug.
|
|
149
|
+
*/
|
|
150
|
+
public function getSlugOptions(): SlugOptions
|
|
151
|
+
{
|
|
152
|
+
return SlugOptions::create()
|
|
153
|
+
->generateSlugsFrom(['name', 'code'])
|
|
154
|
+
->saveSlugsTo('slug');
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Get the activity log options for the model.
|
|
159
|
+
*/
|
|
160
|
+
public function getActivitylogOptions(): LogOptions
|
|
161
|
+
{
|
|
162
|
+
return LogOptions::defaults()->logAll();
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
public function warranty(): BelongsTo
|
|
166
|
+
{
|
|
167
|
+
return $this->belongsTo(Warranty::class, 'warranty_uuid', 'uuid');
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
public function photo(): BelongsTo
|
|
171
|
+
{
|
|
172
|
+
return $this->belongsTo(File::class, 'photo_uuid', 'uuid');
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
public function createdBy(): BelongsTo
|
|
176
|
+
{
|
|
177
|
+
return $this->belongsTo(User::class, 'created_by_uuid', 'uuid');
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
public function updatedBy(): BelongsTo
|
|
181
|
+
{
|
|
182
|
+
return $this->belongsTo(User::class, 'updated_by_uuid', 'uuid');
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
public function equipable(): MorphTo
|
|
186
|
+
{
|
|
187
|
+
return $this->morphTo();
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
public function maintenances(): HasMany
|
|
191
|
+
{
|
|
192
|
+
return $this->hasMany(Maintenance::class, 'maintainable_uuid', 'uuid')
|
|
193
|
+
->where('maintainable_type', static::class);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Get the warranty name.
|
|
198
|
+
*/
|
|
199
|
+
public function getWarrantyNameAttribute(): ?string
|
|
200
|
+
{
|
|
201
|
+
return $this->warranty?->name;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Get the photo URL.
|
|
206
|
+
*/
|
|
207
|
+
public function getPhotoUrlAttribute(): ?string
|
|
208
|
+
{
|
|
209
|
+
return $this->photo?->url;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Get the name of what the equipment is equipped to.
|
|
214
|
+
*/
|
|
215
|
+
public function getEquippedToNameAttribute(): ?string
|
|
216
|
+
{
|
|
217
|
+
if ($this->equipable) {
|
|
218
|
+
return $this->equipable->name ?? $this->equipable->display_name ?? null;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Check if the equipment is currently equipped to something.
|
|
226
|
+
*/
|
|
227
|
+
public function getIsEquippedAttribute(): bool
|
|
228
|
+
{
|
|
229
|
+
return !is_null($this->equipable_uuid) && !is_null($this->equipable_type);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Get the age of the equipment in days.
|
|
234
|
+
*/
|
|
235
|
+
public function getAgeInDaysAttribute(): ?int
|
|
236
|
+
{
|
|
237
|
+
if ($this->purchased_at) {
|
|
238
|
+
return $this->purchased_at->diffInDays(now());
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return null;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Get the depreciated value of the equipment.
|
|
246
|
+
*/
|
|
247
|
+
public function getDepreciatedValueAttribute(): ?float
|
|
248
|
+
{
|
|
249
|
+
if (!$this->purchase_price || !$this->purchased_at) {
|
|
250
|
+
return null;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
$meta = $this->meta ?? [];
|
|
254
|
+
$depreciationRate = $meta['depreciation_rate'] ?? 0.1; // 10% per year default
|
|
255
|
+
$yearsOld = $this->purchased_at->diffInYears(now());
|
|
256
|
+
|
|
257
|
+
$depreciatedAmount = $this->purchase_price * ($depreciationRate * $yearsOld);
|
|
258
|
+
$currentValue = $this->purchase_price - $depreciatedAmount;
|
|
259
|
+
|
|
260
|
+
return max($currentValue, 0); // Don't go below 0
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Scope to get equipment by type.
|
|
265
|
+
*
|
|
266
|
+
* @param \Illuminate\Database\Eloquent\Builder $query
|
|
267
|
+
*
|
|
268
|
+
* @return \Illuminate\Database\Eloquent\Builder
|
|
269
|
+
*/
|
|
270
|
+
public function scopeByType($query, string $type)
|
|
271
|
+
{
|
|
272
|
+
return $query->where('type', $type);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Scope to get active equipment.
|
|
277
|
+
*
|
|
278
|
+
* @param \Illuminate\Database\Eloquent\Builder $query
|
|
279
|
+
*
|
|
280
|
+
* @return \Illuminate\Database\Eloquent\Builder
|
|
281
|
+
*/
|
|
282
|
+
public function scopeActive($query)
|
|
283
|
+
{
|
|
284
|
+
return $query->where('status', 'active');
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Scope to get equipped equipment.
|
|
289
|
+
*
|
|
290
|
+
* @param \Illuminate\Database\Eloquent\Builder $query
|
|
291
|
+
*
|
|
292
|
+
* @return \Illuminate\Database\Eloquent\Builder
|
|
293
|
+
*/
|
|
294
|
+
public function scopeEquipped($query)
|
|
295
|
+
{
|
|
296
|
+
return $query->whereNotNull('equipable_uuid')
|
|
297
|
+
->whereNotNull('equipable_type');
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Scope to get unequipped equipment.
|
|
302
|
+
*
|
|
303
|
+
* @param \Illuminate\Database\Eloquent\Builder $query
|
|
304
|
+
*
|
|
305
|
+
* @return \Illuminate\Database\Eloquent\Builder
|
|
306
|
+
*/
|
|
307
|
+
public function scopeUnequipped($query)
|
|
308
|
+
{
|
|
309
|
+
return $query->whereNull('equipable_uuid')
|
|
310
|
+
->orWhereNull('equipable_type');
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Scope to get equipment by manufacturer.
|
|
315
|
+
*
|
|
316
|
+
* @param \Illuminate\Database\Eloquent\Builder $query
|
|
317
|
+
*
|
|
318
|
+
* @return \Illuminate\Database\Eloquent\Builder
|
|
319
|
+
*/
|
|
320
|
+
public function scopeByManufacturer($query, string $manufacturer)
|
|
321
|
+
{
|
|
322
|
+
return $query->where('manufacturer', $manufacturer);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Equip this equipment to an entity.
|
|
327
|
+
*/
|
|
328
|
+
public function equipTo(Model $equipable): bool
|
|
329
|
+
{
|
|
330
|
+
$updated = $this->update([
|
|
331
|
+
'equipable_type' => get_class($equipable),
|
|
332
|
+
'equipable_uuid' => $equipable->uuid,
|
|
333
|
+
]);
|
|
334
|
+
|
|
335
|
+
if ($updated) {
|
|
336
|
+
activity('equipment_equipped')
|
|
337
|
+
->performedOn($this)
|
|
338
|
+
->withProperties([
|
|
339
|
+
'equipped_to_type' => get_class($equipable),
|
|
340
|
+
'equipped_to_uuid' => $equipable->uuid,
|
|
341
|
+
'equipped_to_name' => $equipable->name ?? $equipable->display_name ?? null,
|
|
342
|
+
])
|
|
343
|
+
->log('Equipment equipped');
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
return $updated;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Unequip this equipment.
|
|
351
|
+
*/
|
|
352
|
+
public function unequip(): bool
|
|
353
|
+
{
|
|
354
|
+
$oldEquipableType = $this->equipable_type;
|
|
355
|
+
$oldEquipableUuid = $this->equipable_uuid;
|
|
356
|
+
|
|
357
|
+
$updated = $this->update([
|
|
358
|
+
'equipable_type' => null,
|
|
359
|
+
'equipable_uuid' => null,
|
|
360
|
+
]);
|
|
361
|
+
|
|
362
|
+
if ($updated) {
|
|
363
|
+
activity('equipment_unequipped')
|
|
364
|
+
->performedOn($this)
|
|
365
|
+
->withProperties([
|
|
366
|
+
'previous_equipped_to_type' => $oldEquipableType,
|
|
367
|
+
'previous_equipped_to_uuid' => $oldEquipableUuid,
|
|
368
|
+
])
|
|
369
|
+
->log('Equipment unequipped');
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
return $updated;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Check if the equipment needs maintenance.
|
|
377
|
+
*/
|
|
378
|
+
public function needsMaintenance(): bool
|
|
379
|
+
{
|
|
380
|
+
// Check if there's overdue maintenance
|
|
381
|
+
$overdueMaintenance = $this->maintenances()
|
|
382
|
+
->where('status', 'scheduled')
|
|
383
|
+
->where('scheduled_at', '<', now())
|
|
384
|
+
->exists();
|
|
385
|
+
|
|
386
|
+
if ($overdueMaintenance) {
|
|
387
|
+
return true;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// Check maintenance intervals based on age or usage
|
|
391
|
+
$meta = $this->meta ?? [];
|
|
392
|
+
$maintenanceIntervalDays = $meta['maintenance_interval_days'] ?? null;
|
|
393
|
+
|
|
394
|
+
if ($maintenanceIntervalDays && $this->purchased_at) {
|
|
395
|
+
$lastMaintenance = $this->maintenances()
|
|
396
|
+
->where('status', 'completed')
|
|
397
|
+
->orderBy('completed_at', 'desc')
|
|
398
|
+
->first();
|
|
399
|
+
|
|
400
|
+
$lastMaintenanceDate = $lastMaintenance?->completed_at ?? $this->purchased_at;
|
|
401
|
+
$daysSinceLastMaintenance = $lastMaintenanceDate->diffInDays(now());
|
|
402
|
+
|
|
403
|
+
return $daysSinceLastMaintenance >= $maintenanceIntervalDays;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
return false;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Schedule maintenance for the equipment.
|
|
411
|
+
*/
|
|
412
|
+
public function scheduleMaintenance(string $type, \DateTime $scheduledAt, array $details = []): Maintenance
|
|
413
|
+
{
|
|
414
|
+
return Maintenance::create([
|
|
415
|
+
'company_uuid' => $this->company_uuid,
|
|
416
|
+
'maintainable_type' => static::class,
|
|
417
|
+
'maintainable_uuid' => $this->uuid,
|
|
418
|
+
'type' => $type,
|
|
419
|
+
'status' => 'scheduled',
|
|
420
|
+
'scheduled_at' => $scheduledAt,
|
|
421
|
+
'summary' => $details['summary'] ?? null,
|
|
422
|
+
'notes' => $details['notes'] ?? null,
|
|
423
|
+
'created_by_uuid' => auth()->id(),
|
|
424
|
+
]);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Get the utilization rate of the equipment.
|
|
429
|
+
*/
|
|
430
|
+
public function getUtilizationRate(int $days = 30): float
|
|
431
|
+
{
|
|
432
|
+
// This would calculate based on actual usage data
|
|
433
|
+
// For now, return a placeholder calculation based on equipped status
|
|
434
|
+
if ($this->is_equipped) {
|
|
435
|
+
return 75.0; // Assume 75% utilization when equipped
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
return 0.0;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Get the maintenance cost for a period.
|
|
443
|
+
*/
|
|
444
|
+
public function getMaintenanceCost(int $days = 365): float
|
|
445
|
+
{
|
|
446
|
+
$startDate = now()->subDays($days);
|
|
447
|
+
|
|
448
|
+
return $this->maintenances()
|
|
449
|
+
->where('status', 'completed')
|
|
450
|
+
->where('completed_at', '>=', $startDate)
|
|
451
|
+
->sum('total_cost') ?? 0;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Check if the equipment is under warranty.
|
|
456
|
+
*/
|
|
457
|
+
public function isUnderWarranty(): bool
|
|
458
|
+
{
|
|
459
|
+
return $this->warranty && $this->warranty->is_active;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* Get the replacement cost estimate.
|
|
464
|
+
*/
|
|
465
|
+
public function getReplacementCostEstimate(): ?float
|
|
466
|
+
{
|
|
467
|
+
$meta = $this->meta ?? [];
|
|
468
|
+
|
|
469
|
+
if (isset($meta['replacement_cost'])) {
|
|
470
|
+
return $meta['replacement_cost'];
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// Estimate based on purchase price with inflation
|
|
474
|
+
if ($this->purchase_price && $this->purchased_at) {
|
|
475
|
+
$yearsOld = $this->purchased_at->diffInYears(now());
|
|
476
|
+
$inflationRate = $meta['inflation_rate'] ?? 0.03; // 3% default
|
|
477
|
+
|
|
478
|
+
return $this->purchase_price * pow(1 + $inflationRate, $yearsOld);
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
return null;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
@@ -5,6 +5,7 @@ namespace Fleetbase\FleetOps\Models;
|
|
|
5
5
|
use Fleetbase\FleetOps\Support\Utils;
|
|
6
6
|
use Fleetbase\Models\Model;
|
|
7
7
|
use Fleetbase\Traits\HasApiModelBehavior;
|
|
8
|
+
use Fleetbase\Traits\HasCustomFields;
|
|
8
9
|
use Fleetbase\Traits\HasPublicId;
|
|
9
10
|
use Fleetbase\Traits\HasUuid;
|
|
10
11
|
use Fleetbase\Traits\Searchable;
|
|
@@ -27,6 +28,7 @@ class Fleet extends Model
|
|
|
27
28
|
use HasSlug;
|
|
28
29
|
use LogsActivity;
|
|
29
30
|
use Notifiable;
|
|
31
|
+
use HasCustomFields;
|
|
30
32
|
|
|
31
33
|
/**
|
|
32
34
|
* The database table used by the model.
|
|
@@ -9,6 +9,7 @@ use Fleetbase\LaravelMysqlSpatial\Eloquent\SpatialTrait;
|
|
|
9
9
|
use Fleetbase\Models\Model;
|
|
10
10
|
use Fleetbase\Models\User;
|
|
11
11
|
use Fleetbase\Traits\HasApiModelBehavior;
|
|
12
|
+
use Fleetbase\Traits\HasCustomFields;
|
|
12
13
|
use Fleetbase\Traits\HasPublicId;
|
|
13
14
|
use Fleetbase\Traits\HasUuid;
|
|
14
15
|
use Fleetbase\Traits\Searchable;
|
|
@@ -22,6 +23,7 @@ class FuelReport extends Model
|
|
|
22
23
|
use HasApiModelBehavior;
|
|
23
24
|
use SpatialTrait;
|
|
24
25
|
use Searchable;
|
|
26
|
+
use HasCustomFields;
|
|
25
27
|
|
|
26
28
|
/**
|
|
27
29
|
* The database table used by the model.
|
|
@@ -9,6 +9,7 @@ use Fleetbase\LaravelMysqlSpatial\Eloquent\SpatialTrait;
|
|
|
9
9
|
use Fleetbase\Models\Model;
|
|
10
10
|
use Fleetbase\Models\User;
|
|
11
11
|
use Fleetbase\Traits\HasApiModelBehavior;
|
|
12
|
+
use Fleetbase\Traits\HasCustomFields;
|
|
12
13
|
use Fleetbase\Traits\HasPublicId;
|
|
13
14
|
use Fleetbase\Traits\HasUuid;
|
|
14
15
|
use Fleetbase\Traits\TracksApiCredential;
|
|
@@ -21,6 +22,7 @@ class Issue extends Model
|
|
|
21
22
|
use TracksApiCredential;
|
|
22
23
|
use SpatialTrait;
|
|
23
24
|
use HasApiModelBehavior;
|
|
25
|
+
use HasCustomFields;
|
|
24
26
|
|
|
25
27
|
/**
|
|
26
28
|
* The database table used by the model.
|