caboose-cms 0.5.162 → 0.5.163

Sign up to get free protection for your applications and to get access to all the features.
@@ -27,22 +27,23 @@ module Caboose
27
27
  pass1 = params[:pass1]
28
28
  pass2 = params[:pass2]
29
29
 
30
- if first_name.nil? || first_name.strip.length == 0 then resp.error = "Your first name is required."
31
- elsif last_name.nil? || last_name.strip.length == 0 then resp.error = "Your last name is required."
32
- elsif email.nil? || email.strip.length == 0 then resp.error = "Your email address is required."
33
- elsif User.where(:email => email.strip.downcase).exists? then resp.error = "A user with that email address already exists."
34
- elsif phone.nil? || phone.strip.length < 10 then resp.error = "Your phone number is required. Please include your area code."
35
- elsif pass1.nil? || pass1.strip.length < 8 then resp.error = "Your password must be at least 8 characters."
36
- elsif pass2.nil? || pass1 != pass2 then resp.error = "Your passwords don't match."
30
+ if first_name.nil? || first_name.strip.length == 0 then resp.error = "Your first name is required."
31
+ elsif last_name.nil? || last_name.strip.length == 0 then resp.error = "Your last name is required."
32
+ elsif email.nil? || email.strip.length == 0 then resp.error = "Your email address is required."
33
+ elsif User.where(:site_id => @site.id, :email => email.strip.downcase).exists? then resp.error = "A user with that email address already exists."
34
+ elsif phone.nil? || phone.strip.length < 10 then resp.error = "Your phone number is required. Please include your area code."
35
+ elsif pass1.nil? || pass1.strip.length < 8 then resp.error = "Your password must be at least 8 characters."
36
+ elsif pass2.nil? || pass1 != pass2 then resp.error = "Your passwords don't match."
37
37
  else
38
38
 
39
39
  u = Caboose::User.new
40
+ u.site_id = @site.id
40
41
  u.first_name = first_name
41
42
  u.last_name = last_name
42
43
  u.email = email.strip.downcase
43
44
  u.phone = phone
44
45
  u.password = Digest::SHA1.hexdigest(Caboose::salt + pass1)
45
- u.date_created = DateTime.now
46
+ u.date_created = DateTime.now
46
47
  u.save
47
48
 
48
49
  # Go ahead and log the user in
@@ -39,6 +39,55 @@ module Caboose
39
39
  resp.success = save && sa.save
40
40
  render :json => resp
41
41
  end
42
+
43
+ #===========================================================================
44
+
45
+ # GET /my-account/orders/:order_id/shipping-address/json
46
+ def my_account_json
47
+ return if !logged_in?
48
+ order = Order.find(params[:order_id])
49
+ if order.customer_id != logged_in_user.id
50
+ render :json => { :error => "The given order does not belong to you." }
51
+ return
52
+ end
53
+ render :json => order.shipping_address
54
+ end
55
+
56
+ # PUT /my-account/orders/:order_id/shipping-address
57
+ def my_account_update
58
+ return if !logged_in?
59
+
60
+ resp = Caboose::StdClass.new
61
+ order = Order.find(params[:order_id])
62
+ if order.customer_id != logged_in_user.id
63
+ render :json => { :error => "The given order does not belong to you." }
64
+ return
65
+ end
66
+
67
+ sa = order.shipping_address
68
+ save = true
69
+ params.each do |name, value|
70
+ case name
71
+ when 'name' then sa.name = value
72
+ when 'first_name' then sa.first_name = value
73
+ when 'last_name' then sa.last_name = value
74
+ when 'street' then sa.street = value
75
+ when 'address1' then sa.address1 = value
76
+ when 'address2' then sa.address2 = value
77
+ when 'company' then sa.company = value
78
+ when 'city' then sa.city = value
79
+ when 'state' then sa.state = value
80
+ when 'province' then sa.province = value
81
+ when 'province_code' then sa.province_code = value
82
+ when 'zip' then sa.zip = value
83
+ when 'country' then sa.country = value
84
+ when 'country_code' then sa.country_code = value
85
+ when 'phone' then sa.phone = value
86
+ end
87
+ end
88
+ resp.success = save && sa.save
89
+ render :json => resp
90
+ end
42
91
 
43
92
  end
44
93
  end
@@ -8,8 +8,8 @@ class Caboose::Authenticator
8
8
  )
9
9
  pass = Digest::SHA1.hexdigest(Caboose::salt + password)
10
10
 
11
- user = Caboose::User.where(:username => username).first
12
- user = Caboose::User.where(:email => username).first if user.nil?
11
+ user = Caboose::User.where(:username => username, :site_id => site.id).first
12
+ user = Caboose::User.where(:email => username, :site_id => site.id).first if user.nil?
13
13
 
14
14
  valid_credentials = false
15
15
  if user && user.password == pass
@@ -18,7 +18,8 @@ module Caboose
18
18
 
19
19
  attr_accessible :id,
20
20
  :site_id,
21
- :alternate_id,
21
+ :alternate_id,
22
+ :order_number,
22
23
  :subtotal,
23
24
  :tax,
24
25
  :shipping,
@@ -235,6 +236,7 @@ module Caboose
235
236
  return false
236
237
  end
237
238
 
239
+ # Capture funds from a previously authorized transaction
238
240
  def capture_funds
239
241
 
240
242
  resp = StdClass.new
@@ -249,49 +251,168 @@ module Caboose
249
251
  else
250
252
 
251
253
  sc = self.site.store_config
254
+ ot = Caboose::OrderTransaction.new(
255
+ :order_id => self.id,
256
+ :date_processed => DateTime.now.utc,
257
+ :transaction_type => OrderTransaction::TYPE_CAPTURE,
258
+ :amount => self.total
259
+ )
260
+
252
261
  case sc.pp_name
253
262
  when 'authorize.net'
254
263
  transaction = AuthorizeNet::AIM::Transaction.new(sc.pp_username, sc.pp_password)
255
264
  response = transaction.prior_auth_capture(t.transaction_id, self.total)
256
-
257
- self.update_attribute(:financial_status, Order::FINANCIAL_STATUS_CAPTURED)
258
- resp.success = 'Captured funds successfully'
259
-
260
- ot = Caboose::OrderTransaction.new(
261
- :order_id => self.id,
262
- :date_processed => DateTime.now.utc,
263
- :transaction_type => OrderTransaction::TYPE_CAPTURE
264
- )
265
+
265
266
  ot.success = response.response_code && response.response_code == '1'
266
267
  ot.transaction_id = response.transaction_id
267
268
  ot.auth_code = response.authorization_code
268
- ot.response_code = response.response_code
269
- ot.amount = self.total
269
+ ot.response_code = response.response_code
270
270
  ot.save
271
-
271
+
272
+ self.update_attribute(:financial_status, Order::FINANCIAL_STATUS_CAPTURED)
273
+ resp.success = 'Captured funds successfully'
274
+
275
+ when 'stripe'
276
+ # TODO: Implement capture funds for stripe
277
+
272
278
  when 'payscape'
273
279
  # TODO: Implement capture funds for payscape
274
280
 
275
281
  end
276
-
277
- #if (order.discounts.any? && order.total < order.discounts.first.amount_current) || PaymentProcessor.capture(order)
278
- # order.financial_status = 'captured'
279
- # order.save
280
- #
281
- # if order.discounts.any?
282
- # order.update_attribute(:amount_discounted, order.discounts.first.amount_current)
283
- # order.update_gift_cards
284
- # end
285
- #
286
- # response.success = "Captured funds successfully"
287
- #else
288
- # response.error = "Error capturing funds."
289
- #end
290
282
 
291
283
  end
292
284
 
293
285
  return resp
294
286
  end
287
+
288
+ # Void an authorized order
289
+ def void
290
+
291
+ resp = StdClass.new
292
+ t = OrderTransaction.where(:order_id => self.id, :transaction_type => OrderTransaction::TYPE_AUTHORIZE, :success => true).first
293
+
294
+ if self.financial_status == Order::FINANCIAL_STATUS_CAPTURED
295
+ resp.error = "This order has already been captured, you will need to refund instead"
296
+ elsif t.nil?
297
+ resp.error = "This order doesn't seem to be authorized."
298
+ else
299
+
300
+ sc = self.site.store_config
301
+ ot = Caboose::OrderTransaction.new(
302
+ :order_id => self.id,
303
+ :date_processed => DateTime.now.utc,
304
+ :transaction_type => OrderTransaction::TYPE_VOID,
305
+ :amount => self.total
306
+ )
307
+
308
+ case sc.pp_name
309
+ when 'authorize.net'
310
+
311
+ response = AuthorizeNet::SIM::Transaction.new(
312
+ sc.pp_username,
313
+ sc.pp_password,
314
+ self.total,
315
+ :transaction_type => OrderTransaction::TYPE_VOID,
316
+ :transaction_id => t.transaction_id
317
+ )
318
+ order.update_attributes(
319
+ :financial_status => Order::FINANCIAL_STATUS_VOIDED,
320
+ :status => Order::STATUS_CANCELED
321
+ )
322
+ self.save
323
+ # TODO: Add the variant quantities ordered back
324
+ resp.success = "Order voided successfully"
325
+
326
+ ot.success = response.response_code && response.response_code == '1'
327
+ ot.transaction_id = response.transaction_id
328
+ #ot.auth_code = response.authorization_code
329
+ ot.response_code = response.response_code
330
+ ot.save
331
+
332
+ when 'stripe'
333
+ # TODO: Implement void order for strip
334
+
335
+ when 'payscape'
336
+ # TODO: Implement void order for payscape
337
+
338
+ end
339
+
340
+ end
341
+ return resp
342
+ end
343
+
344
+ #def refund
345
+ #
346
+ # resp = StdClass.new
347
+ # t = OrderTransaction.where(:order_id => self.id, :transaction_type => OrderTransaction::TYPE_CAPTURE, :success => true).first
348
+ #
349
+ # if self.financial_status != Order::FINANCIAL_STATUS_CAPTURED
350
+ # resp.error = "This order hasn't been captured yet, you will need to void instead"
351
+ # else
352
+ #
353
+ # sc = self.site.store_config
354
+ # case sc.pp_name
355
+ # when 'authorize.net'
356
+ #
357
+ # if PaymentProcessor.refund(order)
358
+ # order.update_attributes(
359
+ # :financial_status => Order::FINANCIAL_STATUS_REFUNDED,
360
+ # :status => Order::STATUS_CANCELED
361
+ # )
362
+ #
363
+ # response.success = 'Order refunded successfully'
364
+ # else
365
+ # response.error = 'Error refunding order'
366
+ # end
367
+ #
368
+ # #if order.calculate_net < (order.amount_discounted || 0) || PaymentProcessor.refund(order)
369
+ # # order.financial_status = 'refunded'
370
+ # # order.status = 'refunded'
371
+ # # order.save
372
+ # #
373
+ # # if order.discounts.any?
374
+ # # discount = order.discounts.first
375
+ # # amount_to_refund = order.calculate_net < order.amount_discounted ? order.calculate_net : order.amount_discounted
376
+ # # discount.update_attribute(:amount_current, amount_to_refund + discount.amount_current)
377
+ # # end
378
+ # #
379
+ # # response.success = "Order refunded successfully"
380
+ # #else
381
+ # # response.error = "Error refunding order."
382
+ # #end
383
+ # end
384
+ #
385
+ # render json: response
386
+ #
387
+ # # return if !user_is_allowed('orders', 'edit')
388
+ # #
389
+ # # response = Caboose::StdClass.new({
390
+ # # 'refresh' => nil,
391
+ # # 'error' => nil,
392
+ # # 'success' => nil
393
+ # # })
394
+ # #
395
+ # # order = Order.find(params[:id])
396
+ # #
397
+ # # if order.financial_status != 'captured'
398
+ # # response.error = "This order hasn't been captured yet, you will need to void instead"
399
+ # # else
400
+ # # if PaymentProcessor.refund(order)
401
+ # # order.financial_status = 'refunded'
402
+ # # order.status = 'refunded'
403
+ # # order.save
404
+ # #
405
+ # # # Add the variant quantities ordered back
406
+ # # order.cancel
407
+ # #
408
+ # # response.success = "Order refunded successfully"
409
+ # # else
410
+ # # response.error = "Error refunding order."
411
+ # # end
412
+ # # end
413
+ # #
414
+ # # render :json => response
415
+ #end
295
416
 
296
417
  end
297
418
  end
@@ -35,10 +35,22 @@ function show_products()
35
35
  $.each(products, function(i, p) {
36
36
  ul.append($('<li/>')
37
37
  .attr('id', 'product_id_' + p.id)
38
- .data('product_id', p.id)
38
+ .data('product_id', p.id)
39
+ .data('variant_id', p.variant_id)
39
40
  .append($('<a/>').html(p.title).click(function(e) {
40
41
  e.preventDefault();
41
- show_variants($(e.target).parent(), $(e.target).parent().data('product_id'));
42
+
43
+ var li = $(e.target).parent();
44
+ var product_id = li.data('product_id');
45
+ var variant_id = li.data('variant_id');
46
+
47
+ if (variant_id && variant_id != null)
48
+ {
49
+ parent.controller.add_variant(variant_id);
50
+ modal.close();
51
+ }
52
+ else
53
+ show_variants(li, product_id);
42
54
  }))
43
55
  );
44
56
  });
@@ -80,6 +92,7 @@ function show_variants(li, product_id)
80
92
  if (v.option2) name.push(v.option2);
81
93
  if (v.option3) name.push(v.option3);
82
94
  name = name.join(' / ');
95
+ if (!name || name.length == 0) name = 'Default';
83
96
  ul.append($('<li/>')
84
97
  .data('variant_id', v.id)
85
98
  .append($('<a/>').html(name).click(function(e) {
@@ -0,0 +1,16 @@
1
+ <%
2
+ # This relay page is rendered from the authorize.net server in a hidden iframe
3
+ # on the host application's checkout page.
4
+ #
5
+ # Since security rules in browsers disallow javascript access to and from
6
+ # iframes with pages in different domains, we need to send things back to
7
+ # a page on our own domain so we can bubble up the response.
8
+ #
9
+ %><!DOCTYPE>
10
+ <html>
11
+ <body>
12
+ <script type='text/javascript'>
13
+ window.location = <%= raw Caboose.json(@url) %>;
14
+ </script>
15
+ </body>
16
+ </html>
@@ -0,0 +1,12 @@
1
+ <%
2
+ # This page is rendered from the host application's domain, and thus is allowed
3
+ # to access the parent's DOM via javascript.
4
+ #
5
+ %><!DOCTYPE>
6
+ <html>
7
+ <body>
8
+ <script type='text/javascript'>
9
+ parent.relay_handler(<%= raw Caboose.json(@resp) %>);
10
+ </script>
11
+ </body>
12
+ </html>
@@ -1,124 +1,66 @@
1
1
  <%
2
- captured = @order.financial_status == 'captured'
3
- ba = @order.billing_address
4
- sa = @order.shipping_address
5
- ba = nil if ba.first_name.nil? || ba.last_name.nil?
6
- sa = nil if sa.first_name.nil? || sa.last_name.nil?
2
+ store_config = @order.site.store_config
7
3
  %>
8
- <input type='hidden' name='order_id' id='order_id' value='<%= @order.id %>' />
9
-
10
4
  <h1>Order #<%= @order.order_number %></h1>
11
5
 
12
- <table class='order'>
13
- <tr>
14
- <% if ba %><th>Billing Address</th><% end %>
15
- <% if sa %><th>Shipping Address</th><% end %>
16
- <th>Order Status</th>
17
- <th>Payment Status</th>
18
- </tr>
19
- <tr>
20
- <% if ba %><td valign='top'><%= raw ba.name_and_address %></td><% end %>
21
- <% if sa %><td valign='top'><%= raw sa.name_and_address %></td><% end %>
22
- <td valign='top'><%= @order.status.capitalize %></td>
23
- <td valign='top'><%= @order.financial_status.capitalize %></td>
24
- </tr>
25
- </table><br />
26
-
27
- <table class='order' width='100%'>
28
- <% @order.order_packages.all.each_with_index do |op, i| %>
29
- <tr><td colspan='5' class='package_header'>Package <%= (i+1) %>: <%= op.shipping_method.service_name %><br /><%= op.status %></td></tr>
30
- <tr>
31
- <th>Item</th>
32
- <th>Status</th>
33
- <th>Unit Price</th>
34
- <th>Quantity</th>
35
- <th>Subtotal</th>
36
- </tr>
37
- <% op.line_items.each do |li| %>
38
- <% img = li.variant.product_image %>
39
- <tr>
40
- <td>
41
- <% if img %><img src='<%= img.url(:tiny) %>' /><% end %>
42
- <% if li.variant.nil? || li.variant.product.nil? %>
43
- <% if li.variant.nil? %>Unknown variant<% else %><%= li.variant.sku %><% end %>
44
- <% else %>
45
- <a href='/products/<%= li.variant.product.id %>'><%= li.variant.product.title %></a><br />
46
- <% if li.variant.sku && li.variant.sku.strip.length > 0 %><%= li.variant.sku %><br /><% end %>
47
- <%= li.variant.title %>
48
- <% end %>
49
- </td>
50
- <td><%= li.status.capitalize %></td>
51
- <td style='text-align: right;'><%= number_to_currency(li.unit_price) %></td>
52
- <td style='text-align: right;'><%= li.quantity %></td>
53
- <td style='text-align: right;'><%= number_to_currency(li.subtotal) %></td>
54
- </tr>
55
- <% end %>
56
- <% end %>
57
- <% if @order.has_downloadable_items? %>
58
- <tr>
59
- <th>Item</th>
60
- <th>Status</th>
61
- <th>Unit Price</th>
62
- <th>Quantity</th>
63
- <th>Subtotal</th>
64
- </tr>
65
- <% end %>
66
- <% @order.line_items.each do |li| %>
67
- <% next if li.order_package_id %>
68
- <% v = li.variant %>
69
- <% if !v.downloadable %><tr><td colspan='5'>Unpackaged Items</td></tr><% end %>
70
- <% img = v.product_image %>
71
- <tr>
72
- <td>
73
- <% if img %><img src='<%= img.url(:tiny) %>' /><% end %>
74
- <% if v.nil? || v.product.nil? %>
75
- <% if v.nil? %>Unknown variant<% else %><%= v.sku %><% end %>
76
- <% else %>
77
- <p><a href='/admin/products/<%= v.product.id %>'><%= v.product.title %></a><br />
78
- <% if v.sku && v.sku.strip.length > 0 %><%= v.sku %><br /><% end %>
79
- <%= v.title %></p>
80
- <% end %>
81
- <% if v.downloadable %>
82
- <% sc = @order.site.store_config %>
83
- <p><a href='<%= raw sc.pp_relay_domain %>/my-account/orders/<%= @order.id %>/line-items/<%= li.id %>/download' target="_blank">Download</a></p>
84
- <% end %>
85
- </td>
86
- <td><%= li.status.capitalize %></td>
87
- <td style='text-align: right;'><%= number_to_currency(li.unit_price) %></td>
88
- <td style='text-align: right;'><%= li.quantity %></td>
89
- <td style='text-align: right;'><%= number_to_currency(li.subtotal) %></td>
90
- </tr>
6
+ <div id='overview_table'></div>
7
+ <% if @order.financial_status == Caboose::Order::FINANCIAL_STATUS_PENDING %>
8
+ <div id='payment_form'>
9
+ <% if store_config.pp_name == 'authorize.net' %>
10
+ <form id="payment" target="relay" action="https://secure.authorize.net/gateway/transact.dll" method="post">
11
+ <%= sim_fields(@sim_transaction) %>
12
+ <input type="hidden" id="x_invoice_num" name="x_invoice_num" value="<%= @order.id %>" />
13
+ <input type="hidden" id="x_description" name="x_after_relay" value="<%= raw store_config.pp_relay_domain %>/my-account/orders/<%= @order.id %>/authnet-response" />
14
+ <input type="hidden" id="x_first_name" name="x_first_name" value="<%= raw @order.billing_address.first_name %>" />
15
+ <input type="hidden" id="x_last_name" name="x_last_name" value="<%= raw @order.billing_address.last_name %>" />
16
+ <input type="hidden" id="x_address" name="x_address" value="<%= raw @order.billing_address.address1 %>" />
17
+ <input type="hidden" id="x_city" name="x_city" value="<%= raw @order.billing_address.city %>" />
18
+ <input type="hidden" id="x_state" name="x_state" value="<%= raw @order.billing_address.state %>" />
19
+ <input type="hidden" id="x_zip" name="x_zip" value="<%= raw @order.billing_address.zip %>" />
20
+
21
+ <div class="field" id="credit-card">
22
+ <span class="field-text">Credit Card Payment</span>
23
+ <div class="icons"><img src="/assets/caboose/credit_cards.png" alt="Credit Cards Accepted" /></div>
24
+ </div>
25
+ <div class="field" id="card-number">
26
+ <span class="field-text">Card</span>
27
+ <input name="x_card_num" id='billing-cc-number' type="text" maxlength="16" placeholder="Card number" />
28
+ <div class="icons"><img src="/assets/caboose/lock.png" alt="Secure Connection" /></div>
29
+ </div>
30
+ <div class="field" id="expiry">
31
+ <span class="field-text">Expiration</span>
32
+ <input id="expiration" name="x_exp_date" type="hidden" />
33
+ <select id="month" name="month"><% (1..12).each do |i| %><option value="<%= (i<10 ? "0#{i}" : i) %>"><%= (i<10 ? "0#{i}" : i) %> - <%= DateTime.new(2000, i, 1).strftime("%b") %></option><% end %></select> /
34
+ <select id="year" name="year"><% (DateTime.now.year...DateTime.now.year + 20).each do |i| %><option value="<%= i-2000 %>"><%= i %></option><% end %></select>
35
+ </div>
36
+ <input type='button' value='Confirm Payment' id='payment_confirm' class='btn' />
37
+ </form>
38
+ <iframe id="relay" name="relay" style='<% if @show_relay %>display: block; width: 800px; height: 400px; border: #000 1px solid;<% else %>display: none;<% end %>'></iframe>
39
+ <% end %>
40
+ </div>
41
+ <div id='payment_message'></div>
91
42
  <% end %>
92
- <tr><td colspan='5' class='totals_header'>Totals</td></tr>
93
- <tr><td colspan='4' align='right'>Subtotal </td><td style='text-align: right;'><%= number_to_currency(@order.subtotal ) %></td></tr>
94
- <tr><td colspan='4' align='right'>Tax </td><td style='text-align: right;'><%= number_to_currency(@order.tax ) %></td></tr>
95
- <tr><td colspan='4' align='right'>Shipping &amp; Handling </td><td style='text-align: right;'><%= number_to_currency(@order.shipping + @order.handling) %></td></tr>
96
- <tr><td colspan='4' align='right'>Discount </td><td style='text-align: right;'><%= number_to_currency(@order.discount ) %></td></tr>
97
- <tr><td colspan='4' align='right'>Total </td><td style='text-align: right;'><%= number_to_currency(@order.total ) %></td></tr>
98
- </table>
43
+ <div id='order_table'></div>
99
44
  <div id='message'></div>
100
45
 
101
- <p>
102
- <input type='button' value='< Back' class='btn' onclick="window.location='/my-account/orders';" />
103
- </p>
104
-
105
- <% content_for :caboose_css do %>
106
- <style type='text/css'>
107
-
108
- table.order { border-collapse: collapse; margin-bottom: 20px; }
109
- table.order th { margin: 0; padding: 10px; border: #000 0px solid; font-weight: bold; text-align: center; }
110
- table.order td { margin: 0; padding: 10px; border: #000 1px solid; }
111
- table.order td img { float: left; margin-right: 10px; }
112
- table.order td.package_header { font-weight: bold; text-align: center; border: 0; }
113
- table.order td.totals_header { font-weight: bold; text-align: center; border: 0; }
114
-
115
- p { margin-bottom: 10px; }
116
-
117
- </style>
118
- <% end %>
46
+ <p><input type='button' value='< Back' class='btn' onclick="window.location='/my-account/orders';" /></p>
119
47
 
120
48
  <% content_for :caboose_js do %>
49
+ <%= javascript_include_tag 'caboose/model/all' %>
50
+ <%= javascript_include_tag 'caboose/my_account_edit_order' %>
121
51
  <script type='text/javascript'>
122
52
 
53
+ var controller = false;
54
+ $(document).ready(function() {
55
+ controller = new MyAccountOrderController({
56
+ order_id: <%= raw Caboose.json(@order.id) %>,
57
+ authenticity_token: <%= raw Caboose.json(form_authenticity_token) %>
58
+ });
59
+ });
60
+
123
61
  </script>
124
62
  <% end %>
63
+
64
+ <% content_for :caboose_css do %>
65
+ <%= stylesheet_link_tag 'caboose/my_account_edit_order' %>
66
+ <% end %>