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.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.github/workflows/ruby.yml +41 -0
  4. data/.gitignore +1 -0
  5. data/.rubocop.yml +15 -0
  6. data/CHANGES.md +27 -1
  7. data/Gemfile +2 -0
  8. data/Guardfile +6 -4
  9. data/README.md +6 -4
  10. data/Rakefile +3 -1
  11. data/certs/yolk.pem +25 -24
  12. data/gemfiles/activemodel-5 +1 -1
  13. data/gemfiles/activemodel-6 +1 -1
  14. data/gemfiles/{activemodel-3-2 → activemodel-7} +2 -2
  15. data/lib/active_model/validations/valvat_validator.rb +65 -32
  16. data/lib/valvat/checksum/at.rb +3 -1
  17. data/lib/valvat/checksum/be.rb +3 -1
  18. data/lib/valvat/checksum/bg.rb +17 -17
  19. data/lib/valvat/checksum/cy.rb +2 -0
  20. data/lib/valvat/checksum/de.rb +5 -3
  21. data/lib/valvat/checksum/dk.rb +3 -1
  22. data/lib/valvat/checksum/ee.rb +2 -0
  23. data/lib/valvat/checksum/es.rb +14 -16
  24. data/lib/valvat/checksum/fi.rb +3 -1
  25. data/lib/valvat/checksum/fr.rb +4 -2
  26. data/lib/valvat/checksum/gb.rb +46 -31
  27. data/lib/valvat/checksum/gr.rb +4 -2
  28. data/lib/valvat/checksum/hr.rb +2 -0
  29. data/lib/valvat/checksum/hu.rb +2 -0
  30. data/lib/valvat/checksum/ie.rb +5 -6
  31. data/lib/valvat/checksum/it.rb +7 -5
  32. data/lib/valvat/checksum/lt.rb +2 -0
  33. data/lib/valvat/checksum/lu.rb +3 -1
  34. data/lib/valvat/checksum/mt.rb +2 -0
  35. data/lib/valvat/checksum/nl.rb +5 -3
  36. data/lib/valvat/checksum/pl.rb +3 -1
  37. data/lib/valvat/checksum/pt.rb +3 -1
  38. data/lib/valvat/checksum/ro.rb +2 -0
  39. data/lib/valvat/checksum/se.rb +5 -3
  40. data/lib/valvat/checksum/si.rb +4 -2
  41. data/lib/valvat/checksum.rb +24 -28
  42. data/lib/valvat/error.rb +8 -2
  43. data/lib/valvat/local.rb +6 -4
  44. data/lib/valvat/locales/de.yml +2 -1
  45. data/lib/valvat/locales/en.yml +2 -1
  46. data/lib/valvat/locales/es.yml +1 -0
  47. data/lib/valvat/locales/fr.yml +1 -0
  48. data/lib/valvat/locales/hu.yml +1 -0
  49. data/lib/valvat/locales/nl.yml +1 -0
  50. data/lib/valvat/locales/pl.yml +1 -0
  51. data/lib/valvat/lookup/fault.rb +29 -21
  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 +12 -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 +99 -93
  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 +32 -0
  89. data/spec/valvat/lookup/response_spec.rb +29 -0
  90. data/spec/valvat/lookup_spec.rb +171 -152
  91. data/spec/valvat/syntax_spec.rb +59 -280
  92. data/spec/valvat/utils_spec.rb +64 -47
  93. data/spec/valvat_spec.rb +140 -152
  94. data/valvat.gemspec +17 -17
  95. data.tar.gz.sig +1 -2
  96. metadata +48 -50
  97. metadata.gz.sig +0 -0
  98. data/.travis.yml +0 -47
  99. data/gemfiles/activemodel-4 +0 -7
  100. data/gemfiles/before-ruby21/activemodel-3-2 +0 -8
  101. data/gemfiles/before-ruby21/activemodel-4 +0 -8
  102. data/gemfiles/before-ruby21/standalone +0 -7
  103. data/spec/valvat/lockup/fault_spec.rb +0 -32
  104. data/spec/valvat/lockup/request_spec.rb +0 -15
  105. data/spec/valvat/lockup/response_spec.rb +0 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6c35eea0081e4df97219ee215ea3321c8add02bc130c5b28488f1dca676765dc
4
- data.tar.gz: 4ba7b89f223d26d1ac9d967944d6c2e0dbea74c3c6066f1d69d0e2f42ba204c8
3
+ metadata.gz: 92de431f5777b0b5115169e30bac0233ce3d9047c1bc74b9d42fe02acb2b460d
4
+ data.tar.gz: 0146a80725a3dce432002a456b8e9f10e3a65ee5d36b27dac5c6d646dc48fa70
5
5
  SHA512:
6
- metadata.gz: ab9623bd1d680546ca7978751b6536b626d2d5cb9ae35240b5152d4e7c9512e99e025481bf0a844254e6ad14d3f1f320dbf54ab6901387e354b7682c45cb3c3c
7
- data.tar.gz: 79a69d5d148b86282f609d66bf053a1b14d4bd86621d7277a5f17d1d1df6c6fd5c9731cff4eca8c8bb9dde9f1265eef7ea03c60d2d66876b0f255d97a9596a6b
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
@@ -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,33 @@
1
1
 
2
2
  ### dev
3
3
 
4
- [full changelog](http://github.com/yolk/valvat/compare/v1.0.1...master)
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
@@ -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,7 +1,7 @@
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
 
@@ -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 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.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 (~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:
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-2020 Yolk Sebastian Munz & Julia Soergel GbR
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
@@ -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,26 @@
1
1
  -----BEGIN CERTIFICATE-----
2
- MIIELDCCApSgAwIBAgIBATANBgkqhkiG9w0BAQsFADAgMR4wHAYDVQQDDBVzZWJh
3
- c3RpYW4vREM9eW8vREM9bGswHhcNMjEwMTA2MTAzMDU3WhcNMjIwMTA2MTAzMDU3
4
- WjAgMR4wHAYDVQQDDBVzZWJhc3RpYW4vREM9eW8vREM9bGswggGiMA0GCSqGSIb3
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
- D3NlYmFzdGlhbkB5by5sazAaBgNVHRIEEzARgQ9zZWJhc3RpYW5AeW8ubGswDQYJ
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-----
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-----
@@ -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,7 +1,7 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gem "activemodel", "~> 3.2"
3
+ gem "activemodel", "~> 7.0"
4
4
 
5
- gem 'rack', '< 2'
5
+ gem 'rack'
6
6
 
7
7
  gemspec path: "../"
@@ -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.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
- 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