has_money 0.3.0 → 0.4.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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +4 -1
- data/README.rdoc +13 -6
- data/VERSION +1 -1
- data/has_money.gemspec +7 -5
- data/lib/has_money.rb +30 -7
- data/spec/has_money_spec.rb +124 -14
- metadata +17 -26
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7b467aec6ef6b361592a857ffa6a6ac801c0f7ff
|
4
|
+
data.tar.gz: 5b541a25814ae908ca68ad4fc7f9d81efdb2b053
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3ccb9fb7cfafb11e0daad1f8c9f16de33440aa19bd43b2bf55b3ae9b302c1147c617a33cd0ee70e8e931573c28c40f37b7cdfd175f2dc0e80bb9441d82911761
|
7
|
+
data.tar.gz: fa02aecf0198463eec4803ebe7397a114b45c26257359bd3d473715177fe8b099c930119bf27420638a03cb25ecd9320cffc1b87b6d9da640d6be31f29d65c52
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
+
## 0.4.0
|
2
|
+
* Adds support for inputs that want to round to nearest dollar but store in cents ([@samvincent][])
|
3
|
+
|
1
4
|
## 0.3.0
|
2
5
|
* Adds support for negative signs when converting ([@samvincent][])
|
3
6
|
|
4
7
|
## 0.2.1
|
5
|
-
* Add support for "39." as a dollar value #=> 3900 cents ([@gregbell][])
|
8
|
+
* Add support for "39." as a dollar value #=> 3900 cents ([@gregbell][])
|
data/README.rdoc
CHANGED
@@ -5,18 +5,25 @@ In your ActiveRecord model:
|
|
5
5
|
class Order < ActiveRecord::Base
|
6
6
|
has_money :default_price
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
Defines methods :default_price_in_dollars and :default_price_in_dollars= which make life easier when building forms.
|
10
10
|
|
11
11
|
> Order.new :default_price_in_dollars => '10.00'
|
12
|
-
=> #<Order default_price: 1000>
|
13
|
-
|
12
|
+
=> #<Order default_price: 1000>
|
13
|
+
|
14
|
+
If you want to store your prices in cents but offer a form input that rounds to the nearest dollar
|
15
|
+
|
16
|
+
> order = Order.new :default_price_in_dollars_without_cents => '9.99'
|
17
|
+
=> #<Order default_price: 1000>
|
18
|
+
> order.default_price_in_dollars_without_cents
|
19
|
+
=> '10'
|
20
|
+
|
14
21
|
== Install
|
15
22
|
As a gem:
|
16
|
-
$ gem install has_money
|
17
|
-
|
23
|
+
$ gem install has_money
|
24
|
+
|
18
25
|
In your `Gemfile`:
|
19
26
|
gem 'has_money'
|
20
27
|
|
21
28
|
As a plugin:
|
22
|
-
script/plugin install git://github.com/samvincent/has_money.git
|
29
|
+
script/plugin install git://github.com/samvincent/has_money.git
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
data/has_money.gemspec
CHANGED
@@ -2,17 +2,20 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
+
# stub: has_money 0.4.0 ruby lib
|
5
6
|
|
6
7
|
Gem::Specification.new do |s|
|
7
8
|
s.name = "has_money"
|
8
|
-
s.version = "0.
|
9
|
+
s.version = "0.4.0"
|
9
10
|
|
10
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib"]
|
11
13
|
s.authors = ["Greg Bell", "Sam Vincent", "Philippe Creux"]
|
12
|
-
s.date = "
|
14
|
+
s.date = "2016-01-28"
|
13
15
|
s.description = "Parsing the various ways people enter dollar amounts so you don't have to. Store values in cents as integer."
|
14
16
|
s.email = "sam.vincent@mac.com"
|
15
17
|
s.extra_rdoc_files = [
|
18
|
+
"CHANGELOG.md",
|
16
19
|
"LICENSE",
|
17
20
|
"README.rdoc"
|
18
21
|
]
|
@@ -29,12 +32,11 @@ Gem::Specification.new do |s|
|
|
29
32
|
"spec/has_money_spec.rb"
|
30
33
|
]
|
31
34
|
s.homepage = "http://github.com/samvincent/has_money"
|
32
|
-
s.
|
33
|
-
s.rubygems_version = "1.8.25"
|
35
|
+
s.rubygems_version = "2.4.6"
|
34
36
|
s.summary = "Parsing the various ways people enter dollar amounts so you don't have to."
|
35
37
|
|
36
38
|
if s.respond_to? :specification_version then
|
37
|
-
s.specification_version =
|
39
|
+
s.specification_version = 4
|
38
40
|
|
39
41
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
40
42
|
s.add_development_dependency(%q<bundler>, [">= 0"])
|
data/lib/has_money.rb
CHANGED
@@ -1,27 +1,36 @@
|
|
1
1
|
require 'bigdecimal'
|
2
2
|
|
3
3
|
module HasMoney
|
4
|
-
|
4
|
+
|
5
5
|
def self.included(base)
|
6
6
|
base.extend ClassMethods
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
module ClassMethods
|
10
|
-
|
10
|
+
|
11
11
|
def has_money(*attributes)
|
12
12
|
attributes.each do |attribute|
|
13
|
-
class_eval <<-EOS
|
13
|
+
class_eval <<-EOS
|
14
14
|
def #{attribute}_in_dollars
|
15
15
|
self.class.calculate_dollars_from_cents(#{attribute})
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
def #{attribute}_in_dollars=(dollars)
|
19
19
|
self.#{attribute} = self.class.calculate_cents_from_dollars(dollars)
|
20
20
|
end
|
21
|
+
|
22
|
+
# Special dollars only formatting (no decimal place and rounded to the nearest dollar)
|
23
|
+
def #{attribute}_in_dollars_without_cents
|
24
|
+
self.class.calculate_dollars_without_cents_from_cents(#{attribute})
|
25
|
+
end
|
26
|
+
|
27
|
+
def #{attribute}_in_dollars_without_cents=(dollars)
|
28
|
+
self.#{attribute} = self.class.calculate_cents_from_dollars_without_cents(dollars)
|
29
|
+
end
|
21
30
|
EOS
|
22
31
|
end
|
23
32
|
end
|
24
|
-
|
33
|
+
|
25
34
|
def calculate_dollars_from_cents(cents)
|
26
35
|
return nil if cents.nil? || cents == ''
|
27
36
|
"%.2f" % (BigDecimal(cents.to_s) / 100).to_f
|
@@ -36,7 +45,21 @@ module HasMoney
|
|
36
45
|
|
37
46
|
(BigDecimal(dollars).round(2) * 100).to_i
|
38
47
|
end
|
39
|
-
|
48
|
+
|
49
|
+
def calculate_dollars_without_cents_from_cents(cents)
|
50
|
+
return nil if cents.nil? || cents == ''
|
51
|
+
"%i" % (BigDecimal(cents.to_s) / 100).to_f.round
|
52
|
+
end
|
53
|
+
|
54
|
+
def calculate_cents_from_dollars_without_cents(dollars)
|
55
|
+
return nil if dollars.nil?
|
56
|
+
|
57
|
+
dollars = dollars.to_s.gsub(/[$,]/, "").strip
|
58
|
+
dollars[0] = '0.' if dollars =~ /^\.\d{1,2}/
|
59
|
+
return nil unless dollars.match(/^-?\d+\.?(\d+)?$/) # xx.xxx
|
60
|
+
|
61
|
+
(BigDecimal(dollars).round * 100).to_i
|
62
|
+
end
|
40
63
|
end
|
41
64
|
end
|
42
65
|
|
data/spec/has_money_spec.rb
CHANGED
@@ -2,7 +2,7 @@ require 'active_record'
|
|
2
2
|
require File.expand_path(File.dirname(__FILE__) + '/../lib/has_money')
|
3
3
|
|
4
4
|
describe HasMoney do
|
5
|
-
|
5
|
+
|
6
6
|
describe "including has money" do
|
7
7
|
it "should extend the class with class methods when included" do
|
8
8
|
klass = Class.new
|
@@ -10,7 +10,7 @@ describe HasMoney do
|
|
10
10
|
klass.should respond_to(:has_money)
|
11
11
|
end
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
describe "working with money" do
|
15
15
|
before(:each) do
|
16
16
|
@klass = Class.new
|
@@ -22,11 +22,11 @@ describe HasMoney do
|
|
22
22
|
@product = @klass.new
|
23
23
|
@product.price = 2999
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
it "should create an accessor method named in_dollars for the attribute" do
|
27
27
|
@product.should respond_to(:price_in_dollars)
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
it "should create a setter method named in_dollars for the attribute" do
|
31
31
|
@product.should respond_to(:price_in_dollars=)
|
32
32
|
end
|
@@ -39,12 +39,12 @@ describe HasMoney do
|
|
39
39
|
@product.price = -4200
|
40
40
|
@product.price_in_dollars.should == '-42.00'
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
it "should set the amount in dollars with a float" do
|
44
44
|
@product.price_in_dollars = 39.99
|
45
45
|
@product.price.should == 3999
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
it "should set the amount in dollars with a string with decimals" do
|
49
49
|
@product.price_in_dollars = '39.99'
|
50
50
|
@product.price.should == 3999
|
@@ -64,17 +64,17 @@ describe HasMoney do
|
|
64
64
|
@product.price_in_dollars = "2,500.99"
|
65
65
|
@product.price.should == 250099
|
66
66
|
end
|
67
|
-
|
67
|
+
|
68
68
|
it "should set the amount in dollars if only cents with a period" do
|
69
69
|
@product.price_in_dollars = ".59"
|
70
70
|
@product.price.should == 59
|
71
71
|
end
|
72
|
-
|
72
|
+
|
73
73
|
it "should set the amount in dollars if it has leading and trailing spaces" do
|
74
74
|
@product.price_in_dollars = " 0.59 "
|
75
75
|
@product.price.should == 59
|
76
76
|
end
|
77
|
-
|
77
|
+
|
78
78
|
it "should round the amount up to the nearest cent" do
|
79
79
|
@product.price_in_dollars = '39.998'
|
80
80
|
@product.price.should == 4000
|
@@ -89,12 +89,12 @@ describe HasMoney do
|
|
89
89
|
@product.price_in_dollars = '39.'
|
90
90
|
@product.price.should == 3900
|
91
91
|
end
|
92
|
-
|
92
|
+
|
93
93
|
it "should set nil if nil is passed as dollars" do
|
94
94
|
@product.price_in_dollars = nil
|
95
95
|
@product.price.should == nil
|
96
96
|
end
|
97
|
-
|
97
|
+
|
98
98
|
it "should set nil if an empty string is passed in as dollars" do
|
99
99
|
@product.price_in_dollars = ''
|
100
100
|
@product.price.should == nil
|
@@ -102,7 +102,7 @@ describe HasMoney do
|
|
102
102
|
|
103
103
|
it "should set nil if a non numerical string is passed in as dollars" do
|
104
104
|
@product.price_in_dollars = 'two dollars'
|
105
|
-
@product.price.should == nil
|
105
|
+
@product.price.should == nil
|
106
106
|
end
|
107
107
|
|
108
108
|
it "should respect negative signs" do
|
@@ -114,11 +114,121 @@ describe HasMoney do
|
|
114
114
|
@product.price_in_dollars = '99'
|
115
115
|
@product.price_in_dollars.should == '99.00'
|
116
116
|
end
|
117
|
-
|
117
|
+
|
118
118
|
it "should return nil if the attribute is nil" do
|
119
119
|
@product.price = nil
|
120
120
|
@product.price_in_dollars.should == nil
|
121
121
|
end
|
122
122
|
end
|
123
|
-
|
123
|
+
|
124
|
+
describe "working with money where cents are not allowed" do
|
125
|
+
before(:each) do
|
126
|
+
@klass = Class.new
|
127
|
+
@klass.class_eval do
|
128
|
+
include HasMoney
|
129
|
+
attr_accessor :price
|
130
|
+
has_money :price
|
131
|
+
end
|
132
|
+
@product = @klass.new
|
133
|
+
@product.price = 2999
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should create an accessor method named in_dollars for the attribute" do
|
137
|
+
@product.should respond_to(:price_in_dollars_without_cents)
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should create a setter method named in_dollars for the attribute" do
|
141
|
+
@product.should respond_to(:price_in_dollars_without_cents=)
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should return the amount in dollars" do
|
145
|
+
@product.price_in_dollars_without_cents.should == '30'
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should return the amount in dollars correctly when negative" do
|
149
|
+
@product.price = -4200
|
150
|
+
@product.price_in_dollars_without_cents.should == '-42'
|
151
|
+
end
|
152
|
+
|
153
|
+
it "should set the amount in dollars with a float" do
|
154
|
+
@product.price_in_dollars_without_cents = 39.99
|
155
|
+
@product.price.should == 4000
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should set the amount in dollars with a string with decimals" do
|
159
|
+
@product.price_in_dollars_without_cents = '39.99'
|
160
|
+
@product.price.should == 4000
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should set the amount in dollars with a string without decimals" do
|
164
|
+
@product.price_in_dollars_without_cents = '39'
|
165
|
+
@product.price.should == 3900
|
166
|
+
end
|
167
|
+
|
168
|
+
it "should set the amount in dollars with a dollar sign" do
|
169
|
+
@product.price_in_dollars_without_cents = "$39.99"
|
170
|
+
@product.price.should == 4000
|
171
|
+
end
|
172
|
+
|
173
|
+
it "should set the amount in dollars with commas" do
|
174
|
+
@product.price_in_dollars_without_cents = "2,500.99"
|
175
|
+
@product.price.should == 250100
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should set the amount in dollars if only cents with a period" do
|
179
|
+
@product.price_in_dollars_without_cents = ".59"
|
180
|
+
@product.price.should == 100
|
181
|
+
end
|
182
|
+
|
183
|
+
it "should set the amount in dollars if it has leading and trailing spaces" do
|
184
|
+
@product.price_in_dollars_without_cents = " 0.59 "
|
185
|
+
@product.price.should == 100
|
186
|
+
end
|
187
|
+
|
188
|
+
it "should round the amount up to the nearest dollar" do
|
189
|
+
@product.price_in_dollars_without_cents = '39.998'
|
190
|
+
@product.price.should == 4000
|
191
|
+
end
|
192
|
+
|
193
|
+
it "should round the amount down to the nearest dollar" do
|
194
|
+
@product.price_in_dollars_without_cents = '39.499'
|
195
|
+
@product.price.should == 3900
|
196
|
+
end
|
197
|
+
|
198
|
+
it "should assume zero cents if none given after decimal point" do
|
199
|
+
@product.price_in_dollars_without_cents = '39.'
|
200
|
+
@product.price.should == 3900
|
201
|
+
end
|
202
|
+
|
203
|
+
it "should set nil if nil is passed as dollars" do
|
204
|
+
@product.price_in_dollars_without_cents = nil
|
205
|
+
@product.price.should == nil
|
206
|
+
end
|
207
|
+
|
208
|
+
it "should set nil if an empty string is passed in as dollars" do
|
209
|
+
@product.price_in_dollars_without_cents = ''
|
210
|
+
@product.price.should == nil
|
211
|
+
end
|
212
|
+
|
213
|
+
it "should set nil if a non numerical string is passed in as dollars" do
|
214
|
+
@product.price_in_dollars_without_cents = 'two dollars'
|
215
|
+
@product.price.should == nil
|
216
|
+
end
|
217
|
+
|
218
|
+
it "should respect negative signs" do
|
219
|
+
@product.price_in_dollars_without_cents = '-$8.12'
|
220
|
+
@product.price.should == -800
|
221
|
+
end
|
222
|
+
|
223
|
+
it "should return string formatted without decimal places" do
|
224
|
+
@product.price_in_dollars_without_cents = '99'
|
225
|
+
@product.price_in_dollars_without_cents.should == '99'
|
226
|
+
end
|
227
|
+
|
228
|
+
it "should return nil if the attribute is nil" do
|
229
|
+
@product.price = nil
|
230
|
+
@product.price_in_dollars_without_cents.should == nil
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
124
234
|
end
|
metadata
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: has_money
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.4.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Greg Bell
|
@@ -11,70 +10,62 @@ authors:
|
|
11
10
|
autorequire:
|
12
11
|
bindir: bin
|
13
12
|
cert_chain: []
|
14
|
-
date:
|
13
|
+
date: 2016-01-28 00:00:00.000000000 Z
|
15
14
|
dependencies:
|
16
15
|
- !ruby/object:Gem::Dependency
|
17
16
|
name: bundler
|
18
17
|
requirement: !ruby/object:Gem::Requirement
|
19
|
-
none: false
|
20
18
|
requirements:
|
21
|
-
- -
|
19
|
+
- - ">="
|
22
20
|
- !ruby/object:Gem::Version
|
23
21
|
version: '0'
|
24
22
|
type: :development
|
25
23
|
prerelease: false
|
26
24
|
version_requirements: !ruby/object:Gem::Requirement
|
27
|
-
none: false
|
28
25
|
requirements:
|
29
|
-
- -
|
26
|
+
- - ">="
|
30
27
|
- !ruby/object:Gem::Version
|
31
28
|
version: '0'
|
32
29
|
- !ruby/object:Gem::Dependency
|
33
30
|
name: activerecord
|
34
31
|
requirement: !ruby/object:Gem::Requirement
|
35
|
-
none: false
|
36
32
|
requirements:
|
37
|
-
- -
|
33
|
+
- - ">="
|
38
34
|
- !ruby/object:Gem::Version
|
39
35
|
version: '0'
|
40
36
|
type: :development
|
41
37
|
prerelease: false
|
42
38
|
version_requirements: !ruby/object:Gem::Requirement
|
43
|
-
none: false
|
44
39
|
requirements:
|
45
|
-
- -
|
40
|
+
- - ">="
|
46
41
|
- !ruby/object:Gem::Version
|
47
42
|
version: '0'
|
48
43
|
- !ruby/object:Gem::Dependency
|
49
44
|
name: rspec
|
50
45
|
requirement: !ruby/object:Gem::Requirement
|
51
|
-
none: false
|
52
46
|
requirements:
|
53
|
-
- - ~>
|
47
|
+
- - "~>"
|
54
48
|
- !ruby/object:Gem::Version
|
55
49
|
version: 2.8.0
|
56
50
|
type: :development
|
57
51
|
prerelease: false
|
58
52
|
version_requirements: !ruby/object:Gem::Requirement
|
59
|
-
none: false
|
60
53
|
requirements:
|
61
|
-
- - ~>
|
54
|
+
- - "~>"
|
62
55
|
- !ruby/object:Gem::Version
|
63
56
|
version: 2.8.0
|
64
57
|
- !ruby/object:Gem::Dependency
|
65
58
|
name: jeweler
|
66
59
|
requirement: !ruby/object:Gem::Requirement
|
67
|
-
none: false
|
68
60
|
requirements:
|
69
|
-
- - ~>
|
61
|
+
- - "~>"
|
70
62
|
- !ruby/object:Gem::Version
|
71
63
|
version: 1.8.4
|
72
64
|
type: :development
|
73
65
|
prerelease: false
|
74
66
|
version_requirements: !ruby/object:Gem::Requirement
|
75
|
-
none: false
|
76
67
|
requirements:
|
77
|
-
- - ~>
|
68
|
+
- - "~>"
|
78
69
|
- !ruby/object:Gem::Version
|
79
70
|
version: 1.8.4
|
80
71
|
description: Parsing the various ways people enter dollar amounts so you don't have
|
@@ -83,10 +74,11 @@ email: sam.vincent@mac.com
|
|
83
74
|
executables: []
|
84
75
|
extensions: []
|
85
76
|
extra_rdoc_files:
|
77
|
+
- CHANGELOG.md
|
86
78
|
- LICENSE
|
87
79
|
- README.rdoc
|
88
80
|
files:
|
89
|
-
- .document
|
81
|
+
- ".document"
|
90
82
|
- CHANGELOG.md
|
91
83
|
- Gemfile
|
92
84
|
- LICENSE
|
@@ -98,26 +90,25 @@ files:
|
|
98
90
|
- spec/has_money_spec.rb
|
99
91
|
homepage: http://github.com/samvincent/has_money
|
100
92
|
licenses: []
|
93
|
+
metadata: {}
|
101
94
|
post_install_message:
|
102
95
|
rdoc_options: []
|
103
96
|
require_paths:
|
104
97
|
- lib
|
105
98
|
required_ruby_version: !ruby/object:Gem::Requirement
|
106
|
-
none: false
|
107
99
|
requirements:
|
108
|
-
- -
|
100
|
+
- - ">="
|
109
101
|
- !ruby/object:Gem::Version
|
110
102
|
version: '0'
|
111
103
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
|
-
none: false
|
113
104
|
requirements:
|
114
|
-
- -
|
105
|
+
- - ">="
|
115
106
|
- !ruby/object:Gem::Version
|
116
107
|
version: '0'
|
117
108
|
requirements: []
|
118
109
|
rubyforge_project:
|
119
|
-
rubygems_version:
|
110
|
+
rubygems_version: 2.4.6
|
120
111
|
signing_key:
|
121
|
-
specification_version:
|
112
|
+
specification_version: 4
|
122
113
|
summary: Parsing the various ways people enter dollar amounts so you don't have to.
|
123
114
|
test_files: []
|