ecr_money 3.6.5

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md ADDED
@@ -0,0 +1,309 @@
1
+ Money 3.x.x
2
+ ===========
3
+
4
+ Features
5
+ --------
6
+ - Add a symbol position option for Money#format (thanks Romain, Gil and
7
+ Julien)
8
+
9
+ Bigfixes
10
+ --------
11
+ - Fixed issue with #format(:no_cents => true) (thanks Romain & Julien)
12
+
13
+ Money 3.5.5
14
+ ===========
15
+
16
+ Features
17
+ --------
18
+ - Enhancements to Money::Currency (thanks Matthew McEachen)
19
+ - Replace delimiter with thousands_separator
20
+ - Replace separator with decimal_mark
21
+ - Added symbol_first and html_entity
22
+ - Added allocation algorithm for fair(ish) splitting of money between parties
23
+ without loosing pennies (thanks Tobias Luetke)
24
+
25
+ Bugfixes
26
+ --------
27
+ - Always store cents as an Integer (thanks Abhay Kumar)
28
+ - Fixed TypeError in rate exchange (thanks Christian Billen)
29
+ - Cleanup #parse (thanks Tom Lianza)
30
+
31
+ Money 3.5.4
32
+ ===========
33
+
34
+ Features
35
+ --------
36
+ - Added Currency#decimal_places.
37
+
38
+ Bugfixes
39
+ --------
40
+ - Fixed error with Money#to_s error with negative amounts that are only cents.
41
+
42
+ Money 3.5.3
43
+ ===========
44
+
45
+ Bugfixes
46
+ --------
47
+ - Fixed an error in #to_s when cents is negative
48
+
49
+ Money 3.5.2
50
+ ===========
51
+
52
+ Bugfixes
53
+ --------
54
+ - Fixed an error in #to_s which appended extra 0s incorrectly
55
+
56
+ Money 3.5.1
57
+ ===========
58
+
59
+ Bugfixes
60
+ --------
61
+ - Removed erroneous require.
62
+
63
+ Money 3.5.0
64
+ ===========
65
+
66
+ Features
67
+ --------
68
+ - Updated to RSpec2.
69
+ - Use i18n to lookup separator and delimiter signs.
70
+ - Removed all deprecated methods up to v3.5.0, including the following:
71
+ - Using Money#format with params instead of a Hash.
72
+ - Using a Hash with Money#new.
73
+ - Using Bank#exchange, use Bank#exchange_with instead.
74
+
75
+ Bugfixes
76
+ --------
77
+ - Updated Money#to_s to respect :separator and :subunit_to_unit.
78
+ - Fixed Money#format for :subunit_to_unit != 100.
79
+ ([#issue/37](http://github.com/RubyMoney/money/issue/37))
80
+ - Fixed String#to_money for :subunit_to_unit != 100.
81
+ ([#issue/36](http://github.com/RubyMoney/money/issue/36))
82
+ - Removed duplicate currencies.
83
+ ([#issue/38](http://github.com/RubyMoney/money/issue/38))
84
+ - Fixed issue related to JRuby returning 2 for Math.log10(1000).floor instead
85
+ of correctly returning 3.
86
+
87
+ Money 3.1.5
88
+ ===========
89
+
90
+ Features
91
+ --------
92
+ - Added support for creating objects with the main monetary unit instead of
93
+ cents.
94
+ ([#issue/25](http://github.com/RubyMoney/money/issues/25))
95
+ - Deprecated `Money#format` with separate params instead of Hash. Deprecation
96
+ target set to Money 3.5.0.
97
+ ([#issue/31](http://github.com/RubyMoney/money/issues/31))
98
+ - Deprecated `Money#new(0, :currency => "EUR")` in favor of
99
+ `Money#new(0, "EUR")`. Deprecation target set to Money 3.5.0.
100
+ ([#issue/31](http://github.com/RubyMoney/money/issues/31))
101
+ - Throw ArgumentError when trying to multiply two Money objects together.
102
+ ([#issue/29](http://github.com/RubyMoney/money/issues/29))
103
+ - Update Money#parse to use :subunit_to_unit
104
+ ([#issue/30](http://github.com/RubyMoney/money/issues/30))
105
+
106
+ Bugfixes
107
+ --------
108
+ - Downgraded required_rubygems_version to >= 1.3.6.
109
+ ([#issue/26](http://github.com/RubyMoney/money/issues/26))
110
+ - Use BigDecimal when floating point calculations are needed.
111
+ - Ruby 1.9.2 compatibility enhancements.
112
+
113
+
114
+ Money 3.1.0
115
+ ===========
116
+
117
+ Features
118
+ --------
119
+ - Implemented `Money::Bank::Base`.
120
+ ([#issue/14](http://github.com/RubyMoney/money/issues/14))
121
+ - Added `Money::Bank::Base#exchange_with`.
122
+ - Deprecated `Money::Bank::Base#exchange`. Deprecation target set to Money
123
+ 3.2.0.
124
+ - Implented `Money::Bank::VariableExchange`
125
+ - Deprecated `Money::VariableExchangeBank`. Deprecation target set to Money
126
+ 3.2.0.
127
+ - Deprecate `Money::SYMBOLS`, `Money::SEPARATORS` and `Money::DELIMITERS`.
128
+ Deprecation target set to Money 3.2.0.
129
+ ([#issue/16](http://github.com/RubyMoney/money/issues/16))
130
+ - Implemented `#has` for `Money` and `Money::Currency`.
131
+ - Refactored test suite to conform to RSpec conventions.
132
+ - Moved project from [FooBarWidget](http://github.com/FooBarWidget) to
133
+ [RubyMoney](http://github.com/RubyMoney)
134
+ - Added Simone Carletti to list of authors.
135
+ - Moved `@rounding_method` from `Money::Bank::VariableExchange` to
136
+ `Money::Bank::Base`.
137
+ ([#issue/18](http://github.com/RubyMoney/money/issues/18))
138
+ - Added `#setup` to `Money::Bank::Base`. Called from `#initialize`.
139
+ ([#issue/19](http://github.com/RubyMoney/money/issues/19))
140
+ - Added [google_currency](http://github.com/RubyMoney/google_currency) to list
141
+ of Currency Exchange Implementations.
142
+ - Added `#export_rates` to `Money::Bank::VariableExchange`.
143
+ ([#issue/21](http://github.com/RubyMoney/money/issues/21))
144
+ - Added `#import_rates` to `Money::Bank::VariableExchange`.
145
+ ([#issue/21](http://github.com/RubyMoney/money/issues/21))
146
+ - Removed dependency on Jeweler.
147
+ - Replaced usage of hanna with yardoc.
148
+ - Rewrote/reformatted all documentation.
149
+
150
+ Bugfixes
151
+ --------
152
+ - Fixed incorrect URLs in documentation.
153
+ ([#issue/17](http://github.com/RubyMoney/money/issues/17))
154
+ - Updated `:subunit_to_unit` for HKD from 10 to 100.
155
+ ([#issue/20](http://github.com/RubyMoney/money/issues/20))
156
+ - Updated Ghanaian Cedi to use correct ISO Code, GHS.
157
+ ([#issue/22](http://github.com/RubyMoney/money/issues/22))
158
+ - Make `default` rake task call `spec`.
159
+ ([#issue/23](http://github.com/RubyMoney/money/issues/23))
160
+
161
+ Money 3.1.0.pre3
162
+ ================
163
+
164
+ Features
165
+ --------
166
+ - Added [google_currency](http://github.com/RubyMoney/google_currency) to list
167
+ of Currency Exchange Implementations.
168
+ - Added `#export_rates` to `Money::Bank::VariableExchange`.
169
+ ([#issue/21](http://github.com/RubyMoney/money/issues/21))
170
+ - Added `#import_rates` to `Money::Bank::VariableExchange`.
171
+ ([#issue/21](http://github.com/RubyMoney/money/issues/21))
172
+
173
+ Bugfixes
174
+ --------
175
+ - Updated `:subunit_to_unit` for HKD from 10 to 100.
176
+ ([#issue/20](http://github.com/RubyMoney/money/issues/20))
177
+
178
+ Money 3.1.0.pre2
179
+ ================
180
+
181
+ Features
182
+ --------
183
+ - Moved `@rounding_method` from `Money::Bank::VariableExchange` to
184
+ `Money::Bank::Base`.
185
+ ([#issue/18](http://github.com/RubyMoney/money/issues/18))
186
+ - Added `#setup` to `Money::Bank::Base`. Called from `#initialize`.
187
+ ([#issue/19](http://github.com/RubyMoney/money/issues/19))
188
+
189
+ Bugfixes
190
+ --------
191
+ - Fixed incorrect URLs in documentation.
192
+ ([#issue/17](http://github.com/RubyMoney/money/issues/17))
193
+
194
+ Money 3.1.0.pre1
195
+ ================
196
+
197
+ Features
198
+ --------
199
+ - Implemented `Money::Bank::Base`.
200
+ ([#issue/14](http://github.com/RubyMoney/money/issues/14))
201
+ - Added `Money::Bank::Base#exchange_with`.
202
+ - Deprecated `Money::Bank::Base#exchange`. Deprecation target set to Money
203
+ 3.2.0.
204
+ - Implented `Money::Bank::VariableExchange`
205
+ - Deprecated `Money::VariableExchangeBank`. Deprecation target set to Money
206
+ 3.2.0.
207
+ - Deprecate `Money::SYMBOLS`, `Money::SEPARATORS` and `Money::DELIMITERS`.
208
+ Deprecation target set to Money 3.2.0.
209
+ ([#issue/16](http://github.com/RubyMoney/money/issues/16))
210
+ - Implemented `#has` for `Money` and `Money::Currency`.
211
+ - Refactored test suite to conform to RSpec conventions.
212
+ - Moved project from [FooBarWidget](http://github.com/FooBarWidget) to
213
+ [RubyMoney](http://github.com/RubyMoney)
214
+ - Added Simone Carletti to list of authors.
215
+
216
+ Bugfixes
217
+ --------
218
+ - Fixed rounding error in `Numeric#to_money`.
219
+ ([#issue/15](http://github.com/RubyMoney/money/issues/15))
220
+
221
+ Money 3.0.5
222
+ ===========
223
+
224
+ Features
225
+ --------
226
+ - Added `Money#abs`.
227
+ - Added ability to pass a block to `VariableExchangeBank#new` or `#exchange`,
228
+ specifying a custom truncation method
229
+ - Added optional `currency` argument to` Numeric#to_money`.
230
+ ([#issue/11](http://github.com/RubyMoney/money/issues/11))
231
+ - Added optional `currency` argument to `String#to_money`.
232
+ ([#issue/11](http://github.com/RubyMoney/money/issues/11))
233
+ - Use '¤' as the default currency symbol.
234
+ ([#issue/10](http://github.com/RubyMoney/money/issues/10))
235
+
236
+ Bugfixes
237
+ --------
238
+ - Updated `Currency#subunit_to_unit` documentation (it's an integer not a
239
+ string).
240
+ - Fixed issue when exchanging currencies with different `:subunit_to_unit`
241
+ values.
242
+ - `Numeric#to_money` now respects `:subunit_to_unit`.
243
+ ([#issue/12](http://github.com/RubyMoney/money/issues/12))
244
+
245
+ Money 3.0.4
246
+ ===========
247
+
248
+ Features
249
+ --------
250
+ - Use `:subunit_to_unit` in `#to_s`, `#to_f` and `#format`.
251
+ - Deprecated `Money#SEPARATORS` and `Money#DELIMITERS`.
252
+
253
+ Bugfixes
254
+ --------
255
+ - Updated `#exchange` to avoid floating point rounding errors.
256
+ - Added `:separator` and `:delimiter` to `Currency`
257
+ - Updated the attributes of the Chilean Peso.
258
+
259
+ Money 3.0.3
260
+ ===========
261
+
262
+ Features
263
+ --------
264
+ - Added `#currency_as_string` and `#currency_as_string=` for easier
265
+ integration with ActiveRecord/Rails
266
+
267
+ Money 3.0.2
268
+ ===========
269
+
270
+ Features
271
+ --------
272
+ - Added `#div`, `#divmod`, `#modulo`, `#%` and `#remainder` to `Money`.
273
+
274
+ Money 3.0.1
275
+ ===========
276
+
277
+ Features
278
+ --------
279
+ - Added `#eql?` to `Money`
280
+ - Updated `Numeric#to_money` to work with all children of `Numeric` (i.e.
281
+ `BigDecimal`, `Integer`, `Fixnum`, `Float`, etc)
282
+
283
+ Money 3.0.0
284
+ ===========
285
+
286
+ Features
287
+ --------
288
+ - Version Bump due to compatibility changes with ActiveRecord. See
289
+ conversation
290
+ [here](http://github.com/RubyMoney/money/issues#issue/4/comment/224880)
291
+ for more information.
292
+
293
+ Money 2.3.0
294
+ ===========
295
+
296
+ Features
297
+ --------
298
+ - Currency is now represented by a `Currency` Object instead of a `String`.
299
+
300
+ Money 2.2.0
301
+ ===========
302
+
303
+ Features
304
+ --------
305
+ - Can now divide two Money objects by one another using `#/`.
306
+ - Can now convert a Money object to a float using `#to_f`.
307
+ - Users can now specify Separators and Delimiters when using `#format`.
308
+ - Support for Brazilian Real `Money.new(1_00, :BRL)`
309
+ - Migrated to Jeweler
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,209 @@
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 a `cents` and a
192
+ `currency` field.
193
+
194
+ composed_of :price,
195
+ :class_name => "Money",
196
+ :mapping => [%w(cents cents), %w(currency currency_as_string)],
197
+ :constructor => Proc.new { |cents, currency| Money.new(cents || 0, currency || Money.default_currency) },
198
+ :converter => Proc.new { |value| value.respond_to?(:to_money) ? value.to_money : raise(ArgumentError, "Can't convert #{value.class} to Money") }
199
+
200
+ For Money 2.2.x and previous versions, simply use the following `composed_of`
201
+ definition:
202
+
203
+ composed_of :price,
204
+ :class_name => "Money",
205
+ :mapping => [%w(cents cents), %w(currency currency)],
206
+ :constructor => Proc.new { |cents, currency| Money.new(cents || 0, currency || Money.default_currency) }
207
+
208
+ For further details read the full discussion
209
+ [here](http://github.com/RubyMoney/money/issues/4#comment_224880).
@@ -0,0 +1,131 @@
1
+ require 'thread'
2
+
3
+ class Money
4
+ # Provides classes that aid in the ability of exchange one currency with
5
+ # another.
6
+ module Bank
7
+
8
+ # The lowest Money::Bank error class.
9
+ # All Money::Bank errors should inherit from it.
10
+ class Error < StandardError
11
+ end
12
+
13
+ # Raised when the bank doesn't know about the conversion rate
14
+ # for specified currencies.
15
+ class UnknownRate < Error
16
+ end
17
+
18
+
19
+ # Money::Bank::Base is the basic interface for creating a money exchange
20
+ # object, also called Bank.
21
+ #
22
+ # A Bank is responsible for storing exchange rates, take a Money object as
23
+ # input and returns the corresponding Money object converted into an other
24
+ # currency.
25
+ #
26
+ # This class exists for aiding in the creating of other classes to exchange
27
+ # money between different currencies. When creating a subclass you will
28
+ # need to implement the following methods to exchange money between
29
+ # currencies:
30
+ #
31
+ # - #exchange_with(Money) #=> Money
32
+ #
33
+ # See Money::Bank::VariableExchange for a real example.
34
+ #
35
+ # Also, you can extend +Money::Bank::VariableExchange+ instead of
36
+ # +Money::Bank::Base+ if your bank implementation needs to store rates
37
+ # internally.
38
+ #
39
+ # @abstract Subclass and override +#exchange_with+ to implement a custom
40
+ # +Money::Bank+ class. You can also override +#setup+ instead of
41
+ # +#initialize+ to setup initial variables, etc.
42
+ class Base
43
+
44
+ # Returns the singleton instance of the Base bank.
45
+ #
46
+ # @return [Money::Bank::Base]
47
+ def self.instance
48
+ @@singleton ||= self.new
49
+ end
50
+
51
+ # The rounding method to use when exchanging rates.
52
+ #
53
+ # @return [Proc]
54
+ attr_reader :rounding_method
55
+
56
+ # Initializes a new +Money::Bank::Base+ object. An optional block can be
57
+ # passed to dictate the rounding method that +#exchange_with+ can use.
58
+ #
59
+ # @yield [n] Optional block to use when rounding after exchanging one
60
+ # currency for another.
61
+ # @yieldparam [Float] n The resulting float after exchanging one currency
62
+ # for another.
63
+ # @yieldreturn [Integer]
64
+ #
65
+ # @return [Money::Bank::Base]
66
+ #
67
+ # @example
68
+ # Money::Bank::Base.new #=> #<Money::Bank::Base @rounding_method=nil>
69
+ # Money::Bank::Base.new {|n|
70
+ # n.floor
71
+ # } #=> #<Money::Bank::Base @round_method=#<Proc>>
72
+ def initialize(&block)
73
+ @rounding_method = block
74
+ setup
75
+ end
76
+
77
+ # Called after initialize. Subclasses can use this method to setup
78
+ # variables, etc that they normally would in +#initialize+.
79
+ #
80
+ # @abstract Subclass and override +#setup+ to implement a custom
81
+ # +Money::Bank+ class.
82
+ #
83
+ # @return [self]
84
+ def setup
85
+ end
86
+
87
+ # Exchanges the given +Money+ object to a new +Money+ object in
88
+ # +to_currency+.
89
+ #
90
+ # @abstract Subclass and override +#exchange_with+ to implement a custom
91
+ # +Money::Bank+ class.
92
+ #
93
+ # @raise NotImplementedError
94
+ #
95
+ # @param [Money] from The +Money+ object to exchange from.
96
+ # @param [Money::Currency, String, Symbol] to_currency The currency
97
+ # string or object to exchange to.
98
+ # @yield [n] Optional block to use to round the result after making
99
+ # the exchange.
100
+ # @yieldparam [Float] n The result after exchanging from one currency to
101
+ # the other.
102
+ # @yieldreturn [Integer]
103
+ #
104
+ # @return [Money]
105
+ def exchange_with(from, to_currency, &block)
106
+ raise NotImplementedError, "#exchange_with must be implemented"
107
+ end
108
+
109
+
110
+ # Given two currency strings or object, checks whether they're both the
111
+ # same currency. Return +true+ if the currencies are the same, +false+
112
+ # otherwise.
113
+ #
114
+ # @param [Money::Currency, String, Symbol] currency1 The first currency
115
+ # to compare.
116
+ # @param [Money::Currency, String, Symbol] currency2 The second currency
117
+ # to compare.
118
+ #
119
+ # @return [Boolean]
120
+ #
121
+ # @example
122
+ # same_currency?("usd", "USD") #=> true
123
+ # same_currency?("usd", "EUR") #=> false
124
+ # same_currency?("usd", Currency.new("USD") #=> true
125
+ # same_currency?("usd", "USD") #=> true
126
+ def same_currency?(currency1, currency2)
127
+ Currency.wrap(currency1) == Currency.wrap(currency2)
128
+ end
129
+ end
130
+ end
131
+ end