141 lines
3.5 KiB
PHP
141 lines
3.5 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use App\Enums\StatusSlug;
|
|
use App\Enums\UserRole;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
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\SoftDeletes;
|
|
|
|
class ServiceRequest extends Model
|
|
{
|
|
use HasFactory;
|
|
use SoftDeletes;
|
|
|
|
protected $table = 'requests';
|
|
|
|
protected $fillable = [
|
|
'ticket_number',
|
|
'title',
|
|
'description',
|
|
'type_id',
|
|
'priority_id',
|
|
'status_id',
|
|
'client_id',
|
|
'assigned_to',
|
|
'equipment_id',
|
|
'location',
|
|
'planned_at',
|
|
'deadline_at',
|
|
'started_at',
|
|
'completed_at',
|
|
'resolution_notes',
|
|
'client_rating',
|
|
'client_comment',
|
|
];
|
|
|
|
protected $casts = [
|
|
'planned_at' => 'datetime',
|
|
'deadline_at' => 'datetime',
|
|
'started_at' => 'datetime',
|
|
'completed_at' => 'datetime',
|
|
'client_rating' => 'integer',
|
|
'created_at' => 'datetime',
|
|
'updated_at' => 'datetime',
|
|
'deleted_at' => 'datetime',
|
|
];
|
|
|
|
public function type(): BelongsTo
|
|
{
|
|
return $this->belongsTo(RequestType::class, 'type_id');
|
|
}
|
|
|
|
public function priority(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Priority::class, 'priority_id');
|
|
}
|
|
|
|
public function status(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Status::class, 'status_id');
|
|
}
|
|
|
|
public function client(): BelongsTo
|
|
{
|
|
return $this->belongsTo(User::class, 'client_id');
|
|
}
|
|
|
|
public function assignee(): BelongsTo
|
|
{
|
|
return $this->belongsTo(User::class, 'assigned_to');
|
|
}
|
|
|
|
public function equipment(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Equipment::class, 'equipment_id');
|
|
}
|
|
|
|
public function comments(): HasMany
|
|
{
|
|
return $this->hasMany(RequestComment::class, 'request_id')->latest();
|
|
}
|
|
|
|
public function attachments(): HasMany
|
|
{
|
|
return $this->hasMany(RequestAttachment::class, 'request_id')->latest();
|
|
}
|
|
|
|
public function scopeOpen(Builder $query): Builder
|
|
{
|
|
return $query->whereHas('status', fn (Builder $status) => $status->where('is_final', false));
|
|
}
|
|
|
|
public function scopeOverdue(Builder $query): Builder
|
|
{
|
|
return $query
|
|
->whereNotNull('deadline_at')
|
|
->where('deadline_at', '<', now())
|
|
->whereHas('status', fn (Builder $status) => $status->where('is_final', false));
|
|
}
|
|
|
|
public function scopeMine(Builder $query, User $user): Builder
|
|
{
|
|
if ($user->isClient()) {
|
|
return $query->where('client_id', $user->id);
|
|
}
|
|
|
|
if ($user->isTechnician()) {
|
|
return $query->where('assigned_to', $user->id);
|
|
}
|
|
|
|
return $query;
|
|
}
|
|
|
|
public function scopeForRole(Builder $query, User $user): Builder
|
|
{
|
|
return match ($user->role) {
|
|
UserRole::CLIENT => $query->where('client_id', $user->id),
|
|
UserRole::TECHNICIAN => $query->where('assigned_to', $user->id),
|
|
default => $query,
|
|
};
|
|
}
|
|
|
|
public function isOverdue(): bool
|
|
{
|
|
if ($this->deadline_at === null) {
|
|
return false;
|
|
}
|
|
|
|
return $this->deadline_at->isPast() && !$this->status?->is_final;
|
|
}
|
|
|
|
public function hasStatus(StatusSlug $slug): bool
|
|
{
|
|
return $this->status?->slug === $slug->value;
|
|
}
|
|
}
|