mirror of
https://github.com/we-promise/sure.git
synced 2026-06-04 02:09:01 +00:00
74 lines
2.5 KiB
Ruby
74 lines
2.5 KiB
Ruby
class AccountableSparklinesController < ApplicationController
|
|
def show
|
|
@accountable = Accountable.from_type(params[:accountable_type]&.classify)
|
|
|
|
etag_key = cache_key
|
|
|
|
# Use HTTP conditional GET so the client receives 304 Not Modified when possible.
|
|
if stale?(etag: etag_key, last_modified: family.latest_sync_completed_at)
|
|
@series = Rails.cache.fetch(etag_key, expires_in: 24.hours) do
|
|
build_series
|
|
end
|
|
|
|
render layout: false
|
|
end
|
|
end
|
|
|
|
private
|
|
def family
|
|
@family ||= Current.family
|
|
end
|
|
|
|
def account_scope
|
|
@account_scope ||= family.accounts.visible.where(accountable_type: @accountable.name)
|
|
end
|
|
|
|
def account_ids
|
|
@account_ids ||= account_identity_rows.map(&:first).uniq
|
|
end
|
|
|
|
def account_identity_rows
|
|
@account_identity_rows ||= account_scope
|
|
.left_outer_joins(:account_providers)
|
|
.pluck(:id, :plaid_account_id, :simplefin_account_id, Arel.sql("account_providers.id"))
|
|
end
|
|
|
|
def build_series
|
|
return aggregate_normalized_series if requires_normalized_aggregation?
|
|
|
|
Balance::ChartSeriesBuilder.new(
|
|
account_ids: account_ids,
|
|
currency: family.currency,
|
|
period: Period.last_30_days,
|
|
favorable_direction: @accountable.favorable_direction,
|
|
interval: "1 day"
|
|
).balance_series
|
|
end
|
|
|
|
# balance_type is derived purely from accountable_type, so only Investment/Crypto
|
|
# can yield :investment. Short-circuit to avoid an N+1 `account.linked?` check
|
|
# on every account for non-investment accountable types (loan, credit_card, etc).
|
|
# The `Account.linked` scope is the SQL-level mirror of `Account#linked?`.
|
|
def requires_normalized_aggregation?
|
|
return false unless %w[Investment Crypto].include?(@accountable.name)
|
|
|
|
account_identity_rows.any? do |_account_id, plaid_account_id, simplefin_account_id, account_provider_id|
|
|
plaid_account_id.present? || simplefin_account_id.present? || account_provider_id.present?
|
|
end
|
|
end
|
|
|
|
def aggregate_normalized_series
|
|
Balance::LinkedInvestmentSeriesNormalizer.aggregate_account_ids(
|
|
account_ids: account_ids,
|
|
currency: family.currency,
|
|
period: Period.last_30_days,
|
|
favorable_direction: @accountable.favorable_direction,
|
|
interval: "1 day"
|
|
)
|
|
end
|
|
|
|
def cache_key
|
|
family.build_cache_key("#{@accountable.name}_sparkline_#{Account::Chartable::SPARKLINE_CACHE_VERSION}", invalidate_on_data_updates: true)
|
|
end
|
|
end
|