Class: InstantQuote::DecisionParsers::Iwoca

Inherits:
InstantQuote::DecisionParser show all
Defined in:
lib/instant_quote/decision_parsers/iwoca.rb

Overview

Example status response:


{

status: "open",
application_id: "0affceb4-1fbe-4b42-b027-5b1f340b34df",
is_closed: false,
requests: [
  {
    amount: 1500.0,
    duration: { unit: "months", amount: 12.0 },
    product_type: "flexi_loan",
    purpose: "equipment_purchase",
    detailed_purpose: nil,
    requested_cash_amount: nil,
    requested_lower_interest: false,
    urgency: "asap",
    suggested_product: {
      amount: 1500.0,
      duration: { unit: "days", amount: 365 },
      product_type: "flexi_loan"
    }
  }
],
last_12_months_turnover: {
  amount: 70000,
  valid_from: "2019-08-24T14:15:22Z"
}

}

Example offers response:


{

offers: [
  {
    product_type: "flexi_loan",
    duration: { unit: "days", amount: 365 },
    max_amount: 15000.0,
    is_suggested: true,
    offer_id: "14c9addf-b7bd-43bb-b8b0-6ad6b0b6397f",
    offer_type: "sample",
    timeout: "2023-07-29T00:00:00+0000",
    data_requirements: [
      {
        category: "personal_data",
        actions: [
          { name: "complete_personal_credit_check" },
          { name: "check_director_as_guarantor" },
          { name: "check_director_as_applicant" },
          { name: "check_directors_match_companies_house" }
        ]
      },
      {
        category: "company_data",
        actions: [
          { name: "complete_business_credit_check" }
        ]
      },
      {
        category: "enhanced_security_check",
        actions: [
          { name: "contact_iwoca" }
        ]
      }
    ],
    interest_rate: 0.03
  }
],
offer_creation_status: "offers_available"

}

Constant Summary collapse

STATUSES =

Check the details on all the statuses here: iwoca.stoplight.io/docs/lapi-uk/3fc78424792f2-make-an-application

{
  funded: 'funded',
  expired: 'expired',
  talking_to_customer: 'talking_to_customer',
  offered: 'offered',
  declined: 'declined',
  deferred: 'deferred',
  in_underwriting: 'in_underwriting',
  awaiting_underwriter: 'awaiting_underwriter',
  open: 'open',
  action_required: 'action_required',
  offer_revoked: 'offer_revoked',
  customer_to_link_open_banking: 'customer_to_link_open_banking',
  conditional_offer: 'conditional_offer',
  offer_rejected: 'offer_rejected',
  conditional_offer_criteria_met: 'conditional_offer_criteria_met',
  not_defined: 'not_defined' # this is the default status, not a iwoca status
}.freeze

Instance Attribute Summary

Attributes inherited from InstantQuote::DecisionParser

#data

Instance Method Summary collapse

Constructor Details

#initialize(data = {}) ⇒ Iwoca

The data object has two responses in two different keys: status - the response of the application status offers - the response of the available offers



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/instant_quote/decision_parsers/iwoca.rb', line 99

def initialize(data = {})
  @data = super

  # Just in case (v1 has a lot of key 'data' nesting)
  @data = @data[:data] if @data.key?(:data)

  # It's a v1 JSON response, so we need to translate it to v2 first!
  if @data.key?(:state_key) || @data.key?(:approval_status) || @data.key?(:latest_approval_request)
    puts '[iwoca] Translating v1 JSON to v2...'
    @data = DecisionParsers::IwocaV2Translator.translate(@data)
  end

  @status = @data[:status] if @data.key?(:status)

  if @data.key?(:offers)
    @offers = @data[:offers]

    # For some reason sometimes the offers are nested in another key called 'offers'
    @offers = @offers[:offers] if @offers.is_a?(Hash) && @offers.key?(:offers)
  end
end

Instance Method Details

#amountObject



158
159
160
161
162
# File 'lib/instant_quote/decision_parsers/iwoca.rb', line 158

def amount
  amount_approved = suggested_product[:amount] || 0

  Money.new(amount_approved * 100).format
end

#approved?Boolean

Returns:

  • (Boolean)


125
126
127
# File 'lib/instant_quote/decision_parsers/iwoca.rb', line 125

def approved?
  status_included?(status, i[offered funded])
end

#credit_durationObject



164
165
166
167
168
169
170
171
# File 'lib/instant_quote/decision_parsers/iwoca.rb', line 164

def credit_duration
  unit = suggested_product.dig(:duration, :unit)
  amount = suggested_product.dig(:duration, :amount)

  return unless unit && amount

  { unit: unit, amount: amount }
end

#declined?Boolean

Returns:

  • (Boolean)


129
130
131
# File 'lib/instant_quote/decision_parsers/iwoca.rb', line 129

def declined?
  status_included?(status, i[declined offer_revoked offer_rejected])
end

#loan_started?Boolean

Returns:

  • (Boolean)


147
148
149
150
151
152
153
154
155
156
# File 'lib/instant_quote/decision_parsers/iwoca.rb', line 147

def loan_started?
  started_statuses = i[
    in_underwriting
    awaiting_underwriter
    talking_to_customer
    customer_to_link_open_banking
  ]

  status_included?(status, started_statuses)
end

#manual_review?Boolean

Returns:

  • (Boolean)


133
134
135
136
137
138
139
140
141
# File 'lib/instant_quote/decision_parsers/iwoca.rb', line 133

def manual_review?
  manual_review_statuses = i[
    deferred
    action_required
    talking_to_customer
  ]

  status_included?(status, manual_review_statuses)
end

#monthly_interest_rateObject



173
174
175
176
177
# File 'lib/instant_quote/decision_parsers/iwoca.rb', line 173

def monthly_interest_rate
  return 0 unless first_offer

  first_offer[:interest_rate]
end

#no_decision_possible?Boolean

Returns:

  • (Boolean)


143
144
145
# File 'lib/instant_quote/decision_parsers/iwoca.rb', line 143

def no_decision_possible?
  status_included?(status, i[expired])
end

#pending?Boolean

Returns:

  • (Boolean)


121
122
123
# File 'lib/instant_quote/decision_parsers/iwoca.rb', line 121

def pending?
  status == STATUSES[:open]
end

#statusObject



179
180
181
182
183
# File 'lib/instant_quote/decision_parsers/iwoca.rb', line 179

def status
  return STATUSES[:not_defined] unless @status

  @status[:status] || STATUSES[:not_defined]
end