class RothIRA

Constants

VERSION

Attributes

age[R]
agi[R]
filing_status[R]
limits[R]
spouse_age[R]
year[R]

Public Class Methods

new(year) click to toggle source
# File lib/roth_ira.rb, line 6
def initialize(year)
  raise(ArgumentError, "Invalid Tax Year #{year}") unless year.between?(2015, 2021)
  @year = year
  @limits = YAML.load(File.read(__dir__ + "/limits.yaml"))[year]
end

Public Instance Methods

calculate(agi, filing_status, *ages) click to toggle source
# File lib/roth_ira.rb, line 12
def calculate(agi, filing_status, *ages)
  @agi = agi
  @filing_status = filing_status
  @age = ages.first
  @spouse_age = ages.size == 2 ? ages.last : 0

  calculate_limit
end

Private Instance Methods

calculate_catch_up() click to toggle source
# File lib/roth_ira.rb, line 60
def calculate_catch_up
  eligible_for_catch_up = [primary_eligible_for_catch_up, spouse_eligible_for_catch_up]
  eligible_for_catch_up.count(true) * catch_up_contribution
end
calculate_limit() click to toggle source
# File lib/roth_ira.rb, line 23
def calculate_limit
  case agi
    when 0..max_contribution then agi
    when max_contribution..lower_limit then max_contribution
    when lower_limit...upper_limit then calculate_phase_out
    else 0
  end
end
calculate_phase_out() click to toggle source
# File lib/roth_ira.rb, line 73
def calculate_phase_out
  excess_income = (agi - lower_limit).to_f
  ratio = 1 - (excess_income/limit_range).round(3)
  phase_out_amount = nearest_10(max_contribution * ratio)
  minimum_200 phase_out_amount
end
catch_up_age() click to toggle source
# File lib/roth_ira.rb, line 44
def catch_up_age
  limits[:catch_up_age]
end
catch_up_contribution() click to toggle source
# File lib/roth_ira.rb, line 48
def catch_up_contribution
  limits[:catch_up_contribution]
end
contribution_limit() click to toggle source
# File lib/roth_ira.rb, line 52
def contribution_limit
  limits[filing_status][:contribution_limit]
end
limit_range() click to toggle source
# File lib/roth_ira.rb, line 80
def limit_range
  upper_limit - lower_limit
end
lower_limit() click to toggle source
# File lib/roth_ira.rb, line 32
def lower_limit
  limits[filing_status][:lower_income_limit]
end
max_contribution() click to toggle source
# File lib/roth_ira.rb, line 40
def max_contribution
  contribution_limit + calculate_catch_up
end
minimum_200(amount) click to toggle source
# File lib/roth_ira.rb, line 89
def minimum_200(amount)
  # IRS instructions allow minimum contribution of $200 in phase-out range (per person)
  amount < minimum_phase_out ? minimum_phase_out : amount
end
minimum_phase_out() click to toggle source
# File lib/roth_ira.rb, line 56
def minimum_phase_out
  limits[filing_status][:minimum_phase_out]
end
nearest_10(amount) click to toggle source
# File lib/roth_ira.rb, line 84
def nearest_10(amount)
  # IRS instructions are to round contribution limit UP to the nearest $10
  (amount.to_f / 10).ceil * 10
end
primary_eligible_for_catch_up() click to toggle source
# File lib/roth_ira.rb, line 65
def primary_eligible_for_catch_up
  age >= catch_up_age
end
spouse_eligible_for_catch_up() click to toggle source
# File lib/roth_ira.rb, line 69
def spouse_eligible_for_catch_up
  filing_status == :married_filing_jointly && spouse_age >= catch_up_age
end
upper_limit() click to toggle source
# File lib/roth_ira.rb, line 36
def upper_limit
  limits[filing_status][:upper_income_limit]
end