Teren-app/app/Models/Contract.php
2025-10-08 18:26:47 +02:00

143 lines
4.6 KiB
PHP

<?php
namespace App\Models;
use App\Traits\Uuid;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\SoftDeletes;
class Contract extends Model
{
/** @use HasFactory<\Database\Factories\ContractFactory> */
use HasFactory;
use SoftDeletes;
use Uuid;
protected $fillable = [
'reference',
'start_date',
'end_date',
'client_case_id',
'type_id',
'description',
];
protected $hidden = [
'id',
'client_case_id',
'type_id',
];
public function type(): BelongsTo
{
return $this->belongsTo(\App\Models\ContractType::class, 'type_id');
}
public function clientCase(): BelongsTo
{
return $this->belongsTo(\App\Models\ClientCase::class)
->with(['person']);
}
public function segments(): BelongsToMany
{
return $this->belongsToMany(\App\Models\Segment::class)
->withPivot('active', 'created_at')
->wherePivot('active', true);
}
public function account(): HasOne
{
// Use latestOfMany to always surface newest account snapshot if multiple exist.
return $this->hasOne(\App\Models\Account::class)
->latestOfMany()
->with('type');
}
public function objects(): HasMany
{
return $this->hasMany(\App\Models\CaseObject::class, 'contract_id');
}
public function documents(): MorphMany
{
return $this->morphMany(\App\Models\Document::class, 'documentable');
}
protected static function booted(): void
{
static::created(function (Contract $contract): void {
// Only apply configs when type and client case are set and no segments are already attached
if (empty($contract->type_id) || empty($contract->client_case_id)) {
return;
}
$existing = \DB::table('contract_segment')
->where('contract_id', $contract->id)
->count();
if ($existing > 0) {
// Respect pre-attached segments (e.g. custom import logic)
return;
}
$configs = ContractConfig::query()
->where('contract_type_id', $contract->type_id)
->where('active', true)
->get(['segment_id', 'is_initial']);
if ($configs->isEmpty()) {
return;
}
foreach ($configs as $cfg) {
// Ensure the segment is attached to the client case and active
$attached = \DB::table('client_case_segment')
->where('client_case_id', $contract->client_case_id)
->where('segment_id', $cfg->segment_id)
->first();
if (! $attached) {
\DB::table('client_case_segment')->insert([
'client_case_id' => $contract->client_case_id,
'segment_id' => $cfg->segment_id,
'active' => true,
'created_at' => now(),
'updated_at' => now(),
]);
} elseif (! $attached->active) {
\DB::table('client_case_segment')
->where('id', $attached->id)
->update(['active' => true, 'updated_at' => now()]);
}
// Attach to contract; mark active if initial, otherwise inactive
$pivot = \DB::table('contract_segment')
->where('contract_id', $contract->id)
->where('segment_id', $cfg->segment_id)
->first();
$activeFlag = $cfg->is_initial ? true : false;
if ($pivot) {
\DB::table('contract_segment')
->where('id', $pivot->id)
->update(['active' => $activeFlag, 'updated_at' => now()]);
} else {
\DB::table('contract_segment')->insert([
'contract_id' => $contract->id,
'segment_id' => $cfg->segment_id,
'active' => $activeFlag,
'created_at' => now(),
'updated_at' => now(),
]);
}
}
});
}
}