migrant-web/app/Models/Worker.php
2026-07-07 01:19:50 +05:30

240 lines
6.8 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Notifications\Notifiable;
class Worker extends Model
{
use HasFactory, SoftDeletes, Notifiable;
protected static function booted()
{
static::updated(function ($worker) {
if ($worker->wasChanged('status')) {
$oldStatus = $worker->getOriginal('status');
$newStatus = $worker->status;
$worker->notify(new \App\Notifications\GenericNotification(
"Profile Status Update",
"Your profile status has changed from '" . ucfirst($oldStatus) . "' to '" . ucfirst($newStatus) . "'.",
[
'type' => 'worker_status_change',
'worker_id' => $worker->id,
'old_status' => $oldStatus,
'new_status' => $newStatus,
]
));
}
});
}
protected $fillable = [
'name',
'email',
'phone',
'language',
'password',
'nationality',
'country',
'city',
'area',
'preferred_location',
'live_in_out',
'age',
'gender',
'salary',
'availability',
'experience',
'religion',
'bio',
'verified',
'status',
'api_token',
'in_country',
'visa_status',
'preferred_job_type',
'main_profession',
'fcm_token',
];
protected $hidden = [
'password',
'api_token', // Hide from public serialization, returned only during auth endpoints specifically
];
protected $casts = [
'verified' => 'boolean',
'in_country' => 'boolean',
'salary' => 'decimal:2',
'password' => 'hashed',
];
protected $appends = [
'passport_status',
'visa_status',
'emirates_id_status',
'document_expiry_days',
'document_expiry_status',
'visa_expiry_date',
'rating',
'reviews_count',
];
public function getPassportStatusAttribute()
{
$passport = $this->documents->where('type', 'passport')->first();
if (!$passport) {
return 'Passport Pending';
}
return $this->verified ? 'Passport Verified' : 'Passport Pending';
}
public function getVisaStatusAttribute()
{
if ($this->attributes['visa_status'] ?? null) {
$val = $this->attributes['visa_status'];
$normalized = strtolower(trim($val));
if (str_contains($normalized, 'residence')) {
return 'Residence Visa';
} elseif (str_contains($normalized, 'employment')) {
return 'Employment Visa';
} else {
return 'Tourist Visa';
}
}
$visa = $this->documents->where('type', 'visa')->first();
if (!$visa) {
return 'Residence Visa';
}
$ocrData = $visa->ocr_data;
$vType = $ocrData['visa_type'] ?? null;
if ($vType) {
$normalized = strtolower(trim($vType));
if (str_contains($normalized, 'residence')) {
return 'Residence Visa';
} elseif (str_contains($normalized, 'employment')) {
return 'Employment Visa';
}
}
return 'Tourist Visa';
}
public function setVisaStatusAttribute($value)
{
if (empty($value)) {
$this->attributes['visa_status'] = null;
return;
}
$normalized = strtolower(trim($value));
if (str_contains($normalized, 'residence')) {
$this->attributes['visa_status'] = 'Residence Visa';
} elseif (str_contains($normalized, 'employment')) {
$this->attributes['visa_status'] = 'Employment Visa';
} else {
$this->attributes['visa_status'] = 'Tourist Visa';
}
}
public function getEmiratesIdStatusAttribute()
{
return $this->passport_status;
}
public function getVisaExpiryDateAttribute()
{
$visa = $this->documents->where('type', 'visa')->first();
return $visa ? $visa->expiry_date : null;
}
public function getDocumentExpiryDaysAttribute()
{
$visa = $this->documents->where('type', 'visa')->first();
$doc = $visa;
if (!$doc || !$doc->expiry_date) {
$passport = $this->documents->where('type', 'passport')->first();
$doc = $passport;
}
if ($doc && $doc->expiry_date) {
$expiry = \Carbon\Carbon::parse($doc->expiry_date);
return (int)now()->startOfDay()->diffInDays(\Carbon\Carbon::parse($expiry)->startOfDay(), false);
}
return null;
}
public function getDocumentExpiryStatusAttribute()
{
$visa = $this->documents->where('type', 'visa')->first();
$doc = $visa;
$typeLabel = 'Visa';
if (!$doc || !$doc->expiry_date) {
$passport = $this->documents->where('type', 'passport')->first();
$doc = $passport;
$typeLabel = 'Passport';
}
if ($doc && $doc->expiry_date) {
$expiry = \Carbon\Carbon::parse($doc->expiry_date);
$days = (int)now()->startOfDay()->diffInDays(\Carbon\Carbon::parse($expiry)->startOfDay(), false);
if ($days < 0) {
return "$typeLabel Expired";
}
return "$typeLabel expires in $days days";
}
return 'No Documents';
}
public function skills()
{
return $this->belongsToMany(Skill::class, 'worker_skills');
}
public function documents()
{
return $this->hasMany(WorkerDocument::class);
}
// Relationship for job offers received
public function offers()
{
return $this->hasMany(JobOffer::class, 'worker_id');
}
public function reviews()
{
return $this->hasMany(Review::class);
}
public function employerReviews()
{
return $this->hasMany(EmployerReview::class, 'worker_id');
}
public function getRatingAttribute()
{
// Prevent infinite recursion by not using relationships if we want to avoid eager load loops,
// but typically $this->reviews is safe as long as we don't eager load recursively.
$dbReviews = $this->reviews;
$count = $dbReviews->count();
return $count > 0 ? round($dbReviews->avg('rating'), 1) : 0.0;
}
public function getReviewsCountAttribute()
{
return $this->reviews()->count();
}
public function profileViews()
{
return $this->hasMany(ProfileView::class);
}
}