*/ use HasFactory, HasUuids, SoftDeletes; /** @var array */ protected $dispatchesEvents = [ 'created' => TransactionCreated::class, 'updated' => TransactionUpdated::class, 'deleted' => TransactionDeleted::class, ]; protected $fillable = [ 'user_id', 'account_id', 'category_id', 'description', 'description_iv', 'original_description', 'transaction_date', 'amount', 'currency_code', 'notes', 'notes_iv', 'source', 'external_transaction_id', 'raw_data', ]; protected function casts(): array { return [ 'transaction_date' => 'date:Y-m-d', 'amount' => 'integer', 'source' => TransactionSource::class, 'raw_data' => 'array', ]; } /** @return BelongsTo */ public function user(): BelongsTo { return $this->belongsTo(User::class); } /** @return BelongsTo */ public function account(): BelongsTo { return $this->belongsTo(Account::class); } /** @return BelongsTo */ public function category(): BelongsTo { return $this->belongsTo(Category::class); } public function labels(): BelongsToMany { return $this->belongsToMany(Label::class) ->using(LabelTransaction::class) ->withTimestamps(); } /** @return HasMany */ public function budgetTransactions(): HasMany { return $this->hasMany(BudgetTransaction::class); } /** * @param Builder $query * @param array $filters * @return Builder */ public function scopeApplyFilters(Builder $query, array $filters): Builder { if (isset($filters['date_from'])) { $query->whereDate('transaction_date', '>=', $filters['date_from']); } if (isset($filters['date_to'])) { $query->whereDate('transaction_date', '<=', $filters['date_to']); } if (isset($filters['amount_min'])) { $query->where('amount', '>=', $filters['amount_min'] * 100); } if (isset($filters['amount_max'])) { $query->where('amount', '<=', $filters['amount_max'] * 100); } if (! empty($filters['category_ids'])) { $ids = collect($filters['category_ids']); $hasUncategorized = $ids->contains('uncategorized'); $realIds = $ids->reject(fn ($id) => $id === 'uncategorized')->values()->all(); $query->where(function (Builder $q) use ($realIds, $hasUncategorized) { if (! empty($realIds)) { $q->whereIn('category_id', $realIds); } if ($hasUncategorized) { $q->orWhereNull('category_id'); } }); } if (! empty($filters['account_ids'])) { $query->whereIn('account_id', $filters['account_ids']); } if (! empty($filters['label_ids'])) { $query->whereHas('labels', fn (Builder $q) => $q->whereIn('labels.id', $filters['label_ids'])); } if (! empty($filters['search'])) { $term = '%'.$filters['search'].'%'; $query->where(fn (Builder $q) => $q->where('description', 'LIKE', $term)->orWhere('notes', 'LIKE', $term)); } return $query; } }