Module: Europe::Vat::Rates

Defined in:
lib/europe/vat/rates.rb

Overview

Rates

Constant Summary collapse

FALLBACK_RATES =
{
  AT: 20.0, BE: 21.0, BG: 20.0, CY: 19.0, CZ: 21.0, DE: 19.0, DK: 25.0, EE: 22.0,
  EL: 24.0, ES: 21.0, FI: 25.5, FR: 20.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: 23.0
}.freeze
RATES_URL =
'https://europa.eu/youreurope/business/taxation/vat' \
'/vat-rules-rates/index_en.htm'

Class Method Summary collapse

Class Method Details

.extract_rates(resp) ⇒ Object

rubocop:disable Metrics/MethodLength



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/europe/vat/rates.rb', line 26

def self.extract_rates(resp)
  rates = {}

  begin
    data = resp.scan(%r{\<tbody\>(.*)\<\/tbody\>}m).first.first.strip
  rescue NoMethodError
    return FALLBACK_RATES
  end

  xml = REXML::Document.new("<root>#{data}</root>")
  xml.first.elements.each('tr') do |result|
    next if result[3].nil?

    rates = filter_rate(result, rates || {})
  end
  rates
end

.fetch_ratesObject



54
55
56
57
# File 'lib/europe/vat/rates.rb', line 54

def self.fetch_rates
  resp = Net::HTTP.get_response(URI.parse(RATES_URL))
  resp.code.to_i == 200 ? resp.body : nil
end

.filter_rate(result, rates) ⇒ Object

rubocop:enable Metrics/MethodLength



45
46
47
48
49
50
51
52
# File 'lib/europe/vat/rates.rb', line 45

def self.filter_rate(result, rates)
  return unless result[1].text.size == 2

  country = result[1].text
  rate = result[5].text
  rates[country.to_sym] = rate.to_f if country && rate
  rates
end

.retrieveObject



18
19
20
21
22
23
# File 'lib/europe/vat/rates.rb', line 18

def self.retrieve
  resp = fetch_rates
  return FALLBACK_RATES if resp.nil?

  extract_rates(resp)
end