mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-07-19 13:19:39 +02:00
* Clean up time series models * Add value group rollup class for summarizing hierarchical data * Integrate new classes * Update UI to use new patterns * Update D3 charts to expect new data format * Clean up account model * More cleanup * Money improvements * Use new money fields * Remove invalid fixture data to avoid orphaned accountables * Update time series to work better with collections * Fix tests and UI bugs
73 lines
2.1 KiB
Ruby
73 lines
2.1 KiB
Ruby
class Account < ApplicationRecord
|
|
include Syncable
|
|
include Monetizable
|
|
|
|
validates :family, presence: true
|
|
|
|
broadcasts_refreshes
|
|
belongs_to :family
|
|
has_many :balances, class_name: "AccountBalance"
|
|
has_many :valuations
|
|
has_many :transactions
|
|
|
|
monetize :balance
|
|
|
|
enum :status, { ok: "ok", syncing: "syncing", error: "error" }, validate: true
|
|
|
|
scope :active, -> { where(is_active: true) }
|
|
scope :assets, -> { where(classification: "asset") }
|
|
scope :liabilities, -> { where(classification: "liability") }
|
|
|
|
delegated_type :accountable, types: Accountable::TYPES, dependent: :destroy
|
|
|
|
before_create :check_currency
|
|
|
|
def self.ransackable_attributes(auth_object = nil)
|
|
%w[name]
|
|
end
|
|
|
|
def balance_on(date)
|
|
balances.where("date <= ?", date).order(date: :desc).first&.balance
|
|
end
|
|
|
|
def self.by_provider
|
|
# TODO: When 3rd party providers are supported, dynamically load all providers and their accounts
|
|
[ { name: "Manual accounts", accounts: all.order(balance: :desc).group_by(&:accountable_type) } ]
|
|
end
|
|
|
|
def self.some_syncing?
|
|
exists?(status: "syncing")
|
|
end
|
|
|
|
def series(period = Period.all)
|
|
TimeSeries.from_collection(balances.in_period(period), :balance_money)
|
|
end
|
|
|
|
def self.by_group(period = Period.all)
|
|
grouped_accounts = { assets: ValueGroup.new("Assets"), liabilities: ValueGroup.new("Liabilities") }
|
|
|
|
Accountable.by_classification.each do |classification, types|
|
|
types.each do |type|
|
|
group = grouped_accounts[classification.to_sym].add_child_node(type)
|
|
Accountable.from_type(type).includes(:account).each do |accountable|
|
|
account = accountable.account
|
|
value_node = group.add_value_node(account)
|
|
value_node.attach_series(account.series(period))
|
|
end
|
|
end
|
|
end
|
|
|
|
grouped_accounts
|
|
end
|
|
|
|
private
|
|
def check_currency
|
|
if self.currency == self.family.currency
|
|
self.converted_balance = self.balance
|
|
self.converted_currency = self.currency
|
|
else
|
|
self.converted_balance = ExchangeRate.convert(self.currency, self.family.currency, self.balance)
|
|
self.converted_currency = self.family.currency
|
|
end
|
|
end
|
|
end
|