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 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.3.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.3.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 = "2013-04-11"
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.require_paths = ["lib"]
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 = 3
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
 
@@ -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.3.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: 2013-04-11 00:00:00.000000000 Z
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: 1.8.25
110
+ rubygems_version: 2.4.6
120
111
  signing_key:
121
- specification_version: 3
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: []