diff --git a/Gemfile b/Gemfile
index cc840dd..7e9c186 100644
--- a/Gemfile
+++ b/Gemfile
@@ -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"
diff --git a/Gemfile.lock b/Gemfile.lock
index 985be7e..32f36b5 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -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
@@ -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)
@@ -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)
@@ -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)
diff --git a/app/controllers/concerns/stream.rb b/app/controllers/concerns/stream.rb
index 1497ad8..8ecb8d0 100644
--- a/app/controllers/concerns/stream.rb
+++ b/app/controllers/concerns/stream.rb
@@ -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
diff --git a/app/controllers/concerns/taxed_income.rb b/app/controllers/concerns/taxed_income.rb
index a1e59cc..d577c7b 100644
--- a/app/controllers/concerns/taxed_income.rb
+++ b/app/controllers/concerns/taxed_income.rb
@@ -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
@@ -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)
diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb
index d069d72..189a80d 100644
--- a/app/controllers/dashboard_controller.rb
+++ b/app/controllers/dashboard_controller.rb
@@ -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
diff --git a/app/services/federal_tax_calculator.rb b/app/services/federal_tax_calculator.rb
index 4fc3eca..aa658e8 100644
--- a/app/services/federal_tax_calculator.rb
+++ b/app/services/federal_tax_calculator.rb
@@ -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
@@ -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
diff --git a/app/views/dashboard/_index.html.erb b/app/views/dashboard/_index.html.erb
new file mode 100644
index 0000000..7766b83
--- /dev/null
+++ b/app/views/dashboard/_index.html.erb
@@ -0,0 +1,99 @@
+<%= turbo_frame_tag "primary_frame" do %>
+
+
+
+
Budget Calculator
+
+
+
+
+
+
+
Final Budget
+
Savings Rate %
+
Investing Rate %
+
+
+
+ <%= render partial: "components/income_switch" %>
+
+
+
+ <%= form_with model: @savings_rate, local: true do |form| %>
+
+ <%= 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"%>
+
+ <% end %>
+
+
+
+ <%= form_with model: @investing_rate, local: true do |form| %>
+
+ <%= 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"%>
+
+ <% end %>
+
+
+
+
+
Filing status
+ <%= form_with url: switch_taxable_income_path, local: true do |form| %>
+
+ <% FederalTaxTableType.all.each do |table| %>
+
+ <%= 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 %>
+
+ <% end %>
+
+ <% end %>
+
+
+
+ <%= 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
+ }
+ %>
+
+
+
+
+
+
+ <%= turbo_frame_tag "income_header_frame" do %>
+
Income
+ <%= link_to "New Income", new_income_path, data: { turbo_frame: :incomes }, class: "btn btn-primary" %>
+ <% end %>
+
+
+ <%= render "incomes/index" %>
+
+
+
+ <%= render partial: "shared/taxed_incomes",
+ locals: { salary_taxed: @salary_taxed, hourly_taxed: @hourly_taxed } %>
+
+
+
+
+
+
+ <%= turbo_frame_tag "fixed_expense_header_frame" do %>
+
Fixed Expenses
+ <%= 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 } %>
+
+
+
+<% end %>
diff --git a/app/views/dashboard/index.html.erb b/app/views/dashboard/index.html.erb
index 29aaf00..5ff9740 100644
--- a/app/views/dashboard/index.html.erb
+++ b/app/views/dashboard/index.html.erb
@@ -1,83 +1 @@
-
-
-
-
Budget Calculator
-
-
-
-
-
-
-
Final Budget
-
Savings Rate %
-
Investing Rate %
-
-
-
- <%= render partial: "components/income_switch" %>
-
-
-
- <%= form_with model: @savings_rate, local: true do |form| %>
-
- <%= 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"%>
-
- <% end %>
-
-
-
- <%= form_with model: @investing_rate, local: true do |form| %>
-
- <%= 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"%>
-
- <% end %>
-
-
-
-
- <%= 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
- }
- %>
-
-
-
-
-
-
- <%= turbo_frame_tag "income_header_frame" do %>
-
Income
- <%= link_to "New Income", new_income_path, data: { turbo_frame: :incomes }, class: "btn btn-primary" %>
- <% end %>
-
-
- <%= render "incomes/index" %>
-
-
-
- <%= render partial: "shared/taxed_incomes",
- locals: { salary_taxed: @salary_taxed, hourly_taxed: @hourly_taxed } %>
-
-
-
-
-
-
- <%= turbo_frame_tag "fixed_expense_header_frame" do %>
-
Fixed Expenses
- <%= 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 } %>
-
-
-
+<%= render partial: "dashboard/index" %>
diff --git a/config/routes.rb b/config/routes.rb
index 0fca9f2..c83a1ae 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -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
diff --git a/spec/factories/federal_tax_brackets.rb b/spec/factories/federal_tax_brackets.rb
index 08daadc..8564003 100644
--- a/spec/factories/federal_tax_brackets.rb
+++ b/spec/factories/federal_tax_brackets.rb
@@ -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
#
diff --git a/spec/services/federal_tax_calculator_spec.rb b/spec/services/federal_tax_calculator_spec.rb
index 0ab8377..65e5008 100644
--- a/spec/services/federal_tax_calculator_spec.rb
+++ b/spec/services/federal_tax_calculator_spec.rb
@@ -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