valvat 1.1.5 → 1.2.0
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
- checksums.yaml.gz.sig +0 -0
- data/.github/workflows/ruby.yml +2 -2
- data/.rubocop.yml +9 -3
- data/CHANGES.md +11 -2
- data/MIT-LICENSE +1 -1
- data/README.md +48 -33
- data/lib/valvat/checksum/es.rb +49 -16
- data/lib/valvat/error.rb +16 -16
- data/lib/valvat/local.rb +2 -49
- data/lib/valvat/lookup/base.rb +73 -0
- data/lib/valvat/lookup/hmrc.rb +86 -0
- data/lib/valvat/lookup/vies.rb +98 -0
- data/lib/valvat/lookup.rb +16 -5
- data/lib/valvat/utils.rb +0 -1
- data/lib/valvat/version.rb +1 -1
- data/lib/valvat.rb +50 -4
- data/spec/spec_helper.rb +2 -1
- data/spec/valvat/checksum/es_spec.rb +41 -1
- data/spec/valvat/checksum/gb_spec.rb +1 -0
- data/spec/valvat/lookup/hmrc_spec.rb +32 -0
- data/spec/valvat/lookup/vies_spec.rb +23 -0
- data/spec/valvat/lookup_spec.rb +259 -71
- data/valvat.gemspec +2 -2
- data.tar.gz.sig +0 -0
- metadata +22 -24
- metadata.gz.sig +0 -0
- data/lib/valvat/lookup/fault.rb +0 -44
- data/lib/valvat/lookup/request.rb +0 -57
- data/lib/valvat/lookup/response.rb +0 -37
- data/spec/valvat/lookup/fault_spec.rb +0 -34
- data/spec/valvat/lookup/request_spec.rb +0 -32
- data/spec/valvat/lookup/response_spec.rb +0 -29
data/spec/valvat/lookup_spec.rb
CHANGED
@@ -4,98 +4,162 @@ require 'spec_helper'
|
|
4
4
|
|
5
5
|
describe Valvat::Lookup do
|
6
6
|
describe '#validate' do
|
7
|
-
context 'with existing VAT number' do
|
7
|
+
context 'with existing EU VAT number' do
|
8
8
|
it 'returns true' do
|
9
9
|
result = described_class.validate('IE6388047V')
|
10
|
-
|
11
|
-
expect(result).to be(true)
|
10
|
+
skip 'VIES is down' if result.nil?
|
11
|
+
expect(result).to be(true)
|
12
12
|
end
|
13
13
|
|
14
14
|
it 'allows Valvat instance as input' do
|
15
15
|
result = described_class.validate(Valvat.new('IE6388047V'))
|
16
|
-
|
17
|
-
expect(result).to be(true)
|
16
|
+
skip 'VIES is down' if result.nil?
|
17
|
+
expect(result).to be(true)
|
18
18
|
end
|
19
|
-
end
|
20
19
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
20
|
+
context 'with details' do
|
21
|
+
it 'returns hash of details instead of true' do
|
22
|
+
result = described_class.validate('IE6388047V', detail: true)
|
23
|
+
skip 'VIES is down' if result.nil?
|
24
|
+
|
25
|
+
expect(result).to match({
|
26
|
+
request_date: kind_of(Date),
|
27
|
+
country_code: 'IE',
|
28
|
+
vat_number: '6388047V',
|
29
|
+
name: 'GOOGLE IRELAND LIMITED',
|
30
|
+
address: '3RD FLOOR, GORDON HOUSE, BARROW STREET, DUBLIN 4',
|
31
|
+
valid: true
|
32
|
+
})
|
33
|
+
end
|
26
34
|
end
|
27
35
|
end
|
28
36
|
|
29
|
-
context 'with
|
30
|
-
it 'returns
|
31
|
-
|
32
|
-
|
37
|
+
context 'with existing GB VAT number' do
|
38
|
+
it 'returns true' do
|
39
|
+
result = described_class.validate('GB727255821', uk: true)
|
40
|
+
skip 'HMRC is down' if result.nil?
|
41
|
+
expect(result).to be(true)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'returns details in format similar to VIES' do
|
45
|
+
result = described_class.validate('GB727255821', detail: true, uk: true)
|
46
|
+
skip 'HMRC is down' if result.nil?
|
47
|
+
expect(result).to match({
|
48
|
+
request_date: kind_of(Time),
|
49
|
+
country_code: 'GB',
|
50
|
+
vat_number: '727255821',
|
51
|
+
name: 'AMAZON EU SARL',
|
52
|
+
address: "1 PRINCIPAL PLACE\nWORSHIP STREET\nLONDON\nEC2A 2FA\nGB",
|
53
|
+
valid: true
|
54
|
+
})
|
33
55
|
end
|
34
56
|
end
|
35
57
|
|
36
|
-
context 'with
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
vat_number: '6388047V',
|
42
|
-
name: 'GOOGLE IRELAND LIMITED',
|
43
|
-
address: '3RD FLOOR, GORDON HOUSE, BARROW STREET, DUBLIN 4',
|
44
|
-
valid: true
|
45
|
-
}
|
58
|
+
context 'with not existing EU VAT number' do
|
59
|
+
it 'returns false' do
|
60
|
+
result = described_class.validate('IE6388048V')
|
61
|
+
skip 'VIES is down' if result.nil?
|
62
|
+
expect(result).to be(false)
|
46
63
|
end
|
47
64
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
expect(result
|
53
|
-
expect(result).to eql(details)
|
65
|
+
context 'with details' do
|
66
|
+
it 'still returns false' do
|
67
|
+
result = described_class.validate('LU21416128', detail: true)
|
68
|
+
skip 'VIES is down' if result.nil?
|
69
|
+
expect(result).to be(false)
|
54
70
|
end
|
55
71
|
end
|
72
|
+
end
|
56
73
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
74
|
+
context 'with not existing GB VAT number' do
|
75
|
+
it 'returns false' do
|
76
|
+
result = described_class.validate('GB727255820', uk: true)
|
77
|
+
skip 'HMRC is down' if result.nil?
|
78
|
+
expect(result).to be(false)
|
61
79
|
end
|
62
80
|
end
|
63
81
|
|
64
|
-
context 'with
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
'@xmlns:ns2': 'urn:ec.europa.eu:taxud:vies:services:checkVat:types',
|
69
|
-
country_code: 'IE',
|
70
|
-
vat_number: '6388047V',
|
71
|
-
name: 'GOOGLE IRELAND LIMITED',
|
72
|
-
company_type: nil,
|
73
|
-
address: '3RD FLOOR, GORDON HOUSE, BARROW STREET, DUBLIN 4',
|
74
|
-
valid: true
|
75
|
-
}
|
82
|
+
context 'with invalid country code / input' do
|
83
|
+
it 'returns false' do
|
84
|
+
expect(described_class.validate('AE259597697')).to be(false)
|
85
|
+
expect(described_class.validate('')).to be(false)
|
76
86
|
end
|
87
|
+
end
|
77
88
|
|
89
|
+
context 'with request identifier' do
|
78
90
|
it 'returns hash of details instead of true' do
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
91
|
+
result = described_class.validate('IE6388047V', requester: 'IE6388047V')
|
92
|
+
|
93
|
+
skip 'VIES is down' if result.nil?
|
94
|
+
|
95
|
+
expect(result).to match({
|
96
|
+
request_date: kind_of(Date),
|
97
|
+
request_identifier: /\A[\w\W]{16}\Z/,
|
98
|
+
country_code: 'IE',
|
99
|
+
vat_number: '6388047V',
|
100
|
+
name: 'GOOGLE IRELAND LIMITED',
|
101
|
+
company_type: nil,
|
102
|
+
address: '3RD FLOOR, GORDON HOUSE, BARROW STREET, DUBLIN 4',
|
103
|
+
valid: true
|
104
|
+
})
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'supports old :requester_vat option for backwards compatibility' do
|
108
|
+
result = described_class.validate('IE6388047V', requester_vat: 'LU21416127')
|
109
|
+
|
110
|
+
expect(result).to match({
|
111
|
+
request_date: kind_of(Date),
|
112
|
+
request_identifier: /\A[\w\W]{16}\Z/,
|
113
|
+
country_code: 'IE',
|
114
|
+
vat_number: '6388047V',
|
115
|
+
name: 'GOOGLE IRELAND LIMITED',
|
116
|
+
company_type: nil,
|
117
|
+
address: '3RD FLOOR, GORDON HOUSE, BARROW STREET, DUBLIN 4',
|
118
|
+
valid: true
|
119
|
+
})
|
120
|
+
end
|
121
|
+
|
122
|
+
context 'with GB VAT number' do
|
123
|
+
it 'returns hash of details with request number' do
|
124
|
+
response = described_class.validate('GB727255821', requester: 'GB727255821', uk: true)
|
125
|
+
skip 'HMRC is down' if response.nil?
|
126
|
+
expect(response).to match({
|
127
|
+
request_date: kind_of(Time),
|
128
|
+
request_identifier: /\A\w\w\w-\w\w\w-\w\w\w\Z/,
|
129
|
+
country_code: 'GB',
|
130
|
+
vat_number: '727255821',
|
131
|
+
name: 'AMAZON EU SARL',
|
132
|
+
address: "1 PRINCIPAL PLACE\nWORSHIP STREET\nLONDON\nEC2A 2FA\nGB",
|
133
|
+
valid: true
|
134
|
+
})
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'raises exception if requester is not from GB' do
|
138
|
+
expect do
|
139
|
+
described_class.validate('GB727255821', requester: 'IE6388047V', uk: true)
|
140
|
+
end.to raise_error(Valvat::InvalidRequester,
|
141
|
+
'The HMRC web service returned the error: '\
|
142
|
+
'INVALID_REQUEST (Invalid requesterVrn - Vrn parameters should be 9 or 12 digits)')
|
84
143
|
end
|
85
|
-
end
|
86
144
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
145
|
+
it 'raises exception if requester is not valid' do
|
146
|
+
expect do
|
147
|
+
described_class.validate('GB727255821', requester: 'GB6388047', uk: true)
|
148
|
+
end.to raise_error(Valvat::InvalidRequester,
|
149
|
+
'The HMRC web service returned the error: '\
|
150
|
+
'INVALID_REQUEST (Invalid requesterVrn - Vrn parameters should be 9 or 12 digits)')
|
151
|
+
end
|
91
152
|
end
|
92
153
|
end
|
93
154
|
end
|
94
155
|
|
95
156
|
describe '#validate with VIES test enviroment' do
|
96
157
|
let(:options) do
|
97
|
-
{
|
98
|
-
|
158
|
+
{ skip_local_validation: true }
|
159
|
+
end
|
160
|
+
|
161
|
+
before do
|
162
|
+
stub_const('Valvat::Lookup::VIES::ENDPOINT_URI', URI('https://ec.europa.eu/taxation_customs/vies/test-services/checkVatTestService'))
|
99
163
|
end
|
100
164
|
|
101
165
|
context 'with valid request with valid VAT number' do
|
@@ -170,6 +234,22 @@ describe Valvat::Lookup do
|
|
170
234
|
end
|
171
235
|
end
|
172
236
|
|
237
|
+
describe 'Network timeout' do
|
238
|
+
subject(:result) { described_class.validate('DE200', options) }
|
239
|
+
|
240
|
+
before { stub_request(:post, /ec.europa.eu/).to_timeout }
|
241
|
+
|
242
|
+
it 'raises error' do
|
243
|
+
expect { result }.to raise_error(Net::OpenTimeout, 'execution expired')
|
244
|
+
end
|
245
|
+
|
246
|
+
it 'also raises error with raise_error set to false (not handled)' do
|
247
|
+
expect do
|
248
|
+
described_class.validate('DE302', options.merge(raise_error: false))
|
249
|
+
end.to raise_error(Net::OpenTimeout, 'execution expired')
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
173
253
|
describe 'Error : VAT_BLOCKED' do
|
174
254
|
subject(:result) { described_class.validate('DE400', options) }
|
175
255
|
|
@@ -242,39 +322,147 @@ describe Valvat::Lookup do
|
|
242
322
|
end
|
243
323
|
end
|
244
324
|
|
245
|
-
describe 'Error :
|
325
|
+
describe 'Error : HTTP error' do
|
246
326
|
subject(:result) { described_class.validate('DE601', options) }
|
247
327
|
|
248
328
|
before do
|
249
|
-
|
250
|
-
allow(Savon::Client).to receive(:new).and_return(dbl)
|
251
|
-
allow(dbl).to receive(:call).and_raise(Savon::UnknownOperationError.new('from stub'))
|
329
|
+
stub_request(:post, %r{\Ahttps://ec\.europa\.eu}).to_return({ status: 405 })
|
252
330
|
end
|
253
331
|
|
254
332
|
it 'raises error' do
|
255
|
-
expect { result }.to raise_error(Valvat::
|
333
|
+
expect { result }.to raise_error(Valvat::HTTPError, 'The VIES web service returned the error: 405')
|
256
334
|
end
|
257
335
|
|
258
336
|
it 'returns nil with raise_error set to false' do
|
259
337
|
expect(described_class.validate('DE601', options.merge(raise_error: false))).to be_nil
|
260
338
|
end
|
261
339
|
end
|
340
|
+
end
|
262
341
|
|
263
|
-
|
264
|
-
|
342
|
+
describe '#validate with HMRC test enviroment' do
|
343
|
+
# https://developer.service.hmrc.gov.uk/api-documentation/docs/testing
|
344
|
+
# https://github.com/hmrc/vat-registered-companies-api/blob/master/public/api/conf/1.0/test-data/vrn.csv
|
345
|
+
subject(:result) { described_class.validate('GB123456789', uk: true) }
|
346
|
+
|
347
|
+
before do
|
348
|
+
stub_const('Valvat::Lookup::HMRC::ENDPOINT_URL', 'https://test-api.service.hmrc.gov.uk/organisations/vat/check-vat-number/lookup')
|
349
|
+
end
|
350
|
+
|
351
|
+
context 'with valid request with valid VAT number' do
|
352
|
+
it 'returns true' do
|
353
|
+
expect(described_class.validate('GB553557881', uk: true)).to be(true)
|
354
|
+
expect(described_class.validate('GB146295999727', uk: true)).to be(true)
|
355
|
+
end
|
356
|
+
end
|
265
357
|
|
358
|
+
context 'with valid request with an invalid VAT number' do
|
359
|
+
it 'returns false' do
|
360
|
+
expect(result).to be(false)
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
describe 'Error : MESSAGE_THROTTLED_OUT' do
|
266
365
|
before do
|
267
|
-
|
268
|
-
|
269
|
-
|
366
|
+
stub_request(:get, /test-api.service.hmrc.gov.uk/).to_return(
|
367
|
+
status: 429,
|
368
|
+
body: '{"code":"MESSAGE_THROTTLED_OUT"}'
|
369
|
+
)
|
270
370
|
end
|
271
371
|
|
272
372
|
it 'raises error' do
|
273
|
-
expect { result }.to raise_error(Valvat::
|
373
|
+
expect { result }.to raise_error(Valvat::RateLimitError, /MESSAGE_THROTTLED_OUT/)
|
274
374
|
end
|
275
375
|
|
276
376
|
it 'returns nil with raise_error set to false' do
|
277
|
-
expect(described_class.validate('
|
377
|
+
expect(described_class.validate('GB123456789', raise_error: false, uk: true)).to be_nil
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
describe 'Error : SCHEDULED_MAINTENANCE' do
|
382
|
+
before do
|
383
|
+
stub_request(:get, /test-api.service.hmrc.gov.uk/).to_return(
|
384
|
+
status: 503,
|
385
|
+
body: '{"code":"SCHEDULED_MAINTENANCE"}'
|
386
|
+
)
|
387
|
+
end
|
388
|
+
|
389
|
+
it 'returns nil' do
|
390
|
+
expect(result).to be_nil
|
391
|
+
end
|
392
|
+
|
393
|
+
it 'raises error with raise_error set to false' do
|
394
|
+
expect do
|
395
|
+
described_class.validate('GB123456789', raise_error: true, uk: true)
|
396
|
+
end.to raise_error(Valvat::ServiceUnavailable, 'The HMRC web service returned the error: SCHEDULED_MAINTENANCE')
|
397
|
+
end
|
398
|
+
end
|
399
|
+
|
400
|
+
describe 'Error : SERVER_ERROR' do
|
401
|
+
before do
|
402
|
+
stub_request(:get, /test-api.service.hmrc.gov.uk/).to_return(
|
403
|
+
status: 503,
|
404
|
+
body: '{"code":"SERVER_ERROR"}'
|
405
|
+
)
|
406
|
+
end
|
407
|
+
|
408
|
+
it 'returns nil' do
|
409
|
+
expect(result).to be_nil
|
410
|
+
end
|
411
|
+
|
412
|
+
it 'raises error with raise_error set to false' do
|
413
|
+
expect do
|
414
|
+
described_class.validate('GB123456789', raise_error: true, uk: true)
|
415
|
+
end.to raise_error(Valvat::ServiceUnavailable, 'The HMRC web service returned the error: SERVER_ERROR')
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
419
|
+
describe 'Error : GATEWAY_TIMEOUT' do
|
420
|
+
before do
|
421
|
+
stub_request(:get, /test-api.service.hmrc.gov.uk/).to_return(
|
422
|
+
status: 504,
|
423
|
+
body: '{"code":"GATEWAY_TIMEOUT"}'
|
424
|
+
)
|
425
|
+
end
|
426
|
+
|
427
|
+
it 'raises error' do
|
428
|
+
expect { result }.to raise_error(Valvat::Timeout, /GATEWAY_TIMEOUT/)
|
429
|
+
end
|
430
|
+
|
431
|
+
it 'returns nil with raise_error set to false' do
|
432
|
+
expect(described_class.validate('GB123456789', raise_error: false, uk: true)).to be_nil
|
433
|
+
end
|
434
|
+
end
|
435
|
+
|
436
|
+
describe 'Network timeout' do
|
437
|
+
before do
|
438
|
+
stub_request(:get, /test-api.service.hmrc.gov.uk/).to_timeout
|
439
|
+
end
|
440
|
+
|
441
|
+
it 'raises error' do
|
442
|
+
expect { result }.to raise_error(Net::OpenTimeout)
|
443
|
+
end
|
444
|
+
|
445
|
+
it 'also raises error with raise_error set to false (not handled)' do
|
446
|
+
expect do
|
447
|
+
described_class.validate('GB123456789', raise_error: false, uk: true)
|
448
|
+
end.to raise_error(Net::OpenTimeout)
|
449
|
+
end
|
450
|
+
end
|
451
|
+
|
452
|
+
describe 'Error : INTERNAL_SERVER_ERROR' do
|
453
|
+
before do
|
454
|
+
stub_request(:get, /test-api.service.hmrc.gov.uk/).to_return(
|
455
|
+
status: 500,
|
456
|
+
body: '{"code":"INTERNAL_SERVER_ERROR"}'
|
457
|
+
)
|
458
|
+
end
|
459
|
+
|
460
|
+
it 'raises error' do
|
461
|
+
expect { result }.to raise_error(Valvat::UnknownLookupError, /INTERNAL_SERVER_ERROR/)
|
462
|
+
end
|
463
|
+
|
464
|
+
it 'returns nil with raise_error set to false' do
|
465
|
+
expect(described_class.validate('GB123456789', raise_error: false, uk: true)).to be_nil
|
278
466
|
end
|
279
467
|
end
|
280
468
|
end
|
data/valvat.gemspec
CHANGED
@@ -20,10 +20,10 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.signing_key = File.expand_path('~/.ssh/gem-private_key.pem') if $PROGRAM_NAME =~ /gem\z/
|
21
21
|
s.required_ruby_version = '>= 2.5.0'
|
22
22
|
|
23
|
-
s.add_dependency 'savon', '>= 2.3.0'
|
24
|
-
|
25
23
|
s.add_development_dependency 'activemodel', '>= 5.0'
|
26
24
|
s.add_development_dependency 'rake'
|
27
25
|
s.add_development_dependency 'rspec', '~> 3.0'
|
26
|
+
s.add_development_dependency 'webmock', '~> 3.0'
|
27
|
+
|
28
28
|
s.metadata['rubygems_mfa_required'] = 'true'
|
29
29
|
end
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: valvat
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sebastian Munz
|
@@ -35,52 +35,52 @@ cert_chain:
|
|
35
35
|
BUdT7mtr41GgvWnIjaGWAldSuabxx5H+PKS5FzjNDMHThRZWuvYp/nP2RXDh4gIa
|
36
36
|
7hV09P+XxvS96G+petG5KmC/lev8VqKu
|
37
37
|
-----END CERTIFICATE-----
|
38
|
-
date: 2022-09-
|
38
|
+
date: 2022-09-30 00:00:00.000000000 Z
|
39
39
|
dependencies:
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
|
-
name:
|
41
|
+
name: activemodel
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
44
|
- - ">="
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version:
|
47
|
-
type: :
|
46
|
+
version: '5.0'
|
47
|
+
type: :development
|
48
48
|
prerelease: false
|
49
49
|
version_requirements: !ruby/object:Gem::Requirement
|
50
50
|
requirements:
|
51
51
|
- - ">="
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version:
|
53
|
+
version: '5.0'
|
54
54
|
- !ruby/object:Gem::Dependency
|
55
|
-
name:
|
55
|
+
name: rake
|
56
56
|
requirement: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
58
|
- - ">="
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: '
|
60
|
+
version: '0'
|
61
61
|
type: :development
|
62
62
|
prerelease: false
|
63
63
|
version_requirements: !ruby/object:Gem::Requirement
|
64
64
|
requirements:
|
65
65
|
- - ">="
|
66
66
|
- !ruby/object:Gem::Version
|
67
|
-
version: '
|
67
|
+
version: '0'
|
68
68
|
- !ruby/object:Gem::Dependency
|
69
|
-
name:
|
69
|
+
name: rspec
|
70
70
|
requirement: !ruby/object:Gem::Requirement
|
71
71
|
requirements:
|
72
|
-
- - "
|
72
|
+
- - "~>"
|
73
73
|
- !ruby/object:Gem::Version
|
74
|
-
version: '0'
|
74
|
+
version: '3.0'
|
75
75
|
type: :development
|
76
76
|
prerelease: false
|
77
77
|
version_requirements: !ruby/object:Gem::Requirement
|
78
78
|
requirements:
|
79
|
-
- - "
|
79
|
+
- - "~>"
|
80
80
|
- !ruby/object:Gem::Version
|
81
|
-
version: '0'
|
81
|
+
version: '3.0'
|
82
82
|
- !ruby/object:Gem::Dependency
|
83
|
-
name:
|
83
|
+
name: webmock
|
84
84
|
requirement: !ruby/object:Gem::Requirement
|
85
85
|
requirements:
|
86
86
|
- - "~>"
|
@@ -166,9 +166,9 @@ files:
|
|
166
166
|
- lib/valvat/locales/sv.yml
|
167
167
|
- lib/valvat/locales/tr.yml
|
168
168
|
- lib/valvat/lookup.rb
|
169
|
-
- lib/valvat/lookup/
|
170
|
-
- lib/valvat/lookup/
|
171
|
-
- lib/valvat/lookup/
|
169
|
+
- lib/valvat/lookup/base.rb
|
170
|
+
- lib/valvat/lookup/hmrc.rb
|
171
|
+
- lib/valvat/lookup/vies.rb
|
172
172
|
- lib/valvat/syntax.rb
|
173
173
|
- lib/valvat/utils.rb
|
174
174
|
- lib/valvat/version.rb
|
@@ -200,9 +200,8 @@ files:
|
|
200
200
|
- spec/valvat/checksum/se_spec.rb
|
201
201
|
- spec/valvat/checksum/si_spec.rb
|
202
202
|
- spec/valvat/checksum_spec.rb
|
203
|
-
- spec/valvat/lookup/
|
204
|
-
- spec/valvat/lookup/
|
205
|
-
- spec/valvat/lookup/response_spec.rb
|
203
|
+
- spec/valvat/lookup/hmrc_spec.rb
|
204
|
+
- spec/valvat/lookup/vies_spec.rb
|
206
205
|
- spec/valvat/lookup_spec.rb
|
207
206
|
- spec/valvat/syntax_spec.rb
|
208
207
|
- spec/valvat/utils_spec.rb
|
@@ -261,9 +260,8 @@ test_files:
|
|
261
260
|
- spec/valvat/checksum/se_spec.rb
|
262
261
|
- spec/valvat/checksum/si_spec.rb
|
263
262
|
- spec/valvat/checksum_spec.rb
|
264
|
-
- spec/valvat/lookup/
|
265
|
-
- spec/valvat/lookup/
|
266
|
-
- spec/valvat/lookup/response_spec.rb
|
263
|
+
- spec/valvat/lookup/hmrc_spec.rb
|
264
|
+
- spec/valvat/lookup/vies_spec.rb
|
267
265
|
- spec/valvat/lookup_spec.rb
|
268
266
|
- spec/valvat/syntax_spec.rb
|
269
267
|
- spec/valvat/utils_spec.rb
|
metadata.gz.sig
CHANGED
Binary file
|
data/lib/valvat/lookup/fault.rb
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class Valvat
|
4
|
-
class Lookup
|
5
|
-
class Fault < Response
|
6
|
-
def to_hash
|
7
|
-
@to_hash ||= case @raw
|
8
|
-
when Savon::HTTPError
|
9
|
-
{ error: HTTPError.new(nil, @raw) }
|
10
|
-
when Savon::UnknownOperationError
|
11
|
-
{ error: OperationUnknown.new(nil, @raw) }
|
12
|
-
else
|
13
|
-
soap_fault
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
FAULTS = {
|
18
|
-
'SERVICE_UNAVAILABLE' => ServiceUnavailable,
|
19
|
-
'MS_UNAVAILABLE' => MemberStateUnavailable,
|
20
|
-
'INVALID_REQUESTER_INFO' => InvalidRequester,
|
21
|
-
'TIMEOUT' => Timeout,
|
22
|
-
'VAT_BLOCKED' => BlockedError,
|
23
|
-
'IP_BLOCKED' => BlockedError,
|
24
|
-
'GLOBAL_MAX_CONCURRENT_REQ' => RateLimitError,
|
25
|
-
'GLOBAL_MAX_CONCURRENT_REQ_TIME' => RateLimitError,
|
26
|
-
'MS_MAX_CONCURRENT_REQ' => RateLimitError,
|
27
|
-
'MS_MAX_CONCURRENT_REQ_TIME' => RateLimitError
|
28
|
-
}.freeze
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
def soap_fault
|
33
|
-
fault = @raw.to_hash[:fault][:faultstring]
|
34
|
-
|
35
|
-
if fault == 'INVALID_INPUT'
|
36
|
-
{ valid: false }
|
37
|
-
else
|
38
|
-
error = (FAULTS[fault] || UnknownViesError).new(fault)
|
39
|
-
{ error: error }
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
@@ -1,57 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'savon'
|
4
|
-
|
5
|
-
class Valvat
|
6
|
-
class Lookup
|
7
|
-
class Request
|
8
|
-
VIES_WSDL_URL = 'https://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl'
|
9
|
-
|
10
|
-
def initialize(vat, options)
|
11
|
-
@vat = Valvat(vat)
|
12
|
-
@options = options || {}
|
13
|
-
@requester = @options[:requester] && Valvat(@options[:requester])
|
14
|
-
end
|
15
|
-
|
16
|
-
def perform
|
17
|
-
Response.new(
|
18
|
-
client.call(action, message: message, message_tag: message_tag, soap_action: nil)
|
19
|
-
)
|
20
|
-
rescue Savon::SOAPFault, Savon::HTTPError, Savon::UnknownOperationError => e
|
21
|
-
Fault.new(e)
|
22
|
-
end
|
23
|
-
|
24
|
-
private
|
25
|
-
|
26
|
-
def client
|
27
|
-
Savon::Client.new({
|
28
|
-
wsdl: VIES_WSDL_URL, log: false, follow_redirects: true
|
29
|
-
}.merge(@options[:savon] || {}))
|
30
|
-
end
|
31
|
-
|
32
|
-
def message
|
33
|
-
add_requester({
|
34
|
-
country_code: @vat.vat_country_code,
|
35
|
-
vat_number: @vat.to_s_wo_country
|
36
|
-
})
|
37
|
-
end
|
38
|
-
|
39
|
-
def message_tag
|
40
|
-
@requester ? :checkVatApprox : :checkVat
|
41
|
-
end
|
42
|
-
|
43
|
-
def action
|
44
|
-
@requester ? :check_vat_approx : :check_vat
|
45
|
-
end
|
46
|
-
|
47
|
-
def add_requester(message)
|
48
|
-
return message unless @requester
|
49
|
-
|
50
|
-
message[:requester_country_code] = @requester.vat_country_code
|
51
|
-
message[:requester_vat_number] = @requester.to_s_wo_country
|
52
|
-
|
53
|
-
message
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class Valvat
|
4
|
-
class Lookup
|
5
|
-
class Response
|
6
|
-
def initialize(raw)
|
7
|
-
@raw = raw
|
8
|
-
end
|
9
|
-
|
10
|
-
def [](key)
|
11
|
-
to_hash[key]
|
12
|
-
end
|
13
|
-
|
14
|
-
def to_hash
|
15
|
-
@to_hash ||= self.class.cleanup(@raw.to_hash)
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.cleanup(hash)
|
19
|
-
(
|
20
|
-
hash[:check_vat_approx_response] || hash[:check_vat_response] || {}
|
21
|
-
).each_with_object({}) do |(key, value), result|
|
22
|
-
result[cleanup_key(key)] = cleanup_value(value) unless key == :@xmlns
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
TRADER_PREFIX = /\Atrader_/.freeze
|
27
|
-
|
28
|
-
def self.cleanup_key(key)
|
29
|
-
key.to_s.sub(TRADER_PREFIX, '').to_sym
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.cleanup_value(value)
|
33
|
-
value == '---' ? nil : value
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|