Skip to content

Commit

Permalink
Merge branch 'master' into balexandr-patch-2
Browse files Browse the repository at this point in the history
  • Loading branch information
wayne-weibel authored Nov 14, 2024
2 parents 087863f + 95afe01 commit 3d3ba73
Show file tree
Hide file tree
Showing 94 changed files with 1,507 additions and 306 deletions.
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ gem 'connect_vbms', git: 'https://github.com/adhocteam/connect_vbms', tag: 'v2.1
gem 'csv'
gem 'date_validator'
gem 'ddtrace'
gem 'dogstatsd-ruby', '5.6.2'
gem 'dogstatsd-ruby', '5.6.3'
gem 'dry-struct'
gem 'dry-types'
gem 'ethon', '>=0.13.0'
Expand Down
10 changes: 5 additions & 5 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ GEM
thread_safe (~> 0.3, >= 0.3.1)
diff-lcs (1.5.1)
docile (1.4.0)
dogstatsd-ruby (5.6.2)
dogstatsd-ruby (5.6.3)
domain_name (0.6.20240107)
down (5.4.2)
addressable (~> 2.8)
Expand Down Expand Up @@ -898,9 +898,9 @@ GEM
rspec-instrumentation-matcher (0.0.9)
activesupport
rspec-expectations
rspec-its (1.3.1)
rspec-core (>= 3.0.0)
rspec-expectations (>= 3.0.0)
rspec-its (2.0.0)
rspec-core (>= 3.13.0)
rspec-expectations (>= 3.13.0)
rspec-mocks (3.13.2)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
Expand Down Expand Up @@ -1162,7 +1162,7 @@ DEPENDENCIES
ddtrace
debts_api!
dhp_connected_devices!
dogstatsd-ruby (= 5.6.2)
dogstatsd-ruby (= 5.6.3)
dry-struct
dry-types
ethon (>= 0.13.0)
Expand Down
22 changes: 19 additions & 3 deletions app/controllers/v0/disability_compensation_forms_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,7 @@ def lighthouse?
end

def create_submission(saved_claim)
Rails.logger.info(
'Creating 526 submission', user_uuid: @current_user&.uuid, saved_claim_id: saved_claim&.id
)
Rails.logger.info('Creating 526 submission', user_uuid: @current_user&.uuid, saved_claim_id: saved_claim&.id)
submission = Form526Submission.new(
user_uuid: @current_user.uuid,
user_account: @current_user.user_account,
Expand All @@ -122,6 +120,13 @@ def create_submission(saved_claim)
form_json: saved_claim.to_submission_data(@current_user),
submit_endpoint: includes_toxic_exposure? ? 'claims_api' : 'evss'
) { |sub| sub.add_birls_ids @current_user.birls_id }

if missing_disabilities?(submission)
raise Common::Exceptions::UnprocessableEntity.new(
detail: 'no new or increased disabilities were submitted', source: 'DisabilityCompensationFormsController'
)
end

submission.save! && submission
rescue PG::NotNullViolation => e
Rails.logger.error(
Expand Down Expand Up @@ -156,5 +161,16 @@ def includes_toxic_exposure?
# any form that has a startedFormVersion (whether it is '2019' or '2022') will go through the Toxic Exposure flow
form_content['form526']['startedFormVersion']
end

def missing_disabilities?(submission)
if submission.form['form526']['form526']['disabilities'].none?
StatsD.increment("#{stats_key}.failure")
Rails.logger.error(
'Creating 526 submission: no new or increased disabilities were submitted', user_uuid: @current_user&.uuid
)
return true
end
false
end
end
end
22 changes: 22 additions & 0 deletions app/models/appeal_submission.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,28 @@ class AppealSubmission < ApplicationRecord

has_many :appeal_submission_uploads, dependent: :destroy
has_many :secondary_appeal_forms, dependent: :destroy
has_many :incomplete_secondary_appeal_forms, lambda {
where(delete_date: nil)
}, class_name: 'SecondaryAppealForm', dependent: nil, inverse_of: :appeal_submission

# Work around for a polymorphic association, each AppealSubmission will only have one of the following: sc, hlr, nod
has_one :saved_claim_sc, class_name: 'SavedClaim::SupplementalClaim', foreign_key: :guid,
primary_key: :submitted_appeal_uuid,
dependent: :restrict_with_exception,
inverse_of: :appeal_submission,
required: false

has_one :saved_claim_hlr, class_name: 'SavedClaim::HigherLevelReview', foreign_key: :guid,
primary_key: :submitted_appeal_uuid,
dependent: :restrict_with_exception,
inverse_of: :appeal_submission,
required: false

has_one :saved_claim_nod, class_name: 'SavedClaim::NoticeOfDisagreement', foreign_key: :guid,
primary_key: :submitted_appeal_uuid,
dependent: :restrict_with_exception,
inverse_of: :appeal_submission,
required: false

scope :failure_not_sent, -> { where(failure_notification_sent_at: nil).order(id: :asc) }

Expand Down
28 changes: 28 additions & 0 deletions app/models/saved_claim/dependency_claim.rb
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,34 @@ def to_pdf(form_id: FORM)
PdfFill::Filler.fill_form(self, nil, { created_at: })
end

# this failure email is not the ideal way to handle the Notification Emails as
# part of the ZSF work, but with the initial timeline it handles the email as intended.
# Future work will be integrating into the Va Notify common lib:
# https://github.com/department-of-veterans-affairs/vets-api/blob/master/lib/va_notify/notification_email.rb

def send_failure_email(encrypted_user_struct = nil)
user_struct = encrypted_user_struct.present? ? JSON.parse(KmsEncrypted::Box.new.decrypt(encrypted_user_struct)) : nil # rubocop:disable Layout/LineLength
email = parsed_form.dig('dependents_application', 'veteran_contact_information', 'email_address') ||
user_struct.try(:va_profile_email)
template_ids = []
template_ids << Settings.vanotify.services.va_gov.template_id.form21_686c_action_needed_email if submittable_686?
template_ids << Settings.vanotify.services.va_gov.template_id.form21_674_action_needed_email if submittable_674?

template_ids.each do |template_id|
if email.present?
VANotify::EmailJob.perform_async(
email,
template_id,
{
'first_name' => parsed_form.dig('veteran_information', 'full_name', 'first')&.upcase.presence,
'date_submitted' => Time.zone.today.strftime('%B %d, %Y'),
'confirmation_number' => confirmation_number
}
)
end
end
end

private

def partitioned_686_674_params
Expand Down
19 changes: 19 additions & 0 deletions app/models/saved_claim/education_career_counseling_claim.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,23 @@ def process_attachments!
def business_line
'EDU'
end

# this failure email is not the ideal way to handle the Notification Emails as
# part of the ZSF work, but with the initial timeline it handles the email as intended.
# Future work will be integrating into the Va Notify common lib:
# https://github.com/department-of-veterans-affairs/vets-api/blob/master/lib/va_notify/notification_email.rb
def send_failure_email
email = parsed_form.dig('claimantInformation', 'emailAddress')
if email.present?
VANotify::EmailJob.perform_async(
email,
Settings.vanotify.services.va_gov.template_id.form27_8832_action_needed_email,
{
'first_name' => parsed_form.dig('claimantInformation', 'fullName', 'first')&.upcase.presence,
'date_submitted' => Time.zone.today.strftime('%B %d, %Y'),
'confirmation_number' => confirmation_number
}
)
end
end
end
2 changes: 2 additions & 0 deletions app/models/saved_claim/higher_level_review.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# frozen_string_literal: true

class SavedClaim::HigherLevelReview < SavedClaim
has_one :appeal_submission, class_name: 'AppealSubmission', foreign_key: :submitted_appeal_uuid, primary_key: :guid,
dependent: nil, inverse_of: :saved_claim_hlr, required: false
FORM = '20-0996'

def form_matches_schema
Expand Down
2 changes: 2 additions & 0 deletions app/models/saved_claim/notice_of_disagreement.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# frozen_string_literal: true

class SavedClaim::NoticeOfDisagreement < SavedClaim
has_one :appeal_submission, class_name: 'AppealSubmission', foreign_key: :submitted_appeal_uuid, primary_key: :guid,
dependent: nil, inverse_of: :saved_claim_nod, required: false
FORM = '10182'

def form_matches_schema
Expand Down
3 changes: 3 additions & 0 deletions app/models/saved_claim/supplemental_claim.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# frozen_string_literal: true

class SavedClaim::SupplementalClaim < SavedClaim
has_one :appeal_submission, class_name: 'AppealSubmission', foreign_key: :submitted_appeal_uuid, primary_key: :guid,
dependent: nil, inverse_of: :saved_claim_sc, required: false

FORM = '20-0995'

def form_matches_schema
Expand Down
20 changes: 20 additions & 0 deletions app/models/saved_claim/veteran_readiness_employment_claim.rb
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,26 @@ def business_line
'VRE'
end

# this failure email is not the ideal way to handle the Notification Emails as
# part of the ZSF work, but with the initial timeline it handles the email as intended.
# Future work will be integrating into the Va Notify common lib:
# https://github.com/department-of-veterans-affairs/vets-api/blob/master/lib/va_notify/notification_email.rb
def send_failure_email(encrypted_user = nil)
user = encrypted_user.present? ? OpenStruct.new(JSON.parse(KmsEncrypted::Box.new.decrypt(encrypted_user))) : nil
email = parsed_form['email'] || user.try(:va_profile_email)
if email.present?
VANotify::EmailJob.perform_async(
email,
Settings.vanotify.services.va_gov.template_id.form1900_action_needed_email,
{
'first_name' => parsed_form.dig('veteranInformation', 'fullName', 'first'),
'date_submitted' => Time.zone.today.strftime('%B %d, %Y'),
'confirmation_number' => confirmation_number
}
)
end
end

private

def check_office_location
Expand Down
2 changes: 2 additions & 0 deletions app/models/secondary_appeal_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ class SecondaryAppealForm < ApplicationRecord
scope :needs_failure_notification, lambda {
where(delete_date: nil, failure_notification_sent_at: nil).where('status LIKE ?', '%error%')
}

scope :incomplete, -> { where(delete_date: nil) }
end
25 changes: 22 additions & 3 deletions app/services/medical_copays/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,32 @@ def initialize
# @return [Faraday::Response]
#
def post(path, params)
with_monitoring do
connection.post(path) do |req|
req.body = Oj.dump(params)
if Flipper.enabled?(:debts_copay_logging) && !Rails.env.development?
with_monitoring_and_error_handling do
connection.post(path) do |req|
req.body = Oj.dump(params)
end
end
else
with_monitoring do
connection.post(path) do |req|
req.body = Oj.dump(params)
end
end
end
end

def with_monitoring_and_error_handling(&)
with_monitoring(2, &)
rescue => e
handle_error(e)
end

def handle_error(error)
Rails.logger.error("MedicalCopays::Request error: #{error.message}")
raise error
end

##
# Make a HTTP GET call to the VBS service in order to obtain copays or PDFs by id
#
Expand Down
4 changes: 4 additions & 0 deletions app/services/medical_copays/vbs/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ def get_pdf_statement_by_id(statement_id)
end

def get_copay_response
if Flipper.enabled?(:debts_copay_logging)
Rails.logger.info("MedicalCopays::VBS::Service#get_copay_response request data: #{@user.uuid}")
end

request.post("#{settings.base_path}/GetStatementsByEDIPIAndVistaAccountNumber", request_data.to_hash)
end

Expand Down
37 changes: 36 additions & 1 deletion app/sidekiq/benefits_intake_status_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
require 'pensions/monitor'
require 'pensions/notification_email'
require 'va_notify/notification_email/burial'
require 'pcpg/monitor'
require 'dependents/monitor'
require 'vre/monitor'

# Datadog Dashboard:
# https://vagov.ddog-gov.com/dashboard/4d8-3fn-dbp/benefits-intake-form-submission-tracking?fromUser=false&refresh_mode=sliding&view=spans&from_ts=1717772535566&to_ts=1718377335566&live=true
Expand Down Expand Up @@ -133,7 +136,6 @@ def log_result(result, form_id, uuid, time_to_transition = nil, error_message =
StatsD.increment("#{STATS_KEY}.all_forms.#{result}")
if result == 'failure'
Rails.logger.error('BenefitsIntakeStatusJob', result:, form_id:, uuid:, time_to_transition:, error_message:)
monitor_failure(form_id, uuid)
else
Rails.logger.info('BenefitsIntakeStatusJob', result:, form_id:, uuid:, time_to_transition:)
end
Expand Down Expand Up @@ -168,6 +170,39 @@ def monitor_failure(form_id, saved_claim_id, bi_uuid)
Pensions::Monitor.new.log_silent_failure(context, nil, call_location:)
end
end

# Dependents
if %w[686C-674].include?(form_id)
claim = SavedClaim::DependencyClaim.find(saved_claim_id)
if claim
claim.send_failure_email
Dependents::Monitor.new.log_silent_failure_avoided(context, nil, call_location:)
else
Dependents::Monitor.new.log_silent_failure(context, nil, call_location:)
end
end

# PCPG
if %w[28-8832].include?(form_id)
claim = SavedClaim::EducationCareerCounselingClaim.find(saved_claim_id)
if claim
claim.send_failure_email
PCPG::Monitor.new.log_silent_failure_avoided(context, nil, call_location:)
else
PCPG::Monitor.new.log_silent_failure(ocntext, nil, call_location:)
end
end

# VRE
if %w[28-1900].include?(form_id)
claim = SavedClaim::VeteranReadinessEmploymentClaim.find(saved_claim_id)
if claim
claim.submit_failure_email
VRE::Monitor.new.log_silent_failure_avoided(context, nil, call_location:)
else
VRE::Monitor.new.log_silent_failure(context, nil, call_location:)
end
end
end
# rubocop:enable Metrics/MethodLength
end
23 changes: 2 additions & 21 deletions app/sidekiq/central_mail/submit_central_form686c_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -233,27 +233,8 @@ def send_confirmation_email(user)
end

def self.trigger_failure_events(saved_claim_id, encrypted_user_struct)
claim = SavedClaim.find(saved_claim_id)
user_struct = JSON.parse(KmsEncrypted::Box.new.decrypt(encrypted_user_struct))
email = claim.parsed_form.dig('dependents_application', 'veteran_contact_information', 'email_address') ||
user_struct.va_profile_email
template_ids = []
template_ids << Settings.vanotify.services.va_gov.template_id.form21_686c_action_needed_email if claim.submittable_686? # rubocop:disable Layout/LineLength
template_ids << Settings.vanotify.services.va_gov.template_id.form21_674_action_needed_email if claim.submittable_674? # rubocop:disable Layout/LineLength

template_ids.each do |template_id|
if claim.present? && email.present?
VANotify::EmailJob.perform_async(
email,
template_id,
{
'first_name' => claim.parsed_form.dig('veteran_information', 'full_name', 'first')&.upcase.presence,
'date_submitted' => Time.zone.today.strftime('%B %d, %Y'),
'confirmation_number' => claim.confirmation_number
}
)
end
end
claim = SavedClaim::DependencyClaim.find(saved_claim_id)
claim.send_failure_email(encrypted_user_struct)
end

private
Expand Down
5 changes: 5 additions & 0 deletions app/sidekiq/central_mail/submit_form4142_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ class CentralMailResponseError < Common::Exceptions::BackendServiceException; e
if Flipper.enabled?(:form526_send_4142_failure_notification)
EVSS::DisabilityCompensationForm::Form4142DocumentUploadFailureEmail.perform_async(form526_submission_id)
end
# NOTE: do NOT add any additional code here between the failure email being enqueued and the rescue block.
# The mailer prevents an upload from failing silently, since we notify the veteran and provide a workaround.
# The rescue will catch any errors in the sidekiq_retries_exhausted block and mark a "silent failure".
# This shouldn't happen if an email was sent; there should be no code here to throw an additional exception.
# The mailer should be the last thing that can fail.
rescue => e
cl = caller_locations.first
call_location = Logging::CallLocation.new(ZSF_DD_TAG_FUNCTION, cl.path, cl.lineno)
Expand Down
Loading

0 comments on commit 3d3ba73

Please sign in to comment.