Class: EducationForm::Process10203Submissions

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

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 Method Details

#check_previous_submissions(submissions, user_has_poa) ⇒ Object (private)

Makes a list of all submissions that have not been processed and have a status of INIT Finds most recent submission that has already been processed

Submissions are marked as processed in EducationForm::CreateDailySpoolFiles

For each unprocessed submission compare isEnrolledStem, isPursuingTeachingCert, and benefitLeft values

to most recent processed submissions

If values are the same set status as PROCESSED Otherwise check submission data and EVSS data to see if submission can be marked as PROCESSED



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'app/sidekiq/education_form/process10203_submissions.rb', line 117

def check_previous_submissions(submissions, user_has_poa)
  unprocessed_submissions = submissions.find_all do |ebc|
    ebc.processed_at.nil? &&
      ebc.education_stem_automated_decision&.automated_decision_state == EducationStemAutomatedDecision::INIT
  end
  most_recent_processed = submissions.find_all do |ebc|
    ebc.processed_at.present? &&
      ebc.education_stem_automated_decision&.automated_decision_state != EducationStemAutomatedDecision::INIT
  end
                                     .max_by(&:processed_at)

  processed_form = format_application(most_recent_processed) if most_recent_processed.present?

  unprocessed_submissions.each do |submission|
    unprocessed_form = format_application(submission)
    if repeat_form?(unprocessed_form, processed_form)
      update_automated_decision(submission, EducationStemAutomatedDecision::PROCESSED, user_has_poa)
    else
      process_submission(submission, user_has_poa)
    end
  end
end

#evss_is_healthy?Boolean (private)

Returns:

  • (Boolean)


45
46
47
# File 'app/sidekiq/education_form/process10203_submissions.rb', line 45

def evss_is_healthy?
  Settings.evss.mock_claims || EVSS::VSOSearch::Service.service_is_up?
end

#format_application(data) ⇒ Object (private)



164
165
166
167
168
169
# File 'app/sidekiq/education_form/process10203_submissions.rb', line 164

def format_application(data)
  EducationForm::Forms::VA10203.build(data)
rescue => e
  inform_on_error(data, e)
  nil
end

#get_user_poa_status(auth_headers) ⇒ Object (private)

Retrieve poa status fromEVSS VSOSearch for a user



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'app/sidekiq/education_form/process10203_submissions.rb', line 76

def get_user_poa_status(auth_headers)
  # stem_automated_decision feature disables EVSS call  for POA which will be removed in a future PR
  return nil if Flipper.enabled?(:stem_automated_decision)

  if auth_headers.nil? ||
     !auth_headers.key?('va_eauth_dodedipnid') ||
     auth_headers['va_eauth_dodedipnid'] == ''

    return nil
  end

  vsosearch_service = EVSS::VSOSearch::Service.new(nil, auth_headers)
  vsosearch_service.get_current_info(auth_headers)['userPoaInfoAvailable']
rescue => e
  log_exception_to_sentry(
    Process10203EVSSError.new("Failed to retrieve VSOSearch data: #{e.message}")
  )
  nil
end

#group_user_uuid(records) ⇒ Object (private)

Group the submissions by user_uuid



50
51
52
# File 'app/sidekiq/education_form/process10203_submissions.rb', line 50

def group_user_uuid(records)
  records.group_by { |ebc| ebc.education_stem_automated_decision&.user_uuid }
end

#inform_on_error(claim, error = nil) ⇒ Object (private)



184
185
186
187
188
189
190
191
192
193
# File 'app/sidekiq/education_form/process10203_submissions.rb', line 184

def inform_on_error(claim, error = nil)
  region = EducationFacility.facility_for(region: :eastern)
  StatsD.increment("worker.education_benefits_claim.failed_formatting.#{region}.22-#{claim.form_type}")
  exception = if error&.present?
                FormattingError.new("Could not format #{claim.confirmation_number}.\n\n#{error}")
              else
                FormattingError.new("Could not format #{claim.confirmation_number}")
              end
  log_exception_to_sentry(exception)
end

#log_info(message) ⇒ Object (private)



195
196
197
# File 'app/sidekiq/education_form/process10203_submissions.rb', line 195

def log_info(message)
  logger.info(message)
end

#more_than_six_months?(remaining_entitlement) ⇒ Boolean (private)

Inverse of less than six months check performed in SavedClaim::EducationBenefits::VA10203

Returns:

  • (Boolean)


178
179
180
181
182
# File 'app/sidekiq/education_form/process10203_submissions.rb', line 178

def more_than_six_months?(remaining_entitlement)
  return false if remaining_entitlement.blank?

  remaining_entitlement_days(remaining_entitlement) > 180
end

#perform(records: EducationBenefitsClaim.joins(:education_stem_automated_decision).includes(:saved_claim).where( saved_claims: { form_id: '22-10203' } ).order('education_benefits_claims.created_at')) ⇒ Object

Get all 10203 submissions that have a row in education_stem_automated_decisions



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'app/sidekiq/education_form/process10203_submissions.rb', line 19

def perform(
  records: EducationBenefitsClaim.joins(:education_stem_automated_decision).includes(:saved_claim).where(
    saved_claims: {
      form_id: '22-10203'
    }
  ).order('education_benefits_claims.created_at')
)
  return false unless evss_is_healthy?

  init_count = records.filter do |r|
    r.education_stem_automated_decision.automated_decision_state == EducationStemAutomatedDecision::INIT
  end.count

  if init_count.zero?
    log_info('No records with init status to process.')
    return true
  else
    log_info("Processing #{init_count} application(s) with init status")
  end

  user_submissions = group_user_uuid(records)
  process_user_submissions(user_submissions)
end

#process_submission(submission, user_has_poa) ⇒ Object (private)

If the user doesn’t have EVSS data mark the 10203 as PROCESSED Set status to DENIED when EVSS data for a user shows there is more than 6 months of remaining_entitlement

This is only checking EVSS data until form questions that affect setting to DENIED have been reviewed



151
152
153
154
155
156
157
158
159
160
161
162
# File 'app/sidekiq/education_form/process10203_submissions.rb', line 151

def process_submission(submission, user_has_poa)
  remaining_entitlement = submission.education_stem_automated_decision&.remaining_entitlement
  # This code will be updated once QA and additional evaluation is completed
  status = if Settings.vsp_environment == 'production' && more_than_six_months?(remaining_entitlement)
             EducationStemAutomatedDecision::PROCESSED
           elsif more_than_six_months?(remaining_entitlement)
             EducationStemAutomatedDecision::DENIED
           else
             EducationStemAutomatedDecision::PROCESSED
           end
  update_automated_decision(submission, status, user_has_poa)
end

#process_user_submissions(user_submissions) ⇒ Object (private)

If there are multiple submissions for a user compare un-submitted to most recent processed

by EducationForm::CreateDailySpoolFiles

Otherwise check submission data and EVSS data to see if submission can be marked as PROCESSED



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'app/sidekiq/education_form/process10203_submissions.rb', line 57

def process_user_submissions(user_submissions)
  user_submissions.each_value do |submissions|
    auth_headers = submissions.last.education_stem_automated_decision.auth_headers

    claim_ids = submissions.map(&:id).join(', ')
    log_info "EDIPI available for process STEM claim ids=#{claim_ids}: #{auth_headers&.key?('va_eauth_dodedipnid')}"

    # only check EVSS if poa wasn't set on submit
    poa = submissions.last.education_stem_automated_decision.poa || get_user_poa_status(auth_headers)

    if submissions.count > 1
      check_previous_submissions(submissions, poa)
    else
      process_submission(submissions.first, poa)
    end
  end
end

#remaining_entitlement_days(remaining_entitlement) ⇒ Object (private)



171
172
173
174
175
# File 'app/sidekiq/education_form/process10203_submissions.rb', line 171

def remaining_entitlement_days(remaining_entitlement)
  months = remaining_entitlement.months
  days = remaining_entitlement.days
  months * 30 + days
end

#repeat_form?(unprocessed_form, processed_form) ⇒ Boolean (private)

Returns:

  • (Boolean)


140
141
142
143
144
145
# File 'app/sidekiq/education_form/process10203_submissions.rb', line 140

def repeat_form?(unprocessed_form, processed_form)
  processed_form.present? &&
    unprocessed_form.enrolled_stem == processed_form.enrolled_stem &&
    unprocessed_form.pursuing_teaching_cert == processed_form.pursuing_teaching_cert &&
    unprocessed_form.benefit_left == processed_form.benefit_left
end

#update_automated_decision(submission, status, poa) ⇒ Object (private)

Ignore already processed either by CreateDailySpoolFiles or this job



97
98
99
100
101
102
103
104
105
106
# File 'app/sidekiq/education_form/process10203_submissions.rb', line 97

def update_automated_decision(submission, status, poa)
  if submission.processed_at.nil? &&
     submission.education_stem_automated_decision&.automated_decision_state == EducationStemAutomatedDecision::INIT

    submission.education_stem_automated_decision.update(
      automated_decision_state: status,
      poa:
    )
  end
end