145 lines
3.7 KiB
PHP
145 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\HasMany;
|
|
|
|
class Technician extends Model
|
|
{
|
|
/** @use HasFactory<\Database\Factories\TechnicianFactory> */
|
|
use HasFactory;
|
|
|
|
protected $fillable = [
|
|
'first_name',
|
|
'last_name',
|
|
'email',
|
|
'phone',
|
|
'employee_id',
|
|
'hourly_rate',
|
|
'specializations',
|
|
'skill_level',
|
|
'certifications',
|
|
'status',
|
|
'shift_start',
|
|
'shift_end',
|
|
];
|
|
|
|
protected $casts = [
|
|
'hourly_rate' => 'decimal:2',
|
|
'specializations' => 'array',
|
|
'shift_start' => 'datetime:H:i',
|
|
'shift_end' => 'datetime:H:i',
|
|
];
|
|
|
|
protected $attributes = [
|
|
'specializations' => '[]',
|
|
'status' => 'active',
|
|
'skill_level' => 'apprentice',
|
|
];
|
|
|
|
// Existing relationships
|
|
public function serviceOrders(): HasMany
|
|
{
|
|
return $this->hasMany(ServiceOrder::class, 'assigned_technician_id');
|
|
}
|
|
|
|
public function appointments(): HasMany
|
|
{
|
|
return $this->hasMany(Appointment::class, 'assigned_technician_id');
|
|
}
|
|
|
|
public function inspections(): HasMany
|
|
{
|
|
return $this->hasMany(VehicleInspection::class, 'technician_id');
|
|
}
|
|
|
|
// New relationships for technician management
|
|
public function skills(): HasMany
|
|
{
|
|
return $this->hasMany(TechnicianSkill::class);
|
|
}
|
|
|
|
public function performances(): HasMany
|
|
{
|
|
return $this->hasMany(TechnicianPerformance::class);
|
|
}
|
|
|
|
public function workloads(): HasMany
|
|
{
|
|
return $this->hasMany(TechnicianWorkload::class);
|
|
}
|
|
|
|
public function primarySkills(): HasMany
|
|
{
|
|
return $this->skills()->where('is_primary_skill', true);
|
|
}
|
|
|
|
public function currentWorkload()
|
|
{
|
|
return $this->workloads()->whereDate('workload_date', now()->toDateString())->first();
|
|
}
|
|
|
|
public function getFullNameAttribute(): string
|
|
{
|
|
return "{$this->first_name} {$this->last_name}";
|
|
}
|
|
|
|
public function isAvailable(): bool
|
|
{
|
|
return $this->status === 'active';
|
|
}
|
|
|
|
// New helper methods for technician management
|
|
public function getAverageRating(): float
|
|
{
|
|
return $this->performances()
|
|
->where('metric_type', 'customer_rating')
|
|
->avg('metric_value') ?? 0;
|
|
}
|
|
|
|
public function getTotalJobsCompleted(): int
|
|
{
|
|
return $this->performances()
|
|
->where('metric_type', 'jobs_completed')
|
|
->sum('metric_value') ?? 0;
|
|
}
|
|
|
|
public function getCurrentUtilizationRate(): float
|
|
{
|
|
$workload = $this->currentWorkload();
|
|
return $workload ? $workload->utilization_rate : 0;
|
|
}
|
|
|
|
public function getSkillLevel(string $skillName): int
|
|
{
|
|
$skill = $this->skills()->where('skill_name', $skillName)->first();
|
|
return $skill ? $skill->proficiency_level : 0;
|
|
}
|
|
|
|
public function hasSkill(string $skillName, int $minimumLevel = 1): bool
|
|
{
|
|
return $this->getSkillLevel($skillName) >= $minimumLevel;
|
|
}
|
|
|
|
public function getWorkloadForPeriod($startDate, $endDate)
|
|
{
|
|
return $this->workloads()
|
|
->whereBetween('workload_date', [$startDate, $endDate])
|
|
->orderBy('workload_date')
|
|
->get();
|
|
}
|
|
|
|
public function getPerformanceMetric(string $metricType, $startDate = null, $endDate = null)
|
|
{
|
|
$query = $this->performances()->where('metric_type', $metricType);
|
|
|
|
if ($startDate && $endDate) {
|
|
$query->whereBetween('performance_date', [$startDate, $endDate]);
|
|
}
|
|
|
|
return $query->avg('metric_value') ?? 0;
|
|
}
|
|
}
|