Skip to content

Commit e5ab999

Browse files
committed
Merge remote-tracking branch 'origin' into FYST-1842-editing-state-withholding-on-w-2-edit-screen-for-az-and-id-causes-error-on-final-review-page
2 parents 8f92ce1 + 0e5cde6 commit e5ab999

File tree

96 files changed

+5629
-285
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+5629
-285
lines changed

Gemfile.lock

+1-1
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ GEM
395395
net-protocol
396396
netrc (0.11.0)
397397
nio4r (2.7.3)
398-
nokogiri (1.16.8)
398+
nokogiri (1.18.3)
399399
mini_portile2 (~> 2.8.2)
400400
racc (~> 1.4)
401401
notiffany (0.1.3)

app/assets/stylesheets/_state-file.scss

+12
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,18 @@
360360
}
361361
}
362362
}
363+
364+
ul {
365+
list-style-type: disc;
366+
padding-left: 2rem;
367+
margin: 1rem 0;
368+
}
369+
370+
li {
371+
font-size: 1.6rem;
372+
line-height: 2.4rem;
373+
margin-bottom: 0.5rem;
374+
}
363375
}
364376

365377
.checkbox.is-selected {

app/controllers/state_file/archived_intakes/archived_intake_controller.rb

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
module StateFile
22
module ArchivedIntakes
33
class ArchivedIntakeController < ApplicationController
4+
layout "state_file"
45
before_action :check_feature_flag
56
def current_request
67
request = StateFileArchivedIntakeRequest.where("ip_address = ? AND LOWER(email_address) = LOWER(?)", ip_for_irs, session[:email_address]).first
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
module StateFile
2+
module Questions
3+
class IdDisabilityController < QuestionsController
4+
def self.show?(intake)
5+
Flipper.enabled?(:show_retirement_ui) &&
6+
intake.state_file1099_rs.any? { |form1099r| form1099r.taxable_amount&.to_f&.positive? } &&
7+
!intake.filing_status_mfs? && meets_age_requirements?(intake)
8+
end
9+
10+
def self.meets_age_requirements?(intake)
11+
primary_age = intake.calculate_age(intake.primary_birth_date, inclusive_of_jan_1: true)
12+
if intake.filing_status_mfj? && intake.spouse_birth_date.present?
13+
spouse_age = intake.calculate_age(intake.spouse_birth_date, inclusive_of_jan_1: true)
14+
(primary_age >= 62 && primary_age < 65) || (spouse_age >= 62 && spouse_age < 65)
15+
else
16+
primary_age >= 62 && primary_age < 65
17+
end
18+
end
19+
20+
private
21+
22+
def form_params
23+
params.require(:state_file_id_disability_form).permit(:mfj_disability, :primary_disabled, :spouse_disabled)
24+
end
25+
end
26+
end
27+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
module StateFile
2+
module Questions
3+
class IdRetirementAndPensionIncomeController < RetirementIncomeSubtractionController
4+
def self.show?(intake)
5+
Flipper.enabled?(:show_retirement_ui) && !intake.filing_status_mfs? &&
6+
has_eligible_1099rs?(intake)
7+
end
8+
9+
def self.has_eligible_1099rs?(intake)
10+
intake.state_file1099_rs.any? do |form1099r|
11+
form1099r.taxable_amount&.to_f&.positive? && person_qualifies?(form1099r, intake)
12+
end
13+
end
14+
15+
def self.person_qualifies?(form1099r, intake)
16+
primary_tin = intake.primary.ssn
17+
spouse_tin = intake.spouse&.ssn
18+
19+
case form1099r.recipient_ssn
20+
when primary_tin
21+
intake.primary_disabled_yes? || intake.primary_senior?
22+
when spouse_tin
23+
intake.spouse_disabled_yes? || intake.spouse_senior?
24+
else
25+
false
26+
end
27+
end
28+
29+
private
30+
31+
def person_qualifies?(form1099r)
32+
self.class.person_qualifies?(form1099r, current_intake)
33+
end
34+
35+
def eligible_1099rs
36+
@eligible_1099rs ||= current_intake.state_file1099_rs.select do |form1099r|
37+
form1099r.taxable_amount&.to_f&.positive? && person_qualifies?(form1099r)
38+
end
39+
end
40+
41+
def num_items
42+
eligible_1099rs.count
43+
end
44+
45+
def load_item(index)
46+
@state_file_1099r = eligible_1099rs[index]
47+
render "public_pages/page_not_found", status: 404 if @state_file_1099r.nil?
48+
end
49+
50+
def followup_class = StateFileId1099RFollowup
51+
end
52+
end
53+
end
+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
module StateFile
2+
class IdDisabilityForm < QuestionsForm
3+
set_attributes_for :intake, :primary_disabled, :spouse_disabled
4+
5+
attr_accessor :mfj_disability
6+
validates_presence_of :mfj_disability, if: -> { intake.filing_status_mfj?}
7+
validates :primary_disabled, inclusion: { in: %w[yes no], message: :blank }, unless: -> { intake.filing_status_mfj? }
8+
9+
def save
10+
if intake.filing_status_mfj?
11+
primary_eligible = eligible?(:primary)
12+
spouse_eligible = eligible?(:spouse)
13+
14+
case mfj_disability
15+
when "me"
16+
@intake.update(primary_disabled: primary_eligible ? "yes" : "no", spouse_disabled: "no")
17+
when "spouse"
18+
@intake.update(primary_disabled: "no", spouse_disabled: spouse_eligible ? "yes" : "no")
19+
when "both"
20+
@intake.update(
21+
primary_disabled: primary_eligible ? "yes" : "no",
22+
spouse_disabled: spouse_eligible ? "yes" : "no"
23+
)
24+
when "none"
25+
@intake.update(primary_disabled: "no", spouse_disabled: "no")
26+
end
27+
else
28+
@intake.update(attributes_for(:intake))
29+
end
30+
end
31+
32+
private
33+
34+
def eligible?(primary_or_spouse)
35+
person = intake.send(primary_or_spouse)
36+
birth_date = person.birth_date
37+
return false unless birth_date.present?
38+
39+
age = intake.calculate_age(birth_date, inclusive_of_jan_1: true)
40+
age_eligible = age >= 62 && age < 65
41+
42+
has_taxable_1099r = intake.state_file1099_rs.any? do |form|
43+
form.recipient_ssn == person.ssn && form.taxable_amount&.to_f&.positive?
44+
end
45+
46+
age_eligible && has_taxable_1099r
47+
end
48+
end
49+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
module StateFile
2+
class IdRetirementAndPensionIncomeForm < Form
3+
include FormAttributes
4+
5+
6+
set_attributes_for :state_file_id1099_r_followup, :eligible_income_source
7+
8+
validates :eligible_income_source, presence: true
9+
10+
def initialize(state_file_id1099_r_followup = nil, params = {})
11+
@state_file_id1099_r_followup = state_file_id1099_r_followup
12+
super(params)
13+
end
14+
15+
def save
16+
@state_file_id1099_r_followup.update(attributes_for(:state_file_id1099_r_followup))
17+
end
18+
end
19+
end

app/forms/state_file/md_permanently_disabled_form.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ def save
1212
if intake.filing_status_mfj?
1313
case mfj_disability
1414
when "me"
15-
@intake.update(primary_disabled: "yes", spouse_disabled: "no", proof_of_disability_submitted: proof_of_disability_submitted)
15+
@intake.update(primary_disabled: "yes", spouse_disabled: "no", proof_of_disability_submitted: proof_of_disability_submitted)
1616
when "spouse"
1717
@intake.update(primary_disabled: "no", spouse_disabled: "yes", proof_of_disability_submitted: proof_of_disability_submitted)
1818
when "both"

app/jobs/state_file/import_from_direct_file_job.rb

+29-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ def perform(authorization_code:, intake:)
77
direct_file_json = IrsApiService.import_federal_data(authorization_code, intake.state_code)
88

99
if direct_file_json.blank?
10-
raise StandardError, "Direct file data was not transferred for intake #{intake.state_code} #{intake.id}."
10+
raise StandardError, "Direct file data was not transferred for intake #{intake.state_code}#{intake.id}."
1111
end
1212

1313
intake.update(
@@ -34,6 +34,11 @@ def perform(authorization_code:, intake:)
3434
intake.synchronize_df_w2s_to_database
3535
intake.synchronize_filers_to_database
3636

37+
# removing duplicate associations here because sometimes we create duplicate records during data import
38+
# future work will prevent this issue from happening and this can be removed
39+
remove_duplicate_w2s(intake)
40+
remove_duplicate_dependents(intake)
41+
3742
intake.update(df_data_import_succeeded_at: DateTime.now)
3843
rescue => err
3944
Rails.logger.error(err)
@@ -46,5 +51,28 @@ def perform(authorization_code:, intake:)
4651
def priority
4752
PRIORITY_LOW
4853
end
54+
55+
private
56+
57+
def remove_duplicates(intake, collection, identifying_attribute_name)
58+
values = []
59+
collection.each do |record|
60+
value = record.send(identifying_attribute_name)
61+
if values.include?(value)
62+
Rails.logger.info("ImportFromDirectFileJob removing duplicate #{record.class&.name} for #{intake&.state_code}#{intake&.id}")
63+
record.destroy!
64+
else
65+
values.push(value)
66+
end
67+
end
68+
end
69+
70+
def remove_duplicate_w2s(intake)
71+
remove_duplicates(intake, intake.state_file_w2s, :w2_index)
72+
end
73+
74+
def remove_duplicate_dependents(intake)
75+
remove_duplicates(intake, intake.dependents, :ssn)
76+
end
4977
end
5078
end

app/lib/efile/id/id39_r_calculator.rb

+40-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,12 @@ def calculate
1616
set_line(:ID39R_B_LINE_3, :calculate_sec_b_line_3)
1717
set_line(:ID39R_B_LINE_7, :calculate_sec_b_line_7)
1818
set_line(:ID39R_B_LINE_6, :calculate_sec_b_line_6)
19-
set_line(:ID39R_B_LINE_8f, -> { 0 })
19+
set_line(:ID39R_B_LINE_8a, :calculate_sec_b_line_8a)
20+
set_line(:ID39R_B_LINE_8b, -> { 0 })
21+
set_line(:ID39R_B_LINE_8c, :calculate_sec_b_line_8c)
22+
set_line(:ID39R_B_LINE_8d, :calculate_sec_b_line_8d)
23+
set_line(:ID39R_B_LINE_8e, :calculate_sec_b_line_8e)
24+
set_line(:ID39R_B_LINE_8f, :calculate_sec_b_line_8f)
2025
set_line(:ID39R_B_LINE_18, :calculate_sec_b_line_18)
2126
set_line(:ID39R_B_LINE_24, :calculate_sec_b_line_24)
2227
set_line(:ID39R_D_LINE_4, -> { 0 })
@@ -63,6 +68,40 @@ def calculate_sec_b_line_7
6368
@direct_file_data.fed_taxable_ssb&.round || 0
6469
end
6570

71+
def calculate_sec_b_line_8a
72+
if @intake.filing_status_single? || @intake.filing_status_hoh? || @intake.filing_status_qw?
73+
45_864
74+
elsif @intake.filing_status_mfj?
75+
68_796
76+
end
77+
end
78+
79+
def calculate_sec_b_line_8c
80+
@direct_file_data.fed_ssb
81+
end
82+
83+
def calculate_sec_b_line_8d
84+
[line_or_zero(:ID39R_B_LINE_8a) - (line_or_zero(:ID39R_B_LINE_8b) + line_or_zero(:ID39R_B_LINE_8c)), 0].max
85+
end
86+
87+
def calculate_sec_b_line_8e
88+
@intake.state_file1099_rs.sum do |form1099r|
89+
if form1099r.state_specific_followup&.eligible_income_source_yes? && form1099r.taxable_amount.present?
90+
form1099r.taxable_amount.round
91+
else
92+
0
93+
end
94+
end
95+
end
96+
97+
def calculate_sec_b_line_8f
98+
if Flipper.enabled?(:show_retirement_ui)
99+
[line_or_zero(:ID39R_B_LINE_8d), line_or_zero(:ID39R_B_LINE_8e)].min
100+
else
101+
0
102+
end
103+
end
104+
66105
def calculate_sec_b_line_18
67106
@intake.has_health_insurance_premium_yes? ? @intake.health_insurance_paid_amount&.round : 0
68107
end

app/lib/efile/id/id40_calculator.rb

+3-1
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,9 @@ def calculate_line_43
253253
def calculate_line_46
254254
@intake.state_file_w2s.sum { |item| item.state_income_tax_amount.round } +
255255
@intake.state_file1099_gs.sum { |item| item.state_income_tax_withheld_amount.round } +
256-
@intake.state_file1099_rs.sum { |item| item.state_tax_withheld_amount.round }
256+
@intake.state_file1099_rs.sum do |item|
257+
item.state_tax_withheld_amount&.round || 0
258+
end
257259
end
258260

259261
def calculate_line_50

app/lib/efile/line_data.yml

+11-1
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,18 @@ ID39R_B_LINE_6:
174174
label: '6. Child/dependent care. Complete worksheet on page 30, and include federal Form 2441'
175175
ID39R_B_LINE_7:
176176
label: '7. Social security and railroad benefits, if included on federal income'
177+
ID39R_B_LINE_8a:
178+
label: '8a. If single, enter $45,864 or if married filing jointly, enter $68,796'
179+
ID39R_B_LINE_8b:
180+
label: '8b. Federal Railroad Retirement benefits received'
181+
ID39R_B_LINE_8c:
182+
label: '8c. Social Security benefits received'
183+
ID39R_B_LINE_8d:
184+
label: '8d. Line 8a minus lines 8b and 8c. If less than zero, enter zero'
185+
ID39R_B_LINE_8e:
186+
label: '8e. Qualifying retirement benefits included in federal income'
177187
ID39R_B_LINE_8f:
178-
label: '8f. Retirement benefits deduction (currently set to 0)'
188+
label: '8f. Retirement benefits deduction. Enter the smaller of line 8d or 8e here'
179189
ID39R_B_LINE_18:
180190
label: '18. Health insurance premium paid amount for household'
181191
ID39R_B_LINE_24:

app/lib/efile/md/md502_su_calculator.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def calculate
2525

2626
def calculate_military_per_filer(filer)
2727
age_benefits = @intake.is_filer_55_and_older?(filer) ? 20_000 : 12_500
28-
[@intake.sum_1099_r_followup_type_for_filer(:primary, :service_type_military?), age_benefits].min
28+
[@intake.sum_1099_r_followup_type_for_filer(filer, :service_type_military?), age_benefits].min
2929
end
3030

3131
def calculate_public_safety_employee(filer)

app/lib/efile/nc/d400_calculator.rb

+12
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,12 @@ def calculate_line_20a
170170
end
171171
end
172172

173+
@intake.state_file1099_rs.each do |state_file_1099_r|
174+
if state_file_1099_r.recipient_ssn == @intake.primary.ssn
175+
sum += state_file_1099_r.state_tax_withheld_amount&.round
176+
end
177+
end
178+
173179
sum
174180
end
175181

@@ -188,6 +194,12 @@ def calculate_line_20b
188194
end
189195
end
190196

197+
@intake.state_file1099_rs.each do |state_file_1099_r|
198+
if state_file_1099_r.recipient_ssn == @intake.spouse.ssn
199+
sum += state_file_1099_r.state_tax_withheld_amount&.round
200+
end
201+
end
202+
191203
sum
192204
end
193205

0 commit comments

Comments
 (0)