valvat 1.4.3 → 2.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1da1b318b333fae01f1ced9c79ff97f9ce37aafc15987a8627327477f22be2bf
4
- data.tar.gz: c9b79dd9166f95a8d70f36dba4da7949f80aa9d96f0a33da65f7ea88db951824
3
+ metadata.gz: 42c6f6cebfde595c408697bfd0fcad362e8978fb11b84e6c3f3e62d5942c8644
4
+ data.tar.gz: 10e1ca8684e582d0b94c87d2d559ce2fbaeb6977d888f717b3e64b7daa1246e2
5
5
  SHA512:
6
- metadata.gz: e29725fa2f5f04aa54aa729d58842c8800fb9115f4c31298c32614e244a1c8a9d992b8666ffea76012604ff27228549d0d4f20e3f2554edc87c687b74f8d7bdf
7
- data.tar.gz: 1ca1548dfd52ed9c1bfa32eae893b444f7093b187e0916802f94dfc9a39c999124057b266ce6f52c7738f88a078cbfd4f3751e39a1aa5db1747d89fd39476175
6
+ metadata.gz: 03b6d77c886adb21ee7c2b03cb07c11c44f5ec69ad504e390408c38a04e876476e8acaa87d64f6332a137c045bd1dbecfd9d0b2ddbf22111efd80caec58e161b
7
+ data.tar.gz: 6f0fc3387f1761f387de1c3ff3168018bc12872711f44369d2528033301e4e77396e69aaaa5f0229903079297048d8a4cd7d6defc3c204798364e42c53c506e3
checksums.yaml.gz.sig CHANGED
Binary file
@@ -7,7 +7,7 @@ class Valvat
7
7
  # Configuration options should be set by passing a hash:
8
8
  #
9
9
  # Valvat.configure(
10
- # uk: true
10
+ # uk: { client_id: '<client_id>', client_secret: '<client_secret>' }
11
11
  # )
12
12
  #
13
13
  def self.configure(options)
@@ -42,7 +42,15 @@ class Valvat
42
42
 
43
43
  # Use lookup via HMRC for VAT numbers from the UK
44
44
  # if set to false lookup will always return false for UK VAT numbers
45
- uk: false
45
+ # HMRC options:
46
+ # :client_id and :client_secret API credentials for OAuth 2.0 Authentication
47
+ # :sandbox Use sandboxed instead of production API (defaults to false)
48
+ # See more details https://developer.service.hmrc.gov.uk/api-documentation/docs/development-practices
49
+ #
50
+ uk: false,
51
+
52
+ # Rate limit for Lookup and HMRC authentication requests
53
+ rate_limit: 5
46
54
  }.freeze
47
55
 
48
56
  def self.initialize
@@ -53,8 +61,12 @@ class Valvat
53
61
  @data[key]
54
62
  end
55
63
 
64
+ def dig(*keys)
65
+ @data.dig(*keys)
66
+ end
67
+
56
68
  def configure(options)
57
- @data = @data.merge(Utils.deep_symbolize_keys(options))
69
+ @data = Utils.deep_merge(@data, Utils.deep_symbolize_keys(options))
58
70
  end
59
71
 
60
72
  def initialize
data/lib/valvat/error.rb CHANGED
@@ -31,4 +31,6 @@ class Valvat
31
31
  UnknownLookupError = Class.new(LookupError)
32
32
 
33
33
  HTTPError = Class.new(LookupError)
34
+
35
+ AuthorizationError = Class.new(LookupError)
34
36
  end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+ require 'json'
5
+
6
+ class Valvat
7
+ module HMRC
8
+ class AccessToken
9
+ Error = Class.new(StandardError)
10
+
11
+ PRODUCTION_ENDPOINT_URL = 'https://api.service.hmrc.gov.uk/oauth/token'
12
+ SANDBOX_ENDPOINT_URL = 'https://test-api.service.hmrc.gov.uk/oauth/token'
13
+ SCOPE = 'read:vat'
14
+ GRANT_TYPE = 'client_credentials'
15
+
16
+ def initialize(options = {})
17
+ uk_options = options[:uk].is_a?(Hash) ? options[:uk] : {}
18
+
19
+ @client_id = uk_options[:client_id].to_s
20
+ @client_secret = uk_options[:client_secret].to_s
21
+ @rate_limit = options[:rate_limit]
22
+ @endpoint_uri = URI(uk_options[:sandbox] ? SANDBOX_ENDPOINT_URL : PRODUCTION_ENDPOINT_URL)
23
+ end
24
+
25
+ def self.fetch(options = {})
26
+ new(options).fetch
27
+ end
28
+
29
+ def fetch(uri = @endpoint_uri, request_count = 0)
30
+ raise_if_invalid!
31
+
32
+ request = build_request(uri)
33
+ response = build_https.request(request)
34
+ handle_response!(response, request_count)
35
+ rescue Errno::ECONNRESET, IOError
36
+ raise if request_count > @rate_limit
37
+
38
+ fetch(uri, request_count + 1)
39
+ end
40
+
41
+ private
42
+
43
+ def raise_if_invalid!
44
+ raise Error, 'Client ID is missing' if @client_id.empty?
45
+ raise Error, 'Client secret is missing' if @client_secret.empty?
46
+ end
47
+
48
+ def build_request(uri)
49
+ request = Net::HTTP::Post.new(uri)
50
+ request['Content-Type'] = 'application/x-www-form-urlencoded'
51
+ request.body = build_body
52
+ request
53
+ end
54
+
55
+ def build_body
56
+ URI.encode_www_form(
57
+ scope: SCOPE,
58
+ grant_type: GRANT_TYPE,
59
+ client_id: @client_id,
60
+ client_secret: @client_secret
61
+ )
62
+ end
63
+
64
+ def build_https
65
+ https = Net::HTTP.new(@endpoint_uri.host, @endpoint_uri.port)
66
+ https.use_ssl = true
67
+ https
68
+ end
69
+
70
+ def parse_response!(response)
71
+ JSON.parse(response.read_body)
72
+ end
73
+
74
+ def parse_response_location(response)
75
+ URI.parse(response['Location'])
76
+ end
77
+
78
+ # See https://developer.service.hmrc.gov.uk/api-documentation/docs/authorisation/application-restricted-endpoints
79
+ def handle_response!(response, request_count)
80
+ if response.is_a?(Net::HTTPRedirection) && request_count < @rate_limit
81
+ fetch(parse_response_location(response), request_count + 1)
82
+ elsif response.code == '200'
83
+ # {"access_token":"<access_token>","token_type":"bearer","expires_in":14400,"scope":"read:vat"}
84
+ parse_response!(response)['access_token']
85
+ else
86
+ raise Error, "Failed to fetch access token: #{handle_response_error(response, request_count)}"
87
+ end
88
+ end
89
+
90
+ def handle_response_error(response, request_count)
91
+ if response.code.match?(/4\d\d/)
92
+ # For 4xx codes: {"error":"invalid_client","error_description":"invalid client id or secret"}
93
+ parse_response!(response)['error_description']
94
+ elsif request_count >= @rate_limit
95
+ 'rate limit exceeded'
96
+ else
97
+ response.read_body
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,34 @@
1
+ bg:
2
+ errors:
3
+ messages:
4
+ invalid_vat: не е валиден %{country_adjective} ДДС номер
5
+ valvat:
6
+ country_adjectives:
7
+ eu: европейски
8
+ at: австрийски
9
+ be: белгийски
10
+ bg: български
11
+ cy: кипърски
12
+ cz: чешки
13
+ de: германски
14
+ dk: датски
15
+ ee: естонски
16
+ es: испански
17
+ fi: финландски
18
+ fr: френски
19
+ gb: британски
20
+ gr: гръцки
21
+ hu: унгарски
22
+ ie: ирландски
23
+ it: италиански
24
+ lt: литовски
25
+ lu: люксембургски
26
+ lv: латвийски
27
+ mt: малтийски
28
+ nl: холандски
29
+ pl: полски
30
+ pt: португалски
31
+ ro: румънски
32
+ se: шведски
33
+ si: словенски
34
+ sk: словашки
@@ -0,0 +1,34 @@
1
+ ca:
2
+ errors:
3
+ messages:
4
+ invalid_vat: no és un número d'IVA intracomunitari %{country_adjective} vàlid
5
+ valvat:
6
+ country_adjectives:
7
+ eu: europeu
8
+ at: austríac
9
+ be: belga
10
+ bg: búlgar
11
+ cy: xipriota
12
+ cz: txec
13
+ de: alemany
14
+ dk: danès
15
+ ee: estoni
16
+ es: espanyol
17
+ fi: finlandés
18
+ fr: francès
19
+ gb: britànic
20
+ gr: grec
21
+ hu: hungarès
22
+ ie: irlandès
23
+ it: italià
24
+ lt: lituà
25
+ lu: luxemburguès
26
+ lv: letó
27
+ mt: maltès
28
+ nl: holandès
29
+ pl: polac
30
+ pt: portuguès
31
+ ro: rumanès
32
+ se: suec
33
+ si: eslovec
34
+ sk: eslovac
@@ -0,0 +1,34 @@
1
+ cs:
2
+ errors:
3
+ messages:
4
+ invalid_vat: "není platné %{country_adjective} DIČ"
5
+ valvat:
6
+ country_adjectives:
7
+ eu: evropské
8
+ at: rakouské
9
+ be: belgické
10
+ bg: bulharské
11
+ cy: kyperské
12
+ cz: české
13
+ de: německé
14
+ dk: dánské
15
+ ee: estonské
16
+ es: španělské
17
+ fi: finské
18
+ fr: francouzské
19
+ gb: britské
20
+ gr: řecké
21
+ hu: maďarské
22
+ ie: irské
23
+ it: italské
24
+ lt: litevské
25
+ lu: lucemburské
26
+ lv: lotyšské
27
+ mt: maltské
28
+ nl: nizozemské
29
+ pl: polské
30
+ pt: portugalské
31
+ ro: rumunské
32
+ se: švédské
33
+ si: slovinské
34
+ sk: slovenské
@@ -0,0 +1,34 @@
1
+ da:
2
+ errors:
3
+ messages:
4
+ invalid_vat: Er ikke et gyldigt %{country_adjective} moms-nummer
5
+ valvat:
6
+ country_adjectives:
7
+ eu: Europæisk
8
+ at: Østrigsk
9
+ be: Belgisk
10
+ bg: Bulgarsk
11
+ cy: Cypriotisk
12
+ cz: Tjekkisk
13
+ de: Tysk
14
+ dk: Dansk
15
+ ee: Estisk
16
+ es: Spansk
17
+ fi: Finsk
18
+ fr: Fransk
19
+ gb: Engelsk
20
+ gr: Græsk
21
+ hu: Ungarsk
22
+ ie: Irsk
23
+ it: Italiensk
24
+ lt: Litauisk
25
+ lu: Luxembourgsk
26
+ lv: Lettisk
27
+ mt: Maltesisk
28
+ nl: Nederlandsk
29
+ pl: Polsk
30
+ pt: Portugisisk
31
+ ro: Rumænsk
32
+ se: Svensk
33
+ si: Slovensk
34
+ sk: Slovakisk
@@ -0,0 +1,35 @@
1
+ de:
2
+ errors:
3
+ messages:
4
+ invalid_vat: "ist keine gültige %{country_adjective} USt-IdNr."
5
+ vies_down: "Die USt-IdNr. kann nicht überprüft werden: der VIES-Webservice ist nicht verfügbar. Bitte später noch einmal versuchen."
6
+ valvat:
7
+ country_adjectives:
8
+ eu: europäische
9
+ at: österreichische
10
+ be: belgische
11
+ bg: bulgarische
12
+ cy: zypriotische
13
+ cz: tschechische
14
+ de: deutsche
15
+ dk: dänische
16
+ ee: estnische
17
+ es: spanische
18
+ fi: finnische
19
+ fr: französische
20
+ gb: britische
21
+ gr: griechische
22
+ hu: ungarische
23
+ ie: irische
24
+ it: italienische
25
+ lt: litauische
26
+ lu: luxemburgische
27
+ lv: lettische
28
+ mt: maltesische
29
+ nl: niederländische
30
+ pl: polnische
31
+ pt: portugiesische
32
+ ro: rumänische
33
+ se: schwedische
34
+ si: slowenische
35
+ sk: slowakische
@@ -0,0 +1,35 @@
1
+ en:
2
+ errors:
3
+ messages:
4
+ invalid_vat: "is not a valid %{country_adjective} VAT number"
5
+ vies_down: "Unable to validate your VAT number: the VIES service is down. Please try again later."
6
+ valvat:
7
+ country_adjectives:
8
+ eu: European
9
+ at: Austrian
10
+ be: Belgian
11
+ bg: Bulgarian
12
+ cy: Cypriot
13
+ cz: Czech
14
+ de: German
15
+ dk: Danish
16
+ ee: Estonian
17
+ es: Spanish
18
+ fi: Finnish
19
+ fr: French
20
+ gb: British
21
+ gr: Greek
22
+ hu: Hungarian
23
+ ie: Irish
24
+ it: Italian
25
+ lt: Lithuanian
26
+ lu: Luxembourgian
27
+ lv: Latvian
28
+ mt: Maltese
29
+ nl: Dutch
30
+ pl: Polish
31
+ pt: Portuguese
32
+ ro: Romanian
33
+ se: Swedish
34
+ si: Slovenian
35
+ sk: Slovakian
@@ -0,0 +1,35 @@
1
+ es:
2
+ errors:
3
+ messages:
4
+ invalid_vat: no es un número de IVA intracomunitario %{country_adjective} válido
5
+ vies_down: "No se ha podido validar su número de IVA: El servicio VIES no está disponible, por favor inténtelo más tarde."
6
+ valvat:
7
+ country_adjectives:
8
+ eu: europeo
9
+ at: austriaco
10
+ be: belga
11
+ bg: búlgaro
12
+ cy: chipriota
13
+ cz: checo
14
+ de: alemán
15
+ dk: danés
16
+ ee: estonio
17
+ es: español
18
+ fi: finlandés
19
+ fr: francés
20
+ gb: británico
21
+ gr: griego
22
+ hu: húngaro
23
+ ie: irlandés
24
+ it: italiano
25
+ lt: lituano
26
+ lu: luxemburgués
27
+ lv: letón
28
+ mt: maltés
29
+ nl: holandés
30
+ pl: polaco
31
+ pt: portugués
32
+ ro: rumano
33
+ se: sueco
34
+ si: esloveno
35
+ sk: eslovaco
@@ -0,0 +1,34 @@
1
+ fi:
2
+ errors:
3
+ messages:
4
+ invalid_vat: ei ole kelvollinen %{country_adjective} alv-numero
5
+ valvat:
6
+ country_adjectives:
7
+ eu: eurooppalainen
8
+ at: itävaltalainen
9
+ be: belgialainen
10
+ bg: bulgarialainen
11
+ cy: kyproslainen
12
+ cz: tsekkiläinen
13
+ de: saksalainen
14
+ dk: tanskalainen
15
+ ee: virolainen
16
+ es: espanjalainen
17
+ fi: suomalainen
18
+ fr: ranskalainen
19
+ gb: brittiläinen
20
+ gr: kreikkalainen
21
+ hu: unkarilainen
22
+ ie: irlantilainen
23
+ it: italialainen
24
+ lt: liettualainen
25
+ lu: luxemburgilainen
26
+ lv: latvialainen
27
+ mt: maltalainen
28
+ nl: hollantilainen
29
+ pl: puolalainen
30
+ pt: portugalilainen
31
+ ro: romanialainen
32
+ se: ruotsalainen
33
+ si: slovenialainen
34
+ sk: slovakialainen
@@ -0,0 +1,34 @@
1
+ fr:
2
+ errors:
3
+ messages:
4
+ invalid_vat: "n’est pas un numéro de TVA %{country_adjective} valide"
5
+ vies_down: "Impossible de valider votre numéro de TVA : le service de validation VIES est indisponible. Merci de réessayer ultérieurement."
6
+ valvat:
7
+ country_adjectives:
8
+ eu: intracommunautaire
9
+ at: autrichien
10
+ be: belge
11
+ bg: bulgare
12
+ cy: chypriote
13
+ cz: tchèque
14
+ de: allemand
15
+ dk: danois
16
+ ee: estonien
17
+ es: espagnol
18
+ fi: finlandais
19
+ fr: français
20
+ gb: britannique
21
+ gr: grec
22
+ ie: irlandais
23
+ it: italien
24
+ lt: lituanien
25
+ lu: luxembourgeois
26
+ lv: letton
27
+ mt: maltais
28
+ nl: hollandais
29
+ pl: polonais
30
+ pt: portugais
31
+ ro: roumain
32
+ se: suédois
33
+ si: slovène
34
+ sk: slovaque
@@ -0,0 +1,35 @@
1
+ hu:
2
+ errors:
3
+ messages:
4
+ invalid_vat: a közösségi adószám %{country_adjective} helytelen
5
+ vies_down: "Az adószám ellenőrzése sikertelen: a VIES szolgáltatás nem elérhető. Kérjük próbálja újra később."
6
+ valvat:
7
+ country_adjectives:
8
+ eu: európai
9
+ at: osztrák
10
+ be: belga
11
+ bg: belga
12
+ cy: ciprus
13
+ cz: cseh
14
+ de: német
15
+ dk: dán
16
+ ee: észt
17
+ es: spanyol
18
+ fi: finn
19
+ fr: francia
20
+ gb: britt
21
+ gr: görög
22
+ hu: magyar
23
+ ie: ír
24
+ it: olasz
25
+ lt: litván
26
+ lu: luxemburgi
27
+ lv: lett
28
+ mt: máltai
29
+ nl: holland
30
+ pl: lengyel
31
+ pt: portugál
32
+ ro: román
33
+ se: svéd
34
+ si: szlovén
35
+ sk: szlovák
@@ -0,0 +1,34 @@
1
+ it:
2
+ errors:
3
+ messages:
4
+ invalid_vat: IVA non valido per %{country_adjective}
5
+ valvat:
6
+ country_adjectives:
7
+ eu: Europa
8
+ at: Austria
9
+ be: Belgio
10
+ bg: Bulgaria
11
+ cy: Cipro
12
+ cz: Repubblica Ceca
13
+ de: Germania
14
+ dk: Danimarca
15
+ ee: Estonia
16
+ es: Spagna
17
+ fi: Finlandia
18
+ fr: Francia
19
+ gb: Regno Unito
20
+ gr: Grecia
21
+ hu: Ungheria
22
+ ie: Irlanda
23
+ it: Italia
24
+ lt: Lituania
25
+ lu: Lussemburgo
26
+ lv: Lettonia
27
+ mt: Malta
28
+ nl: Paesi Bassi
29
+ pl: Polonia
30
+ pt: Portogallo
31
+ ro: Romania
32
+ se: Svezia
33
+ si: Slovenia
34
+ sk: Slovacchia
@@ -0,0 +1,34 @@
1
+ lv:
2
+ errors:
3
+ messages:
4
+ invalid_vat: nav derīgs %{country_adjective} PVN numurs
5
+ valvat:
6
+ country_adjectives:
7
+ eu: Eiropas
8
+ at: Austrijas
9
+ be: Beļģijas
10
+ bg: Bulgārijas
11
+ cy: Kipras
12
+ cz: Čehijas
13
+ de: Vācijas
14
+ dk: Dānijas
15
+ ee: Igaunijas
16
+ es: Spāņijas
17
+ fi: Somijas
18
+ fr: Francijas
19
+ gb: Lielbritānijas
20
+ gr: Grieķu
21
+ hu: Ungārijas
22
+ ie: Īrijas
23
+ it: Itālijas
24
+ lt: Lietuvas
25
+ lu: Luksemburgas
26
+ lv: Latvijas
27
+ mt: Maltas
28
+ nl: Holandiešu
29
+ pl: Polijas
30
+ pt: Portugāļu
31
+ ro: Rumānijas
32
+ se: Zviedrijas
33
+ si: Slovēnijas
34
+ sk: Slovāku
@@ -0,0 +1,34 @@
1
+ nb:
2
+ errors:
3
+ messages:
4
+ invalid_vat: Er ikke et gyldig %{country_adjective} momsnummer
5
+ valvat:
6
+ country_adjectives:
7
+ eu: Europeisk
8
+ at: Østerisk
9
+ be: Belgisk
10
+ bg: Bulgarsk
11
+ cy: Kypriotisk
12
+ cz: Tjekkisk
13
+ de: Tysk
14
+ dk: Dansk
15
+ ee: Estisk
16
+ es: Spansk
17
+ fi: Finsk
18
+ fr: Fransk
19
+ gb: Engelsk
20
+ gr: Gresk
21
+ hu: Ungarsk
22
+ ie: Irsk
23
+ it: Italiensk
24
+ lt: Litauisk
25
+ lu: Luxembourgsk
26
+ lv: Latvisk
27
+ mt: Maltesisk
28
+ nl: Nederlandsk
29
+ pl: Polsk
30
+ pt: Portugisisk
31
+ ro: Rumensk
32
+ se: Svensk
33
+ si: Slovensk
34
+ sk: Slovakisk
@@ -0,0 +1,35 @@
1
+ nl:
2
+ errors:
3
+ messages:
4
+ invalid_vat: is geen geldig %{country_adjective} btw nummer
5
+ vies_down: "We kunnen uw btw-nummer niet bevestigen: de VIES-service is momenteel niet beschikbaar. Probeer het later opnieuw."
6
+ valvat:
7
+ country_adjectives:
8
+ eu: Europees
9
+ at: Oostenrijks
10
+ be: Belgisch
11
+ bg: Bulgaars
12
+ cy: Cypriotisch
13
+ cz: Tsjechisch
14
+ de: Duits
15
+ dk: Deens
16
+ ee: Ests
17
+ es: Spaans
18
+ fi: Fins
19
+ fr: Frans
20
+ gb: Brits
21
+ gr: Grieks
22
+ hu: Hongaars
23
+ ie: Iers
24
+ it: Italiaans
25
+ lt: Litouws
26
+ lu: Luxemburgs
27
+ lv: Lets
28
+ mt: Maltees
29
+ nl: Nederlands
30
+ pl: Pools
31
+ pt: Portugees
32
+ ro: Roemeens
33
+ se: Zweeds
34
+ si: Sloveens
35
+ sk: Slowaaks
@@ -0,0 +1,35 @@
1
+ pl:
2
+ errors:
3
+ messages:
4
+ invalid_vat: nie jest prawidłowym %{country_adjective} numerem VAT
5
+ vies_down: "Nie można zweryfikować numeru VAT: serwis VIES nie działa. Spróbuj ponownie później."
6
+ valvat:
7
+ country_adjectives:
8
+ eu: europejskim
9
+ at: austriackim
10
+ be: belgijskim
11
+ bg: bułgarskim
12
+ cy: cypryjskim
13
+ cz: czeskim
14
+ de: niemieckim
15
+ dk: duńskim
16
+ ee: estońskim
17
+ es: hiszpańskim
18
+ fi: fińskim
19
+ fr: francuskim
20
+ gb: angielskim
21
+ gr: greckim
22
+ hu: węgierskim
23
+ ie: irlandzkim
24
+ it: włoskim
25
+ lt: litewskim
26
+ lu: luksemburskim
27
+ lv: łotewskim
28
+ mt: maltańskim
29
+ nl: holenderskim
30
+ pl: polskim
31
+ pt: portugalskim
32
+ ro: rumuńskim
33
+ se: szwedzkim
34
+ si: słoweńskim
35
+ sk: słowackim
@@ -0,0 +1,34 @@
1
+ pt:
2
+ errors:
3
+ messages:
4
+ invalid_vat: O NIF %{country_adjective} não é válido.
5
+ valvat:
6
+ country_adjectives:
7
+ eu: europeu
8
+ at: austríaco
9
+ be: belga
10
+ bg: búlgaro
11
+ cy: cipriota
12
+ cz: checo
13
+ de: alemão
14
+ dk: dinamarquês
15
+ ee: estónio
16
+ es: espanhol
17
+ fi: finlandês
18
+ fr: francês
19
+ gb: britânico
20
+ gr: grego
21
+ hu: húngaro
22
+ ie: irlandês
23
+ it: italiano
24
+ lt: lituano
25
+ lu: luxemburguês
26
+ lv: letão
27
+ mt: maltês
28
+ nl: holandês
29
+ pl: polaco
30
+ pt: português
31
+ ro: romeno
32
+ se: sueco
33
+ si: esloveno
34
+ sk: eslovaco
@@ -0,0 +1,34 @@
1
+ ro:
2
+ errors:
3
+ messages:
4
+ invalid_vat: TVA invalid pentru %{country_adjective}
5
+ valvat:
6
+ country_adjectives:
7
+ eu: Europa
8
+ at: Austria
9
+ be: Belgia
10
+ bg: Bulgaria
11
+ cy: Cipru
12
+ cz: Cehia
13
+ de: Germania
14
+ dk: Danemarca
15
+ ee: Estonia
16
+ es: Spania
17
+ fi: Finlanda
18
+ fr: Franta
19
+ gb: Marea Britanie
20
+ gr: Grecia
21
+ hu: Ungaria
22
+ ie: Irlanda
23
+ it: Italia
24
+ lt: Lituania
25
+ lu: Luxembourg
26
+ lv: Latvia
27
+ mt: Malta
28
+ nl: Olanda
29
+ pl: Polonia
30
+ pt: Portugalia
31
+ ro: Romania
32
+ se: Suedia
33
+ si: Slovenia
34
+ sk: Slovacia
@@ -0,0 +1,34 @@
1
+ sk:
2
+ errors:
3
+ messages:
4
+ invalid_vat: nie je platné %{country_adjective} IČ DPH
5
+ valvat:
6
+ country_adjectives:
7
+ eu: európske
8
+ at: rakúske
9
+ be: belgické
10
+ bg: bulharské
11
+ cy: cyperské
12
+ cz: české
13
+ de: nemecké
14
+ dk: dánske
15
+ ee: estónske
16
+ es: španielské
17
+ fi: fínske
18
+ fr: francúzske
19
+ gb: britské
20
+ gr: grécke
21
+ hu: maďarské
22
+ ie: írske
23
+ it: talianske
24
+ lt: litovské
25
+ lu: luxemburské
26
+ lv: lotyšské
27
+ mt: maltské
28
+ nl: holandské
29
+ pl: polské
30
+ pt: portugalské
31
+ ro: rumunské
32
+ se: švédske
33
+ si: slovinské
34
+ sk: slovenské
@@ -0,0 +1,34 @@
1
+ sv:
2
+ errors:
3
+ messages:
4
+ invalid_vat: är inte ett giltigt %{country_adjective} momsnummer
5
+ valvat:
6
+ country_adjectives:
7
+ eu: europeiskt
8
+ at: österrikiskt
9
+ be: belgiskt
10
+ bg: bulgariskt
11
+ cy: cypriotiskt
12
+ cz: tjeckiskt
13
+ de: tyskt
14
+ dk: danskt
15
+ ee: estniskt
16
+ es: spanskt
17
+ fi: finskt
18
+ fr: franskt
19
+ gb: brittiskt
20
+ gr: grekiskt
21
+ hu: ungerskt
22
+ ie: irländskt
23
+ it: italienskt
24
+ lt: litauiskt
25
+ lu: luxemburgskt
26
+ lv: lettiskt
27
+ mt: maltesiskt
28
+ nl: nederländskt
29
+ pl: polskt
30
+ pt: portugisiskt
31
+ ro: rumänskt
32
+ se: svenskt
33
+ si: slovenskt
34
+ sk: slovakiskt
@@ -0,0 +1,34 @@
1
+ tr:
2
+ errors:
3
+ messages:
4
+ invalid_vat: geçerli %{country_adjective} vergi numarası değil
5
+ valvat:
6
+ country_adjectives:
7
+ eu: Avrupa
8
+ at: Avusturya
9
+ be: Belçika
10
+ bg: Bulgaristan
11
+ cy: Kıbrıs
12
+ cz: Çek Cumhuriyeti
13
+ de: Almanya
14
+ dk: Danimarka
15
+ ee: Estonya
16
+ es: İspanya
17
+ fi: Finlandiya
18
+ fr: Fransa
19
+ gb: İngiltere
20
+ gr: Yunanistan
21
+ hu: Macaristan
22
+ ie: İrlanda
23
+ it: İtalya
24
+ lt: Litvanya
25
+ lu: Lüksenburg
26
+ lv: Letonya
27
+ mt: Malta
28
+ nl: Hollanda
29
+ pl: Polonya
30
+ pt: Portekiz
31
+ ro: Romanya
32
+ se: İsveç
33
+ si: Slovenya
34
+ sk: Slovakya
@@ -10,6 +10,7 @@ class Valvat
10
10
  @vat = Valvat(vat)
11
11
  @options = Valvat::Options(options)
12
12
  @requester = @options[:requester] && Valvat(@options[:requester])
13
+ @rate_limit = @options[:rate_limit]
13
14
  end
14
15
 
15
16
  def perform
@@ -40,13 +41,13 @@ class Valvat
40
41
  def fetch(uri, limit = 0)
41
42
  response = send_request(uri)
42
43
 
43
- if response == Net::HTTPRedirection && limit < 5
44
+ if response == Net::HTTPRedirection && limit < @rate_limit
44
45
  fetch(URI.parse(response['Location']), limit + 1)
45
46
  else
46
47
  response
47
48
  end
48
49
  rescue Errno::ECONNRESET, IOError
49
- raise if limit > 5
50
+ raise if limit > @rate_limit
50
51
 
51
52
  fetch(uri, limit + 1)
52
53
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'base'
4
+ require_relative '../hmrc/access_token'
4
5
  require 'net/http'
5
6
  require 'json'
6
7
  require 'time'
@@ -8,16 +9,19 @@ require 'time'
8
9
  class Valvat
9
10
  class Lookup
10
11
  class HMRC < Base
11
- ENDPOINT_URL = 'https://api.service.hmrc.gov.uk/organisations/vat/check-vat-number/lookup'
12
+ PRODUCTION_ENDPOINT_URL = 'https://api.service.hmrc.gov.uk/organisations/vat/check-vat-number/lookup'
13
+ SANDBOX_ENDPOINT_URL = 'https://test-api.service.hmrc.gov.uk/organisations/vat/check-vat-number/lookup'
12
14
  HEADERS = {
13
15
  # https://developer.service.hmrc.gov.uk/api-documentation/docs/reference-guide#versioning
14
- 'Accept' => 'application/vnd.hmrc.1.0+json'
16
+ 'Accept' => 'application/vnd.hmrc.2.0+json'
15
17
  }.freeze
16
18
 
17
19
  def perform
18
- return { valid: false } unless @options[:uk]
20
+ return { valid: false } unless @options[:uk].is_a?(Hash)
19
21
 
20
22
  parse(fetch(endpoint_uri).body)
23
+ rescue Valvat::HMRC::AccessToken::Error => e
24
+ { error: e }
21
25
  end
22
26
 
23
27
  private
@@ -25,11 +29,12 @@ class Valvat
25
29
  def endpoint_uri
26
30
  endpoint = "/#{@vat.to_s_wo_country}"
27
31
  endpoint += "/#{@requester.to_s_wo_country}" if @requester
28
- URI.parse(ENDPOINT_URL + endpoint)
32
+ endpoint_url = @options.dig(:uk, :sandbox) ? SANDBOX_ENDPOINT_URL : PRODUCTION_ENDPOINT_URL
33
+ URI.parse(endpoint_url + endpoint)
29
34
  end
30
35
 
31
36
  def build_request(uri)
32
- Net::HTTP::Get.new(uri.request_uri, HEADERS)
37
+ Net::HTTP::Get.new(uri.request_uri, build_headers!)
33
38
  end
34
39
 
35
40
  def parse(body)
@@ -72,7 +77,8 @@ class Valvat
72
77
  'SCHEDULED_MAINTENANCE' => ServiceUnavailable,
73
78
  'SERVER_ERROR' => ServiceUnavailable,
74
79
  'INVALID_REQUEST' => InvalidRequester,
75
- 'GATEWAY_TIMEOUT' => Timeout
80
+ 'GATEWAY_TIMEOUT' => Timeout,
81
+ 'INVALID_CREDENTIALS' => AuthorizationError
76
82
  }.freeze
77
83
 
78
84
  def build_fault(raw)
@@ -82,6 +88,14 @@ class Valvat
82
88
  exception = FAULTS[fault] || UnknownLookupError
83
89
  { error: exception.new("#{fault}#{raw['message'] ? " (#{raw['message']})" : ''}", self.class) }
84
90
  end
91
+
92
+ def build_headers!
93
+ HEADERS.merge('Authorization' => "Bearer #{fetch_access_token!}")
94
+ end
95
+
96
+ def fetch_access_token!
97
+ @fetch_access_token ||= Valvat::HMRC::AccessToken.fetch(@options)
98
+ end
85
99
  end
86
100
  end
87
101
  end
@@ -18,11 +18,26 @@ class Valvat
18
18
  @options[key] ||= @options[deprecated]
19
19
  end
20
20
  end
21
+
22
+ check_uk_key
21
23
  end
22
24
 
23
25
  def [](key)
24
26
  @options.key?(key) ? @options[key] : Valvat.config[key]
25
27
  end
28
+
29
+ def dig(*keys)
30
+ @options.dig(*keys).nil? ? Valvat.config.dig(*keys) : @options.dig(*keys)
31
+ end
32
+
33
+ private
34
+
35
+ def check_uk_key
36
+ return if @options[:uk] != true || silence
37
+
38
+ puts 'DEPRECATED: The option :uk is not allowed to be set to `true` anymore. ' \
39
+ 'Using the HMRC API requires authentication credentials.'
40
+ end
26
41
  end
27
42
 
28
43
  def self.Options(options)
data/lib/valvat/utils.rb CHANGED
@@ -45,5 +45,10 @@ class Valvat
45
45
  val.is_a?(Hash) ? deep_symbolize_keys(val) : val
46
46
  end
47
47
  end
48
+
49
+ def self.deep_merge(original_hash, hash_to_merge)
50
+ merger = proc { |_key, v1, v2| v1.is_a?(Hash) && v2.is_a?(Hash) ? v1.merge(v2, &merger) : v2 }
51
+ original_hash.merge(hash_to_merge, &merger)
52
+ end
48
53
  end
49
54
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Valvat
4
- VERSION = '1.4.3'
4
+ VERSION = '2.0.0'
5
5
  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.3
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sebastian Munz
@@ -34,7 +34,7 @@ cert_chain:
34
34
  4+Gn3/xNnr5M7CdCGOG96P+gnx508xxiuMas8SvHl0/WB4kFpSGTH3uKzFh9fF+I
35
35
  36KG/gudYiTEZqWbjFIh4jJceFclxM/L
36
36
  -----END CERTIFICATE-----
37
- date: 2024-07-11 00:00:00.000000000 Z
37
+ date: 2024-12-06 00:00:00.000000000 Z
38
38
  dependencies:
39
39
  - !ruby/object:Gem::Dependency
40
40
  name: rexml
@@ -42,7 +42,7 @@ dependencies:
42
42
  requirements:
43
43
  - - ">="
44
44
  - !ruby/object:Gem::Version
45
- version: 3.2.7
45
+ version: 3.3.6
46
46
  - - "<"
47
47
  - !ruby/object:Gem::Version
48
48
  version: 4.0.0
@@ -52,7 +52,7 @@ dependencies:
52
52
  requirements:
53
53
  - - ">="
54
54
  - !ruby/object:Gem::Version
55
- version: 3.2.7
55
+ version: 3.3.6
56
56
  - - "<"
57
57
  - !ruby/object:Gem::Version
58
58
  version: 4.0.0
@@ -93,7 +93,28 @@ files:
93
93
  - lib/valvat/checksum/si.rb
94
94
  - lib/valvat/configuration.rb
95
95
  - lib/valvat/error.rb
96
+ - lib/valvat/hmrc/access_token.rb
96
97
  - lib/valvat/local.rb
98
+ - lib/valvat/locales/bg.yml
99
+ - lib/valvat/locales/ca.yml
100
+ - lib/valvat/locales/cs.yml
101
+ - lib/valvat/locales/da.yml
102
+ - lib/valvat/locales/de.yml
103
+ - lib/valvat/locales/en.yml
104
+ - lib/valvat/locales/es.yml
105
+ - lib/valvat/locales/fi.yml
106
+ - lib/valvat/locales/fr.yml
107
+ - lib/valvat/locales/hu.yml
108
+ - lib/valvat/locales/it.yml
109
+ - lib/valvat/locales/lv.yml
110
+ - lib/valvat/locales/nb.yml
111
+ - lib/valvat/locales/nl.yml
112
+ - lib/valvat/locales/pl.yml
113
+ - lib/valvat/locales/pt.yml
114
+ - lib/valvat/locales/ro.yml
115
+ - lib/valvat/locales/sk.yml
116
+ - lib/valvat/locales/sv.yml
117
+ - lib/valvat/locales/tr.yml
97
118
  - lib/valvat/lookup.rb
98
119
  - lib/valvat/lookup/base.rb
99
120
  - lib/valvat/lookup/hmrc.rb
metadata.gz.sig CHANGED
Binary file