valvat 1.1.4 → 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.
@@ -1,38 +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
- fault = @raw.to_hash[:fault][:faultstring]
14
-
15
- if fault == 'INVALID_INPUT'
16
- { valid: false }
17
- else
18
- error = (FAULTS[fault] || UnknownViesError).new(fault)
19
- { error: error }
20
- end
21
- end
22
- end
23
-
24
- FAULTS = {
25
- 'SERVICE_UNAVAILABLE' => ServiceUnavailable,
26
- 'MS_UNAVAILABLE' => MemberStateUnavailable,
27
- 'INVALID_REQUESTER_INFO' => InvalidRequester,
28
- 'TIMEOUT' => Timeout,
29
- 'VAT_BLOCKED' => BlockedError,
30
- 'IP_BLOCKED' => BlockedError,
31
- 'GLOBAL_MAX_CONCURRENT_REQ' => RateLimitError,
32
- 'GLOBAL_MAX_CONCURRENT_REQ_TIME' => RateLimitError,
33
- 'MS_MAX_CONCURRENT_REQ' => RateLimitError,
34
- 'MS_MAX_CONCURRENT_REQ_TIME' => RateLimitError
35
- }.freeze
36
- end
37
- end
38
- 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
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe Valvat::Lookup::Fault do
6
- it "returns {valid: false} on fault 'INVALID_INPUT'" do
7
- expect(described_class.new({
8
- fault: { faultstring: 'INVALID_INPUT' }
9
- }).to_hash).to eql({ valid: false })
10
- end
11
-
12
- {
13
- 'SERVICE_UNAVAILABLE' => Valvat::ServiceUnavailable,
14
- 'MS_UNAVAILABLE' => Valvat::MemberStateUnavailable,
15
- 'INVALID_REQUESTER_INFO' => Valvat::InvalidRequester,
16
- 'TIMEOUT' => Valvat::Timeout,
17
- 'VAT_BLOCKED' => Valvat::BlockedError,
18
- 'IP_BLOCKED' => Valvat::BlockedError,
19
- 'GLOBAL_MAX_CONCURRENT_REQ' => Valvat::RateLimitError,
20
- 'GLOBAL_MAX_CONCURRENT_REQ_TIME' => Valvat::RateLimitError,
21
- 'MS_MAX_CONCURRENT_REQ' => Valvat::RateLimitError,
22
- 'MS_MAX_CONCURRENT_REQ_TIME' => Valvat::RateLimitError,
23
- 'ANYTHING ELSE' => Valvat::UnknownViesError,
24
- 'REALLY ANYTHING' => Valvat::UnknownViesError
25
- }.each do |fault, error|
26
- it "returns error on fault '#{fault}'" do
27
- expect(described_class.new({
28
- fault: { faultstring: fault }
29
- }).to_hash).to eql({
30
- error: error.new(fault)
31
- })
32
- end
33
- end
34
- end
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe Valvat::Lookup::Request do
6
- it 'returns Response on success' do
7
- response = described_class.new('IE6388047V', {}).perform
8
- expect(response).to be_a(Valvat::Lookup::Response)
9
-
10
- # Skip if VIES is down
11
- expect(response.to_hash[:name]).to eql('GOOGLE IRELAND LIMITED') unless response.is_a?(Valvat::Lookup::Fault)
12
- end
13
-
14
- it 'returns Fault on failure' do
15
- response = described_class.new('XC123123', {}).perform
16
- expect(response).to be_a(Valvat::Lookup::Fault)
17
- expect(response.to_hash).to eql({ valid: false })
18
- end
19
-
20
- context 'when Savon::UnknownOperationError is (wrongly) thrown' do
21
- before do
22
- dbl = double(Savon::Client)
23
- allow(Savon::Client).to receive(:new).and_return(dbl)
24
- allow(dbl).to receive(:call).and_raise(Savon::UnknownOperationError.new('from stub'))
25
- end
26
-
27
- it "does handle it like vies down" do
28
- response = described_class.new('IE6388047V', {}).perform
29
- expect(response.to_hash[:error]).to be_a(Valvat::OperationUnknown)
30
- end
31
- end
32
- end
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe Valvat::Lookup::Response do
6
- it 'removes @xmlns from :check_vat_response hash' do
7
- expect(described_class.new({
8
- check_vat_response: { :a => 1, :b => 2, :@xmlns => true }
9
- }).to_hash).to eql({ a: 1, b: 2 })
10
- end
11
-
12
- it "removes 'trader_'-Prefixes :check_vat_response hash" do
13
- expect(described_class.new({
14
- check_vat_response: { a: 1, trader_b: 2 }
15
- }).to_hash).to eql({ a: 1, b: 2 })
16
- end
17
-
18
- it 'accepts hash keyed as :check_vat_approx_response' do
19
- expect(described_class.new({
20
- check_vat_approx_response: { a: 1, b: 2 }
21
- }).to_hash).to eql({ a: 1, b: 2 })
22
- end
23
-
24
- it 'allows direct access to hash via []' do
25
- expect(described_class.new({
26
- check_vat_response: { a: 123, b: 2 }
27
- })[:a]).to be(123)
28
- end
29
- end