Commissioner Guy
Calculates charged and received amounts based on provided one. Calls your exchanger if needed. Applies commissions in order that you define.
Installation
Add this line to your application's Gemfile:
gem 'commissioner-guy', require: 'commissioner'
And then execute:
$ bundle
Or install it yourself as:
$ gem install commissioner-guy
Usage
First, configure the gem
require 'commissioner'
Commissioner.configure do |config|
# If you exchange money provider the lambda that receives
# from - string
# to - string
# amount - Money instance
# 'amount' might be in 'from' or 'to' currency
# Must return either just exchanged amount or [amount, exchanged_rate]
config.exchanger = ->(from, to, amount) { ... }
# When applying commission the amount might be rounded. This setting
# defined the rounding mode. Available modes are:
# - :up
# - :down
# - :half_up
# - :half_even
# See BigDecimal rounding modes for more
config.rouding_mode = :up
end
Explicit call
calculation = Commissioner.calculate(
charged_amount: 100,
charged_currency: 'EUR',
received_currency: 'USD',
commission: 10, # %
exchange_commission: 15 # %
)
calculation.charged_amount # #<Money fractional:10000 currency:EUR>
calculation.received_amount # #<Money fractional:7650 currency:USD>
calculation.fee # #<Money fractional:1000 currency:EUR>
calculation.exchange_fee # <Money fractional:1350 currency:USD>
calculation.exchange_rate # 1 (only if config.exchanger returns it)
As a mixin
class MyCalculator
include Commissiner::Mixin
def call(params)
calculate(params)
end
end
Specify order
You can specify in which order calculation will be applied. The steps are:
- exchange
- commission
- exchange_commission
exchange
- calls exchanger if currencies of received and charged amounts differ
commission
- applies typical commission operation
exchange_commission
- applies commission for exchange (in charged currency if ordered before exchange
or in received currency if ordered after exchange
)
class MyCalculator
include Commissioner::Mixin
# Default order is:
# - :commission
# - :exchange
# - :exchange_commission
Order[
:commission,
:exchange_commission,
:exchange
]
end
MyCalculator.new.calculate(
received_amount: 100,
received_currency: 'EUR',
charged_currency: 'USD',
commission: 10,
exchange_commission: 15
).to_h
# =>
# {
# :received_amount => #<Money fractional:10000 currency:EUR>,
# :charged_amount => #<Money fractional:13072 currency:USD>,
# :fee => #<Money fractional:1307 currency:USD>,
# :exchange_fee => #<Money fractional:1765 currency:USD>,
# :exchange_rate => 1
# }
# Changing the order
class MyCalculator
Order[
:exchange_commission,
:exchange,
:commission
]
end
MyCalculator.new.calculate(
received_amount: 100,
received_currency: 'EUR',
charged_currency: 'USD',
commission: 10,
exchange_commission: 15
).to_h
# =>
# {
# :received_amount => #<Money fractional:10000 currency:EUR>,
# :charged_amount => #<Money fractional:13072 currency:USD>,
# :fee => #<Money fractional:1111 currency:EUR>,
# :exchange_fee => #<Money fractional:1961 currency:USD>,
# :exchange_rate => 1
# }
Development
- Custom exchanger
- If exchanging is not needed, it is not executed
- Commission for operation
- Commission for exchange
- No matter whether received or charged amount is provided, the calculation result is the same
- User-defined order of commissions aplying and exchanging
- Custom commissions and exchanges in order
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/mrexox/commissioner.
License
The gem is available as open source under the terms of the MIT License.