railscart 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/History.txt +5 -0
  2. data/Manifest.txt +22 -20
  3. data/bin/railscart +52 -12
  4. data/config/requirements.rb +0 -2
  5. data/lib/railscart/version.rb +1 -1
  6. data/starter_app/config/database.master.yml +23 -0
  7. data/starter_app/config/database.yml +7 -21
  8. data/starter_app/config/environment.rb +2 -0
  9. data/starter_app/db/migrate/007_railscart_to_version_23.rb +9 -0
  10. data/starter_app/db/sample/line_items.yml +4 -13
  11. data/starter_app/db/sample/option_types.yml +6 -0
  12. data/starter_app/db/sample/option_values.yml +35 -13
  13. data/starter_app/db/sample/orders.yml +0 -2
  14. data/starter_app/db/sample/product_option_types.yml +8 -0
  15. data/starter_app/db/sample/products.yml +1 -22
  16. data/starter_app/db/sample/skus.yml +7 -14
  17. data/starter_app/db/sample/variations.yml +31 -20
  18. data/starter_app/vendor/plugins/railscart/app/controllers/admin/option_types_controller.rb +70 -0
  19. data/starter_app/vendor/plugins/railscart/app/controllers/admin/products_controller.rb +54 -6
  20. data/starter_app/vendor/plugins/railscart/app/helpers/admin/base_helper.rb +0 -1
  21. data/starter_app/vendor/plugins/railscart/app/helpers/admin/products_helper.rb +7 -0
  22. data/starter_app/vendor/plugins/railscart/app/helpers/rails_cart/base_helper.rb +10 -0
  23. data/starter_app/vendor/plugins/railscart/app/helpers/store_helper.rb +1 -1
  24. data/starter_app/vendor/plugins/railscart/app/models/cart_item.rb +3 -2
  25. data/starter_app/vendor/plugins/railscart/app/models/good.rb +4 -0
  26. data/starter_app/vendor/plugins/railscart/app/models/option_type.rb +4 -0
  27. data/starter_app/vendor/plugins/railscart/app/models/option_value.rb +3 -2
  28. data/starter_app/vendor/plugins/railscart/app/models/order_mailer.rb +2 -0
  29. data/starter_app/vendor/plugins/railscart/app/models/product.rb +22 -17
  30. data/starter_app/vendor/plugins/railscart/app/models/product_option_type.rb +5 -0
  31. data/starter_app/vendor/plugins/railscart/app/models/variation.rb +6 -3
  32. data/starter_app/vendor/plugins/railscart/app/views/admin/option_types/_form.rhtml +16 -0
  33. data/starter_app/vendor/plugins/railscart/app/views/admin/option_types/_new_option_value.rhtml +13 -0
  34. data/starter_app/vendor/plugins/railscart/app/views/admin/option_types/_option_values.rhtml +43 -0
  35. data/starter_app/vendor/plugins/railscart/app/views/admin/option_types/edit.rhtml +8 -0
  36. data/starter_app/vendor/plugins/railscart/app/views/admin/option_types/index.rhtml +23 -0
  37. data/starter_app/vendor/plugins/railscart/app/views/admin/{options → option_types}/new.rhtml +2 -2
  38. data/starter_app/vendor/plugins/railscart/app/views/admin/option_types/select.rhtml +28 -0
  39. data/starter_app/vendor/plugins/railscart/app/views/admin/option_types/test.rhtml +8 -0
  40. data/starter_app/vendor/plugins/railscart/app/views/admin/products/_form.rhtml +21 -16
  41. data/starter_app/vendor/plugins/railscart/app/views/admin/products/_menu.rhtml +1 -2
  42. data/starter_app/vendor/plugins/railscart/app/views/admin/products/_new_variation.rhtml +11 -0
  43. data/starter_app/vendor/plugins/railscart/app/views/admin/products/_option_types.rhtml +43 -0
  44. data/starter_app/vendor/plugins/railscart/app/views/admin/products/_variations.rhtml +42 -0
  45. data/starter_app/vendor/plugins/railscart/app/views/cart/index.rhtml +1 -1
  46. data/starter_app/vendor/plugins/railscart/app/views/order_mailer/cancel.rhtml +1 -1
  47. data/starter_app/vendor/plugins/railscart/app/views/order_mailer/confirm.rhtml +1 -1
  48. data/starter_app/vendor/plugins/railscart/app/views/shared/_order_details.rhtml +1 -1
  49. data/starter_app/vendor/plugins/railscart/app/views/store/show.rhtml +1 -6
  50. data/starter_app/vendor/plugins/railscart/assets/stylesheets/products/_controller.css +25 -0
  51. data/starter_app/vendor/plugins/railscart/assets/stylesheets/railscart-admin.css +27 -1
  52. data/starter_app/vendor/plugins/railscart/db/migrate/007_create_option_groups.rb +5 -5
  53. data/starter_app/vendor/plugins/railscart/db/migrate/008_create_option_values.rb +7 -3
  54. data/starter_app/vendor/plugins/railscart/db/migrate/009_create_options.rb +4 -4
  55. data/starter_app/vendor/plugins/railscart/db/migrate/015_create_variations.rb +4 -7
  56. data/starter_app/vendor/plugins/railscart/db/migrate/021_create_option_types.rb +13 -0
  57. data/starter_app/vendor/plugins/railscart/db/migrate/022_create_product_option_types.rb +14 -0
  58. data/starter_app/vendor/plugins/railscart/db/migrate/023_create_option_values_variations.rb +12 -0
  59. metadata +24 -22
  60. data/log/debug.log +0 -0
  61. data/starter_app/db/sample/option_groups.yml +0 -16
  62. data/starter_app/db/sample/options.yml +0 -3
  63. data/starter_app/vendor/plugins/railscart/app/controllers/admin/option_groups_controller.rb +0 -36
  64. data/starter_app/vendor/plugins/railscart/app/controllers/admin/option_values_controller.rb +0 -42
  65. data/starter_app/vendor/plugins/railscart/app/controllers/admin/options_controller.rb +0 -52
  66. data/starter_app/vendor/plugins/railscart/app/helpers/admin/option_groups_helper.rb +0 -2
  67. data/starter_app/vendor/plugins/railscart/app/models/option.rb +0 -4
  68. data/starter_app/vendor/plugins/railscart/app/models/option_group.rb +0 -6
  69. data/starter_app/vendor/plugins/railscart/app/views/admin/option_groups/_form.rhtml +0 -19
  70. data/starter_app/vendor/plugins/railscart/app/views/admin/option_groups/new.rhtml +0 -8
  71. data/starter_app/vendor/plugins/railscart/app/views/admin/option_values/_form.rhtml +0 -8
  72. data/starter_app/vendor/plugins/railscart/app/views/admin/option_values/edit.rhtml +0 -8
  73. data/starter_app/vendor/plugins/railscart/app/views/admin/option_values/list.rhtml +0 -22
  74. data/starter_app/vendor/plugins/railscart/app/views/admin/option_values/new.rhtml +0 -8
  75. data/starter_app/vendor/plugins/railscart/app/views/admin/options/_form.rhtml +0 -7
  76. data/starter_app/vendor/plugins/railscart/app/views/admin/options/edit.rhtml +0 -26
  77. data/starter_app/vendor/plugins/railscart/app/views/admin/options/list.rhtml +0 -23
  78. data/starter_app/vendor/plugins/railscart/app/views/shared/_variations.rhtml +0 -60
@@ -1,35 +1,28 @@
1
1
  ror_tote:
2
- id: 1
3
- stockable_id: 1
2
+ stockable: ror_tote
4
3
  stockable_type: Product
5
4
  number: RR1001
6
5
  ror_bag:
7
- id: 2
8
- stockable_id: 2
6
+ stockable: ror_bag
9
7
  stockable_type: Product
10
8
  number: RR1002
11
9
  ror_baseball_jersey:
12
- id: 3
13
- stockable_id: 3
10
+ stockable: ror_baseball_jersey
14
11
  stockable_type: Product
15
12
  number: RR1003
16
13
  ror_jr_spaghetti:
17
- id: 4
18
- stockable_id: 4
14
+ stockable: ror_jr_spaghetti
19
15
  stockable_type: Product
20
16
  number: RR1004
21
17
  ror_mug:
22
- id: 5
23
- stockable_id: 5
18
+ stockable: ror_mug
24
19
  stockable_type: Product
25
20
  number: RR1005
26
21
  ror_ringer:
27
- id: 6
28
- stockable_id: 6
22
+ stockable: ror_ringer
29
23
  stockable_type: Product
30
24
  number: RR1006
31
25
  ror_stein:
32
- id: 7
33
- stockable_id: 7
26
+ stockable: ror_stein
34
27
  stockable_type: Product
35
28
  number: RR1007
@@ -1,20 +1,31 @@
1
- s:
2
- id: 1
3
- name: 'Size: S'
4
- variable_id: 2
5
- variable_type: Category
6
- m:
7
- id: 2
8
- name: 'Size: M'
9
- variable_id: 2
10
- variable_type: Category
11
- l:
12
- id: 3
13
- name: 'Size: L'
14
- variable_id: 2
15
- variable_type: Category
16
- xl:
17
- id: 4
18
- name: 'Size: XL'
19
- variable_id: 2
20
- variable_type: Category
1
+ small-red-baseball:
2
+ product: ror_baseball_jersey
3
+ option_values: s, red
4
+ small-blue-baseball:
5
+ product: ror_baseball_jersey
6
+ option_values: s, blue
7
+ small-green-baseball:
8
+ product: ror_baseball_jersey
9
+ option_values: s, green
10
+ med-red-baseball:
11
+ product: ror_baseball_jersey
12
+ option_values: m, red
13
+ med-blue-baseball:
14
+ product: ror_baseball_jersey
15
+ option_values: m, blue
16
+ med-green-baseball:
17
+ product: ror_baseball_jersey
18
+ option_values: m, green
19
+ large-red-baseball:
20
+ product: ror_baseball_jersey
21
+ option_values: l, red
22
+ large-blue-baseball:
23
+ product: ror_baseball_jersey
24
+ option_values: l, blue
25
+ large-green-baseball:
26
+ product: ror_baseball_jersey
27
+ option_values: l, green
28
+ xlarge-green-baseball:
29
+ product: ror_baseball_jersey
30
+ option_values: xl, red
31
+
@@ -0,0 +1,70 @@
1
+ class Admin::OptionTypesController < Admin::BaseController
2
+ def select
3
+ @product = Product.find(params[:id])
4
+ @option_types = OptionType.find(:all)
5
+ selected_option_types = []
6
+ @product.selected_options.each do |so|
7
+ selected_option_types << so.option_type
8
+ end
9
+ @option_types.delete_if {|ot| selected_option_types.include? ot}
10
+
11
+ render :layout => false
12
+ end
13
+
14
+ def index
15
+ @option_types = OptionType.find(:all)
16
+ end
17
+
18
+ def new
19
+ if request.post?
20
+ @option_type = OptionType.new(params['option_type'])
21
+ if @option_type.save
22
+ flash[:notice] = 'Option type was successfully created.'
23
+ redirect_to :action => 'index'
24
+ else
25
+ logger.error("unable to create new option type: #{@option_type.inspect}")
26
+ flash[:error] = 'Problem saving new option type.'
27
+ render :action => 'new'
28
+ end
29
+ else
30
+ @option_type = OptionType.new
31
+ end
32
+ end
33
+
34
+ def edit
35
+ @option_type = OptionType.find(params[:id])
36
+ if request.post?
37
+ success = @option_type.update_attributes(params[:option_type])
38
+ if success and params[:option_value]
39
+ option_value = OptionValue.new(params[:option_value])
40
+ @option_type.option_values << option_value
41
+ success = @option_type.save
42
+ end
43
+ flash[:notice] = 'Option type was successfully updated.' if success
44
+ flash[:error] = "Problem updating option type." if not success
45
+ redirect_to :action => 'edit', :id => @option_type
46
+ end
47
+ end
48
+
49
+ def delete
50
+ Option.delete(params[:id])
51
+ redirect_to :action => 'index'
52
+ end
53
+
54
+ #AJAX support method
55
+ def new_option_value
56
+ @option_type = OptionType.find(params[:id])
57
+ render :partial => 'new_option_value',
58
+ :locals => {:option_type => @option_type},
59
+ :layout => false
60
+ end
61
+
62
+ #AJAX support method
63
+ def delete_option_value
64
+ OptionValue.delete(params[:option_value_id])
65
+ @option_type = OptionType.find(params[:id])
66
+ render :partial => 'option_values',
67
+ :locals => {:option_type => @option_type},
68
+ :layout => false
69
+ end
70
+ end
@@ -62,8 +62,10 @@ class Admin::ProductsController < Admin::BaseController
62
62
  category_id = params[:category]
63
63
  @product.category = (category_id.blank? ? nil : Category.find(params[:category]))
64
64
 
65
- @product.sku.number = params[:sku][:number]
66
65
 
66
+ @product.sku.number = params[:sku][:number]
67
+ @product.sku.save
68
+
67
69
  if params[:variation]
68
70
  @variation = Variation.new(params[:variation])
69
71
  unless @variation.valid?
@@ -79,16 +81,27 @@ class Admin::ProductsController < Admin::BaseController
79
81
  unless params[:tags].blank?
80
82
  @product.tag_with params[:tags]
81
83
  @product.save
82
- end
84
+ end
85
+
86
+ if params[:new_variation]
87
+ v = Variation.new
88
+ params[:new_variation].each do |key, value|
89
+ v.option_values << OptionValue.find(value)
90
+ end
91
+ v.save
92
+ @product.variations << v
93
+ @product.save
94
+ end
83
95
 
84
96
  @product.tax_treatments = TaxTreatment.find(params[:tax_treatments]) if params[:tax_treatments]
85
97
  @product.save
86
98
 
87
- if @product.sku.save && @product.update_attributes(params[:product])
99
+ #if @product.sku.save && @product.update_attributes(params[:product])
100
+ if @product.update_attributes(params[:product])
88
101
  flash[:notice] = 'Product was successfully updated.'
89
- redirect_to :action => 'show', :id => @product
102
+ redirect_to :action => 'edit', :id => @product
90
103
  else
91
- render :action => 'edit', :id => @product
104
+ flash.now[:error] = 'Problem updating product.'
92
105
  end
93
106
  else
94
107
  @product = Product.find(params[:id])
@@ -104,6 +117,26 @@ class Admin::ProductsController < Admin::BaseController
104
117
  redirect_to :action => 'index'
105
118
  end
106
119
 
120
+ #AJAX support method
121
+ def add_option_type
122
+ @product = Product.find(params[:id])
123
+ pot = ProductOptionType.new(:product => @product, :option_type => OptionType.find(params[:option_type_id]))
124
+ @product.selected_options << pot
125
+ @product.save
126
+ render :partial => 'option_types',
127
+ :locals => {:product => @product},
128
+ :layout => false
129
+ end
130
+
131
+ #AJAX support method
132
+ def remove_option_type
133
+ ProductOptionType.delete(params[:product_option_type_id])
134
+ @product = Product.find(params[:id])
135
+ render :partial => 'option_types',
136
+ :locals => {:product => @product},
137
+ :layout => false
138
+ end
139
+
107
140
  # AJAX method to show tax treatments based on change in category
108
141
  def tax_treatments
109
142
  product = Product.find_or_initialize_by_id(params[:id])
@@ -117,9 +150,24 @@ class Admin::ProductsController < Admin::BaseController
117
150
  :locals => {:tax_treatments => @all_tax_treatments, :selected_treatments => product.tax_treatments},
118
151
  :layout => false
119
152
  end
120
-
153
+
154
+ #AJAX method
121
155
  def new_variation
156
+ @product = Product.find(params[:id])
122
157
  @variation = Variation.new
158
+ render :partial => 'new_variation',
159
+ :locals => {:product => @product},
160
+ :layout => false
161
+ end
162
+
163
+ #AJAX method
164
+ def delete_variation
165
+ @product = Product.find(params[:id])
166
+ Variation.destroy(params[:variation_id])
167
+ flash.now[:notice] = 'Variation successfully removed.'
168
+ render :partial => 'variations',
169
+ :locals => {:product => @product},
170
+ :layout => false
123
171
  end
124
172
 
125
173
  protected
@@ -1,5 +1,4 @@
1
1
  module Admin::BaseHelper
2
-
3
2
  def breadcrumb_nav category
4
3
  ancestor(category) + link_to(category.name, :id => category)
5
4
  end
@@ -0,0 +1,7 @@
1
+ module Admin::ProductsHelper
2
+ def option_type_select(so)
3
+ select(:new_variation,
4
+ so.option_type.presentation,
5
+ so.option_type.option_values.collect {|ov| [ ov.presentation, ov.id ] })
6
+ end
7
+ end
@@ -64,4 +64,14 @@ module RailsCart::BaseHelper
64
64
  def yesterdays_short_date
65
65
  utc_to_local(Time.now.utc.yesterday).to_ordinalized_s(:stub)
66
66
  end
67
+
68
+
69
+ # human readable list of variation options
70
+ def variation_options(v)
71
+ list = []
72
+ v.option_values.each do |ov|
73
+ list << ov.option_type.presentation + ": " + ov.presentation
74
+ end
75
+ list.to_sentence({:connector => ","})
76
+ end
67
77
  end
@@ -1,3 +1,3 @@
1
1
  module StoreHelper
2
-
2
+
3
3
  end
@@ -21,8 +21,9 @@ class CartItem < ActiveRecord::Base
21
21
  end
22
22
 
23
23
  def price
24
- pe = self.variation ? self.variation.price_effect : 0
25
- self.product.price + pe
24
+ self.product.price
25
+ #pe = self.variation ? self.variation.price_effect : 0
26
+ #self.product.price + pe
26
27
  end
27
28
 
28
29
  end
@@ -0,0 +1,4 @@
1
+ class Good < ActiveRecord::Base
2
+ belongs_to :product
3
+ has_and_belongs_to_many :option_values
4
+ end
@@ -0,0 +1,4 @@
1
+ class OptionType < ActiveRecord::Base
2
+ has_many :option_values, :order => :position, :dependent => :destroy
3
+ validates_presence_of :name
4
+ end
@@ -1,4 +1,5 @@
1
1
  class OptionValue < ActiveRecord::Base
2
- has_many :option_groups
3
- has_many :options, :through => :option_groups
2
+ belongs_to :option_type
3
+ acts_as_list :scope => :option_type
4
+ has_and_belongs_to_many :variations
4
5
  end
@@ -1,4 +1,6 @@
1
1
  class OrderMailer < ActionMailer::Base
2
+ helper "rails_cart/base"
3
+
2
4
  def confirm(order, resend = false)
3
5
  @subject = (resend ? "[RESEND] " : "")
4
6
  @subject += 'Order Confirmation #' + order.number
@@ -1,12 +1,17 @@
1
1
  class Product < ActiveRecord::Base
2
- has_many :variations, :as => :variable, :dependent => :destroy
2
+ has_many :product_option_types, :dependent => :destroy
3
+ has_many :option_types, :through => :product_option_types
4
+ has_many :variations, :dependent => :destroy
3
5
  belongs_to :category
4
6
  has_and_belongs_to_many :tax_treatments
7
+ #has_many :variations, :as => :variable, :dependent => :destroy
5
8
  has_one :sku, :as => :stockable, :dependent => :destroy
6
9
  validates_presence_of :name
7
10
  validates_presence_of :description
8
11
  validates_presence_of :price
9
12
 
13
+ alias :selected_options :product_option_types
14
+
10
15
  def file=(incoming_file)
11
16
  @temp_file = incoming_file
12
17
  #manually set the ActiveRecord field since its the file that is posted (and not filename)
@@ -29,11 +34,11 @@ class Product < ActiveRecord::Base
29
34
  # previous category
30
35
  def before_update
31
36
  return if self.category.nil?
32
- unless self.category.variations.empty?
33
- self.ar_variations.each do |v|
34
- v.destroy
35
- end
36
- end
37
+ #unless self.category.variations.empty?
38
+ # self.ar_variations.each do |v|
39
+ # v.destroy
40
+ # end
41
+ #end
37
42
  ar_tax_treatments.clear unless self.category.tax_treatments.empty?
38
43
  end
39
44
 
@@ -44,19 +49,19 @@ class Product < ActiveRecord::Base
44
49
 
45
50
  # Serious Ruby hacking going on here. We alias the original method for the association as added by
46
51
  # ActiveRecord and then override it so we can return the categories variations if they are present.
47
- alias :ar_variations :variations
48
- def variations
49
- v = ar_variations
50
- return v unless v.empty?
51
- return v if self.category.nil?
52
- if self.category.variations.empty?
52
+ #alias :ar_variations :variations
53
+ #def variations
54
+ #v = ar_variations
55
+ #return v unless v.empty?
56
+ #return v if self.category.nil?
57
+ #if self.category.variations.empty?
53
58
  # return the products variations
54
- return v
55
- else
59
+ #return v
60
+ #else
56
61
  # return a frozen copy of the cateogires variations
57
- return Array.new(self.category.variations).freeze
58
- end
59
- end
62
+ #return Array.new(self.category.variations).freeze
63
+ #end
64
+ #end
60
65
 
61
66
  # Serious Ruby hacking going on here. We alias the original method for the association as added by
62
67
  # ActiveRecord and then override it so we can return the categories treatments if they are present.
@@ -0,0 +1,5 @@
1
+ class ProductOptionType < ActiveRecord::Base
2
+ belongs_to :product
3
+ belongs_to :option_type
4
+ acts_as_list :scope => :product
5
+ end
@@ -1,5 +1,8 @@
1
1
  class Variation < ActiveRecord::Base
2
- has_one :sku
3
- belongs_to :variable, :polymorphic => true
4
- validates_presence_of :name
2
+ belongs_to :product
3
+ has_and_belongs_to_many :option_values
4
+ validates_presence_of :product
5
+ #has_one :sku
6
+ #belongs_to :variable, :polymorphic => true
7
+ #validates_presence_of :name
5
8
  end
@@ -0,0 +1,16 @@
1
+ <!--[form:option]-->
2
+ <p>
3
+ <%=error_message_on :option_type, :name%>
4
+ Name: <%= text_field 'option_type', 'name' -%>
5
+ </p>
6
+ <p>
7
+ Presentation: <%= text_field 'option_type', 'presentation' -%>
8
+ </p>
9
+
10
+ <br/>
11
+ <div id="option-value-listing">
12
+ <%= render :partial => 'option_values', :locals => {:option_type => @option_type} -%>
13
+ </div>
14
+ <br/>
15
+
16
+ <!--[eoform:option]-->
@@ -0,0 +1,13 @@
1
+ <h3>New Option Value</h3>
2
+ <% fields_for :option_value, @option_value do |ov| %>
3
+ <table class="basic-table">
4
+ <tr>
5
+ <td>Name</td>
6
+ <td><%= ov.text_field :name %></td>
7
+ </tr>
8
+ <tr>
9
+ <td>Display</td>
10
+ <td><%= ov.text_field :presentation %></td>
11
+ </tr>
12
+ </table>
13
+ <% end %>