86 lines
1.9 KiB
Ruby
86 lines
1.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "roundable"
|
|
|
|
module Versions
|
|
class V1 < Roda
|
|
module Quote
|
|
class Base
|
|
include Roundable
|
|
|
|
attr_reader :amount, :base, :date, :symbols, :result
|
|
|
|
def initialize(date:, amount: 1.0, base: "EUR", symbols: nil)
|
|
@date = date
|
|
@amount = amount
|
|
@base = base
|
|
@symbols = symbols
|
|
@result = {}
|
|
end
|
|
|
|
def perform
|
|
return false if result.frozen?
|
|
|
|
prepare_rates
|
|
rebase_rates if must_rebase?
|
|
result.freeze
|
|
end
|
|
|
|
def must_rebase?
|
|
base != "EUR"
|
|
end
|
|
|
|
def should_round?
|
|
amount != 1.0 || must_rebase?
|
|
end
|
|
|
|
def formatted
|
|
raise NotImplementedError
|
|
end
|
|
|
|
def not_found?
|
|
result.empty?
|
|
end
|
|
|
|
def cache_key
|
|
raise NotImplementedError
|
|
end
|
|
|
|
private
|
|
|
|
def data
|
|
@data ||= fetch_data
|
|
end
|
|
|
|
def fetch_data
|
|
raise NotImplementedError
|
|
end
|
|
|
|
def prepare_rates
|
|
data.each_with_object(result) do |currency, result|
|
|
date = currency[:date].to_date.to_s
|
|
result[date] ||= {}
|
|
rate = amount * currency[:rate]
|
|
result[date][currency[:quote]] = should_round? ? round(rate) : rate
|
|
end
|
|
end
|
|
|
|
def rebase_rates
|
|
result.each do |date, rates|
|
|
rates["EUR"] = amount if symbols.nil? || symbols.include?("EUR")
|
|
divisor = rates.delete(base)
|
|
if divisor.nil? || rates.empty?
|
|
result.delete(date)
|
|
else
|
|
result[date] = rates.sort
|
|
.map! do |quote, rate|
|
|
[quote, round(amount * rate / divisor)]
|
|
end
|
|
.to_h
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|