instant_quote 1.7.2 → 1.7.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +10 -10
- data/lib/instant_quote/adapter.rb +4 -4
- data/lib/instant_quote/adapters/capital_on_tap.rb +0 -12
- data/lib/instant_quote/adapters/fake.rb +162 -0
- data/lib/instant_quote/connection_translators/capital_on_tap.rb +3 -5
- data/lib/instant_quote/connection_translators/fake.rb +28 -0
- data/lib/instant_quote/decision_parsers/fake.rb +82 -0
- data/lib/instant_quote/decision_parsers/youlend.rb +21 -9
- data/lib/instant_quote/version.rb +1 -1
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c6ca7c25677c925b0b637a2ac22052acf1e0969228fce0a2acd5d3916ea4bcf1
|
4
|
+
data.tar.gz: df855495089300f19461a6fdc50784987305a4064d4919b0426a7e330c9bf67b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0b4449520408ce3c7ea5ecadda96213fee6ae6ffde6476f1ad3cd13f46fa296612e29001ed9cd66e1f836fc32c29f3ed882bd4de88e386855adc511503a4edc0
|
7
|
+
data.tar.gz: dda46d5ba775f70e21319df87dd9e69033188f37f6ffffa59b0e85736179ade50b9ab1b34b0e906e18b5952fcdb814b4627ac0108c99c3b42afc24b0a8be6d5b
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
instant_quote (1.7.
|
4
|
+
instant_quote (1.7.7)
|
5
5
|
activesupport
|
6
6
|
capital_on_tap
|
7
7
|
iwoca
|
@@ -13,7 +13,7 @@ PATH
|
|
13
13
|
GEM
|
14
14
|
remote: https://rubygems.org/
|
15
15
|
specs:
|
16
|
-
activesupport (6.1.3)
|
16
|
+
activesupport (6.1.3.1)
|
17
17
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
18
18
|
i18n (>= 1.6, < 2)
|
19
19
|
minitest (>= 5.1)
|
@@ -44,7 +44,7 @@ GEM
|
|
44
44
|
faraday_middleware (1.0.0)
|
45
45
|
faraday (~> 1.0)
|
46
46
|
hashdiff (1.0.1)
|
47
|
-
i18n (1.8.
|
47
|
+
i18n (1.8.10)
|
48
48
|
concurrent-ruby (~> 1.0)
|
49
49
|
iwoca (1.0.0)
|
50
50
|
addressable
|
@@ -53,8 +53,8 @@ GEM
|
|
53
53
|
multi_json
|
54
54
|
rainbow
|
55
55
|
method_source (1.0.0)
|
56
|
-
minitest (5.14.
|
57
|
-
money (6.14.
|
56
|
+
minitest (5.14.4)
|
57
|
+
money (6.14.1)
|
58
58
|
i18n (>= 0.6.4, <= 2)
|
59
59
|
multi_json (1.15.0)
|
60
60
|
multipart-post (2.1.1)
|
@@ -67,7 +67,7 @@ GEM
|
|
67
67
|
parallel (1.20.1)
|
68
68
|
parser (3.0.0.0)
|
69
69
|
ast (~> 2.4.1)
|
70
|
-
phonelib (0.6.
|
70
|
+
phonelib (0.6.49)
|
71
71
|
pry (0.13.1)
|
72
72
|
coderay (~> 1.1)
|
73
73
|
method_source (~> 1.0)
|
@@ -77,7 +77,7 @@ GEM
|
|
77
77
|
public_suffix (4.0.6)
|
78
78
|
rainbow (3.0.0)
|
79
79
|
rake (10.5.0)
|
80
|
-
regexp_parser (2.
|
80
|
+
regexp_parser (2.1.1)
|
81
81
|
rexml (3.2.4)
|
82
82
|
rspec (3.10.0)
|
83
83
|
rspec-core (~> 3.10.0)
|
@@ -92,7 +92,7 @@ GEM
|
|
92
92
|
diff-lcs (>= 1.2.0, < 2.0)
|
93
93
|
rspec-support (~> 3.10.0)
|
94
94
|
rspec-support (3.10.2)
|
95
|
-
rubocop (1.
|
95
|
+
rubocop (1.11.0)
|
96
96
|
parallel (~> 1.10)
|
97
97
|
parser (>= 3.0.0.0)
|
98
98
|
rainbow (>= 2.2.2, < 4.0)
|
@@ -119,7 +119,7 @@ GEM
|
|
119
119
|
tzinfo (2.0.4)
|
120
120
|
concurrent-ruby (~> 1.0)
|
121
121
|
unicode-display_width (2.0.0)
|
122
|
-
webmock (3.
|
122
|
+
webmock (3.12.1)
|
123
123
|
addressable (>= 2.3.6)
|
124
124
|
crack (>= 0.3.2)
|
125
125
|
hashdiff (>= 0.4.0, < 2.0.0)
|
@@ -148,4 +148,4 @@ DEPENDENCIES
|
|
148
148
|
webmock
|
149
149
|
|
150
150
|
BUNDLED WITH
|
151
|
-
2.2.
|
151
|
+
2.2.11
|
@@ -51,14 +51,14 @@ module InstantQuote
|
|
51
51
|
raise NotImplementedError, "You must implement '#{self.class.name}#get_status'"
|
52
52
|
end
|
53
53
|
|
54
|
-
# Default for pre approval will be
|
54
|
+
# Default for pre approval will be success, override it in the adapter class if needed.
|
55
55
|
def get_preapproval(_params, _connection)
|
56
|
-
true
|
56
|
+
OpenStruct.new(success?: true)
|
57
57
|
end
|
58
58
|
|
59
|
-
# Default for approval will be
|
59
|
+
# Default for approval will be success, override it in the adapter class if needed.
|
60
60
|
def get_approval(_application_id, _connection)
|
61
|
-
true
|
61
|
+
OpenStruct.new(success?: true)
|
62
62
|
end
|
63
63
|
end
|
64
64
|
end
|
@@ -28,18 +28,6 @@ module InstantQuote
|
|
28
28
|
required: true,
|
29
29
|
if: ->(app) { app.borrower_organisation.sole_trader? }
|
30
30
|
},
|
31
|
-
{
|
32
|
-
name: 'turnover_percentage_after_feb_2020',
|
33
|
-
label: 'What is your current turnover as a percentage of your turnover prior to February 2020?',
|
34
|
-
required: true,
|
35
|
-
choices: [
|
36
|
-
'My turnover had increased since covid',
|
37
|
-
'My turnover is about the same as it was pre-covid (within 20%)',
|
38
|
-
'My turnover has fallen materially as a result of covid (20%-60% reduction in turnover)',
|
39
|
-
'My turnover has fallen significantly as a result of covid (more than a 60% reduction in turnover)'
|
40
|
-
],
|
41
|
-
type: 'select'
|
42
|
-
},
|
43
31
|
{
|
44
32
|
name: 'preferred_monthly_repayment_option',
|
45
33
|
label: 'How do you want to set up your direct debit for monthly repayment?',
|
@@ -0,0 +1,162 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'securerandom'
|
4
|
+
require 'instant_quote/decision_parsers/fake'
|
5
|
+
|
6
|
+
module InstantQuote
|
7
|
+
module Adapters
|
8
|
+
class Fake < Adapter
|
9
|
+
additional_fields [
|
10
|
+
{
|
11
|
+
name: 'date_of_birth',
|
12
|
+
label: 'Date of birth',
|
13
|
+
type: 'date',
|
14
|
+
required: true
|
15
|
+
},
|
16
|
+
{
|
17
|
+
name: 'desired_status',
|
18
|
+
label: 'What status do you want to get back?',
|
19
|
+
required: true,
|
20
|
+
choices: {
|
21
|
+
'Pending' => 'pending',
|
22
|
+
'Approved' => 'approved',
|
23
|
+
'Declined' => 'declined',
|
24
|
+
'No decision possible' => 'no_decision_possible',
|
25
|
+
'Error on get_quote' => 'error_on_get_quote',
|
26
|
+
'Error on get_status' => 'error_on_get_status'
|
27
|
+
},
|
28
|
+
type: 'select'
|
29
|
+
},
|
30
|
+
{
|
31
|
+
name: 'decision_info_html',
|
32
|
+
label: 'What html you want to render for decision info?',
|
33
|
+
required: true,
|
34
|
+
choices: {
|
35
|
+
'Iwoca' => 'iwoca',
|
36
|
+
'Iwoca CBILS' => 'iwoca_cbils',
|
37
|
+
'Capital on tap' => 'capital_on_tap',
|
38
|
+
'Optimum' => 'optimum',
|
39
|
+
'Youlend' => 'youlend'
|
40
|
+
},
|
41
|
+
type: 'select'
|
42
|
+
},
|
43
|
+
{
|
44
|
+
name: 'with_preapproval',
|
45
|
+
label: 'Preapproval?',
|
46
|
+
choices: {
|
47
|
+
'No' => 'no',
|
48
|
+
'Yes (success)' => 'yes_success',
|
49
|
+
'Yes (decline)' => 'yes_decline'
|
50
|
+
},
|
51
|
+
type: 'select'
|
52
|
+
},
|
53
|
+
{
|
54
|
+
name: 'with_approval',
|
55
|
+
label: 'With approval?',
|
56
|
+
choices: {
|
57
|
+
'No' => 'no',
|
58
|
+
'Yes' => 'yes'
|
59
|
+
},
|
60
|
+
type: 'select'
|
61
|
+
},
|
62
|
+
{
|
63
|
+
name: 'applicant_consent',
|
64
|
+
label: 'Yes, I give my consent for my data to be shared',
|
65
|
+
required: true,
|
66
|
+
type: 'checkbox'
|
67
|
+
}
|
68
|
+
]
|
69
|
+
|
70
|
+
# TODO: what should we do here?
|
71
|
+
def get_approval(_state_key, _connection)
|
72
|
+
true
|
73
|
+
end
|
74
|
+
|
75
|
+
def get_preapproval(params, _connection)
|
76
|
+
response = OpenStruct.new(success?: true, error_description: '')
|
77
|
+
|
78
|
+
return response if params[:with_preapproval] == 'no'
|
79
|
+
|
80
|
+
if params[:with_preapproval] == 'yes_decline'
|
81
|
+
response[:success?] = false
|
82
|
+
response.error_description = 'preapproval is declined'
|
83
|
+
end
|
84
|
+
|
85
|
+
response
|
86
|
+
end
|
87
|
+
|
88
|
+
def get_quote(params, _connection)
|
89
|
+
if params[:desired_status] == 'error_on_get_quote'
|
90
|
+
response = OpenStruct.new(
|
91
|
+
body: { errorMessage: 'Error on get_quote that raises an exception' },
|
92
|
+
error: '501 error_on_get_quote'
|
93
|
+
)
|
94
|
+
raise_error(response)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Returns a random identifier
|
98
|
+
SecureRandom.hex(3)
|
99
|
+
end
|
100
|
+
|
101
|
+
# Get the status for a given application ID
|
102
|
+
# rubocop:disable Metrics/AbcSize
|
103
|
+
# rubocop:disable Metrics/MethodLength
|
104
|
+
def get_status(_application_id, connection)
|
105
|
+
status = connection.extra_info['desired_status']
|
106
|
+
|
107
|
+
if status == 'error_on_get_status'
|
108
|
+
response = OpenStruct.new(
|
109
|
+
body: { errorMessage: 'Error on get_status that raises an exception' },
|
110
|
+
error: '502 error_on_get_status'
|
111
|
+
)
|
112
|
+
raise_error(response) unless response.success?
|
113
|
+
end
|
114
|
+
|
115
|
+
response = OpenStruct.new(
|
116
|
+
body: {
|
117
|
+
latest_approval_request: {
|
118
|
+
status: status,
|
119
|
+
approved: {
|
120
|
+
interval: rand(10..30),
|
121
|
+
duration: rand(10..30),
|
122
|
+
max_credit: rand(1000..8000),
|
123
|
+
monthly_interest_rate: rand(0..1.0).round(2)
|
124
|
+
}
|
125
|
+
},
|
126
|
+
credit_decision: {
|
127
|
+
status: status,
|
128
|
+
sweep: 10,
|
129
|
+
loan_amount: rand(1000..8000),
|
130
|
+
funded_amount: rand(1000..8000),
|
131
|
+
fee: rand(100..800),
|
132
|
+
monthly_interest_rate: rand(0..1.0).round(2),
|
133
|
+
monthly_card_interest_rate: rand(0..1.0).round(2),
|
134
|
+
amount: rand(1000..8000)
|
135
|
+
}
|
136
|
+
}
|
137
|
+
)
|
138
|
+
|
139
|
+
DecisionParsers::Fake.new(response.body)
|
140
|
+
end
|
141
|
+
# rubocop:enable Metrics/AbcSize
|
142
|
+
# rubocop:enable Metrics/MethodLength
|
143
|
+
|
144
|
+
# The link is always the same
|
145
|
+
def get_link(connection)
|
146
|
+
id = connection.external_id
|
147
|
+
|
148
|
+
"https://fake.com/link/#{id}"
|
149
|
+
end
|
150
|
+
|
151
|
+
private
|
152
|
+
|
153
|
+
def raise_error(response)
|
154
|
+
raise ApiError.new(
|
155
|
+
adapter: 'fake',
|
156
|
+
data: response.body,
|
157
|
+
error: response.error || 'Unknown API error'
|
158
|
+
)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
@@ -72,9 +72,12 @@ module InstantQuote
|
|
72
72
|
}
|
73
73
|
end
|
74
74
|
|
75
|
+
# TODO: this is no longer true, but we are still keeping the range for legacy reasons.
|
75
76
|
# Since in Finpoint the user selects an intervel (i.e. '500,000 - 999,999'). We get the avg
|
76
77
|
# on this interval and use that number as the monthly turnover.
|
77
78
|
def translate_turnover
|
79
|
+
return app_org.turnover_pennies.to_i if app_org.turnover_pennies
|
80
|
+
|
78
81
|
turnover = app_org.turnover_range
|
79
82
|
|
80
83
|
((turnover.from + turnover.to) / 2 / 100).ceil
|
@@ -98,7 +101,6 @@ module InstantQuote
|
|
98
101
|
def additional_questions
|
99
102
|
[
|
100
103
|
preferred_monthly_repayment_option_question,
|
101
|
-
turnover_percentage_question,
|
102
104
|
send_cash_from_credit_facility_to_bank_question
|
103
105
|
]
|
104
106
|
end
|
@@ -107,10 +109,6 @@ module InstantQuote
|
|
107
109
|
question_from_extra_info('preferred_monthly_repayment_option', '17')
|
108
110
|
end
|
109
111
|
|
110
|
-
def turnover_percentage_question
|
111
|
-
question_from_extra_info('turnover_percentage_after_feb_2020', '20')
|
112
|
-
end
|
113
|
-
|
114
112
|
def send_cash_from_credit_facility_to_bank_question
|
115
113
|
question_from_extra_info('send_cash_from_credit_facility_to_bank', '23')
|
116
114
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module InstantQuote
|
4
|
+
module ConnectionTranslators
|
5
|
+
class Fake < ConnectionTranslator
|
6
|
+
def translate
|
7
|
+
{
|
8
|
+
salutation: app_user.salutation,
|
9
|
+
first_name: app_user.first_name,
|
10
|
+
last_name: app_user.last_name,
|
11
|
+
date_of_birth: extra_info['date_of_birth'],
|
12
|
+
registration_number: app_org.company_number,
|
13
|
+
desired_status: extra_info['desired_status']
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def app_user
|
20
|
+
application.primary_user
|
21
|
+
end
|
22
|
+
|
23
|
+
def app_org
|
24
|
+
application.borrower_organisation
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'money'
|
4
|
+
|
5
|
+
module InstantQuote
|
6
|
+
module DecisionParsers
|
7
|
+
class Fake < DecisionParser
|
8
|
+
STATUSES = {
|
9
|
+
pending: 'pending',
|
10
|
+
approved: 'approved',
|
11
|
+
declined: 'declined',
|
12
|
+
could_not_submit: 'CouldNotSubmit',
|
13
|
+
no_decision: 'no_decision_possible'
|
14
|
+
}.freeze
|
15
|
+
|
16
|
+
def pending?
|
17
|
+
status == STATUSES[:pending]
|
18
|
+
end
|
19
|
+
|
20
|
+
def approved?
|
21
|
+
status == STATUSES[:approved]
|
22
|
+
end
|
23
|
+
|
24
|
+
def declined?
|
25
|
+
status == STATUSES[:declined]
|
26
|
+
end
|
27
|
+
|
28
|
+
def credit_duration
|
29
|
+
credit_decision.dig(:approved, :duration)
|
30
|
+
end
|
31
|
+
|
32
|
+
def credit_interval
|
33
|
+
credit_decision.dig(:approved, :interval)
|
34
|
+
end
|
35
|
+
|
36
|
+
def sweep
|
37
|
+
credit_decision[:sweep]
|
38
|
+
end
|
39
|
+
|
40
|
+
def fee
|
41
|
+
fee = credit_decision[:fee].to_f
|
42
|
+
|
43
|
+
Money.new(fee * 100).format
|
44
|
+
end
|
45
|
+
|
46
|
+
def amount
|
47
|
+
Money.new(credit_decision[:amount].to_f * 100).format
|
48
|
+
end
|
49
|
+
|
50
|
+
def loan_amount
|
51
|
+
amount = credit_decision[:loan_amount].to_f
|
52
|
+
|
53
|
+
Money.new(amount * 100).format
|
54
|
+
end
|
55
|
+
|
56
|
+
def funded_amount
|
57
|
+
amount = credit_decision[:funded_amount].to_f
|
58
|
+
|
59
|
+
Money.new(amount * 100).format
|
60
|
+
end
|
61
|
+
|
62
|
+
def monthly_interest_rate
|
63
|
+
credit_decision[:monthly_interes_rate] ||
|
64
|
+
credit_decision.dig(:approved, :monthly_interest_rate) || 0.0
|
65
|
+
end
|
66
|
+
|
67
|
+
def monthly_card_interest_rate
|
68
|
+
credit_decision[:monthly_card_interes_rate] || 0.0
|
69
|
+
end
|
70
|
+
|
71
|
+
def status
|
72
|
+
credit_decision[:status] || STATUSES[:could_not_submit]
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def credit_decision
|
78
|
+
data[:credit_decision] || data[:latest_approval_request] || {}
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -18,43 +18,55 @@ module InstantQuote
|
|
18
18
|
# }
|
19
19
|
class Youlend < DecisionParser
|
20
20
|
def approved?
|
21
|
-
status_hash[:loanOptions].any?
|
21
|
+
status_hash[:loanOptions].any? && !funded_option.empty?
|
22
22
|
end
|
23
23
|
|
24
24
|
def declined?
|
25
|
-
|
25
|
+
!approved?
|
26
26
|
end
|
27
27
|
|
28
28
|
def sweep
|
29
|
-
|
29
|
+
funded_option[:sweep]
|
30
|
+
end
|
31
|
+
|
32
|
+
def status
|
33
|
+
approved? ? 'approved' : 'declined'
|
30
34
|
end
|
31
35
|
|
32
36
|
def fee
|
33
|
-
fee =
|
37
|
+
fee = funded_option[:fee].to_f
|
34
38
|
|
35
39
|
Money.new(fee * 100).format
|
36
40
|
end
|
37
41
|
|
38
42
|
def loan_amount
|
39
|
-
amount =
|
43
|
+
amount = funded_option[:loanAmount].to_f
|
40
44
|
|
41
45
|
Money.new(amount * 100).format
|
42
46
|
end
|
43
47
|
|
44
48
|
def funded_amount
|
45
|
-
amount =
|
49
|
+
amount = funded_option[:fundedAmount].to_f
|
46
50
|
|
47
51
|
Money.new(amount * 100).format
|
48
52
|
end
|
49
53
|
|
54
|
+
alias amount funded_amount
|
55
|
+
|
50
56
|
private
|
51
57
|
|
52
|
-
def
|
53
|
-
@
|
58
|
+
def funded_option
|
59
|
+
@funded_option ||= status_hash[:loanOptions].find(-> { {} }) do |opt|
|
60
|
+
opt[:fundedAmount].positive?
|
61
|
+
end
|
54
62
|
end
|
55
63
|
|
56
64
|
def status_hash
|
57
|
-
|
65
|
+
default = { loanOptions: [] }
|
66
|
+
|
67
|
+
return default unless data && !data.empty?
|
68
|
+
|
69
|
+
data
|
58
70
|
end
|
59
71
|
end
|
60
72
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: instant_quote
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.7.
|
4
|
+
version: 1.7.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- rikas
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-04-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -271,6 +271,7 @@ files:
|
|
271
271
|
- lib/instant_quote/adapter.rb
|
272
272
|
- lib/instant_quote/adapter_finder.rb
|
273
273
|
- lib/instant_quote/adapters/capital_on_tap.rb
|
274
|
+
- lib/instant_quote/adapters/fake.rb
|
274
275
|
- lib/instant_quote/adapters/iwoca.rb
|
275
276
|
- lib/instant_quote/adapters/iwoca_cbils.rb
|
276
277
|
- lib/instant_quote/adapters/optimum.rb
|
@@ -278,12 +279,14 @@ files:
|
|
278
279
|
- lib/instant_quote/api_error.rb
|
279
280
|
- lib/instant_quote/connection_translator.rb
|
280
281
|
- lib/instant_quote/connection_translators/capital_on_tap.rb
|
282
|
+
- lib/instant_quote/connection_translators/fake.rb
|
281
283
|
- lib/instant_quote/connection_translators/iwoca.rb
|
282
284
|
- lib/instant_quote/connection_translators/iwoca_cbils.rb
|
283
285
|
- lib/instant_quote/connection_translators/optimum.rb
|
284
286
|
- lib/instant_quote/connection_translators/youlend.rb
|
285
287
|
- lib/instant_quote/decision_parser.rb
|
286
288
|
- lib/instant_quote/decision_parsers/capital_on_tap.rb
|
289
|
+
- lib/instant_quote/decision_parsers/fake.rb
|
287
290
|
- lib/instant_quote/decision_parsers/iwoca.rb
|
288
291
|
- lib/instant_quote/decision_parsers/iwoca_cbils.rb
|
289
292
|
- lib/instant_quote/decision_parsers/optimum.rb
|
@@ -309,7 +312,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
309
312
|
- !ruby/object:Gem::Version
|
310
313
|
version: '0'
|
311
314
|
requirements: []
|
312
|
-
rubygems_version: 3.
|
315
|
+
rubygems_version: 3.2.11
|
313
316
|
signing_key:
|
314
317
|
specification_version: 4
|
315
318
|
summary: Instant quote providers gem.
|