Skip to content

Commit

Permalink
Merge branch 'main' into nj-293-move-retirement-screen
Browse files Browse the repository at this point in the history
  • Loading branch information
jachan authored Feb 25, 2025
2 parents aa106d3 + a8f38c0 commit 9878948
Show file tree
Hide file tree
Showing 105 changed files with 4,596 additions and 292 deletions.
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ GEM
net-protocol
netrc (0.11.0)
nio4r (2.7.3)
nokogiri (1.16.8)
nokogiri (1.18.3)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
notiffany (0.1.3)
Expand Down
12 changes: 12 additions & 0 deletions app/assets/stylesheets/_state-file.scss
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,18 @@
}
}
}

ul {
list-style-type: disc;
padding-left: 2rem;
margin: 1rem 0;
}

li {
font-size: 1.6rem;
line-height: 2.4rem;
margin-bottom: 0.5rem;
}
}

.checkbox.is-selected {
Expand Down
2 changes: 1 addition & 1 deletion app/channels/df_data_transfer_job_channel.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
class DfDataTransferJobChannel < ApplicationCable::Channel
def subscribed
intake = current_state_file_intake
stream_for intake
if intake.raw_direct_file_data
DfDataTransferJobChannel.broadcast_job_complete(intake)
end
stream_for intake
end

def self.broadcast_job_complete(intake)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ def index

@efile_submissions = @efile_submissions.includes(:efile_submission_transitions).reorder(created_at: :desc).paginate(page: params[:page], per_page: 30)
@efile_submissions = @efile_submissions.in_state(params[:status]) if params[:status].present?

end

def show
Expand Down Expand Up @@ -66,7 +65,8 @@ def show_pdf
end

def state_counts
@efile_submission_state_counts = EfileSubmission.statefile_state_counts(except: %w[new resubmitted ready_to_resubmit])
intake_classes = current_user.state_file_nj_staff? ? "StateFileNjIntake" : ::StateFile::StateInformationService.state_intake_class_names.excluding("StateFileNjIntake").join("','")
@efile_submission_state_counts = EfileSubmission.statefile_state_counts(except: %w[new resubmitted ready_to_resubmit], intake_classes: intake_classes)
respond_to :js
end

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
module StateFile
module ArchivedIntakes
class ArchivedIntakeController < ApplicationController
layout "state_file"
before_action :check_feature_flag
def current_request
request = StateFileArchivedIntakeRequest.find_by(ip_address: ip_for_irs, email_address: session[:email_address])
request = StateFileArchivedIntakeRequest.where("ip_address = ? AND LOWER(email_address) = LOWER(?)", ip_for_irs, session[:email_address]).first
unless request
Rails.logger.warn "StateFileArchivedIntakeRequest not found for IP: #{ip_for_irs}, Email: #{session[:email_address]}"
Sentry.capture_message "StateFileArchivedIntakeRequest not found for IP: #{ip_for_irs}, Email: #{session[:email_address]}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def update
@form = EmailAddressForm.new(email_address_form_params)

if @form.valid?
archived_intake = StateFileArchivedIntake.find_by(email_address: @form.email_address)
archived_intake = StateFileArchivedIntake.where("LOWER(email_address) = LOWER(?)", @form.email_address).first
session[:email_address] = @form.email_address
StateFileArchivedIntakeRequest.find_or_create_by(email_address: @form.email_address, ip_address: ip_for_irs, state_file_archived_intake_id: archived_intake&.id )
create_state_file_access_log("issued_email_challenge")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ class PdfsController < ArchivedIntakeController
end

def index
@prior_year_intake = StateFileArchivedIntake.find_by!(email_address: current_request.email_address)
@pdf_url = @prior_year_intake.submission_pdf.url(expires_in: pdf_expiration_time, disposition: "inline")
@state_code = StateFileArchivedIntake.find_by!(email_address: current_request.email_address).state_code
create_state_file_access_log("issued_pdf_download_link")
end

def log_and_redirect
create_state_file_access_log("client_pdf_download_click")
pdf_url = params[:pdf_url]
redirect_to pdf_url
prior_year_intake = StateFileArchivedIntake.find_by!(email_address: current_request.email_address)
pdf_url = prior_year_intake.submission_pdf.url(expires_in: pdf_expiration_time, disposition: "inline")
redirect_to pdf_url, allow_other_host: true
end

private
Expand Down
27 changes: 27 additions & 0 deletions app/controllers/state_file/questions/id_disability_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module StateFile
module Questions
class IdDisabilityController < QuestionsController
def self.show?(intake)
Flipper.enabled?(:show_retirement_ui) &&
intake.state_file1099_rs.any? { |form1099r| form1099r.taxable_amount&.to_f&.positive? } &&
!intake.filing_status_mfs? && meets_age_requirements?(intake)
end

def self.meets_age_requirements?(intake)
primary_age = intake.calculate_age(intake.primary_birth_date, inclusive_of_jan_1: true)
if intake.filing_status_mfj? && intake.spouse_birth_date.present?
spouse_age = intake.calculate_age(intake.spouse_birth_date, inclusive_of_jan_1: true)
(primary_age >= 62 && primary_age < 65) || (spouse_age >= 62 && spouse_age < 65)
else
primary_age >= 62 && primary_age < 65
end
end

private

def form_params
params.require(:state_file_id_disability_form).permit(:mfj_disability, :primary_disabled, :spouse_disabled)
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
module StateFile
module Questions
class IdRetirementAndPensionIncomeController < RetirementIncomeSubtractionController
def self.show?(intake)
Flipper.enabled?(:show_retirement_ui) && !intake.filing_status_mfs? &&
has_eligible_1099rs?(intake)
end

def self.has_eligible_1099rs?(intake)
intake.state_file1099_rs.any? do |form1099r|
form1099r.taxable_amount&.to_f&.positive? && person_qualifies?(form1099r, intake)
end
end

def self.person_qualifies?(form1099r, intake)
primary_tin = intake.primary.ssn
spouse_tin = intake.spouse&.ssn

case form1099r.recipient_ssn
when primary_tin
intake.primary_disabled_yes? || intake.primary_senior?
when spouse_tin
intake.spouse_disabled_yes? || intake.spouse_senior?
else
false
end
end

private

def person_qualifies?(form1099r)
self.class.person_qualifies?(form1099r, current_intake)
end

def eligible_1099rs
@eligible_1099rs ||= current_intake.state_file1099_rs.select do |form1099r|
form1099r.taxable_amount&.to_f&.positive? && person_qualifies?(form1099r)
end
end

def num_items
eligible_1099rs.count
end

def load_item(index)
@state_file_1099r = eligible_1099rs[index]
render "public_pages/page_not_found", status: 404 if @state_file_1099r.nil?
end

def followup_class = StateFileId1099RFollowup
end
end
end
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module StateFile
module Questions
class MdPermanentlyDisabledController < QuestionsController
include ReturnToReviewConcern
def self.show?(intake)
Flipper.enabled?(:show_retirement_ui) && intake.state_file1099_rs.length.positive?
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def get_detailed_return_info
{ text_key: '16a_interest_income', value: line_or_zero(:NJ1040_LINE_16A) },
{ text_key: '20a_retirement_income', value: line_or_zero(:NJ1040_LINE_20A) },
{ text_key: '27_total_income', value: line_or_zero(:NJ1040_LINE_27) },
# { text_key: '28c_retirement_excluded_from_taxation', value: line_or_zero(:NJ1040_LINE_28C) },
{ text_key: '28c_retirement_excluded_from_taxation', value: line_or_zero(:NJ1040_LINE_28C) },
{ text_key: '29_nj_gross_income', value: line_or_zero(:NJ1040_LINE_29) },
{ text_key: '30_exemptions', value: line_or_zero(:NJ1040_LINE_13) }, # same value for 13 and 30
{ text_key: '31_medical', value: line_or_zero(:NJ1040_LINE_31) },
Expand Down
49 changes: 49 additions & 0 deletions app/forms/state_file/id_disability_form.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
module StateFile
class IdDisabilityForm < QuestionsForm
set_attributes_for :intake, :primary_disabled, :spouse_disabled

attr_accessor :mfj_disability
validates_presence_of :mfj_disability, if: -> { intake.filing_status_mfj?}
validates :primary_disabled, inclusion: { in: %w[yes no], message: :blank }, unless: -> { intake.filing_status_mfj? }

def save
if intake.filing_status_mfj?
primary_eligible = eligible?(:primary)
spouse_eligible = eligible?(:spouse)

case mfj_disability
when "me"
@intake.update(primary_disabled: primary_eligible ? "yes" : "no", spouse_disabled: "no")
when "spouse"
@intake.update(primary_disabled: "no", spouse_disabled: spouse_eligible ? "yes" : "no")
when "both"
@intake.update(
primary_disabled: primary_eligible ? "yes" : "no",
spouse_disabled: spouse_eligible ? "yes" : "no"
)
when "none"
@intake.update(primary_disabled: "no", spouse_disabled: "no")
end
else
@intake.update(attributes_for(:intake))
end
end

private

def eligible?(primary_or_spouse)
person = intake.send(primary_or_spouse)
birth_date = person.birth_date
return false unless birth_date.present?

age = intake.calculate_age(birth_date, inclusive_of_jan_1: true)
age_eligible = age >= 62 && age < 65

has_taxable_1099r = intake.state_file1099_rs.any? do |form|
form.recipient_ssn == person.ssn && form.taxable_amount&.to_f&.positive?
end

age_eligible && has_taxable_1099r
end
end
end
19 changes: 19 additions & 0 deletions app/forms/state_file/id_retirement_and_pension_income_form.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module StateFile
class IdRetirementAndPensionIncomeForm < Form
include FormAttributes


set_attributes_for :state_file_id1099_r_followup, :eligible_income_source

validates :eligible_income_source, presence: true

def initialize(state_file_id1099_r_followup = nil, params = {})
@state_file_id1099_r_followup = state_file_id1099_r_followup
super(params)
end

def save
@state_file_id1099_r_followup.update(attributes_for(:state_file_id1099_r_followup))
end
end
end
2 changes: 1 addition & 1 deletion app/forms/state_file/md_permanently_disabled_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def save
if intake.filing_status_mfj?
case mfj_disability
when "me"
@intake.update(primary_disabled: "yes", spouse_disabled: "no", proof_of_disability_submitted: proof_of_disability_submitted)
@intake.update(primary_disabled: "yes", spouse_disabled: "no", proof_of_disability_submitted: proof_of_disability_submitted)
when "spouse"
@intake.update(primary_disabled: "no", spouse_disabled: "yes", proof_of_disability_submitted: proof_of_disability_submitted)
when "both"
Expand Down
30 changes: 29 additions & 1 deletion app/jobs/state_file/import_from_direct_file_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def perform(authorization_code:, intake:)
direct_file_json = IrsApiService.import_federal_data(authorization_code, intake.state_code)

if direct_file_json.blank?
raise StandardError, "Direct file data was not transferred for intake #{intake.state_code} #{intake.id}."
raise StandardError, "Direct file data was not transferred for intake #{intake.state_code}#{intake.id}."
end

intake.update(
Expand All @@ -34,6 +34,11 @@ def perform(authorization_code:, intake:)
intake.synchronize_df_w2s_to_database
intake.synchronize_filers_to_database

# removing duplicate associations here because sometimes we create duplicate records during data import
# future work will prevent this issue from happening and this can be removed
remove_duplicate_w2s(intake)
remove_duplicate_dependents(intake)

intake.update(df_data_import_succeeded_at: DateTime.now)
rescue => err
Rails.logger.error(err)
Expand All @@ -46,5 +51,28 @@ def perform(authorization_code:, intake:)
def priority
PRIORITY_LOW
end

private

def remove_duplicates(intake, collection, identifying_attribute_name)
values = []
collection.each do |record|
value = record.send(identifying_attribute_name)
if values.include?(value)
Rails.logger.info("ImportFromDirectFileJob removing duplicate #{record.class&.name} for #{intake&.state_code}#{intake&.id}")
record.destroy!
else
values.push(value)
end
end
end

def remove_duplicate_w2s(intake)
remove_duplicates(intake, intake.state_file_w2s, :w2_index)
end

def remove_duplicate_dependents(intake)
remove_duplicates(intake, intake.dependents, :ssn)
end
end
end
41 changes: 40 additions & 1 deletion app/lib/efile/id/id39_r_calculator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ def calculate
set_line(:ID39R_B_LINE_3, :calculate_sec_b_line_3)
set_line(:ID39R_B_LINE_7, :calculate_sec_b_line_7)
set_line(:ID39R_B_LINE_6, :calculate_sec_b_line_6)
set_line(:ID39R_B_LINE_8f, -> { 0 })
set_line(:ID39R_B_LINE_8a, :calculate_sec_b_line_8a)
set_line(:ID39R_B_LINE_8b, -> { 0 })
set_line(:ID39R_B_LINE_8c, :calculate_sec_b_line_8c)
set_line(:ID39R_B_LINE_8d, :calculate_sec_b_line_8d)
set_line(:ID39R_B_LINE_8e, :calculate_sec_b_line_8e)
set_line(:ID39R_B_LINE_8f, :calculate_sec_b_line_8f)
set_line(:ID39R_B_LINE_18, :calculate_sec_b_line_18)
set_line(:ID39R_B_LINE_24, :calculate_sec_b_line_24)
set_line(:ID39R_D_LINE_4, -> { 0 })
Expand Down Expand Up @@ -63,6 +68,40 @@ def calculate_sec_b_line_7
@direct_file_data.fed_taxable_ssb&.round || 0
end

def calculate_sec_b_line_8a
if @intake.filing_status_single? || @intake.filing_status_hoh? || @intake.filing_status_qw?
45_864
elsif @intake.filing_status_mfj?
68_796
end
end

def calculate_sec_b_line_8c
@direct_file_data.fed_ssb
end

def calculate_sec_b_line_8d
[line_or_zero(:ID39R_B_LINE_8a) - (line_or_zero(:ID39R_B_LINE_8b) + line_or_zero(:ID39R_B_LINE_8c)), 0].max
end

def calculate_sec_b_line_8e
@intake.state_file1099_rs.sum do |form1099r|
if form1099r.state_specific_followup&.eligible_income_source_yes? && form1099r.taxable_amount.present?
form1099r.taxable_amount.round
else
0
end
end
end

def calculate_sec_b_line_8f
if Flipper.enabled?(:show_retirement_ui)
[line_or_zero(:ID39R_B_LINE_8d), line_or_zero(:ID39R_B_LINE_8e)].min
else
0
end
end

def calculate_sec_b_line_18
@intake.has_health_insurance_premium_yes? ? @intake.health_insurance_paid_amount&.round : 0
end
Expand Down
4 changes: 3 additions & 1 deletion app/lib/efile/id/id40_calculator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,9 @@ def calculate_line_43
def calculate_line_46
@intake.state_file_w2s.sum { |item| item.state_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 }
@intake.state_file1099_rs.sum do |item|
item.state_tax_withheld_amount&.round || 0
end
end

def calculate_line_50
Expand Down
Loading

0 comments on commit 9878948

Please sign in to comment.