spree_myriad_options 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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>