# ECB Exchange [![Gem Version](https://img.shields.io/gem/v/ecb_exchange.svg?style=flat)](http://rubygems.org/gems/ecb_exchange) [![Travis Build Status](https://travis-ci.org/matthutchinson/ecb_exchange.svg?branch=master)](https://travis-ci.org/matthutchinson/ecb_exchange) [![Maintainability](https://api.codeclimate.com/v1/badges/c67969dd7b921477bdcc/maintainability)](https://codeclimate.com/github/matthutchinson/ecb_exchange/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/c67969dd7b921477bdcc/test_coverage)](https://codeclimate.com/github/matthutchinson/ecb_exchange/test_coverage) [![Gem Dependency Status](https://gemnasium.com/badges/github.com/matthutchinson/ecb_exchange.svg)](https://gemnasium.com/github.com/matthutchinson/ecb_exchange) Currency conversion using the European Central Bank's foreign [exchange rates](http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml). Rates for the last 90 days are fetched and cached on demand. All calculations are performed and returned as `BigDecimal`, usually a [good idea](https://makandracards.com/makandra/1178-bigdecimal-arithmetic-in-ruby) when dealing with money. ## Requirements * Ruby >= 2.1.0 ## Installation Add this line to your Gemfile and run `bundle install`: ```ruby gem 'ecb_exchange' ``` ## Usage To convert an amount from one currency to another use: ```ruby ECB::Exchange.convert(100, from: 'EUR', to: 'GBP') => 0.88235e2 ``` The converted amount (using today's current rate) will be returned (as a `BigDecimal`). In doing so the gem will have fetched and cached ECB rates for the last 90 days. You can ask the exchange to convert an amount on a specific date: ```ruby ECB::Exchange.convert(100, from: 'EUR', to: 'GBP', date: Date.parse('2017-01-11')) => 0.87235e2 ``` To return only the exchange rate multiplier between two currencies use: ```ruby ECB::Exchange.rate(from: 'EUR', to: 'USD') => 0.11969e1 # you can pass an optional `date` argument to this method too ``` You can ask for an array of supported currency codes with: ```ruby ECB::Exchange.currencies => ["USD", "JPY", "BGN", "CZK", "DKK", "GBP", "HUF" ... ] ``` Finally, you can adjust the rates endpoint by setting the `XMLFeed.endpoint` (e.g. in an initializer): ```ruby ECB::Exchange::XMLFeed.endpoint = "http://my-awesome-service.com/feed.xml" ``` The XML feed must conform to the [ECB rates](http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml) structure. ## Handling Errors Not all dates, rates or currencies may be available, or the remote endpoint could be unresponsive. You should consider handling the following errors: * `ECB::Exchange::DateNotFoundError` * `ECB::Exchange::CurrencyNotFoundError` * `ECB::Exchange::ResponseError` * `ECB::Exchange::ParseError` Or rescue `ECB::Exchange::Error` to catch any of them. ## Caching By default rates will be cached to one of the following backend stores (with this order of preference). * Your own backend cache store (see below) * The `Rails.cache` * An `ECB::Exchange::MemoryCache` instance (a simple in memory cache store) To configure your own backend store: ```ruby ECB::Exchange::Cache.backend = MyAwesomeCache.new # your cache must implement public `read(key)` and `write(key, value)` methods ``` All keys in the cache are name-spaced with a `ecb_exchange_rates_for_date-` prefix. ## Development Check out this repo and run `bin/setup`, this will install gem dependencies and generate docs. Use `bundle exec rake` to run tests and generate a coverage report. You can also run `bin/console` for an interactive prompt allowing you to experiment with the code. ## Tests MiniTest is used for testing. Run the test suite with: $ rake test ## Docs Generate docs for this gem with: $ rake rdoc ## Troubles? If you think something is broken or missing, please raise a new [issue](https://github.com/matthutchinson/ecb_exchange/issues). Please remember to check it hasn't already been raised. ## Contributing Bug [reports](https://github.com/matthutchinson/ecb_exchange/issues) and [pull requests](https://github.com/matthutchinson/ecb_exchange/pulls) are welcome on GitHub. When submitting pull requests, remember to add tests covering any new behaviour, and ensure all tests are passing on [Travis](https://travis-ci.org/matthutchinson/ecb_exchange). Read the [contributing guidelines](https://github.com/matthutchinson/ecb_exchange/blob/master/CONTRIBUTING.md) for more details. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct. See [here](https://github.com/matthutchinson/ecb_exchange/blob/master/CODE_OF_CONDUCT.md) for more details. ## Todo * Better rdoc documentation * A small Rails app to demo this gem, with a one-click heroku install * Allow `Net::HTTP` to be swapped out for any another HTTP client ## License The code is available as open source under the terms of [LGPL-3](https://opensource.org/licenses/LGPL-3.0). ## Links * [Travis CI](https://travis-ci.org/matthutchinson/ecb_exchange) * [Maintainability](https://codeclimate.com/github/matthutchinson/ecb_exchange/maintainability) * [Test Coverage](https://codeclimate.com/github/matthutchinson/ecb_exchange/test_coverage) * [RDoc](http://rdoc.info/projects/matthutchinson/ecb_exchange) * [Issues](http://github.com/matthutchinson/ecb_exchange/issues) * [Report a bug](http://github.com/matthutchinson/ecb_exchange/issues/new) * [Gem](http://rubygems.org/gems/ecb_exchange) * [GitHub](https://github.com/matthutchinson/ecb_exchange)