2024-02-02 09:05:04 -06:00
|
|
|
class Account < ApplicationRecord
|
2024-02-29 08:32:52 -05:00
|
|
|
include Syncable
|
2024-03-18 11:21:00 -04:00
|
|
|
include Monetizable
|
2024-02-29 08:32:52 -05:00
|
|
|
|
2024-03-15 12:21:59 -07:00
|
|
|
validates :family, presence: true
|
|
|
|
|
2024-02-24 02:18:30 +00:00
|
|
|
broadcasts_refreshes
|
2024-02-02 09:05:04 -06:00
|
|
|
belongs_to :family
|
2024-02-20 09:07:55 -05:00
|
|
|
has_many :balances, class_name: "AccountBalance"
|
|
|
|
has_many :valuations
|
2024-02-23 21:34:33 -05:00
|
|
|
has_many :transactions
|
2024-02-02 11:09:31 -06:00
|
|
|
|
2024-03-18 11:21:00 -04:00
|
|
|
monetize :balance
|
|
|
|
|
2024-03-11 16:32:13 -04:00
|
|
|
enum :status, { ok: "ok", syncing: "syncing", error: "error" }, validate: true
|
|
|
|
|
2024-03-07 10:55:51 -05:00
|
|
|
scope :active, -> { where(is_active: true) }
|
2024-03-11 16:32:13 -04:00
|
|
|
scope :assets, -> { where(classification: "asset") }
|
|
|
|
scope :liabilities, -> { where(classification: "liability") }
|
2024-03-07 10:55:51 -05:00
|
|
|
|
2024-02-09 14:26:54 +00:00
|
|
|
delegated_type :accountable, types: Accountable::TYPES, dependent: :destroy
|
2024-02-02 23:06:29 +00:00
|
|
|
|
2024-02-10 16:18:56 -06:00
|
|
|
before_create :check_currency
|
|
|
|
|
2024-03-11 14:51:16 +02:00
|
|
|
def self.ransackable_attributes(auth_object = nil)
|
|
|
|
%w[name]
|
|
|
|
end
|
|
|
|
|
2024-03-19 09:10:40 -04:00
|
|
|
def balance_on(date)
|
|
|
|
balances.where("date <= ?", date).order(date: :desc).first&.balance
|
2024-02-20 09:07:55 -05:00
|
|
|
end
|
|
|
|
|
2024-03-07 10:55:51 -05:00
|
|
|
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
|
|
|
|
|
2024-03-11 16:32:13 -04:00
|
|
|
def self.some_syncing?
|
|
|
|
exists?(status: "syncing")
|
|
|
|
end
|
|
|
|
|
2024-03-19 09:10:40 -04:00
|
|
|
def series(period = Period.all)
|
|
|
|
TimeSeries.from_collection(balances.in_period(period), :balance_money)
|
|
|
|
end
|
|
|
|
|
2024-03-06 09:56:59 -05:00
|
|
|
def self.by_group(period = Period.all)
|
2024-03-19 09:10:40 -04:00
|
|
|
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
|
2024-03-06 09:56:59 -05:00
|
|
|
end
|
|
|
|
|
2024-03-19 09:10:40 -04:00
|
|
|
grouped_accounts
|
2024-02-20 09:07:55 -05:00
|
|
|
end
|
|
|
|
|
2024-03-06 09:56:59 -05:00
|
|
|
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
|
2024-02-10 16:18:56 -06:00
|
|
|
end
|
2024-02-02 09:05:04 -06:00
|
|
|
end
|