mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-08-02 12:05:19 +02:00
* Balance reconcilations with new components * Fix materializer and test assumptions * Fix investment valuation calculations and recon display * Lint fixes * Balance series uses new component fields
85 lines
2.3 KiB
Ruby
85 lines
2.3 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)
|
|
|
|
attr_reader :account, :entries
|
|
|
|
def initialize(account, entries)
|
|
@account = account
|
|
@entries = entries.to_a
|
|
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)
|
|
)
|
|
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
|