diff --git a/app/lib/submission_builder/state1099_r.rb b/app/lib/submission_builder/state1099_r.rb
new file mode 100644
index 0000000000..f36cd33ec4
--- /dev/null
+++ b/app/lib/submission_builder/state1099_r.rb
@@ -0,0 +1,53 @@
+module SubmissionBuilder
+ class State1099R < SubmissionBuilder::Document
+ include SubmissionBuilder::FormattingMethods
+
+ def document
+ form1099r = @kwargs[:form1099r]
+ state_abbreviation = form1099r.intake.state_code.upcase
+
+ build_xml_doc("IRS1099R", documentId: "IRS1099R-#{form1099r.id}") do |xml|
+ xml.PayerNameControlTxt form1099r.payer_name_control
+ if form1099r.payer_name.present?
+ xml.PayerName do
+ xml.BusinessNameLine1Txt sanitize_for_xml(form1099r.payer_name.tr('-', ' '), 75)
+ end
+ xml.PayerUSAddress do
+ xml.AddressLine1Txt sanitize_for_xml(form1099r.payer_address_line1, 35) if form1099r.payer_address_line1.present?
+ xml.AddressLine2Txt sanitize_for_xml(form1099r.payer_address_line2, 35) if form1099r.payer_address_line2.present?
+ xml.CityNm sanitize_for_xml(form1099r.payer_city_name, 22) if form1099r.payer_city_name.present?
+ xml.StateAbbreviationCd form1099r.payer_state_code if form1099r.payer_state_code.present?
+ xml.ZIPCd form1099r.payer_zip if form1099r.payer_zip.present?
+ end
+ xml.PayerEIN form1099r.payer_identification_number
+ xml.RecipientSSN sanitize_for_xml(form1099r.recipient_ssn) if form1099r.recipient_ssn.present?
+ xml.RecipientNm sanitize_for_xml(form1099r.recipient_name) if form1099r.recipient_name.present?
+ xml.GrossDistributionAmt form1099r.gross_distribution_amount&.round
+ xml.TaxableAmt form1099r.taxable_amount&.round
+ if form1099r.taxable_amount_not_determined?
+ xml.TxblAmountNotDeterminedInd 'X'
+ end
+ if form1099r.total_distribution?
+ xml.TotalDistributionInd 'X'
+ end
+ xml.FederalIncomeTaxWithheldAmt form1099r.federal_income_tax_withheld_amount&.round
+ xml.F1099RDistributionCd form1099r.distribution_code
+ xml.DesignatedROTHAcctFirstYr form1099r.designated_roth_account_first_year if form1099r.designated_roth_account_first_year.present?
+ xml.F1099RStateLocalTaxGrp do
+ xml.F1099RStateTaxGrp do
+ xml.StateTaxWithheldAmt form1099r.state_tax_withheld_amount&.round
+ xml.StateAbbreviationCd form1099r.state_code if form1099r.state_code.present?
+ xml.PayerStateIdNum form1099r.payer_state_identification_number if form1099r.payer_state_identification_number.present?
+ xml.StateDistributionAmt form1099r.state_distribution_amount&.round
+ end
+ end
+ if form1099r.standard?
+ xml.StandardOrNonStandardCd 'S'
+ else
+ xml.StandardOrNonStandardCd 'N'
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/app/lib/submission_builder/state_return.rb b/app/lib/submission_builder/state_return.rb
index c432a7a77f..6465d92e5d 100644
--- a/app/lib/submission_builder/state_return.rb
+++ b/app/lib/submission_builder/state_return.rb
@@ -90,6 +90,21 @@ def form1099g_builder
SubmissionBuilder::State1099G
end
+ def form1099rs
+ @submission.data_source.state_file1099_rs.map do |form1099r|
+ {
+ xml: form1099r_builder,
+ pdf: nil,
+ include: true,
+ kwargs: { form1099r: form1099r }
+ }
+ end
+ end
+
+ def form1099r_builder
+ SubmissionBuilder::State1099R
+ end
+
# default to nil
def w2_pdf; end
diff --git a/app/lib/submission_builder/ty2022/states/az/az_return_xml.rb b/app/lib/submission_builder/ty2022/states/az/az_return_xml.rb
index 6f45573037..a3ece75876 100644
--- a/app/lib/submission_builder/ty2022/states/az/az_return_xml.rb
+++ b/app/lib/submission_builder/ty2022/states/az/az_return_xml.rb
@@ -214,6 +214,7 @@ def supported_documents
]
supported_docs += combined_w2s
+ supported_docs += form1099rs
supported_docs += form1099gs
supported_docs
end
diff --git a/app/lib/submission_builder/ty2024/states/id/id_return_xml.rb b/app/lib/submission_builder/ty2024/states/id/id_return_xml.rb
index a140688a45..791278d530 100644
--- a/app/lib/submission_builder/ty2024/states/id/id_return_xml.rb
+++ b/app/lib/submission_builder/ty2024/states/id/id_return_xml.rb
@@ -52,6 +52,7 @@ def supported_documents
}
end
+ supported_docs += form1099rs
supported_docs += form1099gs
supported_docs
end
diff --git a/app/lib/submission_builder/ty2024/states/md/md_return_xml.rb b/app/lib/submission_builder/ty2024/states/md/md_return_xml.rb
index ec58ce5ce1..fbcc78cb7d 100644
--- a/app/lib/submission_builder/ty2024/states/md/md_return_xml.rb
+++ b/app/lib/submission_builder/ty2024/states/md/md_return_xml.rb
@@ -51,6 +51,7 @@ def supported_documents
]
supported_docs += combined_w2s
+ supported_docs += form1099rs
supported_docs += form1099gs
supported_docs
end
diff --git a/app/views/state_file/questions/federal_info/_df_1099r.html.erb b/app/views/state_file/questions/federal_info/_df_1099r.html.erb
index 5c2b191e22..7bf45ca243 100644
--- a/app/views/state_file/questions/federal_info/_df_1099r.html.erb
+++ b/app/views/state_file/questions/federal_info/_df_1099r.html.erb
@@ -3,6 +3,7 @@
<%= render 'node_xml_reveal', xml: f.object.to_pretty_s %>
+
For payer_name_control, only use A-Z, 0-9, hyphen and ampersand. Only up to 4 characters are allowed. Spaces and symbols are not allowed.
<%= f.state_file_nested_xml_field :payer_name_control %>
<%= f.state_file_nested_xml_field :payer_name %>
diff --git a/spec/factories/state_file1099_rs.rb b/spec/factories/state_file1099_rs.rb
index d03f86fd27..61a98d1039 100644
--- a/spec/factories/state_file1099_rs.rb
+++ b/spec/factories/state_file1099_rs.rb
@@ -41,6 +41,26 @@
#
FactoryBot.define do
factory :state_file1099_r do
-
+ payer_name { "Dorothy Red" }
+ payer_name_control { "DORO" }
+ payer_address_line1 { "123 Sesame ST" }
+ payer_address_line2 { "Apt 202" }
+ payer_city_name { "Long Island" }
+ payer_zip { "12345"}
+ payer_identification_number { "22345"}
+ recipient_ssn { "123456789"}
+ recipient_name { "Dorothy Jane Red"}
+ gross_distribution_amount { 100.25 }
+ taxable_amount { 50.5 }
+ taxable_amount_not_determined { true }
+ total_distribution { true }
+ federal_income_tax_withheld_amount { 10.55 }
+ distribution_code { '7' }
+ designated_roth_account_first_year { 1993 }
+ state_tax_withheld_amount { 100.5 }
+ state_code { 'AZ' }
+ payer_state_identification_number { "222222222" }
+ state_distribution_amount { 155.15 }
+ standard { false }
end
end
diff --git a/spec/fixtures/state_file/fed_return_xmls/2023/az/alexis_hoh_w2_and_1099.xml b/spec/fixtures/state_file/fed_return_xmls/2023/az/alexis_hoh_w2_and_1099.xml
index 3c6c11e38a..47d955ac46 100644
--- a/spec/fixtures/state_file/fed_return_xmls/2023/az/alexis_hoh_w2_and_1099.xml
+++ b/spec/fixtures/state_file/fed_return_xmls/2023/az/alexis_hoh_w2_and_1099.xml
@@ -198,7 +198,7 @@
S
- ALEXISPAYER
+ ALEX
Payer Name
diff --git a/spec/fixtures/state_file/fed_return_xmls/2023/az/df_complete_sample.xml b/spec/fixtures/state_file/fed_return_xmls/2023/az/df_complete_sample.xml
index a4ae6fc70d..772ad751f4 100644
--- a/spec/fixtures/state_file/fed_return_xmls/2023/az/df_complete_sample.xml
+++ b/spec/fixtures/state_file/fed_return_xmls/2023/az/df_complete_sample.xml
@@ -209,7 +209,7 @@
S
- ALEXISPAYER
+ ALEX
Payer Name
diff --git a/spec/fixtures/state_file/fed_return_xmls/2023/az/richard_retirement_1099r.xml b/spec/fixtures/state_file/fed_return_xmls/2023/az/richard_retirement_1099r.xml
index acacf3591f..d7e7239445 100644
--- a/spec/fixtures/state_file/fed_return_xmls/2023/az/richard_retirement_1099r.xml
+++ b/spec/fixtures/state_file/fed_return_xmls/2023/az/richard_retirement_1099r.xml
@@ -101,7 +101,7 @@
2030 Pecan Street
Monroe
- MA
+ AZ
05502
000000001
@@ -113,7 +113,7 @@
11
- NC
+ AZ
111111111
111
@@ -121,14 +121,14 @@
S
- PAYE DEUX
+ SECO
Second Payer Name
2031 Pecan Street
Nonroe
- NA
+ AZ
05503
000000002
@@ -140,7 +140,7 @@
22
- NC
+ AZ
222222222
222
diff --git a/spec/lib/submission_builder/state1099_r_spec.rb b/spec/lib/submission_builder/state1099_r_spec.rb
new file mode 100644
index 0000000000..9455b6ef92
--- /dev/null
+++ b/spec/lib/submission_builder/state1099_r_spec.rb
@@ -0,0 +1,46 @@
+require 'rails_helper'
+
+describe SubmissionBuilder::State1099R do
+ StateFile::StateInformationService.active_state_codes.each do |state_code|
+ describe ".document" do
+ let(:submission) { create(:efile_submission, data_source: intake) }
+ let!(:form1099r) do
+ create(
+ :state_file1099_r,
+ intake: intake,
+ state_code: state_code.upcase,
+ payer_state_code: state_code.upcase
+ )
+ end
+ let(:intake) do
+ create("state_file_#{state_code}_intake".to_sym)
+ end
+ let(:doc) { described_class.new(submission, kwargs: { form1099r: form1099r }).document }
+
+ it "generates xml with the right values" do
+ expect(doc.at("PayerNameControlTxt").text).to eq "DORO"
+ expect(doc.at("PayerName BusinessNameLine1Txt").text).to eq "Dorothy Red"
+ expect(doc.at("PayerUSAddress AddressLine1Txt").text).to eq "123 Sesame ST"
+ expect(doc.at("PayerUSAddress AddressLine2Txt").text).to eq "Apt 202"
+ expect(doc.at("PayerUSAddress CityNm").text).to eq "Long Island"
+ expect(doc.at("PayerUSAddress StateAbbreviationCd").text).to eq "#{state_code.upcase}"
+ expect(doc.at("PayerUSAddress ZIPCd").text).to eq "12345"
+ expect(doc.at("PayerEIN").text).to eq "22345"
+ expect(doc.at("RecipientSSN").text).to eq "123456789"
+ expect(doc.at("RecipientNm").text).to eq "Dorothy Jane Red"
+ expect(doc.at("GrossDistributionAmt").text).to eq "100"
+ expect(doc.at("TaxableAmt").text).to eq "51"
+ expect(doc.at("TxblAmountNotDeterminedInd").text).to eq "X"
+ expect(doc.at("TotalDistributionInd").text).to eq "X"
+ expect(doc.at("FederalIncomeTaxWithheldAmt").text).to eq "11"
+ expect(doc.at("F1099RDistributionCd").text).to eq "7"
+ expect(doc.at("DesignatedROTHAcctFirstYr").text).to eq "1993"
+ expect(doc.at("F1099RStateTaxGrp StateTaxWithheldAmt").text).to eq "101"
+ expect(doc.at("F1099RStateTaxGrp StateAbbreviationCd").text).to eq "#{state_code.upcase}"
+ expect(doc.at("F1099RStateTaxGrp PayerStateIdNum").text).to eq "222222222"
+ expect(doc.at("F1099RStateTaxGrp StateDistributionAmt").text).to eq "155"
+ expect(doc.at("StandardOrNonStandardCd").text).to eq "N"
+ end
+ end
+ end
+end
diff --git a/spec/lib/submission_builder/state_return_spec.rb b/spec/lib/submission_builder/state_return_spec.rb
index 1686e2a852..9145998446 100644
--- a/spec/lib/submission_builder/state_return_spec.rb
+++ b/spec/lib/submission_builder/state_return_spec.rb
@@ -20,8 +20,6 @@
let(:builder_class) { StateFile::StateInformationService.submission_builder_class(state_code) }
let(:intake) { create("state_file_#{state_code}_intake".to_sym, filing_status: filing_status) }
let(:submission) { create(:efile_submission, data_source: intake) }
- let!(:initial_efile_device_info) { create :state_file_efile_device_info, :initial_creation, :filled, intake: intake }
- let!(:submission_efile_device_info) { create :state_file_efile_device_info, :submission, :filled, intake: intake }
let(:vars) { spec_vars[state_code.to_sym] || spec_vars[:default] }
context "#{state_code}: when there are w2s present" do
@@ -118,8 +116,6 @@
let(:builder_class) { StateFile::StateInformationService.submission_builder_class(state_code) }
let(:intake) { create("state_file_#{state_code}_intake".to_sym) }
let(:submission) { create(:efile_submission, data_source: intake) }
- let!(:initial_efile_device_info) { create :state_file_efile_device_info, :initial_creation, :filled, intake: intake }
- let!(:submission_efile_device_info) { create :state_file_efile_device_info, :submission, :filled, intake: intake }
let!(:form1099g_1) { create(:state_file1099_g, intake: intake, state_income_tax_withheld_amount: 100) }
let!(:form1099g_2) { create(:state_file1099_g, intake: intake, state_income_tax_withheld_amount: 200) }
@@ -131,4 +127,23 @@
end
end
end
+
+ states_requiring_1099rs = StateFile::StateInformationService.active_state_codes.excluding(["nc", "nj", "ny"])
+ states_requiring_1099rs.each do |state_code|
+ describe "#form1099rs", required_schema: state_code do
+ context "#{state_code}: when there are 1099rs present" do
+ let(:builder_class) { StateFile::StateInformationService.submission_builder_class(state_code) }
+ let(:intake) { create("state_file_#{state_code}_intake".to_sym) }
+ let(:submission) { create(:efile_submission, data_source: intake) }
+ let!(:form1099r_1) { create(:state_file1099_r, intake: intake, state_tax_withheld_amount: 100) }
+ let!(:form1099r_2) { create(:state_file1099_r, intake: intake, state_tax_withheld_amount: 200) }
+
+ it "builds all 1099gs from intake" do
+ xml = Nokogiri::XML::Document.parse(builder_class.build(submission).document.to_xml)
+
+ expect(xml.css("IRS1099R").count).to eq 2
+ end
+ end
+ end
+ end
end