bd_money 0.0.8 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +14 -4
- data/VERSION +1 -1
- data/bd_money.gemspec +1 -1
- data/lib/bd_money/bd_money.rb +15 -15
- data/lib/bd_money/rails.rb +8 -2
- data/spec/rails_spec.rb +22 -13
- metadata +3 -3
data/README.rdoc
CHANGED
@@ -59,14 +59,24 @@ There is a rails extension that makes it easier to store money values in the dat
|
|
59
59
|
validates_numericality_of :price, :greater_than => 0
|
60
60
|
end
|
61
61
|
|
62
|
-
This assumes that there is a price (decimal highly recommended) column in the database.
|
63
|
-
|
62
|
+
This assumes that there is a price (decimal highly recommended) column in the database.
|
63
|
+
|
64
|
+
You can also specify the :precision, :round_mode and :format options for more fine control of the results. If you don't
|
65
|
+
specify the :precision option it will try to guess it out of the scale column definition (recommended). Precision is
|
66
|
+
important since the values will get rounded on every change internally to stay consistent with the database.
|
64
67
|
|
65
68
|
class Loan < ActiveRecord::Base
|
66
|
-
money :amount, :round_mode => :half_up
|
67
|
-
money :apr, :precision => 5, :round_mode => :floor
|
69
|
+
money :amount, :round_mode => :half_up, :format => :no_cents
|
70
|
+
money :apr, :precision => 5, :round_mode => :floor, :format => :no_commas
|
68
71
|
end
|
69
72
|
|
73
|
+
loan = Loan.create! :amount => '325.75', :apr => '0.01234'
|
74
|
+
loan.amount #=> 325.75
|
75
|
+
loan.amount.formatted #=> $ 325.75
|
76
|
+
loan.apr #=> 0.0123
|
77
|
+
loan.apr.formatted #=> $ 0.01
|
78
|
+
loan.apr.formatted(:precision => 5, :unit => "", :spacer => "") #=> 0.01234
|
79
|
+
|
70
80
|
You can set the attribute to a String, Fixnum, or Float and it will call #to_money to
|
71
81
|
convert it to a Money object. This makes it convenient for using money fields in forms.
|
72
82
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.9
|
data/bd_money.gemspec
CHANGED
data/lib/bd_money/bd_money.rb
CHANGED
@@ -14,17 +14,17 @@ class Money
|
|
14
14
|
} unless const_defined?(:ROUND_MODES)
|
15
15
|
|
16
16
|
FORMATS = {
|
17
|
-
:default => { :unit => "$", :spacer => " ", :delimiter => ",", :separator => ".", :precision => 2 },
|
18
|
-
:no_cents => { :unit => "$", :spacer => " ", :delimiter => ",", :separator => ".", :precision => 0 },
|
19
|
-
:no_commas => { :unit => "$", :spacer => " ", :delimiter => "", :separator => ".", :precision => 2 },
|
17
|
+
:default => { :unit => "$", :spacer => " ", :delimiter => ",", :separator => ".", :precision => 2, :last => "" },
|
18
|
+
:no_cents => { :unit => "$", :spacer => " ", :delimiter => ",", :separator => ".", :precision => 0, :last => "" },
|
19
|
+
:no_commas => { :unit => "$", :spacer => " ", :delimiter => "", :separator => ".", :precision => 2, :last => "" },
|
20
|
+
:general => { :unit => "", :spacer => "", :delimiter => "", :separator => ".", :precision => 2, :last => "" },
|
20
21
|
} unless const_defined?(:FORMATS)
|
21
22
|
|
22
23
|
REMOVE_RE = %r{[$,_ ]} unless const_defined?(:REMOVE_RE)
|
23
24
|
VALID_RE = %r{^(-)?(\d)+(\.\d{1,30}(e-\d{1,10})?)?$} unless const_defined?(:VALID_RE)
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
YAML_TYPE_FULL = "#{YAML_TYPE_CLASS}/#{YAML_TYPE_MODE}" unless const_defined?(:YAML_TYPE_FULL)
|
26
|
+
YAML_TYPE_ROOT = 'npadv.com,2012-03-12' unless const_defined?(:YAML_TYPE_ROOT)
|
27
|
+
YAML_TYPE_NAME = 'money' unless const_defined?(:YAML_TYPE_NAME)
|
28
28
|
|
29
29
|
include Comparable
|
30
30
|
|
@@ -79,8 +79,8 @@ class Money
|
|
79
79
|
@format || self.class.format
|
80
80
|
end
|
81
81
|
|
82
|
-
def convert(value)
|
83
|
-
self.class.convert value
|
82
|
+
def convert(value, this_precision = precision, this_round_mode = round_mode)
|
83
|
+
self.class.convert value, this_precision, this_round_mode
|
84
84
|
end
|
85
85
|
|
86
86
|
def eql?(other)
|
@@ -187,15 +187,16 @@ class Money
|
|
187
187
|
spacer = options[:spacer] || defaults[:spacer]
|
188
188
|
delimiter = options[:delimiter] || defaults[:delimiter]
|
189
189
|
separator = options[:separator] || defaults[:separator]
|
190
|
-
precision = options[:precision] || defaults[:precision]
|
191
190
|
separator = '' if precision == 0
|
191
|
+
precision = options[:precision] || defaults[:precision]
|
192
|
+
last = options[:last] || defaults[:last]
|
192
193
|
|
193
194
|
number = to_s precision
|
194
195
|
begin
|
195
196
|
parts = number.to_s.split('.')
|
196
197
|
parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}")
|
197
198
|
number = parts.join(separator)
|
198
|
-
"#{unit}#{spacer}#{number}"
|
199
|
+
"#{unit}#{spacer}#{number}#{last}"
|
199
200
|
rescue
|
200
201
|
number
|
201
202
|
end
|
@@ -215,7 +216,7 @@ class Money
|
|
215
216
|
end
|
216
217
|
|
217
218
|
def to_yaml_type
|
218
|
-
"!#{
|
219
|
+
"!#{YAML_TYPE_ROOT}/#{YAML_TYPE_NAME}"
|
219
220
|
end
|
220
221
|
|
221
222
|
def to_yaml(options = { })
|
@@ -258,9 +259,8 @@ class Money
|
|
258
259
|
@format || :default
|
259
260
|
end
|
260
261
|
|
261
|
-
def convert(value)
|
262
|
-
|
263
|
-
new value
|
262
|
+
def convert(value, precision = nil, round_mode = nil)
|
263
|
+
new value, precision, round_mode
|
264
264
|
end
|
265
265
|
|
266
266
|
def clean(value)
|
@@ -275,6 +275,6 @@ class Money
|
|
275
275
|
|
276
276
|
end
|
277
277
|
|
278
|
-
YAML::add_domain_type(Money::
|
278
|
+
YAML::add_domain_type(Money::YAML_TYPE_ROOT, Money::YAML_TYPE_NAME) do |_, map|
|
279
279
|
Money.new map['amount'], map['precision'], map['round_mode'], map['format']
|
280
280
|
end
|
data/lib/bd_money/rails.rb
CHANGED
@@ -27,16 +27,22 @@ module ActiveRecord #:nodoc:
|
|
27
27
|
def money(*names)
|
28
28
|
options = names.extract_options!
|
29
29
|
names.each do |name|
|
30
|
+
if options[:precision]
|
31
|
+
this_precision = options[:precision]
|
32
|
+
else
|
33
|
+
db_column = columns.select { |x| x.name == name.to_s }.first
|
34
|
+
this_precision = (db_column && db_column.respond_to?(:scale)) ? db_column.scale : nil
|
35
|
+
end
|
30
36
|
define_method "#{name}=" do |value|
|
31
37
|
if value.present?
|
32
|
-
self[name] = ::Money.new(value, options[:
|
38
|
+
self[name] = ::Money.new(value, this_precision, options[:round_mode], options[:format]).round.amount
|
33
39
|
else
|
34
40
|
self[name] = nil
|
35
41
|
end
|
36
42
|
end
|
37
43
|
define_method "#{name}" do
|
38
44
|
return nil unless self[name].present?
|
39
|
-
::Money.new self[name], options[:
|
45
|
+
::Money.new self[name], this_precision, options[:round_mode], options[:format]
|
40
46
|
end
|
41
47
|
end
|
42
48
|
end
|
data/spec/rails_spec.rb
CHANGED
@@ -21,22 +21,25 @@ end
|
|
21
21
|
class BetterLoanExample < ActiveRecord::Base
|
22
22
|
set_table_name "money_examples"
|
23
23
|
|
24
|
-
money :amount, :
|
25
|
-
money :apr, :precision =>
|
24
|
+
money :amount, :round_mode => :half_up, :format => :no_cents
|
25
|
+
money :apr, :precision => 4, :round_mode => :floor, :format => :no_commas
|
26
26
|
end
|
27
27
|
|
28
28
|
describe Money do
|
29
29
|
describe "default settings" do
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
30
|
+
before(:all) { @record = BetterLoanExample.create! :amount => '325.75', :apr => '0.01234' }
|
31
|
+
subject { BetterLoanExample.find_by_amount('325.75'.to_money) }
|
32
|
+
it { BetterLoanExample.find_by_amount(0.to_money).should be_nil }
|
33
|
+
it { subject.id.should == @record.id }
|
34
|
+
it { subject.amount.should be_a(Money) }
|
35
|
+
it { subject.amount.to_s.should == '325.75' }
|
36
|
+
it { subject.amount.format.should == :no_cents }
|
37
|
+
it { subject.amount.formatted.should == '$ 325.75' }
|
38
|
+
it { subject.apr.should be_a(Money) }
|
39
|
+
it { subject.apr.to_s.should == '0.0123' }
|
40
|
+
it { subject.apr.format.should == :no_commas }
|
41
|
+
it { subject.apr.formatted.should == '$ 0.01' }
|
42
|
+
it { subject.apr.formatted(:precision => 3, :unit => "", :spacer => "").should == '0.012' }
|
40
43
|
end
|
41
44
|
describe "custom settings" do
|
42
45
|
it "should allow dynamic finders to work with money objects" do
|
@@ -47,7 +50,7 @@ describe Money do
|
|
47
50
|
found.amount.should be_a(Money)
|
48
51
|
found.amount.to_s.should == '123.45'
|
49
52
|
found.apr.should be_a(Money)
|
50
|
-
found.apr.to_s.should == '0.
|
53
|
+
found.apr.to_s.should == '0.0123'
|
51
54
|
end
|
52
55
|
end
|
53
56
|
describe "setter method" do
|
@@ -72,5 +75,11 @@ describe Money do
|
|
72
75
|
me.update_attribute :amount, nil
|
73
76
|
me.amount.should be_nil
|
74
77
|
end
|
78
|
+
|
79
|
+
describe "should round numbers to the column's' precision" do
|
80
|
+
subject { BetterLoanExample.new :amount => 300, :apr => 0.123456789 }
|
81
|
+
it { subject.amount.amount.to_s('F').should == '300.0' }
|
82
|
+
it { subject.apr.amount.to_s('F').should == '0.1234' }
|
83
|
+
end
|
75
84
|
end
|
76
85
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bd_money
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 13
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 9
|
10
|
+
version: 0.0.9
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Adrian Madrid
|