money-joshm1 5.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +475 -0
- data/LICENSE +21 -0
- data/README.md +257 -0
- data/Rakefile +52 -0
- data/config/currency_backwards_compatible.json +128 -0
- data/config/currency_iso.json +2297 -0
- data/config/currency_non_iso.json +30 -0
- data/lib/money.rb +6 -0
- data/lib/money/bank/base.rb +130 -0
- data/lib/money/bank/variable_exchange.rb +252 -0
- data/lib/money/core_extensions.rb +82 -0
- data/lib/money/currency.rb +355 -0
- data/lib/money/currency/heuristics.rb +149 -0
- data/lib/money/currency/loader.rb +22 -0
- data/lib/money/money.rb +536 -0
- data/lib/money/money/arithmetic.rb +288 -0
- data/lib/money/money/formatting.rb +315 -0
- data/lib/money/money/parsing.rb +371 -0
- data/money.gemspec +29 -0
- data/spec/bank/base_spec.rb +77 -0
- data/spec/bank/variable_exchange_spec.rb +233 -0
- data/spec/core_extensions_spec.rb +160 -0
- data/spec/currency/heuristics_spec.rb +84 -0
- data/spec/currency_spec.rb +183 -0
- data/spec/money/arithmetic_spec.rb +598 -0
- data/spec/money/formatting_spec.rb +466 -0
- data/spec/money/parsing_spec.rb +309 -0
- data/spec/money_spec.rb +497 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/support/default_currency_helper.rb +13 -0
- metadata +145 -0
data/LICENSE
ADDED
@@ -0,0 +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.
|
data/README.md
ADDED
@@ -0,0 +1,257 @@
|
|
1
|
+
# RubyMoney - Money
|
2
|
+
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/money.png)](http://badge.fury.io/rb/money) [![Build Status](https://travis-ci.org/RubyMoney/money.png?branch=master)](https://travis-ci.org/RubyMoney/money) [![Code Climate](https://codeclimate.com/github/RubyMoney/money.png)](https://codeclimate.com/github/RubyMoney/money)
|
4
|
+
|
5
|
+
## Contributing
|
6
|
+
|
7
|
+
See the [Contribution Guidelines](https://github.com/RubyMoney/money/blob/master/CONTRIBUTING.md)
|
8
|
+
|
9
|
+
## Introduction
|
10
|
+
|
11
|
+
This library aids one in handling money and different currencies.
|
12
|
+
|
13
|
+
### Features
|
14
|
+
|
15
|
+
- Provides a `Money` class which encapsulates all information about an certain
|
16
|
+
amount of money, such as its value and its currency.
|
17
|
+
- Provides a `Money::Currency` class which encapsulates all information about
|
18
|
+
a monetary unit.
|
19
|
+
- Represents monetary values as integers, in cents. This avoids floating point
|
20
|
+
rounding errors.
|
21
|
+
- Represents currency as `Money::Currency` instances providing an high level of
|
22
|
+
flexibility.
|
23
|
+
- Provides APIs for exchanging money from one currency to another.
|
24
|
+
- Has the ability to parse a money and currency strings
|
25
|
+
into the corresponding Money/Currency object.
|
26
|
+
|
27
|
+
### Resources
|
28
|
+
|
29
|
+
- [Website](http://rubymoney.github.com/money)
|
30
|
+
- [API Documentation](http://rubydoc.info/gems/money/frames)
|
31
|
+
- [Git Repository](http://github.com/RubyMoney/money)
|
32
|
+
|
33
|
+
### Notes
|
34
|
+
|
35
|
+
- Your app must use UTF-8 to function with this library. There are a
|
36
|
+
number of non-ASCII currency attributes.
|
37
|
+
- This app requires Ruby 1.9 and JSON. If you're using JRuby < 1.7.0
|
38
|
+
you'll need to add `gem "json"` to your Gemfile or similar.
|
39
|
+
|
40
|
+
## Downloading
|
41
|
+
|
42
|
+
Install stable releases with the following command:
|
43
|
+
|
44
|
+
gem install money
|
45
|
+
|
46
|
+
The development version (hosted on Github) can be installed with:
|
47
|
+
|
48
|
+
git clone git://github.com/RubyMoney/money.git
|
49
|
+
cd money
|
50
|
+
rake install
|
51
|
+
|
52
|
+
## Usage
|
53
|
+
|
54
|
+
``` ruby
|
55
|
+
require 'money'
|
56
|
+
|
57
|
+
# 10.00 USD
|
58
|
+
money = Money.new(1000, "USD")
|
59
|
+
money.cents #=> 1000
|
60
|
+
money.currency #=> Currency.new("USD")
|
61
|
+
|
62
|
+
# Comparisons
|
63
|
+
Money.new(1000, "USD") == Money.new(1000, "USD") #=> true
|
64
|
+
Money.new(1000, "USD") == Money.new(100, "USD") #=> false
|
65
|
+
Money.new(1000, "USD") == Money.new(1000, "EUR") #=> false
|
66
|
+
Money.new(1000, "USD") != Money.new(1000, "EUR") #=> true
|
67
|
+
|
68
|
+
# Arithmetic
|
69
|
+
Money.new(1000, "USD") + Money.new(500, "USD") == Money.new(1500, "USD")
|
70
|
+
Money.new(1000, "USD") - Money.new(200, "USD") == Money.new(800, "USD")
|
71
|
+
Money.new(1000, "USD") / 5 == Money.new(200, "USD")
|
72
|
+
Money.new(1000, "USD") * 5 == Money.new(5000, "USD")
|
73
|
+
|
74
|
+
# Assumptive Currencies
|
75
|
+
Money.assume_from_symbol = true
|
76
|
+
Money.parse("$100") == Money.new(10000, "USD")
|
77
|
+
Money.parse("€100") == Money.new(10000, "EUR")
|
78
|
+
Money.parse("£100") == Money.new(10000, "GBP")
|
79
|
+
|
80
|
+
# Currency conversions
|
81
|
+
some_code_to_setup_exchange_rates
|
82
|
+
Money.new(1000, "USD").exchange_to("EUR") == Money.new(some_value, "EUR")
|
83
|
+
```
|
84
|
+
|
85
|
+
## Currency
|
86
|
+
|
87
|
+
Currencies are consistently represented as instances of `Money::Currency`.
|
88
|
+
The most part of `Money` APIs allows you to supply either a `String` or a
|
89
|
+
`Money::Currency`.
|
90
|
+
|
91
|
+
``` ruby
|
92
|
+
Money.new(1000, "USD") == Money.new(1000, Currency.new("USD"))
|
93
|
+
Money.new(1000, "EUR").currency == Currency.new("EUR")
|
94
|
+
```
|
95
|
+
|
96
|
+
A `Money::Currency` instance holds all the information about the currency,
|
97
|
+
including the currency symbol, name and much more.
|
98
|
+
|
99
|
+
``` ruby
|
100
|
+
currency = Money.new(1000, "USD").currency
|
101
|
+
currency.iso_code #=> "USD"
|
102
|
+
currency.name #=> "United States Dollar"
|
103
|
+
```
|
104
|
+
|
105
|
+
To define a new `Money::Currency` use `Money::Currency.register` as shown
|
106
|
+
below.
|
107
|
+
|
108
|
+
``` ruby
|
109
|
+
curr = {
|
110
|
+
:priority => 1,
|
111
|
+
:iso_code => "USD",
|
112
|
+
:iso_numeric => "840",
|
113
|
+
:name => "United States Dollar",
|
114
|
+
:symbol => "$",
|
115
|
+
:subunit => "Cent",
|
116
|
+
:subunit_to_unit => 100,
|
117
|
+
:separator => ".",
|
118
|
+
:delimiter => ","
|
119
|
+
}
|
120
|
+
|
121
|
+
Money::Currency.register(curr)
|
122
|
+
```
|
123
|
+
|
124
|
+
The pre-defined set of attributes includes:
|
125
|
+
|
126
|
+
- `:priority` a numerical value you can use to sort/group the currency list
|
127
|
+
- `:iso_code` the international 3-letter code as defined by the ISO 4217 standard
|
128
|
+
- `:iso_numeric` the international 3-digit code as defined by the ISO 4217 standard
|
129
|
+
- `:name` the currency name
|
130
|
+
- `:symbol` the currency symbol (UTF-8 encoded)
|
131
|
+
- `:subunit` the name of the fractional monetary unit
|
132
|
+
- `:subunit_to_unit` the proportion between the unit and the subunit
|
133
|
+
- `:separator` character between the whole and fraction amounts
|
134
|
+
- `:delimiter` character between each thousands place
|
135
|
+
|
136
|
+
All attributes are optional. Some attributes, such as `:symbol`, are used by
|
137
|
+
the Money class to print out a representation of the object. Other attributes,
|
138
|
+
such as `:name` or `:priority`, exist to provide a basic API you can take
|
139
|
+
advantage of to build your application.
|
140
|
+
|
141
|
+
### :priority
|
142
|
+
|
143
|
+
The priority attribute is an arbitrary numerical value you can assign to the
|
144
|
+
`Money::Currency` and use in sorting/grouping operation.
|
145
|
+
|
146
|
+
For instance, let's assume your Rails application needs to render a currency
|
147
|
+
selector like the one available
|
148
|
+
[here](http://finance.yahoo.com/currency-converter/). You can create a couple of
|
149
|
+
custom methods to return the list of major currencies and all currencies as
|
150
|
+
follows:
|
151
|
+
|
152
|
+
``` ruby
|
153
|
+
# Returns an array of currency id where
|
154
|
+
# priority < 10
|
155
|
+
def major_currencies(hash)
|
156
|
+
hash.inject([]) do |array, (id, attributes)|
|
157
|
+
priority = attributes[:priority]
|
158
|
+
if priority && priority < 10
|
159
|
+
array[priority] ||= []
|
160
|
+
array[priority] << id
|
161
|
+
end
|
162
|
+
array
|
163
|
+
end.compact.flatten
|
164
|
+
end
|
165
|
+
|
166
|
+
# Returns an array of all currency id
|
167
|
+
def all_currencies(hash)
|
168
|
+
hash.keys
|
169
|
+
end
|
170
|
+
|
171
|
+
major_currencies(Money::Currency.table)
|
172
|
+
# => [ :usd, :eur, :bgp, :cad ]
|
173
|
+
|
174
|
+
all_currencies(Money::Currency.table)
|
175
|
+
# => [ :aed, :afn, all, ... ]
|
176
|
+
```
|
177
|
+
|
178
|
+
### Default Currency
|
179
|
+
|
180
|
+
By default `Money` defaults to USD as its currency. This can be overwritten
|
181
|
+
using:
|
182
|
+
|
183
|
+
``` ruby
|
184
|
+
Money.default_currency = Money::Currency.new("CAD")
|
185
|
+
```
|
186
|
+
|
187
|
+
If you use Rails, then `environment.rb` is a very good place to put this.
|
188
|
+
|
189
|
+
### Currency Exponent
|
190
|
+
|
191
|
+
The exponent of a money value is the number of digits after the decimal
|
192
|
+
separator (which separates the major unit from the minor unit). See e.g.
|
193
|
+
[Wikipedia on ISO 4217](http://en.wikipedia.org/wiki/ISO_4217) for more
|
194
|
+
information. You can find the exponent (as a `Float`) by
|
195
|
+
|
196
|
+
``` ruby
|
197
|
+
Money::Currency.new("USD").exponent # => 2.0
|
198
|
+
Money::Currency.new("JPY").exponent # => 0.0
|
199
|
+
Money::Currency.new("MGA").exponent # => 0.6989700043360189
|
200
|
+
```
|
201
|
+
|
202
|
+
### Currency Lookup
|
203
|
+
|
204
|
+
To find a given currency by ISO 4217 numeric code (three digits) you can do
|
205
|
+
|
206
|
+
``` ruby
|
207
|
+
Money::Currency.find_by_iso_numeric(978) #=> Money::Currency.new(:eur)
|
208
|
+
```
|
209
|
+
|
210
|
+
## Currency Exchange
|
211
|
+
|
212
|
+
Exchanging money is performed through an exchange bank object. The default
|
213
|
+
exchange bank object requires one to manually specify the exchange rate. Here's
|
214
|
+
an example of how it works:
|
215
|
+
|
216
|
+
``` ruby
|
217
|
+
Money.add_rate("USD", "CAD", 1.24515)
|
218
|
+
Money.add_rate("CAD", "USD", 0.803115)
|
219
|
+
|
220
|
+
Money.us_dollar(100).exchange_to("CAD") # => Money.new(124, "CAD")
|
221
|
+
Money.ca_dollar(100).exchange_to("USD") # => Money.new(80, "USD")
|
222
|
+
```
|
223
|
+
|
224
|
+
Comparison and arithmetic operations work as expected:
|
225
|
+
|
226
|
+
``` ruby
|
227
|
+
Money.new(1000, "USD") <=> Money.new(900, "USD") # => 1; 9.00 USD is smaller
|
228
|
+
Money.new(1000, "EUR") + Money.new(10, "EUR") == Money.new(1010, "EUR")
|
229
|
+
|
230
|
+
Money.add_rate("USD", "EUR", 0.5)
|
231
|
+
Money.new(1000, "EUR") + Money.new(1000, "USD") == Money.new(1500, "EUR")
|
232
|
+
```
|
233
|
+
|
234
|
+
There is nothing stopping you from creating bank objects which scrapes
|
235
|
+
[XE](http://www.xe.com) for the current rates or just returns `rand(2)`:
|
236
|
+
|
237
|
+
``` ruby
|
238
|
+
Money.default_bank = ExchangeBankWhichScrapesXeDotCom.new
|
239
|
+
```
|
240
|
+
|
241
|
+
### Implementations
|
242
|
+
|
243
|
+
The following is a list of Money.gem compatible currency exchange rate
|
244
|
+
implementations.
|
245
|
+
|
246
|
+
- [eu_central_bank](http://github.com/RubyMoney/eu_central_bank)
|
247
|
+
- [google_currency](http://github.com/RubyMoney/google_currency)
|
248
|
+
- [nordea](https://github.com/k33l0r/nordea)
|
249
|
+
- [nbrb_currency](https://github.com/slbug/nbrb_currency)
|
250
|
+
- [money-open-exchange-rates](https://github.com/spk/money-open-exchange-rates)
|
251
|
+
- [money-historical-bank](https://github.com/atwam/money-historical-bank)
|
252
|
+
|
253
|
+
## Ruby on Rails
|
254
|
+
|
255
|
+
To integrate money in a Rails application use [money-rails](http://github.com/RubyMoney/money-rails).
|
256
|
+
|
257
|
+
For deprecated methods of integrating with Rails, check [the wiki](https://github.com/RubyMoney/money/wiki).
|
data/Rakefile
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/clean'
|
3
|
+
|
4
|
+
CLOBBER.include('doc', '.yardoc')
|
5
|
+
|
6
|
+
def gemspec
|
7
|
+
@gemspec ||= begin
|
8
|
+
file = File.expand_path("../money.gemspec", __FILE__)
|
9
|
+
eval(File.read(file), binding, file)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
task :default => :spec
|
15
|
+
task :test => :spec
|
16
|
+
|
17
|
+
|
18
|
+
require 'rspec/core/rake_task'
|
19
|
+
|
20
|
+
RSpec::Core::RakeTask.new
|
21
|
+
|
22
|
+
|
23
|
+
require 'yard'
|
24
|
+
|
25
|
+
YARD::Rake::YardocTask.new do |t|
|
26
|
+
t.options << "--files" << "CHANGELOG.md,LICENSE"
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
require 'rubygems/package_task'
|
31
|
+
|
32
|
+
Gem::PackageTask.new(gemspec) do |pkg|
|
33
|
+
pkg.gem_spec = gemspec
|
34
|
+
end
|
35
|
+
|
36
|
+
task :gem => :gemspec
|
37
|
+
|
38
|
+
desc "Install the gem locally"
|
39
|
+
task :install => :gem do
|
40
|
+
sh "gem install pkg/#{gemspec.full_name}.gem"
|
41
|
+
end
|
42
|
+
|
43
|
+
desc "Validate the gemspec"
|
44
|
+
task :gemspec do
|
45
|
+
gemspec.validate
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
desc "Open an irb session preloaded with this library"
|
50
|
+
task :console do
|
51
|
+
sh "irb -rubygems -I lib -r money.rb"
|
52
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
{
|
2
|
+
"eek": {
|
3
|
+
"priority": 100,
|
4
|
+
"iso_code": "EEK",
|
5
|
+
"name": "Estonian Kroon",
|
6
|
+
"symbol": "KR",
|
7
|
+
"alternate_symbols": [],
|
8
|
+
"subunit": "Sent",
|
9
|
+
"subunit_to_unit": 100,
|
10
|
+
"symbol_first": false,
|
11
|
+
"html_entity": "",
|
12
|
+
"decimal_mark": ".",
|
13
|
+
"thousands_separator": ",",
|
14
|
+
"iso_numeric": "233"
|
15
|
+
},
|
16
|
+
"ghc": {
|
17
|
+
"priority": 100,
|
18
|
+
"iso_code": "GHS",
|
19
|
+
"name": "Ghanaian Cedi",
|
20
|
+
"symbol": "₵",
|
21
|
+
"alternate_symbols": ["GH₵"],
|
22
|
+
"subunit": "Pesewa",
|
23
|
+
"subunit_to_unit": 100,
|
24
|
+
"symbol_first": true,
|
25
|
+
"html_entity": "₵",
|
26
|
+
"decimal_mark": ".",
|
27
|
+
"thousands_separator": ",",
|
28
|
+
"iso_numeric": "288"
|
29
|
+
},
|
30
|
+
"mtl": {
|
31
|
+
"priority": 100,
|
32
|
+
"iso_code": "MTL",
|
33
|
+
"name": "Maltese Lira",
|
34
|
+
"symbol": "₤",
|
35
|
+
"alternate_symbols": ["Lm"],
|
36
|
+
"subunit": "Cent",
|
37
|
+
"subunit_to_unit": 100,
|
38
|
+
"symbol_first": true,
|
39
|
+
"html_entity": "£",
|
40
|
+
"decimal_mark": ".",
|
41
|
+
"thousands_separator": ",",
|
42
|
+
"iso_numeric": "470"
|
43
|
+
},
|
44
|
+
"tmm": {
|
45
|
+
"priority": 100,
|
46
|
+
"iso_code": "TMM",
|
47
|
+
"name": "Turkmenistani Manat",
|
48
|
+
"symbol": "m",
|
49
|
+
"alternate_symbols": [],
|
50
|
+
"subunit": "Tennesi",
|
51
|
+
"subunit_to_unit": 100,
|
52
|
+
"symbol_first": false,
|
53
|
+
"html_entity": "",
|
54
|
+
"decimal_mark": ".",
|
55
|
+
"thousands_separator": ",",
|
56
|
+
"iso_numeric": "795"
|
57
|
+
},
|
58
|
+
"yen": {
|
59
|
+
"priority": 100,
|
60
|
+
"iso_code": "JPY",
|
61
|
+
"name": "Japanese Yen",
|
62
|
+
"symbol": "¥",
|
63
|
+
"alternate_symbols": ["円", "圓"],
|
64
|
+
"subunit": "Sen",
|
65
|
+
"subunit_to_unit": 100,
|
66
|
+
"symbol_first": true,
|
67
|
+
"html_entity": "¥",
|
68
|
+
"decimal_mark": ".",
|
69
|
+
"thousands_separator": ",",
|
70
|
+
"iso_numeric": ""
|
71
|
+
},
|
72
|
+
"zwd": {
|
73
|
+
"priority": 100,
|
74
|
+
"iso_code": "ZWD",
|
75
|
+
"name": "Zimbabwean Dollar",
|
76
|
+
"symbol": "$",
|
77
|
+
"alternate_symbols": ["Z$"],
|
78
|
+
"subunit": "Cent",
|
79
|
+
"subunit_to_unit": 100,
|
80
|
+
"symbol_first": true,
|
81
|
+
"html_entity": "$",
|
82
|
+
"decimal_mark": ".",
|
83
|
+
"thousands_separator": ",",
|
84
|
+
"iso_numeric": "716"
|
85
|
+
},
|
86
|
+
"zwl": {
|
87
|
+
"priority": 100,
|
88
|
+
"iso_code": "ZWL",
|
89
|
+
"name": "Zimbabwean Dollar",
|
90
|
+
"symbol": "$",
|
91
|
+
"alternate_symbols": ["Z$"],
|
92
|
+
"subunit": "Cent",
|
93
|
+
"subunit_to_unit": 100,
|
94
|
+
"symbol_first": true,
|
95
|
+
"html_entity": "$",
|
96
|
+
"decimal_mark": ".",
|
97
|
+
"thousands_separator": ",",
|
98
|
+
"iso_numeric": "932"
|
99
|
+
},
|
100
|
+
"zwn": {
|
101
|
+
"priority": 100,
|
102
|
+
"iso_code": "ZWN",
|
103
|
+
"name": "Zimbabwean Dollar",
|
104
|
+
"symbol": "$",
|
105
|
+
"alternate_symbols": ["Z$"],
|
106
|
+
"subunit": "Cent",
|
107
|
+
"subunit_to_unit": 100,
|
108
|
+
"symbol_first": true,
|
109
|
+
"html_entity": "$",
|
110
|
+
"decimal_mark": ".",
|
111
|
+
"thousands_separator": ",",
|
112
|
+
"iso_numeric": "942"
|
113
|
+
},
|
114
|
+
"zwr": {
|
115
|
+
"priority": 100,
|
116
|
+
"iso_code": "ZWR",
|
117
|
+
"name": "Zimbabwean Dollar",
|
118
|
+
"symbol": "$",
|
119
|
+
"alternate_symbols": ["Z$"],
|
120
|
+
"subunit": "Cent",
|
121
|
+
"subunit_to_unit": 100,
|
122
|
+
"symbol_first": true,
|
123
|
+
"html_entity": "$",
|
124
|
+
"decimal_mark": ".",
|
125
|
+
"thousands_separator": ",",
|
126
|
+
"iso_numeric": "935"
|
127
|
+
}
|
128
|
+
}
|