caboose-cms 0.5.119 → 0.5.120

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YWM0NzQ5Njc3NjBlOTNmMDBhZjViMTA1Y2MyZDM0OTk3Mjg0ZGQ2NQ==
4
+ ZmU1MjAyN2Y0NGRhODA2ZTcyYTg2ZjBmYWY1NjkzOGVhNmFhNTQxYQ==
5
5
  data.tar.gz: !binary |-
6
- Y2QxMzJkOWEzYzg0ZWFkYzVkNTc5MjhmYTdjZGRjOGQ1NmQxMWYxYw==
6
+ NTdkNTllYzUzNGQxZTg2YTE0N2FjYzI1Y2UxYWE2MzM4YmRkZjgxMQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NWEwYjFjM2JjNWU3MjUyNTUzZDkxZjNiMTczMmMxZmJiZTFiZjhjNGYzNjk4
10
- Yzk5M2ZjNGFkYjZhOGYwZjYzNzUxZjVhMDE4MDM3YTFlODBhOTVmNWM1YmFm
11
- N2JkNWJlNWE2NmJjYzhkYjE1YjkyMmU2NGNlOGNhZDhjNDU0MDM=
9
+ MzQ1M2ZiNjQwNzljNDlkYmU1MjFiYjAwN2M0NmQ2MWY0ODdlOGY5Nzc5ZWI1
10
+ MjA1ZmMzNGZiZGFkNjQ1ZDY3ZWJjZDdhYmU0NzQyZjk2NDJmNmE5MTQ5M2M3
11
+ NDFiZjE3NGQ5Njk0NThhOWQwODgzYjliMzg3ZDYzMjU2OTZjOTQ=
12
12
  data.tar.gz: !binary |-
13
- YTQ4ZGNjNTEzM2QwN2MyZmQ5MGQ2MTFkNTc4ODllNzc5MzdhYzVjNjliNWQw
14
- NDU2N2VjYWYzNDE0NWM1NTI4NjRkMGU4Nzk5YjM4YjY4YzZjYjk5YjdlZDVm
15
- Y2U5N2M3OGUyYWM4NGZlYTI0MDJmOTM2ZGEwYjI5ZTRlMjljM2U=
13
+ ZTU3ZWM0OTMxNzE1YWFjZmEzNzkyZDI5MmFlNDE5NmI5MmYyNjhjZjAyYzYx
14
+ ZGFkODIyYjZhNDA2MmE3Y2M1ZTQ2NTY3NTA2YTQyNTg2ODEzNzdkZTE4MjA0
15
+ MzUxNWMwNzlkMGFkMTNiZGQ0ZWVjZjlhMjQ3MmJkYjQwMzA0NTA=
@@ -89,7 +89,12 @@ function relay_handler(resp)
89
89
  console.log('RELAY');
90
90
  console.log(resp);
91
91
  if (resp.success == true)
92
- window.location = '/checkout/thanks';
92
+ {
93
+ if (resp.redirect)
94
+ window.location = resp.redirect;
95
+ else
96
+ window.location = '/checkout/thanks';
97
+ }
93
98
  else if (resp.error)
94
99
  $('#message').html("<p class='note error'>" + resp.error + "</p>");
95
100
  else
@@ -72,10 +72,11 @@ body {
72
72
  #content h1 {
73
73
  margin: 0 0 20px -30px;
74
74
  padding: 40px 0 0 30px;
75
- height: 80px;
75
+ height: 80px;
76
76
  background: #e1e1e1;
77
77
  border-bottom: #aaa 1px solid;
78
78
  font-size: 36pt;
79
+ overflow: hidden;
79
80
  }
80
81
 
81
82
  #content h1.model_attribute_h1 {
@@ -36,6 +36,11 @@ module Caboose
36
36
  redirect_to '/checkout' and return if !logged_in?
37
37
  redirect_to '/checkout/addresses' and return if @order.shipping_address.nil? || @order.billing_address.nil?
38
38
 
39
+ if !@order.has_shippable_items?
40
+ redirect_to '/checkout/gift-cards'
41
+ return
42
+ end
43
+
39
44
  # Remove any order packages
40
45
  LineItem.where(:order_id => @order.id).update_all(:order_package_id => nil)
41
46
  OrderPackage.where(:order_id => @order.id).destroy_all
@@ -44,7 +49,8 @@ module Caboose
44
49
  OrderPackage.create_for_order(@order)
45
50
 
46
51
  # Now get the rates for those packages
47
- @rates = ShippingCalculator.rates(@order)
52
+ @rates = ShippingCalculator.rates(@order)
53
+
48
54
  #Caboose.log(@rates.inspect)
49
55
  @logged_in_user = logged_in_user
50
56
  end
@@ -54,7 +60,7 @@ module Caboose
54
60
  def gift_cards
55
61
  redirect_to '/checkout' and return if !logged_in?
56
62
  redirect_to '/checkout/addresses' and return if @order.shipping_address.nil? || @order.billing_address.nil?
57
- redirect_to '/checkout/shipping' and return if @order.has_empty_shipping_methods?
63
+ redirect_to '/checkout/shipping' and return if @order.has_shippable_items? && @order.has_empty_shipping_methods?
58
64
  @logged_in_user = logged_in_user
59
65
  end
60
66
 
@@ -63,7 +69,7 @@ module Caboose
63
69
  def payment
64
70
  redirect_to '/checkout' and return if !logged_in?
65
71
  redirect_to '/checkout/addresses' and return if @order.shipping_address.nil? || @order.billing_address.nil?
66
- redirect_to '/checkout/shipping' and return if @order.has_empty_shipping_methods?
72
+ redirect_to '/checkout/shipping' and return if @order.has_shippable_items? && @order.has_empty_shipping_methods?
67
73
 
68
74
  # Make sure all the variants still exist
69
75
  @order.line_items.each do |li|
@@ -102,6 +108,10 @@ module Caboose
102
108
  # GET /checkout/thanks
103
109
  def thanks
104
110
  @logged_in_user = logged_in_user
111
+
112
+ # Find the last order for the user
113
+ @last_order = Order.where(:customer_id => @logged_in_user.id).order("id desc").limit(1).first
114
+
105
115
  end
106
116
 
107
117
  #===========================================================================
@@ -120,19 +130,23 @@ module Caboose
120
130
  # Grab or create addresses
121
131
  shipping_address = if @order.shipping_address then @order.shipping_address else Address.new end
122
132
  billing_address = if @order.billing_address then @order.billing_address else Address.new end
123
-
133
+
134
+ has_shippable_items = @order.has_shippable_items?
135
+
124
136
  # Shipping address
125
- shipping_address.first_name = params[:shipping][:first_name]
126
- shipping_address.last_name = params[:shipping][:last_name]
127
- shipping_address.company = params[:shipping][:company]
128
- shipping_address.address1 = params[:shipping][:address1]
129
- shipping_address.address2 = params[:shipping][:address2]
130
- shipping_address.city = params[:shipping][:city]
131
- shipping_address.state = params[:shipping][:state]
132
- shipping_address.zip = params[:shipping][:zip]
137
+ if has_shippable_items
138
+ shipping_address.first_name = params[:shipping][:first_name]
139
+ shipping_address.last_name = params[:shipping][:last_name]
140
+ shipping_address.company = params[:shipping][:company]
141
+ shipping_address.address1 = params[:shipping][:address1]
142
+ shipping_address.address2 = params[:shipping][:address2]
143
+ shipping_address.city = params[:shipping][:city]
144
+ shipping_address.state = params[:shipping][:state]
145
+ shipping_address.zip = params[:shipping][:zip]
146
+ end
133
147
 
134
148
  # Billing address
135
- if params[:use_as_billing]
149
+ if has_shippable_items && params[:use_as_billing]
136
150
  billing_address.update_attributes(shipping_address.attributes)
137
151
  else
138
152
  billing_address.first_name = params[:billing][:first_name]
@@ -146,7 +160,7 @@ module Caboose
146
160
  end
147
161
 
148
162
  # Save address info; generate ids
149
- render :json => { :success => false, :errors => shipping_address.errors.full_messages, :address => 'shipping' } and return if !shipping_address.save
163
+ render :json => { :success => false, :errors => shipping_address.errors.full_messages, :address => 'shipping' } and return if has_shippable_items && !shipping_address.save
150
164
  render :json => { :success => false, :errors => billing_address.errors.full_messages, :address => 'billing' } and return if !billing_address.save
151
165
 
152
166
  # Associate address info with order
@@ -0,0 +1,56 @@
1
+ module Caboose
2
+ class MyAccountLineItemsController < Caboose::ApplicationController
3
+
4
+ # GET /my-account/orders/:order_id/line-items
5
+ def index
6
+ return if !logged_in?
7
+ @order = Order.find(params[:order_id])
8
+ if @order.customer_id != logged_in_user.id
9
+ @error = "The given order does not belong to you."
10
+ render :file => 'caboose/extras/error'
11
+ return
12
+ end
13
+ end
14
+
15
+ # GET /my-account/orders/:order_id/line-items/:id
16
+ def edit
17
+ return if !logged_in?
18
+
19
+ @order = Order.find(params[:order_id])
20
+ @line_item = LineItem.find(params[:id])
21
+ if @order.customer_id != logged_in_user.id
22
+ @error = "The given order does not belong to you."
23
+ render :file => 'caboose/extras/error'
24
+ return
25
+ end
26
+ end
27
+
28
+ # GET /my-account/orders/:order_id/line-items/:id/download
29
+ def download
30
+ return if !logged_in?
31
+
32
+ order = Order.find(params[:order_id])
33
+ if order.customer_id != logged_in_user.id
34
+ @error = "The given order does not belong to you."
35
+ render :file => 'caboose/extras/error'
36
+ return
37
+ end
38
+
39
+ li = LineItem.find(params[:id])
40
+ if !li.variant.downloadable
41
+ render :text => "Not a downloadable file."
42
+ return
43
+ end
44
+
45
+ # Generate the download URL and redirect to it
46
+ sc = @site.store_config
47
+ config = YAML.load_file("#{::Rails.root}/config/aws.yml")
48
+ bucket = AWS::S3::Bucket.new(config[Rails.env]['bucket'])
49
+ s3object = AWS::S3::S3Object.new(bucket, li.variant.download_path)
50
+ url = s3object.url_for(:read, :expires => sc.download_url_expires_in.minutes).to_s
51
+
52
+ redirect_to url
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,35 @@
1
+ module Caboose
2
+ class MyAccountOrdersController < Caboose::ApplicationController
3
+
4
+ # GET /my-account/orders
5
+ def index
6
+ return if !logged_in?
7
+
8
+ @pager = Caboose::PageBarGenerator.new(params, {
9
+ 'customer_id' => @logged_in_user_id.id,
10
+ 'status' => '',
11
+ 'id' => ''
12
+ }, {
13
+ 'model' => 'Caboose::Order',
14
+ 'sort' => 'id',
15
+ 'desc' => 1,
16
+ 'base_url' => '/my-account/orders',
17
+ 'use_url_params' => false
18
+ })
19
+ @orders = @pager.items
20
+ end
21
+
22
+ # GET /my-account/orders/:id
23
+ def edit
24
+ return if !logged_in?
25
+
26
+ @order = Order.find(params[:id])
27
+ if @order.customer_id != logged_in_user.id
28
+ @error = "The given order does not belong to you."
29
+ render :file => 'caboose/extras/error'
30
+ return
31
+ end
32
+ end
33
+
34
+ end
35
+ end
@@ -49,7 +49,8 @@ module Caboose
49
49
  when 'calculate_packages' then sc.calculate_packages = value
50
50
  when 'shipping_rates_function' then sc.shipping_rates_function = value
51
51
  when 'length_unit' then sc.length_unit = value
52
- when 'weight_unit' then sc.weight_unit = value
52
+ when 'weight_unit' then sc.weight_unit = value
53
+ when 'download_url_expires_in' then sc.download_url_expires_in = value
53
54
  end
54
55
  end
55
56
 
@@ -68,6 +68,14 @@ module Caboose
68
68
  :models => pager.items
69
69
  }
70
70
  end
71
+
72
+ # GET /admin/products/:product_id/variants/:id/json
73
+ def admin_json_single
74
+ return if !user_is_allowed('products', 'view')
75
+
76
+ v = Variant.find(params[:id])
77
+ render :json => v
78
+ end
71
79
 
72
80
  # GET /admin/products/:product_id/variants/:variant_id
73
81
  def admin_edit
@@ -77,6 +85,27 @@ module Caboose
77
85
  render :layout => 'caboose/admin'
78
86
  end
79
87
 
88
+ # GET /admin/producst/:product_id/variants/:id/download-url
89
+ def admin_download_url
90
+ return if !user_is_allowed('variants', 'edit')
91
+
92
+ resp = StdClass.new
93
+ v = Variant.find(params[:id])
94
+ expires_in = params[:expires_in].to_i
95
+
96
+ if !v.downloadable
97
+ resp.error = "This variant is not downloadable."
98
+ else
99
+ config = YAML.load_file("#{::Rails.root}/config/aws.yml")
100
+ bucket = AWS::S3::Bucket.new(config[Rails.env]['bucket'])
101
+ s3object = AWS::S3::S3Object.new(bucket, v.download_path)
102
+ resp.url = s3object.url_for(:read, :expires => expires_in.minutes).to_s
103
+ resp.success = true
104
+ end
105
+
106
+ render :json => resp
107
+ end
108
+
80
109
  # PUT /admin/variants/:id
81
110
  def admin_update
82
111
  return if !user_is_allowed('variants', 'edit')
@@ -104,6 +133,8 @@ module Caboose
104
133
  when 'option3' then v.option3 = value
105
134
  when 'requires_shipping' then v.requires_shipping = value
106
135
  when 'taxable' then v.taxable = value
136
+ when 'downloadable' then v.downloadable = value
137
+ when 'download_path' then v.download_path = value
107
138
  end
108
139
  end
109
140
  resp.success = save && v.save
@@ -319,10 +350,15 @@ module Caboose
319
350
  end
320
351
 
321
352
  if resp.error.nil?
322
- CSV.parse(params[:csv_data]).each do |row|
323
- v = Caboose::Variant.where(:alternate_id => row[0]).first
324
- v = Caboose::Variant.new(:product_id => p.id) if v.nil?
325
-
353
+ CSV.parse(params[:csv_data]).each do |row|
354
+ v = nil
355
+ if row[0].strip.length == 0
356
+ v = Caboose::Variant.new(:product_id => p.id)
357
+ else
358
+ v = Caboose::Variant.where(:alternate_id => row[0]).first
359
+ v = Caboose::Variant.new(:product_id => p.id) if v.nil?
360
+ end
361
+
326
362
  v.product_id = p.id
327
363
  v.alternate_id = row[0].strip
328
364
  v.quantity_in_stock = row[1].strip.to_i
@@ -365,7 +401,9 @@ module Caboose
365
401
  when 'option2' then variants.each { |v| v.option2 = value }
366
402
  when 'option3' then variants.each { |v| v.option3 = value }
367
403
  when 'requires_shipping' then variants.each { |v| v.requires_shipping = value }
368
- when 'taxable' then variants.each { |v| v.taxable = value }
404
+ when 'taxable' then variants.each { |v| v.taxable = value }
405
+ when 'downloadable' then variants.each { |v| v.downloadable = value }
406
+ when 'download_path' then variants.each { |v| v.download_path = value }
369
407
  end
370
408
  end
371
409
  variants.each{ |v| v.save }
@@ -205,6 +205,20 @@ module Caboose
205
205
  return false
206
206
  end
207
207
 
208
+ def has_downloadable_items?
209
+ self.line_items.each do |li|
210
+ return true if li.variant.downloadable
211
+ end
212
+ return false
213
+ end
214
+
215
+ def has_shippable_items?
216
+ self.line_items.each do |li|
217
+ return true if !li.variant.downloadable
218
+ end
219
+ return false
220
+ end
221
+
208
222
  end
209
223
  end
210
224
 
@@ -617,7 +617,8 @@ class Caboose::Schema < Caboose::Utilities::Schema
617
617
  [ :order_packages_function , :text ],
618
618
  [ :shipping_rates_function , :text ],
619
619
  [ :length_unit , :string , { :default => 'in' }],
620
- [ :weight_unit , :string , { :default => 'oz' }]
620
+ [ :weight_unit , :string , { :default => 'oz' }],
621
+ [ :download_url_expires_in , :string , { :default => 5 }]
621
622
  ],
622
623
  Caboose::User => [
623
624
  [ :site_id , :integer ],
@@ -672,7 +673,9 @@ class Caboose::Schema < Caboose::Utilities::Schema
672
673
  [ :option1_sort_order , :integer , { :default => 0 }],
673
674
  [ :option2_sort_order , :integer , { :default => 0 }],
674
675
  [ :option3_sort_order , :integer , { :default => 0 }],
675
- [ :sort_order , :integer , { :default => 0 }]
676
+ [ :sort_order , :integer , { :default => 0 }],
677
+ [ :downloadable , :boolean , { :default => false }],
678
+ [ :download_path , :string ]
676
679
  ],
677
680
  Caboose::Vendor => [
678
681
  [ :site_id , :integer ],
@@ -30,9 +30,9 @@ module Caboose
30
30
  :postal_code => order.shipping_address.zip
31
31
  )
32
32
  carriers = {}
33
- carriers['UPS'] = UPS.new( :login => sc.ups_username, :password => sc.ups_password, :key => sc.ups_key, :origin_account => sc.ups_origin_account) if sc.ups_username.strip.length > 0
34
- carriers['USPS'] = USPS.new( :login => sc.usps_username) if sc.usps_username.strip.length > 0
35
- carriers['FedEx'] = FedEx.new(:login => sc.fedex_username, :password => sc.fedex_password, :key => sc.fedex_key, :account => sc.fedex_account) if sc.fedex_username.strip.length > 0
33
+ carriers['UPS'] = UPS.new( :login => sc.ups_username, :password => sc.ups_password, :key => sc.ups_key, :origin_account => sc.ups_origin_account) if sc.ups_username && sc.ups_username.strip.length > 0
34
+ carriers['USPS'] = USPS.new( :login => sc.usps_username) if sc.usps_username && sc.usps_username.strip.length > 0
35
+ carriers['FedEx'] = FedEx.new(:login => sc.fedex_username, :password => sc.fedex_password, :key => sc.fedex_key, :account => sc.fedex_account) if sc.fedex_username && sc.fedex_username.strip.length > 0
36
36
 
37
37
  all_rates = []
38
38
  order.packages.each do |op|
@@ -17,21 +17,23 @@ end
17
17
  <% else %>
18
18
  <form action="/checkout/addresses" method="put" id='address_form'>
19
19
  <section id="checkout-address">
20
- <div class="wrapper">
21
- <section>
22
- <fieldset id="shipping">
23
- <h3>Shipping Address</h3>
24
- <label><span>First Name </span> <input name="shipping[first_name]" type="text" value="<%= sa ? sa.first_name : "" %>" /></label>
25
- <label><span>Last Name </span> <input name="shipping[last_name]" type="text" value="<%= sa ? sa.last_name : "" %>" /></label>
26
- <label><span>Company </span> <input name="shipping[company]" type="text" value="<%= sa ? sa.company : "" %>" /></label>
27
- <label><span>Address 1 </span> <input name="shipping[address1]" type="text" value="<%= sa ? sa.address1 : "" %>" /></label>
28
- <label><span>Address 2 </span> <input name="shipping[address2]" type="text" value="<%= sa ? sa.address2 : "" %>" /></label>
29
- <label><span>City </span> <input name="shipping[city]" type="text" value="<%= sa ? sa.city : "" %>" /></label>
30
- <label><span>State </span> <select name="shipping[state]"><% Caboose::States.all.each do |abbr, state| %><option value="<%= abbr %>" <%= sa && sa.state == abbr ? 'selected' : "" %>><%= state %></option><% end %></select></label>
31
- <label><span>Zip </span> <input name="shipping[zip]" type="text" value="<%= sa ? sa.zip : "" %>" /></label>
32
- <label><input name="use_as_billing" type="checkbox" value="false" /> Use as billing address</label>
33
- </fieldset>
34
- </section>
20
+ <div class="wrapper">
21
+ <% if @order.has_shippable_items? %>
22
+ <section>
23
+ <fieldset id="shipping">
24
+ <h3>Shipping Address</h3>
25
+ <label><span>First Name </span> <input name="shipping[first_name]" type="text" value="<%= sa ? sa.first_name : "" %>" /></label>
26
+ <label><span>Last Name </span> <input name="shipping[last_name]" type="text" value="<%= sa ? sa.last_name : "" %>" /></label>
27
+ <label><span>Company </span> <input name="shipping[company]" type="text" value="<%= sa ? sa.company : "" %>" /></label>
28
+ <label><span>Address 1 </span> <input name="shipping[address1]" type="text" value="<%= sa ? sa.address1 : "" %>" /></label>
29
+ <label><span>Address 2 </span> <input name="shipping[address2]" type="text" value="<%= sa ? sa.address2 : "" %>" /></label>
30
+ <label><span>City </span> <input name="shipping[city]" type="text" value="<%= sa ? sa.city : "" %>" /></label>
31
+ <label><span>State </span> <select name="shipping[state]"><% Caboose::States.all.each do |abbr, state| %><option value="<%= abbr %>" <%= sa && sa.state == abbr ? 'selected' : "" %>><%= state %></option><% end %></select></label>
32
+ <label><span>Zip </span> <input name="shipping[zip]" type="text" value="<%= sa ? sa.zip : "" %>" /></label>
33
+ <label><input name="use_as_billing" type="checkbox" value="false" /> Use as billing address</label>
34
+ </fieldset>
35
+ </section>
36
+ <% end %>
35
37
  <section>
36
38
  <fieldset id="billing">
37
39
  <h3>Billing Address</h3>
@@ -65,17 +65,19 @@ store_config = @site.store_config
65
65
  <% end %>
66
66
  </section>
67
67
  <section id='checkout-confirm'>
68
- <section id='shipping_address'>
69
- <h3>Shipping Address</h3>
70
- <% sa = @order.shipping_address %>
71
- <address>
72
- <%= "#{sa.first_name} #{sa.last_name}" %><br />
73
- <%= sa.address1 %><br />
74
- <%= "#{sa.address2}<br />" if sa.address2 and not sa.address2.empty? %>
75
- <%= "#{sa.city}, #{sa.state} #{sa.zip}" %>
76
- </address>
77
- <p><a href="/checkout/addresses">Edit</a></p>
78
- </section>
68
+ <% if @order.has_shippable_items? %>
69
+ <section id='shipping_address'>
70
+ <h3>Shipping Address</h3>
71
+ <% sa = @order.shipping_address %>
72
+ <address>
73
+ <%= "#{sa.first_name} #{sa.last_name}" %><br />
74
+ <%= sa.address1 %><br />
75
+ <%= "#{sa.address2}<br />" if sa.address2 and not sa.address2.empty? %>
76
+ <%= "#{sa.city}, #{sa.state} #{sa.zip}" %>
77
+ </address>
78
+ <p><a href="/checkout/addresses">Edit</a></p>
79
+ </section>
80
+ <% end %>
79
81
  <section id='billing_address'>
80
82
  <h3>Billing Address</h3>
81
83
  <% ba = @order.billing_address %>
@@ -87,15 +89,17 @@ store_config = @site.store_config
87
89
  </address>
88
90
  <p><a href="/checkout/addresses">Edit</a></p>
89
91
  </section>
90
- <section id='shipping_method'>
91
- <h3>Shipping</h3>
92
- <% @order.order_packages.each do |op| %>
93
- <p><%= op.shipping_method.service_name %> - <%= number_to_currency(op.total) %></p>
94
- <% end %>
95
- <p><a href="/checkout/shipping">Edit</a></p>
96
- </section>
92
+ <% if @order.has_shippable_items? %>
93
+ <section id='shipping_method'>
94
+ <h3>Shipping</h3>
95
+ <% @order.order_packages.each do |op| %>
96
+ <p><%= op.shipping_method.service_name %> - <%= number_to_currency(op.total) %></p>
97
+ <% end %>
98
+ <p><a href="/checkout/shipping">Edit</a></p>
99
+ </section>
100
+ <% end %>
97
101
  <section id='payment_method'>
98
- <h3>Payment</h3>
102
+ <h3>Payment Method</h3>
99
103
  <div id='confirm_card'>
100
104
  <p id='confirm_card_number'></p>
101
105
  <p><a href="#" id='edit_payment'>Edit</a></p>
@@ -1,5 +1,16 @@
1
1
  <h3>All Finished!</h3>
2
2
  <p>Thank you for your order! Your order has been submitted.</p>
3
3
  <p>Please allow up to 48 hours for your order to be processed. Orders are processed during normal business hours Monday through Friday.</p>
4
- <p><a href="/">Continue Shopping</a></p>
5
4
 
5
+ <% if @last_order.has_downloadable_items? %>
6
+ <p>Your order contained downloadable items. Download your items with the links below:</p>
7
+ <ul>
8
+ <% @last_order.line_items.each do |li| %>
9
+ <% if li.variant.downloadable %>
10
+ <li><a href='/my-account/orders/<%= @last_order.id %>/line-items/<%= li.id %>/download' target="_blank"><%= li.variant.product.title %></a></li>
11
+ <% end %>
12
+ <% end %>
13
+ </ul>
14
+ <% end %>
15
+
16
+ <p><a href="/">Continue Shopping</a></p>
@@ -41,6 +41,7 @@ sc = @store_config
41
41
 
42
42
  <h2>Other</h2>
43
43
  <p><div id='storeconfig_<%= sc.id %>_handling_percentage' ></div></p>
44
+ <p><div id='storeconfig_<%= sc.id %>_download_url_expires_in' ></div></p>
44
45
 
45
46
  <div id='message'></div>
46
47
 
@@ -66,31 +67,32 @@ $(document).ready(function() {
66
67
  update_url: '/admin/store',
67
68
  authenticity_token: '<%= form_authenticity_token %>',
68
69
  attributes: [
69
- { name: 'pp_name' , nice_name: 'Type' , type: 'select' , value: <%= raw Caboose.json(sc.pp_name ) %>, width: 400 , options_url: '/admin/store/payment-processor-options' },
70
- { name: 'pp_username' , nice_name: 'Username' , type: 'text' , value: <%= raw Caboose.json(sc.pp_username ) %>, width: 400 },
71
- { name: 'pp_password' , nice_name: 'Password' , type: 'text' , value: <%= raw Caboose.json(sc.pp_password ) %>, width: 400 },
72
- { name: 'pp_relay_domain' , nice_name: 'Relay Domain' , type: 'text' , value: <%= raw Caboose.json(sc.pp_relay_domain ) %>, width: 400 },
73
- { name: 'pp_testing' , nice_name: 'Test Mode' , type: 'checkbox' , value: <%= raw Caboose.json(sc.pp_testing ? 1 : 0 ) %>, width: 400 },
74
- { name: 'fulfillment_email' , nice_name: 'Fulfillment Email' , type: 'text' , value: <%= raw Caboose.json(sc.fulfillment_email ) %>, width: 400 },
75
- { name: 'shipping_email' , nice_name: 'Shipping Email' , type: 'text' , value: <%= raw Caboose.json(sc.shipping_email ) %>, width: 400 },
76
- { name: 'handling_percentage' , nice_name: 'Handling Percentage' , type: 'text' , value: <%= raw Caboose.json(sc.handling_percentage ) %>, width: 400 },
77
- { name: 'length_unit' , nice_name: 'Length' , type: 'select' , value: <%= raw Caboose.json(sc.length_unit ) %>, width: 400 , options_url: '/admin/store/length-unit-options' },
78
- { name: 'weight_unit' , nice_name: 'Weight' , type: 'select' , value: <%= raw Caboose.json(sc.weight_unit ) %>, width: 400 , options_url: '/admin/store/weight-unit-options' },
79
- { name: 'ups_username' , nice_name: 'UPS Username' , type: 'text' , value: <%= raw Caboose.json(sc.ups_username ) %>, width: 400 },
80
- { name: 'ups_password' , nice_name: 'UPS Password' , type: 'text' , value: <%= raw Caboose.json(sc.ups_password ) %>, width: 400 },
81
- { name: 'ups_key' , nice_name: 'UPS Key' , type: 'text' , value: <%= raw Caboose.json(sc.ups_key ) %>, width: 400 },
82
- { name: 'ups_origin_account' , nice_name: 'UPS Origin Account' , type: 'text' , value: <%= raw Caboose.json(sc.ups_origin_account ) %>, width: 400 },
83
- { name: 'usps_username' , nice_name: 'USPS Username' , type: 'text' , value: <%= raw Caboose.json(sc.usps_username ) %>, width: 400 },
84
- { name: 'usps_secret_key' , nice_name: 'USPS Secret Key' , type: 'text' , value: <%= raw Caboose.json(sc.usps_secret_key ) %>, width: 400 },
85
- { name: 'usps_publishable_key' , nice_name: 'USPS Publishable Key' , type: 'text' , value: <%= raw Caboose.json(sc.usps_publishable_key ) %>, width: 400 },
86
- { name: 'fedex_username' , nice_name: 'FedEx Username' , type: 'text' , value: <%= raw Caboose.json(sc.fedex_username ) %>, width: 400 },
87
- { name: 'fedex_password' , nice_name: 'FedEx Password' , type: 'text' , value: <%= raw Caboose.json(sc.fedex_password ) %>, width: 400 },
88
- { name: 'fedex_key' , nice_name: 'FedEx Key' , type: 'text' , value: <%= raw Caboose.json(sc.fedex_key ) %>, width: 400 },
89
- { name: 'fedex_account' , nice_name: 'FedEx Account' , type: 'text' , value: <%= raw Caboose.json(sc.fedex_account ) %>, width: 400 },
90
- { name: 'origin_country' , nice_name: 'Country' , type: 'text' , value: <%= raw Caboose.json(sc.origin_country ) %>, width: 400 },
91
- { name: 'origin_state' , nice_name: 'State' , type: 'text' , value: <%= raw Caboose.json(sc.origin_state ) %>, width: 400 },
92
- { name: 'origin_city' , nice_name: 'City' , type: 'text' , value: <%= raw Caboose.json(sc.origin_city ) %>, width: 400 },
93
- { name: 'origin_zip' , nice_name: 'Zip' , type: 'text' , value: <%= raw Caboose.json(sc.origin_zip ) %>, width: 400 }
70
+ { name: 'pp_name' , nice_name: 'Type' , type: 'select' , value: <%= raw Caboose.json(sc.pp_name ) %>, width: 400 , options_url: '/admin/store/payment-processor-options' },
71
+ { name: 'pp_username' , nice_name: 'Username' , type: 'text' , value: <%= raw Caboose.json(sc.pp_username ) %>, width: 400 },
72
+ { name: 'pp_password' , nice_name: 'Password' , type: 'text' , value: <%= raw Caboose.json(sc.pp_password ) %>, width: 400 },
73
+ { name: 'pp_relay_domain' , nice_name: 'Relay Domain' , type: 'text' , value: <%= raw Caboose.json(sc.pp_relay_domain ) %>, width: 400 },
74
+ { name: 'pp_testing' , nice_name: 'Test Mode' , type: 'checkbox' , value: <%= raw Caboose.json(sc.pp_testing ? 1 : 0 ) %>, width: 400 },
75
+ { name: 'fulfillment_email' , nice_name: 'Fulfillment Email' , type: 'text' , value: <%= raw Caboose.json(sc.fulfillment_email ) %>, width: 400 },
76
+ { name: 'shipping_email' , nice_name: 'Shipping Email' , type: 'text' , value: <%= raw Caboose.json(sc.shipping_email ) %>, width: 400 },
77
+ { name: 'handling_percentage' , nice_name: 'Handling Percentage' , type: 'text' , value: <%= raw Caboose.json(sc.handling_percentage ) %>, width: 400 },
78
+ { name: 'length_unit' , nice_name: 'Length' , type: 'select' , value: <%= raw Caboose.json(sc.length_unit ) %>, width: 400 , options_url: '/admin/store/length-unit-options' },
79
+ { name: 'weight_unit' , nice_name: 'Weight' , type: 'select' , value: <%= raw Caboose.json(sc.weight_unit ) %>, width: 400 , options_url: '/admin/store/weight-unit-options' },
80
+ { name: 'ups_username' , nice_name: 'UPS Username' , type: 'text' , value: <%= raw Caboose.json(sc.ups_username ) %>, width: 400 },
81
+ { name: 'ups_password' , nice_name: 'UPS Password' , type: 'text' , value: <%= raw Caboose.json(sc.ups_password ) %>, width: 400 },
82
+ { name: 'ups_key' , nice_name: 'UPS Key' , type: 'text' , value: <%= raw Caboose.json(sc.ups_key ) %>, width: 400 },
83
+ { name: 'ups_origin_account' , nice_name: 'UPS Origin Account' , type: 'text' , value: <%= raw Caboose.json(sc.ups_origin_account ) %>, width: 400 },
84
+ { name: 'usps_username' , nice_name: 'USPS Username' , type: 'text' , value: <%= raw Caboose.json(sc.usps_username ) %>, width: 400 },
85
+ { name: 'usps_secret_key' , nice_name: 'USPS Secret Key' , type: 'text' , value: <%= raw Caboose.json(sc.usps_secret_key ) %>, width: 400 },
86
+ { name: 'usps_publishable_key' , nice_name: 'USPS Publishable Key' , type: 'text' , value: <%= raw Caboose.json(sc.usps_publishable_key ) %>, width: 400 },
87
+ { name: 'fedex_username' , nice_name: 'FedEx Username' , type: 'text' , value: <%= raw Caboose.json(sc.fedex_username ) %>, width: 400 },
88
+ { name: 'fedex_password' , nice_name: 'FedEx Password' , type: 'text' , value: <%= raw Caboose.json(sc.fedex_password ) %>, width: 400 },
89
+ { name: 'fedex_key' , nice_name: 'FedEx Key' , type: 'text' , value: <%= raw Caboose.json(sc.fedex_key ) %>, width: 400 },
90
+ { name: 'fedex_account' , nice_name: 'FedEx Account' , type: 'text' , value: <%= raw Caboose.json(sc.fedex_account ) %>, width: 400 },
91
+ { name: 'origin_country' , nice_name: 'Country' , type: 'text' , value: <%= raw Caboose.json(sc.origin_country ) %>, width: 400 },
92
+ { name: 'origin_state' , nice_name: 'State' , type: 'text' , value: <%= raw Caboose.json(sc.origin_state ) %>, width: 400 },
93
+ { name: 'origin_city' , nice_name: 'City' , type: 'text' , value: <%= raw Caboose.json(sc.origin_city ) %>, width: 400 },
94
+ { name: 'origin_zip' , nice_name: 'Zip' , type: 'text' , value: <%= raw Caboose.json(sc.origin_zip ) %>, width: 400 },
95
+ { name: 'download_url_expires_in' , nice_name: 'Download URL Expires In (minutes)' , type: 'text' , value: <%= raw Caboose.json(sc.download_url_expires_in ) %>, width: 400 }
94
96
  ]
95
97
  });
96
98
 
@@ -3,7 +3,7 @@ p = @product
3
3
  v = @variant
4
4
  %>
5
5
  <h1>Edit Variant</h1>
6
-
6
+ <p><strong>Product:</strong> <%= p.title %></p>
7
7
  <table>
8
8
  <tr>
9
9
  <td valign='top'>
@@ -15,6 +15,7 @@ v = @variant
15
15
  <div id='variant_<%= v.id %>_requires_shipping' ></div>
16
16
  <div id='variant_<%= v.id %>_allow_backorder' ></div>
17
17
  <div id='variant_<%= v.id %>_taxable' ></div>
18
+ <div id='variant_<%= v.id %>_downloadable' ></div>
18
19
  </td><td valign='top'>
19
20
  <h2>Inventory</h2>
20
21
  <div id='variant_<%= v.id %>_alternate_id' ></div>
@@ -33,9 +34,11 @@ v = @variant
33
34
  </td>
34
35
  </tr>
35
36
  </table>
37
+ <div id='variant_<%= v.id %>_download_path' ></div>
36
38
  <div id='message'></div>
37
39
  <p>
38
40
  <input type='button' value='< Back' onclick="window.location='/admin/products/<%= p.id %>/variants';" />
41
+ <input type='button' value='Generate Download URL' onclick="download_url();" />
39
42
  <input type='button' value='Delete Variant' onclick="delete_variant(<%= v.id %>);" />
40
43
  </p>
41
44
 
@@ -68,15 +71,38 @@ $(document).ready(function() {
68
71
  { name: 'requires_shipping' , nice_name: 'Requires shipping' , type: 'checkbox' , align: 'right' , value: <%= raw Caboose.json(v.requires_shipping ) %>, width: 250 },
69
72
  { name: 'taxable' , nice_name: 'Taxable' , type: 'checkbox' , align: 'right' , value: <%= raw Caboose.json(v.taxable ) %>, width: 250 },
70
73
  { name: 'allow_backorder' , nice_name: 'Allow backorder' , type: 'checkbox' , align: 'right' , value: <%= raw Caboose.json(v.allow_backorder ) %>, width: 250 },
71
- { name: 'status' , nice_name: 'Status' , type: 'select' , align: 'right' , value: <%= raw Caboose.json(v.status) %>, text: <%= raw Caboose.json(v.status) %>, width: 250, options_url: '/admin/variants/status-options' }
74
+ { name: 'status' , nice_name: 'Status' , type: 'select' , align: 'right' , value: <%= raw Caboose.json(v.status ) %>, width: 250, options_url: '/admin/variants/status-options' },
75
+ { name: 'downloadable' , nice_name: 'Downloadable' , type: 'checkbox' , align: 'right' , value: <%= raw Caboose.json(v.downloadable ) %>, width: 250 },
76
+ { name: 'download_path' , nice_name: 'Download path' , type: 'text' , align: 'right' , value: <%= raw Caboose.json(v.download_path ) %>, width: 800 }
72
77
  ]
73
78
  });
74
79
  });
75
80
 
76
- var modal = false;
77
- $(window).load(function() {
78
- modal = new CabooseModal(800);
79
- });
81
+ function download_url(expires_in)
82
+ {
83
+ if (!expires_in)
84
+ {
85
+ var p = $('<p/>').addClass('note')
86
+ .append("For how many minutes do you want the download link to be valid?<br />")
87
+ .append($('<input/>').attr('type', 'text').attr('id', 'expires_in').css('width', '50px').val('5'))
88
+ .append(' minutes<br/>')
89
+ .append($('<input/>').attr('type', 'button').val('Generate Download URL').click(function() {
90
+ download_url($('#expires_in').val());
91
+ }));
92
+ $('#message').empty().append(p);
93
+ return;
94
+ }
95
+ $('#message').html("<p class='loading'>Generating download URL...</p>");
96
+ $.ajax({
97
+ url: '/admin/products/<%= v.product_id %>/variants/<%= v.id %>/download-url',
98
+ type: 'get',
99
+ data: { expires_in: expires_in },
100
+ success: function(resp) {
101
+ if (resp.error) $('#message').html("<p class='note error'>" + resp.error + "</p>");
102
+ if (resp.success) $('#message').html("<p class='note success'>The URL has been generated successfully:<br/><br/>" + resp.url + "</p>");
103
+ }
104
+ });
105
+ }
80
106
 
81
107
  </script>
82
108
  <% end %>
@@ -78,10 +78,12 @@ $(document).ready(function() {
78
78
  { show: false , name: 'length' , nice_name: 'Length (in)' , sort: 'length' , type: 'text' , value: function(v) { return v.length }, width: 50, align: 'right' , bulk_edit: true },
79
79
  { show: false , name: 'width' , nice_name: 'Width (in)' , sort: 'width' , type: 'text' , value: function(v) { return v.width }, width: 50, align: 'right' , bulk_edit: true },
80
80
  { show: false , name: 'height' , nice_name: 'Height (in)' , sort: 'height' , type: 'text' , value: function(v) { return v.height }, width: 50, align: 'right' , bulk_edit: true },
81
- { show: false , name: 'cylinder' , nice_name: 'Cylinder' , sort: 'cylinder' , type: 'checkbox' , value: function(v) { return v.cylinder }, width: 50, align: 'center' , bulk_edit: true },
82
- { show: false , name: 'requires_shipping' , nice_name: 'Requires shipping' , sort: 'requires_shipping' , type: 'checkbox' , value: function(v) { return v.requires_shipping }, width: 50, align: 'center' , bulk_edit: true },
83
- { show: false , name: 'taxable' , nice_name: 'Taxable' , sort: 'taxable' , type: 'checkbox' , value: function(v) { return v.taxable }, width: 50, align: 'center' , bulk_edit: true },
84
- { show: false , name: 'allow_backorder' , nice_name: 'Allow backorder' , sort: 'allow_backorder' , type: 'checkbox' , value: function(v) { return v.allow_backorder }, width: 50, align: 'center' , bulk_edit: true }
81
+ { show: false , name: 'cylinder' , nice_name: 'Cylinder' , sort: 'cylinder' , type: 'checkbox' , value: function(v) { return v.cylinder }, text: function(v) { return v.cylinder ? 'Yes' : 'No' }, width: 50, align: 'center' , bulk_edit: true },
82
+ { show: false , name: 'requires_shipping' , nice_name: 'Requires shipping' , sort: 'requires_shipping' , type: 'checkbox' , value: function(v) { return v.requires_shipping }, text: function(v) { return v.requires_shipping ? 'Yes' : 'No' }, width: 50, align: 'center' , bulk_edit: true },
83
+ { show: false , name: 'taxable' , nice_name: 'Taxable' , sort: 'taxable' , type: 'checkbox' , value: function(v) { return v.taxable }, text: function(v) { return v.taxable ? 'Yes' : 'No' }, width: 50, align: 'center' , bulk_edit: true },
84
+ { show: false , name: 'allow_backorder' , nice_name: 'Allow backorder' , sort: 'allow_backorder' , type: 'checkbox' , value: function(v) { return v.allow_backorder }, text: function(v) { return v.allow_backorder ? 'Yes' : 'No' }, width: 50, align: 'center' , bulk_edit: true },
85
+ { show: false , name: 'downloadable' , nice_name: 'Downloadable' , sort: 'downloadable' , type: 'checkbox' , value: function(v) { return v.downloadable }, text: function(v) { return v.downloadable ? 'Yes' : 'No' }, width: 50, align: 'center' , bulk_edit: true },
86
+ { show: false , name: 'download_path' , nice_name: 'Download path' , sort: 'download_path' , type: 'text' , value: function(v) { return v.download_path }, width: 50, align: 'left' , bulk_edit: true }
85
87
  ],
86
88
  new_model_text: 'New Variant',
87
89
  new_model_fields: [
data/config/routes.rb CHANGED
@@ -19,9 +19,21 @@ Caboose::Engine.routes.draw do
19
19
  get "logout" => "logout#index"
20
20
  get "register" => "register#index"
21
21
  post "register" => "register#register"
22
- get "my-account" => "users#my_account"
23
- put "my-account" => "users#update_my_account"
24
22
 
23
+ #=============================================================================
24
+ # My Account
25
+ #=============================================================================
26
+
27
+ get "my-account" => "users#my_account"
28
+ put "my-account" => "users#update_my_account"
29
+
30
+ get "my-account/orders/:order_id/line-items/:id/download" => "my_account_line_items#download"
31
+ get "my-account/orders/:order_id/line-items/:id" => "my_account_line_items#edit"
32
+ get "my-account/orders/:order_id/line-items" => "my_account_line_items#index"
33
+
34
+ get "my-account/orders/:id" => "my_account_orders#edit"
35
+ get "my-account/orders" => "my_account_orders#index"
36
+
25
37
  #=============================================================================
26
38
  # Sites
27
39
  #=============================================================================
@@ -413,7 +425,9 @@ Caboose::Engine.routes.draw do
413
425
  put '/admin/products/:product_id/variants/option3-sort-order' => 'variants#admin_update_option3_sort_order'
414
426
  put "/admin/products/:product_id/variants/:id/attach-to-image" => "variants#admin_attach_to_image"
415
427
  put "/admin/products/:product_id/variants/:id/unattach-from-image" => "variants#admin_unattach_from_image"
416
- get "/admin/products/:product_id/variants/:id" => "variants#admin_edit"
428
+ get "/admin/products/:product_id/variants/:id/download-url" => "variants#admin_download_url"
429
+ get "/admin/products/:product_id/variants/:id/json" => "variants#admin_json_single"
430
+ get "/admin/products/:product_id/variants/:id" => "variants#admin_edit"
417
431
  put '/admin/products/:product_id/variants/bulk' => 'variants#admin_bulk_update'
418
432
  put "/admin/products/:product_id/variants/:id" => "variants#admin_update"
419
433
  get "/admin/products/:product_id/variants/new" => "variants#admin_new"
@@ -1,3 +1,3 @@
1
1
  module Caboose
2
- VERSION = '0.5.119'
2
+ VERSION = '0.5.120'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: caboose-cms
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.119
4
+ version: 0.5.120
5
5
  platform: ruby
6
6
  authors:
7
7
  - William Barry
@@ -512,6 +512,8 @@ files:
512
512
  - app/controllers/caboose/logout_controller.rb
513
513
  - app/controllers/caboose/media_categories_controller.rb
514
514
  - app/controllers/caboose/modal_controller.rb
515
+ - app/controllers/caboose/my_account_line_items_controller.rb
516
+ - app/controllers/caboose/my_account_orders_controller.rb
515
517
  - app/controllers/caboose/order_packages_controller.rb
516
518
  - app/controllers/caboose/orders_controller.rb
517
519
  - app/controllers/caboose/page_permissions_controller.rb