Files
sure/app/models/account/activity_feed_data.rb
T
7e26fcb478 feat(accounts): group split transactions in account activity feed (#3359)
The account activity tab rendered split transaction children as flat,
ungrouped rows, unlike /transactions which collapses them into a
parent row with indented children when "Group split transactions" is
enabled. Wire the same EntriesHelper.group_split_entries logic into
the account activity feed (UI::Account::ActivityDate, the actual
render path since the ViewComponent refactor superseded the old
accounts/show/_activity partial), sourcing split parents via the same
single-query batched lookup pattern already used by
TransactionsController#index.

Also forward view_ctx through entries/_split_group so split children
render correctly regardless of which page renders the group.

Fixes we-promise/sure#3227

Co-authored-by: Gerald <248542187+gfr-free@users.noreply.github.com>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 22:20:25 +02:00

88 lines
2.5 KiB
Ruby

# Data used to build the paginated feed of account "activity" (events like transfers, deposits, withdrawals, etc.)
# This data object is useful for avoiding N+1 queries and having an easy way to pass around the required data to the
# activity feed component in controllers and background jobs that refresh it.
class Account::ActivityFeedData
ActivityDateData = Data.define(:date, :entries, :balance, :transfers, :split_parents)
attr_reader :account, :entries, :split_parents
def initialize(account, entries, split_parents: {})
@account = account
@entries = entries.to_a
@split_parents = split_parents
end
def entries_by_date
@entries_by_date_objects ||= begin
grouped_entries.map do |date, date_entries|
ActivityDateData.new(
date: date,
entries: date_entries,
balance: balance_for_date(date),
transfers: transfers_for_date(date),
split_parents: split_parents
)
end
end
end
private
def balance_for_date(date)
balances_by_date[date]
end
def transfers_for_date(date)
transfers_by_date[date] || []
end
def grouped_entries
@grouped_entries ||= entries.group_by(&:date)
end
def balances_by_date
@balances_by_date ||= begin
return {} if entries.empty?
dates = grouped_entries.keys
account.balances
.where(date: dates, currency: account.currency)
.index_by(&:date)
end
end
def transfers_by_date
@transfers_by_date ||= begin
return {} if transaction_ids.empty?
transfers = Transfer
.where(inflow_transaction_id: transaction_ids)
.or(Transfer.where(outflow_transaction_id: transaction_ids))
.to_a
# Group transfers by the date of their transaction entries
result = Hash.new { |h, k| h[k] = [] }
entries.each do |entry|
next unless entry.transaction? && transaction_ids.include?(entry.entryable_id)
transfers.each do |transfer|
if transfer.inflow_transaction_id == entry.entryable_id ||
transfer.outflow_transaction_id == entry.entryable_id
result[entry.date] << transfer
end
end
end
# Remove duplicates
result.transform_values(&:uniq)
end
end
def transaction_ids
@transaction_ids ||= entries
.select(&:transaction?)
.map(&:entryable_id)
.compact
end
end