Skip to content

Commit

Permalink
VA forms: Add form 21P-0847 (#12960)
Browse files Browse the repository at this point in the history
* initially generated files for 21p-0847

* add form mappings and tests

* rename files

* one more name change

* refactor multistamp methods and add tests
  • Loading branch information
gmrabian authored Jun 12, 2023
1 parent 9f088aa commit cae9321
Show file tree
Hide file tree
Showing 10 changed files with 205 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class UploadsController < ApplicationController
FORM_NUMBER_MAP = {
'21-10210' => 'vba_21_10210',
'21-4142' => 'vba_21_4142',
'21P-0847' => 'vba_21p_0847',
'26-4555' => 'vba_26_4555',
'10-10D' => 'vha_10_10d'
}.freeze
Expand Down
39 changes: 39 additions & 0 deletions modules/forms_api/app/form_mappings/vba_21p_0847.json.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"F[0].Page_2[0].FirstNameOfDeceasedClaimant[0]": "<%= data.dig('veteran_full_name', 'first') %>",
"F[0].Page_2[0].DeceasedClaimantMiddleInitial1[0]": "<%= data.dig('veteran_full_name', 'middle') %>",
"F[0].Page_2[0].DeceasedClaimantLastName[0]": "<%= data.dig('veteran_full_name', 'last') %>",
"F[0].Page_2[0].VA_File_Number[0]": "<%= data['veteran_va_file_number'] %>",
"F[0].Page_2[0].VeteransSocialSecurityNumber_FirstThreeNumbers[0]": "<%= data['veteran_ssn']&.[](0..2) %>",
"F[0].Page_2[0].VeteransSocialSecurityNumber_SecondTwoNumbers[0]": "<%= data['veteran_ssn']&.[](3..4) %>",
"F[0].Page_2[0].VeteransSocialSecurityNumber_LastFourNumbers[0]": "<%= data['veteran_ssn']&.[](5..8) %>",
"F[0].Page_2[0].DOByear[0]": "<%= data['veteran_date_of_birth']&.[](0..3) %>",
"F[0].Page_2[0].DOBmonth[0]": "<%= data['veteran_date_of_birth']&.[](5..6) %>",
"F[0].Page_2[0].DOBday[0]": "<%= data['veteran_date_of_birth']&.[](8..9) %>",
"F[0].Page_2[0].DODyear[0]": "<%= data['veteran_date_of_death']&.[](0..3) %>",
"F[0].Page_2[0].DODmonth[0]": "<%= data['veteran_date_of_death']&.[](5..6) %>",
"F[0].Page_2[0].DODday[0]": "<%= data['veteran_date_of_death']&.[](8..9) %>",

"F[0].Page_2[0].SubstituteClaimantFirstName[0]": "<%= data.dig('preparer_name', 'first') %>",
"F[0].Page_2[0].SubstituteClaimantMiddleInitial[0]": "<%= data.dig('preparer_name', 'middle') %>",
"F[0].Page_2[0].SubstituteClaimantLastName[0]": "<%= data.dig('preparer_name', 'last') %>",
"F[0].Page_2[0].Relationship[0]": "<%= data['relationship_to_deceased_claimant'] == 'other' ? data['other_relationship_to_deceased_claimant'] : data['relationship_to_deceased_claimant'] %>",
"F[0].Page_2[0].ClaimantsSocialSecurityNumber_FirstThreeNumbers[0]": "<%= data['preparer_ssn']&.[](0..2) %>",
"F[0].Page_2[0].ClaimantsSocialSecurityNumber_SecondTwoNumbers[0]": "<%= data['preparer_ssn']&.[](3..4) %>",
"F[0].Page_2[0].ClaimantsSocialSecurityNumber_LastFourNumbers[0]": "<%= data['preparer_ssn']&.[](5..8) %>",
"F[0].Page_2[0].CurrentMailingAddress_Country[0]": "<%= data.dig('preparer_address', 'country') %>",
"F[0].Page_2[0].CurrentMailingAddress_NumberAndStreet[0]": "<%= data.dig('preparer_address', 'street') %>",
"F[0].Page_2[0].CurrentMailingAddress_ApartmentOrUnitNumber[0]": "<%= data.dig('preparer_address', 'street2')&.gsub(/\D/, '') %>",
"F[0].Page_2[0].CurrentMailingAddress_StateOrProvince[0]": "<%= data.dig('preparer_address', 'state') %>",
"F[0].Page_2[0].CurrentMailingAddress_City[0]": "<%= data.dig('preparer_address', 'city') %>",
"F[0].Page_2[0].CurrentMailingAddress_ZIPOrPostalCode_FirstFiveNumbers[0]": "<%= data.dig('preparer_address', 'postal_code')&.[](0..4) %>",
"F[0].Page_2[0].CurrentMailingAddress_ZIPOrPostalCode_LastFourNumbers[0]": "<%= data.dig('preparer_address', 'postal_code')&.[](5..8) %>",
"F[0].Page_2[0].DaytimePhone[0]": "<%= data['preparer_home_phone'] %>",
"F[0].Page_2[0].EveningPhone[0]": "<%= data['preparer_home_phone'] %>",
"F[0].Page_2[0].CellPhone[0]": "<%= data['preparer_mobile_phone'] %>",
"F[0].Page_2[0].EmailAddress[0]": "<%= data['preparer_email'] %>",
"F[0].Page_2[0].FaxNumber[0]": "<%= %>",
"F[0].Page_2[0].Remarks[0]": "<%= data.dig('deceased_claimant_name', 'first') ? 'Deceased claimant info: ' : '' %><%= data.dig('deceased_claimant_name', 'first') %> <%= data.dig('deceased_claimant_name', 'middle') %> <%= data.dig('deceased_claimant_name', 'last') %> <%= data['deceased_claimant_date_of_birth'] ? 'dob: ' : '' %><%= data['deceased_claimant_date_of_birth'] %> <%= data['deceased_claimant_date_of_death'] ? 'dod:' : '' %> <%= data['deceased_claimant_date_of_death'] %> <%= data['deceased_claimant_ssn'] ? 'ssn: ' : '' %><%= data['deceased_claimant_ssn'] %> <%= data['deceased_claimant_va_file_number'] ? 'va file number: ' : '' %><%= data['deceased_claimant_va_file_number'] %> <%= data['additional_information'] ? 'Remarks: ' : '' %><%= data['additional_information'] %>",
"F[0].Page_2[0].SignatureField1[0]": "<%= data.dig('preparer_name', 'first') %> <%= data.dig('preparer_name', 'middle') %> <%= data.dig('preparer_name', 'last') %>",
"F[0].Page_2[0].DateSigned[0]": "<%= Time.current.in_time_zone('America/Chicago').strftime('%m/%d/%Y') %>",
"F[0]": "<%= data.dig('F') %>"
}
25 changes: 25 additions & 0 deletions modules/forms_api/app/models/forms_api/vba_21p_0847.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# frozen_string_literal: true

module FormsApi
class VBA21p0847
include Virtus.model(nullify_blank: true)

attribute :data

def initialize(data)
@data = data
end

def metadata
{
'veteranFirstName' => data.dig('veteran_full_name', 'first'),
'veteranLastName' => data.dig('veteran_full_name', 'last'),
'fileNumber' => data['veteran_va_file_number'].presence || data['veteran_ssn'],
'zipCode' => data.dig('preparer_address', 'postal_code'),
'source' => 'VA Platform Digital Forms',
'docType' => @data['form_number'],
'businessLine' => 'CMP'
}
end
end
end
65 changes: 43 additions & 22 deletions modules/forms_api/app/services/forms_api/pdf_stamper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@

module FormsApi
class PdfStamper
FORM_REQUIRES_STAMP = %w[26-4555 21-4142 21-10210].freeze
FORM_REQUIRES_STAMP = %w[26-4555 21-4142 21-10210 21P-0847].freeze
SUBMISSION_TEXT = 'Signed electronically and submitted via VA.gov at '

def self.stamp_pdf(generated_form_path, data)
if FORM_REQUIRES_STAMP.include? data['form_number']
stamp_method = "stamp#{data['form_number'].gsub('-', '')}"
stamp_method = "stamp#{data['form_number'].gsub('-', '')}".downcase
send(stamp_method, generated_form_path, data)
end
current_time = Time.current.in_time_zone('America/Chicago').strftime('%H:%M:%S')
Expand All @@ -33,36 +33,57 @@ def self.stamp214142(generated_form_path, data)
last_name = data.dig('preparer_identification', 'preparer_full_name', 'last')
suffix = data.dig('preparer_identification', 'preparer_full_name', 'suffix')
signature_text = "#{first_name} #{middle_name} #{last_name} #{suffix}"
page_configuration = [
{ type: :new_page },
{ type: :text, position: desired_stamps[0] },
{ type: :new_page }
]

stamp_path = Common::FileHelpers.random_file_path
Prawn::Document.generate(stamp_path, margin: [0, 0]) do |pdf|
pdf.start_new_page
pdf.draw_text signature_text, at: desired_stamps[0], size: 16
pdf.start_new_page
end

multistamp(generated_form_path, stamp_path)
rescue
Rails.logger.error "Failed to generate stamped file: #{e.message}"
raise
ensure
Common::FileHelpers.delete_file_if_exists(stamp_path) if defined?(stamp_path)
multistamp(generated_form_path, signature_text, page_configuration)
end

def self.stamp2110210(generated_form_path, data)
first_name, middle_name, last_name = get_name_to_stamp10210(data)
desired_stamps = [[50, 160]]
first_name, middle_name, last_name = get_name_to_stamp10210(data)
signature_text = "#{first_name} #{middle_name} #{last_name}"
page_configuration = [
{ type: :new_page },
{ type: :new_page },
{ type: :text, position: desired_stamps[0] }
]

multistamp(generated_form_path, signature_text, page_configuration)
end

def self.stamp21p0847(generated_form_path, data)
desired_stamps = [[50, 190]]
first_name = data.dig('preparer_name', 'first')
middle_name = data.dig('preparer_name', 'middle')
last_name = data.dig('preparer_name', 'last')
signature_text = "#{first_name} #{middle_name} #{last_name}"
page_configuration = [
{ type: :new_page },
{ type: :text, position: desired_stamps[0] }
]

multistamp(generated_form_path, signature_text, page_configuration)
end

def self.multistamp(generated_form_path, signature_text, page_configuration)
stamp_path = Common::FileHelpers.random_file_path
Prawn::Document.generate(stamp_path, margin: [0, 0]) do |pdf|
pdf.start_new_page
pdf.start_new_page
pdf.draw_text signature_text, at: desired_stamps[0], size: 16
page_configuration.each do |config|
case config[:type]
when :text
pdf.draw_text signature_text, at: config[:position], size: 16
when :new_page
pdf.start_new_page
end
end
end

multistamp(generated_form_path, stamp_path)
rescue
perform_multistamp(generated_form_path, stamp_path)
rescue => e
Rails.logger.error "Failed to generate stamped file: #{e.message}"
raise
ensure
Expand Down Expand Up @@ -99,7 +120,7 @@ def self.stamp(desired_stamps, generated_form_path, text_only: true)
File.rename(current_file_path, generated_form_path)
end

def self.multistamp(generated_form_path, stamp_path)
def self.perform_multistamp(generated_form_path, stamp_path)
out_path = "#{Common::FileHelpers.random_file_path}.pdf"
pdftk = PdfFill::Filler::PDF_FORMS
pdftk.multistamp(generated_form_path, stamp_path, out_path)
Expand Down
25 changes: 25 additions & 0 deletions modules/forms_api/spec/fixtures/form_json/vba_21p_0847-min.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"form_number": "21P-0847",
"preparer_name": {
"first": "Arthur",
"middle": "C",
"last": "Preparer"
},
"preparer_ssn": "222668888",
"preparer_home_phone": "1234567890",
"preparer_address": {
"country": "USA",
"street": "124 Main St",
"city": "Anytown",
"state": "CA",
"postal_code": "12345"
},
"veteran_full_name": {
"first": "Ursula",
"middle": "K",
"last": "Veteran"
},
"veteran_date_of_birth": "1929-10-21",
"veteran_ssn": "999442222",
"relationship_to_deceased_claimant": "spouse"
}
41 changes: 41 additions & 0 deletions modules/forms_api/spec/fixtures/form_json/vba_21p_0847.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"form_number": "21P-0847",
"preparer_name": {
"first": "Arthur",
"middle": "C",
"last": "Preparer"
},
"preparer_ssn": "222668888",
"preparer_home_phone": "1234567890",
"preparer_mobile_phone": "1234567890",
"preparer_email": "preparer_address@email.com",
"preparer_address": {
"country": "USA",
"street": "124 Main St",
"street2": "Apt #44",
"city": "Anytown",
"state": "CA",
"postal_code": "12345"
},
"veteran_full_name": {
"first": "Ursula",
"middle": "K",
"last": "Veteran"
},
"veteran_date_of_birth": "1929-10-21",
"veteran_date_of_death": "2018-01-22",
"veteran_ssn": "999442222",
"veteran_va_file_number": "111776666",
"deceased_claimant_name": {
"first": "Philip",
"middle": "K",
"last": "Deceased"
},
"deceased_claimant_date_of_birth": "1928-12-16",
"deceased_claimant_date_of_death": "1982-03-12",
"deceased_claimant_ssn": "666117777",
"deceased_claimant_va_file_number": "777992222",
"relationship_to_deceased_claimant": "other",
"other_relationship_to_deceased_claimant": "friend",
"additional_information": "Lots of extra stuff here"
}
1 change: 1 addition & 0 deletions modules/forms_api/spec/requests/v1/uploads_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ def self.test_submit_request(test_payload)
test_submit_request 'vba_26_4555.json'
test_submit_request 'vba_21_4142.json'
test_submit_request 'vba_21_10210.json'
test_submit_request 'vba_21p_0847.json'

def self.test_failed_request_scrubs_error_message(test_payload)
it 'makes the request and expects a failure' do
Expand Down
3 changes: 3 additions & 0 deletions modules/forms_api/spec/services/pdf_filler_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ def self.test_pdf_fill(form_number, test_payload = form_number)
test_pdf_fill 'vba_21_4142', 'vba_21_4142-min'
test_pdf_fill 'vba_21_10210'
test_pdf_fill 'vba_21_10210', 'vba_21_10210-min'
test_pdf_fill 'vba_21p_0847'
test_pdf_fill 'vba_21p_0847', 'vba_21p_0847-min'

def self.test_json_valid(mapping_file)
it 'validates json is parseable' do
Expand All @@ -39,4 +41,5 @@ def self.test_json_valid(mapping_file)
test_json_valid 'vha_10_10d.json.erb'
test_json_valid 'vba_21_4142.json.erb'
test_json_valid 'vba_21_10210.json.erb'
test_json_valid 'vba_21p_0847.json.erb'
end
27 changes: 27 additions & 0 deletions modules/forms_api/spec/services/pdf_stamper_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# frozen_string_literal: true

require 'rails_helper'
require FormsApi::Engine.root.join('spec', 'spec_helper.rb')

describe FormsApi::PdfStamper do
def self.test_pdf_stamp_error(stamp_method, test_payload)
it 'raises an error when generating stamped file' do
allow(Common::FileHelpers).to receive(:random_file_path).and_return('fake/stamp_path')
allow(Common::FileHelpers).to receive(:delete_file_if_exists)
allow(Prawn::Document).to receive(:generate).and_raise('Error generating stamped file')

generated_form_path = 'fake/generated_form_path'
data = JSON.parse(File.read("modules/forms_api/spec/fixtures/form_json/#{test_payload}.json"))

expect do
FormsApi::PdfStamper.send(stamp_method, generated_form_path, data)
end.to raise_error(RuntimeError, 'Error generating stamped file')

expect(Common::FileHelpers).to have_received(:delete_file_if_exists).with('fake/stamp_path')
end
end

test_pdf_stamp_error 'stamp214142', 'vba_21_4142'
test_pdf_stamp_error 'stamp2110210', 'vba_21_10210'
test_pdf_stamp_error 'stamp21p0847', 'vba_21p_0847'
end
Binary file added modules/forms_api/templates/vba_21p_0847.pdf
Binary file not shown.

0 comments on commit cae9321

Please sign in to comment.