Class: CentralMail::SubmitCentralForm686cJob

Inherits:
Object
  • Object
show all
Includes:
SentryLogging, Sidekiq::Job
Defined in:
app/sidekiq/central_mail/submit_central_form686c_job.rb

Defined Under Namespace

Classes: CentralMailResponseError

Constant Summary collapse

FOREIGN_POSTALCODE =
'00000'
FORM_ID =
'686C-674'
FORM_ID_674 =
'21-674'
STATSD_KEY_PREFIX =
'worker.submit_686c_674_backup_submission'
RETRY =
16

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from SentryLogging

#log_exception_to_sentry, #log_message_to_sentry, #non_nil_hash?, #normalize_level, #rails_logger, #set_sentry_metadata

Instance Attribute Details

#attachment_pathsObject (readonly)

Returns the value of attribute attachment_paths.



23
24
25
# File 'app/sidekiq/central_mail/submit_central_form686c_job.rb', line 23

def attachment_paths
  @attachment_paths
end

#claimObject (readonly)

Returns the value of attribute claim.



23
24
25
# File 'app/sidekiq/central_mail/submit_central_form686c_job.rb', line 23

def claim
  @claim
end

#form_pathObject (readonly)

Returns the value of attribute form_path.



23
24
25
# File 'app/sidekiq/central_mail/submit_central_form686c_job.rb', line 23

def form_path
  @form_path
end

Class Method Details

.trigger_failure_events(msg) ⇒ Object



234
235
236
237
238
239
240
241
242
243
# File 'app/sidekiq/central_mail/submit_central_form686c_job.rb', line 234

def self.trigger_failure_events(msg)
  monitor = Dependents::Monitor.new
  saved_claim_id, _, encrypted_user_struct = msg['args']
  user_struct = JSON.parse(KmsEncrypted::Box.new.decrypt(encrypted_user_struct)) if encrypted_user_struct.present?
  claim = SavedClaim::DependencyClaim.find(saved_claim_id)
  email = claim.parsed_form.dig('dependents_application', 'veteran_contact_information', 'email_address') ||
          user_struct.try(:va_profile_email)
  monitor.track_submission_exhaustion(msg, email)
  claim.send_failure_email(email)
end

Instance Method Details

#check_success(response, saved_claim_id, user_struct) ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
118
# File 'app/sidekiq/central_mail/submit_central_form686c_job.rb', line 107

def check_success(response, saved_claim_id, user_struct)
  if response.success?
    Rails.logger.info('CentralMail::SubmitCentralForm686cJob succeeded!',
                      { user_uuid: user_struct['uuid'], saved_claim_id:, icn: user_struct['icn'] })
    update_submission('success')
    send_confirmation_email(OpenStruct.new(user_struct))
  else
    Rails.logger.info('CentralMail::SubmitCentralForm686cJob Unsuccessful',
                      { response: response['message'].presence || response['errors'] })
    raise CentralMailResponseError
  end
end

#cleanup_file_pathsObject



102
103
104
105
# File 'app/sidekiq/central_mail/submit_central_form686c_job.rb', line 102

def cleanup_file_paths
  Common::FileHelpers.delete_file_if_exists(form_path)
  attachment_paths.each { |p| Common::FileHelpers.delete_file_if_exists(p) }
end

#create_form_submission_attempt(intake_uuid) ⇒ Object



81
82
83
84
85
86
87
88
89
90
# File 'app/sidekiq/central_mail/submit_central_form686c_job.rb', line 81

def create_form_submission_attempt(intake_uuid)
  FormSubmissionAttempt.transaction do
    form_submission = FormSubmission.create(
      form_type: claim.submittable_686? ? FORM_ID : FORM_ID_674,
      saved_claim: claim,
      user_account: UserAccount.find_by(icn: claim.parsed_form['veteran_information']['icn'])
    )
    FormSubmissionAttempt.create(form_submission:, benefits_intake_uuid: intake_uuid)
  end
end

#create_request_bodyObject



120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'app/sidekiq/central_mail/submit_central_form686c_job.rb', line 120

def create_request_body
  body = {
    'metadata' => .to_json
  }

  body['document'] = to_faraday_upload(form_path)

  i = 0
  attachment_paths.each do |file_path|
    body["attachment#{i += 1}"] = to_faraday_upload(file_path)
  end

  body
end

#extract_uuid_from_central_mail_message(data) ⇒ Object



27
28
29
# File 'app/sidekiq/central_mail/submit_central_form686c_job.rb', line 27

def extract_uuid_from_central_mail_message(data)
  data.body[/(?<=\[).*?(?=\])/].split(': ').last if data.body.present?
end

#generate_attachment_metadata(attachment_paths) ⇒ Object



211
212
213
214
215
216
217
218
219
220
221
# File 'app/sidekiq/central_mail/submit_central_form686c_job.rb', line 211

def (attachment_paths)
   = {}
  i = 0
  attachment_paths.each do |file_path|
    i += 1
     = get_hash_and_pages(file_path)
    ["ahash#{i}"] = [:hash]
    ["numberPages#{i}"] = [:pages]
  end
  
end

#generate_metadataObject



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'app/sidekiq/central_mail/submit_central_form686c_job.rb', line 168

def 
  form = claim.parsed_form['dependents_application']
  veteran_information = form['veteran_information'].presence || claim.parsed_form['veteran_information']
   = get_hash_and_pages(form_path)
  address = form['veteran_contact_information']['veteran_address']
  is_usa = address['country_name'] == 'USA'
   = {
    'veteranFirstName' => veteran_information['full_name']['first'],
    'veteranLastName' => veteran_information['full_name']['last'],
    'fileNumber' => veteran_information['file_number'] || veteran_information['ssn'],
    'receiveDt' => claim.created_at.in_time_zone('Central Time (US & Canada)').strftime('%Y-%m-%d %H:%M:%S'),
    'uuid' => claim.guid,
    'zipCode' => is_usa ? address['zip_code'] : FOREIGN_POSTALCODE,
    'source' => 'va.gov',
    'hashV' => [:hash],
    'numberAttachments' => attachment_paths.size,
    'docType' => claim.form_id,
    'numberPages' => [:pages]
  }

   = SimpleFormsApiSubmission::MetadataValidator.validate(, zip_code_is_us_based: is_usa)

  .merge((attachment_paths))
end

#generate_metadata_lhObject



193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'app/sidekiq/central_mail/submit_central_form686c_job.rb', line 193

def 
  form = claim.parsed_form['dependents_application']
  # sometimes veteran_information is not in dependents_application, but claim.add_veteran_info will make sure
  # it's in the outer layer of parsed_form
  veteran_information = form['veteran_information'].presence || claim.parsed_form['veteran_information']
  address = form['veteran_contact_information']['veteran_address']
  {
    veteran_first_name: veteran_information['full_name']['first'],
    veteran_last_name: veteran_information['full_name']['last'],
    file_number: veteran_information['file_number'] || veteran_information['ssn'],
    zip: address['country_name'] == 'USA' ? address['zip_code'] : FOREIGN_POSTALCODE,
    doc_type: claim.form_id,
    claim_date: claim.created_at,
    source: 'va.gov backup dependent claim submission',
    business_line: 'CMP'
  }
end

#get_files_from_claimObject



92
93
94
95
96
97
98
99
100
# File 'app/sidekiq/central_mail/submit_central_form686c_job.rb', line 92

def get_files_from_claim
  # process the main pdf record and the attachments as we would for a vbms submission
  form_674_path = process_pdf(claim.to_pdf(form_id: FORM_ID_674), claim.created_at, FORM_ID_674) if claim.submittable_674? # rubocop:disable Layout/LineLength
  form_686c_path = process_pdf(claim.to_pdf(form_id: FORM_ID), claim.created_at, FORM_ID) if claim.submittable_686?
  @form_path = form_686c_path || form_674_path
  @attachment_paths = claim.persistent_attachments.map { |pa| process_pdf(pa.to_pdf, claim.created_at) }
  # Treat 674 as first attachment
  attachment_paths.insert(0, form_674_path) if form_686c_path.present? && form_674_path.present?
end

#get_hash_and_pages(file_path) ⇒ Object



161
162
163
164
165
166
# File 'app/sidekiq/central_mail/submit_central_form686c_job.rb', line 161

def get_hash_and_pages(file_path)
  {
    hash: Digest::SHA256.file(file_path).hexdigest,
    pages: PdfInfo::Metadata.read(file_path).pages
  }
end

#log_cmp_response(response) ⇒ Object (private)



260
261
262
# File 'app/sidekiq/central_mail/submit_central_form686c_job.rb', line 260

def log_cmp_response(response)
  log_message_to_sentry("vre-central-mail-response: #{response}", :info, {}, { team: 'vfs-ebenefits' })
end

#perform(saved_claim_id, encrypted_vet_info, encrypted_user_struct) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'app/sidekiq/central_mail/submit_central_form686c_job.rb', line 39

def perform(saved_claim_id, encrypted_vet_info, encrypted_user_struct)
  vet_info = JSON.parse(KmsEncrypted::Box.new.decrypt(encrypted_vet_info))
  user_struct = JSON.parse(KmsEncrypted::Box.new.decrypt(encrypted_user_struct))
  # if the 686c-674 has failed we want to call this central mail job (credit to submit_saved_claim_job.rb)
  # have to re-find the claim and add the relevant veteran info
  Rails.logger.info('CentralMail::SubmitCentralForm686cJob running!',
                    { user_uuid: user_struct['uuid'], saved_claim_id:, icn: user_struct['icn'] })
  @claim = SavedClaim::DependencyClaim.find(saved_claim_id)
  claim.add_veteran_info(vet_info)

  get_files_from_claim
  result = upload_to_lh
  check_success(result, saved_claim_id, user_struct)
rescue => e
  # if we fail, update the associated central mail record to failed and send the user the failure email
  Rails.logger.warn('CentralMail::SubmitCentralForm686cJob failed!',
                    { user_uuid: user_struct['uuid'], saved_claim_id:, icn: user_struct['icn'], error: e.message })
  update_submission('failed')
  raise
ensure
  cleanup_file_paths
end

#process_pdf(pdf_path, timestamp = nil, form_id = nil) ⇒ Object



146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'app/sidekiq/central_mail/submit_central_form686c_job.rb', line 146

def process_pdf(pdf_path, timestamp = nil, form_id = nil)
  stamped_path1 = PDFUtilities::DatestampPdf.new(pdf_path).run(text: 'VA.GOV', x: 5, y: 5, timestamp:)
  stamped_path2 = PDFUtilities::DatestampPdf.new(stamped_path1).run(
    text: 'FDC Reviewed - va.gov Submission',
    x: 400,
    y: 770,
    text_only: true
  )
  if form_id.present?
    stamped_pdf_with_form(form_id, stamped_path2, timestamp)
  else
    stamped_path2
  end
end

#send_confirmation_email(user) ⇒ Object



223
224
225
226
227
228
229
230
231
232
# File 'app/sidekiq/central_mail/submit_central_form686c_job.rb', line 223

def send_confirmation_email(user)
  return if user.va_profile_email.blank?

  VANotify::ConfirmationEmail.send(
    email_address: user.va_profile_email,
    template_id: Settings.vanotify.services.va_gov.template_id.form686c_confirmation_email,
    first_name: user&.first_name&.upcase,
    user_uuid_and_form_id: "#{user.uuid}_#{FORM_ID}"
  )
end

#split_file_and_path(path) ⇒ Object (private)



274
275
276
# File 'app/sidekiq/central_mail/submit_central_form686c_job.rb', line 274

def split_file_and_path(path)
  { file: path, file_name: path.split('/').last }
end

#stamped_pdf_with_form(form_id, path, timestamp) ⇒ Object (private)



247
248
249
250
251
252
253
254
255
256
257
258
# File 'app/sidekiq/central_mail/submit_central_form686c_job.rb', line 247

def stamped_pdf_with_form(form_id, path, timestamp)
  PDFUtilities::DatestampPdf.new(path).run(
    text: 'Application Submitted on va.gov',
    x: form_id == '686C-674' ? 400 : 300,
    y: form_id == '686C-674' ? 675 : 775,
    text_only: true, # passing as text only because we override how the date is stamped in this instance
    timestamp:,
    page_number: form_id == '686C-674' ? 6 : 0,
    template: "lib/pdf_fill/forms/pdfs/#{form_id}.pdf",
    multistamp: true
  )
end

#to_faraday_upload(file_path) ⇒ Object



139
140
141
142
143
144
# File 'app/sidekiq/central_mail/submit_central_form686c_job.rb', line 139

def to_faraday_upload(file_path)
  Faraday::UploadIO.new(
    file_path,
    Mime[:pdf].to_s
  )
end

#update_submission(state) ⇒ Object



135
136
137
# File 'app/sidekiq/central_mail/submit_central_form686c_job.rb', line 135

def update_submission(state)
  claim.central_mail_submission.update!(state:) if claim.respond_to?(:central_mail_submission)
end

#upload_to_lhObject



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'app/sidekiq/central_mail/submit_central_form686c_job.rb', line 62

def upload_to_lh
  Rails.logger.info({ message: 'SubmitCentralForm686cJob Lighthouse Initiate Submission Attempt',
                      claim_id: claim.id })
  lighthouse_service = BenefitsIntakeService::Service.new(with_upload_location: true)
  uuid = lighthouse_service.uuid
  Rails.logger.info({ message: 'SubmitCentralForm686cJob Lighthouse Submission Attempt', claim_id: claim.id,
                      uuid: })
  response = lighthouse_service.upload_form(
    main_document: split_file_and_path(form_path),
    attachments: attachment_paths.map(&method(:split_file_and_path)),
    form_metadata: 
  )
  create_form_submission_attempt(uuid)

  Rails.logger.info({ message: 'SubmitCentralForm686cJob Lighthouse Submission Successful', claim_id: claim.id,
                      uuid: })
  response
end

#valid_claim_data(saved_claim_id, vet_info) ⇒ Object (private)

Raises:

  • (Invalid686cClaim)


264
265
266
267
268
269
270
271
272
# File 'app/sidekiq/central_mail/submit_central_form686c_job.rb', line 264

def valid_claim_data(saved_claim_id, vet_info)
  claim = SavedClaim::DependencyClaim.find(saved_claim_id)

  claim.add_veteran_info(vet_info)

  raise Invalid686cClaim unless claim.valid?(:run_686_form_jobs)

  claim.formatted_686_data(vet_info)
end