Last active
April 26, 2022 19:35
-
-
Save jarthod/865b52fa388bbad53da695aa92b4be2a to your computer and use it in GitHub Desktop.
EU VAT rates in ruby (2020) + online fetcher to verify/update rates.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module VAT | |
RATES = { | |
"AT" => 20.0, | |
"BE" => 21.0, | |
"BG" => 20.0, | |
"CY" => 19.0, | |
"CZ" => 21.0, | |
"DE" => 19.0, | |
"DK" => 25.0, | |
"EE" => 20.0, | |
"ES" => 21.0, | |
"FI" => 24.0, | |
"FR" => 20.0, | |
"GB" => 20.0, # not in online rates any more since Brexit | |
"GR" => 24.0, | |
"HR" => 25.0, | |
"HU" => 27.0, | |
"IE" => 23.0, | |
"IT" => 22.0, | |
"LT" => 21.0, | |
"LU" => 17.0, | |
"LV" => 21.0, | |
"MT" => 18.0, | |
"NL" => 21.0, | |
"PL" => 23.0, | |
"PT" => 23.0, | |
"RO" => 19.0, | |
"SE" => 25.0, | |
"SI" => 22.0, | |
"SK" => 20.0, | |
}.freeze | |
# updated twice a year - January & July | |
def self.online_rates | |
# https://github.com/VvanGemert/europe/blob/master/lib/europe/vat/rates.rb | |
require 'rexml/document' | |
require 'net/http' | |
resp = Net::HTTP.get_response(URI.parse('https://europa.eu/youreurope/business/taxation/vat/vat-rules-rates/index_en.htm')) | |
if resp.code.to_i == 200 | |
rates = {} | |
data = resp.body.scan(%r{\<tbody\>(.*)\<\/tbody\>}m).first.first.strip | |
xml = REXML::Document.new("<root>#{data}</root>") | |
xml.first.elements.each('tr') do |result| | |
next if result[3].nil? | |
country = result[3].text.strip | |
next if country == "" | |
rate = result[5].text | |
# converting to ISO 3166 | |
country = "GR" if country == "EL" | |
rates[country] = rate.to_f if country | |
end | |
rates | |
end | |
rescue Errno::ECONNRESET | |
nil | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rails_helper' | |
describe VAT do | |
it "uses ISO 3166-1 code" do | |
expect(VAT::RATES.keys).to match_array(ISO3166::Country.codes & VAT::RATES.keys) | |
expect(VAT::RATES['GB']).to be > 15 # GB instead of UK | |
expect(VAT::RATES['GR']).to be > 15 # GR instead of EL | |
end | |
it "matches countries gem rates" do | |
ISO3166::Country.codes.each do |code| | |
country = ISO3166::Country[code] | |
if country.in_eu? || code == "GB" | |
expect(VAT::RATES[code]).to eq country.vat_rates&.dig('standard') | |
else # Only care about Europe so far | |
expect(VAT::RATES[code]).to be_nil | |
end | |
end | |
end | |
it "matches online rates (+GB manually)", :requires_internet do | |
WebMock.allow_net_connect! | |
reference = VAT::online_rates | |
skip "Couldn't fetch online rates" if reference.nil? | |
expect(VAT::RATES).to eq(reference.merge("GB" => 20.0)) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment