-
Notifications
You must be signed in to change notification settings - Fork 81
/
Copy pathvalvat_validator.rb
102 lines (79 loc) · 2.85 KB
/
valvat_validator.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# frozen_string_literal: true
require 'active_model'
require 'valvat/syntax'
require 'valvat/lookup'
module ActiveModel
module Validations
class ValvatValidator < EachValidator
def initialize(options)
normalize_options(options)
super
end
def validate_each(record, attribute, value)
vat = Valvat(value)
iso_country_code = vat.iso_country_code
is_valid = if country_does_not_match?(record, iso_country_code)
iso_country_code = iso_country_code_of(record)
false
else
vat_valid?(vat)
end
iso_country_code = 'eu' if iso_country_code.blank?
add_error(is_valid, record, attribute, iso_country_code)
end
private
def vat_valid?(vat)
vat.valid? && valid_checksum?(vat) && vat_exists?(vat)
end
def valid_checksum?(vat)
return true unless options[:checksum]
vat.valid_checksum?
end
def vat_exists?(vat)
return true unless options[:lookup]
exists = vat.exists?(options[:lookup])
return true if exists.nil? && !options[:lookup][:fail_if_down]
exists
end
def country_does_not_match?(record, iso_country_code)
return false unless options[:match_country]
iso_country_code_of(record) != iso_country_code
end
def iso_country_code_of(record)
(record.send(options[:match_country]) || '').upcase
end
def add_error(is_valid, record, attribute, iso_country_code)
case is_valid
when false
add_invalid_vat_error(record, attribute, iso_country_code)
when nil
add_vies_down_error(record, attribute)
end
end
def add_invalid_vat_error(record, attribute, iso_country_code)
record.errors.add(attribute, :invalid_vat,
message: options[:message],
country_adjective: I18n.translate(
:"valvat.country_adjectives.#{iso_country_code.downcase}",
default: [:'valvat.country_adjectives.eu', 'european']
))
end
def add_vies_down_error(record, attribute)
record.errors.add(attribute, :vies_down,
message: options[:vies_down_message])
end
def normalize_options(options)
return unless options[:lookup]
options[:lookup] = case options[:lookup]
when :fail_if_down
{ fail_if_down: true }
when Hash
options[:lookup]
else
{}
end
end
end
end
end
I18n.load_path += Dir["#{File.dirname(__FILE__)}/../../valvat/locales/*.yml"]