Skip to content

Commit

Permalink
Federal tax bracket radio buttons (#48)
Browse files Browse the repository at this point in the history
* Add radio buttons to dashboard

* add route to submit form when button selected.

* Render updated figures.

* Refactor radio buttons.

* Lint.

* Add prys.

* Update factories.

* Lint.
  • Loading branch information
neb417 authored Nov 5, 2024
1 parent 6dcf8d1 commit 785f670
Show file tree
Hide file tree
Showing 11 changed files with 139 additions and 114 deletions.
4 changes: 3 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ group :development, :test do
gem "faker"
gem "launchy"
gem "orderly"
gem "pry"
gem "pry-byebug"
gem "pry-rescue"
gem "pry-rails"
gem "rspec-rails"
gem "shoulda-matchers"
gem "simplecov"
Expand Down
14 changes: 13 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ GEM
bootsnap (1.16.0)
msgpack (~> 1.2)
builder (3.2.4)
byebug (11.1.3)
capybara (3.38.0)
addressable
matrix
Expand Down Expand Up @@ -109,6 +110,7 @@ GEM
importmap-rails (1.1.6)
actionpack (>= 6.0.0)
railties (>= 6.0.0)
interception (0.5)
jbuilder (2.11.5)
actionview (>= 5.0.0)
activesupport (>= 5.0.0)
Expand Down Expand Up @@ -166,6 +168,14 @@ GEM
pry (0.14.2)
coderay (~> 1.1)
method_source (~> 1.0)
pry-byebug (3.10.1)
byebug (~> 11.0)
pry (>= 0.13, < 0.15)
pry-rails (0.3.9)
pry (>= 0.10.4)
pry-rescue (1.6.0)
interception (>= 0.5)
pry (>= 0.12.0)
public_suffix (5.0.1)
puma (5.6.5)
nio4r (~> 2.0)
Expand Down Expand Up @@ -315,7 +325,9 @@ DEPENDENCIES
net-http
orderly
pg (~> 1.1)
pry
pry-byebug
pry-rails
pry-rescue
puma (~> 5.0)
rails (~> 7.0.5)
redis (~> 4.0)
Expand Down
20 changes: 1 addition & 19 deletions app/controllers/concerns/stream.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,7 @@ def switch_to_salary

def render_dashboard
[
turbo_stream.replace("hourly_budget",
partial: "budget/salary_budget",
locals: build_locals(tax_on_salary)),
turbo_stream.replace("salary_budget",
partial: "budget/hourly_budget",
locals: build_locals(tax_on_hourly)),
turbo_stream.replace("total_costs",
partial: "shared/total_costs",
locals: {
total_annual_cost: @total_annual_cost,
total_monthly_cost: @total_monthly_cost,
total_bi_weekly_cost: @total_bi_weekly_cost
}),
turbo_stream.replace("taxed_incomes",
partial: "shared/taxed_incomes",
locals: {
salary_taxed: @salary_taxed,
hourly_taxed: @hourly_taxed
})
turbo_stream.replace("primary_frame", partial: "dashboard/index")
]
end
end
9 changes: 6 additions & 3 deletions app/controllers/concerns/taxed_income.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ def build_income_tax_variables!
@hourly_taxed = build_income_tax_object(income: hourly_income)
end

private

def salary_income
@salary_income = Income.find_by(income_type: "Salary").weekly_income * 52
end
Expand All @@ -18,8 +16,13 @@ def hourly_income
@hourly_income = Income.find_by(income_type: "Hourly").weekly_income * 52
end

def federal_tax_table_type_id
filter = params[:federal_tax_table_type_id].present? ? {id: params[:federal_tax_table_type_id]} : {filing_status: "single"}
@federal_tax_table_type_id = FederalTaxTableType.find_by(filter).id
end

def build_income_tax_object(income:)
federal_tax = FederalTaxCalculator.call(income: income)
federal_tax = FederalTaxCalculator.call(income: income, federal_tax_table_type_id: federal_tax_table_type_id)
fica_tax = FicaTaxCalculator.call(income: income)
state_tax = StateTaxCalculator.call(income: income)
net_income = income - (fica_tax + federal_tax + state_tax)
Expand Down
6 changes: 6 additions & 0 deletions app/controllers/dashboard_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
class DashboardController < ApplicationController
include DashboardBuilder
include Stream

def index
build_dashboard_variables!
end

def switch_taxable_income
build_dashboard_variables!
render_respond_to(render_dashboard)
end
end
7 changes: 4 additions & 3 deletions app/services/federal_tax_calculator.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
class FederalTaxCalculator
include Callable

def initialize(income:)
def initialize(income:, federal_tax_table_type_id:)
self.income = income
self.federal_tax_table_type_id = federal_tax_table_type_id
end

def call
Expand All @@ -11,10 +12,10 @@ def call

private

attr_accessor :income
attr_accessor :income, :federal_tax_table_type_id

def calculate
bracket = FederalTaxBracket.where("bottom_range_cents <= ?", income.fractional).order(:bottom_range_cents).last
bracket = FederalTaxBracket.where(federal_tax_table_type_id: federal_tax_table_type_id).where("bottom_range_cents <= ?", income.fractional).order(:bottom_range_cents).last
taxable_at_bracket_rate = Money.new(income - bracket.bottom_range)
rated = bracket.rate * taxable_at_bracket_rate
rated + bracket.cumulative
Expand Down
99 changes: 99 additions & 0 deletions app/views/dashboard/_index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<%= turbo_frame_tag "primary_frame" do %>
<div class="min-h-full">
<div class="primary-card">
<div class="mx-auto px-4 py-6 sm:px-6 lg:px-8">
<h1>Budget Calculator</h1>
</div>
</div>

<div class="primary-card">
<div class="mx-auto py-6 sm:px-6 lg:px-8">
<div class="grid grid-cols-3">
<h3>Final Budget</h3>
<div>Savings Rate %</div>
<div>Investing Rate %</div>
</div>
<div class="grid grid-cols-3">
<div class="pt-4">
<%= render partial: "components/income_switch" %>
</div>

<div class="">
<%= form_with model: @savings_rate, local: true do |form| %>
<div class="flex">
<%= form.number_field :rate, in: 0.00..50.00, step: 0.25, value: @savings_rate.display_rate, class: "block shadow rounded-md border border-gray-200 outline-none px-3 py-2 mt-2 w-1/4 h-7" %>
<%= form.submit "Save", class:"btn btn-primary ml-4 mt-2 py-0.5 my-auto"%>
</div>
<% end %>
</div>

<div class="">
<%= form_with model: @investing_rate, local: true do |form| %>
<div class="flex">
<%= form.number_field :rate, in: 0.00..50.00, step: 0.25, value: @investing_rate.display_rate, class: "block shadow rounded-md border border-gray-200 outline-none px-3 py-2 mt-2 w-1/4 h-7" %>
<%= form.submit "Invest", class:"btn btn-primary ml-4 mt-2 py-0.5 my-auto"%>
</div>
<% end %>
</div>
</div>

<div class="py-4" id="federal_tax_status">
<strong>Filing status</strong>
<%= form_with url: switch_taxable_income_path, local: true do |form| %>
<div class="flex flex-row">
<% FederalTaxTableType.all.each do |table| %>
<div class="mx-auto">
<%= form.radio_button :federal_tax_table_type_id, table.id, checked: table.id == @federal_tax_table_type_id, onchange: "this.form.requestSubmit()" %>
<%= form.label :federal_tax_table_type_id, table.filing_status.humanize.capitalize %>
</div>
<% end %>
</div>
<% end %>
</div>

<div id="final_income">
<%= render partial: "budget/salary_budget",
locals: {
income: @salary_taxed,
total_cost: @total_cost,
investing_amount: @salary_invest,
savings_amount: @salary_saving,
guilt_free: @guilt_free_salary
}
%>
</div>
</div>
</div>

<div class="primary-card">
<div class="mx-auto py-6 sm:px-6 lg:px-8">
<%= turbo_frame_tag "income_header_frame" do %>
<h1>Income</h1>
<%= link_to "New Income", new_income_path, data: { turbo_frame: :incomes }, class: "btn btn-primary" %>
<% end %>

<div class="pt-4">
<%= render "incomes/index" %>
</div>

<div class="pt-4">
<%= render partial: "shared/taxed_incomes",
locals: { salary_taxed: @salary_taxed, hourly_taxed: @hourly_taxed } %>
</div>
</div>
</div>

<div class="primary-card">
<div class="mx-auto py-6 sm:px-6 lg:px-8">
<%= turbo_frame_tag "fixed_expense_header_frame" do %>
<h3>Fixed Expenses</h3>
<%= link_to "New Fixed Expense", new_fixed_expense_path, data: { turbo_frame: :fixed_expenses }, class: "btn btn-primary" %>
<% end %>

<%= render "fixed_expenses/index" %>

<%= render partial: "shared/total_costs", locals: { total_cost: @total_cost } %>
</div>
</div>
</div>
<% end %>
84 changes: 1 addition & 83 deletions app/views/dashboard/index.html.erb
Original file line number Diff line number Diff line change
@@ -1,83 +1 @@
<div class="min-h-full">
<div class="primary-card">
<div class="mx-auto px-4 py-6 sm:px-6 lg:px-8">
<h1>Budget Calculator</h1>
</div>
</div>

<div class="primary-card">
<div class="mx-auto py-6 sm:px-6 lg:px-8">
<div class="grid grid-cols-3">
<h3>Final Budget</h3>
<div>Savings Rate %</div>
<div>Investing Rate %</div>
</div>
<div class="grid grid-cols-3">
<div class="pt-4">
<%= render partial: "components/income_switch" %>
</div>

<div class="">
<%= form_with model: @savings_rate, local: true do |form| %>
<div class="flex">
<%= form.number_field :rate, in: 0.00..50.00, step: 0.25, value: @savings_rate.display_rate, class: "block shadow rounded-md border border-gray-200 outline-none px-3 py-2 mt-2 w-1/4 h-7" %>
<%= form.submit "Save", class:"btn btn-primary ml-4 mt-2 py-0.5 my-auto"%>
</div>
<% end %>
</div>

<div class="">
<%= form_with model: @investing_rate, local: true do |form| %>
<div class="flex">
<%= form.number_field :rate, in: 0.00..50.00, step: 0.25, value: @investing_rate.display_rate, class: "block shadow rounded-md border border-gray-200 outline-none px-3 py-2 mt-2 w-1/4 h-7" %>
<%= form.submit "Invest", class:"btn btn-primary ml-4 mt-2 py-0.5 my-auto"%>
</div>
<% end %>
</div>

</div>
<div id="final_income">
<%= render partial: "budget/salary_budget",
locals: {
income: @salary_taxed,
total_cost: @total_cost,
investing_amount: @salary_invest,
savings_amount: @salary_saving,
guilt_free: @guilt_free_salary
}
%>
</div>
</div>
</div>

<div class="primary-card">
<div class="mx-auto py-6 sm:px-6 lg:px-8">
<%= turbo_frame_tag "income_header_frame" do %>
<h1>Income</h1>
<%= link_to "New Income", new_income_path, data: { turbo_frame: :incomes }, class: "btn btn-primary" %>
<% end %>

<div class="pt-4">
<%= render "incomes/index" %>
</div>

<div class="pt-4">
<%= render partial: "shared/taxed_incomes",
locals: { salary_taxed: @salary_taxed, hourly_taxed: @hourly_taxed } %>
</div>
</div>
</div>

<div class="primary-card">
<div class="mx-auto py-6 sm:px-6 lg:px-8">
<%= turbo_frame_tag "fixed_expense_header_frame" do %>
<h3>Fixed Expenses</h3>
<%= link_to "New Fixed Expense", new_fixed_expense_path, data: { turbo_frame: :fixed_expenses }, class: "btn btn-primary" %>
<% end %>

<%= render "fixed_expenses/index" %>

<%= render partial: "shared/total_costs", locals: { total_cost: @total_cost } %>
</div>
</div>
</div>
<%= render partial: "dashboard/index" %>
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@
root "dashboard#index"
resources :incomes
post "/income_switch", to: "incomes#income_switch"
post "/switch_taxable_income", to: "dashboard#switch_taxable_income", as: "switch_taxable_income"
end
6 changes: 3 additions & 3 deletions spec/factories/federal_tax_brackets.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@
end

trait :with_all_tiers do
after :create do |_record|
create(:federal_tax_bracket, :tier_2)
create(:federal_tax_bracket, :tier_3)
after :create do |record|
create(:federal_tax_bracket, :tier_2, federal_tax_table_type: record.federal_tax_table_type)
create(:federal_tax_bracket, :tier_3, federal_tax_table_type: record.federal_tax_table_type)
end
end
#
Expand Down
3 changes: 2 additions & 1 deletion spec/services/federal_tax_calculator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
RSpec.describe FederalTaxCalculator, type: :service do
subject(:service) do
described_class.call(
income: salary_income.rate
income: salary_income.rate,
federal_tax_table_type_id: tax_brackets.federal_tax_table_type_id
)
end

Expand Down

0 comments on commit 785f670

Please sign in to comment.