Teren-app/app/Models/FieldJob.php
2025-10-09 01:05:17 +02:00

147 lines
4.3 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\DB;
class FieldJob extends Model
{
use HasFactory;
use SoftDeletes;
protected $fillable = [
'field_job_setting_id',
'assigned_user_id',
'user_id',
'contract_id',
'assigned_at',
'completed_at',
'cancelled_at',
'priority',
'notes',
'address_snapshot ',
];
protected $casts = [
'assigned_at' => 'datetime',
'completed_at' => 'datetime',
'cancelled_at' => 'datetime',
'priority' => 'boolean',
'address_snapshot ' => 'array',
];
protected static function booted()
{
static::creating(function (FieldJob $fieldJob) {
if (! isset($fieldJob->user_id)) {
$fieldJob->user_id = auth()->id();
}
});
static::updated(function (FieldJob $fieldJob): void {
// If job was just completed or cancelled, move contract to configured segment
$completedChanged = $fieldJob->wasChanged('completed_at') && ! is_null($fieldJob->completed_at);
$cancelledChanged = $fieldJob->wasChanged('cancelled_at') && ! is_null($fieldJob->cancelled_at);
if (! $completedChanged && ! $cancelledChanged) {
return;
}
if (! $fieldJob->relationLoaded('setting')) {
$fieldJob->load('setting');
}
if ($cancelledChanged) {
// On cancel: redirect to queue segment
$segmentId = $fieldJob->setting?->queue_segment_id;
$fieldJob->moveContractToSegment($segmentId);
return;
}
if ($completedChanged) {
// On complete: redirect to return segment
$segmentId = $fieldJob->setting?->return_segment_id;
$fieldJob->moveContractToSegment($segmentId);
return;
}
});
}
public function setting(): BelongsTo
{
return $this->belongsTo(FieldJobSetting::class, 'field_job_setting_id');
}
public function assignedUser(): BelongsTo
{
return $this->belongsTo(User::class, 'assigned_user_id');
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class, 'user_id');
}
public function contract(): BelongsTo
{
return $this->belongsTo(Contract::class, 'contract_id');
}
/**
* Set/ensure the contract has the return segment marked active based on the field job setting.
*/
/**
* Ensure the contract has the provided segment marked active.
*/
public function moveContractToSegment(?int $segmentId): void
{
if (empty($segmentId) || empty($this->contract_id)) {
return;
}
// First, deactivate any currently active segments for this contract
DB::table('contract_segment')
->where('contract_id', $this->contract_id)
->where('active', true)
->update(['active' => false, 'updated_at' => now()]);
// Then activate (or create) the target segment pivot
$pivot = DB::table('contract_segment')
->where('contract_id', $this->contract_id)
->where('segment_id', $segmentId)
->first();
if ($pivot) {
DB::table('contract_segment')
->where('id', $pivot->id)
->update(['active' => true, 'updated_at' => now()]);
} else {
DB::table('contract_segment')->insert([
'contract_id' => $this->contract_id,
'segment_id' => $segmentId,
'active' => true,
'created_at' => now(),
'updated_at' => now(),
]);
}
}
/**
* Back-compat convenience: move to configured return segment.
*/
public function returnContractToConfiguredSegment(): void
{
if (! $this->relationLoaded('setting')) {
$this->load('setting');
}
$this->moveContractToSegment($this->setting?->return_segment_id);
}
}