Teren-app/app/Models/Activity.php
2025-11-20 18:11:43 +01:00

150 lines
4.2 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
class Activity extends Model
{
/** @use HasFactory<\Database\Factories\ActivityFactory> */
use HasFactory;
use SoftDeletes;
protected $fillable = [
'due_date',
'amount',
'note',
'action_id',
'user_id',
'decision_id',
'contract_id',
'client_case_id',
];
protected $hidden = [
'action_id',
'decision_id',
'client_case_id',
'user_id',
'contract_id',
];
protected static function booted()
{
static::creating(function (Activity $activity) {
if (! isset($activity->user_id)) {
$activity->user_id = auth()->id();
}
// If an activity with a due date is added for a contract, update the related account's promise_date
if (! empty($activity->contract_id) && ! empty($activity->due_date)) {
\App\Models\Account::query()
->where('contract_id', $activity->contract_id)
->update(
['promise_date' => $activity->due_date, 'updated_at' => now()],
);
}
});
static::created(function (Activity $activity) {
if (! empty($activity->decision_id)) {
event(new \App\Events\ActivityDecisionApplied($activity));
}
});
}
/**
* Scope activities to those linked to contracts within a specific segment.
*/
#[Scope]
public function scopeForSegment(Builder $query, int $segmentId, array $contractIds): Builder
{
return $query->where(function ($q) use ($contractIds) {
$q->whereNull('contract_id');
if (! empty($contractIds)) {
$q->orWhereIn('contract_id', $contractIds);
}
});
}
/**
* Scope activities with decoded base64 filters.
*/
#[Scope]
public function scopeWithFilters(Builder $query, ?string $encodedFilters, \App\Models\ClientCase $clientCase): Builder
{
if (empty($encodedFilters)) {
return $query;
}
try {
$decompressed = base64_decode($encodedFilters);
$filters = json_decode($decompressed, true);
if (! is_array($filters)) {
return $query;
}
if (! empty($filters['action_id'])) {
$query->where('action_id', $filters['action_id']);
}
if (! empty($filters['contract_uuid'])) {
$contract = $clientCase->contracts()->where('uuid', $filters['contract_uuid'])->first(['id']);
if ($contract) {
$query->where('contract_id', $contract->id);
}
}
if (! empty($filters['user_id'])) {
$query->where('user_id', $filters['user_id']);
}
if (! empty($filters['date_from'])) {
$query->whereDate('created_at', '>=', $filters['date_from']);
}
if (! empty($filters['date_to'])) {
$query->whereDate('created_at', '<=', $filters['date_to']);
}
} catch (\Throwable $e) {
\Log::error('Invalid activity filter format', [
'error' => $e->getMessage(),
]);
}
return $query;
}
public function action(): BelongsTo
{
return $this->belongsTo(\App\Models\Action::class);
}
public function decision(): BelongsTo
{
return $this->belongsTo(\App\Models\Decision::class);
}
public function clientCase(): BelongsTo
{
return $this->belongsTo(\App\Models\ClientCase::class);
}
public function contract(): ?BelongsTo
{
return $this->belongsTo(\App\Models\Contract::class);
}
public function user(): BelongsTo
{
return $this->belongsTo(\App\Models\User::class);
}
}