1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-08-08 06:55:21 +02:00

Finish account processor

This commit is contained in:
Zach Gollwitzer 2025-05-20 13:52:36 -04:00
parent 13b1560438
commit 67e5705905
4 changed files with 83 additions and 10 deletions

View file

@ -73,12 +73,6 @@ class Account < ApplicationRecord
end end
end end
def set_name(name)
if enrichable?(:name)
self.name = name
end
end
def institution_domain def institution_domain
url_string = plaid_account&.plaid_item&.institution_url url_string = plaid_account&.plaid_item&.institution_url
return nil unless url_string.present? return nil unless url_string.present?

View file

@ -34,7 +34,11 @@ module Enrichable
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
enrichable_attrs.each do |attr, value| enrichable_attrs.each do |attr, value|
self.send("#{attr}=", value) self.send("#{attr}=", value)
log_enrichment(attribute_name: attr, attribute_value: value, source: source, metadata: metadata)
# If it's a new record, this isn't technically an "enrichment". No logging necessary.
unless self.new_record?
log_enrichment(attribute_name: attr, attribute_value: value, source: source, metadata: metadata)
end
end end
save save

View file

@ -0,0 +1,17 @@
# Plaid Investment balances have a ton of edge cases. This processor is responsible
# for deriving "brokerage cash" vs. "total value" based on Plaid's reported balances and holdings.
class PlaidAccount::InvestmentBalanceProcessor
attr_reader :plaid_account
def initialize(plaid_account)
@plaid_account = plaid_account
end
def balance
plaid_account.current_balance || plaid_account.available_balance
end
def cash_balance
plaid_account.available_balance || 0
end
end

View file

@ -1,6 +1,17 @@
class PlaidAccount::Processor class PlaidAccount::Processor
attr_reader :plaid_account attr_reader :plaid_account
UnknownAccountTypeError = Class.new(StandardError)
# Plaid Account Types -> Accountable Types
TYPE_MAPPING = {
"depository" => Depository,
"credit" => CreditCard,
"loan" => Loan,
"investment" => Investment,
"other" => OtherAsset
}
def initialize(plaid_account) def initialize(plaid_account)
@plaid_account = plaid_account @plaid_account = plaid_account
end end
@ -11,12 +22,59 @@ class PlaidAccount::Processor
plaid_account_id: plaid_account.id plaid_account_id: plaid_account.id
) )
account.set_name(plaid_account.name) # Name is the only attribute a user can override for Plaid accounts
account.enrich_attribute(
:name,
plaid_account.name,
source: "plaid"
)
account.assign_attributes(
accountable: accountable,
balance: balance,
currency: plaid_account.currency,
cash_balance: cash_balance
)
account.save!
end end
PlaidAccount::TransactionsProcessor.new(plaid_account).process
PlaidAccount::InvestmentsProcessor.new(plaid_account).process
end end
private private
def family def family
plaid_account.plaid_item.family plaid_account.plaid_item.family
end end
end
def accountable
accountable_class = TYPE_MAPPING[plaid_account.plaid_type]
raise UnknownAccountTypeError, "Unknown account type: #{plaid_account.plaid_type}" unless accountable_class
accountable_class.new
end
def balance
case plaid_account.plaid_type
when "investment"
investment_balance_processor.balance
else
plaid_account.current_balance || plaid_account.available_balance
end
end
def cash_balance
case plaid_account.plaid_type
when "investment"
investment_balance_processor.cash_balance
else
plaid_account.available_balance || 0
end
end
def investment_balance_processor
PlaidAccount::InvestmentBalanceProcessor.new(plaid_account)
end
end