Skip to content

Instantly share code, notes, and snippets.

@FooBarWidget
Created June 4, 2012 10:30
Show Gist options
  • Save FooBarWidget/2867662 to your computer and use it in GitHub Desktop.
Save FooBarWidget/2867662 to your computer and use it in GitHub Desktop.
require 'thread'
begin
require 'soap/wsdlDriver'
rescue LoadError
require 'savon'
end
class VatUtils
SERVICE_URL = 'http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl'.freeze
VAT_FORMAT = /\A([A-Z]{2})([0-9A-Za-z\+\*\.]{2,12})\Z/.freeze
# Names must be consistent with the country_select plugin.
EU_MEMBER_STATES = [
'Austria',
'Belgium',
'Bulgaria',
'Cyprus',
'Czech Republic',
'Denmark',
'Estonia',
'Finland',
'France',
'Germany',
'Greece',
'Hungary',
'Ireland',
'Italy',
'Latvia',
'Lithuania',
'Luxembourg',
'Malta',
'Netherlands',
'Poland',
'Portugal',
'Romania',
'Slovakia',
'Slovenia',
'Spain',
'Sweden',
'United Kingdom'
].freeze
@@mutex = Mutex.new
@@vat_check_driver = nil
class InvalidFormatError < StandardError
end
# Any exception other than InvalidFormatError indicates that the service is down.
def self.check_vat_number(vat_number)
if vat_number =~ VAT_FORMAT
country_code = $1
number = $2
@@mutex.synchronize do
@@vat_check_driver ||= create_vat_check_driver
end
if @@vat_check_driver.respond_to?(:checkVat)
# TODO: is this thread-safe?
result = @@vat_check_driver.checkVat(
:countryCode => country_code,
:vatNumber => number)
return result.valid == "true"
else
result = @@vat_check_driver.request(:checkVat) do
soap.body = {
:countryCode => country_code,
:vatNumber => number
}
end
return result[:check_vat_response][:valid]
end
else
raise InvalidFormatError
end
end
def self.must_charge_vat?(country, vat_number)
# http://www.belastingdienst.nl/reken/diensten_in_en_uit_het_buitenland/
if country == 'Netherlands'
return true
else
if vat_number.present?
return false
else
return EU_MEMBER_STATES.include?(country)
end
end
end
private
def self.create_vat_check_driver
if defined?(SOAP)
return SOAP::WSDLDriverFactory.new(SERVICE_URL).create_rpc_driver
else
return Savon::Client.new(SERVICE_URL)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment