Skip to content

Commit

Permalink
refine DumpSubmissionToPdf class further
Browse files Browse the repository at this point in the history
  • Loading branch information
pennja committed Sep 5, 2024
1 parent d3b7cf1 commit 40c1642
Showing 1 changed file with 103 additions and 142 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@
# ids.each { |id| DumpSubmissionToPdf.new(submission_id: id, parent_dir:).run }
# this will just put each submission in a folder by it's id under the parent dir
class DumpSubmissionToPdf
attr_accessor :submission, :parent_dir, :failed_uploads, :include_text_dump,
:quiet_upload_failures, :quiet_pdf_failures, :include_json_dump, :run_quiet
attr_reader :failures, :form_id, :include_json_dump, :include_text_dump,
:parent_dir, :quiet_pdf_failures, :quiet_upload_failures, :submission

def initialize(submission_id: nil, submission: nil, **options)
def initialize(form_id: nil, submission_id: nil, submission: nil, **options)
defaults = default_options.merge(options)

@failures = []
@submission = defaults[:submission] || FormSubmission.find(submission_id)
@form_id = form_id
@submission = submission || FormSubmission.find(submission_id)
@parent_dir = defaults[:parent_dir]
@include_text_dump = defaults[:include_text_dump]
@include_json_dump = defaults[:include_json_dump]
Expand All @@ -36,206 +37,166 @@ def initialize(submission_id: nil, submission: nil, **options)
end

def run
log_info(" - submission id: #{submission.id}")
write
write_as_json_dump if include_json_dump
write_as_text_dump if include_text_dump
write_user_uploads if user_uploads.present?
write_metadata
log_info("Processing submission ID: #{submission.id}")
process_submission_files
output_directory_path
rescue => e
if run_quiet
@failures << { id: submission.id, error: e.try(:message) || e }
log_error("failed submission: #{submission.id}")
else
raise e
end
rescue StandardError => e

Check failure on line 43 in modules/simple_forms_api/app/services/simple_forms_api/s3/dump_submission_to_pdf.rb

View workflow job for this annotation

GitHub Actions / Linting and Security

Style/RescueStandardError: Omit the error class when rescuing `StandardError` by itself.
handle_run_error(e)
end

private

def default_options
{
parent_dir: 'wipn8923-test',
include_text_dump: true, # include the form data as a text file
include_json_dump: true, # include the form data as a JSON object
quiet_upload_failures: true, # will skip problematic user uploads if true
quiet_pdf_failures: true, # will skip the PDF generating if it's not working
include_text_dump: true, # include the form data as a text file
parent_dir: 'wipn8923-test',
quiet_pdf_failures: true, # skip PDF generation silently
quiet_upload_failures: true, # skip problematic uploads silently
run_quiet: true
}
end

def metadata
@metadata ||= generate_metadata
end

def output_directory_path
@output_directory_path ||= "#{parent_dir}/#{submission.id}"
def process_submission_files
write_pdf
write_as_json_dump if include_json_dump
write_as_text_dump if include_text_dump
write_user_uploads if user_uploads.present?
write_metadata
end

def s3_resource
@s3_resource ||= Reports::Uploader.new_s3_resource
end
def handle_run_error(error)
raise error unless default_options[:run_quiet]

def target_bucket
@target_bucket ||= Reports::Uploader.s3_bucket
failures << { id: submission.id, error: error.message }
log_error("Failed submission: #{submission.id}", error)
end

def form_json
@form_json ||= JSON.parse(submission.form_json)['form']
def write_pdf
encoded_pdf = generate_pdf_content
save_file_to_s3("#{output_directory_path}/form.pdf", Base64.decode64(encoded_pdf))
rescue StandardError => e

Check failure on line 78 in modules/simple_forms_api/app/services/simple_forms_api/s3/dump_submission_to_pdf.rb

View workflow job for this annotation

GitHub Actions / Linting and Security

Style/RescueStandardError: Omit the error class when rescuing `StandardError` by itself.
quiet_pdf_failures ? write_pdf_error(e) : raise(e)
end

# ##
# File Writing Helpers:
def write
submission_create_date = submission.created_at.iso8601
form_json['form']['claimDate'] ||= submission_create_date
form_json['form']['applicationExpirationDate'] = 365.days.from_now.iso8601
def generate_pdf_content
service = EVSS::DisabilityCompensationForm::NonBreakeredService.new(submission.auth_headers)
response = service.get_form(form_json.to_json)
encoded_pdf = response.body['pdf']
content = Base64.decode64(encoded_pdf)
object = s3_resource.bucket(target_bucket).object("#{output_directory_path}/form.pdf")
object.put(body: content)
rescue => e
if quiet_pdf_failures
write_pdf_error(e)
else
raise e
end
service.get_form(form_json.to_json).body['pdf']
end

def write_pdf_error(error)
content = if error.present?
"#{error.try(:message)}\n\n#{error.try(:messages).try(:join, "\n\t - ")}"
else
'unknown failure'
end
rescue
content = 'unknown failure'
ensure
object = s3_resource.bucket(target_bucket).object("#{output_directory_path}/pdf_generating_failure_explanation.txt")
object.put(body: content)
log_error("PDF generation failed for submission: #{submission.id}", error)
save_file_to_s3("#{output_directory_path}/pdf_generating_failure.txt", error_details(error))
end

def error_details(error)
"#{error.message}\n\n#{error.backtrace.join("\n")}"
end

def write_as_json_dump
object = s3_resource.bucket(target_bucket).object("#{output_directory_path}/form_text_dump.txt")
content = JSON.pretty_generate(submission.form)
object.put(body: content)
save_file_to_s3("#{output_directory_path}/form_text_dump.json", JSON.pretty_generate(form_json))
end

def write_alternative
new_target = s3_resource.bucket(target_bucket).object("#{output_directory_path}/form.pdf")
new_target.upload_file(form_initial_path)
Common::FileHelpers.delete_file_if_exists(form_initial_path)
def write_as_text_dump
save_file_to_s3("#{output_directory_path}/form_text_dump.txt", form_text_dump.to_json)
end

def write_metadata
path = "#{output_directory_path}/metadata.txt"
object = s3_resource.bucket(target_bucket).object(path)
object.put(body: metadata.to_json)
save_file_to_s3("#{output_directory_path}/metadata.json", metadata.to_json)
end

def write_failure_report
path = "#{output_directory_path}/user_upload_failures.txt"
object = s3_resource.bucket(target_bucket).object(path)
content = JSON.pretty_generate(user_upload_failures)
object.put(body: content)
def write_user_uploads
log_info("Moving #{user_uploads.count} user uploads")
user_uploads.each { |upload| process_user_upload(upload) }
write_failure_report if user_upload_failures.present?
rescue StandardError => e

Check failure on line 112 in modules/simple_forms_api/app/services/simple_forms_api/s3/dump_submission_to_pdf.rb

View workflow job for this annotation

GitHub Actions / Linting and Security

Style/RescueStandardError: Omit the error class when rescuing `StandardError` by itself.
handle_upload_error(e)
end

def write_as_text_dump
path = "#{output_directory_path}/form_text_dump.txt"
object = s3_resource.bucket(target_bucket).object(path)
object.put(body: form_text_dump.to_json)
def process_user_upload(upload)
log_info("Processing upload: #{upload['name']} - #{upload['confirmationCode']}")
local_file = SupportingEvidenceAttachment.find_by(guid: upload['confirmationCode'])
raise 'Local record not found' unless local_file

copy_file_between_buckets(local_file)
end

def form_text_dump
@form_text_dump ||= generate_form_text_dump
def copy_file_between_buckets(local_file)
source_obj = s3_resource.bucket(local_file.get_file.uploader.aws_bucket).object(local_file.get_file.path)
target_obj = s3_resource.bucket(target_bucket).object("#{user_upload_path}/#{local_file.get_file.filename}")
target_obj.copy_from(source_obj)
end

def generate_form_text_dump
form = submission.form
return form if form['form'].blank?
def write_failure_report
save_file_to_s3("#{output_directory_path}/user_upload_failures.txt", JSON.pretty_generate(user_upload_failures))
end

form['form']['claimDate'] ||= submission.created_at.iso8601
form
def save_file_to_s3(path, content)
s3_resource.bucket(target_bucket).object(path).put(body: content)
end

def user_upload_path
@user_upload_path ||= "#{output_directory_path}/user_uploads"
def s3_resource
@s3_resource ||= Reports::Uploader.new_s3_resource
end

def user_uploads
@user_uploads ||= submission.form['form_uploads']
def target_bucket
@target_bucket ||= Reports::Uploader.s3_bucket
end

def user_upload_failures
@user_upload_failures ||= []
def form_json
@form_json ||= JSON.parse(submission.form_json)[form_id]
end

# ##
# User Upload Processing:
def write_user_uploads
log_info(" Moving #{user_uploads.count} user uploads:")
user_uploads.each do |upload|
write_user_upload upload
rescue => e
if quiet_upload_failures
user_upload_failures << {
filename: upload['name'],
confirmationCode: upload['attachmentId'],
attachmentId: upload['attachmentId'],
error: e.try(:message) || e || 'unknown error'
}
else
raise e
end
end
write_failure_report if user_upload_failures.present?
def form_text_dump
form = submission.form
form[form_id]['claimDate'] ||= submission.created_at.iso8601
form
end

def write_user_upload(upload_data)
log_info(" - processing upload: #{upload_data['name']} - #{upload_data['confirmationCode']}")
local = SupportingEvidenceAttachment.find_by(guid: upload_data['confirmationCode'])
raise 'No local record found' if local.blank?
def metadata
return {} unless submission.auth_headers.present? && submission.form[form_id].present?

read_bucket = local.get_file.uploader.aws_bucket
aws_path = local.get_file.path
old_obj = s3_resource.bucket(read_bucket).object(aws_path)
new_obj = s3_resource.bucket(target_bucket).object("#{user_upload_path}/#{upload_data['name']}")
new_obj.copy_from(old_obj)
extract_metadata_from_submission
end

# ##
# Metadata Processing:
# create metadata json with
# - vet PII
# - formsIncluded value indicates to the reviewing admin that nothing is missing
# - GUIDs of failed document uploads
def generate_metadata
return {} unless submission.auth_headers.present? && submission.form['form'].present?

zc = submission.form.dig('form', 'veteran', 'currentMailingAddress')
zipcode = zc.nil? ? '00000' : [zc['zipFirstFive'], zc['zipLastFour']].join('-')
def extract_metadata_from_submission
address = submission.form.dig(form_id, 'veteran', 'currentMailingAddress')
zip = [address['zipFirstFive'], address['zipLastFour']].join('-') if address.present?
pii = JSON.parse(submission.auth_headers['va_eauth_authorization'])['authorizationResponse']
pii.merge({
fileNumber: pii['va_eauth_pnid'],
birlsfilenumber: pii['va_eauth_birlsfilenumber'],
zipCode: zipcode,
claimDate: submission.created_at.iso8601,
formsIncluded: map_form_inclusion
})
fileNumber: pii['va_eauth_pnid'],

Check failure on line 167 in modules/simple_forms_api/app/services/simple_forms_api/s3/dump_submission_to_pdf.rb

View workflow job for this annotation

GitHub Actions / Linting and Security

Layout/FirstHashElementIndentation: Use 2 spaces for indentation in a hash, relative to the first position after the preceding left parenthesis.
zipCode: zip || '00000',
claimDate: submission.created_at.iso8601,
formsIncluded: map_form_inclusion
})

Check failure on line 171 in modules/simple_forms_api/app/services/simple_forms_api/s3/dump_submission_to_pdf.rb

View workflow job for this annotation

GitHub Actions / Linting and Security

Layout/FirstHashElementIndentation: Indent the right brace the same as the first position after the preceding left parenthesis.
end

def map_form_inclusion
%w[form1 form2].select { |type| submission.form[type].present? }
end

def log_info(message, **details)
Rails.logger.info(message, details)
def log_info(message)
Rails.logger.info(message)
end

def log_error(message, error, **details)
Rails.logger.error(message, details.merge(error: error.message, backtrace: error.backtrace.first(5)))
def log_error(message, error)
Rails.logger.error("#{message}: #{error.message}")
end

def output_directory_path
@output_directory_path ||= "#{parent_dir}/#{submission.id}"
end

def user_uploads
@user_uploads ||= submission.form['form_uploads']
end

def user_upload_failures
@user_upload_failures ||= []
end

def user_upload_path
@user_upload_path ||= "#{output_directory_path}/user_uploads"
end
end

Check failure on line 202 in modules/simple_forms_api/app/services/simple_forms_api/s3/dump_submission_to_pdf.rb

View workflow job for this annotation

GitHub Actions / Linting and Security

Layout/TrailingEmptyLines: 1 trailing blank lines detected.

0 comments on commit 40c1642

Please sign in to comment.