1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-08-09 15:35:22 +02:00

Add short and long versions of subtypes

This commit is contained in:
hatz 2025-04-21 14:23:43 -05:00
parent 4a51acfe67
commit 7533179350
No known key found for this signature in database
11 changed files with 73 additions and 38 deletions

View file

@ -155,6 +155,20 @@ class Account < ApplicationRecord
first_valuation&.amount_money || balance_money
end
# Get short version of the subtype label
def short_subtype_label
return nil unless subtype && accountable_type
accountable_class = accountable_type.constantize
accountable_class.short_subtype_label_for(subtype) || accountable_class.display_name
end
# Get long version of the subtype label
def long_subtype_label
return nil unless subtype && accountable_type
accountable_class = accountable_type.constantize
accountable_class.long_subtype_label_for(subtype) || accountable_class.display_name
end
private
def sync_balances
strategy = linked? ? :reverse : :forward

View file

@ -60,9 +60,14 @@ class BalanceSheet
classification_total.zero? ? 0 : account.converted_balance / classification_total.to_d * 100
end
# Define our subtype labeling logic
account.define_singleton_method(:subtype_label) do
accountable.subtype_label_for(account.subtype) || accountable.display_name
# Define our subtype labeling logic with short format (for sidebar)
account.define_singleton_method(:short_subtype_label) do
accountable.short_subtype_label_for(account.subtype) || accountable.display_name
end
# Define long label method (for other views that might need it)
account.define_singleton_method(:long_subtype_label) do
accountable.long_subtype_label_for(account.subtype) || accountable.display_name
end
account

View file

@ -3,8 +3,8 @@ module Accountable
TYPES = %w[Depository Investment Crypto Property Vehicle OtherAsset CreditCard Loan OtherLiability]
# Define empty array to ensure all accountables have this defined
SUBTYPES = []
# Define empty hash to ensure all accountables have this defined
SUBTYPES = {}.freeze
def self.from_type(type)
return nil unless TYPES.include?(type)
@ -30,9 +30,22 @@ module Accountable
raise NotImplementedError, "Accountable must implement #color"
end
# Given a subtype, look up the "label" for this accountable type
def subtype_label_for(subtype)
self::SUBTYPES.find { |subtype_label, subtype_value| subtype_value == subtype }&.first
# 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
def favorable_direction

View file

@ -1,10 +1,10 @@
class Depository < ApplicationRecord
include Accountable
SUBTYPES = [
[ "Checking", "checking" ],
[ "Savings", "savings" ]
].freeze
SUBTYPES = {
"checking" => { short: "Checking", long: "Checking" },
"savings" => { short: "Savings", long: "Savings" }
}.freeze
class << self
def display_name

View file

@ -1,20 +1,20 @@
class Investment < ApplicationRecord
include Accountable
SUBTYPES = [
[ "Brokerage", "brokerage" ],
[ "Pension", "pension" ],
[ "Retirement", "retirement" ],
[ "401(k)", "401k" ],
[ "Traditional 401(k)", "traditional_401k" ],
[ "Roth 401(k)", "roth_401k" ],
[ "529 Plan", "529_plan" ],
[ "Health Savings Account", "hsa" ],
[ "Mutual Fund", "mutual_fund" ],
[ "Traditional IRA", "traditional_ira" ],
[ "Roth IRA", "roth_ira" ],
[ "Angel", "angel" ]
].freeze
SUBTYPES = {
"brokerage" => { short: "Brokerage", long: "Brokerage" },
"pension" => { short: "Pension", long: "Pension" },
"retirement" => { short: "Retirement", long: "Retirement" },
"401k" => { short: "401(k)", long: "401(k)" },
"traditional_401k" => { short: "Traditional 401(k)", long: "Traditional 401(k)" },
"roth_401k" => { short: "Roth 401(k)", long: "Roth 401(k)" },
"529_plan" => { short: "529 Plan", long: "529 Plan" },
"hsa" => { short: "HSA", long: "Health Savings Account" },
"mutual_fund" => { short: "Mutual Fund", long: "Mutual Fund" },
"traditional_ira" => { short: "Traditional IRA", long: "Traditional IRA" },
"roth_ira" => { short: "Roth IRA", long: "Roth IRA" },
"angel" => { short: "Angel", long: "Angel" }
}.freeze
class << self
def color

View file

@ -1,14 +1,14 @@
class Property < ApplicationRecord
include Accountable
SUBTYPES = [
[ "Single Family Home", "single_family_home" ],
[ "Multi-Family Home", "multi_family_home" ],
[ "Condominium", "condominium" ],
[ "Townhouse", "townhouse" ],
[ "Investment Property", "investment_property" ],
[ "Second Home", "second_home" ]
]
SUBTYPES = {
"single_family_home" => { short: "Single Family Home", long: "Single Family Home" },
"multi_family_home" => { short: "Multi-Family Home", long: "Multi-Family Home" },
"condominium" => { short: "Condo", long: "Condominium" },
"townhouse" => { short: "Townhouse", long: "Townhouse" },
"investment_property" => { short: "Investment Property", long: "Investment Property" },
"second_home" => { short: "Second Home", long: "Second Home" }
}.freeze
has_one :address, as: :addressable, dependent: :destroy

View file

@ -17,6 +17,9 @@
</p>
<% else %>
<%= link_to account.name, account, class: [(account.is_active ? "text-primary" : "text-subdued"), "text-sm font-medium hover:underline"], data: { turbo_frame: "_top" } %>
<% if account.respond_to?(:long_subtype_label) && account.long_subtype_label %>
<p class="text-sm text-secondary truncate"><%= account.long_subtype_label %></p>
<% end %>
<% end %>
</div>

View file

@ -24,7 +24,7 @@
<div class="min-w-0 grow">
<%= tag.p account.name, class: "text-sm text-primary font-medium mb-0.5 truncate" %>
<%= tag.p account.subtype_label, class: "text-sm text-secondary truncate" %>
<%= tag.p account.short_subtype_label, class: "text-sm text-secondary truncate" %>
</div>
<div class="ml-auto text-right grow h-10">

View file

@ -2,6 +2,6 @@
<%= render "accounts/form", account: account, url: url do |form| %>
<%= form.select :subtype,
Depository::SUBTYPES,
Depository::SUBTYPES.map { |k, v| [v[:long], k] },
{ label: true, prompt: t("depositories.form.subtype_prompt"), include_blank: t("depositories.form.none") } %>
<% end %>

View file

@ -2,6 +2,6 @@
<%= render "accounts/form", account: account, url: url do |form| %>
<%= form.select :subtype,
Investment::SUBTYPES,
Investment::SUBTYPES.map { |k, v| [v[:long], k] },
{ label: true, prompt: t("investments.form.subtype_prompt"), include_blank: t("investments.form.none") } %>
<% end %>

View file

@ -2,7 +2,7 @@
<%= render "accounts/form", account: account, url: url do |form| %>
<%= form.select :subtype,
Property::SUBTYPES,
Property::SUBTYPES.map { |k, v| [v[:long], k] },
{ label: true, prompt: t("properties.form.subtype_prompt"), include_blank: t("properties.form.none") } %>
<hr class="my-4">