Skip to content

Commit

Permalink
FYST-1827 Show errors for 1099-R on income review (#5657)
Browse files Browse the repository at this point in the history
Co-authored-by: Arin Choi <[email protected]>
  • Loading branch information
jenny-heath and arinchoi03 authored Mar 4, 2025
1 parent c0672c2 commit ff10d0f
Show file tree
Hide file tree
Showing 10 changed files with 173 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,14 @@ def update
private

def invalid_income_form?(intake)
intake.allows_w2_editing? && @w2s.any? do |w2|
has_invalid_w2 = intake.allows_w2_editing? && @w2s.any? do |w2|
w2.check_box14_limits = true
!w2.valid?(:state_file_income_review)
end
has_invalid_1099r = intake.allows_1099_r_editing? && intake.state_file1099_rs.any? do |form1099r|
!form1099r.valid?(:income_review)
end
has_invalid_w2 || has_invalid_1099r
end

def should_show_warning?(w2, w2_count_for_filer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,14 @@ module StateFile
module Questions
class RetirementIncomeController < QuestionsController
before_action :allows_1099_r_editing, only: [:edit, :update]
before_action :load_1099_r
before_action :load_warnings, only: [:edit]

def prev_path
StateFile::Questions::IncomeReviewController.to_path_helper(return_to_review: params[:return_to_review])
end

def show
@state_file1099_r = current_intake.state_file1099_rs.find(params[:id])
end

def edit
@state_file1099_r = current_intake.state_file1099_rs.find(params[:id])
end

def update
@state_file1099_r = current_intake.state_file1099_rs.find(params[:id])
@state_file1099_r.assign_attributes(state_file1099_r_params)

if @state_file1099_r.valid?(:retirement_income_intake)
Expand All @@ -29,6 +22,19 @@ def update

private

def load_1099_r
@state_file1099_r = current_intake.state_file1099_rs.find(params[:id])
end

def load_warnings
if @state_file1099_r.state_tax_withheld_amount == 0 || @state_file1099_r.state_tax_withheld_amount.nil?
@state_file1099_r.errors.add(:state_tax_withheld_amount, I18n.t("state_file.questions.retirement_income.edit.state_tax_withheld_absent_warning"))
end
if @state_file1099_r.state_tax_withheld_amount.present? && @state_file1099_r.state_tax_withheld_amount > @state_file1099_r.gross_distribution_amount
@state_file1099_r.errors.add(:state_tax_withheld_amount, I18n.t("activerecord.errors.models.state_file1099_r.errors.must_be_less_than_gross_distribution", gross_distribution_amount: @state_file1099_r.gross_distribution_amount))
end
end

def state_file1099_r_params
params.require(:state_file1099_r).permit(
:state_tax_withheld_amount,
Expand Down
39 changes: 19 additions & 20 deletions app/models/state_file1099_r.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,32 +53,31 @@ class StateFile1099R < ApplicationRecord

# Not adding validations for fields we just copy over from the DF XML, since we have no recourse if they fail
with_options on: :retirement_income_intake do
validate :less_than_gross_distribution, if: -> { gross_distribution_amount.present? }
validates :gross_distribution_amount, numericality: { greater_than: 0 }
validates :state_tax_withheld_amount,
numericality: {
greater_than_or_equal_to: 0,
},
presence: {
message: proc { I18n.t('forms.errors.no_money_amount') }
}

validates :state_distribution_amount,
numericality: {
greater_than_or_equal_to: 0,
},
presence: {
message: proc { I18n.t('forms.errors.no_money_amount') }
}
numericality: {
greater_than_or_equal_to: 0,
},
presence: {
message: proc { I18n.t('forms.errors.no_money_amount') }
}
validates :payer_state_identification_number, presence: true, length: { maximum: 16 }, if: -> { state_tax_withheld_amount&.positive? }
end

with_options on: [:income_review, :retirement_income_intake] do
validate :less_than_gross_distribution, if: -> { gross_distribution_amount.present? }
validates :state_tax_withheld_amount,
numericality: {
greater_than_or_equal_to: 0,
},
presence: {
message: proc { I18n.t('forms.errors.no_money_amount') }
}
end

def less_than_gross_distribution
[:state_tax_withheld_amount, :state_distribution_amount].each do |attr_name|
value = send(attr_name)
if value.present? && value > gross_distribution_amount
errors.add(attr_name, I18n.t("activerecord.errors.models.state_file_1099_r.errors.must_be_less_than_gross_distribution"))
end
if state_tax_withheld_amount.present? && state_tax_withheld_amount > gross_distribution_amount
errors.add(:state_tax_withheld_amount, I18n.t("activerecord.errors.models.state_file1099_r.errors.must_be_less_than_gross_distribution", gross_distribution_amount: gross_distribution_amount))
end
end
end
5 changes: 5 additions & 0 deletions app/views/state_file/questions/income_review/edit.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@
),
class: "button--small"
%>
<% if !state_1099r.valid?(:income_review) %>
<div class="notice--warning spacing-above-5">
<p><%= t(".warning") %></p>
</div>
<% end %>
<% else %>
<%= link_to t(".review_state_info"),
StateFile::Questions::RetirementIncomeController.to_path_helper(
Expand Down
5 changes: 3 additions & 2 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ en:
invalid: should be a five digit number beginning with 2
date_of_contribution:
inclusion: Date must be valid and in the current tax year
state_file_1099_r:
state_file1099_r:
errors:
must_be_less_than_gross_distribution: Must be less than gross distribution amount
must_be_less_than_gross_distribution: Box 14 State tax withheld cannot be greater than %{gross_distribution_amount}
attributes:
confirm_primary_ssn: Confirm SSN or ITIN
confirm_spouse_ssn: Confirm spouse's SSN or ITIN
Expand Down Expand Up @@ -3987,6 +3987,7 @@ en:
box14_html: "<b>Box 14</b>, State tax withheld"
box15_html: "<b>Box 15</b>, State/Payer’s State Number"
box16_html: "<b>Box 16</b>, State distribution"
state_tax_withheld_absent_warning: Please confirm that the amount in Box 14 on your 1099-R is 0
title_html: Please review your retirement income (1099-R) details for <strong>%{payer_name}</strong>.
retirement_income_subtraction:
doc_1099r_label: 1099-R
Expand Down
5 changes: 3 additions & 2 deletions config/locales/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ es:
invalid: Debe ser un número de cinco dígitos que comience con 2
date_of_contribution:
inclusion: La fecha debe ser válida y corresponder al año fiscal actual.
state_file_1099_r:
state_file1099_r:
errors:
must_be_less_than_gross_distribution: Debe ser menor que el monto bruto de distribución
must_be_less_than_gross_distribution: Box 14 State tax withheld cannot be greater than %{gross_distribution_amount}
attributes:
confirm_primary_ssn: Confirme el Número de Seguro Social (SSN) o Número de Identificación Personal (ITIN)
confirm_spouse_ssn: Confirme el Número de Seguro Social (SSN) o Número de Identificación Personal (ITIN) de su cónyuge
Expand Down Expand Up @@ -3973,6 +3973,7 @@ es:
box14_html: "<b>Casilla 14</b>, Impuesto estatal retenido"
box15_html: "<b>Casilla 15</b>, Número estatal del pagador"
box16_html: "<b>Casilla 16</b>, Distribución estatal"
state_tax_withheld_absent_warning: Please confirm that the amount in Box 14 on your 1099-R is 0
title_html: Por favor, revisa los detalles de los ingresos estatales (1099-R) que recibiste de <strong>%{payer_name}</strong>.
retirement_income_subtraction:
doc_1099r_label: 1099-R
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
let(:form_params) { params }
end

context "W-2 validity" do
context "income form validity" do
let(:mock_next_path) { root_path }
before do
allow(subject).to receive(:next_path).and_return mock_next_path
Expand Down Expand Up @@ -115,6 +115,13 @@

include_examples "proceeds as if there are no errors"
end

context "with 1099rs having invalid Box 14 values" do
let(:intake) { create(:state_file_md_intake) }
let!(:state_file1099_r) { create(:state_file1099_r, intake: intake, gross_distribution_amount: 500, state_tax_withheld_amount: 550) }

include_examples "shows error and does not proceed"
end
end
end

Expand Down Expand Up @@ -367,19 +374,50 @@
describe "1099R card" do
render_views

context "when there are state 1099Rs" do
it "shows a summary of each" do
primary_1099r = create(:state_file1099_r, intake: intake, payer_name: "Payeur", recipient_name: 'Prim Rose')
spouse_1099r = create(:state_file1099_r, intake: intake, payer_name: "Payure", recipient_name: 'Sprout Vine')
shared_examples "does not display 1099R warning" do
it "has no warnings" do
get :edit, params: params
expect(response.body).not_to have_text I18n.t("state_file.questions.income_review.edit.warning")
end
end

shared_examples "displays one 1099R warning" do
it "displays warning in 1099R card" do
get :edit, params: params
expect(response.body.scan(I18n.t("state_file.questions.income_review.edit.warning")).size).to eq(1)
end
end

context "when there are state 1099Rs" do
context "when 1099Rs are valid" do
let!(:primary_1099r) { create(:state_file1099_r, intake: intake, payer_name: "Payeur", recipient_name: "Prim Rose") }
let!(:spouse_1099r) { create(:state_file1099_r, intake: intake, payer_name: "Payure", recipient_name: "Sprout Vine") }

it_behaves_like "does not display 1099R warning"

it "shows a summary of each" do
get :edit, params: params

expect(response.body).to have_text "Retirement income (1099-R)"
expect(response.body).to have_text "Payeur"
expect(response.body).to have_text "Prim Rose"
expect(response.body).to have_link(href: edit_retirement_income_path(id: primary_1099r.id))
expect(response.body).to have_text "Payure"
expect(response.body).to have_text "Sprout Vine"
expect(response.body).to have_link(href: edit_retirement_income_path(id: spouse_1099r.id))
end
end

context "when a 1099R is blocking-invalid" do
let!(:invalid_1099r) { create(:state_file1099_r, intake: intake, gross_distribution_amount: 500, state_tax_withheld_amount: 550) }

it_behaves_like "displays one 1099R warning"
end

context "when a 1099R is nonblocking-invalid" do
let!(:invalid_1099r) { create(:state_file1099_r, intake: intake, payer_state_identification_number: "123456789asdfghjklqwertyuiop") }

expect(response.body).to have_text "Retirement income (1099-R)"
expect(response.body).to have_text "Payeur"
expect(response.body).to have_text "Prim Rose"
expect(response.body).to have_link(href: edit_retirement_income_path(id: primary_1099r.id))
expect(response.body).to have_text "Payure"
expect(response.body).to have_text "Sprout Vine"
expect(response.body).to have_link(href: edit_retirement_income_path(id: spouse_1099r.id))
it_behaves_like "does not display 1099R warning"
end
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
end
end


describe "#edit" do
let(:client) { intake.client }
let!(:form1099r) do
Expand All @@ -58,6 +57,38 @@
expect(response.body).to include("30")
expect(response.body).to include("40")
end

context "when there are box 14 warnings" do
context "state tax withheld more than gross distribution amount" do
let!(:form1099r) { create :state_file1099_r, state_tax_withheld_amount: 40, gross_distribution_amount: 30, intake: intake }

it "displays the errors on edit" do
get :edit, params: params

expect(response.body).to include I18n.t("activerecord.errors.models.state_file1099_r.errors.must_be_less_than_gross_distribution", gross_distribution_amount: 30)
end
end

context "state tax withheld amount nil" do
let!(:form1099r) { create :state_file1099_r, state_tax_withheld_amount: nil, intake: intake }

it "displays the errors on edit" do
get :edit, params: params

expect(response.body).to include I18n.t("state_file.questions.retirement_income.edit.state_tax_withheld_absent_warning")
end
end

context "state tax withheld amount is 0" do
let!(:form1099r) { create :state_file1099_r, state_tax_withheld_amount: 0, intake: intake }

it "displays the errors on edit" do
get :edit, params: params

expect(response.body).to include I18n.t("state_file.questions.retirement_income.edit.state_tax_withheld_absent_warning")
end
end
end
end

context "when the intake's 1099R is not editable" do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,9 @@
<F1099RStateLocalTaxGrp>
<F1099RStateTaxGrp>
<StateAbbreviationCd>ID</StateAbbreviationCd>
<PayerStateIdNum>123456789asdfghjklqwertyuiop</PayerStateIdNum>
<PayerStateIdNum>123456789</PayerStateIdNum>
<StateDistributionAmt>2000</StateDistributionAmt>
<StateTaxWithheldAmt>10</StateTaxWithheldAmt>
<StateTaxWithheldAmt>4001</StateTaxWithheldAmt>
<F1099RLocalTaxGrp>
<LocalTaxWithheldAmt>2000</LocalTaxWithheldAmt>
<LocalityNm>How Town</LocalityNm>
Expand Down
65 changes: 39 additions & 26 deletions spec/models/state_file1099_r_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,43 +61,57 @@
.with_message(I18n.t('forms.errors.no_money_amount'))
end

context "retirement_income_intake" do
context "both contexts" do
let!(:state_file1099_r) { create(:state_file1099_r, intake: create(:state_file_nc_intake)) }
let(:context) { :retirement_income_intake }

context "state_tax_withheld_amount and state_distribution_amount must be less than gross_distribution_amount" do
let(:state_file1099_r) {
create :state_file1099_r,
intake: create(:state_file_nc_intake),
gross_distribution_amount: gross_distribution_amount,
state_tax_withheld_amount: state_tax_withheld_amount,
state_distribution_amount: state_distribution_amount
}
[:retirement_income_intake, :income_review].each do |context_name|
context "state_tax_withheld_amount must be less than gross_distribution_amount" do
let(:state_file1099_r) {
create :state_file1099_r,
intake: create(:state_file_nc_intake),
gross_distribution_amount: gross_distribution_amount,
state_tax_withheld_amount: state_tax_withheld_amount
}

context "when the gross_distribution_amount is present" do
let(:gross_distribution_amount) { 100 }
context "when the gross_distribution_amount is present" do
let(:gross_distribution_amount) { 100 }

context "other values are less" do
let(:state_tax_withheld_amount) { 50 }
let(:state_distribution_amount) { 50 }
context "state tax withheld is less" do
let(:state_tax_withheld_amount) { 50 }

it "is valid" do
expect(state_file1099_r).to be_valid(context)
it "is valid" do
expect(state_file1099_r).to be_valid(context_name)
end
end
end

context "other values are greater" do
let(:state_tax_withheld_amount) { 200 }
let(:state_distribution_amount) { 200 }
context "state tax withheld is greater" do
let(:state_tax_withheld_amount) { 200 }

it "is invalid" do
expect(state_file1099_r).not_to be_valid(context)
expect(state_file1099_r.errors[:state_tax_withheld_amount]).to be_present
expect(state_file1099_r.errors[:state_distribution_amount]).to be_present
it "is invalid" do
expect(state_file1099_r).not_to be_valid(context_name)
expect(state_file1099_r.errors[:state_tax_withheld_amount]).to be_present
end
end
end
end

it "validates state_tax_withheld_amount is number if present" do
['string', -1].each do |val|
state_file1099_r.state_tax_withheld_amount = val
expect(state_file1099_r.valid?(context_name)).to eq false
end

[0, 1].each do |val|
state_file1099_r.state_tax_withheld_amount = val
expect(state_file1099_r.valid?(context_name)).to eq true
end
end
end
end

context "retirement_income_intake" do
let!(:state_file1099_r) { create(:state_file1099_r, intake: create(:state_file_nc_intake)) }
let(:context) { :retirement_income_intake }

it "validates gross_distribution_amount is present and a positive number" do
state_file1099_r.state_tax_withheld_amount = 0
Expand Down Expand Up @@ -128,7 +142,6 @@
expect(state_file1099_r.valid?(context)).to eq true
end
end

end

context "payer_state_identification_number" do
Expand Down

0 comments on commit ff10d0f

Please sign in to comment.