Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions app/lib/efile/line_data.yml
Original file line number Diff line number Diff line change
Expand Up @@ -712,8 +712,24 @@ MD502_LINE_33:
label: '33. Local tax after credits: local tax amount minus total local tax credits (line 28 - line 32)'
MD502_LINE_34:
label: '34. Total Maryland and local tax amount (line 27 + line 33 if deduction standard)'
MD502_LINE_39:
label: "39. Total Maryland income tax, local income tax and contributions"
MD502_LINE_40:
label: "40 Total Maryland and local tax withheld"
MD502_LINE_42:
label: "42. Refundable earned income credit"
MD502_LINE_43:
label: "43. Refundable income tax credits from Part CC, line 10 of Form 502CR"
MD502_LINE_44:
label: "44. Total payments and credits (Add lines 40 through 43.)"
MD502_LINE_45:
label: "45. Balance due (If line 39 is more than line 44, subtract line 44 from line 39"
MD502_LINE_46:
label: "46. Overpayment (If line 39 is less than line 44, subtract line 39 from line 44.)"
MD502_LINE_48:
label: "48. Amount of overpayment TO BE REFUNDED TO YOU"
MD502_LINE_50:
label: "50. TOTAL AMOUNT DUE (Add lines 45 and 49.)"
MD502_AUTHORIZE_DIRECT_DEPOSIT:
label: "Client authorizes the State of Maryland to issue refund by direct deposit (tax refund controller)."
MD502_LINE_51D:
Expand Down
52 changes: 50 additions & 2 deletions app/lib/efile/md/md502_calculator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module Efile
module Md
class Md502Calculator < ::Efile::TaxCalculator
attr_reader :lines
set_refund_owed_lines refund: :MD502_LINE_48, owed: :MD502_LINE_50

def initialize(year:, intake:, include_source: false)
super
Expand Down Expand Up @@ -99,10 +100,16 @@ def calculate
set_line(:MD502_LINE_32, :calculate_line_32)
set_line(:MD502_LINE_33, :calculate_line_33)
set_line(:MD502_LINE_34, :calculate_line_34)

set_line(:MD502_LINE_39, :calculate_line_39)
set_line(:MD502_LINE_40, :calculate_line_40)
set_line(:MD502_LINE_42, :calculate_line_42)
set_line(:MD502_LINE_43, :calculate_line_43)
set_line(:MD502_LINE_44, :calculate_line_44)
set_line(:MD502_LINE_45, :calculate_line_45)
set_line(:MD502_LINE_46, :calculate_line_46)
set_line(:MD502_LINE_48, :calculate_line_48)
set_line(:MD502_LINE_50, :calculate_line_50)
set_line(:MD502_AUTHORIZE_DIRECT_DEPOSIT, @intake, :bank_authorization_confirmed_yes?)

@md502cr.calculate
@lines.transform_values(&:value)
end
Expand Down Expand Up @@ -560,13 +567,54 @@ def calculate_line_34
end
end

def calculate_line_39
(34..38).sum do |line_num|
line_or_zero("MD502_LINE_#{line_num}")
end
end

def calculate_line_40
@intake.state_file_w2s.sum { |item| item.state_income_tax_amount.round } +
@intake.state_file_w2s.sum { |item| item.local_income_tax_amount.round } +
@intake.state_file1099_gs.sum { |item| item.state_income_tax_withheld_amount.round } +
@intake.state_file1099_rs.sum { |item| item.state_tax_withheld_amount.round }
end

def calculate_line_42
# Earned Income Credit (EIC)
if filing_status_mfj? || filing_status_mfs? || @direct_file_data.fed_eic_qc_claimed
[(@direct_file_data.fed_eic * 0.45).round - line_or_zero(:MD502_LINE_21), 0].max
elsif filing_status_single? || filing_status_hoh? || filing_status_qw?
[@direct_file_data.fed_eic - line_or_zero(:MD502_LINE_21), 0].max
end
end

def calculate_line_43; end

def calculate_line_44
[40, 42, 43].sum { |number| line_or_zero("MD502_LINE_#{number}") }
end

def calculate_line_45
if line_or_zero(:MD502_LINE_39) > line_or_zero(:MD502_LINE_44)
line_or_zero(:MD502_LINE_39) - line_or_zero(:MD502_LINE_44)
end
end

def calculate_line_46
if line_or_zero(:MD502_LINE_39) < line_or_zero(:MD502_LINE_44)
line_or_zero(:MD502_LINE_44) - line_or_zero(:MD502_LINE_39)
end
end

def calculate_line_48
line_or_zero(:MD502_LINE_46) - line_or_zero(:MD502_LINE_47)
end

def calculate_line_50
line_or_zero(:MD502_LINE_45) + line_or_zero(:MD502_LINE_49)
end

def filing_status_dependent?
@filing_status == :dependent
end
Expand Down
15 changes: 15 additions & 0 deletions app/lib/pdf_filler/md502_pdf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ def hash_for_pdf
'Enter 13': @xml_document.at('Form502 Subtractions Other')&.text,
'Enter 14': @xml_document.at('Form502 Subtractions TwoIncome')&.text,
'Text Box 68': @xml_document.at('Form502 TaxWithheld')&.text,
'Text Box 69': @xml_document.at('Form502 TaxWithheld')&.text.present? ? "00" : nil,
'Text Box 34': @xml_document.at('Form502 StateTaxComputation EarnedIncomeCredit')&.text,
'Check Box 37': checkbox_value(@xml_document.at('Form502 StateTaxComputation MDEICWithQualChildInd')&.text),
'Text Box 96': @xml_document.at('ReturnHeaderState Filer Primary USPhone')&.text,
Expand All @@ -93,6 +94,20 @@ def hash_for_pdf
'Text Box 36': @xml_document.at('Form502 StateTaxComputation PovertyLevelCredit')&.text,
'Text Box 40': @xml_document.at('Form502 StateTaxComputation TotalCredits')&.text,
'Text Box 42': @xml_document.at('Form502 StateTaxComputation StateTaxAfterCredits')&.text,
'Text Box 66': calculated_fields.fetch(:MD502_LINE_39),
'Text Box 67': "00",
'Text Box 72': calculated_fields.fetch(:MD502_LINE_42),
'Text Box 73': "00",
'Text Box 76': calculated_fields.fetch(:MD502_LINE_44),
'Text Box 77': "00",
'Text Box 78': calculated_fields.fetch(:MD502_LINE_45),
'Text Box 79': calculated_fields.fetch(:MD502_LINE_45).present? ? "00" : nil,
'Text Box 80': calculated_fields.fetch(:MD502_LINE_46),
'Text Box 81': calculated_fields.fetch(:MD502_LINE_46).present? ? "00" : nil,
'Text Box 84': calculated_fields.fetch(:MD502_LINE_48),
'Text Box 85': "00",
'Text Box 91': calculated_fields.fetch(:MD502_LINE_50),
'Text Box 92': "00",
'Enter local tax rate': @xml_document.at('Form502 LocalTaxComputation LocalTaxRate')&.text&.split('0.0')&.last,
'Text Box 44': @xml_document.at('Form502 LocalTaxComputation LocalIncomeTax')&.text,
'Text Box 46': @xml_document.at('Form502 LocalTaxComputation EarnedIncomeCredit')&.text,
Expand Down
8 changes: 7 additions & 1 deletion app/lib/pdf_filler/md_el101_pdf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,19 @@ def hash_for_pdf
'ERO firm name 2': @submission.data_source.spouse_esigned_yes? ? 'FileYourStateTaxes' : "",
'Primary Signature Pin': @xml_document.at('Primary TaxpayerPIN')&.text,
'Spouse Esigned': checkbox_value(@submission.data_source.spouse_esigned_yes?),
'Secondary Signature Pin': @xml_document.at('Secondary TaxpayerPIN')&.text
'Secondary Signature Pin': @xml_document.at('Secondary TaxpayerPIN')&.text,
'2 Amount of overpayment to be refunded to you 2': calculated_fields.fetch(:MD502_LINE_48),
'3': calculated_fields.fetch(:MD502_LINE_50),
}
end

def checkbox_value(condition)
condition ? 'On' : 'Off'
end

def calculated_fields
@calculated_fields ||= @submission.data_source.tax_calculator.calculate
end
end
end

15 changes: 13 additions & 2 deletions app/lib/submission_builder/ty2024/states/md/documents/md502.rb
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,22 @@ def document
add_element_if_present(xml, "LocalIncomeTax", :MD502_LINE_28_LOCAL_TAX_AMOUNT)
add_element_if_present(xml, "EarnedIncomeCredit", :MD502_LINE_29)
add_element_if_present(xml, "PovertyLevelCredit", :MD502_LINE_30)
add_element_if_present(xml,"TotalCredits", :MD502_LINE_32)
add_element_if_present(xml,"LocalTaxAfterCredits", :MD502_LINE_33)
add_element_if_present(xml, "TotalCredits", :MD502_LINE_32)
add_element_if_present(xml, "LocalTaxAfterCredits", :MD502_LINE_33)
end
add_element_if_present(xml, "TotalStateAndLocalTax", :MD502_LINE_34)
add_non_zero_value(xml, :TotalTaxAndContributions, :MD502_LINE_39)
xml.TaxWithheld calculated_fields.fetch(:MD502_LINE_40)
add_non_zero_value(xml, :RefundableEIC, :MD502_LINE_42)
add_non_zero_value(xml, :TotalPaymentsAndCredits, :MD502_LINE_44)
add_non_zero_value(xml, :BalanceDue, :MD502_LINE_45)
add_non_zero_value(xml, :Overpayment, :MD502_LINE_46)
if calculated_fields.fetch(:MD502_LINE_48).positive?
xml.AmountOverpayment do
xml.ToBeRefunded calculated_fields.fetch(:MD502_LINE_48)
end
end
add_non_zero_value(xml, :TotalAmountDue, :MD502_LINE_50)
xml.AuthToDirectDepositInd "X" if calculated_fields.fetch(:MD502_AUTHORIZE_DIRECT_DEPOSIT)
if @intake.payment_or_deposit_type.to_sym == :direct_deposit
xml.NameOnBankAccount do
Expand Down
165 changes: 163 additions & 2 deletions spec/lib/efile/md/md502_calculator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1124,6 +1124,27 @@
end
end

describe "#calculate_line_39" do
context "when there is a value for line 34" do
before do
allow_any_instance_of(described_class).to receive(:calculate_line_34).and_return 500
end

it "returns line 34" do
instance.calculate
expect(instance.lines[:MD502_LINE_39].value).to eq 500
end
end

context "when line 34 is nil" do
it "returns 0" do
allow_any_instance_of(described_class).to receive(:calculate_line_34).and_return nil
instance.calculate
expect(instance.lines[:MD502_LINE_39].value).to eq 0
end
end
end

describe "#calculate_line_28_local_tax_rate" do
let(:taxable_net_income) { 10_000 }
before do
Expand Down Expand Up @@ -1198,6 +1219,82 @@
end
end

describe "#calculate_line_42" do
let(:filing_status) { "head_of_household" }
let(:df_xml_key) { "md_laney_qss" }
let!(:intake) {
create(
:state_file_md_intake,
filing_status: filing_status,
raw_direct_file_data: StateFile::DirectFileApiResponseSampleService.new.read_xml(df_xml_key)
)
}
let(:federal_eic) { 1200 }

before do
intake.direct_file_data.fed_eic = federal_eic
allow_any_instance_of(described_class).to receive(:calculate_line_21).and_return 500
instance.calculate
end

context "when there is least one qualifying child" do
context "when federal EIC * .45 is equal to or greater than Maryland tax (line 21)" do
it 'refundable EIC equals (federal EIC * .45) - Maryland tax (line 21)' do
expect(instance.lines[:MD502_LINE_42].value).to eq 40 # .45 of 1200 is 540. 540 - 500
end
end

context "when federal EIC * .45 is less than than Maryland tax (line 21)" do
before do
intake.direct_file_data.fed_eic = federal_eic
allow_any_instance_of(described_class).to receive(:calculate_line_21).and_return 600
instance.calculate
end
it 'refundable EIC is 0' do
expect(instance.lines[:MD502_LINE_42].value).to eq 0
end
end
end

context "when mfj and no qualifying children" do
let(:filing_status) { "married_filing_jointly" }
let(:df_xml_key) { "md_zeus_two_w2s" }
it 'refundable EIC equals (federal EIC * .45) - Maryland tax (line 21)' do
expect(instance.lines[:MD502_LINE_42].value).to eq 40
end
end

context "when single and no qualifying children" do
let(:filing_status) { "single" }
let(:df_xml_key) { "md_zeus_two_w2s" }

context "when federal EIC is equal to or greater than Maryland tax (line 21)" do
it "refundable EIC equals - Maryland tax (line 21)" do
expect(instance.lines[:MD502_LINE_42].value).to eq 700
end
end

context "when federal EIC is less than than Maryland tax (line 21)" do
before do
intake.direct_file_data.fed_eic = federal_eic
allow_any_instance_of(described_class).to receive(:calculate_line_21).and_return 1500
instance.calculate
end
it 'refundable EIC is 0' do
expect(instance.lines[:MD502_LINE_42].value).to eq 0
end
end
end

context "when filing as a dependent and no qualifying children" do
let(:filing_status) { "dependent" }
let(:df_xml_key) { "md_zeus_two_w2s" }
it 'refundable EIC is nil' do
expect(instance.lines[:MD502_LINE_42].value).to eq nil
end
end
end

describe "#calculate_line_28_local_tax_amount" do
before do
allow_any_instance_of(described_class).to receive(:calculate_line_20).and_return 300_000
Expand Down Expand Up @@ -1258,6 +1355,68 @@
end
end

describe "#calculate_line_44" do
before do
allow_any_instance_of(described_class).to receive(:calculate_line_40).and_return 250
allow_any_instance_of(described_class).to receive(:calculate_line_42).and_return 200
allow_any_instance_of(described_class).to receive(:calculate_line_43).and_return 150
end
it "sums lines 40 to 44" do
instance.calculate
expect(instance.lines[:MD502_LINE_44].value).to eq(600)
end
end

describe "#calculate_line_45" do
context "line 39 is less than 44" do
before do
allow_any_instance_of(described_class).to receive(:calculate_line_39).and_return 50
allow_any_instance_of(described_class).to receive(:calculate_line_44).and_return 150
end
it "returns nil" do
instance.calculate
expect(instance.lines[:MD502_LINE_45].value).to eq(nil)
end
end

context "line 39 is more than 44" do
before do
allow_any_instance_of(described_class).to receive(:calculate_line_39).and_return 1_000
allow_any_instance_of(described_class).to receive(:calculate_line_44).and_return 900
end
it "subtracts line 39 from line 44" do
instance.calculate
expect(instance.lines[:MD502_LINE_45].value).to eq(100)
expect(instance.lines[:MD502_LINE_50].value).to eq(100)
end
end
end

describe "#calculate_line_46" do
context "line 39 is less than 44" do
before do
allow_any_instance_of(described_class).to receive(:calculate_line_39).and_return 900
allow_any_instance_of(described_class).to receive(:calculate_line_44).and_return 1_000
end
it "subtracts line 39 from line 44" do
instance.calculate
expect(instance.lines[:MD502_LINE_46].value).to eq(100)
expect(instance.lines[:MD502_LINE_48].value).to eq(100)
end
end

context "line 39 is more than 44" do
before do
allow_any_instance_of(described_class).to receive(:calculate_line_39).and_return 150
allow_any_instance_of(described_class).to receive(:calculate_line_44).and_return 50
end
it "returns nil" do
instance.calculate
expect(instance.lines[:MD502_LINE_46].value).to eq(nil)
end
end
end

describe "#calculate_line_30" do
context "deduction method is standard and they qualify for state poverty level credit" do
before do
Expand Down Expand Up @@ -1383,8 +1542,10 @@

describe "refund_or_owed_amount" do
it "subtracts owed amount from refund amount" do
# TEMP: stub calculator lines and test outcome of method once implemented
expect(instance.refund_or_owed_amount).to eq(0)
allow(instance).to receive(:calculate_line_48).and_return 0
allow(instance).to receive(:calculate_line_50).and_return -30
instance.calculate
expect(instance.refund_or_owed_amount).to eq(30)
end
end

Expand Down
Loading
Loading