2024-02-02 23:09:35 +00:00
module Accountable
extend ActiveSupport :: Concern
2025-02-21 11:57:59 -05:00
TYPES = %w[ Depository Investment Crypto Property Vehicle OtherAsset CreditCard Loan OtherLiability ]
2024-02-09 14:26:54 +00:00
2025-04-22 13:10:50 -05:00
# Define empty hash to ensure all accountables have this defined
SUBTYPES = { } . freeze
2024-02-09 14:26:54 +00:00
def self . from_type ( type )
2024-06-20 07:26:25 -04:00
return nil unless TYPES . include? ( type )
type . constantize
2024-02-09 14:26:54 +00:00
end
2024-02-02 23:09:35 +00:00
included do
2025-04-18 11:39:58 -04:00
include Enrichable
2024-02-02 23:09:35 +00:00
has_one :account , as : :accountable , touch : true
end
2024-08-02 17:09:25 -04:00
2025-02-21 11:57:59 -05:00
class_methods do
def classification
raise NotImplementedError , " Accountable must implement # classification "
end
def icon
raise NotImplementedError , " Accountable must implement # icon "
end
def color
raise NotImplementedError , " Accountable must implement # color "
end
2025-04-22 13:10:50 -05:00
# Given a subtype, look up the label for this accountable type
def subtype_label_for ( subtype , format : :short )
return nil if subtype . nil?
label_type = format == :long ? :long : :short
self :: SUBTYPES [ subtype ] & . fetch ( label_type , nil )
end
# Convenience method for getting the short label
def short_subtype_label_for ( subtype )
subtype_label_for ( subtype , format : :short )
end
# Convenience method for getting the long label
def long_subtype_label_for ( subtype )
subtype_label_for ( subtype , format : :long )
end
2025-02-21 11:57:59 -05:00
def favorable_direction
classification == " asset " ? " up " : " down "
end
def display_name
self . name . pluralize . titleize
end
def balance_money ( family )
family . accounts
. active
. joins ( sanitize_sql_array ( [
" LEFT JOIN exchange_rates ON exchange_rates.date = :current_date AND accounts.currency = exchange_rates.from_currency AND exchange_rates.to_currency = :family_currency " ,
{ current_date : Date . current . to_s , family_currency : family . currency }
] ) )
. where ( accountable_type : self . name )
. sum ( " accounts.balance * COALESCE(exchange_rates.rate, 1) " )
end
end
def display_name
self . class . display_name
end
2025-07-03 09:33:07 -04:00
def balance_display_name
" account value "
end
def opening_balance_display_name
" opening balance "
end
2025-02-21 11:57:59 -05:00
def icon
self . class . icon
end
def color
self . class . color
end
def classification
self . class . classification
end
2024-02-02 23:09:35 +00:00
end