Skip to content

Commit

Permalink
Refactor federal tax (#35)
Browse files Browse the repository at this point in the history
* Calculate taxes for self-employed.

* Add tests.

* Lint.
  • Loading branch information
neb417 authored Jan 13, 2024
1 parent e160a3d commit 06fc825
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 22 deletions.
34 changes: 26 additions & 8 deletions app/services/income_tax_calculator_service.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
class IncomeTaxCalculatorService
attr_reader :income,
:annual_income,
:federal_tax,
:fica_tax,
:agi_deduction,
:agi,
:federal_income_tax,
:total_federal_tax,
:net_after_fed_tax,
:state_tax,
:total_net_income,
Expand All @@ -16,8 +19,11 @@ class IncomeTaxCalculatorService
def initialize(income:)
@income = income
@annual_income = income.weekly_income * 52
@federal_tax = calculate_fed_tax
@fica_tax = calculate_fica_tax
@agi_deduction = calculate_agi_deduction
@agi = calculate_agi
@federal_income_tax = calculate_fed_tax
@total_federal_tax = calculate_total_federal_tax
@net_after_fed_tax = calculate_net_after_fed_tax
@state_tax = calculate_state_tax
@total_net_income = calculate_total_net_income
Expand All @@ -31,23 +37,35 @@ def initialize(income:)

private

def calculate_fica_tax
@annual_income * 0.153
end

def calculate_agi_deduction
@fica_tax * 0.5
end

def calculate_agi
@annual_income - @agi_deduction
end

def calculate_fed_tax
bracket = FederalTaxBracket.where("bottom_range_cents <= ?", @annual_income.cents).order(:bottom_range_cents).last
taxable_at_bracket_rate = Money.new(@annual_income.cents - bracket.bottom_range_cents)
bracket = FederalTaxBracket.where("bottom_range_cents <= ?", @agi.cents).order(:bottom_range_cents).last
taxable_at_bracket_rate = Money.new(@agi - bracket.bottom_range)
rated = bracket.rate * taxable_at_bracket_rate
rated + bracket.cumulative
end

def calculate_fica_tax
@annual_income * 0.0765
def calculate_total_federal_tax
@fica_tax + @federal_income_tax
end

def calculate_state_tax
@net_after_fed_tax * 0.0463
@net_after_fed_tax * 0.044
end

def calculate_net_after_fed_tax
@annual_income - @federal_tax
@agi - @federal_income_tax
end

def calculate_total_net_income
Expand Down
2 changes: 1 addition & 1 deletion app/views/shared/_taxed_income.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<% paid_taxes = [ taxed_income.federal_tax, taxed_income.fica_tax, taxed_income.state_tax, taxed_income.total_net_income ] %>
<% paid_taxes = [ taxed_income.federal_income_tax, taxed_income.fica_tax, taxed_income.state_tax, taxed_income.total_net_income ] %>

<% paid_taxes.each do |tax| %>
<% if annual %>
Expand Down
26 changes: 13 additions & 13 deletions spec/factories/federal_tax_brackets.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,32 +18,32 @@
factory :federal_tax_bracket do
tier { "Tier 1" }
bottom_range_cents { 0 }
top_range_cents { 100000 }
top_range_cents { 100_000 }
rate { 0.1 }
cumulative_cents { 0 }

trait :tier_2 do
tier { "Tier 2" }
bottom_range_cents { 1000100 }
top_range_cents { 10000000 }
bottom_range_cents { 1_000_100 }
top_range_cents { 10_000_000 }
rate { 0.15 }
cumulative_cents { 200000 }
cumulative_cents { 200_000 }
end

trait :tier_3 do
tier { "Tier 2" }
bottom_range_cents { 10000100 }
top_range_cents { 50000000 }
bottom_range_cents { 10_000_100 }
top_range_cents { 50_000_000 }
rate { 0.25 }
cumulative_cents { 500000 }
cumulative_cents { 500_000 }
end

# trait :with_all_tiers do
# after :create do |_record|
# create(:federal_tax_bracket, :tier_2)
# create(:federal_tax_bracket, :tier_3)
# end
# end
trait :with_all_tiers do
after :create do |_record|
create(:federal_tax_bracket, :tier_2)
create(:federal_tax_bracket, :tier_3)
end
end
#
# to_create do |instance|
# instance.id = FederalTaxBracket.find_or_create_by(tier: instance.tier).id
Expand Down
54 changes: 54 additions & 0 deletions spec/services/income_tax_calculator_service_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# frozen_string_literal: true

require("rails_helper")

RSpec.describe IncomeTaxCalculatorService, type: :service do
let(:salary) { create(:income) }
let(:hourly) { create(:income, :hourly) }
let!(:tax_brackets) { create(:federal_tax_bracket, :with_all_tiers) }
let!(:taxed_salary) { IncomeTaxCalculatorService.new(income: salary) }
let!(:taxed_hourly) { IncomeTaxCalculatorService.new(income: hourly) }

describe "income taxes calculator" do
it { expect(taxed_salary).to be_an IncomeTaxCalculatorService }
it { expect(taxed_hourly).to be_an IncomeTaxCalculatorService }

it "calculates salary" do
expect(taxed_salary.income).to be_truthy
expect(taxed_salary.annual_income).to be_truthy
expect(taxed_salary.fica_tax).to be_truthy
expect(taxed_salary.agi_deduction).to be_truthy
expect(taxed_salary.agi).to be_truthy
expect(taxed_salary.federal_income_tax).to be_truthy
expect(taxed_salary.total_federal_tax).to be_truthy
expect(taxed_salary.net_after_fed_tax).to be_truthy
expect(taxed_salary.state_tax).to be_truthy
expect(taxed_salary.total_net_income).to be_truthy
expect(taxed_salary.bi_weekly_net_income).to be_truthy
expect(taxed_salary.daily_income).to be_truthy
expect(taxed_salary.weekly_income).to be_truthy
expect(taxed_salary.monthly_income).to be_truthy
expect(taxed_salary.quarterly_income).to be_truthy
expect(taxed_salary.biannual_income).to be_truthy
end

it "calculates hourly" do
expect(taxed_hourly.income).to be_truthy
expect(taxed_hourly.annual_income).to be_truthy
expect(taxed_hourly.fica_tax).to be_truthy
expect(taxed_hourly.agi_deduction).to be_truthy
expect(taxed_hourly.agi).to be_truthy
expect(taxed_hourly.federal_income_tax).to be_truthy
expect(taxed_hourly.total_federal_tax).to be_truthy
expect(taxed_hourly.net_after_fed_tax).to be_truthy
expect(taxed_hourly.state_tax).to be_truthy
expect(taxed_hourly.total_net_income).to be_truthy
expect(taxed_hourly.bi_weekly_net_income).to be_truthy
expect(taxed_hourly.daily_income).to be_truthy
expect(taxed_hourly.weekly_income).to be_truthy
expect(taxed_hourly.monthly_income).to be_truthy
expect(taxed_hourly.quarterly_income).to be_truthy
expect(taxed_hourly.biannual_income).to be_truthy
end
end
end

0 comments on commit 06fc825

Please sign in to comment.