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

Handle Immigration ATP Statuses #472

Open
wants to merge 3 commits into
base: trunk
Choose a base branch
from
Open
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
20 changes: 10 additions & 10 deletions lib/aca_entities/atp/functions/build_application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ def tax_returns_hash
if applicant_is_primary_tax_filer
true
else
@tax_return[:tax_household][:spouse_tax_filer] == @applicant_identifier
@tax_return.dig(:tax_household, :spouse_tax_filer, :role_reference, :ref) == @applicant_identifier
end
else
false
Expand Down Expand Up @@ -334,17 +334,17 @@ def applicant_hash
# assumption that the first immigration document sent holds the subject for the FAA applicant, may need to be revisited
vlp_subject: vlp_documents_hash&.first&.dig(:subject),
alien_number: vlp_documents_hash&.select { |document| document[:alien_number].present? }&.first&.dig(:alien_number),
i94_number: nil,
visa_number: nil,
passport_number: nil,
sevis_id: nil,
i94_number: vlp_documents_hash&.select { |document| document[:i94_number].present? }&.first&.dig(:i94_number),
visa_number: vlp_documents_hash&.select { |document| document[:visa_number].present? }&.first&.dig(:visa_number),
passport_number: vlp_documents_hash&.select { |document| document[:passport_number].present? }&.first&.dig(:passport_number),
sevis_id: vlp_documents_hash&.select { |document| document[:sevis_id].present? }&.first&.dig(:sevis_id),
naturalization_number: vlp_documents_hash&.select { |document| document[:naturalization_number].present? }&.first&.dig(:naturalization_number),
receipt_number: nil,
citizenship_number: nil,
card_number: nil,
country_of_citizenship: nil,
citizenship_number: vlp_documents_hash&.select { |document| document[:citizenship_number].present? }&.first&.dig(:citizenship_number),
card_number: vlp_documents_hash&.select { |document| document[:card_number].present? }&.first&.dig(:card_number),
country_of_citizenship: vlp_documents_hash&.select { |document| document[:country_of_citizenship].present? }&.first&.dig(:country_of_citizenship),
vlp_description: nil,
expiration_date: nil,
expiration_date: vlp_documents_hash&.first&.dig(:expiration_date),
issuing_country: nil,
family_member_reference: family_member_reference_hash,
person_hbx_id: @applicant_identifier, # default value
Expand Down Expand Up @@ -375,7 +375,7 @@ def applicant_hash
has_other_income: !other_income_hash.empty?,
has_deductions: !deduction_hash.empty?,
has_enrolled_health_coverage: !benefits_hash.concat(benefits_esc_hash).select { |h| h['kind'] == 'is_enrolled' }.empty?,
has_eligible_health_coverage: benefits_hash.concat(benefits_esc_hash).select { |h| h['kind'] == 'is_eligible' }.empty? ? nil : true,
has_eligible_health_coverage: benefits_hash.concat(benefits_esc_hash).select { |h| h['kind'] == 'is_eligible' }.present?,
addresses: AcaEntities::Atp::Functions::AddressBuilder.new.call(@memoized_data, @applicant_identifier), # default value
emails: email_hash, # default value
phones: phone_hash, # default value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,33 @@ class LawfulPresenceDeterminationBuilder
extend Dry::Transformer::Registry
import Dry::Transformer::Coercions

# rubocop:disable Metrics/CyclomaticComplexity
def call(cache, m_identifier = nil)
member_id = m_identifier || '*'
person_augmentation = cache.find(Regexp.new("record.people.#{member_id}.augementation"))
us_citizen_indicator = cache.find(Regexp.new("us_citizen_indicator.#{member_id}"))&.first&.item
naturalized_indicator = person_augmentation.map(&:item).first[:us_naturalized_citizen_indicator]
# no_alien_number_indicator = input.find(Regexp.new("noAlienNumberIndicator.#{member_identifier}"))&.first

# if an immigration document exists, then the person is lawfully present
applicants = cache.find(Regexp.new("insurance_application.insurance_applicants"))&.first&.item
insurance_applicant = applicants[member_id.to_sym]
immigration_document = insurance_applicant&.dig(:lawful_presence_status, :immigration_documents, 0)
alien_lawfully_present_indicator = immigration_document&.dig(:category_code)&.present?

hash = {
'us_citizen' => us_citizen_indicator,
'naturalized_citizen' => naturalized_indicator
# 'alien_lawfully_present' => no_alien_number_indicator,
'naturalized_citizen' => naturalized_indicator,
'alien_lawfully_present' => alien_lawfully_present_indicator
}

val = if naturalized_indicator
'naturalized_citizen'
else
hash.keys.find { |_k| hash.key(true) }
hash.keys.find { |k| hash[k] == true }
end
val || 'not_lawfully_present_in_us'
end

# rubocop:enable Metrics/CyclomaticComplexity
end
end
end
Expand Down
120 changes: 117 additions & 3 deletions lib/aca_entities/atp/functions/vlp_document_hash_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,26 @@ module Functions
# build VlpDocument hash so that transformer can deal with array values
class VlpDocumentHashBuilder
SUBJECT_MAP = {
"NaturalizationCertificate" => "Naturalization Certificate"
# Certificate of Citizenship
"NaturalizationCertificate" => "Naturalization Certificate",
"CertificateOfCitizenship" => "Certificate of Citizenship",
"DS2019" => "DS2019 (Certificate of Eligibility for Exchange Visitor (J-1) Status)",
"I20" => "I-20 (Certificate of Eligibility for Nonimmigrant (F-1) Student Status)",
"I327" => "I-327 (Reentry Permit)",
"I551" => "I-551 (Permanent Resident Card)",
"I571" => "I-571 (Refugee Travel Document)",
"I766" => "I-766 (Employment Authorization Card)",
"I94" => "I-94 (Arrival/Departure Record)",
"I94InPassport" => "I-94 (Arrival/Departure Record) in Unexpired Foreign Passport",
"MachineReadableVisa" => "Machine Readable Immigrant Visa (with Temporary I-551 Language)",
"TemporaryI551Stamp" => "Temporary I-551 Stamp (on passport or I-94)",
"UnexpiredForeignPassport" => "Unexpired Foreign Passport"
}.freeze

def call(document)
vlp_document = update_subject(document)
person_ids_hash = create_person_ids_hash(vlp_document)
document_number_hash = create_document_number_hash(vlp_document)

vlp_document = collect_document_fields(vlp_document)
extracted_information_hash = person_ids_hash.merge!(document_number_hash)
vlp_document.merge!(extracted_information_hash)
end
Expand All @@ -41,6 +52,109 @@ def create_document_number_hash(vlp_document)
# assuming only one document_number is sent and matches the document category code, may need to be revisited
{ category_code_key => vlp_document[:document_numbers]&.first&.dig(:identification_id) }
end

# the document number will either correspond to the vlp document's card number or the naturalization number.
# if the document type is a naturalization certificate, the document number will be considered the naturalization_number key.
def collect_document_fields(vlp_document)
vlp_document[:card_number] = vlp_document[:document_numbers]&.first&.dig(:identification_id).to_s

# this handles whether the expiration date returned is a date inside a hash or null
vlp_document[:expiration_date] =
vlp_document[:expiration_date].is_a?(Hash) ? vlp_document[:expiration_date][:date] : vlp_document[:expiration_date]

handle_document_person_ids(vlp_document)
vlp_document
end

def handle_document_person_ids(vlp_document)
document_person_ids = vlp_document[:document_person_ids]
document_person_ids.each do |document_person_id|
handle_identification_category(vlp_document, document_person_id)
end
end

# this method handles the identification category text and maps it to the correct key in the vlp_document hash
def handle_identification_category(vlp_document, document_person_id)
case document_person_id[:identification_category_text]
when 'Alien Number'
vlp_document[:alien_number] = document_person_id[:identification_id]
when 'Passport Number'
vlp_document[:passport_number] = document_person_id[:identification_id]
vlp_document[:country_of_citizenship] = map_iso_to_country_names(document_person_id[:identification_jurisdiction])
when 'I-94 Number'
vlp_document[:i94_number] = document_person_id[:identification_id]
when 'Sevis ID'
vlp_document[:sevis_id] = document_person_id[:identification_id]
when 'Certificate of Citizenship'
vlp_document[:citizenship_number] = vlp_document[:document_numbers]&.dig(:identification_id)
when 'Visa Number'
vlp_document[:visa_number] = document_person_id[:identification_id]
end
end

def map_iso_to_country_names(country_of_citizenship)
return nil unless country_of_citizenship.present?
iso_country_name = IsoCountryCodes.find(country_of_citizenship).name
if iso_countries.include?(iso_country_name)
map_countries_to_iso[iso_country_name]
else
iso_country_name
end
end

def iso_countries
[
"Bolivia (Plurinational State of)",
"Brunei Darussalam",
"Czechia",
"Cote d'Ivoire",
"Holy See",
"Iran (Islamic Republic of)",
"East Timor (Timor Timur)",
"Korea (Democratic People's Republic of)",
"Korea (Republic of)",
"Lao People's Democratic Republic",
"Macedonia (the former Yugoslav Republic of)",
"Micronesia (Federated States of)",
"Moldova (Republic of)",
"Russian Federation",
"Saint Vincent and the Grenadines",
"Swaziland",
"Syrian Arab Republic",
"Tanzania, United Republic of",
"Timor-Leste",
"United Kingdom of Great Britain and Northern Ireland",
"United States of America",
"Venezuela (Bolivarian Republic of)"
]
end

# this is a list of countries that have different names in the ISO library than our vlp documents on the frontend
def map_countries_to_iso
{
"Bolivia (Plurinational State of)" => "Bolivia",
"Brunei Darussalam" => "Brunei",
"Czechia" => "Czech Republic",
"Côte d'Ivoire" => "Cote d'Ivoire",
"Holy See" => "Vatican City",
"Iran (Islamic Republic of)" => "Iran",
"Korea (Democratic People's Republic of)" => "Korea, North",
"Korea (Republic of)" => "Korea, South",
"Lao People's Democratic Republic" => "Laos",
"Macedonia (the former Yugoslav Republic of)" => "Macedonia",
"Micronesia (Federated States of)" => "Micronesia",
"Moldova (Republic of)" => "Moldova",
"Russian Federation" => "Russia",
"Saint Vincent and the Grenadines" => "Saint Vincent",
"Swaziland" => "Eswatini",
"Syrian Arab Republic" => "Syria",
"Tanzania, United Republic of" => "Tanzania",
"Timor-Leste" => "East Timor (Timor Timur)",
"United Kingdom of Great Britain and Northern Ireland" => "United Kingdom",
"United States of America" => "United States",
"Venezuela (Bolivarian Republic of)" => "Venezuela"
}
end
end
end
end
Expand Down
18 changes: 8 additions & 10 deletions lib/aca_entities/atp/transformers/cv/vlp_document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,19 @@ module Cv
# Transformers implementation for atp payloads
class VlpDocument < ::AcaEntities::Operations::Transforms::Transform
include ::AcaEntities::Operations::Transforms::Transformer

map 'category_code', 'subject'
map 'alien_number', 'alien_number'
add_key 'i94_number', value: nil
add_key 'visa_number', value: nil
add_key 'sevis_id', value: nil
map 'i94_number', 'i94_number'
map 'visa_number', 'visa_number'
map 'sevis_id', 'sevis_id'
map 'naturalization_certificate', 'naturalization_number'
add_key 'passport_number', value: nil
map 'passport_number', 'passport_number'
add_key 'receipt_number', value: nil
add_key 'citizenship_number', value: nil
add_key 'card_number', value: nil
add_key 'country_of_citizenship', value: nil
add_key 'expiration_date', value: nil
map 'citizenship_number', 'citizenship_number'
map 'card_number', 'card_number'
map 'country_of_citizenship', 'country_of_citizenship'
map 'expiration_date', 'expiration_date'
add_key 'issuing_country', value: nil

end
end
end
Expand Down
44 changes: 41 additions & 3 deletions spec/aca_entities/atp/functions/build_application_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@
result = subject.first
expect(result[:applicants].first[:has_eligible_health_coverage]).to be_truthy
end
it "should contain nil for applicant without other eligible coverage" do
it "should contain false for applicant without other eligible coverage" do
result = subject.first
expect(result[:applicants][1][:has_eligible_health_coverage]).to be nil
expect(result[:applicants][1][:has_eligible_health_coverage]).to be_falsey
end
end

Expand All @@ -48,6 +48,21 @@
end
end

context "with valid xml containing applicant filing tax return jointly" do
before do
@result = subject.last
end
it "should return true for is_joint_tax_filing" do
expect(@result[:applicants][0][:is_joint_tax_filing]).to be_truthy
end
it "should return joint for tax_filer_kind" do
expect(@result[:applicants][0][:tax_filer_kind]).to eq("joint")
end
it "should return true for is_required_to_file_taxes" do
expect(@result[:applicants][0][:is_required_to_file_taxes]).to be_truthy
end
end

context "with valid xml containing pregnant and post partum applicant" do
before do
@result = subject.first
Expand Down Expand Up @@ -78,14 +93,19 @@
end
end

context "with valid xml containing naturalization certificate document information" do
context "with valid xml containing naturalization certificate document information and other document fields" do
before do
@result = subject.first
end
it "should return naturalization certificate document information for naturalized applicant" do
expect(@result[:applicants][0][:vlp_subject]).to eq("Naturalization Certificate")
expect(@result[:applicants][0][:naturalization_number]).to eq(12_345)
expect(@result[:applicants][0][:alien_number]).to eq(67_890)
expect(@result[:applicants][0][:i94_number]).to eq(45_678)
expect(@result[:applicants][0][:passport_number]).to eq(14_373)
expect(@result[:applicants][0][:sevis_id]).to eq(54_321)
expect(@result[:applicants][0][:visa_number]).to eq(56_789)
expect(@result[:applicants][0][:country_of_citizenship]).to eq("Brazil")
end
it "should return nil naturalization certificate document information for other applicant" do
expect(@result[:applicants][1][:vlp_subject]).to be nil
Expand Down Expand Up @@ -170,4 +190,22 @@
expect(@result[:applicants][0][:deductions].last[:amount]).to eq(100)
end
end

context "with valid xml containing applicant with enrolled in health coverage and access to other coverage info" do
before do
@result = subject.first
end

it "should return correct enrolled in health coverage for applicant" do
expect(@result[:applicants][0][:has_enrolled_health_coverage]).to eq(false)
expect(@result[:applicants][1][:has_enrolled_health_coverage]).to eq(false)
expect(@result[:applicants][2][:has_enrolled_health_coverage]).to eq(false)
end

it "should return correct access to other coverage for applicant" do
expect(@result[:applicants][0][:has_eligible_health_coverage]).to eq(true)
expect(@result[:applicants][1][:has_eligible_health_coverage]).to eq(false)
expect(@result[:applicants][2][:has_eligible_health_coverage]).to eq(false)
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# frozen_string_literal: true

require 'spec_helper'
require 'aca_entities/atp/functions/lawful_presence_determination_builder'
require "support/atp/inbound_lawful_presence_application"

RSpec.describe AcaEntities::Atp::Functions::LawfulPresenceDeterminationBuilder do
include_context "inbound_build_application"
let(:cache) { context }
let(:member_id_alien_document) { "IDC1003158" }
let(:member_id_naturalized_citizen) { "IDC1003159" }
let(:member_id_us_citizen) { "IDC1002699" }
let(:member_id_not_lawful) { "IDC1003160" }
let(:subject) { described_class.new }

describe '#call' do
context 'when member_id is not provided' do
it 'returns "not_lawfully_present_in_us" when no indicators are true' do
expect(subject.call(cache)).to eq('not_lawfully_present_in_us')
end
end

context 'when member_id is provided' do
it 'returns "alien_lawfully_present" when category code on document is present' do
expect(subject.call(cache, member_id_alien_document)).to eq('alien_lawfully_present')
end

it 'returns "naturalized_citizen" when naturalized citizen indicator is true' do
expect(subject.call(cache, member_id_naturalized_citizen)).to eq('naturalized_citizen')
end

it 'returns "us_citizen" when us citizen indicator is true' do
expect(subject.call(cache, member_id_us_citizen)).to eq('us_citizen')
end

it 'returns "not_lawfully_present_in_us" when no indicators are true' do
expect(subject.call(cache, member_id_not_lawful)).to eq('not_lawfully_present_in_us')
end
end
end
end
Loading
Loading