From 6d3611a6cd400660cd975139b24002a54226a729 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 8 Oct 2024 13:01:26 -0400 Subject: [PATCH 1/5] Add medical expenses to nj intake --- .../nj_medical_expenses_controller.rb | 9 +++ .../state_file/nj_medical_expenses_form.rb | 15 +++++ app/helpers/vita_min_form_builder.rb | 26 ++++---- app/lib/efile/line_data.yml | 2 + app/lib/efile/nj/nj1040_calculator.rb | 11 +++- .../state_file_nj_question_navigation.rb | 1 + app/lib/pdf_filler/nj1040_pdf.rb | 14 ++++ .../ty2024/states/nj/documents/nj1040.rb | 5 ++ app/models/state_file_nj_intake.rb | 1 + .../nj_medical_expenses/edit.html.erb | 41 ++++++++++++ .../questions/nj_review/edit.html.erb | 11 ++++ config/locales/en.yml | 23 +++++++ config/locales/es.yml | 23 +++++++ ...10254_add_medical_expenses_to_nj_intake.rb | 5 ++ db/schema.rb | 1 + .../questions/nj_medical_expenses.rb | 35 ++++++++++ spec/factories/state_file_nj_intakes.rb | 1 + .../nj_medical_expenses_form_spec.rb | 64 +++++++++++++++++++ spec/lib/efile/nj/nj1040_calculator_spec.rb | 49 ++++++++++++++ spec/lib/pdf_filler/nj1040_pdf_spec.rb | 48 ++++++++++++++ .../ty2024/states/nj/documents/nj1040_spec.rb | 27 ++++++++ spec/models/efile_error_spec.rb | 1 + spec/models/state_file_nj_intake_spec.rb | 1 + 23 files changed, 401 insertions(+), 13 deletions(-) create mode 100644 app/controllers/state_file/questions/nj_medical_expenses_controller.rb create mode 100644 app/forms/state_file/nj_medical_expenses_form.rb create mode 100644 app/views/state_file/questions/nj_medical_expenses/edit.html.erb create mode 100644 db/migrate/20241007210254_add_medical_expenses_to_nj_intake.rb create mode 100644 spec/controllers/state_file/questions/nj_medical_expenses.rb create mode 100644 spec/forms/state_file/nj_medical_expenses_form_spec.rb diff --git a/app/controllers/state_file/questions/nj_medical_expenses_controller.rb b/app/controllers/state_file/questions/nj_medical_expenses_controller.rb new file mode 100644 index 0000000000..14707f8941 --- /dev/null +++ b/app/controllers/state_file/questions/nj_medical_expenses_controller.rb @@ -0,0 +1,9 @@ +module StateFile + module Questions + class NjMedicalExpensesController < QuestionsController + include ReturnToReviewConcern + + before_action -> { @filing_year = Rails.configuration.statefile_current_tax_year } + end + end +end diff --git a/app/forms/state_file/nj_medical_expenses_form.rb b/app/forms/state_file/nj_medical_expenses_form.rb new file mode 100644 index 0000000000..9e612592d7 --- /dev/null +++ b/app/forms/state_file/nj_medical_expenses_form.rb @@ -0,0 +1,15 @@ +module StateFile + class NjMedicalExpensesForm < QuestionsForm + set_attributes_for :intake, + :medical_expenses + + validates_numericality_of :medical_expenses, only_integer: true, message: :round_to_whole_number, if: -> { medical_expenses.present? } + validates :medical_expenses, presence: true, allow_blank: false, numericality: { greater_than_or_equal_to: 0 }, if: -> { medical_expenses.present? } + + def save + unless medical_expenses.nil? + @intake.update(attributes_for(:intake)) + end + end + end +end \ No newline at end of file diff --git a/app/helpers/vita_min_form_builder.rb b/app/helpers/vita_min_form_builder.rb index 4a22f6b875..2b2a02d934 100644 --- a/app/helpers/vita_min_form_builder.rb +++ b/app/helpers/vita_min_form_builder.rb @@ -71,14 +71,14 @@ def vita_min_state_file_select( html_options_with_errors = html_options.merge(error_attributes(method: method)) html_output = <<~HTML -
- #{formatted_label} -
- #{select(method, collection, options, html_options_with_errors, &block)} -
- #{errors_for(object, method)} -
- HTML +
+ #{formatted_label} +
+ #{select(method, collection, options, html_options_with_errors, &block)} +
+ #{errors_for(object, method)} +
+ HTML html_output.html_safe end @@ -282,11 +282,12 @@ def vita_min_money_field( method, label_text, options: {}, - classes: [] + classes: [], + help_text: nil ) text_field_options = standard_options.merge( class: (classes + ["text-input money-input"]).join(" "), - ).merge(options).merge(error_attributes(method: method)).merge(placeholder: '0.00') + ).merge(error_attributes(method: method)).merge(placeholder: '0.00').merge(options) text_field_options[:id] ||= sanitized_id(method) options[:input_id] ||= sanitized_id(method) @@ -301,6 +302,7 @@ def vita_min_money_field( prefix: '$', options: options, wrapper_classes: wrapper_classes, + help_text: help_text ) html_output = <<~HTML @@ -412,9 +414,9 @@ def continue(value = I18n.t("general.continue")) def warning_for_select(element_id, permitted_values, msg) @template.content_tag(:div, msg, class: "warning warning-for-select", - "data-warning-for-select": element_id, + 'data-warning-for-select': element_id, style: "display:none", - "data-permitted": permitted_values.to_json + 'data-permitted': permitted_values.to_json ) end end diff --git a/app/lib/efile/line_data.yml b/app/lib/efile/line_data.yml index 942304a8dd..1cbaf38dd9 100644 --- a/app/lib/efile/line_data.yml +++ b/app/lib/efile/line_data.yml @@ -578,6 +578,8 @@ NJ1040_LINE_27: label: '27 Total Income (Add lines 15, 16a, and 20a)' NJ1040_LINE_29: label: "29 New Jersey Gross Income (Subtract line 28c from line 27) (See instructions)" +NJ1040_LINE_31: + label: "Medical Expenses (See Worksheet F and instructions)" NJ1040_LINE_38: label: "38 Total Exemptions and Deductions (Add lines 30 through 37c)" NJ1040_LINE_39: diff --git a/app/lib/efile/nj/nj1040_calculator.rb b/app/lib/efile/nj/nj1040_calculator.rb index 3e2d8838ea..744527ef00 100644 --- a/app/lib/efile/nj/nj1040_calculator.rb +++ b/app/lib/efile/nj/nj1040_calculator.rb @@ -20,6 +20,7 @@ def calculate set_line(:NJ1040_LINE_15, :calculate_line_15) set_line(:NJ1040_LINE_27, :calculate_line_27) set_line(:NJ1040_LINE_29, :calculate_line_29) + set_line(:NJ1040_LINE_31, :calculate_line_31) set_line(:NJ1040_LINE_38, :calculate_line_38) set_line(:NJ1040_LINE_39, :calculate_line_39) set_line(:NJ1040_LINE_40A, :calculate_line_40a) @@ -186,8 +187,16 @@ def calculate_line_29 calculate_line_27 end + def calculate_line_31 + two_percent_gross = calculate_line_29 * 0.02 + difference_with_med_expenses = @intake.medical_expenses - two_percent_gross + rounded_difference = difference_with_med_expenses.round + return rounded_difference if rounded_difference.positive? + nil + end + def calculate_line_38 - calculate_line_13 + calculate_line_13 + line_or_zero(:NJ1040_LINE_31) end def calculate_line_39 diff --git a/app/lib/navigation/state_file_nj_question_navigation.rb b/app/lib/navigation/state_file_nj_question_navigation.rb index e6cbf0c245..be7151454f 100644 --- a/app/lib/navigation/state_file_nj_question_navigation.rb +++ b/app/lib/navigation/state_file_nj_question_navigation.rb @@ -31,6 +31,7 @@ class StateFileNjQuestionNavigation < Navigation::StateFileBaseQuestionNavigatio Navigation::NavigationStep.new(StateFile::Questions::NameDobController), Navigation::NavigationStep.new(StateFile::Questions::NjCountyController), Navigation::NavigationStep.new(StateFile::Questions::NjMunicipalityController), + Navigation::NavigationStep.new(StateFile::Questions::NjMedicalExpensesController), Navigation::NavigationStep.new(StateFile::Questions::NjHouseholdRentOwnController), Navigation::NavigationStep.new(StateFile::Questions::NjHomeownerEligibilityController), Navigation::NavigationStep.new(StateFile::Questions::NjTenantEligibilityController), diff --git a/app/lib/pdf_filler/nj1040_pdf.rb b/app/lib/pdf_filler/nj1040_pdf.rb index 211cbb4f98..558b25c53b 100644 --- a/app/lib/pdf_filler/nj1040_pdf.rb +++ b/app/lib/pdf_filler/nj1040_pdf.rb @@ -124,6 +124,20 @@ def hash_for_pdf ])) end + if @xml_document.at("Body MedicalExpenses") + medical_expenses = @xml_document.at("Body MedicalExpenses").text.to_i + answers.merge!(insert_digits_into_fields(medical_expenses, [ + "219", + "undefined_93", + "218", + "217", + "undefined_92", + "216", + "215", + "31" + ])) + end + if @xml_document.at("TotalExemptDeductions") total_exemptions = @xml_document.at("TotalExemptDeductions").text.to_i answers.merge!(insert_digits_into_fields(total_exemptions, [ diff --git a/app/lib/submission_builder/ty2024/states/nj/documents/nj1040.rb b/app/lib/submission_builder/ty2024/states/nj/documents/nj1040.rb index 75fb4ee9df..241b4be2df 100644 --- a/app/lib/submission_builder/ty2024/states/nj/documents/nj1040.rb +++ b/app/lib/submission_builder/ty2024/states/nj/documents/nj1040.rb @@ -109,6 +109,11 @@ def document end xml.TotalExemptionAmountB calculated_fields.fetch(:NJ1040_LINE_13) + + if calculated_fields.fetch(:NJ1040_LINE_31) + xml.MedicalExpenses calculated_fields.fetch(:NJ1040_LINE_31) + end + xml.TotalExemptDeductions calculated_fields.fetch(:NJ1040_LINE_38) if calculated_fields.fetch(:NJ1040_LINE_39) > 0 diff --git a/app/models/state_file_nj_intake.rb b/app/models/state_file_nj_intake.rb index faaad971d0..4c4bb38b83 100644 --- a/app/models/state_file_nj_intake.rb +++ b/app/models/state_file_nj_intake.rb @@ -36,6 +36,7 @@ # last_sign_in_ip :inet # locale :string default("en") # locked_at :datetime +# medical_expenses :integer default(0), not null # message_tracker :jsonb # municipality_code :string # municipality_name :string diff --git a/app/views/state_file/questions/nj_medical_expenses/edit.html.erb b/app/views/state_file/questions/nj_medical_expenses/edit.html.erb new file mode 100644 index 0000000000..f9029fa903 --- /dev/null +++ b/app/views/state_file/questions/nj_medical_expenses/edit.html.erb @@ -0,0 +1,41 @@ +<% + title = t(".title", filing_year: @filing_year) + content_for :page_title, title +%> + +<% content_for :card do %> +

<%= t(".title") %>

+ + + <%= form_with model: @form, url: { action: :update }, local: true, method: "put", builder: VitaMinFormBuilder do |f| %> +
+ <%= f.vita_min_money_field( + :medical_expenses, + t('.label', filing_year: @filing_year), + help_text: t('.help_text'), + classes: ["form-width--long"], + options: { placeholder: "" } + ) %> +
+ +
+

+ +

+
+

<%= t('.learn_more_meaning') %>:

+
    <%= t('.learn_more_content_html') %>
+

<%= t('.learn_more_note_html') %>

+
+
+ + <% if params[:return_to_review].present? %> + <%= hidden_field_tag "return_to_review", params[:return_to_review] %> + <% end %> + <%= f.continue %> + <% end %> +<% end %> diff --git a/app/views/state_file/questions/nj_review/edit.html.erb b/app/views/state_file/questions/nj_review/edit.html.erb index c31209f97e..fb92ab22bf 100644 --- a/app/views/state_file/questions/nj_review/edit.html.erb +++ b/app/views/state_file/questions/nj_review/edit.html.erb @@ -61,6 +61,17 @@ <% end %> + +
+
+

<%=t(".medical_expenses") %>

+

<%= number_to_currency(current_intake.medical_expenses) %>

+ <%= link_to StateFile::Questions::NjMedicalExpensesController.to_path_helper(return_to_review: "y"), class: "button--small" do %> + <%= t("general.edit") %> + <%= t(".medical_expenses") %> + <% end %> +
+
<%= render "state_file/questions/shared/review_footer" %> <% end %> \ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml index a3d1e2b23b..2977a75597 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -2639,6 +2639,28 @@ en: edit: helper_description: Please continue to see what else we can guide you to qualify for. title: Looks like you’re not eligible for this credit. + nj_medical_expenses: + edit: + description: |- +
  • This includes expenses for yourself, your spouse, and your dependents.
  • +
  • Only expenses that exceed 2% of your gross income may be deducted.
  • +
  • You can’t deduct expenses for which you were reimbursed through your health insurance plan.
  • + help_text: If you do not want to claim this deduction, click “Continue”. + label: Non-reimbursed medical expenses paid in %{filing_year} + learn_more_content_html: |- +
  • Physicians, dental, and other medical fees
  • Prescription eyeglasses and contact lenses
  • +
  • Hospital care
  • +
  • Nursing care
  • +
  • Medicines and drugs
  • Prosthetic devices
  • +
  • X‑rays and other diagnostic services conducted by or directed by a physician or dentist
  • +
  • Amounts paid for transportation primarily for and essential to medical care
  • +
  • Insurance (including amounts paid as premiums under Part B of Title XVIII of the Social Security Act, relating to supplementary medical insurance for the aged) covering medical care
  • + learn_more_meaning: Medical expenses means non-reimbursed payments for costs such as + learn_more_note_html: |- + Note: In NJ, if you are paying for your adult child’s health insurance (ages 18 to 27), this can only be deducted as a medical expense if the child was your dependent. + learn_more_title: What are medical expenses? + title: You can deduct medical expenses nj_municipality: edit: helper_description_html: If the place where you live is not listed, use the NJ state locality tool to get the name of your municipality. @@ -2649,6 +2671,7 @@ en: edit: county: County household_rent_own: Rent or own home + medical_expenses: Medical expenses municipality: Municipality primary_disabled: I have a disability property_tax_paid: Property taxes paid diff --git a/config/locales/es.yml b/config/locales/es.yml index f02e6dc615..f825a05729 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -2613,6 +2613,28 @@ es: edit: helper_description: Continúe viendo para qué más podemos ayudarlo a calificar. title: Parece que no eres elegible para este crédito. + nj_medical_expenses: + edit: + description: |- +
  • This includes expenses for yourself, your spouse, and your dependents.
  • +
  • Only expenses that exceed 2% of your gross income may be deducted.
  • +
  • You can’t deduct expenses for which you were reimbursed through your health insurance plan.
  • + help_text: If you do not want to claim this deduction, click “Continue”. + label: Non-reimbursed medical expenses paid in %{filing_year} + learn_more_content_html: |- +
  • Physicians, dental, and other medical fees
  • Prescription eyeglasses and contact lenses
  • +
  • Hospital care
  • +
  • Nursing care
  • +
  • Medicines and drugs
  • Prosthetic devices
  • +
  • X‑rays and other diagnostic services conducted by or directed by a physician or dentist
  • +
  • Amounts paid for transportation primarily for and essential to medical care
  • +
  • Insurance (including amounts paid as premiums under Part B of Title XVIII of the Social Security Act, relating to supplementary medical insurance for the aged) covering medical care
  • + learn_more_meaning: Medical expenses means non-reimbursed payments for costs such as + learn_more_note_html: |- + Note: In NJ, if you are paying for your adult child’s health insurance (ages 18 to 27), this can only be deducted as a medical expense if the child was your dependent. + learn_more_title: What are medical expenses? + title: You can deduct medical expenses nj_municipality: edit: helper_description_html: Si el lugar donde usted vive no aparece en la lista, utilice la herramienta de localidad del estado de New Jersey para obtener el nombre de su municipio. @@ -2623,6 +2645,7 @@ es: edit: county: Condado household_rent_own: Vivienda en alquiler o en propiedad propia + medical_expenses: Gastos médicos municipality: Municipio primary_disabled: Primary disabled property_tax_paid: Impuestos sobre la propiedad pagados diff --git a/db/migrate/20241007210254_add_medical_expenses_to_nj_intake.rb b/db/migrate/20241007210254_add_medical_expenses_to_nj_intake.rb new file mode 100644 index 0000000000..8d2eb35c29 --- /dev/null +++ b/db/migrate/20241007210254_add_medical_expenses_to_nj_intake.rb @@ -0,0 +1,5 @@ +class AddMedicalExpensesToNjIntake < ActiveRecord::Migration[7.1] + def change + add_column :state_file_nj_intakes, :medical_expenses, :integer, default: 0, null: false + end +end diff --git a/db/schema.rb b/db/schema.rb index 1826a40d2c..ae2de6dc14 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -2062,6 +2062,7 @@ t.inet "last_sign_in_ip" t.string "locale", default: "en" t.datetime "locked_at" + t.integer "medical_expenses", default: 0, null: false t.jsonb "message_tracker", default: {} t.string "municipality_code" t.string "municipality_name" diff --git a/spec/controllers/state_file/questions/nj_medical_expenses.rb b/spec/controllers/state_file/questions/nj_medical_expenses.rb new file mode 100644 index 0000000000..8da9241be2 --- /dev/null +++ b/spec/controllers/state_file/questions/nj_medical_expenses.rb @@ -0,0 +1,35 @@ +require "rails_helper" + +RSpec.describe StateFile::Questions::NjCountyController do + let(:intake) { create :state_file_nj_intake } + before do + sign_in intake + end + + describe "#edit" do + render_views + it 'succeeds' do + get :edit + expect(response).to be_successful + end + + describe "#update" do + context "when a user has medical expenses" do + let(:form_params) { + { + state_file_nj_medical_expenses_form: { + medical_expenses: 1000, + } + } + } + + it "saves the correct value for renter" do + post :update, params: form_params + + intake.reload + expect(intake.medical_expenses).to eq 1000 + end + end + end + end +end \ No newline at end of file diff --git a/spec/factories/state_file_nj_intakes.rb b/spec/factories/state_file_nj_intakes.rb index fb3bd0f9a0..2ca083ba11 100644 --- a/spec/factories/state_file_nj_intakes.rb +++ b/spec/factories/state_file_nj_intakes.rb @@ -36,6 +36,7 @@ # last_sign_in_ip :inet # locale :string default("en") # locked_at :datetime +# medical_expenses :integer default(0), not null # message_tracker :jsonb # municipality_code :string # municipality_name :string diff --git a/spec/forms/state_file/nj_medical_expenses_form_spec.rb b/spec/forms/state_file/nj_medical_expenses_form_spec.rb new file mode 100644 index 0000000000..2a02b39c68 --- /dev/null +++ b/spec/forms/state_file/nj_medical_expenses_form_spec.rb @@ -0,0 +1,64 @@ +require "rails_helper" + +RSpec.describe StateFile::NjMedicalExpensesForm do + let(:intake) { create :state_file_nj_intake } + + describe "validations" do + let(:form) { described_class.new(intake, invalid_params) } + + context "invalid params" do + context "must be numeric" do + let(:invalid_params) do + { medical_expenses: "awefwaefw" } + end + + it "is invalid" do + expect(form.valid?).to eq false + expect(form.errors[:medical_expenses]).to include "Round to the nearest whole number" + end + end + + context "must be an integer only" do + let(:invalid_params) do + { medical_expenses: 123.45 } + end + + it "is invalid" do + expect(form.valid?).to eq false + expect(form.errors[:medical_expenses]).to include "Round to the nearest whole number" + end + end + + context "cannot be negative" do + let(:invalid_params) do + { medical_expenses: "-123" } + end + + it "is invalid" do + expect(form.valid?).to eq false + expect(form.errors[:medical_expenses]).to include "must be greater than or equal to 0" + end + end + end + end + + describe ".save" do + let(:intake) { + create :state_file_nj_intake, medical_expenses: 0 + } + let(:form) { described_class.new(intake, valid_params) } + + context "when saving medical expenses" do + let(:valid_params) do + { medical_expenses: 12345 } + end + + it "saves attributes" do + expect(form.valid?).to eq true + form.save + + expect(intake.medical_expenses).to eq 12345 + end + end + end +end diff --git a/spec/lib/efile/nj/nj1040_calculator_spec.rb b/spec/lib/efile/nj/nj1040_calculator_spec.rb index fa0aa41c72..1bbf391df7 100644 --- a/spec/lib/efile/nj/nj1040_calculator_spec.rb +++ b/spec/lib/efile/nj/nj1040_calculator_spec.rb @@ -352,6 +352,55 @@ def over_65_birth_year end end + describe 'line 31 - medical expenses' do + let(:intake) { create(:state_file_nj_intake, medical_expenses: medical_expenses)} + + before do + allow(instance).to receive(:calculate_line_29).and_return gross_income + allow(instance).to receive(:calculate_line_13).and_return 1000 + instance.calculate + end + + context 'when gross income is 0' do + let(:gross_income) { 0 } + let(:medical_expenses) { 1234 } + + it 'sets line 31 to the entire cost of medical expenses' do + expect(instance.lines[:NJ1040_LINE_31].value).to eq(1234) + end + + it 'includes medical expenses in line 38' do + expect(instance.lines[:NJ1040_LINE_38].value).to eq(2234) + end + end + + context 'when medical expenses exceed 2% of gross income' do + let(:gross_income) { 10_000 } + let(:medical_expenses) { 201 } + + it 'sets line 31 to medical expenses minus $200' do + expect(instance.lines[:NJ1040_LINE_31].value).to eq(1) + end + + it 'includes medical expenses in line 38' do + expect(instance.lines[:NJ1040_LINE_38].value).to eq(1001) + end + end + + context 'when medical expenses do not exceed 2% of gross income' do + let(:gross_income) { 10_000 } + let(:medical_expenses) { 199 } + + it 'does not set a value for line 31' do + expect(instance.lines[:NJ1040_LINE_31].value).to eq(nil) + end + + it 'does not alter line 38' do + expect(instance.lines[:NJ1040_LINE_38].value).to eq(1000) + end + end + end + describe 'line 38 - total exemptions/deductions' do let(:intake) { create(:state_file_nj_intake, :primary_over_65, :primary_blind) } it 'sets line 38 to the total exemption amount' do diff --git a/spec/lib/pdf_filler/nj1040_pdf_spec.rb b/spec/lib/pdf_filler/nj1040_pdf_spec.rb index 6d870c5841..242e547eab 100644 --- a/spec/lib/pdf_filler/nj1040_pdf_spec.rb +++ b/spec/lib/pdf_filler/nj1040_pdf_spec.rb @@ -899,6 +899,54 @@ end end + describe "line 31 medical expenses" do + context "with a gross income of 200k" do + let(:submission) { + create :efile_submission, tax_return: nil, data_source: create( + :state_file_nj_intake, + :df_data_many_w2s, + medical_expenses: 567_890 + ) + } + it "writes sum $563,890.00 to fill boxes on line 31" do + # thousands + expect(pdf_fields["31"]).to eq "5" + expect(pdf_fields["215"]).to eq "6" + expect(pdf_fields["216"]).to eq "3" + # hundreds + expect(pdf_fields["undefined_92"]).to eq "8" + expect(pdf_fields["217"]).to eq "9" + expect(pdf_fields["218"]).to eq "0" + # decimals + expect(pdf_fields["undefined_93"]).to eq "0" + expect(pdf_fields["219"]).to eq "0" + end + end + + context "when medical expenses do not exceed 2% gross income" do + let(:submission) { + create :efile_submission, tax_return: nil, data_source: create( + :state_file_nj_intake, + :df_data_many_w2s, + medical_expenses: 4000 + ) + } + it "does not fill line 31" do + # thousands + expect(pdf_fields["31"]).to eq "" + expect(pdf_fields["215"]).to eq "" + expect(pdf_fields["216"]).to eq "" + # hundreds + expect(pdf_fields["undefined_92"]).to eq "" + expect(pdf_fields["217"]).to eq "" + expect(pdf_fields["218"]).to eq "" + # decimals + expect(pdf_fields["undefined_93"]).to eq "" + expect(pdf_fields["219"]).to eq "" + end + end + end + describe "line 38 total exemptions and deductions" do let(:submission) { create :efile_submission, tax_return: nil, data_source: create( diff --git a/spec/lib/submission_builder/ty2024/states/nj/documents/nj1040_spec.rb b/spec/lib/submission_builder/ty2024/states/nj/documents/nj1040_spec.rb index 1e61249be8..3cad8f5c82 100644 --- a/spec/lib/submission_builder/ty2024/states/nj/documents/nj1040_spec.rb +++ b/spec/lib/submission_builder/ty2024/states/nj/documents/nj1040_spec.rb @@ -331,6 +331,33 @@ end end + describe "line 31 medical expenses" do + context "with an income of 200k" do + let(:intake) { create(:state_file_nj_intake, :df_data_many_w2s, medical_expenses: 10_000) } + it "fills MedicalExpenses with medical expenses exceeding two percent gross income" do + expected_line_15_w2_wages = 200_000 + two_percent_gross = expected_line_15_w2_wages * 0.02 + expected_value = 10_000 - two_percent_gross + expect(xml.at("MedicalExpenses").text).to eq(expected_value.round.to_s) + end + end + + context "with no income" do + let(:intake) { create(:state_file_nj_intake, :df_data_minimal, medical_expenses: 10_000) } + it "fills MedicalExpenses with full medical expesnse amount" do + expected_value = 10_000 + expect(xml.at("MedicalExpenses").text).to eq(expected_value.round.to_s) + end + end + + context "with no medical expenses" do + let(:intake) { create(:state_file_nj_intake, :df_data_minimal, medical_expenses: 0) } + it "does not fill MedicalExpenses" do + expect(xml.at("MedicalExpenses")).to eq(nil) + end + end + end + describe "total exemptions and deductions - line 38" do let(:intake) { create(:state_file_nj_intake) } it "fills TotalExemptDeductions with total exemptions and deductions" do diff --git a/spec/models/efile_error_spec.rb b/spec/models/efile_error_spec.rb index 2460dc4334..cc5295977a 100644 --- a/spec/models/efile_error_spec.rb +++ b/spec/models/efile_error_spec.rb @@ -80,6 +80,7 @@ "nj-homeowner-property-tax", "nj-household-rent-own", "nj-ineligible-property-tax", + "nj-medical-expenses", "nj-municipality", "nj-review", "nj-tenant-eligibility", diff --git a/spec/models/state_file_nj_intake_spec.rb b/spec/models/state_file_nj_intake_spec.rb index e4779efd20..8547264db5 100644 --- a/spec/models/state_file_nj_intake_spec.rb +++ b/spec/models/state_file_nj_intake_spec.rb @@ -36,6 +36,7 @@ # last_sign_in_ip :inet # locale :string default("en") # locked_at :datetime +# medical_expenses :integer default(0), not null # message_tracker :jsonb # municipality_code :string # municipality_name :string From a9930613a04b27e33060c513a89868a1d317afa4 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 21 Oct 2024 09:37:13 -0400 Subject: [PATCH 2/5] Correct description formatting --- .../state_file/questions/nj_medical_expenses/edit.html.erb | 2 +- config/locales/en.yml | 2 +- config/locales/es.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/state_file/questions/nj_medical_expenses/edit.html.erb b/app/views/state_file/questions/nj_medical_expenses/edit.html.erb index f9029fa903..30e6a1db12 100644 --- a/app/views/state_file/questions/nj_medical_expenses/edit.html.erb +++ b/app/views/state_file/questions/nj_medical_expenses/edit.html.erb @@ -6,7 +6,7 @@ <% content_for :card do %>

    <%= t(".title") %>

    <%= form_with model: @form, url: { action: :update }, local: true, method: "put", builder: VitaMinFormBuilder do |f| %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 2977a75597..202e75d45b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -2641,7 +2641,7 @@ en: title: Looks like you’re not eligible for this credit. nj_medical_expenses: edit: - description: |- + description_html: |-
  • This includes expenses for yourself, your spouse, and your dependents.
  • Only expenses that exceed 2% of your gross income may be deducted.
  • You can’t deduct expenses for which you were reimbursed through your health insurance plan.
  • diff --git a/config/locales/es.yml b/config/locales/es.yml index f825a05729..5b060f83b9 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -2615,7 +2615,7 @@ es: title: Parece que no eres elegible para este crédito. nj_medical_expenses: edit: - description: |- + description_html: |-
  • This includes expenses for yourself, your spouse, and your dependents.
  • Only expenses that exceed 2% of your gross income may be deducted.
  • You can’t deduct expenses for which you were reimbursed through your health insurance plan.
  • From 32cfebc323f5ffe5637ea82fc5e3844c9f0be310 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 21 Oct 2024 12:41:26 -0400 Subject: [PATCH 3/5] Make description paragraphs rather than a list --- .../questions/nj_medical_expenses/edit.html.erb | 4 +--- config/locales/en.yml | 11 ++++++----- config/locales/es.yml | 11 ++++++----- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/app/views/state_file/questions/nj_medical_expenses/edit.html.erb b/app/views/state_file/questions/nj_medical_expenses/edit.html.erb index 30e6a1db12..562a14a05b 100644 --- a/app/views/state_file/questions/nj_medical_expenses/edit.html.erb +++ b/app/views/state_file/questions/nj_medical_expenses/edit.html.erb @@ -5,9 +5,7 @@ <% content_for :card do %>

    <%= t(".title") %>

    -
      - <%= t(".description_html") %> -
    + <%= t(".description_html") %> <%= form_with model: @form, url: { action: :update }, local: true, method: "put", builder: VitaMinFormBuilder do |f| %>
    diff --git a/config/locales/en.yml b/config/locales/en.yml index 202e75d45b..082f0029bd 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -2641,11 +2641,12 @@ en: title: Looks like you’re not eligible for this credit. nj_medical_expenses: edit: + help_text: Estimates are ok. For example, $3000. description_html: |- -
  • This includes expenses for yourself, your spouse, and your dependents.
  • -
  • Only expenses that exceed 2% of your gross income may be deducted.
  • -
  • You can’t deduct expenses for which you were reimbursed through your health insurance plan.
  • - help_text: If you do not want to claim this deduction, click “Continue”. +

    This includes expenses for yourself, your spouse, and your dependents.

    +

    Only expenses that exceed 2% of your gross income may be deducted.

    +

    You can’t deduct expenses for which you were reimbursed through your health insurance plan.

    + do_not_claim: If you do not want to claim this deduction, click “Continue”. label: Non-reimbursed medical expenses paid in %{filing_year} learn_more_content_html: |-
  • Physicians, dental, and other medical fees
  • Prescription eyeglasses and contact lenses
  • @@ -2660,7 +2661,7 @@ en: Note: In NJ, if you are paying for your adult child’s health insurance (ages 18 to 27), this can only be deducted as a medical expense if the child was your dependent. learn_more_title: What are medical expenses? - title: You can deduct medical expenses + title: You can deduct medical expenses. nj_municipality: edit: helper_description_html: If the place where you live is not listed, use the NJ state locality tool to get the name of your municipality. diff --git a/config/locales/es.yml b/config/locales/es.yml index 5b060f83b9..db18d84615 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -2615,11 +2615,12 @@ es: title: Parece que no eres elegible para este crédito. nj_medical_expenses: edit: + help_text: Estimates are ok. For example, $3000. description_html: |- -
  • This includes expenses for yourself, your spouse, and your dependents.
  • -
  • Only expenses that exceed 2% of your gross income may be deducted.
  • -
  • You can’t deduct expenses for which you were reimbursed through your health insurance plan.
  • - help_text: If you do not want to claim this deduction, click “Continue”. +

    This includes expenses for yourself, your spouse, and your dependents.

    +

    Only expenses that exceed 2% of your gross income may be deducted.

    +

    You can’t deduct expenses for which you were reimbursed through your health insurance plan.

    + do_not_claim: If you do not want to claim this deduction, click “Continue”. label: Non-reimbursed medical expenses paid in %{filing_year} learn_more_content_html: |-
  • Physicians, dental, and other medical fees
  • Prescription eyeglasses and contact lenses
  • @@ -2634,7 +2635,7 @@ es: Note: In NJ, if you are paying for your adult child’s health insurance (ages 18 to 27), this can only be deducted as a medical expense if the child was your dependent. learn_more_title: What are medical expenses? - title: You can deduct medical expenses + title: You can deduct medical expenses. nj_municipality: edit: helper_description_html: Si el lugar donde usted vive no aparece en la lista, utilice la herramienta de localidad del estado de New Jersey para obtener el nombre de su municipio. From e12dfcd0354103e57712fb83cfcd3c3e234dd80d Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 21 Oct 2024 15:39:41 -0400 Subject: [PATCH 4/5] Move do not claim text and adjust help text spacing --- app/assets/stylesheets/components/_form-elements.scss | 4 ++++ .../state_file/questions/nj_medical_expenses/edit.html.erb | 2 ++ config/locales/en.yml | 2 +- config/locales/es.yml | 2 +- 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/components/_form-elements.scss b/app/assets/stylesheets/components/_form-elements.scss index 2b3bff466d..39f9a444ae 100644 --- a/app/assets/stylesheets/components/_form-elements.scss +++ b/app/assets/stylesheets/components/_form-elements.scss @@ -101,3 +101,7 @@ .textarea { margin-bottom: 0; } + +.form-group .form-question + .text--help{ + margin-top: 0; +} \ No newline at end of file diff --git a/app/views/state_file/questions/nj_medical_expenses/edit.html.erb b/app/views/state_file/questions/nj_medical_expenses/edit.html.erb index 562a14a05b..8a92393e5b 100644 --- a/app/views/state_file/questions/nj_medical_expenses/edit.html.erb +++ b/app/views/state_file/questions/nj_medical_expenses/edit.html.erb @@ -18,6 +18,8 @@ ) %>
    +

    <%= t(".do_not_claim") %>

    +