class FortuneTeller::State

We extend `state` Hash with this module for readability

Attributes

accounts[R]
cashflow[R]
date[R]
from[R]
to[R]

Public Class Methods

cashflow_base() click to toggle source
# File lib/fortuneteller/state.rb, line 6
def self.cashflow_base
  FortuneTeller::Cashflow.new(
    pretax_gross: 0,
    pretax_salary: 0,
    pretax_savings_withdrawal: 0,
    pretax_savings: 0,
    pretax_savings_matched: 0,
    pretax_adjusted: 0,
    tax_withholding: 0,
    take_home_pay: 0
  )
end
new(start_date:, previous: nil) click to toggle source
# File lib/fortuneteller/state.rb, line 19
def initialize(start_date:, previous: nil)
  @from = start_date.dup
  @date = start_date
  @accounts = {}
  unless previous.nil?
    previous.accounts.each { |k, a| @accounts[k] = a.dup }
  end
  @cashflow = {
    primary: Array.new(12) { self.class.cashflow_base },
    partner: Array.new(12) { self.class.cashflow_base }
  }
end

Public Instance Methods

add_account(key:, account:) click to toggle source
# File lib/fortuneteller/state.rb, line 32
def add_account(key:, account:)
  @accounts[key] = account.initial_state(start_date: @date)
end
apply_pretax_savings_withdrawal(date:, holder:, amount:, source:) click to toggle source
# File lib/fortuneteller/state.rb, line 42
def apply_pretax_savings_withdrawal(date:, holder:, amount:, source:)
  @accounts[source].debit(amount: amount, on: date)
  c = FortuneTeller::Cashflow.new(pretax_gross: amount, pretax_savings_withdrawal: amount)
  c.line_items[:pretax_adjusted] = amount
  c.line_items[:tax_withholding] = 0
  c.line_items[:take_home_pay] = amount
  apply_cashflow(date: date, holder: holder, cashflow: c)
end
apply_ss_income(date:, holder:, income:) click to toggle source
# File lib/fortuneteller/state.rb, line 59
def apply_ss_income(date:, holder:, income:)
  c = generate_ss_cashflow(date, income)
  apply_cashflow(date: date, holder: holder, cashflow: c)
end
apply_w2_income(date:, holder:, income:, account_credits:) click to toggle source
# File lib/fortuneteller/state.rb, line 51
def apply_w2_income(date:, holder:, income:, account_credits:)
  c = generate_w2_cashflow(date, income)
  apply_cashflow(date: date, holder: holder, cashflow: c)
  account_credits.each do |k, amount|
    @accounts[k].credit(amount: amount, on: date)
  end
end
as_json(_options = nil) click to toggle source
# File lib/fortuneteller/state.rb, line 72
def as_json(_options = nil)
  {
    date: @date,
    # cashflow: {
    #   primary: merged_cashflow(holder: :primary).as_json(options),
    #   partner: merged_cashflow(holder: :partner).as_json(options)
    # },
    accounts: @accounts.as_json
  }
end
init_next() click to toggle source
# File lib/fortuneteller/state.rb, line 64
def init_next
  self.class.new(start_date: @date, previous: self)
end
merged_cashflow(holder:) click to toggle source
# File lib/fortuneteller/state.rb, line 68
def merged_cashflow(holder:)
  @cashflow[holder].reduce(FortuneTeller::Cashflow.new, :merge!)
end
pass_time(to:) click to toggle source
# File lib/fortuneteller/state.rb, line 36
def pass_time(to:)
  @date = to
  @to = to
  @accounts.each_value { |a| a.pass_time(to: to) }
end

Private Instance Methods

apply_cashflow(date:, holder:, cashflow:) click to toggle source
# File lib/fortuneteller/state.rb, line 117
def apply_cashflow(date:, holder:, cashflow:)
  @cashflow[holder][(date.month - 1)].merge!(cashflow)
end
calculate_w2_withholding(date:, adjusted_income:, pay_period:) click to toggle source
# File lib/fortuneteller/state.rb, line 112
def calculate_w2_withholding(date:, adjusted_income:, pay_period:)
  # Ideally, use state to determine w-4 allowances
  (adjusted_income * 0.3).floor
end
generate_ss_cashflow(date, income) click to toggle source
# File lib/fortuneteller/state.rb, line 102
def generate_ss_cashflow(date, income)
  FortuneTeller::Cashflow.new(
    pretax_gross: income[:ss],
    pretax_ss: income[:ss],
    pretax_adjusted: income[:ss],
    tax_withholding: 0,
    take_home_pay: income[:ss]
  )
end
generate_w2_cashflow(date, income) click to toggle source
# File lib/fortuneteller/state.rb, line 85
def generate_w2_cashflow(date, income)
  c = FortuneTeller::Cashflow.new(
    pretax_gross: (income[:wages] + income[:matched]),
    pretax_salary: income[:wages],
    pretax_savings: income[:saved],
    pretax_savings_matched: income[:matched],
    pretax_adjusted: (income[:wages] - income[:saved])
  )
  c.line_items[:tax_withholding] = calculate_w2_withholding(
    date: date,
    adjusted_income: c.line_items[:pretax_adjusted],
    pay_period: income[:pay_period]
  )
  c.line_items[:take_home_pay] = c.line_items[:pretax_adjusted] - c.line_items[:tax_withholding]
  c
end