Class: AsyncTransaction::VAProfile::Base

Inherits:
Base show all
Defined in:
app/models/async_transaction/va_profile/base.rb

Constant Summary collapse

FINAL_STATUSES =
%w[
  REJECTED
  COMPLETED_SUCCESS
  COMPLETED_NO_CHANGES_DETECTED
  COMPLETED_FAILURE
].freeze
REQUESTED =
'requested'
COMPLETED =
'completed'

Constants inherited from Base

Base::DELETE_COMPLETED_AFTER

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#parsed_metadata, #serialize_metadata

Methods inherited from ApplicationRecord

descendants_using_encryption, lockbox_options, #timestamp_attributes_for_update_in_model, #valid?

Class Method Details

.fetch_transaction(transaction_record, service) ⇒ VAProfile::Models::Transaction

Requests a transaction from VAProfile for an app transaction

Parameters:

Returns:



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'app/models/async_transaction/va_profile/base.rb', line 82

def self.fetch_transaction(transaction_record, service)
  case transaction_record
  when AsyncTransaction::Vet360::AddressTransaction, AsyncTransaction::VAProfile::AddressTransaction
    service.get_address_transaction_status(transaction_record.transaction_id)
  when AsyncTransaction::Vet360::EmailTransaction, AsyncTransaction::VAProfile::EmailTransaction
    service.get_email_transaction_status(transaction_record.transaction_id)
  when AsyncTransaction::Vet360::TelephoneTransaction, AsyncTransaction::VAProfile::TelephoneTransaction
    service.get_telephone_transaction_status(transaction_record.transaction_id)
  when AsyncTransaction::Vet360::PermissionTransaction, AsyncTransaction::VAProfile::PermissionTransaction
    service.get_permission_transaction_status(transaction_record.transaction_id)
  when AsyncTransaction::Vet360::InitializePersonTransaction,
       AsyncTransaction::VAProfile::InitializePersonTransaction
    service.get_person_transaction_status(transaction_record.transaction_id)
  else
    # Unexpected transaction type means something went sideways
    raise
  end
end

.find_transaction!(user_uuid, transaction_id) ⇒ AddressTransaction, ...

Finds a transaction by transaction_id for a user

Parameters:

  • user_uuid (String)

    the user’s UUID

  • transaction_id (String)

    the transaction UUID

Returns:



105
106
107
108
# File 'app/models/async_transaction/va_profile/base.rb', line 105

def self.find_transaction!(user_uuid, transaction_id)
  Base.find_by(user_uuid:, transaction_id:) ||
    AsyncTransaction::Vet360::Base.find_by!(user_uuid:, transaction_id:)
end

.last_ongoing_transactions_for_user(user) ⇒ Array

Find the most recent address, email, or telelphone transactions for a user

Returns:

  • (Array)

    an array of any outstanding transactions



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'app/models/async_transaction/va_profile/base.rb', line 143

def self.last_ongoing_transactions_for_user(user)
  ongoing_transactions = []

  %w[
    Address
    Email
    Telephone
    Permission
  ].each do |transaction_type|
    ongoing_transactions += "AsyncTransaction::VAProfile::#{transaction_type}Transaction"
                            .constantize
                            .last_requested_for_user(user)
  end

  ongoing_transactions
end

.last_requested_for_user(user) ⇒ AsyncTransaction::VAProfile::Base

Get most recent requested transaction for a user

Parameters:

  • user (User)

    The user associated with the transaction

Returns:



23
24
25
26
27
28
29
30
31
32
33
34
# File 'app/models/async_transaction/va_profile/base.rb', line 23

def self.last_requested_for_user(user)
  transactions = where(
    status: Base::REQUESTED,
    user_uuid: user.uuid
  ).order(
    created_at: :desc
  ).limit(1)

  return to_s.gsub('VAProfile', 'Vet360').constantize.last_requested.for_user(user) if transactions.blank?

  transactions
end

.refresh_transaction_status(user, service, tx_id = nil) ⇒ AsyncTransaction::VAProfile::Base

Updates the status and transaction_status with fresh API data

Parameters:

Returns:



69
70
71
72
73
74
75
# File 'app/models/async_transaction/va_profile/base.rb', line 69

def self.refresh_transaction_status(user, service, tx_id = nil)
  transaction_record = find_transaction!(user.uuid, tx_id)
  return transaction_record if transaction_record.finished?

  api_response = Base.fetch_transaction(transaction_record, service)
  update_transaction_from_api(transaction_record, api_response)
end

.refresh_transaction_statuses(user, service) ⇒ Array

Wrapper for .refresh_transaction_status which finds any outstanding transactions

for a user and refreshes them

Parameters:

Returns:

  • (Array)

    An array with any outstanding transactions refreshed. Empty if none.



130
131
132
133
134
135
136
137
138
# File 'app/models/async_transaction/va_profile/base.rb', line 130

def self.refresh_transaction_statuses(user, service)
  last_ongoing_transactions_for_user(user).each_with_object([]) do |transaction, array|
    array << refresh_transaction_status(
      user,
      service,
      transaction.transaction_id
    )
  end
end

.start(user, response) ⇒ AsyncTransaction::VAProfile::Base

Creates an initial AsyncTransaction record for ongoing tracking

Parameters:

Returns:



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'app/models/async_transaction/va_profile/base.rb', line 44

def self.start(user, response)
  # vet360_id is no longer required for Contact Information API V2
  source_id = if Flipper.enabled?(:va_v3_contact_information_service,
                                  user)
                user.vet360_id || user.uuid
              else
                user.vet360_id
              end
  create(
    user_uuid: user.uuid,
    user_account: user.,
    source_id: source_id,
    source: 'va_profile',
    status: REQUESTED,
    transaction_id: response.transaction.id,
    transaction_status: response.transaction.status,
    metadata: response.transaction.messages
  )
end

.update_transaction_from_api(transaction_record, api_response) ⇒ Object



110
111
112
113
114
115
116
# File 'app/models/async_transaction/va_profile/base.rb', line 110

def self.update_transaction_from_api(transaction_record, api_response)
  transaction_record.status = COMPLETED if FINAL_STATUSES.include? api_response.transaction.status
  transaction_record.transaction_status = api_response.transaction.status
  transaction_record. = api_response.transaction.messages
  transaction_record.save!
  transaction_record
end

Instance Method Details

#finished?Boolean

Note:

this checks transaction_status status fields, which should be redundant

Returns true or false if a transaction is “over”

Returns:

  • (Boolean)

    true if status is “over”



121
122
123
# File 'app/models/async_transaction/va_profile/base.rb', line 121

def finished?
  FINAL_STATUSES.include?(transaction_status) || status == COMPLETED
end

#initialize_person?Boolean (private)

Returns:

  • (Boolean)


162
163
164
# File 'app/models/async_transaction/va_profile/base.rb', line 162

def initialize_person?
  type&.constantize == AsyncTransaction::VAProfile::InitializePersonTransaction
end