Class: BenefitsClaims::Service

Inherits:
Common::Client::Base show all
Defined in:
lib/lighthouse/benefits_claims/service.rb

Constant Summary collapse

STATSD_KEY_PREFIX =
'api.benefits_claims'
FILTERED_STATUSES =
%w[CANCELED ERRORED PENDING].freeze

Instance Method Summary collapse

Methods inherited from Common::Client::Base

#config, configuration, #connection, #delete, #get, #perform, #post, #put, #raise_backend_exception, #raise_not_authenticated, #request, #sanitize_headers!, #service_name

Methods included from SentryLogging

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

Constructor Details

#initialize(icn) ⇒ Service

Returns a new instance of Service.



15
16
17
18
19
20
21
22
# File 'lib/lighthouse/benefits_claims/service.rb', line 15

def initialize(icn)
  @icn = icn
  if icn.blank?
    raise ArgumentError, 'no ICN passed in for LH API request.'
  else
    super()
  end
end

Instance Method Details

#build_request_body(body, transaction_id = "vagov-#{SecureRandom}") ⇒ Object (private)



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/lighthouse/benefits_claims/service.rb', line 175

def build_request_body(body, transaction_id = "vagov-#{SecureRandom}")
  body = body.as_json
  if body.dig('data', 'attributes').nil?
    body = {
      data: {
        type: 'form/526',
        attributes: body
      },
      meta: {
        transaction_id:
      }
    }
  end
  body.as_json.deep_transform_keys { |k| k.camelize(:lower) }
end

#create_intent_to_file(type, claimant_ssn, lighthouse_client_id = nil, lighthouse_rsa_key_path = nil, options = {}) ⇒ Object

For type “survivor”, the request must include claimantSsn and be made by a valid Veteran Representative. If the Representative is not a Veteran or a VA employee, this method is currently not available to them, and they should use the Benefits Intake API as an alternative.



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/lighthouse/benefits_claims/service.rb', line 87

def create_intent_to_file(type, claimant_ssn, lighthouse_client_id = nil, lighthouse_rsa_key_path = nil,
                          options = {})
  if claimant_ssn.blank? && type == 'survivor'
    raise ArgumentError, 'BenefitsClaims::Service: No SSN provided for survivor type create request.'
  end

  endpoint = 'benefits_claims/intent_to_file'
  path = "#{@icn}/intent-to-file"
  config.post(
    path,
    {
      data: {
        type: 'intent_to_file',
        attributes: {
          type:,
          claimantSsn: claimant_ssn
        }
      }
    },
    lighthouse_client_id, lighthouse_rsa_key_path, options
  ).body
rescue Faraday::ClientError, Faraday::ServerError => e
  handle_error(e, lighthouse_client_id, endpoint)
end

#filter_by_status(items) ⇒ Object (private)



261
262
263
# File 'lib/lighthouse/benefits_claims/service.rb', line 261

def filter_by_status(items)
  items.reject { |item| FILTERED_STATUSES.include?(item.dig('attributes', 'status')) }
end

#fix_current_va_employee(body) ⇒ Object (private)



212
213
214
215
216
217
218
219
220
# File 'lib/lighthouse/benefits_claims/service.rb', line 212

def fix_current_va_employee(body)
  if body.dig('data', 'attributes', 'veteranIdentification')&.select do |field|
       field['currentVAEmployee']
     end&.key?('currentVAEmployee')
    body['data']['attributes']['veteranIdentification']['currentVaEmployee'] =
      body['data']['attributes']['veteranIdentification']['currentVAEmployee']
    body['data']['attributes']['veteranIdentification'].delete('currentVAEmployee')
  end
end

#get_claim(id, lighthouse_client_id = nil, lighthouse_rsa_key_path = nil, options = {}) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/lighthouse/benefits_claims/service.rb', line 38

def get_claim(id, lighthouse_client_id = nil, lighthouse_rsa_key_path = nil, options = {})
  claim = config.get("#{@icn}/claims/#{id}", lighthouse_client_id, lighthouse_rsa_key_path, options).body
  # Manual status override for PMR Pending items
  # See https://github.com/department-of-veterans-affairs/va-mobile-app/issues/9671
  # This should be removed when the items are re-categorized by BGS
  override_pmr_pending(claim['data'])
  claim
rescue Faraday::TimeoutError
  raise BenefitsClaims::ServiceException.new({ status: 504 }), 'Lighthouse Error'
rescue Faraday::ClientError, Faraday::ServerError => e
  raise BenefitsClaims::ServiceException.new(e.response), 'Lighthouse Error'
end

#get_claims(lighthouse_client_id = nil, lighthouse_rsa_key_path = nil, options = {}) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/lighthouse/benefits_claims/service.rb', line 24

def get_claims(lighthouse_client_id = nil, lighthouse_rsa_key_path = nil, options = {})
  claims = config.get("#{@icn}/claims", lighthouse_client_id, lighthouse_rsa_key_path, options).body
  claims['data'] = filter_by_status(claims['data'])
  # Manual status override for PMR Pending items
  # See https://github.com/department-of-veterans-affairs/va-mobile-app/issues/9671
  # This should be removed when the items are re-categorized by BGS
  claims['data'].each { |claim| override_pmr_pending(claim) }
  claims
rescue Faraday::TimeoutError
  raise BenefitsClaims::ServiceException.new({ status: 504 }), 'Lighthouse Error'
rescue Faraday::ClientError, Faraday::ServerError => e
  raise BenefitsClaims::ServiceException.new(e.response), 'Lighthouse Error'
end

#get_intent_to_file(type, lighthouse_client_id = nil, lighthouse_rsa_key_path = nil, options = {}) ⇒ Object



76
77
78
79
80
81
82
# File 'lib/lighthouse/benefits_claims/service.rb', line 76

def get_intent_to_file(type, lighthouse_client_id = nil, lighthouse_rsa_key_path = nil, options = {})
  endpoint = 'benefits_claims/intent_to_file'
  path = "#{@icn}/intent-to-file/#{type}"
  config.get(path, lighthouse_client_id, lighthouse_rsa_key_path, options).body
rescue Faraday::ClientError, Faraday::ServerError => e
  handle_error(e, lighthouse_client_id, endpoint)
end

#get_power_of_attorney(lighthouse_client_id = nil, lighthouse_rsa_key_path = nil, options = {}) ⇒ Object



51
52
53
54
55
56
57
# File 'lib/lighthouse/benefits_claims/service.rb', line 51

def get_power_of_attorney(lighthouse_client_id = nil, lighthouse_rsa_key_path = nil, options = {})
  config.get("#{@icn}/power-of-attorney", lighthouse_client_id, lighthouse_rsa_key_path, options).body
rescue Faraday::TimeoutError
  raise BenefitsClaims::ServiceException.new({ status: 504 }), 'Lighthouse Error'
rescue Faraday::ClientError, Faraday::ServerError => e
  raise BenefitsClaims::ServiceException.new(e.response), 'Lighthouse Error'
end

#handle_error(error, lighthouse_client_id, endpoint) ⇒ Object (private)



276
277
278
279
280
281
282
283
# File 'lib/lighthouse/benefits_claims/service.rb', line 276

def handle_error(error, lighthouse_client_id, endpoint)
  Lighthouse::ServiceException.send_error(
    error,
    self.class.to_s.underscore,
    lighthouse_client_id,
    "#{config.base_api_path}/#{endpoint}"
  )
end

#override_pmr_pending(claim) ⇒ Object (private)



265
266
267
268
269
270
271
272
273
274
# File 'lib/lighthouse/benefits_claims/service.rb', line 265

def override_pmr_pending(claim)
  tracked_items = claim['attributes']['trackedItems']
  return unless tracked_items

  tracked_items.select { |i| i['displayName'] == 'PMR Pending' }.each do |i|
    i['status'] = 'NEEDED_FROM_OTHERS'
    i['displayName'] = 'Private Medical Record'
  end
  tracked_items
end

#prepare_submission_body(body, transaction_id) ⇒ Object (private)



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/lighthouse/benefits_claims/service.rb', line 191

def prepare_submission_body(body, transaction_id)
  # if we're coming straight from the transformation service without
  # making this a jsonapi request body first ({data: {type:, attributes}, meta: {transactionId:}}),
  # this will put it in the correct format for transmission
  body = build_request_body(body, transaction_id)

  # Inflection settings force 'current_va_employee' to render as 'currentVAEmployee' in the above camelize() call
  # Since Lighthouse needs 'currentVaEmployee', the following workaround renames it.
  fix_current_va_employee(body)

  # LH PDF generator service crashes with having an empty array for confinements
  # removes confinements from the request body if confinements attribute empty or nil
  remove_empty_array(body, 'serviceInformation', 'confinements')

  # Lighthouse expects at least 1 element in the multipleExposures array if it is not null
  # this removes the multipleExposures array if it is empty
  remove_empty_array(body, 'toxicExposure', 'multipleExposures')

  body
end

#remove_empty_array(body, parent_key, child_key) ⇒ Object (private)



222
223
224
225
226
227
228
# File 'lib/lighthouse/benefits_claims/service.rb', line 222

def remove_empty_array(body, parent_key, child_key)
  if body.dig('data', 'attributes', parent_key)&.select do |field|
    field[child_key]
  end&.key?(child_key) && body['data']['attributes'][parent_key][child_key].blank?
    body['data']['attributes'][parent_key].delete(child_key)
  end
end

#submit5103(id, tracked_item_id = nil, options = {}) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/lighthouse/benefits_claims/service.rb', line 59

def submit5103(id, tracked_item_id = nil, options = {})
  config.post("#{@icn}/claims/#{id}/5103", {
                data: {
                  type: 'form/5103',
                  attributes: {
                    trackedItemIds: [
                      tracked_item_id
                    ]
                  }
                }
              }, nil, nil, options).body
rescue Faraday::TimeoutError
  raise BenefitsClaims::ServiceException.new({ status: 504 }), 'Lighthouse Error'
rescue Faraday::ClientError, Faraday::ServerError => e
  raise BenefitsClaims::ServiceException.new(e.response), 'Lighthouse Error'
end

#submit526(body, lighthouse_client_id = nil, lighthouse_rsa_key_path = nil, options = {}) ⇒ Object

submit form526 to Lighthouse API endpoint: /services/claims/v2/veterans/veteranId/526/synchronous, /services/claims/v2/veterans/veteranId/526/generatePdf, or /services/claims/v2/veterans/veteranId/526 (asynchronous) attributes in the Lighthouse request schema

Parameters:

  • body: (hash || Requests::Form526)

    a hash representing the form526

  • lighthouse_client_id: (string)

    the lighthouse_client_id requested from Lighthouse

  • lighthouse_rsa_key_path: (string)

    absolute path to the rsa key file

  • options: (hash)

    options to override aud_claim_url, params, and auth_params

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • :body_only (hash)

    only return the body from the request

  • :aud_claim_url (string)

    option to override the aud_claim_url for LH Veteran Verification APIs

  • :auth_params (hash)

    a hash to send in auth params to create the access token

  • :generate_pdf (hash)

    call the generatePdf endpoint to receive the 526 pdf

  • :asynchronous (hash)

    call the asynchronous endpoint

  • :transaction_id (hash)

    submission endpoint tracking



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/lighthouse/benefits_claims/service.rb', line 127

def submit526(body, lighthouse_client_id = nil, lighthouse_rsa_key_path = nil, options = {})
  endpoint, path = submit_endpoint(options)

  body = prepare_submission_body(body, options[:transaction_id])

  response = config.post(
    path,
    body,
    lighthouse_client_id, lighthouse_rsa_key_path, options
  )

  submit_response(response, options[:body_only])
rescue Faraday::ClientError, Faraday::ServerError => e
  handle_error(e, lighthouse_client_id, endpoint)
end

#submit_endpoint(options) ⇒ Object (private)

chooses the path and endpoint for submission “synchronous” is the default



242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/lighthouse/benefits_claims/service.rb', line 242

def submit_endpoint(options)
  # nothing past the "526" in the path means asynchronous endpoint
  endpoint = '{icn}/526'
  path = "#{@icn}/526"

  if options[:generate_pdf].present?
    path = "#{@icn}/526/generatePDF/minimum-validations"
    endpoint = '{icn}/526/generatePDF/minimum-validations'
  end

  # "synchronous" should be the default
  if options[:asynchronous].blank? && options[:generate_pdf].blank?
    path = "#{@icn}/526/synchronous"
    endpoint = '{icn}/526/synchronous'
  end

  [endpoint, path]
end

#submit_response(response, body_only) ⇒ Object (private)



230
231
232
233
234
235
236
237
238
# File 'lib/lighthouse/benefits_claims/service.rb', line 230

def submit_response(response, body_only)
  if body_only
    # return only the response body
    response.body
  else
    # return the whole response
    response
  end
end

#validate526(body, lighthouse_client_id = nil, lighthouse_rsa_key_path = nil, options = {}) ⇒ Object

submit form526 to Lighthouse API endpoint: /services/claims/v2/veterans/veteranId/526/validate attributes in the Lighthouse request schema NOTE: This method is similar to submit526. The only difference is the path and endpoint values

Parameters:

  • body: (hash || Requests::Form526)

    a hash representing the form526

  • lighthouse_client_id: (string)

    the lighthouse_client_id requested from Lighthouse

  • lighthouse_rsa_key_path: (string)

    absolute path to the rsa key file

  • options: (hash)

    options to override aud_claim_url, params, and auth_params

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • :body_only (hash)

    only return the body from the request



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/lighthouse/benefits_claims/service.rb', line 154

def validate526(body, lighthouse_client_id = nil, lighthouse_rsa_key_path = nil, options = {})
  endpoint = '{icn}/526/validate'
  path = "#{@icn}/526/validate"
  body = prepare_submission_body(body, options[:transaction_id])

  response = config.post(
    path,
    body,
    lighthouse_client_id,
    lighthouse_rsa_key_path,
    options
  )

  submit_response(response, options[:body_only])
rescue  Faraday::ClientError,
        Faraday::ServerError => e
  handle_error(e, lighthouse_client_id, endpoint)
end