nofxx-money 2.3.6 → 2.3.8

Sign up to get free protection for your applications and to get access to all the features.
data/Manifest.txt CHANGED
@@ -22,4 +22,3 @@ spec/money/exchange_bank_spec.rb
22
22
  spec/money/money_spec.rb
23
23
  spec/spec.opts
24
24
  spec/spec_helper.rb
25
- tmp/acts_as_money.sqlite3
data/README.rdoc CHANGED
@@ -10,28 +10,14 @@ This library aids one in handling money and different currencies. Features:
10
10
  - Has the ability to parse a money string into a Money object.
11
11
  - Provides ActiveRecord "has_money" method.
12
12
 
13
- Resources:
14
-
15
- - Website: http://money.rubyforge.org
16
- - RDoc API: http://money.rubyforge.org
17
- - This fork: http://github.com/ShadowBelmolve/money
18
- - Forked from: http://github.com/nofxx/money
19
- - Git repository: http://github.com/FooBarWidget/money/tree/master
20
-
21
-
22
- == Download
23
-
24
- Install stable releases with the following command:
25
-
26
- gem install money
27
13
 
28
- The development version (hosted on Github) can be installed with:
14
+ == Install
29
15
 
30
16
  gem sources -a http://gems.github.com
31
- gem install nofxx-money
17
+ gem install <this-fork>-money
32
18
 
33
19
 
34
- == Usage
20
+ == Use
35
21
 
36
22
  === Synopsis
37
23
 
@@ -51,6 +37,14 @@ The development version (hosted on Github) can be installed with:
51
37
  Money.new(1000, "USD") == Money.new(1000, "EUR") # => false
52
38
 
53
39
 
40
+ === Rounding
41
+
42
+ You can use round_to_coin when you don't have currency with coins for cents.
43
+ E.g. if the smallest coin is 0.50, then
44
+
45
+ Money.new(1448, 'CZK').round_to_coin(50).to_s # => "14.50"
46
+
47
+
54
48
  === Currency Exchange
55
49
 
56
50
  Exchanging money is performed through an exchange bank object. The default
@@ -88,6 +82,17 @@ www.xe.com for the current rates or just returns <tt>rand(2)</tt>:
88
82
  Money.default_bank = ExchangeBankWhichScrapesXeDotCom.new
89
83
 
90
84
 
85
+ === Default Currency
86
+
87
+ By default Money defaults to USD as its currency. This can be overwritten using:
88
+
89
+ Money.default_currency = "CAD"
90
+
91
+ If you use Rails, then environment.rb is a very good place to put this.
92
+
93
+
94
+ == Webapps
95
+
91
96
  === Ruby on Rails
92
97
 
93
98
  Use the +has_money+ method to embed the money object in your models.
@@ -96,7 +101,7 @@ fields on the database.
96
101
 
97
102
  config/enviroment.rb
98
103
 
99
- require.gem 'nofxx-money', :lib => 'money'
104
+ require.gem 'bobek-money', :lib => 'money'
100
105
 
101
106
  app/models/product.rb
102
107
 
@@ -115,18 +120,25 @@ migration:
115
120
  end
116
121
 
117
122
 
118
- === Default Currency
123
+ === jQuery
119
124
 
120
- By default Money defaults to USD as its currency. This can be overwritten using:
125
+ Check out http://meiaduzia.com.br/cuducos2/priceformat for a nice
126
+ mask for webapp's textfields.
121
127
 
122
- Money.default_currency = "CAD"
123
128
 
124
- If you use Rails, then environment.rb is a very good place to put this.
129
+ == About
130
+
131
+ Resources:
125
132
 
133
+ Orinally developed by:
134
+
135
+ - Forked from: http://github.com/FooBarWidget/money
136
+ - Website: http://money.rubyforge.org
137
+ - RDoc API: http://money.rubyforge.org
126
138
 
127
- == TODO
128
139
 
129
- * Better validation (fix composed_of allow_nil)
130
- * Interest (almost there..)
131
- * Remote rate fetching
140
+ This branch is part of:
132
141
 
142
+ :: http://github.com/bobek/money
143
+ :: http://github.com/nofxx/money
144
+ :: http://github.com/ShadowBelmove/money
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.3.6
1
+ 2.3.8
@@ -13,7 +13,7 @@ class Numeric
13
13
  Money.new(self.to_s.gsub(/\./,'').to_i)
14
14
  end
15
15
  else
16
- Money.new(self * 100)
16
+ Money.new((self * 100).round)
17
17
  end
18
18
  end
19
19
  end
@@ -22,12 +22,12 @@ class String
22
22
  # Parses the current string and converts it to a Money object.
23
23
  # Excess characters will be discarded.
24
24
  #
25
- # '100'.to_money # => #<Money @cents=100>
25
+ # '100'.to_money # => #<Money @cents=10000>
26
26
  # '100.37'.to_money # => #<Money @cents=10037>
27
- # '100 USD'.to_money # => #<Money @cents=100, @currency="USD">
28
- # 'USD 100'.to_money # => #<Money @cents=100, @currency="USD">
29
- # '$100 USD'.to_money # => #<Money @cents=100, @currency="USD">
30
- # '$100 USD'.to_money(false) # => #<Money @cents=10000, @currency="USD">
27
+ # '100 USD'.to_money # => #<Money @cents=10000, @currency="USD">
28
+ # 'USD 100'.to_money # => #<Money @cents=10000, @currency="USD">
29
+ # '$100 USD'.to_money # => #<Money @cents=10000, @currency="USD">
30
+ # 'hello 2000 world'.to_money # => #<Money @cents=200000 @currency="USD")>
31
31
  def to_money(with_cents = false)
32
32
  # Get the currency.
33
33
  matches = scan /([A-Z]{2,3})/
@@ -38,7 +38,7 @@ class String
38
38
 
39
39
  private
40
40
 
41
- def calculate_cents(number, with_cents = true)
41
+ def calculate_cents(number, with_cents)
42
42
  # remove anything that's not a number, potential delimiter, or minus sign
43
43
  num = number.gsub(/[^\d|\.|,|\'|\s|\-]/, '').strip
44
44
 
@@ -89,12 +89,14 @@ class String
89
89
  # ex: 1,000 - 1.0000 - 10001.000
90
90
  # split number into possible major (dollars) and minor (cents) values
91
91
  possible_major, possible_minor = num.split(separator)
92
+ possible_major ||= "0"
93
+ possible_minor ||= "00"
92
94
 
93
95
  # if the minor (cents) length isn't 3, assign major/minor from the possibles
94
96
  # e.g.
95
- # 1,00 => 1.00
96
- # 1.0000 => 1.00
97
- # 1.2 => 1.20
97
+ # 1,00 => 1.00
98
+ # 1.0000 => 1.00
99
+ # 1.2 => 1.20
98
100
  if possible_minor.length != 3 # delimiter
99
101
  major, minor = possible_major, possible_minor
100
102
  else
@@ -104,8 +106,8 @@ class String
104
106
  # the major length is greater than three, which means
105
107
  # the comma or period is used as a delimiter
106
108
  # e.g.
107
- # 1000,000
108
- # 100000,000
109
+ # 1000,000
110
+ # 100000,000
109
111
  if possible_major.length > 3
110
112
  major, minor = possible_major, possible_minor
111
113
  else
@@ -124,16 +126,27 @@ class String
124
126
  end
125
127
 
126
128
  # build the string based on major/minor since separator/delimiters have been removed
127
- # transform to a float, multiply by 100 to convert to cents
128
- if with_cents and minor == 0
129
- cents = "#{major}.#{minor}".to_f
129
+ # avoiding floating point arithmetic here to ensure accuracy
130
+ if with_cents #and minor == 0
131
+ cents = major.to_i
130
132
  else
131
- cents = "#{major}.#{minor}".to_f * 100
133
+ cents = major.to_i * 100
134
+ # add the minor number as well. this may have any number of digits,
135
+ # so we treat minor as a string and truncate or right-fill it with zeroes
136
+ # until it becomes a two-digit number string, which we add to cents.
137
+ minor = minor.to_s
138
+ truncated_minor = minor[0..1]
139
+ truncated_minor << "0" * (2 - truncated_minor.size) if truncated_minor.size < 2
140
+ cents += truncated_minor.to_i
141
+ # respect rounding rules
142
+ if minor.size >= 3 && minor[2..2].to_i >= 5
143
+ cents += 1
144
+ end
132
145
  end
133
146
 
134
-
135
147
  # if negative, multiply by -1; otherwise, return positive cents
136
148
  negative ? cents * -1 : cents
137
149
  end
138
150
 
139
151
  end
152
+
@@ -26,6 +26,10 @@ end
26
26
  # bank.exchange(100_00, "USD", "CAD") # => 6450
27
27
  class Money
28
28
  class ExchangeBank
29
+ #
30
+ # Rates to be autofetched
31
+ attr_accessor :default_rates
32
+
29
33
  # Returns the singleton instance of ExchangeBank.
30
34
  #
31
35
  # By default, <tt>Money.default_bank</tt> returns the same object.
@@ -51,6 +55,7 @@ class Money
51
55
  @mutex.synchronize do
52
56
  @rates["#{from}<>#{to}".upcase] = rate
53
57
  @rates["#{to}<>#{from}".upcase] = 1.0/rate
58
+ @rates["sync_at"] = Time.now.to_i
54
59
  end
55
60
  end
56
61
 
@@ -74,21 +79,27 @@ class Money
74
79
  # Returns the amount of cents in +to_currency+ as an integer, rounded down.
75
80
  #
76
81
  # If the conversion rate is unknown, then Money::UnknownRate will be raised.
77
- def exchange(cents, from_currency, to_currency)
78
- rate = get_rate(from_currency, to_currency)
79
- if !rate
80
- raise Money::UnknownRate, "No conversion rate known for '#{from_currency}' -> '#{to_currency}'"
81
- end
82
+ def exchange(cents, from, to)
83
+ rate = get_rate(from, to)
84
+ raise(Money::UnknownRate, "No conversion rate for #{from} -> #{to}") unless rate
82
85
  (cents * rate).floor
83
86
  end
84
87
 
88
+ def fetch_rate(from, to)
89
+
90
+ end
91
+
85
92
  # Fetch rates
86
93
  def fetch_rates
87
94
  xml = Parser::XML(Net::HTTP.get(URI.parse('http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml')))
88
95
  curr = (xml/:Cube).select { |r| r["currency"] == Money.default_currency }.first
89
96
  diff = Money.default_currency == "EUR" || !curr ? 1 : curr["rate"].to_f
90
97
  (xml/:Cube).each do |x|
91
- parse_rate x['rate'].to_f / diff, curr ? Money.default_currency : "EUR", x['currency'].upcase if x['currency']
98
+ r = x['rate'].to_f
99
+ c = x['currency'] || ""
100
+ unless default_rates && !default_rates.include?(c)
101
+ parse_rate r / diff, curr ? Money.default_currency : "EUR", c.upcase
102
+ end
92
103
  end
93
104
  parse_rate diff, Money.default_currency, "EUR" if curr
94
105
  self
data/lib/money/money.rb CHANGED
@@ -99,6 +99,7 @@ class Money
99
99
  end
100
100
 
101
101
  def <=>(other_money)
102
+ other_money = Money.new(other_money) unless other_money.is_a? Money
102
103
  if bank.same_currency?(currency, other_money.currency)
103
104
  cents <=> other_money.cents
104
105
  else
data/money.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{money}
5
- s.version = "2.3.6"
5
+ s.version = "2.3.8"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Money Team"]
9
- s.date = %q{2009-05-29}
9
+ s.date = %q{2009-06-20}
10
10
  s.description = %q{This library aids one in handling money and different currencies.}
11
11
  s.email = %q{see@reame}
12
12
  s.extra_rdoc_files = [
@@ -41,14 +41,14 @@ Gem::Specification.new do |s|
41
41
  s.homepage = %q{http://github.com/nofxx/money}
42
42
  s.rdoc_options = ["--charset=UTF-8"]
43
43
  s.require_paths = ["lib"]
44
- s.rubygems_version = %q{1.3.3}
44
+ s.rubygems_version = %q{1.3.4}
45
45
  s.summary = %q{This library aids one in handling money and different currencies.}
46
46
  s.test_files = [
47
- "spec/money/exchange_bank_spec.rb",
47
+ "spec/db/schema.rb",
48
48
  "spec/money/acts_as_money_spec.rb",
49
+ "spec/money/exchange_bank_spec.rb",
49
50
  "spec/money/money_spec.rb",
50
51
  "spec/money/core_extensions_spec.rb",
51
- "spec/db/schema.rb",
52
52
  "spec/spec_helper.rb"
53
53
  ]
54
54
 
@@ -15,30 +15,48 @@ describe "Money core extensions" do
15
15
  end
16
16
  end
17
17
 
18
- describe "String#to_money works" do
19
- it { "100".to_money.should == Money.new(100_00) }
20
- it { "100.37".to_money.should == Money.new(100_37) }
21
- it { "100,37".to_money.should == Money.new(100_37) }
22
- it { "100 000".to_money.should == Money.new(100_000_00) }
23
- it { "100.000,45".to_money.should == Money.new(100_000_45) }
24
- it { "-100.100,45".to_money.should == Money.new(-100_100_45) }
18
+ describe "String#to_money" do
19
+ EXAMPLES = {
20
+ "20.15" => {:cents => Money.new(20_15), :no_cents => Money.new(20)},
21
+ "100" => {:cents => Money.new(100_00), :no_cents => Money.new(100)},
22
+ "100.37" => {:cents => Money.new(100_37), :no_cents => Money.new(100)},
23
+ "100,37" => {:cents => Money.new(100_37), :no_cents => Money.new(100)},
24
+ "100 000" => {:cents => Money.new(100_000_00), :no_cents => Money.new(100_000)},
25
+ "100 USD" => {:cents => Money.new(100_00, "USD"), :no_cents => Money.new(100, "USD")},
26
+ "-100 USD" => {:cents => Money.new(-100_00, "USD"), :no_cents => Money.new(-100, "USD")},
27
+ "100 EUR" => {:cents => Money.new(100_00, "EUR"), :no_cents => Money.new(100, "EUR")},
28
+ "$100 USD" => {:cents => Money.new(100_00, "USD"), :no_cents => Money.new(100, "USD")},
29
+ "USD 100" => {:cents => Money.new(100_00, "USD"), :no_cents => Money.new(100, "USD")},
30
+ "EUR 100" => {:cents => Money.new(100_00, "EUR"), :no_cents => Money.new(100, "EUR")},
31
+ "1,000.5" => {:cents => Money.new(1_000_50), :no_cents => Money.new(1_000) },
32
+ "1,000.51" => {:cents => Money.new(1_000_51), :no_cents => Money.new(1_000) },
33
+ "100.000,45" => {:cents => Money.new(100_000_45), :no_cents => Money.new(100_000)},
34
+ "-100.100,45" => {:cents => Money.new(-100_100_45), :no_cents => Money.new(-100_100)},
35
+ "1,000.505" => {:cents => Money.new(1_000_51), :no_cents => Money.new(1_000) },
36
+ "1,000.504" => {:cents => Money.new(1_000_50), :no_cents => Money.new(1_000) },
37
+ "100.37 EUR" => {:cents => Money.new(100_37, "EUR"), :no_cents => Money.new(100, "EUR")},
38
+ "100,37 EUR" => {:cents => Money.new(100_37, "EUR"), :no_cents => Money.new(100, "EUR")},
39
+ "EUR 100.37" => {:cents => Money.new(100_37, "EUR"), :no_cents => Money.new(100, "EUR")},
40
+ "CAD -100.37" => {:cents => Money.new(-100_37, "CAD"), :no_cents => Money.new(-100, "CAD")},
41
+ "EUR 100,37" => {:cents => Money.new(100_37, "EUR"), :no_cents => Money.new(100, "EUR")},
42
+ "EUR -100,37" => {:cents => Money.new(-100_37, "EUR"), :no_cents => Money.new(-100, "EUR")},
43
+ "BRL 100,37" => {:cents => Money.new(100_37, "BRL"), :no_cents => Money.new(100, "BRL")},
44
+ "BRL -100,37" => {:cents => Money.new(-100_37, "BRL"), :no_cents => Money.new(-100, "BRL")}
25
45
 
26
- it { "100 USD".to_money.should == Money.new(100_00, "USD") }
27
- it { "-100 USD".to_money.should == Money.new(-100_00, "USD") }
28
- it { "100 EUR".to_money.should == Money.new(100_00, "EUR") }
29
- it { "100.37 EUR".to_money.should == Money.new(100_37, "EUR") }
30
- it { "100,37 EUR".to_money.should == Money.new(100_37, "EUR") }
46
+ }
31
47
 
32
- it { "USD 100".to_money.should == Money.new(100_00, "USD") }
33
- it { "EUR 100".to_money.should == Money.new(100_00, "EUR") }
34
- it { "EUR 100.37".to_money.should == Money.new(100_37, "EUR") }
35
- it { "CAD -100.37".to_money.should == Money.new(-100_37, "CAD") }
36
- it { "EUR 100,37".to_money.should == Money.new(100_37, "EUR") }
37
- it { "EUR -100,37".to_money.should == Money.new(-100_37, "EUR") }
48
+ EXAMPLES.each_pair do |string, expected_money|
49
+ it "should convert '#{string}' with cents by default" do
50
+ string.to_money.should == expected_money[:cents]
51
+ end
38
52
 
39
- it { "BRL 100,37".to_money.should == Money.new(100_37, "BRL") }
40
- it { "BRL -100,37".to_money.should == Money.new(-100_37, "BRL") }
53
+ it "should convert '#{string}' without cents" do
54
+ string.to_money(true).should == expected_money[:no_cents]
55
+ end
41
56
 
42
- it {"$100 USD".to_money.should == Money.new(100_00, "USD") }
57
+ it "should convert '#{string}' with cents" do
58
+ string.to_money(false).should == expected_money[:cents]
59
+ end
60
+ end
43
61
  end
44
62
  end
@@ -88,8 +88,7 @@ describe Money::ExchangeBank do
88
88
  end
89
89
 
90
90
  it "raises Money::UnknownRate upon conversion if the conversion rate is unknown" do
91
- block = lambda { @bank.exchange(10, "USD", "ABC") }
92
- block.should raise_error(Money::UnknownRate)
91
+ lambda { @bank.exchange(10, "USD", "ABC") }.should raise_error(Money::UnknownRate)
93
92
  end
94
93
 
95
94
  describe "Fetching Data" do
@@ -122,6 +121,23 @@ describe Money::ExchangeBank do
122
121
  @bank.get_rate("EUR", "USD").should be_close(1.4098, 0.001)
123
122
  end
124
123
 
124
+ it "should fetch only what I want" do
125
+ Money.stub!(:default_currency).and_return("BRL")
126
+ @bank.default_rates = ["BRL", "EUR"]
127
+ @bank.fetch_rates
128
+ @bank.get_rate("DKK").should be_nil
129
+ @bank.get_rate("USD").should be_nil
130
+ @bank.get_rate("EUR").should be_close(2.832, 0.001)
131
+ end
132
+
133
+ it "should be convert EUR to BRL with default USD" do
134
+ Money.stub!(:default_currency).and_return("USD")
135
+ @bank.default_rates = ["BRL", "EUR", "USD"]
136
+ @bank.fetch_rates
137
+ @bank.exchange(100, "BRL", "EUR").should be_close(2,2)
138
+ @bank.exchange(100, "EUR", "BRL")
139
+ end
140
+
125
141
  end
126
142
 
127
143
  describe "Live Fetching" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nofxx-money
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.6
4
+ version: 2.3.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Money Team
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-05-29 00:00:00 -07:00
12
+ date: 2009-06-20 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -73,9 +73,9 @@ signing_key:
73
73
  specification_version: 3
74
74
  summary: This library aids one in handling money and different currencies.
75
75
  test_files:
76
- - spec/money/exchange_bank_spec.rb
76
+ - spec/db/schema.rb
77
77
  - spec/money/acts_as_money_spec.rb
78
+ - spec/money/exchange_bank_spec.rb
78
79
  - spec/money/money_spec.rb
79
80
  - spec/money/core_extensions_spec.rb
80
- - spec/db/schema.rb
81
81
  - spec/spec_helper.rb