valvat 1.0.0 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.github/workflows/ruby.yml +35 -0
  4. data/.gitignore +1 -0
  5. data/.rubocop.yml +15 -0
  6. data/CHANGES.md +29 -1
  7. data/Gemfile +2 -0
  8. data/Guardfile +6 -4
  9. data/README.md +10 -4
  10. data/Rakefile +3 -1
  11. data/certs/yolk.pem +21 -21
  12. data/gemfiles/activemodel-5 +1 -1
  13. data/gemfiles/activemodel-6 +1 -1
  14. data/lib/active_model/validations/valvat_validator.rb +65 -32
  15. data/lib/valvat/checksum/at.rb +3 -1
  16. data/lib/valvat/checksum/be.rb +3 -1
  17. data/lib/valvat/checksum/bg.rb +17 -17
  18. data/lib/valvat/checksum/cy.rb +2 -0
  19. data/lib/valvat/checksum/de.rb +5 -3
  20. data/lib/valvat/checksum/dk.rb +3 -1
  21. data/lib/valvat/checksum/ee.rb +2 -0
  22. data/lib/valvat/checksum/es.rb +14 -16
  23. data/lib/valvat/checksum/fi.rb +3 -1
  24. data/lib/valvat/checksum/fr.rb +4 -2
  25. data/lib/valvat/checksum/gb.rb +46 -31
  26. data/lib/valvat/checksum/gr.rb +4 -2
  27. data/lib/valvat/checksum/hr.rb +2 -0
  28. data/lib/valvat/checksum/hu.rb +2 -0
  29. data/lib/valvat/checksum/ie.rb +5 -6
  30. data/lib/valvat/checksum/it.rb +7 -5
  31. data/lib/valvat/checksum/lt.rb +2 -0
  32. data/lib/valvat/checksum/lu.rb +3 -1
  33. data/lib/valvat/checksum/mt.rb +2 -0
  34. data/lib/valvat/checksum/nl.rb +5 -3
  35. data/lib/valvat/checksum/pl.rb +3 -1
  36. data/lib/valvat/checksum/pt.rb +3 -1
  37. data/lib/valvat/checksum/ro.rb +2 -0
  38. data/lib/valvat/checksum/se.rb +5 -3
  39. data/lib/valvat/checksum/si.rb +4 -2
  40. data/lib/valvat/checksum.rb +24 -28
  41. data/lib/valvat/error.rb +5 -2
  42. data/lib/valvat/local.rb +8 -5
  43. data/lib/valvat/locales/de.yml +2 -1
  44. data/lib/valvat/locales/en.yml +2 -1
  45. data/lib/valvat/locales/es.yml +1 -0
  46. data/lib/valvat/locales/fr.yml +1 -0
  47. data/lib/valvat/locales/hu.yml +1 -0
  48. data/lib/valvat/locales/nl.yml +1 -0
  49. data/lib/valvat/locales/pl.yml +1 -0
  50. data/lib/valvat/locales/pt.yml +28 -28
  51. data/lib/valvat/lookup/fault.rb +17 -16
  52. data/lib/valvat/lookup/request.rb +21 -16
  53. data/lib/valvat/lookup/response.rb +11 -10
  54. data/lib/valvat/lookup.rb +5 -4
  55. data/lib/valvat/syntax.rb +31 -30
  56. data/lib/valvat/utils.rb +20 -9
  57. data/lib/valvat/version.rb +3 -1
  58. data/lib/valvat.rb +4 -2
  59. data/spec/active_model/validations/valvat_validator_spec.rb +119 -87
  60. data/spec/spec_helper.rb +8 -8
  61. data/spec/valvat/checksum/at_spec.rb +6 -4
  62. data/spec/valvat/checksum/be_spec.rb +6 -4
  63. data/spec/valvat/checksum/bg_spec.rb +7 -4
  64. data/spec/valvat/checksum/cy_spec.rb +3 -1
  65. data/spec/valvat/checksum/de_spec.rb +6 -4
  66. data/spec/valvat/checksum/dk_spec.rb +6 -4
  67. data/spec/valvat/checksum/ee_spec.rb +3 -1
  68. data/spec/valvat/checksum/es_spec.rb +7 -4
  69. data/spec/valvat/checksum/fi_spec.rb +6 -4
  70. data/spec/valvat/checksum/fr_spec.rb +6 -4
  71. data/spec/valvat/checksum/gb_spec.rb +4 -2
  72. data/spec/valvat/checksum/gr_spec.rb +6 -4
  73. data/spec/valvat/checksum/hr_spec.rb +3 -1
  74. data/spec/valvat/checksum/hu_spec.rb +3 -1
  75. data/spec/valvat/checksum/ie_spec.rb +8 -6
  76. data/spec/valvat/checksum/it_spec.rb +10 -8
  77. data/spec/valvat/checksum/lt_spec.rb +3 -1
  78. data/spec/valvat/checksum/lu_spec.rb +6 -4
  79. data/spec/valvat/checksum/mt_spec.rb +3 -1
  80. data/spec/valvat/checksum/nl_spec.rb +9 -7
  81. data/spec/valvat/checksum/pl_spec.rb +8 -6
  82. data/spec/valvat/checksum/pt_spec.rb +10 -11
  83. data/spec/valvat/checksum/ro_spec.rb +3 -1
  84. data/spec/valvat/checksum/se_spec.rb +8 -6
  85. data/spec/valvat/checksum/si_spec.rb +10 -8
  86. data/spec/valvat/checksum_spec.rb +24 -9
  87. data/spec/valvat/lookup/fault_spec.rb +34 -0
  88. data/spec/valvat/lookup/request_spec.rb +19 -0
  89. data/spec/valvat/lookup/response_spec.rb +29 -0
  90. data/spec/valvat/lookup_spec.rb +138 -153
  91. data/spec/valvat/syntax_spec.rb +59 -280
  92. data/spec/valvat/utils_spec.rb +77 -42
  93. data/spec/valvat_spec.rb +140 -152
  94. data/valvat.gemspec +17 -17
  95. data.tar.gz.sig +0 -0
  96. metadata +44 -47
  97. metadata.gz.sig +0 -0
  98. data/.travis.yml +0 -47
  99. data/gemfiles/activemodel-3-2 +0 -7
  100. data/gemfiles/activemodel-4 +0 -7
  101. data/gemfiles/before-ruby21/activemodel-3-2 +0 -8
  102. data/gemfiles/before-ruby21/activemodel-4 +0 -8
  103. data/gemfiles/before-ruby21/standalone +0 -7
  104. data/spec/valvat/lockup/fault_spec.rb +0 -32
  105. data/spec/valvat/lockup/request_spec.rb +0 -15
  106. data/spec/valvat/lockup/response_spec.rb +0 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9b64b4bcee899d80f3c9205b541eeaf7123df7560e47528368bedc0e06d85f85
4
- data.tar.gz: 31f18a7bf075a71c719002e3b34dd4a057da7ba85aeaf7283385d7ffc98f7dcb
3
+ metadata.gz: c16a7d36925ce61bf367e4770331dff3e41b76b5cfe21699f04379086e73d55b
4
+ data.tar.gz: bd011d1f238122ffe21ebfc882707e54de6e56a9fb97c90a2836d4e5d20ee189
5
5
  SHA512:
6
- metadata.gz: 2b419833c23922a653f932995541e25300a8897529cd3bfdea2078de762f5829451e35c1a658510cfbd64978f0f6165471d1331e1673d381ef5c0ecd6ca6380a
7
- data.tar.gz: e595829c058d7b2b89a644b779c4ea95c66eb9d416e395a4b32cf4d28f73bcb717f55c720fe51dd8d027092c94ae04b3c094cd1e7fbf1fe95d833330851a37d5
6
+ metadata.gz: 45c3632f628083f4113e90eef117cef893cc4a9742fbbfaacdffa2106c6585964949143af2591d0ad13c81a7657222d591a67119a3b4a1cc3c9e61a17765607a
7
+ data.tar.gz: 2ef6fe227f4726abbd3952befeabb82abffad26ce8f70e30da394956d14818208e45bd05a42870c68fc9d17b716c112fa304a16fbec12f9cf53fc7331d29c05d
checksums.yaml.gz.sig CHANGED
Binary file
@@ -0,0 +1,35 @@
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.5', '2.6', '2.7', '3.0', 'jruby-head', 'truffleruby-head']
21
+ gemfile: [ 'standalone', 'activemodel-5', 'activemodel-6' ]
22
+ exclude:
23
+ - ruby-version: '3.0'
24
+ gemfile: 'activemodel-5'
25
+
26
+ steps:
27
+ - uses: actions/checkout@v2
28
+ - name: Set up Ruby
29
+ uses: ruby/setup-ruby@v1
30
+ with:
31
+ ruby-version: ${{ matrix.ruby-version }}
32
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
33
+ - name: Run specs
34
+ run: |
35
+ bundle exec rspec
data/.gitignore CHANGED
@@ -6,3 +6,4 @@ gemfiles/*.lock
6
6
  tmp
7
7
  .rbenv-*
8
8
  .ruby-version
9
+ .ruby-gemset
data/.rubocop.yml ADDED
@@ -0,0 +1,15 @@
1
+ require: rubocop-rspec
2
+ AllCops:
3
+ NewCops: enable
4
+ TargetRubyVersion: 2.5
5
+
6
+ Metrics/BlockLength:
7
+ Exclude:
8
+ - valvat.gemspec
9
+ - spec/**/*_spec.rb
10
+
11
+ Style/Documentation:
12
+ Enabled: false
13
+
14
+ RSpec/MultipleExpectations:
15
+ Enabled: false
data/CHANGES.md CHANGED
@@ -1,7 +1,35 @@
1
1
 
2
2
  ### dev
3
3
 
4
- [full changelog](http://github.com/yolk/valvat/compare/v0.9.1...master)
4
+ [full changelog](http://github.com/yolk/valvat/compare/v1.1.2...master)
5
+
6
+ ### 1.1.0 / 2021-10-29
7
+
8
+ [full changelog](http://github.com/yolk/valvat/compare/v1.1.1...v1.1.2)
9
+
10
+ * Fixed SOAPAction error (#105) (by [Ľubo ](https://github.com/lubosch))
11
+
12
+ ### 1.1.0 / 2021-07-15
13
+
14
+ [full changelog](http://github.com/yolk/valvat/compare/v1.1.0...v1.1.1)
15
+
16
+ * Added support for italian VAT numbers with special province part (#104)
17
+
18
+ ### 1.1.0 / 2021-01-15
19
+
20
+ [full changelog](http://github.com/yolk/valvat/compare/v1.0.1...v1.1.0)
21
+
22
+ * Added support for Northern Ireland XI prefixed VAT numbers (by [Avatar Ignacy Kasperowicz](https://github.com/kspe))
23
+ * ActiveModel: Return specific error message if VIES is down and fail_if_down is set to true (by [Arkadiy Zabazhanov](https://github.com/pyromaniac))
24
+ * Removed support for EOL rubies (all before 2.5) and ActiveModel before 5.0
25
+
26
+ ### 1.0.1 / 2020-12-06
27
+
28
+ [full changelog](http://github.com/yolk/valvat/compare/v1.0.0...v1.0.1)
29
+
30
+ * Added missing spaces to malformatted portuegese locale file
31
+ * Removed GB from EU_COUNTRIES / EU_MEMBER_STATES but kept support
32
+ * Fixed typo in error message: UNK(N)OWN (by [Igor Gonchar](https://github.com/gigorok))
5
33
 
6
34
  ### 1.0.0 / 2020-11-06
7
35
 
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in valvat.gemspec
data/Guardfile CHANGED
@@ -1,5 +1,7 @@
1
- guard :rspec, cmd: "bundle exec rspec --color" do
2
- watch(/^spec\/(.*)_spec.rb/)
3
- watch(/^lib\/(.*)\.rb/) { |m| "spec/#{m[1]}_spec.rb" }
4
- watch(/^spec\/spec_helper.rb/) { "spec" }
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,10 +1,16 @@
1
1
  valvat
2
2
  ===========
3
3
 
4
- [![Gem Version](https://badge.fury.io/rb/valvat.svg)](http://badge.fury.io/rb/valvat) [![Build Status](https://travis-ci.org/yolk/valvat.svg)](https://travis-ci.org/yolk/valvat) [![Code Climate](https://codeclimate.com/github/yolk/valvat.svg)](https://codeclimate.com/github/yolk/valvat)
4
+ [![rubygems](https://badgen.net/rubygems/v/valvat)](https://rubygems.org/gems/valvat) [![Specs](https://github.com/yolk/valvat/workflows/Specs/badge.svg)](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
 
8
+ ## A note on Brexit
9
+
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
+
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
+
8
14
  ## Features
9
15
 
10
16
  * Simple syntax verification
@@ -14,7 +20,7 @@ Validates european vat numbers. Standalone or as a ActiveModel validator.
14
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.
15
21
  * *Experimental* checksum verification
16
22
 
17
- valvat is tested and works with ruby MRI 1.9.3/2.0/2.1/2.2/2.3/2.4/2.5/2.6/2.7, jruby (including 1.9 mode) and ActiveModel 3/4/5/6
23
+ valvat is tested and works with ruby MRI 2.5/2.6/2.7/3.0, jruby-head, truffleruby-head and ActiveModel 5/6. 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).
18
24
 
19
25
  ## Installation
20
26
 
@@ -22,7 +28,7 @@ Add it to your Gemfile:
22
28
 
23
29
  gem 'valvat'
24
30
 
25
- To use less memory (~3.5 mb vs. ~0.5 mb) and load only the local verification functionality – and not the remote lookup with VIES – add it like this instead:
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:
26
32
 
27
33
  gem 'valvat', require: 'valvat/local'
28
34
 
@@ -201,7 +207,7 @@ To allow vat numbers from outside of europe, add something like this to your mod
201
207
  validates :vat_number, valvat: true, if: :eu?
202
208
 
203
209
  def eu?
204
- Valvat::Utils::EU_COUNTRIES.include?(country_code)
210
+ Valvat::Utils::EU_MEMBER_STATES.include?(country_code)
205
211
  end
206
212
  end
207
213
 
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler'
2
4
  Bundler::GemHelper.install_tasks
3
5
 
@@ -5,4 +7,4 @@ require 'rspec/core/rake_task'
5
7
 
6
8
  RSpec::Core::RakeTask.new(:spec)
7
9
 
8
- task :default => :spec
10
+ task default: :spec
data/certs/yolk.pem CHANGED
@@ -1,25 +1,25 @@
1
1
  -----BEGIN CERTIFICATE-----
2
2
  MIIELDCCApSgAwIBAgIBATANBgkqhkiG9w0BAQsFADAgMR4wHAYDVQQDDBVzZWJh
3
- c3RpYW4vREM9eW8vREM9bGswHhcNMTkxMTE1MTIzMzUwWhcNMjAxMTE0MTIzMzUw
3
+ c3RpYW4vREM9eW8vREM9bGswHhcNMjEwMTA2MTAzMDU3WhcNMjIwMTA2MTAzMDU3
4
4
  WjAgMR4wHAYDVQQDDBVzZWJhc3RpYW4vREM9eW8vREM9bGswggGiMA0GCSqGSIb3
5
- DQEBAQUAA4IBjwAwggGKAoIBgQC96oQ16N6R0H69fWFfsfHo2oIJHtLgETPK6ly+
6
- tLeznJsZomCkZgFS0wNwnExr9qlH+AmygvNoaniVq/Pp2+2jwMuLgk5hkZMRM8Rf
7
- i3wp5LCbW4BysT1rURQoqfo4iH8d60WgUl2Ggou70RMGlizvgvGOfszxfRTkuNXd
8
- Eisbzs3UTKIWdx/umzHW4hbfbZcJ89cXoRLbxPjzozCfXPymmimlyva3Tu3QrxNH
9
- /IBdzni9qj6gctmTYgWHMwzRJz+yJBY7V3G7jss/3vWaAoOhLns5bJUAXOvNsR4D
10
- sWE5676q+Hi8Ti7B7AvWhqxB+9HSevjNrK+fNV7GFNRtbPW6o6vzYjPhtsdjluzP
11
- 94UA2AC6rjxtzNgzaXtQHZAnBjCf6ayoqbizh++SHU7J+tdoyxHjSfKPfdIW0P7Z
12
- W5npDb+b2kGTa6cclciBpRqyZWVz0CIgi06k+GuxgroQVf7465CEjyh2krQqGXtt
13
- A7d8gWiKsxpZgOjh5wFmFT97h8MCAwEAAaNxMG8wCQYDVR0TBAIwADALBgNVHQ8E
14
- BAMCBLAwHQYDVR0OBBYEFOGxpUkCn17xMxFtmn/CFk5W57s6MBoGA1UdEQQTMBGB
5
+ DQEBAQUAA4IBjwAwggGKAoIBgQC1KB7VOGa6pr926eaL2xCrnbnTxadpjq+6JoFj
6
+ 6rvDpmgD8wkdfU7aFTwBiEK9JKzhqCoW86Rt/8wOrEJRMXz1QBbpMBSrubtMB+0/
7
+ N59hKPLwgBkhbxY7BwGnujxnTICgiGzkhjlgBe/MisoabfK5Tn84GWVk5e0/LUp1
8
+ qTRkSgcaDlnKs2/dAUo1lXHa13TJeemgz76TYx4p4J2w7VGh7WS2ax5SNWKw+J+q
9
+ HVSHT2Chc+a7As2cJyU/r2jX0oqSfvyg09CmF0inUBykeiuB9aeP/Me29hvg13/D
10
+ r1gaQ3/Vyfuqjs8lrwIZCWLU607g5q3+UM884WWpvApsZwzajNM2+9l5jay7Dnan
11
+ m05PcDtMYbPHiMyvuN9Vp4YIRqSBXP/DPGMnIYXbpzAQgtZymPQ8I3k8doj9q4+E
12
+ 2Cf+x/nqvF09r/+gJj4ybzNW23zU6mhZ+xzBTDWrWBDetz+Y3wdbU5X6j08jLuEg
13
+ mMHmtgFdr/4VQxeaon7kHPR3DUsCAwEAAaNxMG8wCQYDVR0TBAIwADALBgNVHQ8E
14
+ BAMCBLAwHQYDVR0OBBYEFG8VE8+yijOldghb3w0MpSQnrslxMBoGA1UdEQQTMBGB
15
15
  D3NlYmFzdGlhbkB5by5sazAaBgNVHRIEEzARgQ9zZWJhc3RpYW5AeW8ubGswDQYJ
16
- KoZIhvcNAQELBQADggGBAEDGrRAAvS7w793sYSoE8VAt45pw71zio2BgdcpYRoHB
17
- rdaghjIVg77lybTmKdRGPM1T9m4zL01xddrqpgQFflVLmd/JVfEHwkLfJzZKvpy+
18
- 1vxgdIHhXkBB9G/X+LZC3PtMQx4f6BYIyf4kiVrTSWiKeeftFsH1tdvU5oYR7Gzy
19
- dugPR09J0oVA/DiLlzfUy9o2meH8QyCGX8c0LHY8gx4C4orZz+FIFZczZB1FUOeu
20
- LjR/yNUh7bYqwVHTQL5sajfQMFyt8HotazwdBvUETXGZW3VQZymR99gcMjr/H4xg
21
- mPEildrYsY7glEKryCc2YDYC1ahqWshnpOLqAXatonsoDBXpVKl+HGsUnrnCiaxh
22
- ctN4at+sy0CqPL+zXqp14b34rO0lP6hf0l+/LnuM96ImE+Rw+3gPX2iOtqivhrfM
23
- rAFNAD1QEGN6elQdy1MRuXwjcUhM8P8ofLDEaE225TSZvAI+XoCxW2PSsQj5cGER
24
- 9vbf6JSKzQPa/HeBoU0s1Q==
25
- -----END CERTIFICATE-----
16
+ KoZIhvcNAQELBQADggGBAIky67U9hnB8d4qMKwXHGb3Ne7JLvEigtEhjqGlDVecb
17
+ C94vQ8Jg7lYB3kKVjvFN2drptq/JUpxmAxPQIqfx39gKcKyv0BjkroVFE8MS1324
18
+ khMOZFOoSPMd9pkpm7oJ1M+sCYcUM+tPKnU8Ojq6r9j5b5XrbxG8YSpwahva3Vap
19
+ 1g0+3KzuWPpFjFen1VbS/Sb1cyE5uQtUj7lVcdhF3EFvzXkUMUUtJ4xsk114znFO
20
+ 986sKab5AjlJ7TnsmPphCv/UXans7rAVB2lnozlt/kw6dcct5JD4kz1tD6AmO5Qd
21
+ jWRuKNZs66GBglRvseKoypXz1XDCCu1m/uI1IGmKnq8Ry+IeRq9RnlvbfPvSxRIx
22
+ 9aowoL79T9plhcEcEX/KYRp8ht1z+3Vyk2UVZP8Xl5x+K44co5xdhljYi1gtw0w8
23
+ KzzULF0bF9oNpXwBEamlH2myNb19u1W8ijobQ7Y19ca8UFHr5LI32ZW5Zlmep8je
24
+ vb+o07oLRx3t2T/EO4DZ1w==
25
+ -----END CERTIFICATE-----
@@ -1,6 +1,6 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gem "activemodel", "~> 5.2.0"
3
+ gem "activemodel", "~> 5.0"
4
4
 
5
5
  gem 'rack'
6
6
 
@@ -1,6 +1,6 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gem "activemodel", "~> 6.0.0"
3
+ gem "activemodel", "~> 6.0"
4
4
 
5
5
  gem 'rack'
6
6
 
@@ -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
- if options[:lookup]
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
- iso_country_code = iso_country_code_of(record)
28
- elsif vat.valid? && valid_checksum?(vat) && vat_exists?(vat)
29
- return
30
- end
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 = "eu" if iso_country_code.blank?
33
- record.errors.add(attribute, :invalid_vat,
34
- message: options[:message],
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]) || "").upcase
60
+ (record.send(options[:match_country]) || '').upcase
51
61
  end
52
62
 
53
- def valid_checksum?(vat)
54
- return true unless options[:checksum]
55
- vat.valid_checksum?
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 vat_exists?(vat)
59
- return true unless options[:lookup]
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.t(
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
- is_valid = vat.exists?(options[:lookup])
62
- return is_valid unless is_valid.nil?
63
- !options[:lookup][:fail_if_down]
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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Valvat
2
4
  module Checksum
3
5
  class AT < Base
@@ -11,4 +13,4 @@ class Valvat
11
13
  end
12
14
  end
13
15
  end
14
- end
16
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Valvat
2
4
  module Checksum
3
5
  class BE < Base
@@ -8,4 +10,4 @@ class Valvat
8
10
  end
9
11
  end
10
12
  end
11
- end
13
+ end
@@ -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
- return 0
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
- chk = figures.map do |fig|
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
- prod = 0
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
- prod = 0
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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Valvat
2
4
  module Checksum
3
5
  class CY < Base
@@ -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 == 0
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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Valvat
2
4
  module Checksum
3
5
  class DK < Base
@@ -15,4 +17,4 @@ class Valvat
15
17
  end
16
18
  end
17
19
  end
18
- end
20
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Valvat
2
4
  module Checksum
3
5
  class EE < Base
@@ -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(T R W A G M Y F P D X B N J Z S Q V H L C K E)
5
- NATURAL_PERSON_EXP = /\A([\d]{8}[ABCDEFGHJKLMNPQRSTVWXYZ]|[KLMXYZ][\d]{7}[ABCDEFGHJKLMNPQRSTVWXYZ])\Z/
6
- LEGAL_PERSON_CHARS = [false] + %w(A B C D E F G H I J)
7
- LEGAL_PERSON_EXP = /\A[NPQRSW][\d]{7}[ABCDEFGHIJ]\Z/
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
- if letter == 'X'
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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Valvat
2
4
  module Checksum
3
5
  class FI < Base
@@ -10,4 +12,4 @@ class Valvat
10
12
  end
11
13
  end
12
14
  end
13
- end
15
+ end
@@ -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