money 3.7.1 → 4.0.0

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.
Files changed (43) hide show
  1. data/CHANGELOG.md +384 -351
  2. data/LICENSE +21 -21
  3. data/README.md +243 -214
  4. data/Rakefile +49 -49
  5. data/lib/money.rb +28 -27
  6. data/lib/money/bank/base.rb +131 -131
  7. data/lib/money/bank/variable_exchange.rb +252 -252
  8. data/lib/money/core_extensions.rb +82 -82
  9. data/lib/money/currency.rb +263 -422
  10. data/lib/money/currency_loader.rb +19 -0
  11. data/lib/money/money.rb +405 -405
  12. data/lib/money/money/arithmetic.rb +246 -246
  13. data/lib/money/money/formatting.rb +260 -244
  14. data/lib/money/money/parsing.rb +350 -350
  15. data/money.gemspec +29 -35
  16. data/spec/bank/base_spec.rb +72 -72
  17. data/spec/bank/variable_exchange_spec.rb +238 -238
  18. data/spec/core_extensions_spec.rb +158 -158
  19. data/spec/currency_spec.rb +120 -133
  20. data/spec/money/arithmetic_spec.rb +479 -479
  21. data/spec/money/formatting_spec.rb +383 -375
  22. data/spec/money/parsing_spec.rb +197 -197
  23. data/spec/money_spec.rb +292 -292
  24. data/spec/spec_helper.rb +28 -28
  25. metadata +54 -126
  26. data/lib/money.rbc +0 -184
  27. data/lib/money/bank/base.rbc +0 -818
  28. data/lib/money/bank/variable_exchange.rbc +0 -2550
  29. data/lib/money/core_extensions.rbc +0 -664
  30. data/lib/money/currency.rbc +0 -22708
  31. data/lib/money/money.rbc +0 -3861
  32. data/lib/money/money/arithmetic.rbc +0 -2778
  33. data/lib/money/money/formatting.rbc +0 -2265
  34. data/lib/money/money/parsing.rbc +0 -2737
  35. data/spec/bank/base_spec.rbc +0 -2461
  36. data/spec/bank/variable_exchange_spec.rbc +0 -7541
  37. data/spec/core_extensions_spec.rbc +0 -5921
  38. data/spec/currency_spec.rbc +0 -4535
  39. data/spec/money/arithmetic_spec.rbc +0 -25140
  40. data/spec/money/formatting_spec.rbc +0 -12545
  41. data/spec/money/parsing_spec.rbc +0 -6511
  42. data/spec/money_spec.rbc +0 -9824
  43. data/spec/spec_helper.rbc +0 -575
data/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- Copyright (c) 2005 Tobias Lutke
2
- Copyright (c) 2008 Phusion
3
-
4
- Permission is hereby granted, free of charge, to any person obtaining
5
- a copy of this software and associated documentation files (the
6
- "Software"), to deal in the Software without restriction, including
7
- without limitation the rights to use, copy, modify, merge, publish,
8
- distribute, sublicense, and/or sell copies of the Software, and to
9
- permit persons to whom the Software is furnished to do so, subject to
10
- the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be
13
- included in all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ Copyright (c) 2005 Tobias Lutke
2
+ Copyright (c) 2008 Phusion
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,214 +1,243 @@
1
- # RubyMoney - Money
2
-
3
- ## Introduction
4
-
5
- This library aids one in handling money and different currencies.
6
-
7
- ### Features
8
-
9
- - Provides a `Money` class which encapsulates all information about an certain
10
- amount of money, such as its value and its currency.
11
- - Provides a `Money::Currency` class which encapsulates all information about
12
- a monetary unit.
13
- - Represents monetary values as integers, in cents. This avoids floating point
14
- rounding errors.
15
- - Represents currency as `Money::Currency` instances providing an high level of
16
- flexibility.
17
- - Provides APIs for exchanging money from one currency to another.
18
- - Has the ability to parse a money and currency strings
19
- into the corresponding Money/Currency object.
20
-
21
- ### Resources
22
-
23
- - [Website](http://money.rubyforge.org)
24
- - [API Documentation](http://money.rubyforge.org)
25
- - [Git Repository](http://github.com/RubyMoney/money)
26
-
27
- ## Downloading
28
-
29
- Install stable releases with the following command:
30
-
31
- gem install money
32
-
33
- The development version (hosted on Github) can be installed with:
34
-
35
- git clone git://github.com/RubyMoney/money.git
36
- cd money
37
- rake install
38
-
39
- ## Usage
40
-
41
- require 'money'
42
-
43
- # 10.00 USD
44
- money = Money.new(1000, "USD")
45
- money.cents #=> 1000
46
- money.currency #=> Currency.new("USD")
47
-
48
- # Comparisons
49
- Money.new(1000, "USD") == Money.new(1000, "USD") #=> true
50
- Money.new(1000, "USD") == Money.new(100, "USD") #=> false
51
- Money.new(1000, "USD") == Money.new(1000, "EUR") #=> false
52
- Money.new(1000, "USD") != Money.new(1000, "EUR") #=> true
53
-
54
- # Arithmetic
55
- Money.new(1000, "USD") + Money.new(500, "USD") == Money.new(1500, "USD")
56
- Money.new(1000, "USD") - Money.new(200, "USD") == Money.new(800, "USD")
57
- Money.new(1000, "USD") / 5 == Money.new(200, "USD")
58
- Money.new(1000, "USD") * 5 == Money.new(5000, "USD")
59
-
60
- # Currency conversions
61
- some_code_to_setup_exchange_rates
62
- Money.new(1000, "USD").exchange_to("EUR") == Money.new(some_value, "EUR")
63
-
64
- ## Currency
65
-
66
- Currencies are consistently represented as instances of `Money::Currency`.
67
- The most part of `Money` APIs allows you to supply either a `String` or a
68
- `Money::Currency`.
69
-
70
- Money.new(1000, "USD") == Money.new(900, Currency.new("USD"))
71
- Money.new(1000, "EUR").currency == Currency.new("EUR")
72
-
73
- A `Money::Currency` instance holds all the information about the currency,
74
- including the currency symbol, name and much more.
75
-
76
- currency = Money.new(1000, "USD").currency
77
- currency.iso_code #=> "USD"
78
- currency.name #=> "United States Dollar"
79
-
80
- To define a new `Money::Currency` simply add a new item to the
81
- `Money::Currency::TABLE` hash, where the key is the identifier for the currency
82
- object and the value is a hash containing all the currency attributes.
83
-
84
- Money::Currency::TABLE[:usd] = {
85
- :priority => 1,
86
- :iso_code => "USD",
87
- :name => "United States Dollar",
88
- :symbol => "$",
89
- :subunit => "Cent"
90
- :subunit_to_unit => 100,
91
- :separator => ".",
92
- :delimiter => ","
93
- }
94
-
95
- The pre-defined set of attributes includes:
96
-
97
- - `:priority` a numerical value you can use to sort/group the currency list
98
- - `:iso_code` the international 3-letter code as defined by the ISO 4217 standard
99
- - `:name` the currency name
100
- - `:symbol` the currency symbol (UTF-8 encoded)
101
- - `:subunit` the name of the fractional monetary unit
102
- - `:subunit_to_unit` the proportion between the unit and the subunit
103
- - `:separator` character between the whole and fraction amounts
104
- - `:delimiter` character between each thousands place
105
-
106
- All attributes are optional. Some attributes, such as `:symbol`, are used by
107
- the Money class to print out a representation of the object. Other attributes,
108
- such as `:name` or `:priority`, exist to provide a basic API you can take
109
- advantage of to build your application.
110
-
111
- ### :priority
112
-
113
- The priority attribute is an arbitrary numerical value you can assign to the
114
- `Money::Currency` and use in sorting/grouping operation.
115
-
116
- For instance, let's assume your Rails application needs to render a currency
117
- selector like the one available
118
- [here](http://finance.yahoo.com/currency-converter/). You can create a couple of
119
- custom methods to return the list of major currencies and all currencies as
120
- follows:
121
-
122
- # Returns an array of currency id where
123
- # priority < 10
124
- def major_currencies(hash)
125
- hash.inject([]) do |array, (id, attributes)|
126
- priority = attributes[:priority]
127
- if priority && priority < 10
128
- array[priority] ||= []
129
- array[priority] << id
130
- end
131
- array
132
- end.compact.flatten
133
- end
134
-
135
- # Returns an array of all currency id
136
- def all_currencies(hash)
137
- hash.keys
138
- end
139
-
140
- major_currencies(Money::Currency::TABLE)
141
- # => [ :usd, :eur, :bgp, :cad ]
142
-
143
- all_currencies(Money::Currency::TABLE)
144
- # => [ :aed, :afn, all, ... ]
145
-
146
- ### Default Currency
147
-
148
- By default `Money` defaults to USD as its currency. This can be overwritten
149
- using:
150
-
151
- Money.default_currency = Money::Currency.new("CAD")
152
-
153
- If you use Rails, then `environment.rb` is a very good place to put this.
154
-
155
- ## Currency Exchange
156
-
157
- Exchanging money is performed through an exchange bank object. The default
158
- exchange bank object requires one to manually specify the exchange rate. Here's
159
- an example of how it works:
160
-
161
- Money.add_rate("USD", "CAD", 1.24515)
162
- Money.add_rate("CAD", "USD", 0.803115)
163
-
164
- Money.us_dollar(100).exchange_to("CAD") # => Money.new(124, "CAD")
165
- Money.ca_dollar(100).exchange_to("USD") # => Money.new(80, "USD")
166
-
167
- Comparison and arithmetic operations work as expected:
168
-
169
- Money.new(1000, "USD") <=> Money.new(900, "USD") # => 1; 9.00 USD is smaller
170
- Money.new(1000, "EUR") + Money.new(10, "EUR") == Money.new(1010, "EUR")
171
-
172
- Money.add_rate("USD", "EUR", 0.5)
173
- Money.new(1000, "EUR") + Money.new(1000, "USD") == Money.new(1500, "EUR")
174
-
175
- There is nothing stopping you from creating bank objects which scrapes
176
- [XE](http://www.xe.com) for the current rates or just returns `rand(2)`:
177
-
178
- Money.default_bank = ExchangeBankWhichScrapesXeDotCom.new
179
-
180
- ### Implementations
181
-
182
- The following is a list of Money.gem compatible currency exchange rate
183
- implementations.
184
-
185
- - [eu_central_bank](http://github.com/RubyMoney/eu_central_bank)
186
- - [google_currency](http://github.com/RubyMoney/google_currency)
187
-
188
- ## Ruby on Rails
189
-
190
- Use the `compose_of` helper to let Active Record deal with embedding the money
191
- object in your models. The following example requires 2 columns:
192
-
193
- :price_cents, :integer, :default => 0, :null => false
194
- :currency, :string
195
-
196
- Then in your model file:
197
-
198
- composed_of :price,
199
- :class_name => "Money",
200
- :mapping => [%w(price_cents cents), %w(currency currency_as_string)],
201
- :constructor => Proc.new { |cents, currency| Money.new(cents || 0, currency || Money.default_currency) },
202
- :converter => Proc.new { |value| value.respond_to?(:to_money) ? value.to_money : raise(ArgumentError, "Can't convert #{value.class} to Money") }
203
-
204
-
205
- For Money 2.2.x and previous versions, simply use the following `composed_of`
206
- definition:
207
-
208
- composed_of :price,
209
- :class_name => "Money",
210
- :mapping => [%w(cents cents), %w(currency currency)],
211
- :constructor => Proc.new { |cents, currency| Money.new(cents || 0, currency || Money.default_currency) }
212
-
213
- For further details read the full discussion
214
- [here](http://github.com/RubyMoney/money/issues/4#comment_224880).
1
+ # RubyMoney - Money
2
+
3
+ [![Build Status](http://travis-ci.org/RubyMoney/money.png)](http://travis-ci.org/RubyMoney/money)
4
+
5
+ ## Introduction
6
+
7
+ This library aids one in handling money and different currencies.
8
+
9
+ ### Features
10
+
11
+ - Provides a `Money` class which encapsulates all information about an certain
12
+ amount of money, such as its value and its currency.
13
+ - Provides a `Money::Currency` class which encapsulates all information about
14
+ a monetary unit.
15
+ - Represents monetary values as integers, in cents. This avoids floating point
16
+ rounding errors.
17
+ - Represents currency as `Money::Currency` instances providing an high level of
18
+ flexibility.
19
+ - Provides APIs for exchanging money from one currency to another.
20
+ - Has the ability to parse a money and currency strings
21
+ into the corresponding Money/Currency object.
22
+
23
+ ### Resources
24
+
25
+ - [Website](http://money.rubyforge.org)
26
+ - [API Documentation](http://money.rubyforge.org)
27
+ - [Git Repository](http://github.com/RubyMoney/money)
28
+
29
+ ## Downloading
30
+
31
+ Install stable releases with the following command:
32
+
33
+ gem install money
34
+
35
+ The development version (hosted on Github) can be installed with:
36
+
37
+ git clone git://github.com/RubyMoney/money.git
38
+ cd money
39
+ rake install
40
+
41
+ ## Usage
42
+
43
+ ``` ruby
44
+ require 'money'
45
+
46
+ # 10.00 USD
47
+ money = Money.new(1000, "USD")
48
+ money.cents #=> 1000
49
+ money.currency #=> Currency.new("USD")
50
+
51
+ # Comparisons
52
+ Money.new(1000, "USD") == Money.new(1000, "USD") #=> true
53
+ Money.new(1000, "USD") == Money.new(100, "USD") #=> false
54
+ Money.new(1000, "USD") == Money.new(1000, "EUR") #=> false
55
+ Money.new(1000, "USD") != Money.new(1000, "EUR") #=> true
56
+
57
+ # Arithmetic
58
+ Money.new(1000, "USD") + Money.new(500, "USD") == Money.new(1500, "USD")
59
+ Money.new(1000, "USD") - Money.new(200, "USD") == Money.new(800, "USD")
60
+ Money.new(1000, "USD") / 5 == Money.new(200, "USD")
61
+ Money.new(1000, "USD") * 5 == Money.new(5000, "USD")
62
+
63
+ # Currency conversions
64
+ some_code_to_setup_exchange_rates
65
+ Money.new(1000, "USD").exchange_to("EUR") == Money.new(some_value, "EUR")
66
+ ```
67
+
68
+ ## Currency
69
+
70
+ Currencies are consistently represented as instances of `Money::Currency`.
71
+ The most part of `Money` APIs allows you to supply either a `String` or a
72
+ `Money::Currency`.
73
+
74
+ ``` ruby
75
+ Money.new(1000, "USD") == Money.new(1000, Currency.new("USD"))
76
+ Money.new(1000, "EUR").currency == Currency.new("EUR")
77
+ ```
78
+
79
+ A `Money::Currency` instance holds all the information about the currency,
80
+ including the currency symbol, name and much more.
81
+
82
+ ``` ruby
83
+ currency = Money.new(1000, "USD").currency
84
+ currency.iso_code #=> "USD"
85
+ currency.name #=> "United States Dollar"
86
+ ```
87
+
88
+ To define a new `Money::Currency` simply add a new item to the
89
+ `Money::Currency::TABLE` hash, where the key is the identifier for the currency
90
+ object and the value is a hash containing all the currency attributes.
91
+
92
+ ``` ruby
93
+ Money::Currency::TABLE[:usd] = {
94
+ :priority => 1,
95
+ :iso_code => "USD",
96
+ :iso_numeric => "840",
97
+ :name => "United States Dollar",
98
+ :symbol => "$",
99
+ :subunit => "Cent"
100
+ :subunit_to_unit => 100,
101
+ :separator => ".",
102
+ :delimiter => ","
103
+ }
104
+ ```
105
+
106
+ The pre-defined set of attributes includes:
107
+
108
+ - `:priority` a numerical value you can use to sort/group the currency list
109
+ - `:iso_code` the international 3-letter code as defined by the ISO 4217 standard
110
+ - `:iso_numeric` the international 3-digit code as defined by the ISO 4217 standard
111
+ - `:name` the currency name
112
+ - `:symbol` the currency symbol (UTF-8 encoded)
113
+ - `:subunit` the name of the fractional monetary unit
114
+ - `:subunit_to_unit` the proportion between the unit and the subunit
115
+ - `:separator` character between the whole and fraction amounts
116
+ - `:delimiter` character between each thousands place
117
+
118
+ All attributes are optional. Some attributes, such as `:symbol`, are used by
119
+ the Money class to print out a representation of the object. Other attributes,
120
+ such as `:name` or `:priority`, exist to provide a basic API you can take
121
+ advantage of to build your application.
122
+
123
+ ### :priority
124
+
125
+ The priority attribute is an arbitrary numerical value you can assign to the
126
+ `Money::Currency` and use in sorting/grouping operation.
127
+
128
+ For instance, let's assume your Rails application needs to render a currency
129
+ selector like the one available
130
+ [here](http://finance.yahoo.com/currency-converter/). You can create a couple of
131
+ custom methods to return the list of major currencies and all currencies as
132
+ follows:
133
+
134
+ ``` ruby
135
+ # Returns an array of currency id where
136
+ # priority < 10
137
+ def major_currencies(hash)
138
+ hash.inject([]) do |array, (id, attributes)|
139
+ priority = attributes[:priority]
140
+ if priority && priority < 10
141
+ array[priority] ||= []
142
+ array[priority] << id
143
+ end
144
+ array
145
+ end.compact.flatten
146
+ end
147
+
148
+ # Returns an array of all currency id
149
+ def all_currencies(hash)
150
+ hash.keys
151
+ end
152
+
153
+ major_currencies(Money::Currency::TABLE)
154
+ # => [ :usd, :eur, :bgp, :cad ]
155
+
156
+ all_currencies(Money::Currency::TABLE)
157
+ # => [ :aed, :afn, all, ... ]
158
+ ```
159
+
160
+ ### Default Currency
161
+
162
+ By default `Money` defaults to USD as its currency. This can be overwritten
163
+ using:
164
+
165
+ ``` ruby
166
+ Money.default_currency = Money::Currency.new("CAD")
167
+ ```
168
+
169
+ If you use Rails, then `environment.rb` is a very good place to put this.
170
+
171
+ ## Currency Exchange
172
+
173
+ Exchanging money is performed through an exchange bank object. The default
174
+ exchange bank object requires one to manually specify the exchange rate. Here's
175
+ an example of how it works:
176
+
177
+ ``` ruby
178
+ Money.add_rate("USD", "CAD", 1.24515)
179
+ Money.add_rate("CAD", "USD", 0.803115)
180
+
181
+ Money.us_dollar(100).exchange_to("CAD") # => Money.new(124, "CAD")
182
+ Money.ca_dollar(100).exchange_to("USD") # => Money.new(80, "USD")
183
+ ```
184
+
185
+ Comparison and arithmetic operations work as expected:
186
+
187
+ ``` ruby
188
+ Money.new(1000, "USD") <=> Money.new(900, "USD") # => 1; 9.00 USD is smaller
189
+ Money.new(1000, "EUR") + Money.new(10, "EUR") == Money.new(1010, "EUR")
190
+
191
+ Money.add_rate("USD", "EUR", 0.5)
192
+ Money.new(1000, "EUR") + Money.new(1000, "USD") == Money.new(1500, "EUR")
193
+ ```
194
+
195
+ There is nothing stopping you from creating bank objects which scrapes
196
+ [XE](http://www.xe.com) for the current rates or just returns `rand(2)`:
197
+
198
+ ``` ruby
199
+ Money.default_bank = ExchangeBankWhichScrapesXeDotCom.new
200
+ ```
201
+
202
+ ### Implementations
203
+
204
+ The following is a list of Money.gem compatible currency exchange rate
205
+ implementations.
206
+
207
+ - [eu_central_bank](http://github.com/RubyMoney/eu_central_bank)
208
+ - [google_currency](http://github.com/RubyMoney/google_currency)
209
+ - [nordea](https://github.com/k33l0r/nordea)
210
+ - [nbrb_currency](https://github.com/slbug/nbrb_currency)
211
+
212
+ ## Ruby on Rails
213
+
214
+ Use the `composed_of` helper to let Active Record deal with embedding the money
215
+ object in your models. The following example requires 2 columns:
216
+
217
+ ``` ruby
218
+ :price_cents, :integer, :default => 0, :null => false
219
+ :currency, :string
220
+ ```
221
+
222
+ Then in your model file:
223
+
224
+ ``` ruby
225
+ composed_of :price,
226
+ :class_name => "Money",
227
+ :mapping => [%w(price_cents cents), %w(currency currency_as_string)],
228
+ :constructor => Proc.new { |cents, currency| Money.new(cents || 0, currency || Money.default_currency) },
229
+ :converter => Proc.new { |value| value.respond_to?(:to_money) ? value.to_money : raise(ArgumentError, "Can't convert #{value.class} to Money") }
230
+ ```
231
+
232
+ For Money 2.2.x and previous versions, simply use the following `composed_of`
233
+ definition:
234
+
235
+ ``` ruby
236
+ composed_of :price,
237
+ :class_name => "Money",
238
+ :mapping => [%w(cents cents), %w(currency currency)],
239
+ :constructor => Proc.new { |cents, currency| Money.new(cents || 0, currency || Money.default_currency) }
240
+ ```
241
+
242
+ Note the difference in the currency column mapping (currency_as_string vs. currency) - this matters! For further details read the full discussion
243
+ [here](http://github.com/RubyMoney/money/issues/4#comment_224880).