first&last
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class ActivityLog extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
public const UPDATED_AT = null;
|
||||
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'model_type',
|
||||
'model_id',
|
||||
'action',
|
||||
'description',
|
||||
'ip_address',
|
||||
'created_at',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'created_at' => 'datetime',
|
||||
];
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class Department extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'description',
|
||||
];
|
||||
|
||||
public function users(): HasMany
|
||||
{
|
||||
return $this->hasMany(User::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\EquipmentCondition;
|
||||
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;
|
||||
|
||||
class Equipment extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'equipment';
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'serial_number',
|
||||
'inventory_number',
|
||||
'category_id',
|
||||
'client_id',
|
||||
'purchase_date',
|
||||
'warranty_until',
|
||||
'condition',
|
||||
'notes',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'purchase_date' => 'date',
|
||||
'warranty_until' => 'date',
|
||||
'condition' => EquipmentCondition::class,
|
||||
];
|
||||
|
||||
public function category(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(EquipmentCategory::class, 'category_id');
|
||||
}
|
||||
|
||||
public function client(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'client_id');
|
||||
}
|
||||
|
||||
public function requests(): HasMany
|
||||
{
|
||||
return $this->hasMany(ServiceRequest::class, 'equipment_id');
|
||||
}
|
||||
|
||||
public function scopeWarrantyExpired(Builder $query): Builder
|
||||
{
|
||||
return $query->whereNotNull('warranty_until')->whereDate('warranty_until', '<', now());
|
||||
}
|
||||
|
||||
public function scopeWarrantyExpiringSoon(Builder $query, int $days = 30): Builder
|
||||
{
|
||||
return $query
|
||||
->whereNotNull('warranty_until')
|
||||
->whereDate('warranty_until', '>=', now())
|
||||
->whereDate('warranty_until', '<=', now()->addDays($days));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class EquipmentCategory extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'slug',
|
||||
'description',
|
||||
];
|
||||
|
||||
public function equipment(): HasMany
|
||||
{
|
||||
return $this->hasMany(Equipment::class, 'category_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class Priority extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'color_hex',
|
||||
'level',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'level' => 'integer',
|
||||
];
|
||||
|
||||
public function requests(): HasMany
|
||||
{
|
||||
return $this->hasMany(ServiceRequest::class, 'priority_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class RequestAttachment extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'request_id',
|
||||
'user_id',
|
||||
'filename',
|
||||
'path',
|
||||
'size',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'size' => 'integer',
|
||||
];
|
||||
|
||||
public function request(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(ServiceRequest::class, 'request_id');
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class RequestComment extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'request_id',
|
||||
'user_id',
|
||||
'body',
|
||||
'is_internal',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'is_internal' => 'boolean',
|
||||
];
|
||||
|
||||
public function request(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(ServiceRequest::class, 'request_id');
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class RequestType extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'description',
|
||||
'sla_hours',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'sla_hours' => 'integer',
|
||||
];
|
||||
|
||||
public function requests(): HasMany
|
||||
{
|
||||
return $this->hasMany(ServiceRequest::class, 'type_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Setting extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'key',
|
||||
'value',
|
||||
'type',
|
||||
];
|
||||
|
||||
public static function getValue(string $key, mixed $default = null): mixed
|
||||
{
|
||||
$setting = static::query()->where('key', $key)->first();
|
||||
|
||||
if (!$setting) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return $setting->castValue();
|
||||
}
|
||||
|
||||
public static function setValue(string $key, mixed $value, string $type = 'string'): self
|
||||
{
|
||||
return static::query()->updateOrCreate(
|
||||
['key' => $key],
|
||||
['value' => static::serializeValue($value, $type), 'type' => $type]
|
||||
);
|
||||
}
|
||||
|
||||
public function castValue(): mixed
|
||||
{
|
||||
return match ($this->type) {
|
||||
'integer' => (int) $this->value,
|
||||
'boolean' => filter_var($this->value, FILTER_VALIDATE_BOOLEAN),
|
||||
'json' => $this->value ? json_decode($this->value, true, 512, JSON_THROW_ON_ERROR) : [],
|
||||
default => $this->value,
|
||||
};
|
||||
}
|
||||
|
||||
private static function serializeValue(mixed $value, string $type): ?string
|
||||
{
|
||||
if ($value === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return match ($type) {
|
||||
'json' => json_encode($value, JSON_THROW_ON_ERROR),
|
||||
'boolean' => $value ? '1' : '0',
|
||||
default => (string) $value,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class Status extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'color_hex',
|
||||
'slug',
|
||||
'is_final',
|
||||
'sort_order',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'is_final' => 'boolean',
|
||||
'sort_order' => 'integer',
|
||||
];
|
||||
|
||||
public function requests(): HasMany
|
||||
{
|
||||
return $this->hasMany(ServiceRequest::class, 'status_id');
|
||||
}
|
||||
|
||||
public function scopeFinal(Builder $query): Builder
|
||||
{
|
||||
return $query->where('is_final', true);
|
||||
}
|
||||
|
||||
public function scopeActiveFlow(Builder $query): Builder
|
||||
{
|
||||
return $query->where('is_final', false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\UserRole;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Laravel\Sanctum\HasApiTokens;
|
||||
|
||||
class User extends Authenticatable
|
||||
{
|
||||
use HasApiTokens;
|
||||
use HasFactory;
|
||||
use Notifiable;
|
||||
use SoftDeletes;
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'email',
|
||||
'password',
|
||||
'role',
|
||||
'phone',
|
||||
'avatar',
|
||||
'department_id',
|
||||
'is_active',
|
||||
'last_login_at',
|
||||
];
|
||||
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'email_verified_at' => 'datetime',
|
||||
'password' => 'hashed',
|
||||
'last_login_at' => 'datetime',
|
||||
'is_active' => 'boolean',
|
||||
'role' => UserRole::class,
|
||||
];
|
||||
|
||||
public function department(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Department::class);
|
||||
}
|
||||
|
||||
public function clientRequests(): HasMany
|
||||
{
|
||||
return $this->hasMany(ServiceRequest::class, 'client_id');
|
||||
}
|
||||
|
||||
public function assignedRequests(): HasMany
|
||||
{
|
||||
return $this->hasMany(ServiceRequest::class, 'assigned_to');
|
||||
}
|
||||
|
||||
public function requestComments(): HasMany
|
||||
{
|
||||
return $this->hasMany(RequestComment::class);
|
||||
}
|
||||
|
||||
public function requestAttachments(): HasMany
|
||||
{
|
||||
return $this->hasMany(RequestAttachment::class);
|
||||
}
|
||||
|
||||
public function activityLogs(): HasMany
|
||||
{
|
||||
return $this->hasMany(ActivityLog::class);
|
||||
}
|
||||
|
||||
public function equipment(): HasMany
|
||||
{
|
||||
return $this->hasMany(Equipment::class, 'client_id');
|
||||
}
|
||||
|
||||
public function isAdmin(): bool
|
||||
{
|
||||
return $this->role === UserRole::ADMIN;
|
||||
}
|
||||
|
||||
public function isManager(): bool
|
||||
{
|
||||
return $this->role === UserRole::MANAGER;
|
||||
}
|
||||
|
||||
public function isTechnician(): bool
|
||||
{
|
||||
return $this->role === UserRole::TECHNICIAN;
|
||||
}
|
||||
|
||||
public function isClient(): bool
|
||||
{
|
||||
return $this->role === UserRole::CLIENT;
|
||||
}
|
||||
|
||||
public function isStaff(): bool
|
||||
{
|
||||
return $this->isAdmin() || $this->isManager() || $this->isTechnician();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user