acts_as_priceable 0.2.0 → 0.2.1
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.
- data/README.md +8 -0
- data/acts_as_priceable.gemspec +2 -1
- data/lib/acts_as_priceable/base.rb +30 -5
- data/lib/acts_as_priceable/version.rb +1 -1
- data/spec/base_spec.rb +228 -3
- data/spec/database.yml +7 -2
- data/spec/models/dummy_serialize.rb +6 -0
- data/spec/spec_helper.rb +10 -0
- metadata +23 -5
data/README.md
CHANGED
@@ -105,8 +105,16 @@ class Product < ActiveRecord::Base
|
|
105
105
|
end
|
106
106
|
```
|
107
107
|
|
108
|
+
From version 0.2.1 you can use serialized fields to store your price information. Gem supports serialization to Hash and Hstore
|
108
109
|
|
110
|
+
```ruby
|
111
|
+
class Product
|
112
|
+
serialize :data, Hash
|
113
|
+
|
114
|
+
has_price :price, serialized: :data
|
109
115
|
|
116
|
+
end
|
117
|
+
```
|
110
118
|
|
111
119
|
## Contributing
|
112
120
|
|
data/acts_as_priceable.gemspec
CHANGED
@@ -17,5 +17,6 @@ Gem::Specification.new do |gem|
|
|
17
17
|
gem.add_dependency "activerecord", ">= 3.0.0"
|
18
18
|
gem.add_development_dependency 'rspec', "~> 2.10.0"
|
19
19
|
gem.add_development_dependency 'rake'
|
20
|
-
gem.add_development_dependency '
|
20
|
+
gem.add_development_dependency 'pg'
|
21
|
+
gem.add_development_dependency 'activerecord-postgres-hstore'
|
21
22
|
end
|
@@ -14,11 +14,12 @@ module ActsAsPriceable
|
|
14
14
|
def has_price(name = :price, options = {})
|
15
15
|
scale = options[:scale] || 2
|
16
16
|
without_validations = options[:without_validations] || false
|
17
|
+
serialized = options[:serialized]
|
17
18
|
|
18
19
|
ActsAsPriceable::Schema::COLUMNS.each do |column_name, column_type|
|
19
20
|
raise AttributeError, "#{name}_#{column_name} is not defined" if columns_hash["#{name}_#{column_name}"].nil?
|
20
21
|
raise AttributeError, "#{name}_#{column_name} has wrong column type (is #{columns_hash["#{name}_#{column_name}"].type}) should be #{column_type}" if columns_hash["#{name}_#{column_name}"].type != column_type
|
21
|
-
end
|
22
|
+
end if serialized.nil?
|
22
23
|
|
23
24
|
gross = "#{name}_gross"
|
24
25
|
net = "#{name}_net"
|
@@ -26,20 +27,44 @@ module ActsAsPriceable
|
|
26
27
|
tax = "#{name}_tax"
|
27
28
|
mode = "#{name}_mode"
|
28
29
|
|
30
|
+
send :define_method, "get_#{name}_attribute" do |attribute|
|
31
|
+
if serialized.nil?
|
32
|
+
self[attribute.to_sym].to_i
|
33
|
+
else
|
34
|
+
self.send(serialized)[attribute.to_s].to_i
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
send :define_method, "set_#{name}_attribute" do |attribute, value|
|
39
|
+
if serialized.nil?
|
40
|
+
self[attribute.to_sym] = value
|
41
|
+
else
|
42
|
+
self.send(serialized)[attribute.to_s] = value
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
29
46
|
send :define_method, gross do
|
30
|
-
BigDecimal.new(self
|
47
|
+
BigDecimal.new(self.send("get_#{name}_attribute", gross)) / BigDecimal.new(10**scale.to_i)
|
31
48
|
end
|
32
49
|
|
33
50
|
send :define_method, "#{gross}=" do |value|
|
34
|
-
self
|
51
|
+
self.send "set_#{name}_attribute", gross, (value.to_s.gsub(',', '.').to_d * (10**scale)).to_i
|
35
52
|
end
|
36
53
|
|
37
54
|
send :define_method, net do
|
38
|
-
BigDecimal.new(self
|
55
|
+
BigDecimal.new(self.send("get_#{name}_attribute", net)) / BigDecimal.new(10**scale.to_i)
|
39
56
|
end
|
40
57
|
|
41
58
|
send :define_method, "#{net}=" do |value|
|
42
|
-
self
|
59
|
+
self.send("set_#{name}_attribute", net, (value.to_s.gsub(',', '.').to_d * (10**scale)).to_i)
|
60
|
+
end
|
61
|
+
|
62
|
+
send :define_method, tax do
|
63
|
+
self.send "get_#{name}_attribute", tax
|
64
|
+
end
|
65
|
+
|
66
|
+
send :define_method, "#{tax}=" do |value|
|
67
|
+
self.send "set_#{name}_attribute", tax, value
|
43
68
|
end
|
44
69
|
|
45
70
|
send :define_method, tax_value do
|
data/spec/base_spec.rb
CHANGED
@@ -27,7 +27,7 @@ describe Dummy do
|
|
27
27
|
@dummy.should respond_to(:price=)
|
28
28
|
end
|
29
29
|
|
30
|
-
it 'should have
|
30
|
+
it 'should have price_mode attr_accessor' do
|
31
31
|
@dummy.should respond_to(:price_mode)
|
32
32
|
@dummy.should respond_to(:price_mode=)
|
33
33
|
end
|
@@ -42,7 +42,7 @@ describe Dummy do
|
|
42
42
|
|
43
43
|
it 'price_net should be converted to integer' do
|
44
44
|
@dummy.price_net = @test_value
|
45
|
-
@dummy
|
45
|
+
@dummy.get_price_attribute(:price_net).should be(1020)
|
46
46
|
end
|
47
47
|
|
48
48
|
it 'price_net should return correct value' do
|
@@ -52,7 +52,7 @@ describe Dummy do
|
|
52
52
|
|
53
53
|
it 'price_gross should be converted to integer' do
|
54
54
|
@dummy.price_gross = @test_value
|
55
|
-
@dummy
|
55
|
+
@dummy.get_price_attribute(:price_gross).should be(1020)
|
56
56
|
end
|
57
57
|
|
58
58
|
it 'price_gross should return correct value' do
|
@@ -115,4 +115,229 @@ describe Dummy do
|
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
118
|
+
end
|
119
|
+
|
120
|
+
describe DummySerialize do
|
121
|
+
|
122
|
+
describe 'class methods' do
|
123
|
+
it 'should have has_price method' do
|
124
|
+
DummySerialize.should respond_to(:has_price)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe 'instance' do
|
129
|
+
|
130
|
+
describe 'hstore' do
|
131
|
+
|
132
|
+
before(:all) do
|
133
|
+
DummySerialize.send :has_price, :price, serialized: :hstore_data
|
134
|
+
@test_value = '10.20'
|
135
|
+
end
|
136
|
+
|
137
|
+
describe 'methods' do
|
138
|
+
|
139
|
+
before(:each) do
|
140
|
+
@dummy = DummySerialize.new
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'should have price attr_accessor' do
|
144
|
+
@dummy.should respond_to(:price)
|
145
|
+
@dummy.should respond_to(:price=)
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'should have price_mode attr_accessor' do
|
149
|
+
@dummy.should respond_to(:price_mode)
|
150
|
+
@dummy.should respond_to(:price_mode=)
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'should have price_tax_value method' do
|
154
|
+
@dummy.should respond_to(:price_tax_value)
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'should have update_price method' do
|
158
|
+
@dummy.should respond_to(:update_price)
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'price_net should be converted to integer' do
|
162
|
+
@dummy.price_net = @test_value
|
163
|
+
@dummy.get_price_attribute(:price_net).should be(1020)
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'price_net should return correct value' do
|
167
|
+
@dummy.price_net = @test_value
|
168
|
+
@dummy.price_net.should == BigDecimal.new(@test_value)
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'price_gross should be converted to integer' do
|
172
|
+
@dummy.price_gross = @test_value
|
173
|
+
@dummy.get_price_attribute(:price_gross).should be(1020)
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'price_gross should return correct value' do
|
177
|
+
@dummy.price_gross = @test_value
|
178
|
+
@dummy.price_gross.should == BigDecimal.new(@test_value)
|
179
|
+
end
|
180
|
+
|
181
|
+
it 'calculates price gross from price_net' do
|
182
|
+
@dummy.price = '10.00'
|
183
|
+
@dummy.price_tax = 23
|
184
|
+
@dummy.price_mode = 'net'
|
185
|
+
@dummy.update_price
|
186
|
+
@dummy.price_net.should == BigDecimal.new('10.00')
|
187
|
+
@dummy.price_gross.should == BigDecimal.new('12.30')
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'calculates price net from price gross' do
|
191
|
+
@dummy.price = '12.30'
|
192
|
+
@dummy.price_tax = 23
|
193
|
+
@dummy.price_mode = 'gross'
|
194
|
+
@dummy.update_price
|
195
|
+
@dummy.price_net.should == BigDecimal.new('10.00')
|
196
|
+
@dummy.price_gross.should == BigDecimal.new('12.30')
|
197
|
+
end
|
198
|
+
|
199
|
+
it 'calculates tax value properly' do
|
200
|
+
@dummy.price = '10.00'
|
201
|
+
@dummy.price_tax = 23
|
202
|
+
@dummy.price_mode = 'net'
|
203
|
+
@dummy.update_price
|
204
|
+
@dummy.price_tax_value.should == BigDecimal.new('2.30')
|
205
|
+
end
|
206
|
+
|
207
|
+
end
|
208
|
+
|
209
|
+
describe 'validations' do
|
210
|
+
|
211
|
+
before(:each) do
|
212
|
+
@dummy = DummySerialize.new price_net: '10.00', price_gross: '12.30', price_tax: 23
|
213
|
+
end
|
214
|
+
|
215
|
+
it 'correct should be valid' do
|
216
|
+
@dummy.valid?.should be(true)
|
217
|
+
end
|
218
|
+
|
219
|
+
it "price_net can't be negative" do
|
220
|
+
@dummy.price_net = -1
|
221
|
+
@dummy.valid?.should be(false)
|
222
|
+
end
|
223
|
+
|
224
|
+
it "price_gross can't be negative" do
|
225
|
+
@dummy.price_gross = -1
|
226
|
+
@dummy.valid?.should be(false)
|
227
|
+
end
|
228
|
+
|
229
|
+
it "price_tax can't be negative" do
|
230
|
+
@dummy.price_tax = -1
|
231
|
+
@dummy.valid?.should be(false)
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
describe 'hash' do
|
237
|
+
|
238
|
+
before(:all) do
|
239
|
+
DummySerialize.send :has_price, :price, serialized: :hash_data
|
240
|
+
@test_value = '10.20'
|
241
|
+
end
|
242
|
+
|
243
|
+
describe 'methods' do
|
244
|
+
|
245
|
+
before(:each) do
|
246
|
+
@dummy = DummySerialize.new
|
247
|
+
end
|
248
|
+
|
249
|
+
it 'should have price attr_accessor' do
|
250
|
+
@dummy.should respond_to(:price)
|
251
|
+
@dummy.should respond_to(:price=)
|
252
|
+
end
|
253
|
+
|
254
|
+
it 'should have price_mode attr_accessor' do
|
255
|
+
@dummy.should respond_to(:price_mode)
|
256
|
+
@dummy.should respond_to(:price_mode=)
|
257
|
+
end
|
258
|
+
|
259
|
+
it 'should have price_tax_value method' do
|
260
|
+
@dummy.should respond_to(:price_tax_value)
|
261
|
+
end
|
262
|
+
|
263
|
+
it 'should have update_price method' do
|
264
|
+
@dummy.should respond_to(:update_price)
|
265
|
+
end
|
266
|
+
|
267
|
+
it 'price_net should be converted to integer' do
|
268
|
+
@dummy.price_net = @test_value
|
269
|
+
@dummy.get_price_attribute(:price_net).should be(1020)
|
270
|
+
end
|
271
|
+
|
272
|
+
it 'price_net should return correct value' do
|
273
|
+
@dummy.price_net = @test_value
|
274
|
+
@dummy.price_net.should == BigDecimal.new(@test_value)
|
275
|
+
end
|
276
|
+
|
277
|
+
it 'price_gross should be converted to integer' do
|
278
|
+
@dummy.price_gross = @test_value
|
279
|
+
@dummy.get_price_attribute(:price_gross).should be(1020)
|
280
|
+
end
|
281
|
+
|
282
|
+
it 'price_gross should return correct value' do
|
283
|
+
@dummy.price_gross = @test_value
|
284
|
+
@dummy.price_gross.should == BigDecimal.new(@test_value)
|
285
|
+
end
|
286
|
+
|
287
|
+
it 'calculates price gross from price_net' do
|
288
|
+
@dummy.price = '10.00'
|
289
|
+
@dummy.price_tax = 23
|
290
|
+
@dummy.price_mode = 'net'
|
291
|
+
@dummy.update_price
|
292
|
+
@dummy.price_net.should == BigDecimal.new('10.00')
|
293
|
+
@dummy.price_gross.should == BigDecimal.new('12.30')
|
294
|
+
end
|
295
|
+
|
296
|
+
it 'calculates price net from price gross' do
|
297
|
+
@dummy.price = '12.30'
|
298
|
+
@dummy.price_tax = 23
|
299
|
+
@dummy.price_mode = 'gross'
|
300
|
+
@dummy.update_price
|
301
|
+
@dummy.price_net.should == BigDecimal.new('10.00')
|
302
|
+
@dummy.price_gross.should == BigDecimal.new('12.30')
|
303
|
+
end
|
304
|
+
|
305
|
+
it 'calculates tax value properly' do
|
306
|
+
@dummy.price = '10.00'
|
307
|
+
@dummy.price_tax = 23
|
308
|
+
@dummy.price_mode = 'net'
|
309
|
+
@dummy.update_price
|
310
|
+
@dummy.price_tax_value.should == BigDecimal.new('2.30')
|
311
|
+
end
|
312
|
+
|
313
|
+
end
|
314
|
+
|
315
|
+
describe 'validations' do
|
316
|
+
|
317
|
+
before(:each) do
|
318
|
+
@dummy = DummySerialize.new price_net: '10.00', price_gross: '12.30', price_tax: 23
|
319
|
+
end
|
320
|
+
|
321
|
+
it 'correct should be valid' do
|
322
|
+
@dummy.valid?.should be(true)
|
323
|
+
end
|
324
|
+
|
325
|
+
it "price_net can't be negative" do
|
326
|
+
@dummy.price_net = -1
|
327
|
+
@dummy.valid?.should be(false)
|
328
|
+
end
|
329
|
+
|
330
|
+
it "price_gross can't be negative" do
|
331
|
+
@dummy.price_gross = -1
|
332
|
+
@dummy.valid?.should be(false)
|
333
|
+
end
|
334
|
+
|
335
|
+
it "price_tax can't be negative" do
|
336
|
+
@dummy.price_tax = -1
|
337
|
+
@dummy.valid?.should be(false)
|
338
|
+
end
|
339
|
+
end
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
118
343
|
end
|
data/spec/database.yml
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -4,17 +4,27 @@ require 'yaml'
|
|
4
4
|
|
5
5
|
|
6
6
|
def create_tables
|
7
|
+
#ActiveRecord::Base.connection.execute "CREATE EXTENSION hstore;"
|
8
|
+
|
7
9
|
ActiveRecord::Base.connection.create_table :dummies, force: true do |table|
|
8
10
|
table.column :price_gross, :integer
|
9
11
|
table.column :price_net, :integer
|
10
12
|
table.column :price_tax, :integer
|
11
13
|
end
|
14
|
+
|
15
|
+
ActiveRecord::Base.connection.create_table :dummy_serializes, force: true do |table|
|
16
|
+
table.column :hstore_data, :hstore
|
17
|
+
table.column :hash_data, :text
|
18
|
+
end
|
12
19
|
end
|
13
20
|
|
14
21
|
RSpec.configure do |config|
|
15
22
|
ActiveRecord::Base.establish_connection YAML.load_file("#{File.dirname __FILE__}/database.yml")['test']
|
16
23
|
create_tables
|
24
|
+
#require 'active_support'
|
25
|
+
require 'activerecord-postgres-hstore'
|
17
26
|
require 'models/dummy'
|
27
|
+
require 'models/dummy_serialize'
|
18
28
|
config.color_enabled = true
|
19
29
|
#config.formatter = 'documentation'
|
20
30
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts_as_priceable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-04-
|
12
|
+
date: 2013-04-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -60,7 +60,23 @@ dependencies:
|
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
- !ruby/object:Gem::Dependency
|
63
|
-
name:
|
63
|
+
name: pg
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: activerecord-postgres-hstore
|
64
80
|
requirement: !ruby/object:Gem::Requirement
|
65
81
|
none: false
|
66
82
|
requirements:
|
@@ -95,6 +111,7 @@ files:
|
|
95
111
|
- spec/base_spec.rb
|
96
112
|
- spec/database.yml
|
97
113
|
- spec/models/dummy.rb
|
114
|
+
- spec/models/dummy_serialize.rb
|
98
115
|
- spec/schema_spec.rb
|
99
116
|
- spec/spec_helper.rb
|
100
117
|
homepage: ''
|
@@ -111,7 +128,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
111
128
|
version: '0'
|
112
129
|
segments:
|
113
130
|
- 0
|
114
|
-
hash:
|
131
|
+
hash: -81614923785070028
|
115
132
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
116
133
|
none: false
|
117
134
|
requirements:
|
@@ -120,7 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
120
137
|
version: '0'
|
121
138
|
segments:
|
122
139
|
- 0
|
123
|
-
hash:
|
140
|
+
hash: -81614923785070028
|
124
141
|
requirements: []
|
125
142
|
rubyforge_project:
|
126
143
|
rubygems_version: 1.8.25
|
@@ -131,5 +148,6 @@ test_files:
|
|
131
148
|
- spec/base_spec.rb
|
132
149
|
- spec/database.yml
|
133
150
|
- spec/models/dummy.rb
|
151
|
+
- spec/models/dummy_serialize.rb
|
134
152
|
- spec/schema_spec.rb
|
135
153
|
- spec/spec_helper.rb
|