caboose-cms 0.8.24 → 0.8.25

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.
@@ -0,0 +1,84 @@
1
+ module Caboose
2
+ class VariantChildrenController < Caboose::ApplicationController
3
+
4
+ #=============================================================================
5
+ # Admin actions
6
+ #=============================================================================
7
+
8
+ # @route GET /admin/products/:product_id/variants/:variant_id/children/json
9
+ def admin_json
10
+ return if !user_is_allowed('products', 'view')
11
+
12
+ pager = Caboose::PageBarGenerator.new(params, {
13
+ 'parent_id' => params[:variant_id]
14
+ }, {
15
+ 'model' => 'Caboose::VariantChild',
16
+ 'sort' => 'parent_id',
17
+ 'desc' => false,
18
+ 'base_url' => "/admin/products/#{params[:product_id]}/variants/#{params[:variant_id]}/children",
19
+ 'items_per_page' => 100,
20
+ 'use_url_params' => false
21
+ })
22
+ render :json => {
23
+ :pager => pager,
24
+ :models => pager.items.as_json(:include => { :variant => { :methods => :full_title }})
25
+ }
26
+ end
27
+
28
+ # @route GET /admin/products/:product_id/variants/:variant_id/children/:id/json
29
+ def admin_json_single
30
+ return if !user_is_allowed('products', 'view')
31
+
32
+ vc = VariantChild.find(params[:id])
33
+ render :json => vc.as_json(:include => { :variant => { :methods => :full_title }})
34
+ end
35
+
36
+ # @route POST /admin/products/:product_id/variants/:parent_id/children
37
+ def admin_add
38
+ resp = Caboose::StdClass.new
39
+
40
+ if params[:parent_id] == params[:variant_id]
41
+ resp.error = "Can't add the same variant as a child."
42
+ else
43
+ vc = VariantChild.create(
44
+ :parent_id => params[:parent_id],
45
+ :variant_id => params[:variant_id],
46
+ :quantity => params[:quantity] ? params[:quantity] : 1
47
+ )
48
+ resp.new_id = vc.id
49
+ resp.success = true
50
+ end
51
+ render :json => resp
52
+ end
53
+
54
+ # @route PUT /admin/products/:product_id/variants/:parent_variant_id/children/:id
55
+ def admin_update
56
+ return if !user_is_allowed('variants', 'edit')
57
+
58
+ resp = Caboose::StdClass.new
59
+ vcs = params[:id] == 'bulk' ? params[:model_ids].collect{ |model_id| VariantChild.find(model_id) } : [VariantChild.find(params[:id])]
60
+
61
+ params.each do |name,value|
62
+ case name
63
+ when 'parent_id' then vcs.each{ |vc| vc.parent_id = value }
64
+ when 'variant_id' then vcs.each{ |vc| vc.variant_id = value }
65
+ when 'quantity' then vcs.each{ |vc| vc.quantity = value }
66
+ end
67
+ end
68
+ vcs.each{ |vc| vc.save }
69
+ resp.success = true
70
+ render :json => resp
71
+ end
72
+
73
+ # @route DELETE /admin/products/:product_id/variants/:variant_id/children/:id
74
+ def admin_delete
75
+ return if !user_is_allowed('variants', 'delete')
76
+ vc_ids = params[:id] == 'bulk' ? params[:model_ids] : [params[:id]]
77
+ vc_ids.each do |vc_id|
78
+ VariantChild.where(:id => vc_id).destroy_all
79
+ end
80
+ render :json => { :success => true }
81
+ end
82
+
83
+ end
84
+ end
@@ -75,7 +75,7 @@ module Caboose
75
75
  v = Variant.find(params[:id])
76
76
  render :json => v
77
77
  end
78
-
78
+
79
79
  # @route GET /admin/products/:product_id/variants/:id/download-url
80
80
  def admin_download_url
81
81
  return if !user_is_allowed('variants', 'edit')
@@ -148,7 +148,7 @@ module Caboose
148
148
  @product = @variant.product
149
149
  render :layout => 'caboose/admin'
150
150
  end
151
-
151
+
152
152
  # @route PUT /admin/products/:product_id/variants/:id/attach-to-image
153
153
  def admin_attach_to_image
154
154
  render :json => false if !user_is_allowed('variants', 'edit')
@@ -353,6 +353,7 @@ module Caboose
353
353
  when 'option3' then v.option3 = value
354
354
  when 'requires_shipping' then v.requires_shipping = value
355
355
  when 'taxable' then v.taxable = value
356
+ when 'is_bundle' then v.is_bundle = value
356
357
  when 'flat_rate_shipping' then v.flat_rate_shipping = value
357
358
  when 'flat_rate_shipping_single' then v.flat_rate_shipping_single = value
358
359
  when 'flat_rate_shipping_combined' then v.flat_rate_shipping_combined = value
@@ -376,6 +377,7 @@ module Caboose
376
377
  v.date_sale_ends = ModelBinder.local_datetime_to_utc(value, @logged_in_user.timezone)
377
378
  v.product.delay(:run_at => v.date_sale_ends , :queue => 'caboose_store').update_on_sale
378
379
  v.product.delay(:run_at => 3.seconds.from_now, :queue => 'caboose_store').update_on_sale
380
+
379
381
  end
380
382
  end
381
383
  resp.success = save && v.save
@@ -427,6 +429,9 @@ module Caboose
427
429
  resp = Caboose::StdClass.new
428
430
  p = Caboose::Product.find(params[:product_id])
429
431
 
432
+ pd = @site.product_default
433
+ vd = @site.variant_default
434
+
430
435
  v = Caboose::Variant.where(:alternate_id => params[:alternate_id]).first
431
436
  v = Caboose::Variant.new(:product_id => p.id) if v.nil?
432
437
 
@@ -434,10 +439,26 @@ module Caboose
434
439
  v.alternate_id = params[:alternate_id].strip
435
440
  v.quantity_in_stock = params[:quantity_in_stock].strip.to_i
436
441
  v.price = '%.2f' % params[:price].strip.to_f
437
- v.option1 = params[:option1] if p.option1
438
- v.option2 = params[:option2] if p.option2
439
- v.option3 = params[:option3] if p.option3
440
- v.status = 'Active'
442
+ v.option1 = params[:option1] if p.option1
443
+ v.option2 = params[:option2] if p.option2
444
+ v.option3 = params[:option3] if p.option3
445
+
446
+ v.cost = vd.cost
447
+ v.available = vd.available
448
+ v.ignore_quantity = vd.ignore_quantity
449
+ v.allow_backorder = vd.allow_backorder
450
+ v.weight = vd.weight
451
+ v.length = vd.length
452
+ v.width = vd.width
453
+ v.height = vd.height
454
+ v.volume = vd.volume
455
+ v.cylinder = vd.cylinder
456
+ v.requires_shipping = vd.requires_shipping
457
+ v.taxable = vd.taxable
458
+ v.status = vd.status
459
+ v.downloadable = vd.downloadable
460
+ v.is_bundle = vd.is_bundle
461
+
441
462
  v.save
442
463
 
443
464
  resp.success = true
@@ -0,0 +1,25 @@
1
+ #
2
+ # ProductDefault
3
+ #
4
+ # :: Class Methods
5
+ # :: Instance Methods
6
+
7
+ module Caboose
8
+ class ProductDefault < ActiveRecord::Base
9
+ self.table_name = 'store_product_defaults'
10
+
11
+ belongs_to :site
12
+ belongs_to :vendor
13
+ attr_accessible :id ,
14
+ :site_id ,
15
+ :vendor_id ,
16
+ :option1 ,
17
+ :option2 ,
18
+ :option3 ,
19
+ :status ,
20
+ :on_sale ,
21
+ :allow_gift_wrap ,
22
+ :gift_wrap_price
23
+
24
+ end
25
+ end
@@ -604,7 +604,18 @@ class Caboose::Schema < Caboose::Utilities::Schema
604
604
  [ :allow_gift_wrap , :boolean , { :default => false }],
605
605
  [ :gift_wrap_price , :decimal , { :precision => 8, :scale => 2 }],
606
606
  [ :media_category_id , :integer ]
607
- ],
607
+ ],
608
+ Caboose::ProductDefault => [
609
+ [ :site_id , :integer ],
610
+ [ :vendor_id , :integer ],
611
+ [ :option1 , :string ],
612
+ [ :option2 , :string ],
613
+ [ :option3 , :string ],
614
+ [ :status , :string ],
615
+ [ :on_sale , :boolean , { :default => false }],
616
+ [ :allow_gift_wrap , :boolean , { :default => false }],
617
+ [ :gift_wrap_price , :decimal , { :precision => 8, :scale => 2 }]
618
+ ],
608
619
  Caboose::ProductImage => [
609
620
  [ :product_id , :integer ],
610
621
  [ :alternate_id , :string ],
@@ -802,7 +813,10 @@ class Caboose::Schema < Caboose::Utilities::Schema
802
813
  [ :weight_unit , :string , { :default => 'oz' }],
803
814
  [ :download_url_expires_in , :string , { :default => 5 }],
804
815
  [ :starting_invoice_number , :integer , { :default => 1000 }],
805
- [ :default_payment_terms , :string , { :default => 'pia' }]
816
+ [ :default_payment_terms , :string , { :default => 'pia' }],
817
+ [ :default_vendor_id , :integer ],
818
+ [ :default_product_status , :string ],
819
+ [ :default_taxable , :boolean ]
806
820
  ],
807
821
  Caboose::Subscription => [
808
822
  [ :site_id , :integer ],
@@ -900,7 +914,39 @@ class Caboose::Schema < Caboose::Utilities::Schema
900
914
  [ :option3_sort_order , :integer , { :default => 0 }],
901
915
  [ :sort_order , :integer , { :default => 0 }],
902
916
  [ :downloadable , :boolean , { :default => false }],
903
- [ :download_path , :string ]
917
+ [ :download_path , :string ],
918
+ [ :is_bundle , :boolean , { :default => false }]
919
+ ],
920
+ Caboose::VariantChild => [
921
+ [ :parent_id , :integer ],
922
+ [ :variant_id , :integer ],
923
+ [ :quantity , :integer ]
924
+ ],
925
+ Caboose::VariantDefault => [
926
+ [ :site_id , :integer ],
927
+ [ :cost , :decimal , { :precision => 8, :scale => 2, :default => 0.00 }],
928
+ [ :price , :decimal , { :precision => 8, :scale => 2, :default => 0.00 }],
929
+ [ :available , :boolean , { :default => true }],
930
+ [ :quantity_in_stock , :integer , { :default => 0 }],
931
+ [ :ignore_quantity , :boolean , { :default => false }],
932
+ [ :allow_backorder , :boolean , { :default => false }],
933
+ [ :weight , :decimal ],
934
+ [ :length , :decimal ],
935
+ [ :width , :decimal ],
936
+ [ :height , :decimal ],
937
+ [ :volume , :decimal ],
938
+ [ :cylinder , :boolean , { :default => false }],
939
+ [ :requires_shipping , :boolean , { :default => true }],
940
+ [ :taxable , :boolean , { :default => true }],
941
+ [ :shipping_unit_value , :numeric ],
942
+ [ :flat_rate_shipping , :boolean , { :default => false }],
943
+ [ :flat_rate_shipping_package_id , :integer ],
944
+ [ :flat_rate_shipping_method_id , :integer ],
945
+ [ :flat_rate_shipping_single , :decimal , { :precision => 8, :scale => 2, :default => 0.0 }],
946
+ [ :flat_rate_shipping_combined , :decimal , { :precision => 8, :scale => 2, :default => 0.0 }],
947
+ [ :status , :string ],
948
+ [ :downloadable , :boolean , { :default => false }],
949
+ [ :is_bundle , :boolean , { :default => false }]
904
950
  ],
905
951
  Caboose::Vendor => [
906
952
  [ :site_id , :integer ],
@@ -44,6 +44,18 @@ class Caboose::Site < ActiveRecord::Base
44
44
  return c
45
45
  end
46
46
 
47
+ def product_default
48
+ pd = Caboose::ProductDefault.where(:site_id => self.id).first
49
+ pd = Caboose::ProductDefault.create(:site_id => self.id) if pd.nil?
50
+ return pd
51
+ end
52
+
53
+ def variant_default
54
+ vd = Caboose::VariantDefault.where(:site_id => self.id).first
55
+ vd = Caboose::VariantDefault.create(:site_id => self.id) if vd.nil?
56
+ return vd
57
+ end
58
+
47
59
  def self.id_for_domain(domain)
48
60
  d = Caboose::Domain.where(:domain => domain).first
49
61
  return nil if d.nil?
@@ -75,9 +75,10 @@ class Caboose::Utilities::Schema
75
75
  end
76
76
 
77
77
  # Column exists, but not with the correct data type, try to change it
78
- else
79
- c.execute("alter table #{tbl} alter column #{col[0]} type #{col[1]} using cast(#{col[0]} as #{col[1]})")
80
-
78
+ else
79
+ dct = col[1] == 'string' || col[1] == :string ? 'text' : col[1]
80
+ c.execute("alter table #{tbl} alter column #{col[0]} type #{dct} using cast(#{col[0]} as #{dct})")
81
+
81
82
  end
82
83
  if col[0].to_s == model.primary_key
83
84
  c.execute("alter table #{tbl} add primary key (\"#{col[0].to_s}\")")
@@ -16,10 +16,12 @@ module Caboose
16
16
  belongs_to :option1_media, :class_name => 'Caboose::Media'
17
17
  belongs_to :option2_media, :class_name => 'Caboose::Media'
18
18
  belongs_to :option3_media, :class_name => 'Caboose::Media'
19
+ has_many :variant_childen, :class_name => 'Caboose::Variant'
19
20
 
20
21
  attr_accessible :id,
21
22
  :alternate_id,
22
23
  :product_id,
24
+ :sku,
23
25
  :barcode, # Returns the barcode value of the variant.
24
26
  :cost, # Cost of goods (don't show to customer)
25
27
  :price, # Variant’s price.
@@ -37,6 +39,7 @@ module Caboose
37
39
  :length, # Length of variant in inches
38
40
  :width, # Width of variant in inches
39
41
  :height, # Height of variant in inches
42
+ :volume,
40
43
  :option1, # Returns the value of option1 for given variant
41
44
  :option2, # If a product has a second option defined, then returns the value of this variant's option2.
42
45
  :option3, # If a product has a third option defined, then returns the value of this variant's option3.
@@ -45,10 +48,12 @@ module Caboose
45
48
  :option3_color,
46
49
  :option1_media_id,
47
50
  :option2_media_id,
48
- :option3_media_id,
51
+ :option3_media_id,
52
+ :option1_sort_order,
53
+ :option2_sort_order,
54
+ :option3_sort_order,
49
55
  :requires_shipping, # Returns true if the variant is shippable or false if it is a service or a digital good.
50
- :taxable, # Returns true if the variant is taxable or false if it is not.
51
- :sku,
56
+ :taxable, # Returns true if the variant is taxable or false if it is not.
52
57
  :available,
53
58
  :cylinder,
54
59
  :shipping_unit_value,
@@ -56,7 +61,11 @@ module Caboose
56
61
  :flat_rate_shipping_single,
57
62
  :flat_rate_shipping_combined,
58
63
  :flat_rate_shipping_method_id,
59
- :flat_rate_shipping_package_id
64
+ :flat_rate_shipping_package_id,
65
+ :sort_order,
66
+ :downloadable,
67
+ :download_path,
68
+ :is_bundle
60
69
 
61
70
  after_initialize do |v|
62
71
  v.price = 0.00 if v.price.nil?
@@ -114,6 +123,11 @@ module Caboose
114
123
  return self.options.join(' / ')
115
124
  end
116
125
 
126
+ def full_title
127
+ return self.product.title if self.options.count == 0
128
+ return "#{self.product.title} - #{self.title}"
129
+ end
130
+
117
131
  def options
118
132
  arr = []
119
133
  arr << self.option1 if self.option1 && self.option1.strip.length > 0
@@ -0,0 +1,13 @@
1
+ module Caboose
2
+ class VariantChild < ActiveRecord::Base
3
+ self.table_name = 'store_variant_children'
4
+
5
+ belongs_to :parent, :class_name => 'Caboose::Variant'
6
+ belongs_to :variant, :class_name => 'Caboose::Variant'
7
+ attr_accessible :id,
8
+ :parent_id,
9
+ :variant_id,
10
+ :quantity
11
+
12
+ end
13
+ end
@@ -0,0 +1,39 @@
1
+ #
2
+ # VariantDefault
3
+ #
4
+ # :: Class Methods
5
+ # :: Instance Methods
6
+
7
+ module Caboose
8
+ class VariantDefault < ActiveRecord::Base
9
+ self.table_name = 'store_variant_defaults'
10
+
11
+ belongs_to :site
12
+ attr_accessible :id ,
13
+ :site_id ,
14
+ :cost ,
15
+ :price ,
16
+ :available ,
17
+ :quantity_in_stock ,
18
+ :ignore_quantity ,
19
+ :allow_backorder ,
20
+ :weight ,
21
+ :length ,
22
+ :width ,
23
+ :height ,
24
+ :volume ,
25
+ :cylinder ,
26
+ :requires_shipping ,
27
+ :taxable ,
28
+ :shipping_unit_value ,
29
+ :flat_rate_shipping ,
30
+ :flat_rate_shipping_package_id ,
31
+ :flat_rate_shipping_method_id ,
32
+ :flat_rate_shipping_single ,
33
+ :flat_rate_shipping_combined ,
34
+ :status ,
35
+ :downloadable ,
36
+ :is_bundle
37
+
38
+ end
39
+ end
@@ -13,11 +13,12 @@
13
13
  <%= javascript_include_tag "caboose/admin_products" %>
14
14
  <% end %>
15
15
 
16
+ <div id='crumbtrail'></div>
16
17
  <h1 id="product-title">Edit Product - <%= @product.title %></h1>
17
18
  <ul id='tabs'>
18
19
  <%
19
20
  tabs = {
20
- "/admin/products/#{@product.id}/general" => 'Product details',
21
+ "/admin/products/#{@product.id}" => 'Product details',
21
22
  "/admin/products/#{@product.id}/description" => 'Long Description',
22
23
  "/admin/products/#{@product.id}/categories" => 'Categories'
23
24
  }
@@ -32,7 +33,8 @@ tabs["/admin/products/#{@product.id}/delete" ] = 'Delete Product'
32
33
 
33
34
  %>
34
35
  <% tabs.each do |href,text| %>
35
- <li<%= raw request.fullpath == href ? " class='selected'" : '' %>><a href='<%= href %>'><%= raw text %></a></li>
36
+ <% selected = href == "/admin/products/#{@product.id}" ? request.fullpath == href : request.fullpath.starts_with?(href) %>
37
+ <li<%= raw selected ? " class='selected'" : '' %>><a href='<%= href %>'><%= raw text %></a></li>
36
38
  <% end %>
37
39
  <li class='back'><input type='button' class="caboose-btn" value='< Back' onclick="window.location='/admin/products';" /></li>
38
40
  </ul>
@@ -19,6 +19,12 @@ label span.prefix { display: inline-block; margin: 0 8px; }
19
19
 
20
20
  var mb = false;
21
21
  $(document).ready(function() {
22
+
23
+ add_to_crumbtrail('/admin', 'Admin');
24
+ add_to_crumbtrail('/admin/products', 'Products');
25
+ add_to_crumbtrail('/admin/products/<%= p.id %>', <%= raw Caboose.json(p.title) %>);
26
+ add_to_crumbtrail('/admin/products/<%= p.id %>/categories', 'Categories');
27
+
22
28
  mb = new ModelBinder({
23
29
  name: 'Product',
24
30
  id: <%= p.id %>,
@@ -12,6 +12,12 @@ p = @product
12
12
  <script type='text/javascript'>
13
13
 
14
14
  $(document).ready(function() {
15
+
16
+ add_to_crumbtrail('/admin', 'Admin');
17
+ add_to_crumbtrail('/admin/products', 'Products');
18
+ add_to_crumbtrail('/admin/products/<%= p.id %>', <%= raw Caboose.json(p.title) %>);
19
+ add_to_crumbtrail('/admin/products/<%= p.id %>/description', 'Description');
20
+
15
21
  m = new ModelBinder({
16
22
  name: 'Product',
17
23
  id: <%= p.id %>,