spree_myriad_options 0.1.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.
Files changed (49) hide show
  1. data/.gitignore +3 -0
  2. data/.rspec +2 -0
  3. data/.rvmrc +1 -0
  4. data/Gemfile +3 -0
  5. data/Gemfile.lock +213 -0
  6. data/Guardfile +19 -0
  7. data/LICENSE +26 -0
  8. data/README.md +114 -0
  9. data/Rakefile +29 -0
  10. data/Versionfile +12 -0
  11. data/app/controllers/spree/orders_controller_decorator.rb +31 -0
  12. data/app/models/spree/line_item_decorator.rb +33 -0
  13. data/app/models/spree/line_item_option_value.rb +27 -0
  14. data/app/models/spree/option_value_decorator.rb +4 -0
  15. data/app/models/spree/order_decorator.rb +30 -0
  16. data/app/overrides/admin_option_value_fields.rb +23 -0
  17. data/app/overrides/admin_order_form_line_item_row.rb +6 -0
  18. data/app/overrides/cart_item_description.rb +5 -0
  19. data/app/overrides/order_item_description.rb +6 -0
  20. data/app/overrides/product_cart_form.rb +5 -0
  21. data/app/views/spree/admin/_order_details_line_item_row.html.erb +6 -0
  22. data/app/views/spree/admin/option_types/_option_value_adder_fields.html.erb +1 -0
  23. data/app/views/spree/admin/option_types/_option_value_customization_fields.html.erb +4 -0
  24. data/app/views/spree/orders/_cart_item_description.html.erb +11 -0
  25. data/app/views/spree/products/_product_cart_form.html.erb +43 -0
  26. data/app/views/spree/shared/_order_item_description.html.erb +7 -0
  27. data/app/views/spree/shared/_order_line_item_options.html.erb +17 -0
  28. data/config/locales/en.yml +5 -0
  29. data/db/migrate/20120606023958_add_line_item_option_values_table.rb +14 -0
  30. data/db/migrate/20120606143114_add_adder_to_option_values.rb +5 -0
  31. data/db/migrate/20120614192000_add_option_value_customization_to_line_item_option_values.rb +5 -0
  32. data/db/migrate/20120614192726_add_adder_to_line_item_option_values.rb +5 -0
  33. data/db/migrate/20120615032058_add_snapshot_cols_to_line_item_option_values.rb +8 -0
  34. data/db/migrate/20120615173147_add_customization_lines_to_option_value.rb +5 -0
  35. data/lib/generators/spree_myriad_options/install/install_generator.rb +19 -0
  36. data/lib/spree_myriad_options/engine.rb +25 -0
  37. data/lib/spree_myriad_options.rb +2 -0
  38. data/script/rails +7 -0
  39. data/spec/controllers/spree/orders_controller_spec.rb +62 -0
  40. data/spec/models/spree/line_item_option_value_spec.rb +10 -0
  41. data/spec/models/spree/line_item_spec.rb +79 -0
  42. data/spec/models/spree/option_value_spec.rb +13 -0
  43. data/spec/models/spree/order_spec.rb +65 -0
  44. data/spec/requests/admin_option_types_spec.rb +58 -0
  45. data/spec/requests/orders_spec.rb +21 -0
  46. data/spec/requests/products_spec.rb +89 -0
  47. data/spec/spec_helper.rb +52 -0
  48. data/spree_myriad_options.gemspec +29 -0
  49. metadata +184 -0
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ log/*.log
2
+ tmp/*
3
+ spec/dummy
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --colour
2
+ --backtrace
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.9.2-p290@global
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,213 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ spree_myriad_options (0.0.2)
5
+ spree_core (~> 1.1)
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ actionmailer (3.2.3)
11
+ actionpack (= 3.2.3)
12
+ mail (~> 2.4.4)
13
+ actionpack (3.2.3)
14
+ activemodel (= 3.2.3)
15
+ activesupport (= 3.2.3)
16
+ builder (~> 3.0.0)
17
+ erubis (~> 2.7.0)
18
+ journey (~> 1.0.1)
19
+ rack (~> 1.4.0)
20
+ rack-cache (~> 1.2)
21
+ rack-test (~> 0.6.1)
22
+ sprockets (~> 2.1.2)
23
+ active_utils (1.0.3)
24
+ activesupport (>= 2.3.11)
25
+ i18n
26
+ activemerchant (1.20.4)
27
+ active_utils (>= 1.0.2)
28
+ activesupport (>= 2.3.11)
29
+ braintree (>= 2.0.0)
30
+ builder (>= 2.0.0)
31
+ i18n
32
+ json (>= 1.5.1)
33
+ money (<= 3.7.1)
34
+ activemodel (3.2.3)
35
+ activesupport (= 3.2.3)
36
+ builder (~> 3.0.0)
37
+ activerecord (3.2.3)
38
+ activemodel (= 3.2.3)
39
+ activesupport (= 3.2.3)
40
+ arel (~> 3.0.2)
41
+ tzinfo (~> 0.3.29)
42
+ activeresource (3.2.3)
43
+ activemodel (= 3.2.3)
44
+ activesupport (= 3.2.3)
45
+ activesupport (3.2.3)
46
+ i18n (~> 0.6)
47
+ multi_json (~> 1.0)
48
+ acts_as_list (0.1.4)
49
+ arel (3.0.2)
50
+ aws-sdk (1.3.9)
51
+ httparty (~> 0.7)
52
+ json (~> 1.4)
53
+ nokogiri (>= 1.4.4)
54
+ uuidtools (~> 2.1)
55
+ braintree (2.16.0)
56
+ builder (>= 2.0.0)
57
+ builder (3.0.0)
58
+ capybara (1.1.2)
59
+ mime-types (>= 1.16)
60
+ nokogiri (>= 1.3.3)
61
+ rack (>= 1.0.0)
62
+ rack-test (>= 0.5.4)
63
+ selenium-webdriver (~> 2.0)
64
+ xpath (~> 0.1.4)
65
+ childprocess (0.3.2)
66
+ ffi (~> 1.0.6)
67
+ cocaine (0.2.1)
68
+ deface (0.9.1)
69
+ nokogiri (~> 1.5.0)
70
+ rails (~> 3.1)
71
+ diff-lcs (1.1.3)
72
+ erubis (2.7.0)
73
+ factory_girl (2.6.4)
74
+ activesupport (>= 2.3.9)
75
+ factory_girl_rails (1.7.0)
76
+ factory_girl (~> 2.6.0)
77
+ railties (>= 3.0.0)
78
+ ffaker (1.12.1)
79
+ ffi (1.0.11)
80
+ guard (1.0.2)
81
+ ffi (>= 0.5.0)
82
+ thor (~> 0.14.6)
83
+ guard-rspec (0.5.11)
84
+ guard (>= 0.8.4)
85
+ highline (1.6.11)
86
+ hike (1.2.1)
87
+ httparty (0.8.3)
88
+ multi_json (~> 1.0)
89
+ multi_xml
90
+ i18n (0.6.0)
91
+ journey (1.0.3)
92
+ jquery-rails (2.0.2)
93
+ railties (>= 3.2.0, < 5.0)
94
+ thor (~> 0.14)
95
+ json (1.7.3)
96
+ kaminari (0.13.0)
97
+ actionpack (>= 3.0.0)
98
+ activesupport (>= 3.0.0)
99
+ railties (>= 3.0.0)
100
+ mail (2.4.4)
101
+ i18n (>= 0.4.0)
102
+ mime-types (~> 1.16)
103
+ treetop (~> 1.4.8)
104
+ mime-types (1.18)
105
+ money (3.7.1)
106
+ i18n (~> 0.4)
107
+ multi_json (1.3.6)
108
+ multi_xml (0.5.1)
109
+ nested_set (1.7.0)
110
+ activerecord (>= 3.0.0)
111
+ railties (>= 3.0.0)
112
+ nokogiri (1.5.3)
113
+ paperclip (2.7.0)
114
+ activerecord (>= 2.3.0)
115
+ activesupport (>= 2.3.2)
116
+ cocaine (>= 0.0.2)
117
+ mime-types
118
+ polyamorous (0.5.0)
119
+ activerecord (~> 3.0)
120
+ polyglot (0.3.3)
121
+ rack (1.4.1)
122
+ rack-cache (1.2)
123
+ rack (>= 0.4)
124
+ rack-ssl (1.3.2)
125
+ rack
126
+ rack-test (0.6.1)
127
+ rack (>= 1.0)
128
+ rails (3.2.3)
129
+ actionmailer (= 3.2.3)
130
+ actionpack (= 3.2.3)
131
+ activerecord (= 3.2.3)
132
+ activeresource (= 3.2.3)
133
+ activesupport (= 3.2.3)
134
+ bundler (~> 1.0)
135
+ railties (= 3.2.3)
136
+ railties (3.2.3)
137
+ actionpack (= 3.2.3)
138
+ activesupport (= 3.2.3)
139
+ rack-ssl (~> 1.3.2)
140
+ rake (>= 0.8.7)
141
+ rdoc (~> 3.4)
142
+ thor (~> 0.14.6)
143
+ rake (0.9.2.2)
144
+ ransack (0.6.0)
145
+ actionpack (~> 3.0)
146
+ activerecord (~> 3.0)
147
+ polyamorous (~> 0.5.0)
148
+ rdoc (3.12)
149
+ json (~> 1.4)
150
+ rspec (2.9.0)
151
+ rspec-core (~> 2.9.0)
152
+ rspec-expectations (~> 2.9.0)
153
+ rspec-mocks (~> 2.9.0)
154
+ rspec-core (2.9.0)
155
+ rspec-expectations (2.9.1)
156
+ diff-lcs (~> 1.1.3)
157
+ rspec-mocks (2.9.0)
158
+ rspec-rails (2.9.0)
159
+ actionpack (>= 3.0)
160
+ activesupport (>= 3.0)
161
+ railties (>= 3.0)
162
+ rspec (~> 2.9.0)
163
+ rubyzip (0.9.8)
164
+ selenium-webdriver (2.20.0)
165
+ childprocess (>= 0.2.5)
166
+ ffi (~> 1.0)
167
+ multi_json (~> 1.0)
168
+ rubyzip
169
+ shoulda-matchers (1.0.0)
170
+ spree_core (1.1.1)
171
+ activemerchant (= 1.20.4)
172
+ acts_as_list (= 0.1.4)
173
+ aws-sdk (~> 1.3.4)
174
+ deface (>= 0.8.0)
175
+ ffaker (~> 1.12.0)
176
+ highline (= 1.6.11)
177
+ jquery-rails (~> 2.0.0)
178
+ kaminari (>= 0.13.0)
179
+ nested_set (= 1.7.0)
180
+ paperclip (~> 2.7)
181
+ rails (>= 3.2.2, <= 3.2.3)
182
+ ransack (~> 0.6.0)
183
+ state_machine (= 1.1.2)
184
+ stringex (~> 1.3.2)
185
+ sprockets (2.1.3)
186
+ hike (~> 1.2)
187
+ rack (~> 1.0)
188
+ tilt (~> 1.1, != 1.3.0)
189
+ sqlite3 (1.3.6)
190
+ state_machine (1.1.2)
191
+ stringex (1.3.3)
192
+ thor (0.14.6)
193
+ tilt (1.3.3)
194
+ treetop (1.4.10)
195
+ polyglot
196
+ polyglot (>= 0.3.1)
197
+ tzinfo (0.3.33)
198
+ uuidtools (2.1.2)
199
+ xpath (0.1.4)
200
+ nokogiri (~> 1.3)
201
+
202
+ PLATFORMS
203
+ ruby
204
+
205
+ DEPENDENCIES
206
+ capybara
207
+ factory_girl_rails (~> 1.7)
208
+ ffaker
209
+ guard-rspec (~> 0.5.0)
210
+ rspec-rails (~> 2.9.0)
211
+ shoulda-matchers (~> 1.0.0)
212
+ spree_myriad_options!
213
+ sqlite3
data/Guardfile ADDED
@@ -0,0 +1,19 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec', :version => 2 do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+
9
+ # Rails example
10
+ watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
11
+ watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
12
+ watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
13
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
14
+ watch('config/routes.rb') { "spec/routing" }
15
+ watch('app/controllers/application_controller.rb') { "spec/controllers" }
16
+ # Capybara request specs
17
+ watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
18
+ end
19
+
data/LICENSE ADDED
@@ -0,0 +1,26 @@
1
+ Copyright (c) 2012 [name of plugin creator]
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+ * Neither the name Spree nor the names of its contributors may be used to
13
+ endorse or promote products derived from this software without specific
14
+ prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,114 @@
1
+ Spree Myriad Options
2
+ ==================
3
+
4
+ This extension makes a few changes to the Spree data model and controller
5
+ logic, to let you create Products with many Option Types/Values, but not have
6
+ to maintain sets of Variants for each combination.
7
+
8
+ In other words, if you have a store where Products have 5 user-selectable
9
+ options, and each option has 10 potential values, and you want to offer every
10
+ combination of those options to customers, in a default Spree installation your
11
+ store admin would be faced with creating and maintaining 97,656,259 Variants -
12
+ just for that product.
13
+
14
+ This extension bypasses the LineItem/Variant/Option Value relationship to make
15
+ that uneccessary. You just create the list of Option Types and Option Values
16
+ normally in Spree, and associate those as needed to Products. A LineItem then
17
+ has many OptionValue's directly, and only is tied to the 'master' variant for
18
+ that product.
19
+
20
+ Of course, with this extension, inventory is no longer tracked on a
21
+ per-option-combination (Variant) basis. It is only tracked per-product (Master
22
+ Variant). The use case would assume that inventory is not important, or that
23
+ products are manufactured to order.
24
+
25
+ Changes to the Product add-to-cart form will list selections for each option as
26
+ a set of radio buttons.
27
+
28
+ In the admin, Option Values also get a new 'adder' field, which is added to the
29
+ line item price when that option is selected and added to the cart.
30
+
31
+ Option Values can also be set up by the admin with a "Customization Lines"
32
+ numeric value, which may be useful for "Engraving Message" or similar
33
+ user-entered text. This should result in the customer seeing the specified
34
+ number of fields below each option value, which they can fill out as needed.
35
+ There is as yet no validation on these user-generated values.
36
+
37
+
38
+ Status
39
+ ======
40
+
41
+ Version 0.1.0
42
+
43
+ Tests complete and passing.
44
+
45
+ Example
46
+ =======
47
+
48
+ Add to gemfile
49
+
50
+ gem 'spree_myriad_options', :git => 'git://github.com/sbeam/spree_myriad_options.git'
51
+
52
+ Install
53
+
54
+ $ bundle
55
+ $ bundle exec rake railties:install:migrations FROM=spree_myriad_options
56
+ $ bundle exec rake db:migrate
57
+
58
+ Restart Rails, and in your Products admin, add some Option Types and Values to
59
+ a Product (and remove any Variants - only the invisible 'master' Variant should
60
+ exist on a Product for this extension to affect it.
61
+
62
+ Then in the Product detail page you should see sets of radio buttons for each
63
+ configured option. Each cart/order view should display the selected options in
64
+ the line item detail.
65
+
66
+ Note, this extension might not jive with some others, like
67
+ `spree_variant_options` (although it's a great extension, it still would
68
+ require maintaining Variants for each option combination)
69
+
70
+ Similar Gems
71
+ ------------
72
+
73
+ You might also want to look at
74
+ [spree_flexi_variants](https://github.com/jsqu99/spree_flexi_variants) which
75
+ has similar goals, and more features than this. Since our needs were simpler,
76
+ this was begun as a total rewrite that would simply provide a way around the
77
+ Variant maintance problem in Spree, no more no less. There are now a few more
78
+ features, but think of this as more a clean, well-tested blank-slate that can
79
+ be built upon to meet your app's needs, rather than a turnkey install-and-go
80
+ extension.
81
+
82
+ TODO
83
+ ----
84
+
85
+ * replace simple `option_value.customization_lines` with Customization
86
+ classes, ie includable modules with field definitions and validation
87
+ callbacks
88
+ * (maybe) some JS to auto-update the price on the product detail form
89
+
90
+ Contributions
91
+ -------------
92
+
93
+ feedback, ideas, reports, new features and fixes would be great. Fork and
94
+ create a pull request. Patches should come with green tests.
95
+
96
+ Testing
97
+ -------
98
+
99
+ Be sure to bundle your dependencies and then create a dummy test app for the
100
+ specs to run against.
101
+
102
+ in Spree 1.1.2+, you should be able to do this -
103
+
104
+ $ bundle
105
+ $ bundle exec rake test_app
106
+ $ bundle exec guard
107
+
108
+ But, due to an issue with the dummy app generator and namespacing in
109
+ Spree 1.1.1 (see https://github.com/spree/spree/issues/1580) you will need to
110
+ create a barebones Spree site somewhere else and hook this engine to that for
111
+ testing. See `spec/spec_helper.rb` and change the `path_to_test_store` value.
112
+
113
+ Copyright (c) 2012 [Sam Beam, creator], released under the New BSD License
114
+
data/Rakefile ADDED
@@ -0,0 +1,29 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/packagetask'
4
+ require 'rubygems/package_task'
5
+ require 'rspec/core/rake_task'
6
+ require 'spree/core/testing_support/common_rake'
7
+
8
+ RSpec::Core::RakeTask.new
9
+
10
+ task :default => [:spec]
11
+
12
+ spec = eval(File.read('spree_myriad_options.gemspec'))
13
+
14
+ Gem::PackageTask.new(spec) do |p|
15
+ p.gem_spec = spec
16
+ end
17
+
18
+ desc 'Release to gemcutter'
19
+ task :release => :package do
20
+ require 'rake/gemcutter'
21
+ Rake::Gemcutter::Tasks.new(spec).define
22
+ Rake::Task['gem:push'].invoke
23
+ end
24
+
25
+ desc 'Generates a dummy app for testing'
26
+ task :test_app do
27
+ ENV['LIB_NAME'] = 'spree_myriad_options'
28
+ Rake::Task['common:test_app'].invoke
29
+ end
data/Versionfile ADDED
@@ -0,0 +1,12 @@
1
+ # This file is used to designate compatibilty with different versions of Spree
2
+ # Please see http://spreecommerce.com/documentation/extensions.html#versionfile for details
3
+
4
+ # Examples
5
+ #
6
+ # '1.2.x' => { :branch => 'master' }
7
+ # '1.1.x' => { :branch => '1-1-stable' }
8
+ # '1.0.x' => { :branch => '1-0-stable' }
9
+ # '0.70.x' => { :branch => '0-70-stable' }
10
+ # '0.40.x' => { :tag => 'v1.0.0', :version => '1.0.0' }
11
+
12
+ '1.1.x' => { :branch => 'master' }
@@ -0,0 +1,31 @@
1
+ Spree::OrdersController.class_eval do
2
+
3
+ # prepend to orders#populate to
4
+ # look for params[:options] and attach the option values
5
+ # to the add_variant call
6
+ def populate_with_options
7
+ @order = current_order(true)
8
+
9
+ if params[:options].present? && params[:variants]
10
+
11
+ params[:variants].each do |variant_id, quantity|
12
+ if variant = Spree::Variant.find(variant_id)
13
+ quantity = quantity.to_i
14
+
15
+ option_values = Spree::OptionValue.find(params[:options].values.map(&:to_i))
16
+
17
+ line_item = @order.add_variant(variant, quantity, option_values)
18
+
19
+ line_item.customizations = params[:customizations] if params[:customizations]
20
+ end
21
+ end
22
+
23
+ params.delete(:variants) # prevent populate_orig from adding again
24
+ end
25
+
26
+ populate_without_options
27
+ end
28
+
29
+ alias_method_chain :populate, :options
30
+
31
+ end
@@ -0,0 +1,33 @@
1
+ Spree::LineItem.class_eval do
2
+
3
+ has_many :line_item_option_values, :dependent => :destroy
4
+ has_many :option_values, :through => :line_item_option_values
5
+
6
+ alias_method :options, :line_item_option_values
7
+
8
+ def has_options?
9
+ self.option_values.length > 0
10
+ end
11
+
12
+ def copy_price
13
+ self.price = variant.price if variant && price.nil?
14
+
15
+ self.option_values.each do |val|
16
+ self.price += val.adder
17
+ end
18
+ end
19
+
20
+ def customizations= params
21
+ params.each do |option_value_id, val|
22
+ if option = self.options.find_by_option_value_id(option_value_id)
23
+ option.customization = val
24
+ option.save
25
+ end
26
+ end
27
+ end
28
+
29
+ def customizations
30
+ self.options.each_with_object({}) { |opt, h| h[opt.option_value_id] = opt.customization unless opt.customization.blank? }
31
+ end
32
+
33
+ end
@@ -0,0 +1,27 @@
1
+ module Spree
2
+ class LineItemOptionValue < ActiveRecord::Base
3
+ belongs_to :line_item
4
+ belongs_to :option_value, :class_name => 'Spree::OptionValue'
5
+
6
+ before_save :snapshot_option_values
7
+
8
+ serialize :customization
9
+
10
+ def customizable?
11
+ !self.option_value.customization_lines.blank?
12
+ end
13
+
14
+ private
15
+
16
+ def snapshot_option_values
17
+ if option_value
18
+ self.adder = option_value.adder
19
+ self.value_name = option_value.name
20
+ self.value_presentation = option_value.presentation
21
+ self.type_name = option_value.option_type.name
22
+ self.type_presentation = option_value.option_type.presentation
23
+ end
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,4 @@
1
+ Spree::OptionValue.class_eval do
2
+ attr_accessible :adder, :customization_lines
3
+ has_many :line_item_option_values
4
+ end
@@ -0,0 +1,30 @@
1
+ Spree::Order.class_eval do
2
+
3
+ def contains? variant, options
4
+ options ||= []
5
+ line_items.detect { |line_item| line_item.variant_id == variant.id && line_item.option_values == options }
6
+ end
7
+
8
+
9
+ def add_variant variant, quantity=1, options=nil
10
+
11
+ current_item = contains?(variant, options)
12
+
13
+ if current_item
14
+ current_item.quantity += quantity
15
+ current_item.save
16
+ else
17
+ current_item = Spree::LineItem.new(:quantity => quantity)
18
+ current_item.variant = variant
19
+ current_item.price = variant.price
20
+
21
+ current_item.option_values = options if options
22
+
23
+ self.line_items << current_item
24
+ end
25
+
26
+ current_item
27
+
28
+ end
29
+
30
+ end
@@ -0,0 +1,23 @@
1
+ Deface::Override.new(:virtual_path => "spree/admin/option_types/_option_value_fields",
2
+ :name => "admin_option_value_fields",
3
+ :insert_after => "tr[data-hook=option_value] td.presentation",
4
+ :partial => "spree/admin/option_types/option_value_adder_fields",
5
+ :disabled => false)
6
+
7
+ Deface::Override.new(:virtual_path => "spree/admin/option_types/edit",
8
+ :name => "admin_option_value_header",
9
+ :insert_after => "thead[data-hook=option_header] th:nth-child(2)",
10
+ :text => '<th>Adder</th>',
11
+ :disabled => false)
12
+
13
+ Deface::Override.new(:virtual_path => "spree/admin/option_types/_option_value_fields",
14
+ :name => "admin_option_value_customization_fields",
15
+ :insert_after => "tr[data-hook=option_value] td.adder",
16
+ :partial => "spree/admin/option_types/option_value_customization_fields",
17
+ :disabled => false)
18
+
19
+ Deface::Override.new(:virtual_path => "spree/admin/option_types/edit",
20
+ :name => "admin_option_value_customization_header",
21
+ :insert_after => "thead[data-hook=option_header] th:nth-child(3)",
22
+ :text => '<th>Customization Lines</th>',
23
+ :disabled => false)
@@ -0,0 +1,6 @@
1
+ Deface::Override.new(:virtual_path => "spree/admin/shared/_order_details",
2
+ :name => "admin_order_details_line_item_row",
3
+ :replace => "tr[data-hook=order_details_line_item_row] td:first-child", # replace the first <td> in the row only
4
+ :partial => "spree/admin/order_details_line_item_row",
5
+ :disabled => false)
6
+
@@ -0,0 +1,5 @@
1
+ Deface::Override.new(:virtual_path => "spree/orders/_line_item",
2
+ :name => "cart_item_description",
3
+ :replace => "td[data-hook=cart_item_description]",
4
+ :partial => "spree/orders/cart_item_description",
5
+ :disabled => false)
@@ -0,0 +1,6 @@
1
+ Deface::Override.new(:virtual_path => "spree/shared/_order_details",
2
+ :name => "order_item_description",
3
+ :replace => "td[data-hook=order_item_description]",
4
+ :partial => "spree/shared/order_item_description",
5
+ :disabled => false)
6
+
@@ -0,0 +1,5 @@
1
+ Deface::Override.new(:virtual_path => "spree/products/_cart_form",
2
+ :name => "cart_item_image",
3
+ :insert_top => "div#inside-product-cart-form",
4
+ :partial => "spree/products/product_cart_form",
5
+ :disabled => false)
@@ -0,0 +1,6 @@
1
+ <td width="300"><%= item.variant.product.name %>
2
+ <%= "(" + variant_options(item.variant) + ")" unless item.variant.option_values.empty? %>
3
+ <%- if item.has_options? %>
4
+ <%= render :partial => 'spree/shared/order_line_item_options', :locals => { :item => item } %>
5
+ <% end %>
6
+ </td>
@@ -0,0 +1 @@
1
+ <td class="adder"><%= f.text_field :adder, :value => number_to_currency(f.object.adder, :unit => '') %></td>
@@ -0,0 +1,4 @@
1
+ <td class="customization">
2
+ <%= f.number_field :customization_lines, :in => 0..20 %>
3
+ </td>
4
+
@@ -0,0 +1,11 @@
1
+ <td data-hook="cart_item_description">
2
+
3
+ <h4><%= link_to variant.product.name, product_path(variant.product) %></h4>
4
+
5
+ <%= truncate(variant.product.description, :length => 100, :omission => "...") %>
6
+
7
+ <%- if line_item.has_options? %>
8
+ <%= render :partial => 'spree/shared/order_line_item_options', :locals => { :item => line_item } %>
9
+ <% end %>
10
+
11
+ </td>