valvat 1.0.1 → 1.1.3
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 +41 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +15 -0
- data/CHANGES.md +27 -1
- data/Gemfile +2 -0
- data/Guardfile +6 -4
- data/README.md +6 -4
- data/Rakefile +3 -1
- data/certs/yolk.pem +25 -24
- data/gemfiles/activemodel-5 +1 -1
- data/gemfiles/activemodel-6 +1 -1
- data/gemfiles/{activemodel-3-2 → activemodel-7} +2 -2
- data/lib/active_model/validations/valvat_validator.rb +65 -32
- data/lib/valvat/checksum/at.rb +3 -1
- data/lib/valvat/checksum/be.rb +3 -1
- data/lib/valvat/checksum/bg.rb +17 -17
- data/lib/valvat/checksum/cy.rb +2 -0
- data/lib/valvat/checksum/de.rb +5 -3
- data/lib/valvat/checksum/dk.rb +3 -1
- data/lib/valvat/checksum/ee.rb +2 -0
- data/lib/valvat/checksum/es.rb +14 -16
- data/lib/valvat/checksum/fi.rb +3 -1
- data/lib/valvat/checksum/fr.rb +4 -2
- data/lib/valvat/checksum/gb.rb +46 -31
- data/lib/valvat/checksum/gr.rb +4 -2
- data/lib/valvat/checksum/hr.rb +2 -0
- data/lib/valvat/checksum/hu.rb +2 -0
- data/lib/valvat/checksum/ie.rb +5 -6
- data/lib/valvat/checksum/it.rb +7 -5
- data/lib/valvat/checksum/lt.rb +2 -0
- data/lib/valvat/checksum/lu.rb +3 -1
- data/lib/valvat/checksum/mt.rb +2 -0
- data/lib/valvat/checksum/nl.rb +5 -3
- data/lib/valvat/checksum/pl.rb +3 -1
- data/lib/valvat/checksum/pt.rb +3 -1
- data/lib/valvat/checksum/ro.rb +2 -0
- data/lib/valvat/checksum/se.rb +5 -3
- data/lib/valvat/checksum/si.rb +4 -2
- data/lib/valvat/checksum.rb +24 -28
- data/lib/valvat/error.rb +8 -2
- data/lib/valvat/local.rb +6 -4
- data/lib/valvat/locales/de.yml +2 -1
- data/lib/valvat/locales/en.yml +2 -1
- data/lib/valvat/locales/es.yml +1 -0
- data/lib/valvat/locales/fr.yml +1 -0
- data/lib/valvat/locales/hu.yml +1 -0
- data/lib/valvat/locales/nl.yml +1 -0
- data/lib/valvat/locales/pl.yml +1 -0
- data/lib/valvat/lookup/fault.rb +29 -21
- data/lib/valvat/lookup/request.rb +21 -16
- data/lib/valvat/lookup/response.rb +11 -10
- data/lib/valvat/lookup.rb +5 -4
- data/lib/valvat/syntax.rb +31 -30
- data/lib/valvat/utils.rb +12 -9
- data/lib/valvat/version.rb +3 -1
- data/lib/valvat.rb +4 -2
- data/spec/active_model/validations/valvat_validator_spec.rb +99 -93
- data/spec/spec_helper.rb +8 -8
- data/spec/valvat/checksum/at_spec.rb +6 -4
- data/spec/valvat/checksum/be_spec.rb +6 -4
- data/spec/valvat/checksum/bg_spec.rb +7 -4
- data/spec/valvat/checksum/cy_spec.rb +3 -1
- data/spec/valvat/checksum/de_spec.rb +6 -4
- data/spec/valvat/checksum/dk_spec.rb +6 -4
- data/spec/valvat/checksum/ee_spec.rb +3 -1
- data/spec/valvat/checksum/es_spec.rb +7 -4
- data/spec/valvat/checksum/fi_spec.rb +6 -4
- data/spec/valvat/checksum/fr_spec.rb +6 -4
- data/spec/valvat/checksum/gb_spec.rb +4 -2
- data/spec/valvat/checksum/gr_spec.rb +6 -4
- data/spec/valvat/checksum/hr_spec.rb +3 -1
- data/spec/valvat/checksum/hu_spec.rb +3 -1
- data/spec/valvat/checksum/ie_spec.rb +8 -6
- data/spec/valvat/checksum/it_spec.rb +10 -8
- data/spec/valvat/checksum/lt_spec.rb +3 -1
- data/spec/valvat/checksum/lu_spec.rb +6 -4
- data/spec/valvat/checksum/mt_spec.rb +3 -1
- data/spec/valvat/checksum/nl_spec.rb +9 -7
- data/spec/valvat/checksum/pl_spec.rb +8 -6
- data/spec/valvat/checksum/pt_spec.rb +10 -11
- data/spec/valvat/checksum/ro_spec.rb +3 -1
- data/spec/valvat/checksum/se_spec.rb +8 -6
- data/spec/valvat/checksum/si_spec.rb +10 -8
- data/spec/valvat/checksum_spec.rb +24 -9
- data/spec/valvat/lookup/fault_spec.rb +34 -0
- data/spec/valvat/lookup/request_spec.rb +32 -0
- data/spec/valvat/lookup/response_spec.rb +29 -0
- data/spec/valvat/lookup_spec.rb +171 -152
- data/spec/valvat/syntax_spec.rb +59 -280
- data/spec/valvat/utils_spec.rb +64 -47
- data/spec/valvat_spec.rb +140 -152
- data/valvat.gemspec +17 -17
- data.tar.gz.sig +1 -2
- metadata +48 -50
- metadata.gz.sig +0 -0
- data/.travis.yml +0 -47
- data/gemfiles/activemodel-4 +0 -7
- data/gemfiles/before-ruby21/activemodel-3-2 +0 -8
- data/gemfiles/before-ruby21/activemodel-4 +0 -8
- data/gemfiles/before-ruby21/standalone +0 -7
- data/spec/valvat/lockup/fault_spec.rb +0 -32
- data/spec/valvat/lockup/request_spec.rb +0 -15
- data/spec/valvat/lockup/response_spec.rb +0 -27
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 92de431f5777b0b5115169e30bac0233ce3d9047c1bc74b9d42fe02acb2b460d
|
|
4
|
+
data.tar.gz: 0146a80725a3dce432002a456b8e9f10e3a65ee5d36b27dac5c6d646dc48fa70
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b6d08a4d98163bd195d861c83a837042e93bfebe13606c0fce10a703bf702296eb406f75d39349e46e7078289b74d2779f511b3d3a77a49e4d4fb5e585fb01cc
|
|
7
|
+
data.tar.gz: c2190c0f729188281e4894fb1d7e2b4b771171215da07329b0fc92fcda8806f5ac8fe3d7d1eb2d2c1f1e941a06b3d3c22a975369d5617589702a86d727166d4b
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: Specs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ master ]
|
|
6
|
+
paths-ignore:
|
|
7
|
+
- 'README.md'
|
|
8
|
+
- 'CHANGES.md'
|
|
9
|
+
pull_request:
|
|
10
|
+
branches: [ master ]
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
test:
|
|
14
|
+
if: "!contains(github.event.head_commit.message, '[skip ci]')"
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps
|
|
17
|
+
BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}
|
|
18
|
+
strategy:
|
|
19
|
+
matrix:
|
|
20
|
+
ruby-version: ['2.6', '2.7', '3.0', '3.1', 'truffleruby-head', 'jruby-9.3.2.0']
|
|
21
|
+
gemfile: [ 'standalone', 'activemodel-5', 'activemodel-6', 'activemodel-7' ]
|
|
22
|
+
exclude:
|
|
23
|
+
- ruby-version: '3.0'
|
|
24
|
+
gemfile: 'activemodel-5'
|
|
25
|
+
- ruby-version: '3.1'
|
|
26
|
+
gemfile: 'activemodel-5'
|
|
27
|
+
- ruby-version: '2.6'
|
|
28
|
+
gemfile: 'activemodel-7'
|
|
29
|
+
- ruby-version: 'jruby-9.3.2.0'
|
|
30
|
+
gemfile: 'activemodel-7'
|
|
31
|
+
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@v2
|
|
34
|
+
- name: Set up Ruby
|
|
35
|
+
uses: ruby/setup-ruby@v1
|
|
36
|
+
with:
|
|
37
|
+
ruby-version: ${{ matrix.ruby-version }}
|
|
38
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
|
39
|
+
- name: Run specs
|
|
40
|
+
run: |
|
|
41
|
+
bundle exec rspec
|
data/.gitignore
CHANGED
data/.rubocop.yml
ADDED
data/CHANGES.md
CHANGED
|
@@ -1,7 +1,33 @@
|
|
|
1
1
|
|
|
2
2
|
### dev
|
|
3
3
|
|
|
4
|
-
[full changelog](http://github.com/yolk/valvat/compare/v1.
|
|
4
|
+
[full changelog](http://github.com/yolk/valvat/compare/v1.1.3...master)
|
|
5
|
+
|
|
6
|
+
### 1.1.3 / 2022-01-26
|
|
7
|
+
|
|
8
|
+
[full changelog](http://github.com/yolk/valvat/compare/v1.1.2...v1.1.3)
|
|
9
|
+
|
|
10
|
+
* Handle Savon::HTTPError and Savon::UnknownOperationError as ViesError and throw Valvat::HTTPError and Valvat::OperationUnknown instead.
|
|
11
|
+
|
|
12
|
+
### 1.1.2 / 2021-10-29
|
|
13
|
+
|
|
14
|
+
[full changelog](http://github.com/yolk/valvat/compare/v1.1.1...v1.1.2)
|
|
15
|
+
|
|
16
|
+
* Fixed SOAPAction error (#105) (by [Ľubo ](https://github.com/lubosch))
|
|
17
|
+
|
|
18
|
+
### 1.1.1 / 2021-07-15
|
|
19
|
+
|
|
20
|
+
[full changelog](http://github.com/yolk/valvat/compare/v1.1.0...v1.1.1)
|
|
21
|
+
|
|
22
|
+
* Added support for italian VAT numbers with special province part (#104)
|
|
23
|
+
|
|
24
|
+
### 1.1.0 / 2021-01-15
|
|
25
|
+
|
|
26
|
+
[full changelog](http://github.com/yolk/valvat/compare/v1.0.1...v1.1.0)
|
|
27
|
+
|
|
28
|
+
* Added support for Northern Ireland XI prefixed VAT numbers (by [Avatar Ignacy Kasperowicz](https://github.com/kspe))
|
|
29
|
+
* ActiveModel: Return specific error message if VIES is down and fail_if_down is set to true (by [Arkadiy Zabazhanov](https://github.com/pyromaniac))
|
|
30
|
+
* Removed support for EOL rubies (all before 2.5) and ActiveModel before 5.0
|
|
5
31
|
|
|
6
32
|
### 1.0.1 / 2020-12-06
|
|
7
33
|
|
data/Gemfile
CHANGED
data/Guardfile
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
watch(
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
guard :rspec, cmd: 'bundle exec rspec --color' do
|
|
4
|
+
watch(%r{^spec/(.*)_spec.rb})
|
|
5
|
+
watch(%r{^lib/(.*)\.rb}) { |m| "spec/#{m[1]}_spec.rb" }
|
|
6
|
+
watch(%r{^spec/spec_helper.rb}) { 'spec' }
|
|
5
7
|
end
|
data/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
valvat
|
|
2
2
|
===========
|
|
3
3
|
|
|
4
|
-
[](https://rubygems.org/gems/valvat) [](https://github.com/yolk/valvat/actions?query=workflow%3ASpecs)
|
|
5
5
|
|
|
6
6
|
Validates european vat numbers. Standalone or as a ActiveModel validator.
|
|
7
7
|
|
|
@@ -9,6 +9,8 @@ Validates european vat numbers. Standalone or as a ActiveModel validator.
|
|
|
9
9
|
|
|
10
10
|
Valvat supports validating VAT-IDs from the UK by syntax & checksum for now. Validation against the VIES web service will probably stop working (and return `false`) in 2021.
|
|
11
11
|
|
|
12
|
+
Northern Ireland received its own VAT number prefix - XI which is supported by VIES web service so any XI-prefixed VAT numbers should be validated as any EU VAT number.
|
|
13
|
+
|
|
12
14
|
## Features
|
|
13
15
|
|
|
14
16
|
* Simple syntax verification
|
|
@@ -18,7 +20,7 @@ Valvat supports validating VAT-IDs from the UK by syntax & checksum for now. Val
|
|
|
18
20
|
* I18n locales for language specific error messages in English, German, French, Spanish, Italian, Portuguese, Polish, Swedish, Dutch, Danish, Czech, Slovakian, Hungarian, Bulgarian, Romanian, Latvian, Catalan, Norwegian, and Finnish.
|
|
19
21
|
* *Experimental* checksum verification
|
|
20
22
|
|
|
21
|
-
valvat is tested and works with ruby MRI
|
|
23
|
+
valvat is tested and works with ruby MRI 2.6/2.7/3.0/3.1, jruby, truffleruby-head and ActiveModel 5/6/7. If you need support for ruby down to 1.9.3 and ActiveModel 3 and 4 use [v1.0.1](https://github.com/yolk/valvat/tree/v1.0.1).
|
|
22
24
|
|
|
23
25
|
## Installation
|
|
24
26
|
|
|
@@ -26,7 +28,7 @@ Add it to your Gemfile:
|
|
|
26
28
|
|
|
27
29
|
gem 'valvat'
|
|
28
30
|
|
|
29
|
-
To use less memory (~
|
|
31
|
+
To use less memory (~0.5 mb vs. ~3.5 mb) and load only the local verification functionality – and not the remote lookup with VIES – add it like this instead:
|
|
30
32
|
|
|
31
33
|
gem 'valvat', require: 'valvat/local'
|
|
32
34
|
|
|
@@ -256,7 +258,7 @@ https://github.com/yolk/valvat/graphs/contributors
|
|
|
256
258
|
|
|
257
259
|
## BlaBla
|
|
258
260
|
|
|
259
|
-
Copyright (c) 2011-
|
|
261
|
+
Copyright (c) 2011-2022 Yolk Sebastian Munz & Julia Soergel GbR
|
|
260
262
|
|
|
261
263
|
Beyond that, the implementation is licensed under the MIT License.
|
|
262
264
|
|
data/Rakefile
CHANGED
data/certs/yolk.pem
CHANGED
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
-----BEGIN CERTIFICATE-----
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
2
|
+
MIIEZDCCAsygAwIBAgIBATANBgkqhkiG9w0BAQsFADA8MRIwEAYDVQQDDAlzZWJh
|
|
3
|
+
c3RpYW4xEjAQBgoJkiaJk/IsZAEZFgJ5bzESMBAGCgmSJomT8ixkARkWAmxrMB4X
|
|
4
|
+
DTIyMDEyNjE4MjIxNFoXDTIzMDEyNjE4MjIxNFowPDESMBAGA1UEAwwJc2ViYXN0
|
|
5
|
+
aWFuMRIwEAYKCZImiZPyLGQBGRYCeW8xEjAQBgoJkiaJk/IsZAEZFgJsazCCAaIw
|
|
6
|
+
DQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAM8Gdm81LvuqMyJr9sO+KtJz+PhM
|
|
7
|
+
x75w6uc5q3J8sTHGhOtWJlXiBFf8gbBkxUsQwDMEEbJ+WV63oqq9InVBrMHg9FxH
|
|
8
|
+
415dC0UlCv5IjKij4N5OVRnUTZDoxXczVVscNFyQcRhJO1TqORw6uOF8gd/MVWl4
|
|
9
|
+
6gJapzkLBMTIaqRUVbX3hTJpiGc1RV2zJmLkkvBtJ+lzqza0bklXh52LLs2UpTc1
|
|
10
|
+
e5ADVoq9K09G5QXES/GlFMYerQbtdXl0KpUQugXtRFAOoOrFKQFLETZSDq80lC7p
|
|
11
|
+
+zN+wNOEAuHtJP7EZVk/gU8hEkSDMexW5NRndgeQb+N/JH8DIRBbhOytZbAo19Pq
|
|
12
|
+
LEZBucHheI0xstLWuIP+ktwa/rIWv5v4gv3JZ/4H3q6tGPHigLKneRmaXo3e6jna
|
|
13
|
+
RFDxQLXbJgI37qusk4Qyl/iBVSBZ+TABBvA/jPXnHdd29qkuMTXvWLIiBDM6H0+2
|
|
14
|
+
SUabsieR1CqNZs/6YLO7nQHwFudHqzo8OB4+3QIDAQABo3EwbzAJBgNVHRMEAjAA
|
|
15
|
+
MAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUfC99QRDzqEe0tw1Da+XR9u4dmjEwGgYD
|
|
16
|
+
VR0RBBMwEYEPc2ViYXN0aWFuQHlvLmxrMBoGA1UdEgQTMBGBD3NlYmFzdGlhbkB5
|
|
17
|
+
by5sazANBgkqhkiG9w0BAQsFAAOCAYEAwYCyAFFXgYXWgaO8vQEZoQSjp5v6g1v/
|
|
18
|
+
t9TcO8JmX6UqEgoRHsdxPEyCK9RroYIv7X5GDyJ12ZdiGpzCqJiBIC9Gz3cCWAbp
|
|
19
|
+
LtnkhO8SQbz5B0NMOvo4o6XnbAr+rhVihuJmf0zXInnm1KZW/Yi+4JNAebPqwF1S
|
|
20
|
+
VZ/2Dz2BtTuTFhqlHOGxV2NxcnZjFff9kfUOLwl/oNUKgBecsMP5aW74zSOmc2fO
|
|
21
|
+
3sykOkKf5mWSY/KSuaCmAP1Ou3UUXOQmxiPUW9SDAzhYGKS63yPMkzJAziDP9ewI
|
|
22
|
+
zmOE2OJr0NuCmH9ykqlJZU4wnmloCnE1+8kHCl4+76cgBnN5gnYnzUb4RDM3J4EI
|
|
23
|
+
Jdm7+JxQbgAP/HJ2C2ara+uwc9jwhw2s1b2+TPnVCZdh9uBttHWfk0wgDoeFwky1
|
|
24
|
+
BUdT7mtr41GgvWnIjaGWAldSuabxx5H+PKS5FzjNDMHThRZWuvYp/nP2RXDh4gIa
|
|
25
|
+
7hV09P+XxvS96G+petG5KmC/lev8VqKu
|
|
26
|
+
-----END CERTIFICATE-----
|
data/gemfiles/activemodel-5
CHANGED
data/gemfiles/activemodel-6
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'active_model'
|
|
2
4
|
require 'valvat/syntax'
|
|
3
5
|
require 'valvat/lookup'
|
|
@@ -6,16 +8,7 @@ module ActiveModel
|
|
|
6
8
|
module Validations
|
|
7
9
|
class ValvatValidator < EachValidator
|
|
8
10
|
def initialize(options)
|
|
9
|
-
|
|
10
|
-
options[:lookup] = if options[:lookup] == :fail_if_down
|
|
11
|
-
{fail_if_down: true}
|
|
12
|
-
elsif options[:lookup].is_a?(Hash)
|
|
13
|
-
options[:lookup]
|
|
14
|
-
else
|
|
15
|
-
{}
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
11
|
+
normalize_options(options)
|
|
19
12
|
super
|
|
20
13
|
end
|
|
21
14
|
|
|
@@ -23,44 +16,84 @@ module ActiveModel
|
|
|
23
16
|
vat = Valvat(value)
|
|
24
17
|
iso_country_code = vat.iso_country_code
|
|
25
18
|
|
|
26
|
-
if country_does_not_match?(record, iso_country_code)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
19
|
+
is_valid = if country_does_not_match?(record, iso_country_code)
|
|
20
|
+
iso_country_code = iso_country_code_of(record)
|
|
21
|
+
false
|
|
22
|
+
else
|
|
23
|
+
vat_valid?(vat)
|
|
24
|
+
end
|
|
31
25
|
|
|
32
|
-
iso_country_code =
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
country_adjective: I18n.t(
|
|
36
|
-
:"valvat.country_adjectives.#{iso_country_code.downcase}",
|
|
37
|
-
default: [:"valvat.country_adjectives.eu", "european"]
|
|
38
|
-
)
|
|
39
|
-
)
|
|
26
|
+
iso_country_code = 'eu' if iso_country_code.blank?
|
|
27
|
+
|
|
28
|
+
add_error(is_valid, record, attribute, iso_country_code)
|
|
40
29
|
end
|
|
41
30
|
|
|
42
31
|
private
|
|
43
32
|
|
|
33
|
+
def vat_valid?(vat)
|
|
34
|
+
vat.valid? && valid_checksum?(vat) && vat_exists?(vat)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def valid_checksum?(vat)
|
|
38
|
+
return true unless options[:checksum]
|
|
39
|
+
|
|
40
|
+
vat.valid_checksum?
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def vat_exists?(vat)
|
|
44
|
+
return true unless options[:lookup]
|
|
45
|
+
|
|
46
|
+
exists = vat.exists?(options[:lookup])
|
|
47
|
+
|
|
48
|
+
return true if exists.nil? && !options[:lookup][:fail_if_down]
|
|
49
|
+
|
|
50
|
+
exists
|
|
51
|
+
end
|
|
52
|
+
|
|
44
53
|
def country_does_not_match?(record, iso_country_code)
|
|
45
54
|
return false unless options[:match_country]
|
|
55
|
+
|
|
46
56
|
iso_country_code_of(record) != iso_country_code
|
|
47
57
|
end
|
|
48
58
|
|
|
49
59
|
def iso_country_code_of(record)
|
|
50
|
-
(record.send(options[:match_country]) ||
|
|
60
|
+
(record.send(options[:match_country]) || '').upcase
|
|
51
61
|
end
|
|
52
62
|
|
|
53
|
-
def
|
|
54
|
-
|
|
55
|
-
|
|
63
|
+
def add_error(is_valid, record, attribute, iso_country_code)
|
|
64
|
+
case is_valid
|
|
65
|
+
when false
|
|
66
|
+
add_invalid_vat_error(record, attribute, iso_country_code)
|
|
67
|
+
when nil
|
|
68
|
+
add_vies_down_error(record, attribute)
|
|
69
|
+
end
|
|
56
70
|
end
|
|
57
71
|
|
|
58
|
-
def
|
|
59
|
-
|
|
72
|
+
def add_invalid_vat_error(record, attribute, iso_country_code)
|
|
73
|
+
record.errors.add(attribute, :invalid_vat,
|
|
74
|
+
message: options[:message],
|
|
75
|
+
country_adjective: I18n.translate(
|
|
76
|
+
:"valvat.country_adjectives.#{iso_country_code.downcase}",
|
|
77
|
+
default: [:"valvat.country_adjectives.eu", 'european']
|
|
78
|
+
))
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def add_vies_down_error(record, attribute)
|
|
82
|
+
record.errors.add(attribute, :vies_down,
|
|
83
|
+
message: options[:vies_down_message])
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def normalize_options(options)
|
|
87
|
+
return unless options[:lookup]
|
|
60
88
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
89
|
+
options[:lookup] = case options[:lookup]
|
|
90
|
+
when :fail_if_down
|
|
91
|
+
{ fail_if_down: true }
|
|
92
|
+
when Hash
|
|
93
|
+
options[:lookup]
|
|
94
|
+
else
|
|
95
|
+
{}
|
|
96
|
+
end
|
|
64
97
|
end
|
|
65
98
|
end
|
|
66
99
|
end
|
data/lib/valvat/checksum/at.rb
CHANGED
data/lib/valvat/checksum/be.rb
CHANGED
data/lib/valvat/checksum/bg.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
class Valvat
|
|
2
4
|
module Checksum
|
|
3
5
|
class BG < Base
|
|
@@ -9,6 +11,7 @@ class Valvat
|
|
|
9
11
|
local_person_chk = check_digit_local_natural_person
|
|
10
12
|
|
|
11
13
|
return local_person_chk if given_check_digit == local_person_chk
|
|
14
|
+
|
|
12
15
|
check_digit_foreign_natural_person
|
|
13
16
|
end
|
|
14
17
|
|
|
@@ -19,43 +22,40 @@ class Valvat
|
|
|
19
22
|
end.inject(:+).modulo(11)
|
|
20
23
|
|
|
21
24
|
return chk if chk < 10
|
|
22
|
-
|
|
25
|
+
|
|
26
|
+
0
|
|
23
27
|
end
|
|
24
28
|
|
|
25
29
|
def check_digit_foreign_natural_person
|
|
26
30
|
weight = [21, 19, 17, 13, 11, 9, 7, 3, 1]
|
|
27
31
|
|
|
28
|
-
|
|
32
|
+
figures.map do |fig|
|
|
29
33
|
fig * weight.shift
|
|
30
34
|
end.inject(:+).modulo(10)
|
|
31
|
-
|
|
32
|
-
chk
|
|
33
35
|
end
|
|
34
36
|
|
|
35
37
|
def check_digit_legal_person
|
|
36
|
-
|
|
37
|
-
figures.each_with_index do |fig, index|
|
|
38
|
-
prod += (index + 1) * fig.to_i
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
chk = prod % 11
|
|
38
|
+
chk = build_prod % 11
|
|
42
39
|
|
|
43
40
|
if chk == 10
|
|
44
|
-
|
|
45
|
-
figures.each_with_index do |fig, index|
|
|
46
|
-
prod += (index + 3) * fig.to_i
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
chk = prod % 11
|
|
41
|
+
chk = build_prod(3) % 11
|
|
50
42
|
chk = 0 if chk == 10
|
|
51
43
|
end
|
|
52
44
|
|
|
53
45
|
chk
|
|
54
46
|
end
|
|
55
47
|
|
|
48
|
+
def build_prod(add = 1)
|
|
49
|
+
prod = 0
|
|
50
|
+
figures.each_with_index do |fig, index|
|
|
51
|
+
prod += (index + add) * fig.to_i
|
|
52
|
+
end
|
|
53
|
+
prod
|
|
54
|
+
end
|
|
55
|
+
|
|
56
56
|
def natural_person?
|
|
57
57
|
vat.to_s_wo_country.length == 10
|
|
58
58
|
end
|
|
59
59
|
end
|
|
60
60
|
end
|
|
61
|
-
end
|
|
61
|
+
end
|
data/lib/valvat/checksum/cy.rb
CHANGED
data/lib/valvat/checksum/de.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
class Valvat
|
|
2
4
|
module Checksum
|
|
3
5
|
class DE < Base
|
|
@@ -8,12 +10,12 @@ class Valvat
|
|
|
8
10
|
prod = M
|
|
9
11
|
figures.each do |fig|
|
|
10
12
|
sum = (prod + fig).modulo(M)
|
|
11
|
-
sum = M if sum
|
|
12
|
-
prod = (2*sum).modulo(N)
|
|
13
|
+
sum = M if sum.zero?
|
|
14
|
+
prod = (2 * sum).modulo(N)
|
|
13
15
|
end
|
|
14
16
|
chk = N - prod
|
|
15
17
|
chk == 10 ? 0 : chk
|
|
16
18
|
end
|
|
17
19
|
end
|
|
18
20
|
end
|
|
19
|
-
end
|
|
21
|
+
end
|
data/lib/valvat/checksum/dk.rb
CHANGED
data/lib/valvat/checksum/ee.rb
CHANGED
data/lib/valvat/checksum/es.rb
CHANGED
|
@@ -1,33 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
class Valvat
|
|
2
4
|
module Checksum
|
|
3
5
|
class ES < Base
|
|
4
|
-
NATURAL_PERSON_CHARS = %w
|
|
5
|
-
NATURAL_PERSON_EXP = /\A(
|
|
6
|
-
LEGAL_PERSON_CHARS = [false] + %w
|
|
7
|
-
LEGAL_PERSON_EXP = /\A[NPQRSW]
|
|
6
|
+
NATURAL_PERSON_CHARS = %w[T R W A G M Y F P D X B N J Z S Q V H L C K E].freeze
|
|
7
|
+
NATURAL_PERSON_EXP = /\A(\d{8}[ABCDEFGHJKLMNPQRSTVWXYZ]|[KLMXYZ]\d{7}[ABCDEFGHJKLMNPQRSTVWXYZ])\Z/.freeze
|
|
8
|
+
LEGAL_PERSON_CHARS = [false] + %w[A B C D E F G H I J]
|
|
9
|
+
LEGAL_PERSON_EXP = /\A[NPQRSW]\d{7}[ABCDEFGHIJ]\Z/.freeze
|
|
10
|
+
NIE_DIGIT_BY_LETTER = %w[X Y Z].freeze
|
|
8
11
|
|
|
9
12
|
def check_digit
|
|
10
13
|
natural_person? ? check_digit_natural_person : check_digit_legal_person
|
|
11
14
|
end
|
|
12
15
|
|
|
13
16
|
def check_digit_natural_person
|
|
14
|
-
nie_digit = nil
|
|
15
17
|
letter = vat.to_s_wo_country[0]
|
|
16
|
-
|
|
17
|
-
nie_digit = 0
|
|
18
|
-
elsif letter == 'Y'
|
|
19
|
-
nie_digit = 1
|
|
20
|
-
elsif letter == 'Z'
|
|
21
|
-
nie_digit = 2
|
|
22
|
-
end
|
|
18
|
+
nie_digit = NIE_DIGIT_BY_LETTER.index(letter)
|
|
23
19
|
NATURAL_PERSON_CHARS["#{nie_digit}#{figures_str}".to_i.modulo(23)]
|
|
24
20
|
end
|
|
25
21
|
|
|
26
22
|
def check_digit_legal_person
|
|
27
|
-
chk = 10 - sum_of_figures_for_at_es_it_se(true).modulo(10)
|
|
28
|
-
legal_foreign_person?
|
|
29
|
-
LEGAL_PERSON_CHARS[chk]
|
|
23
|
+
chk = 10 - sum_of_figures_for_at_es_it_se(reverse_ints: true).modulo(10)
|
|
24
|
+
if legal_foreign_person?
|
|
25
|
+
LEGAL_PERSON_CHARS[chk]
|
|
26
|
+
else
|
|
30
27
|
(chk == 10 ? 0 : chk)
|
|
28
|
+
end
|
|
31
29
|
end
|
|
32
30
|
|
|
33
31
|
def given_check_digit
|
|
@@ -52,4 +50,4 @@ class Valvat
|
|
|
52
50
|
end
|
|
53
51
|
end
|
|
54
52
|
end
|
|
55
|
-
end
|
|
53
|
+
end
|
data/lib/valvat/checksum/fi.rb
CHANGED
data/lib/valvat/checksum/fr.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
class Valvat
|
|
2
4
|
module Checksum
|
|
3
5
|
class FR < Base
|
|
@@ -5,10 +7,10 @@ class Valvat
|
|
|
5
7
|
siren = str_wo_country[2..-1].to_i
|
|
6
8
|
(12 + (3 * siren) % 97) % 97
|
|
7
9
|
end
|
|
8
|
-
|
|
10
|
+
|
|
9
11
|
def given_check_digit
|
|
10
12
|
str_wo_country[0..1].to_i
|
|
11
13
|
end
|
|
12
14
|
end
|
|
13
15
|
end
|
|
14
|
-
end
|
|
16
|
+
end
|