Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SIMPLE-FORMS] fix: consolidate contact info parsing under one file #21106

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
# frozen_string_literal: true

require_relative 'notification/parsing_utils'

module SimpleFormsApi
module Notification
class Email
attr_reader :form_number, :confirmation_number, :date_submitted, :expiration_date, :lighthouse_updated_at,
:notification_type, :user, :user_account, :form_data

include SimpleFormsApi::Notification::ParsingUtils

TEMPLATE_IDS = {
'vba_21_0845' => {
confirmation: Settings.vanotify.services.va_gov.template_id.form21_0845_confirmation_email,
Expand Down Expand Up @@ -127,12 +131,12 @@ def flipper?
end

def enqueue_email(at, template_id)
email_from_form_data = get_email_address_from_form_data
first_name_from_form_data = get_first_name_from_form_data
email = contact_info[:email]
first_name = contact_info[:first_name]

# async job and form data includes email
if email_from_form_data && first_name_from_form_data
async_job_with_form_data(email_from_form_data, first_name_from_form_data, at, template_id)
if email && first_name
async_job_with_form_data(email, first_name, at, template_id)
# async job and we have a UserAccount
elsif user_account
async_job_with_user_account(user_account, at, template_id)
Expand All @@ -159,100 +163,39 @@ def async_job_with_form_data(email, first_name, at, template_id)
end

def async_job_with_user_account(user_account, at, template_id)
first_name_from_user_account = get_first_name_from_user_account
return unless first_name_from_user_account
first_name = get_first_name_from_user_account
return unless first_name

if Flipper.enabled?(:simple_forms_notification_callbacks)
VANotify::UserAccountJob.perform_at(
at,
user_account.id,
template_id,
get_personalization(first_name_from_user_account),
get_personalization(first_name),
*email_args
)
else
VANotify::UserAccountJob.perform_at(
at,
user_account.id,
template_id,
get_personalization(first_name_from_user_account)
get_personalization(first_name)
)
end
end

def send_email_now(template_id)
email_from_form_data = get_email_address_from_form_data
first_name_from_form_data = get_first_name_from_form_data

# sync job and form data includes email
if email_from_form_data && first_name_from_form_data
VANotify::EmailJob.perform_async(
email_from_form_data,
template_id,
get_personalization(first_name_from_form_data)
)
# sync job and we have a User
elsif user
first_name = get_first_name_from_form_data || get_first_name_from_user
return unless first_name

VANotify::EmailJob.perform_async(
user.va_profile_email,
template_id,
get_personalization(first_name)
)
end
end
email = contact_info[:email]
first_name = contact_info[:first_name] || get_first_name_from_user

def get_email_address_from_form_data
case @form_number
when 'vba_21_0845'
form21_0845_contact_info[0]
when 'vba_21p_0847', 'vba_21_0972'
form_data['preparer_email']
when 'vba_21_0966', 'vba_21_0966_intent_api'
form21_0966_email_address
when 'vba_21_4142', 'vba_26_4555'
form_data.dig('veteran', 'email')
when 'vba_21_10210'
form21_10210_contact_info[0]
when 'vba_20_10206'
form20_10206_contact_info[0]
when 'vba_20_10207'
form20_10207_contact_info[0]
when 'vba_40_0247'
form_data['applicant_email']
when 'vba_40_10007'
form_data.dig('application', 'claimant', 'email')
end
end
return unless first_name && email

# rubocop:disable Metrics/MethodLength
def get_first_name_from_form_data
case @form_number
when 'vba_21_0845'
form21_0845_contact_info[1]
when 'vba_21p_0847'
form_data.dig('preparer_name', 'first')
when 'vba_21_0966', 'vba_21_0966_intent_api'
form21_0966_first_name
when 'vba_21_0972'
form_data.dig('preparer_full_name', 'first')
when 'vba_21_4142', 'vba_26_4555'
form_data.dig('veteran', 'full_name', 'first')
when 'vba_21_10210'
form21_10210_contact_info[1]
when 'vba_20_10206'
form20_10206_contact_info[1]
when 'vba_20_10207'
form20_10207_contact_info[1]
when 'vba_40_0247'
form_data.dig('applicant_full_name', 'first')
when 'vba_40_10007'
form40_10007_first_name
end
VANotify::EmailJob.perform_async(
email,
template_id,
get_personalization(first_name)
)
end
# rubocop:enable Metrics/MethodLength

def get_first_name_from_user_account
mpi_response = MPI::Service.new.find_profile_by_identifier(identifier_type: 'ICN', identifier: user_account.icn)
Expand All @@ -268,10 +211,8 @@ def get_first_name_from_user_account
end

def get_first_name_from_user
first_name = user.first_name
Rails.logger.error('First name not found in user profile') unless first_name

first_name
Rails.logger.error('First name not found in user profile') unless user&.first_name
user&.first_name
end

def get_personalization(first_name)
Expand All @@ -295,99 +236,6 @@ def default_personalization(first_name)
}
end

# email and first name for form 20-10206
def form20_10206_contact_info
# email address not required and omitted
if @form_data['email_address'].blank? && @user
[@user.va_profile_email, @form_data.dig('full_name', 'first')]

# email address not required and optionally entered
else
[@form_data['email_address'], @form_data.dig('full_name', 'first')]
end
end

# email and first name for form 20-10207
def form20_10207_contact_info
preparer_types = %w[veteran third-party-veteran non-veteran third-party-non-veteran]

return unless preparer_types.include?(@form_data['preparer_type'])

email_and_first_name = [@user&.va_profile_email]
# veteran
email_and_first_name << if @form_data['preparer_type'] == 'veteran'
@form_data['veteran_full_name']['first']

# non-veteran
elsif @form_data['preparer_type'] == 'non-veteran'
@form_data['non_veteran_full_name']['first']

# third-party
else
@form_data['third_party_full_name']['first']
end

email_and_first_name
end

# email and first name for form 21-0845
def form21_0845_contact_info
# (vet && signed in)
if @form_data['authorizer_type'] == 'veteran'
[@form_data['veteran_email'] || @user&.va_profile_email, @form_data.dig('veteran_full_name', 'first')]

# (non-vet && signed in) || (non-vet && anon)
elsif @form_data['authorizer_type'] == 'nonVeteran'
[@form_data['authorizer_email'], @form_data.dig('authorizer_full_name', 'first')]

# (vet && anon)
else
[nil, nil]
end
end

# email and first name for form 21-10210
def form21_10210_contact_info
# user's own claim
# user is a veteran
if @form_data['claim_ownership'] == 'self' && @form_data['claimant_type'] == 'veteran'
email = @form_data['veteran_email'] || user&.va_profile_email
[email, @form_data.dig('veteran_full_name', 'first')]

# user's own claim
# user is not a veteran
elsif @form_data['claim_ownership'] == 'self' && @form_data['claimant_type'] == 'non-veteran'
email = @form_data['claimant_email'] || user&.va_profile_email
[email, @form_data.dig('claimant_full_name', 'first')]

# someone else's claim
# claimant (aka someone else) is a veteran
# or
# claimant (aka someone else) is not a veteran
elsif @form_data['claim_ownership'] == 'third-party'
[@form_data['witness_email'], @form_data.dig('witness_full_name', 'first')]

else
[nil, nil]
end
end

def form21_0966_first_name
if form_data['preparer_identification'] == 'SURVIVING_DEPENDENT'
form_data.dig('surviving_dependent_full_name', 'first')
else
form_data.dig('veteran_full_name', 'first') || user&.first_name
end
end

def form21_0966_email_address
if form_data['preparer_identification'] == 'SURVIVING_DEPENDENT'
form_data['surviving_dependent_email']
else
form_data['veteran_email']
end
end

def form21_0966_personalization
intent_to_file_benefits, intent_to_file_benefits_links = get_intent_to_file_benefits_variables
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
vba_20_10206:
first_name: [full_name, first]
email: email_address
vba_20_10207:
preparer_type:
veteran:
first_name: [veteran_full_name, first]
email: veteran_email_address
third-party-veteran:
first_name: [third_party_full_name, first]
email: veteran_email_address
non-veteran:
first_name: [non_veteran_full_name, first]
email: non_veteran_email_address
third-party-non-veteran:
first_name: [third_party_full_name, first]
email: non_veteran_email_address
vba_21_0845:
authorizer_type:
veteran:
first_name: [veteran_full_name, first]
email: veteran_email
non_veteran:
first_name: [authorizer_full_name, first]
email: authorizer_email
vba_21_0966:
preparer_identification:
surviving_dependent:
first_name: [surviving_dependent_full_name, first]
email: surviving_dependent_email
vba_21_10210:
claim_ownership:
self:
claimant_type:
veteran:
first_name: [veteran_full_name, first]
email: veteran_email
non-veteran:
first_name: [claimant_full_name, first]
email: claimant_email
third-party:
claimant_type:
veteran: veteran_email
non-veteran: [veteran_full_name, first]
vba_40_10007:
application:
applicant:
applicant_relationship_to_claimant:
self:
first_name: [application, claimant, name, first]
first_name: [application, applicant, name, first]
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# frozen_string_literal: true

module SimpleFormsApi
module Notification
module ParsingUtils
def contact_info
form_mapping = YAML.load_file(
'modules/simple_forms_api/app/services/simple_forms_api/notification/form_mapping.yml'
)&.dig(form_number)

return unless form_mapping

transformed_data = deep_transform_keys_and_values(form_data)
mapping_path = find_mapping_path(form_mapping, transformed_data)

return unless mapping_path

first_name = dig_value(transformed_data, mapping_path['first_name'])
email = dig_value(transformed_data, mapping_path['email']) || user&.va_profile_email

{ first_name:, email: }
end

private

def find_mapping_path(form_mapping, form_data)
return form_mapping if form_mapping.key?('first_name') && form_mapping.key?('email')

form_mapping.each do |key, value|
next unless form_data.key?(key)

# If the value under this key is a hash and its keys
# match the form_data's value, go deeper
return find_mapping_path(value[form_data[key]], form_data) if value.is_a?(Hash) && value.key?(form_data[key])
end

nil
end

def deep_transform_keys_and_values(hash)
hash.deep_transform_keys { |key| key.to_s.underscore.downcase }
.transform_values do |value|
case value
when Hash
deep_transform_keys_and_values(value)
when Array
value.map { |v| v.is_a?(Hash) ? deep_transform_keys_and_values(v) : v.to_s.underscore.downcase }
else
value.to_s.underscore.downcase
end
end
end

def dig_value(data, keys)
return data[keys] unless keys.is_a?(Array)

keys.reduce(data) { |d, key| d.is_a?(Hash) ? d[key] : nil }
end
end
end
end
Loading
Loading