Files
RecruIT/app/Models/Candidate.php

75 lines
2.2 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use App\Traits\BelongsToTenant;
#[Fillable(['user_id', 'job_position_id', 'phone', 'linkedin_url', 'status', 'is_selected', 'notes', 'cv_score', 'motivation_score', 'interview_score', 'ai_analysis', 'tenant_id'])]
class Candidate extends Model
{
use HasFactory, BelongsToTenant;
protected static function booted()
{
static::creating(function ($candidate) {
if ($candidate->job_position_id && !$candidate->tenant_id) {
$jobPosition = JobPosition::find($candidate->job_position_id);
if ($jobPosition) {
$candidate->tenant_id = $jobPosition->tenant_id;
}
}
});
}
protected $casts = [
'ai_analysis' => 'array',
'is_selected' => 'boolean',
];
public function jobPosition(): BelongsTo
{
return $this->belongsTo(JobPosition::class);
}
protected $appends = ['weighted_score'];
public function getWeightedScoreAttribute(): float
{
$cv = (float)$this->cv_score;
$motivation = (float)$this->motivation_score;
$interview = (float)$this->interview_score;
// On récupère le meilleur test (ramené sur 20)
$bestAttempt = $this->attempts()->whereNotNull('finished_at')->get()->map(function($a) {
return $a->max_score > 0 ? ($a->score / $a->max_score) * 20 : 0;
})->max() ?? 0;
$totalPoints = $cv + $motivation + $interview + $bestAttempt;
$maxPoints = 20 + 10 + 30 + 20; // Total potentiel = 80
return round(($totalPoints / $maxPoints) * 20, 2);
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function documents(): HasMany
{
return $this->hasMany(Document::class);
}
public function attempts(): HasMany
{
return $this->hasMany(Attempt::class);
}
}