Packages

Money functions for operations on and localization of a money data type with support for ISO 4217 currencies and ISO 24165 digial tokens (crypto currencies).

Retired package: Deprecated

Current section

Files

Jump to
ex_money lib money exchange_rates open_exchange_rates.ex
Raw

lib/money/exchange_rates/open_exchange_rates.ex

defmodule Money.ExchangeRates.OpenExchangeRates do
@behaviour Money.ExchangeRates
@dummy_app_id "not_configured"
@app_id Money.get_env(:open_exchange_rates_app_id, @dummy_app_id)
@exr_url Money.get_env(:open_exchange_rates_url, "https://openexchangerates.org/api")
@doc """
Retrieves the latest exchange rates from Open Exchange Rates site.
* `app_id` is a valid Open Exchange Rates app_id. Defaults to the
configured `app_id` in `config.exs`
Returns:
* `{:ok, rates}` if the rates can be retrieved
* `{:error, reason}` if rates cannot be retrieved
Typically this function is called by the exchange rates retrieval
service althouhg it can be called outside that context as
required.
"""
@latest_endpoint "/latest.json"
@latest_url @exr_url <> @latest_endpoint <> "?app_id="
@spec get_latest_rates(String.t) :: {:ok, Map.t} | {:error, String.t}
def get_latest_rates(app_id \\ @app_id)
def get_latest_rates(@dummy_app_id) do
{:error, "Open Exchange Rates app_id is not configured. Rates are not retrieved."}
end
def get_latest_rates(app_id) do
get_rates(@latest_url, app_id)
end
defp get_rates(url, app_id) when is_binary(url) do
url <> app_id
|> String.to_char_list
|> get_rates
end
defp get_rates(url) when is_list(url) do
require Logger
case :httpc.request(url) do
{:ok, {{_version, 200, 'OK'}, _headers, body}} ->
%{"base" => _base, "rates" => rates} = Poison.decode!(body)
decimal_rates = rates
|> Cldr.Map.atomize_keys
|> Enum.map(fn {k, v} -> {k, Decimal.new(v)} end)
{:ok, decimal_rates}
{_, {{_version, code, message}, _headers, _body}} ->
{:error, "#{code} #{message}"}
{:error, {:failed_connect, [{_, {_host, _port}}, {_, _, sys_message}]}} ->
{:error, sys_message}
end
end
end