money2 7.0.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,17 @@
1
+ # Contribution Guidelines
2
+
3
+ ## Steps
4
+
5
+ 1. Fork [the repo](https://github.com/RubyMoney/money)
6
+ 2. Grab dependencies: `bundle install`
7
+ 3. Make sure everything is working: `bundle exec rake spec`
8
+ 4. Make your changes
9
+ 5. Test your changes
10
+ 5. Create a Pull Request
11
+ 6. Celebrate!!!!!
12
+
13
+ ## Notes
14
+
15
+ When contributing, please make sure to update the CHANGELOG and AUTHORS files
16
+ when you submit your pull request. Upon merging of your first pull request,
17
+ you will be given commit access to the repository.
data/Gemfile ADDED
@@ -0,0 +1,16 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'coveralls', :require => false
4
+ gem 'pry', :require => false
5
+
6
+ # JSON gem no longer supports ruby < 2.0.0
7
+ if defined?(JRUBY_VERSION)
8
+ gem 'json'
9
+ elsif RUBY_VERSION =~ /^1/
10
+ # Legacy gem locks for ruby 1.9.x
11
+ gem 'json', '~> 1.8.3'
12
+ gem 'tins', '~> 1.6.0'
13
+ gem 'term-ansicolor', '< 1.4'
14
+ end
15
+
16
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2005 Tobias Lutke
4
+ Copyright (c) 2008 Phusion
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining
7
+ a copy of this software and associated documentation files (the
8
+ "Software"), to deal in the Software without restriction, including
9
+ without limitation the rights to use, copy, modify, merge, publish,
10
+ distribute, sublicense, and/or sell copies of the Software, and to
11
+ permit persons to whom the Software is furnished to do so, subject to
12
+ the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be
15
+ included in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,438 @@
1
+ # RubyMoney - Money
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/money.svg)](http://badge.fury.io/rb/money)
4
+ [![Build Status](https://travis-ci.org/RubyMoney/money.svg?branch=master)](https://travis-ci.org/RubyMoney/money)
5
+ [![Code Climate](https://codeclimate.com/github/RubyMoney/money.svg)](https://codeclimate.com/github/RubyMoney/money)
6
+ [![Coverage Status](https://coveralls.io/repos/RubyMoney/money/badge.svg?branch=master)](https://coveralls.io/r/RubyMoney/money?branch=master)
7
+ [![Inline docs](http://inch-ci.org/github/RubyMoney/money.svg)](http://inch-ci.org/github/RubyMoney/money)
8
+ [![Dependency Status](https://gemnasium.com/RubyMoney/money.svg)](https://gemnasium.com/RubyMoney/money)
9
+ [![License](https://img.shields.io/github/license/RubyMoney/money.svg)](http://opensource.org/licenses/MIT)
10
+
11
+ :warning: Please read about the [difference](https://github.com/printercu/money/wiki)
12
+ between this version and original `money` gem.
13
+
14
+ If you miss String parsing, check out the new [monetize gem](https://github.com/RubyMoney/monetize).
15
+
16
+ ## Contributing
17
+
18
+ See the [Contribution Guidelines](https://github.com/RubyMoney/money/blob/master/CONTRIBUTING.md)
19
+
20
+ ## Introduction
21
+
22
+ A Ruby Library for dealing with money and currency conversion.
23
+
24
+ ### Features
25
+
26
+ - Provides a `Money` class which encapsulates all information about an certain
27
+ amount of money, such as its value and its currency.
28
+ - Provides a `Money::Currency` class which encapsulates all information about
29
+ a monetary unit.
30
+ - Represents monetary values as integers, in cents. This avoids floating point
31
+ rounding errors.
32
+ - Represents currency as `Money::Currency` instances providing a high level of
33
+ flexibility.
34
+ - Provides APIs for exchanging money from one currency to another.
35
+
36
+ ### Resources
37
+
38
+ - [Website](http://rubymoney.github.io/money/)
39
+ - [API Documentation](http://www.rubydoc.info/gems/money/frames)
40
+ - [Git Repository](https://github.com/RubyMoney/money)
41
+
42
+ ### Notes
43
+
44
+ - Your app must use UTF-8 to function with this library. There are a
45
+ number of non-ASCII currency attributes.
46
+ - This app requires JSON. If you're using JRuby < 1.7.0
47
+ you'll need to add `gem "json"` to your Gemfile or similar.
48
+
49
+ ## Downloading
50
+
51
+ Install stable releases with the following command:
52
+
53
+ gem install money
54
+
55
+ The development version (hosted on Github) can be installed with:
56
+
57
+ git clone git://github.com/RubyMoney/money.git
58
+ cd money
59
+ rake install
60
+
61
+ ## Usage
62
+
63
+ ``` ruby
64
+ require 'money'
65
+
66
+ # 10.00 USD
67
+ money = Money.new(1000, "USD")
68
+ money.fractional #=> 1000
69
+ money.currency #=> Currency.new("USD")
70
+
71
+ # Comparisons
72
+ Money.new(1000, "USD") == Money.new(1000, "USD") #=> true
73
+ Money.new(1000, "USD") == Money.new(100, "USD") #=> false
74
+ Money.new(1000, "USD") == Money.new(1000, "EUR") #=> false
75
+ Money.new(1000, "USD") != Money.new(1000, "EUR") #=> true
76
+
77
+ # Arithmetic
78
+ Money.new(1000, "USD") + Money.new(500, "USD") == Money.new(1500, "USD")
79
+ Money.new(1000, "USD") - Money.new(200, "USD") == Money.new(800, "USD")
80
+ Money.new(1000, "USD") / 5 == Money.new(200, "USD")
81
+ Money.new(1000, "USD") * 5 == Money.new(5000, "USD")
82
+
83
+ # Unit to subunit conversions
84
+ Money.from_amount(5, "USD") == Money.new(500, "USD") # 5 USD
85
+ Money.from_amount(5, "JPY") == Money.new(5, "JPY") # 5 JPY
86
+ Money.from_amount(5, "TND") == Money.new(5000, "TND") # 5 TND
87
+
88
+ # Currency conversions
89
+ some_code_to_setup_exchange_rates
90
+ Money.new(1000, "USD").exchange_to("EUR") == Money.new(some_value, "EUR")
91
+
92
+ # Formatting (see Formatter section for more options)
93
+ Money.new(100, "USD").format #=> "$1.00"
94
+ Money.new(100, "GBP").format #=> "£1.00"
95
+ Money.new(100, "EUR").format #=> "€1.00"
96
+ ```
97
+
98
+ ## Currency
99
+
100
+ Currencies are consistently represented as instances of `Money::Currency`.
101
+ The most part of `Money` APIs allows you to supply either a `String` or a
102
+ `Money::Currency`.
103
+
104
+ ``` ruby
105
+ Money.new(1000, "USD") == Money.new(1000, Money::Currency.new("USD"))
106
+ Money.new(1000, "EUR").currency == Money::Currency.new("EUR")
107
+ ```
108
+
109
+ A `Money::Currency` instance holds all the information about the currency,
110
+ including the currency symbol, name and much more.
111
+
112
+ ``` ruby
113
+ currency = Money.new(1000, "USD").currency
114
+ currency.code #=> "USD"
115
+ currency.name #=> "United States Dollar"
116
+ ```
117
+
118
+ To define a new `Money::Currency` use `Money::Currency.register` as shown
119
+ below.
120
+
121
+ ``` ruby
122
+ curr = {
123
+ priority: 1,
124
+ code: 'USD',
125
+ iso_numeric: 840,
126
+ name: 'United States Dollar',
127
+ symbol: '$',
128
+ subunit: 'Cent',
129
+ subunit_to_unit: 100,
130
+ separator: '.',
131
+ delimiter: ',',
132
+ }
133
+
134
+ Money::Currency.register(curr)
135
+ ```
136
+
137
+ The pre-defined set of attributes includes:
138
+
139
+ - `:priority` a numerical value you can use to sort/group the currency list
140
+ - `:code` the international 3-letter code as defined by the ISO 4217 standard or
141
+ other code for non-ISO currencies.
142
+ - `:iso_numeric` the international 3-digit code as defined by the ISO 4217 standard
143
+ - `:name` the currency name
144
+ - `:symbol` the currency symbol (UTF-8 encoded)
145
+ - `:subunit` the name of the fractional monetary unit
146
+ - `:subunit_to_unit` the proportion between the unit and the subunit
147
+ - `:separator` character between the whole and fraction amounts
148
+ - `:delimiter` character between each thousands place
149
+
150
+ All attributes except `:code` are optional. Some attributes, such as
151
+ `:symbol`, are used by the Money class to print out a representation of the
152
+ object. Other attributes, such as `:name` or `:priority`, exist to provide a
153
+ basic API you can take advantage of to build your application.
154
+
155
+ ### :priority
156
+
157
+ The priority attribute is an arbitrary numerical value you can assign to the
158
+ `Money::Currency` and use in sorting/grouping operation.
159
+
160
+ For instance, let's assume your Rails application needs to render a currency
161
+ selector like the one available
162
+ [here](http://finance.yahoo.com/currency-converter/). You can create a couple of
163
+ custom methods to return the list of major currencies and all currencies as
164
+ follows:
165
+
166
+ ``` ruby
167
+ # Returns an array of currency id where
168
+ # priority < 10
169
+ def major_currencies(hash)
170
+ hash.inject([]) do |array, (id, attributes)|
171
+ priority = attributes[:priority]
172
+ if priority && priority < 10
173
+ array[priority] ||= []
174
+ array[priority] << id
175
+ end
176
+ array
177
+ end.compact.flatten
178
+ end
179
+
180
+ # Returns an array of all currency id
181
+ def all_currencies(hash)
182
+ hash.keys
183
+ end
184
+
185
+ major_currencies(Money::Currency.table)
186
+ # => [:usd, :eur, :gbp, :aud, :cad, :jpy]
187
+
188
+ all_currencies(Money::Currency.table)
189
+ # => [:aed, :afn, :all, ...]
190
+ ```
191
+
192
+ ### Default Currency
193
+
194
+ By default `Money` defaults to USD as its currency. This can be overwritten
195
+ using:
196
+
197
+ ``` ruby
198
+ Money.default_currency = Money::Currency.new("CAD")
199
+ ```
200
+
201
+ If you use Rails, then `environment.rb` is a very good place to put this.
202
+
203
+ ### Currency Exponent
204
+
205
+ The exponent of a money value is the number of digits after the decimal
206
+ separator (which separates the major unit from the minor unit). See e.g.
207
+ [ISO 4217](http://www.currency-iso.org/en/shared/amendments/iso-4217-amendment.html) for more
208
+ information. You can find the exponent (as an `Integer`) by
209
+
210
+ ``` ruby
211
+ Money::Currency.new("USD").exponent # => 2
212
+ Money::Currency.new("JPY").exponent # => 0
213
+ Money::Currency.new("MGA").exponent # => 1
214
+ ```
215
+
216
+ ### Currency Lookup
217
+
218
+ To find a given currency by ISO 4217 numeric code (three digits) you can do
219
+
220
+ ``` ruby
221
+ Money::Currency.find_by_iso_numeric(978) #=> Money::Currency.new(:eur)
222
+ ```
223
+
224
+ ## Currency Exchange
225
+
226
+ Exchanging money is performed through an exchange bank object. The default
227
+ exchange bank object requires one to manually specify the exchange rate. Here's
228
+ an example of how it works:
229
+
230
+ ``` ruby
231
+ Money.add_rate("USD", "CAD", 1.24515)
232
+ Money.add_rate("CAD", "USD", 0.803115)
233
+
234
+ Money.us_dollar(100).exchange_to("CAD") # => Money.new(124, "CAD")
235
+ Money.ca_dollar(100).exchange_to("USD") # => Money.new(80, "USD")
236
+ ```
237
+
238
+ Comparison and arithmetic operations work as expected:
239
+
240
+ ``` ruby
241
+ Money.new(1000, "USD") <=> Money.new(900, "USD") # => 1; 9.00 USD is smaller
242
+ Money.new(1000, "EUR") + Money.new(10, "EUR") == Money.new(1010, "EUR")
243
+
244
+ Money.add_rate("USD", "EUR", 0.5)
245
+ Money.new(1000, "EUR") + Money.new(1000, "USD") == Money.new(1500, "EUR")
246
+ ```
247
+
248
+ ### Exchange rate stores
249
+
250
+ The default bank is initialized with an in-memory store for exchange rates.
251
+
252
+ ```ruby
253
+ Money.default_bank = Money::Bank::VariableExchange.new(Money::RatesStore::Memory.new)
254
+ ```
255
+
256
+ You can pass you own store implementation, ie. for storing and retrieving rates off a database, file, cache, etc.
257
+
258
+ ```ruby
259
+ Money.default_bank = Money::Bank::VariableExchange.new(MyCustomStore.new)
260
+ ```
261
+
262
+ Stores must implement the following interface:
263
+
264
+ ```ruby
265
+ # Add new exchange rate.
266
+ # @param [String] iso_from Currency ISO code. ex. 'USD'
267
+ # @param [String] iso_to Currency ISO code. ex. 'CAD'
268
+ # @param [Numeric] rate Exchange rate. ex. 0.0016
269
+ #
270
+ # @return [Numeric] rate.
271
+ def add_rate(iso_from, iso_to, rate); end
272
+
273
+ # Get rate. Must be idempotent. ie. adding the same rate must not produce duplicates.
274
+ # @param [String] iso_from Currency ISO code. ex. 'USD'
275
+ # @param [String] iso_to Currency ISO code. ex. 'CAD'
276
+ #
277
+ # @return [Numeric] rate.
278
+ def get_rate(iso_from, iso_to); end
279
+
280
+ # Iterate over rate tuples (iso_from, iso_to, rate)
281
+ #
282
+ # @yieldparam iso_from [String] Currency ISO string.
283
+ # @yieldparam iso_to [String] Currency ISO string.
284
+ # @yieldparam rate [Numeric] Exchange rate.
285
+ #
286
+ # @return [Enumerator]
287
+ #
288
+ # @example
289
+ # store.each_rate do |iso_from, iso_to, rate|
290
+ # puts [iso_from, iso_to, rate].join
291
+ # end
292
+ def each_rate(&block); end
293
+
294
+ # Wrap store operations in a thread-safe transaction
295
+ # (or IO or Database transaction, depending on your implementation)
296
+ #
297
+ # @yield [n] Block that will be wrapped in transaction.
298
+ #
299
+ # @example
300
+ # store.transaction do
301
+ # store.add_rate('USD', 'CAD', 0.9)
302
+ # store.add_rate('USD', 'CLP', 0.0016)
303
+ # end
304
+ def transaction(&block); end
305
+
306
+ # Serialize store and its content to make Marshal.dump work.
307
+ #
308
+ # Returns an array with store class and any arguments needed to initialize the store in the current state.
309
+
310
+ # @return [Array] [class, arg1, arg2]
311
+ def marshal_dump; end
312
+ ```
313
+
314
+ The following example implements an `ActiveRecord` store to save exchange rates to a database.
315
+
316
+ ```ruby
317
+ # DB columns :from[String], :to[String], :rate[Float]
318
+
319
+ class ExchangeRate < ActiveRecord::Base
320
+ def self.get_rate(from_code, to_code)
321
+ rate = find_by(:from => from_code, :to => to_code)
322
+ rate.present? ? rate.rate : nil
323
+ end
324
+
325
+ def self.add_rate(from_code, to_code, rate)
326
+ exrate = find_or_initialize_by(:from => from_code, :to => to_code)
327
+ exrate.rate = rate
328
+ exrate.save!
329
+ end
330
+ end
331
+ ```
332
+
333
+ Now you can use it with the default bank.
334
+
335
+ ```ruby
336
+ Money.default_bank = Money::Bank::VariableExchange.new(ExchangeRate)
337
+
338
+ # Add to the underlying store
339
+ Money.default_bank.add_rate('USD', 'CAD', 0.9)
340
+ # Retrieve from the underlying store
341
+ Money.default_bank.get_rate('USD', 'CAD') # => 0.9
342
+ # Exchanging amounts just works.
343
+ Money.new(1000, 'USD').exchange_to('CAD') #=> #<Money fractional:900 currency:CAD>
344
+ ```
345
+
346
+ There is nothing stopping you from creating store objects which scrapes
347
+ [XE](http://www.xe.com) for the current rates or just returns `rand(2)`:
348
+
349
+ ``` ruby
350
+ Money.default_bank = Money::Bank::VariableExchange.new(StoreWhichScrapesXeDotCom.new)
351
+ ```
352
+
353
+ You can also implement your own Bank to calculate exchanges differently.
354
+ Different banks can share Stores.
355
+
356
+ ```ruby
357
+ Money.default_bank = MyCustomBank.new(Money::RatesStore::Memory.new)
358
+ ```
359
+
360
+ If you wish to disable automatic currency conversion to prevent arithmetic when
361
+ currencies don't match:
362
+
363
+ ``` ruby
364
+ Money.disallow_currency_conversion!
365
+ ```
366
+
367
+ ### Implementations
368
+
369
+ The following is a list of Money.gem compatible currency exchange rate
370
+ implementations.
371
+
372
+ - [eu_central_bank](https://github.com/RubyMoney/eu_central_bank)
373
+ - [google_currency](https://github.com/RubyMoney/google_currency)
374
+ - [currencylayer](https://github.com/askuratovsky/currencylayer)
375
+ - [nordea](https://github.com/matiaskorhonen/nordea)
376
+ - [nbrb_currency](https://github.com/slbug/nbrb_currency)
377
+ - [money-currencylayer-bank](https://github.com/phlegx/money-currencylayer-bank)
378
+ - [money-open-exchange-rates](https://github.com/spk/money-open-exchange-rates)
379
+ - [money-historical-bank](https://github.com/atwam/money-historical-bank)
380
+ - [russian_central_bank](https://github.com/rmustafin/russian_central_bank)
381
+ - [money-uphold-bank](https://github.com/subvisual/money-uphold-bank)
382
+
383
+ ## Ruby on Rails
384
+
385
+ To integrate money in a Rails application use [money-rails](https://github.com/RubyMoney/money-rails).
386
+
387
+ For deprecated methods of integrating with Rails, check [the wiki](https://github.com/RubyMoney/money/wiki).
388
+
389
+ ## I18n
390
+
391
+ If you want thousands seperator and decimal mark to be same across all
392
+ currencies this can be defined in your `I18n` translation files.
393
+
394
+ In an rails application this may look like:
395
+
396
+ ```yml
397
+ # config/locale/en.yml
398
+ en:
399
+ number:
400
+ format:
401
+ delimiter: ","
402
+ separator: "."
403
+ # or
404
+ number:
405
+ currency:
406
+ format:
407
+ delimiter: ","
408
+ separator: "."
409
+ ```
410
+
411
+ For this example `Money.new(123456789, "SEK").format` will return `1,234,567.89
412
+ kr` which otherwise will return `1 234 567,89 kr`.
413
+
414
+ If you wish to disable this feature:
415
+ ``` ruby
416
+ Money.formatter.use_i18n = false
417
+ ```
418
+
419
+ ### Troubleshooting
420
+
421
+ If you get a runtime error such as:
422
+
423
+ I18n::InvalidLocale: :en is not a valid locale
424
+
425
+ Set the following:
426
+ ``` ruby
427
+ I18n.enforce_available_locales = false
428
+ ```
429
+
430
+ ## Formatting
431
+
432
+ There are several formatting rules for when `Money#format` is called. For more information, check out the [formatting module source](https://github.com/RubyMoney/money/blob/master/lib/money/formatting.rb), or read the latest release's [rdoc version](http://www.rubydoc.info/gems/money/Money/Formatting).
433
+
434
+ If you wish to format money according to the EU's [Rules for expressing monetary units](http://publications.europa.eu/code/en/en-370303.htm#position) in either English, Irish, Latvian or Maltese:
435
+ ```ruby
436
+ m = Money.new('123', :gbp) # => #<Money fractional:123 currency:GBP>
437
+ m.format( symbol: m.currency.to_s + ' ') # => "GBP 1.23"
438
+ ```