gps_system/app/Models/Device.php
sackey 6b878bb0a0
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
Initial commit
2025-09-12 16:19:56 +00:00

173 lines
3.7 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
class Device extends Model
{
use HasFactory;
protected $fillable = [
'user_id',
'traccar_device_id',
'name',
'unique_id',
'imei',
'phone',
'model',
'contact',
'category',
'protocol',
'status',
'last_update',
'position_id',
'group_id',
'attributes',
'is_active',
];
protected $casts = [
'last_update' => 'datetime',
'attributes' => 'array',
'is_active' => 'boolean',
];
/**
* Get the user that owns the device
*/
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
/**
* Get the device group
*/
public function group(): BelongsTo
{
return $this->belongsTo(DeviceGroup::class, 'group_id');
}
/**
* Get the current position
*/
public function currentPosition(): BelongsTo
{
return $this->belongsTo(Position::class, 'position_id');
}
/**
* Get all positions for this device
*/
public function positions(): HasMany
{
return $this->hasMany(Position::class);
}
/**
* Get the latest position for this device
*/
public function latestPosition(): HasOne
{
return $this->hasOne(Position::class)->latestOfMany('device_time');
}
/**
* Get the assigned driver
*/
public function driver(): BelongsTo
{
return $this->belongsTo(Driver::class);
}
/**
* Get device events
*/
public function events(): HasMany
{
return $this->hasMany(Event::class);
}
/**
* Get assigned geofences
*/
public function geofences(): BelongsToMany
{
return $this->belongsToMany(Geofence::class, 'device_geofences');
}
/**
* Get device commands
*/
public function commands(): HasMany
{
return $this->hasMany(Command::class);
}
/**
* Scope for active devices
*/
public function scopeActive($query)
{
return $query->where('is_active', true);
}
/**
* Scope for devices by status
*/
public function scopeByStatus($query, $status)
{
return $query->where('status', $status);
}
/**
* Check if device is online
*/
public function isOnline(): bool
{
if (!$this->last_update) {
return false;
}
return $this->last_update->diffInMinutes(now()) <= 5;
}
/**
* Get device status badge color
*/
public function getStatusColor(): string
{
return match ($this->status) {
'online' => 'green',
'offline' => 'red',
'unknown' => 'gray',
default => 'gray'
};
}
/**
* Get latest position data
*/
public function getLatestPosition(): ?array
{
if (!$this->currentPosition) {
return null;
}
return [
'latitude' => $this->currentPosition->latitude,
'longitude' => $this->currentPosition->longitude,
'speed' => $this->currentPosition->speed,
'course' => $this->currentPosition->course,
'address' => $this->currentPosition->address,
'timestamp' => $this->currentPosition->device_time,
];
}
}