'date', 'end_date' => 'date', 'amount' => MoneyCast::class, ]; public function budget(): BelongsTo { return $this->belongsTo(Budget::class); } public function account(): BelongsTo { return $this->belongsTo(Account::class); } /** * Get actual transaction amount for this account and date range. */ protected function actualAmount(): Attribute { return Attribute::make( get: function () { return Transaction::whereHas('journalEntries', function ($query) { $query->where('account_id', $this->account_id); }) ->whereBetween('posted_at', [$this->start_date, $this->end_date]) ->sum('amount'); } ); } /** * Get variance (budget - actual) for this budget item. */ protected function variance(): Attribute { return Attribute::make( get: function () { return $this->amount - $this->actualAmount; } ); } /** * Get variance percentage for this budget item. */ protected function variancePercentage(): Attribute { return Attribute::make( get: function () { if ($this->amount == 0) { return 0; } return ($this->variance / $this->amount) * 100; } ); } }