vat_validator 1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc ADDED
@@ -0,0 +1,59 @@
1
+ = Description
2
+
3
+ Use this plugin to validate VAT numbers for european countries.
4
+
5
+ = Usage
6
+
7
+ To validate a model field as a valid intracom VAT number :
8
+
9
+ validates :vat_number, :vat => true
10
+
11
+ It may be optional like this :
12
+
13
+ validates :vat_number, :vat => true, :allow_blank => true
14
+
15
+ If you want the VAT number's country to match another kind of country field, use
16
+ the 'country_method' option :
17
+
18
+ validates :vat_number, :vat => { :country_method => :my_method }
19
+
20
+ where it is supposed that your model has a method named 'my_method' which
21
+ returns the country ISO code you want to match. The available country codes
22
+ available for Europa are: DE, AT, BE, BG, CY, DK, ES, EE, FI, FR, EL, HU, IE,
23
+ IT, LV, LT, LU, MT, NL, PL, PT, GB, RO, SK, SI, SE and CZ.
24
+
25
+ Example :
26
+
27
+ class Invoice < ActiveRecord::Base
28
+ validates :vat_number, :vat => { :country_method => :country_code }
29
+
30
+ # Logic to return the country code
31
+ def country_code
32
+ case country.downcase
33
+ when 'belgium' then 'BE'
34
+ when 'france' then 'FR'
35
+ when 'sweden' then 'SE'
36
+ # ...
37
+ else nil
38
+ end
39
+ end
40
+ end
41
+
42
+ = Installation
43
+
44
+ In your project's Gemfile :
45
+
46
+ gem 'vat_validator'
47
+
48
+ = Tests
49
+
50
+ If you want to run the specs :
51
+
52
+ rake spec
53
+
54
+ = Credits
55
+
56
+ This plugin in released under MIT license by Aurélien Malisart (see MIT-LICENSE
57
+ file).
58
+
59
+ (c) http://aurelien.malisart.be
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'spec/rake/spectask'
4
+
5
+ desc "Run specs"
6
+ Spec::Rake::SpecTask.new do |t|
7
+ t.spec_files = Rake::FileList["spec/**/*_spec.rb"]
8
+ t.spec_opts = ["-c"]
9
+ end
10
+
11
+ task :default => :spec
@@ -0,0 +1,55 @@
1
+ require 'active_model'
2
+
3
+ module VatValidator
4
+
5
+ # Constants ------------------------------------------------------------------
6
+
7
+ VAT_PATTERNS = {
8
+ 'DE' => /\ADE[0-9]{9}\Z/, # Germany
9
+ 'AT' => /\AATU[0-9]{8}\Z/, # Austria
10
+ 'BE' => /\ABE[0-9]{10}\Z/, # Belgium
11
+ 'BG' => /\ABG[0-9]{9,10}\Z/, # Bulgaria
12
+ 'CY' => /\ACY[0-9]{8}[A-Z]\Z/, # Cyprus
13
+ 'DK' => /\ADK[0-9]{8}\Z/, # Denmark
14
+ 'ES' => /\AES[0-9]{9}\Z/, # Spain
15
+ 'EE' => /\AEE[0-9]{9}\Z/, # Estonia
16
+ 'FI' => /\AFI[0-9]{8}\Z/, # Finland
17
+ 'FR' => /\AFR[A-Z0-9]{2}[0-9]{9}\Z/, # France
18
+ 'EL' => /\AEL[0-9]{9}\Z/, # Greece
19
+ 'HU' => /\AHU[0-9]{8}\Z/, # Hungary
20
+ 'IE' => /\AIE([0-9][A-Z][0-9]{5}[A-Z]|[0-9]{7}[A-Z])\Z/, # Ireland
21
+ 'IT' => /\AIT[0-9]{11}\Z/, # Italy
22
+ 'LV' => /\ALV[0-9]{11}\Z/, # Latvia
23
+ 'LT' => /\ALT([0-9]{9}|[0-9]{12})\Z/, # Lithuania
24
+ 'LU' => /\ALU[0-9]{8}\Z/, # Luxembourg
25
+ 'MT' => /\AMT[0-9]{8}\Z/, # Malta
26
+ 'NL' => /\ANL[0-9]{9}[A-Z][0-9]{2}\Z/, # Netherlands
27
+ 'PL' => /\APL[0-9]{10}\Z/, # Poland
28
+ 'PT' => /\APT[0-9]{9}\Z/, # Portugal
29
+ 'GB' => /\AGB([0-9]{9}|[A-Z0-9]{2}[0-9]{3})\Z/, # United Kingdom
30
+ 'RO' => /\ARO[0-9]{9}\Z/, # Romania
31
+ 'SK' => /\ASK[0-9]{10}\Z/, # Slovakia
32
+ 'SI' => /\ASI[0-9]{8}\Z/, # Slovenia
33
+ 'SE' => /\ASE[0-9]{12}\Z/, # Sweden
34
+ 'CZ' => /\ACZ[0-9]{8,10}\Z/ # Czech Republic
35
+ }
36
+
37
+ # Classes --------------------------------------------------------------------
38
+
39
+ class VatValidator < ActiveModel::EachValidator
40
+ def validate_each(record, attribute, value)
41
+ if options[:country_method]
42
+ country_code = record.send(options[:country_method]).to_s
43
+ unless VAT_PATTERNS.has_key?(country_code) && value.to_s =~ VAT_PATTERNS[country_code]
44
+ record.errors.add(attribute, options[:message])
45
+ end
46
+ else
47
+ unless value =~ VAT_PATTERNS.values.detect { |p| value.to_s =~ p }
48
+ record.errors.add(attribute, options[:message])
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ ActiveModel::Validations.__send__(:include, VatValidator)
@@ -0,0 +1,49 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+ require 'active_model'
4
+
5
+ require File.dirname(__FILE__) + '/../lib/vat_validator.rb'
6
+
7
+ # Utils models =================================================================
8
+
9
+ class BaseTestModel
10
+ include ActiveModel::Serialization
11
+ include ActiveModel::Validations
12
+
13
+ attr_accessor :attributes
14
+
15
+ def initialize(attributes = {})
16
+ @attributes = attributes
17
+ end
18
+
19
+ def read_attribute_for_validation(key)
20
+ @attributes[key]
21
+ end
22
+ end
23
+
24
+ class Invoice < BaseTestModel
25
+ validates :vat_number, :vat => true
26
+ end
27
+
28
+ class OptionalVatInvoice < BaseTestModel
29
+ validates :vat_number, :vat => true, :allow_blank => true
30
+ end
31
+
32
+ class CountryCheckedInvoice < BaseTestModel
33
+ validates :vat_number, :vat => { :country_method => :country_code }
34
+
35
+ # Fake attribute accessor
36
+ def country
37
+ @attributes[:country]
38
+ end
39
+
40
+ # Logic to return the country code
41
+ def country_code
42
+ case country.downcase
43
+ when 'belgium' then 'BE'
44
+ when 'france' then 'FR'
45
+ when 'sweden' then 'SE'
46
+ else nil
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,345 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Invoice do
4
+
5
+ # DE
6
+
7
+ it "should validate well a DE vat number" do
8
+ Invoice.new(:vat_number => "DE345889003").should be_valid
9
+
10
+ Invoice.new(:vat_number => "DE34588900").should_not be_valid
11
+ Invoice.new(:vat_number => "DE3458890090").should_not be_valid
12
+ Invoice.new(:vat_number => "DE34588900C").should_not be_valid
13
+ end
14
+
15
+ # AT
16
+
17
+ it "should validate well a AT vat number" do
18
+ Invoice.new(:vat_number => "ATU03458890").should be_valid
19
+
20
+ Invoice.new(:vat_number => "ATU034588908").should_not be_valid
21
+ Invoice.new(:vat_number => "ATU0345908").should_not be_valid
22
+ Invoice.new(:vat_number => "ATU0345889Y").should_not be_valid
23
+ end
24
+
25
+ # BE
26
+
27
+ it "should validate well a BE vat number" do
28
+ Invoice.new(:vat_number => "BE0817331995").should be_valid
29
+
30
+ Invoice.new(:vat_number => "BE081733199").should_not be_valid
31
+ Invoice.new(:vat_number => "BE08173319944").should_not be_valid
32
+ Invoice.new(:vat_number => "BE081733199H").should_not be_valid
33
+ end
34
+
35
+ # BG
36
+
37
+ it "should validate well a BG vat number" do
38
+ Invoice.new(:vat_number => "BG468134789").should be_valid
39
+ Invoice.new(:vat_number => "BG4681347897").should be_valid
40
+
41
+ Invoice.new(:vat_number => "BG46813478979").should_not be_valid
42
+ Invoice.new(:vat_number => "BG4681347897C").should_not be_valid
43
+ Invoice.new(:vat_number => "BG46813478G").should_not be_valid
44
+ Invoice.new(:vat_number => "BG46813478").should_not be_valid
45
+ end
46
+
47
+ # CY
48
+
49
+ it "should validate well a CY vat number" do
50
+ Invoice.new(:vat_number => "CY36579347A").should be_valid
51
+
52
+ Invoice.new(:vat_number => "CY36579347").should_not be_valid
53
+ Invoice.new(:vat_number => "CY365793478").should_not be_valid
54
+ Invoice.new(:vat_number => "CY365793G").should_not be_valid
55
+ end
56
+
57
+ # DK
58
+
59
+ it "should validate well a DK vat number" do
60
+ Invoice.new(:vat_number => "DK67893463").should be_valid
61
+
62
+ Invoice.new(:vat_number => "DK678934637").should_not be_valid
63
+ Invoice.new(:vat_number => "DK6789346").should_not be_valid
64
+ Invoice.new(:vat_number => "DK6789346H").should_not be_valid
65
+ end
66
+
67
+ # ES
68
+
69
+ it "should validate well a ES vat number" do
70
+ Invoice.new(:vat_number => "ES567345987").should be_valid
71
+ Invoice.new(:vat_number => "ES5673459879").should_not be_valid
72
+
73
+ Invoice.new(:vat_number => "ES56734598").should_not be_valid
74
+ Invoice.new(:vat_number => "ES56734598J").should_not be_valid
75
+ end
76
+
77
+ # EE
78
+
79
+ it "should validate well a EE vat number" do
80
+ Invoice.new(:vat_number => "EE678678456").should be_valid
81
+ Invoice.new(:vat_number => "EE6786784560").should_not be_valid
82
+ Invoice.new(:vat_number => "EE67867845").should_not be_valid
83
+ Invoice.new(:vat_number => "EE67867845K").should_not be_valid
84
+ end
85
+
86
+ # FI
87
+
88
+ it "should validate well a FI vat number" do
89
+ Invoice.new(:vat_number => "FI67845638").should be_valid
90
+
91
+ Invoice.new(:vat_number => "FI678456389").should_not be_valid
92
+ Invoice.new(:vat_number => "FI6784563").should_not be_valid
93
+ Invoice.new(:vat_number => "FI6784563K").should_not be_valid
94
+ end
95
+
96
+ # FR
97
+
98
+ it "should validate well a FR vat number" do
99
+ Invoice.new(:vat_number => "FR99123543267").should be_valid
100
+ Invoice.new(:vat_number => "FRBB123543267").should be_valid
101
+ Invoice.new(:vat_number => "FR9B123543267").should be_valid
102
+ Invoice.new(:vat_number => "FRB9123543267").should be_valid
103
+
104
+ Invoice.new(:vat_number => "FR99123543267B").should_not be_valid
105
+ Invoice.new(:vat_number => "FRBB12354326").should_not be_valid
106
+ Invoice.new(:vat_number => "FR9B123543F67").should_not be_valid
107
+ Invoice.new(:vat_number => "FRB9123543").should_not be_valid
108
+ end
109
+
110
+ # EL
111
+
112
+ it "should validate well a EL vat number" do
113
+ Invoice.new(:vat_number => "EL678456345").should be_valid
114
+
115
+ Invoice.new(:vat_number => "EL67845634").should_not be_valid
116
+ Invoice.new(:vat_number => "EL6784563459").should_not be_valid
117
+ Invoice.new(:vat_number => "EL67845634P").should_not be_valid
118
+ end
119
+
120
+ # HU
121
+
122
+ it "should validate well a HU vat number" do
123
+ Invoice.new(:vat_number => "HU67894595").should be_valid
124
+
125
+ Invoice.new(:vat_number => "HU6789459").should_not be_valid
126
+ Invoice.new(:vat_number => "HU67894595L").should_not be_valid
127
+ Invoice.new(:vat_number => "HU6789459J").should_not be_valid
128
+ end
129
+
130
+ # IE
131
+
132
+ it "should validate well a IE vat number" do
133
+ Invoice.new(:vat_number => "IE1B12345J").should be_valid
134
+ Invoice.new(:vat_number => "IE1234567B").should be_valid
135
+
136
+ Invoice.new(:vat_number => "IE1B123459").should_not be_valid
137
+ Invoice.new(:vat_number => "IE19123450").should_not be_valid
138
+ Invoice.new(:vat_number => "IEA9123450").should_not be_valid
139
+ end
140
+
141
+ # IT
142
+
143
+ it "should validate well a IT vat number" do
144
+ Invoice.new(:vat_number => "IT45875359285").should be_valid
145
+
146
+ Invoice.new(:vat_number => "IT458753592859").should_not be_valid
147
+ Invoice.new(:vat_number => "IT4587535928G").should_not be_valid
148
+ Invoice.new(:vat_number => "IT4587535928").should_not be_valid
149
+ end
150
+
151
+ # LV
152
+
153
+ it "should validate well a LV vat number" do
154
+ Invoice.new(:vat_number => "LV85678368906").should be_valid
155
+
156
+ Invoice.new(:vat_number => "LV8567836890").should_not be_valid
157
+ Invoice.new(:vat_number => "LV856783689066").should_not be_valid
158
+ Invoice.new(:vat_number => "LV8567836890S").should_not be_valid
159
+ end
160
+
161
+ # LT
162
+
163
+ it "should validate well a LT vat number" do
164
+ Invoice.new(:vat_number => "LT678678987").should be_valid
165
+ Invoice.new(:vat_number => "LT678678987956").should be_valid
166
+
167
+ Invoice.new(:vat_number => "LT67867898").should_not be_valid
168
+ Invoice.new(:vat_number => "LT6786789870").should_not be_valid
169
+ Invoice.new(:vat_number => "LT678678987K").should_not be_valid
170
+ Invoice.new(:vat_number => "LT67867898709").should_not be_valid
171
+ Invoice.new(:vat_number => "LT6786789870C").should_not be_valid
172
+ Invoice.new(:vat_number => "LT67867898795H").should_not be_valid
173
+ end
174
+
175
+ # LU
176
+
177
+ it "should validate well a LU vat number" do
178
+ Invoice.new(:vat_number => "LU45679456").should be_valid
179
+
180
+ Invoice.new(:vat_number => "LU4567945").should_not be_valid
181
+ Invoice.new(:vat_number => "LU456794560").should_not be_valid
182
+ Invoice.new(:vat_number => "LU4567945J").should_not be_valid
183
+ end
184
+
185
+ # MT
186
+
187
+ it "should validate well a MT vat number" do
188
+ Invoice.new(:vat_number => "MT64569367").should be_valid
189
+
190
+ Invoice.new(:vat_number => "MT6456936").should_not be_valid
191
+ Invoice.new(:vat_number => "MT645693679").should_not be_valid
192
+ Invoice.new(:vat_number => "MT6456936L").should_not be_valid
193
+ end
194
+
195
+ # NL
196
+
197
+ it "should validate well a NL vat number" do
198
+ Invoice.new(:vat_number => "NL673739491A77").should be_valid
199
+
200
+ Invoice.new(:vat_number => "NL673739491977").should_not be_valid
201
+ Invoice.new(:vat_number => "NL67373949197").should_not be_valid
202
+ Invoice.new(:vat_number => "NL67373949").should_not be_valid
203
+ end
204
+
205
+ # PL
206
+
207
+ it "should validate well a PL vat number" do
208
+ Invoice.new(:vat_number => "PL6784567284").should be_valid
209
+
210
+ Invoice.new(:vat_number => "PL678456728").should_not be_valid
211
+ Invoice.new(:vat_number => "PL67845672849").should_not be_valid
212
+ Invoice.new(:vat_number => "PL678456728K").should_not be_valid
213
+ end
214
+
215
+ # PT
216
+
217
+ it "should validate well a PT vat number" do
218
+ Invoice.new(:vat_number => "PT346296476").should be_valid
219
+
220
+ Invoice.new(:vat_number => "PT34629647").should_not be_valid
221
+ Invoice.new(:vat_number => "PT3462964769").should_not be_valid
222
+ end
223
+
224
+ # GB
225
+
226
+ it "should validate well a GB vat number" do
227
+ Invoice.new(:vat_number => "GB123456789").should be_valid
228
+ Invoice.new(:vat_number => "GBAB123").should be_valid
229
+ Invoice.new(:vat_number => "GBA0123").should be_valid
230
+ Invoice.new(:vat_number => "GB0B123").should be_valid
231
+ Invoice.new(:vat_number => "GB00123").should be_valid
232
+
233
+ Invoice.new(:vat_number => "GB12345678").should_not be_valid
234
+ Invoice.new(:vat_number => "GBAB1238").should_not be_valid
235
+ Invoice.new(:vat_number => "GBA0123L").should_not be_valid
236
+ Invoice.new(:vat_number => "GB0B12300").should_not be_valid
237
+ Invoice.new(:vat_number => "GB00123L").should_not be_valid
238
+ end
239
+
240
+ # RO
241
+
242
+ it "should validate well a RO vat number" do
243
+ Invoice.new(:vat_number => "RO856723965").should be_valid
244
+ end
245
+
246
+ # SK
247
+
248
+ it "should validate well a SK vat number" do
249
+ Invoice.new(:vat_number => "SK5683075682").should be_valid
250
+ end
251
+
252
+ # SI
253
+
254
+ it "should validate well a SI vat number" do
255
+ Invoice.new(:vat_number => "SI74357893").should be_valid
256
+ end
257
+
258
+ # SE
259
+
260
+ it "should validate well a SE vat number" do
261
+ Invoice.new(:vat_number => "SE567396352789").should be_valid
262
+ end
263
+
264
+ # CZ
265
+
266
+ it "should validate well a CZ vat number" do
267
+ Invoice.new(:vat_number => "CZ56389267").should be_valid
268
+ Invoice.new(:vat_number => "CZ563892670").should be_valid
269
+ Invoice.new(:vat_number => "CZ5638926790").should be_valid
270
+ end
271
+
272
+ # Blank
273
+
274
+ it "should not be valid if vat number is blank" do
275
+ Invoice.new(:vat_number => '').should_not be_valid
276
+ end
277
+
278
+ # Misc
279
+
280
+ it "should be invalid if really non-sense VAT number is passed" do
281
+ Invoice.new(:vat_number => '345678').should_not be_valid
282
+ Invoice.new(:vat_number => 'BE').should_not be_valid
283
+ Invoice.new(:vat_number => 'BEFR').should_not be_valid
284
+ Invoice.new(:vat_number => 'ZERTYU').should_not be_valid
285
+ Invoice.new(:vat_number => 'be817331995').should_not be_valid
286
+ Invoice.new(:vat_number => '&hczeà').should_not be_valid
287
+ end
288
+ end
289
+
290
+ describe OptionalVatInvoice do
291
+ it "should be valid if vat number is correct" do
292
+ OptionalVatInvoice.new(:vat_number => 'BE0817331995').should be_valid
293
+ end
294
+
295
+ it "should not be valid if vat number is incorrect" do
296
+ OptionalVatInvoice.new(:vat_number => 'BE081733199').should_not be_valid
297
+ end
298
+
299
+ it "should be valid if vat number is blank" do
300
+ OptionalVatInvoice.new(:vat_number => '').should be_valid
301
+ end
302
+ end
303
+
304
+ describe CountryCheckedInvoice do
305
+ it "should be valid if vat number is correct and matches country" do
306
+ CountryCheckedInvoice.new(
307
+ :vat_number => 'BE0817331995',
308
+ :country => 'Belgium'
309
+ ).should be_valid
310
+
311
+ CountryCheckedInvoice.new(
312
+ :vat_number => 'FRBB123543267',
313
+ :country => 'France'
314
+ ).should be_valid
315
+ end
316
+
317
+ it "should not be valid if vat number is correct and does not match country" do
318
+ CountryCheckedInvoice.new(
319
+ :vat_number => 'BE0817331995',
320
+ :country => ''
321
+ ).should_not be_valid
322
+
323
+ CountryCheckedInvoice.new(
324
+ :vat_number => 'BE0817331995',
325
+ :country => 'France'
326
+ ).should_not be_valid
327
+
328
+ CountryCheckedInvoice.new(
329
+ :vat_number => 'BE0817331995',
330
+ :country => 'FunkyCountry'
331
+ ).should_not be_valid
332
+ end
333
+
334
+ it "should be valid if vat number is blank" do
335
+ CountryCheckedInvoice.new(
336
+ :vat_number => '',
337
+ :country => ''
338
+ ).should_not be_valid
339
+
340
+ CountryCheckedInvoice.new(
341
+ :vat_number => '',
342
+ :country => 'Belgium'
343
+ ).should_not be_valid
344
+ end
345
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vat_validator
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 0
8
+ version: "1.0"
9
+ platform: ruby
10
+ authors:
11
+ - "Aur\xC3\xA9lien Malisart"
12
+ autorequire:
13
+ bindir: bin
14
+ cert_chain: []
15
+
16
+ date: 2010-05-19 00:00:00 +02:00
17
+ default_executable:
18
+ dependencies: []
19
+
20
+ description: Validator for european countries VAT numbers for ActiveModel
21
+ email: aurelien.malisart@gmail.com
22
+ executables: []
23
+
24
+ extensions: []
25
+
26
+ extra_rdoc_files:
27
+ - README.rdoc
28
+ files:
29
+ - lib/vat_validator.rb
30
+ - spec/spec_helper.rb
31
+ - spec/vat_validator/validations_spec.rb
32
+ - README.rdoc
33
+ - Rakefile
34
+ has_rdoc: true
35
+ homepage: http://github.com/aurels/vat_validator
36
+ licenses: []
37
+
38
+ post_install_message:
39
+ rdoc_options: []
40
+
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ segments:
48
+ - 0
49
+ version: "0"
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ segments:
55
+ - 1
56
+ - 3
57
+ - 6
58
+ version: 1.3.6
59
+ requirements: []
60
+
61
+ rubyforge_project:
62
+ rubygems_version: 1.3.6
63
+ signing_key:
64
+ specification_version: 3
65
+ summary: Validator for european countries VAT numbers for ActiveModel
66
+ test_files: []
67
+