caboose-cms 0.8.64 → 0.8.65
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/caboose/my_account_edit_invoice.js +80 -16
- data/app/assets/javascripts/caboose/my_account_payment_method_controller.js +175 -0
- data/app/assets/stylesheets/caboose/my_account_edit_invoice.css.scss +1 -1
- data/app/controllers/caboose/#checkout_controller.rb# +464 -0
- data/app/controllers/caboose/invoices_controller.rb +2 -1
- data/app/controllers/caboose/my_account_invoices_controller.rb +81 -1
- data/app/mailers/caboose/invoices_mailer.rb +2 -2
- data/app/models/caboose/invoice.rb +3 -1
- data/app/views/caboose/my_account_invoices/edit.html.erb +19 -0
- data/lib/caboose/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e6a4ba5943295734cab32b17d7fdbfa8dd72711d
|
4
|
+
data.tar.gz: 88ff9aec8169a808c90b0b9ed97e63816638be5e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ec41548d7130692a7754d55d62703cf5d17266222a4b2215da0c4bdc5179f8f5722868ad7878d7340a3248de76cfb1c2839e9eed03e21fd12927fc85695d56d8
|
7
|
+
data.tar.gz: b50b104307b57b2839efbfc1460be7922d6967150c91e00daf2d455f4d1b27b0afcbf435ed17746094ec3362166f623931c915ed3ced32c5b38303dff4f64b57
|
@@ -14,6 +14,7 @@ MyAccountInvoiceController.prototype = {
|
|
14
14
|
|
15
15
|
var that = this;
|
16
16
|
$('#payment_form').hide();
|
17
|
+
|
17
18
|
$(document).ready(function() { that.refresh(); });
|
18
19
|
},
|
19
20
|
|
@@ -21,9 +22,13 @@ MyAccountInvoiceController.prototype = {
|
|
21
22
|
{
|
22
23
|
var that = this;
|
23
24
|
that.refresh_invoice(function() {
|
25
|
+
if (that.invoice.financial_status == 'pending')
|
26
|
+
that.payment_method_controller = new MyAccountPaymentMethodController({ ic: that });
|
27
|
+
|
24
28
|
$('#invoice_table').html("<p class='loading'>Getting invoice...</p>");
|
25
29
|
that.print();
|
26
|
-
|
30
|
+
|
31
|
+
if (after) after();
|
27
32
|
});
|
28
33
|
},
|
29
34
|
|
@@ -79,6 +84,9 @@ MyAccountInvoiceController.prototype = {
|
|
79
84
|
if (count_downloadable > 0) that.downloadable_line_items_table(table);
|
80
85
|
that.summary_table(table);
|
81
86
|
$('#invoice_table').empty().append(table);
|
87
|
+
|
88
|
+
if (that.invoice.financial_status == 'pending')
|
89
|
+
that.payment_method_controller.print();
|
82
90
|
}
|
83
91
|
else
|
84
92
|
{
|
@@ -96,7 +104,8 @@ MyAccountInvoiceController.prototype = {
|
|
96
104
|
var fstatus = $('<div/>').append($('<p/>').html(capitalize_first_letter(that.invoice.financial_status)));
|
97
105
|
if (that.invoice.financial_status == 'pending')
|
98
106
|
{
|
99
|
-
fstatus.append($('<
|
107
|
+
fstatus.append($('<div/>').attr('id', 'payment_method_container'));
|
108
|
+
//fstatus.append($('<p/>').append($('<input/>').attr('type', 'button').addClass('btn').val('Pay now').click(function(e) { e.preventDefault(); that.payment_form(); })));
|
100
109
|
}
|
101
110
|
|
102
111
|
var table = $('<table/>').addClass('invoice');
|
@@ -424,32 +433,87 @@ MyAccountInvoiceController.prototype = {
|
|
424
433
|
},
|
425
434
|
|
426
435
|
/****************************************************************************/
|
436
|
+
|
437
|
+
confirm_invoice: function()
|
438
|
+
{
|
439
|
+
var that = this;
|
440
|
+
var cust = that.invoice.customer;
|
441
|
+
var form = $('#payment_form');
|
442
|
+
var message = $('#payment_message');
|
443
|
+
|
444
|
+
if (form.is(':visible'))
|
445
|
+
{
|
446
|
+
form.slideUp(function() { form.empty(); });
|
447
|
+
message.empty();
|
448
|
+
return;
|
449
|
+
}
|
450
|
+
|
451
|
+
form.append($('<h4/>').append("Confirm payment"));
|
452
|
+
form.append($('<p/>').html("A payment of $" + curr(that.invoice.total) + " will be charged to your " + cust.card_brand + ' ending in ' + cust.card_last4 + "."));
|
453
|
+
|
454
|
+
form.append($('<input/>').attr('type', 'button').addClass('btn').val('Pay Now').click(function(e)
|
455
|
+
{
|
456
|
+
e.preventDefault();
|
457
|
+
message.empty().html("<p class='loading'>Processing payment...</p>");
|
458
|
+
|
459
|
+
$.ajax({
|
460
|
+
url: '/my-account/confirm',
|
461
|
+
type: 'post',
|
462
|
+
data: { id: that.invoice.id},
|
463
|
+
success: function(resp) {
|
464
|
+
if (resp.success == true)
|
465
|
+
{
|
466
|
+
form.slideUp(function() { form.empty(); });
|
467
|
+
message.empty().html("<p class='note success'>" + resp.message + "</p>");
|
468
|
+
setTimeout(function() { message.empty() }, 5000);
|
469
|
+
that.refresh();
|
470
|
+
}
|
471
|
+
else {
|
472
|
+
message.empty().html("<p class='note error'>" + resp.error + "</p>");
|
473
|
+
}
|
474
|
+
}
|
475
|
+
});
|
476
|
+
}
|
477
|
+
));
|
478
|
+
|
479
|
+
form.slideDown();
|
480
|
+
},
|
427
481
|
|
428
482
|
payment_form: function()
|
429
483
|
{
|
430
|
-
var that
|
431
|
-
var form
|
484
|
+
var that = this;
|
485
|
+
var form = $('#payment_form');
|
486
|
+
var message = $('#payment_message')
|
432
487
|
if (form.is(':visible'))
|
433
488
|
{
|
434
489
|
form.slideUp(function() { form.empty(); });
|
435
|
-
|
490
|
+
message.empty();
|
436
491
|
return;
|
437
492
|
}
|
438
493
|
|
439
|
-
|
494
|
+
message.empty().html("<p class='loading'>Processing payment...</p>");
|
440
495
|
$.ajax({
|
441
496
|
url: '/my-account/invoices/' + that.invoice.id + '/payment-form',
|
442
497
|
type: 'get',
|
443
|
-
success: function(
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
}
|
498
|
+
success: function(resp) {
|
499
|
+
if (resp.success == true)
|
500
|
+
{
|
501
|
+
message.empty().html("<p class='note success'>" + resp.message + "</p>");
|
502
|
+
setTimeout(function() { message.empty() }, 5000);
|
503
|
+
that.refresh();
|
504
|
+
}
|
505
|
+
else {
|
506
|
+
message.empty().html("<p class='note error'>" + resp.error + "</p>");
|
507
|
+
}
|
508
|
+
|
509
|
+
// form.empty().append(html);
|
510
|
+
// form.slideDown();
|
511
|
+
// $('#payment_confirm').click(function(e) {
|
512
|
+
// $('#expiration').val($('#month').val() + $('#year').val());
|
513
|
+
// $('#payment_message').empty().html("<p class='loading'>Processing payment...</p>");
|
514
|
+
// $('#payment_form').slideUp();
|
515
|
+
// $('#payment').submit();
|
516
|
+
// });
|
453
517
|
}
|
454
518
|
});
|
455
519
|
},
|
@@ -0,0 +1,175 @@
|
|
1
|
+
|
2
|
+
var MyAccountPaymentMethodController = function(params) { this.init(params); };
|
3
|
+
|
4
|
+
MyAccountPaymentMethodController.prototype = {
|
5
|
+
|
6
|
+
container: 'payment_method_container',
|
7
|
+
stripe_key: false,
|
8
|
+
customer_id: false,
|
9
|
+
card_brand: false,
|
10
|
+
card_last4: false,
|
11
|
+
card_name: false,
|
12
|
+
card_zip: false,
|
13
|
+
ic: false,
|
14
|
+
|
15
|
+
init: function(params)
|
16
|
+
{
|
17
|
+
var that = this;
|
18
|
+
for (var i in params)
|
19
|
+
that[i] = params[i];
|
20
|
+
},
|
21
|
+
|
22
|
+
refresh: function(after)
|
23
|
+
{
|
24
|
+
var that = this;
|
25
|
+
$.ajax({
|
26
|
+
url: '/checkout/stripe/json',
|
27
|
+
type: 'get',
|
28
|
+
success: function(resp) {
|
29
|
+
that.stripe_key = resp.stripe_key;
|
30
|
+
that.customer_id = resp.customer_id;
|
31
|
+
that.card_brand = resp.card_brand;
|
32
|
+
that.card_last4 = resp.card_last4;
|
33
|
+
//that.cc.print_ready_message();
|
34
|
+
if (after) after();
|
35
|
+
}
|
36
|
+
});
|
37
|
+
},
|
38
|
+
|
39
|
+
print: function()
|
40
|
+
{
|
41
|
+
var that = this;
|
42
|
+
if (!that.stripe_key)
|
43
|
+
{
|
44
|
+
that.refresh(function() { that.print(); });
|
45
|
+
return;
|
46
|
+
}
|
47
|
+
var msg = that.card_brand && that.card_last4 ? that.card_brand + ' ending in ' + that.card_last4 : 'You have no card on file.';
|
48
|
+
var div = $('<div/>');
|
49
|
+
|
50
|
+
if (that.ic.invoice.financial_status == 'pending') {
|
51
|
+
if (that.card_brand && that.card_last4) {
|
52
|
+
div.append($('<p/>').append($('<input/>').attr('type', 'button').addClass('btn').val('Confirm').click(function(e) { e.preventDefault(); that.ic.refresh_invoice( function() { that.ic.confirm_invoice(); }); })));
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
if (that.ic.invoice.total > 0.00)
|
57
|
+
{
|
58
|
+
var msg = that.card_brand && that.card_last4 ? that.card_brand + ' ending in ' + that.card_last4 : 'You have no card on file.';
|
59
|
+
div.append($('<p/>')
|
60
|
+
.append(msg).append(' ')
|
61
|
+
.append($('<a/>').attr('href', '#').html('Edit').click(function(e) { e.preventDefault(); that.edit(); })
|
62
|
+
));
|
63
|
+
}
|
64
|
+
else
|
65
|
+
{
|
66
|
+
div.append($('<p/>')
|
67
|
+
.append("No payment is required at this time. ")
|
68
|
+
.append($('<a/>').attr('href', '#').html('Edit').click(function(e) { e.preventDefault(); that.edit(); })
|
69
|
+
));
|
70
|
+
}
|
71
|
+
$('#'+that.container).empty().append(div);
|
72
|
+
},
|
73
|
+
|
74
|
+
edit: function()
|
75
|
+
{
|
76
|
+
var that = this;
|
77
|
+
|
78
|
+
if (that.ic.invoice.total <= 0.00)
|
79
|
+
{
|
80
|
+
that.print();
|
81
|
+
return;
|
82
|
+
}
|
83
|
+
|
84
|
+
var form = $('<form/>')
|
85
|
+
.attr('action', '')
|
86
|
+
.attr('method', 'post')
|
87
|
+
.attr('id', 'stripe_form')
|
88
|
+
.addClass('stripe_form')
|
89
|
+
.submit(function(e) { e.preventDefault(); that.update(); return false; });
|
90
|
+
|
91
|
+
form.append($('<div/>').addClass('card_number_container')
|
92
|
+
.append($('<input/>').attr('id', 'card_number').attr('type', 'tel').attr('autocomplete', 'off').attr('autocorrect', 'off').attr('spellcheck', 'off').attr('autocapitalize', 'off').attr('placeholder', 'Card number'))
|
93
|
+
.append($('<div/>').addClass('svg icon').css('width', '30px').css('height', '30px').html('<svg version="1.1" viewBox="0 0 30 30" width="30" height="30" focusable="false"><g fill-rule="evenodd"><path d="M2.00585866,0 C0.898053512,0 0,0.900176167 0,1.99201702 L0,9.00798298 C0,10.1081436 0.897060126,11 2.00585866,11 L11.9941413,11 C13.1019465,11 14,10.0998238 14,9.00798298 L14,1.99201702 C14,0.891856397 13.1029399,0 11.9941413,0 L2.00585866,0 Z M2.00247329,1 C1.44882258,1 1,1.4463114 1,1.99754465 L1,9.00245535 C1,9.55338405 1.45576096,10 2.00247329,10 L11.9975267,10 C12.5511774,10 13,9.5536886 13,9.00245535 L13,1.99754465 C13,1.44661595 12.544239,1 11.9975267,1 L2.00247329,1 Z M1,3 L1,5 L13,5 L13,3 L1,3 Z M11,8 L11,9 L12,9 L12,8 L11,8 Z M9,8 L9,9 L10,9 L10,8 L9,8 Z M9,8" style="fill:#3b6faa" transform="translate(8,10)"></g></svg>')));
|
94
|
+
form.append($('<div/>').addClass('card_exp_container')
|
95
|
+
.append($('<input/>').attr('id', 'card_exp').attr('type', 'tel').attr('autocomplete', 'off').attr('autocorrect', 'off').attr('spellcheck', 'off').attr('autocapitalize', 'off').attr('placeholder', 'MM / YY').attr('x-autocompletetype', 'off').attr('autocompletetype', 'off'))
|
96
|
+
.append($('<div/>').addClass('svg icon').css('width', '30px').css('height', '30px').html('<svg version="1.1" viewBox="0 0 30 30" width="30" height="30" focusable="false"><g fill-rule="evenodd"><path d="M2.0085302,1 C0.899249601,1 0,1.90017617 0,2.99201702 L0,10.007983 C0,11.1081436 0.901950359,12 2.0085302,12 L9.9914698,12 C11.1007504,12 12,11.0998238 12,10.007983 L12,2.99201702 C12,1.8918564 11.0980496,1 9.9914698,1 L2.0085302,1 Z M1.99539757,4 C1.44565467,4 1,4.43788135 1,5.00292933 L1,9.99707067 C1,10.5509732 1.4556644,11 1.99539757,11 L10.0046024,11 C10.5543453,11 11,10.5621186 11,9.99707067 L11,5.00292933 C11,4.44902676 10.5443356,4 10.0046024,4 L1.99539757,4 Z M3,1 L3,2 L4,2 L4,1 L3,1 Z M8,1 L8,2 L9,2 L9,1 L8,1 Z M3,0 L3,1 L4,1 L4,0 L3,0 Z M8,0 L8,1 L9,1 L9,0 L8,0 Z M8,0" style="fill:#3b6faa" transform="translate(8,9)"></g></svg>')));
|
97
|
+
form.append($('<div/>').addClass('card_cvc_container')
|
98
|
+
.append($('<input>').attr('id', 'card_cvc').attr('type', 'tel').attr('autocomplete', 'off').attr('autocorrect', 'off').attr('spellcheck', 'off').attr('autocapitalize', 'off').attr('placeholder', 'CVC').attr('maxlength', '4'))
|
99
|
+
.append($('<div>').addClass('svg icon').css('width', '30px').css('height', '30px').html('<svg version="1.1" viewBox="0 0 30 30" width="30" height="30" focusable="false"><g fill-rule="evenodd"><path d="M8.8,4 C8.8,1.79086089 7.76640339,4.18628304e-07 5.5,0 C3.23359661,-4.1480896e-07 2.2,1.79086089 2.2,4 L3.2,4 C3.2,2.34314567 3.81102123,0.999999681 5.5,1 C7.18897877,1.00000032 7.80000001,2.34314567 7.80000001,4 L8.8,4 Z M1.99201702,4 C0.891856397,4 0,4.88670635 0,5.99810135 L0,10.0018986 C0,11.1054196 0.900176167,12 1.99201702,12 L9.00798298,12 C10.1081436,12 11,11.1132936 11,10.0018986 L11,5.99810135 C11,4.89458045 10.0998238,4 9.00798298,4 L1.99201702,4 Z M1.99754465,5 C1.44661595,5 1,5.45097518 1,5.99077797 L1,10.009222 C1,10.5564136 1.4463114,11 1.99754465,11 L9.00245535,11 C9.55338405,11 10,10.5490248 10,10.009222 L10,5.99077797 C10,5.44358641 9.5536886,5 9.00245535,5 L1.99754465,5 Z M1.99754465,5" style="fill:#3b6faa" transform="translate(9,9)"></g></svg>')));
|
100
|
+
form.append($('<div/>').addClass('card_name_container')
|
101
|
+
.append($('<input/>').attr('id', 'card_name').attr('type', 'text').attr('autocomplete', 'off').attr('autocorrect', 'off').attr('spellcheck', 'off').attr('autocapitalize', 'on').attr('placeholder', 'Name on card')));
|
102
|
+
form.append($('<div/>').addClass('card_zip_container')
|
103
|
+
.append($('<input/>').attr('id', 'card_zip').attr('type', 'tel').attr('autocomplete', 'off').attr('autocorrect', 'off').attr('spellcheck', 'off').attr('autocapitalize', 'on').attr('placeholder', 'Zip code')));
|
104
|
+
form.append($('<div/>').attr('id', 'payment_message'))
|
105
|
+
form.append($('<p/>').addClass('payment_controls')
|
106
|
+
.append($('<input/>').attr('type', 'button').attr('id', 'cancel_payment_btn').val('Cancel' ).click(function(e) { that.print(); })).append(' ')
|
107
|
+
.append($('<input/>').attr('type', 'submit').attr('id', 'save_payment_btn').val('Save' ))
|
108
|
+
);
|
109
|
+
|
110
|
+
$('#payment_method_container').empty().append(form);
|
111
|
+
|
112
|
+
$('#stripe_form .card_number_container input').payment('formatCardNumber');
|
113
|
+
$('#stripe_form .card_exp_container input').payment('formatCardExpiry');
|
114
|
+
$('#stripe_form .card_cvc_container input').payment('formatCardCVC');
|
115
|
+
},
|
116
|
+
|
117
|
+
update: function()
|
118
|
+
{
|
119
|
+
var that = this;
|
120
|
+
var info = {
|
121
|
+
number: $('#card_number').val(),
|
122
|
+
exp: $('#card_exp').val(),
|
123
|
+
cvc: $('#card_cvc').val(),
|
124
|
+
name: $('card_name').val(),
|
125
|
+
address_zip: $('card_zip').val()
|
126
|
+
};
|
127
|
+
var exp = info.exp.split('/');
|
128
|
+
var m = exp.length > 0 ? exp[0] : '';
|
129
|
+
var y = exp.length > 1 ? exp[1] : '';
|
130
|
+
var error = false;
|
131
|
+
if (!$.payment.validateCardNumber(info.number)) error = "Invalid card number.";
|
132
|
+
if (!$.payment.validateCardExpiry(m, y)) error = "Invalid expiration date.";
|
133
|
+
if (!$.payment.validateCardCVC(info.cvc)) error = "Invalid CVC.";
|
134
|
+
if (error) { $('#payment_message').html("<p class='note error'>" + error + "</p>"); return; }
|
135
|
+
|
136
|
+
$('#save_payment_btn').attr('disabled', 'true').val('Saving card...');
|
137
|
+
Stripe.setPublishableKey(that.stripe_key);
|
138
|
+
Stripe.card.createToken(info, function(status, resp) {
|
139
|
+
if (resp.error)
|
140
|
+
{
|
141
|
+
$('#save_payment_btn').attr('disabled', 'false').val('Save Payment Method');
|
142
|
+
$('#payment_message').html("<p class='note error'>" + resp.error.message + "</p>");
|
143
|
+
}
|
144
|
+
else
|
145
|
+
{
|
146
|
+
that.card_brand = resp.card.brand;
|
147
|
+
that.card_last4 = resp.card.last4;
|
148
|
+
$.ajax({
|
149
|
+
url: '/checkout/stripe-details',
|
150
|
+
type: 'put',
|
151
|
+
data: { token: resp.id, card: resp.card },
|
152
|
+
success: function(resp2) {
|
153
|
+
if (resp2.success)
|
154
|
+
{
|
155
|
+
that.customer_id = resp2.customer_id;
|
156
|
+
that.print();
|
157
|
+
//that.cc.print_ready_message();
|
158
|
+
}
|
159
|
+
if (resp2.error) $('#payment_message').html("<p class='note error'>" + resp2.error + "</p>");
|
160
|
+
}
|
161
|
+
});
|
162
|
+
}
|
163
|
+
});
|
164
|
+
},
|
165
|
+
|
166
|
+
ready: function()
|
167
|
+
{
|
168
|
+
var that = this;
|
169
|
+
if (that.ic.invoice.total <= 0.00) return true;
|
170
|
+
if (!that.customer_id ) return false;
|
171
|
+
if (!that.card_brand ) return false;
|
172
|
+
if (!that.card_last4 ) return false;
|
173
|
+
return true;
|
174
|
+
}
|
175
|
+
};
|
@@ -0,0 +1,464 @@
|
|
1
|
+
require 'authorize_net'
|
2
|
+
|
3
|
+
module Caboose
|
4
|
+
class CheckoutController < Caboose::ApplicationController
|
5
|
+
|
6
|
+
before_filter :ensure_line_items, :only => [:step_one, :step_two]
|
7
|
+
protect_from_forgery
|
8
|
+
|
9
|
+
def ensure_line_items
|
10
|
+
redirect_to '/checkout/empty' if @invoice.line_items.empty?
|
11
|
+
end
|
12
|
+
|
13
|
+
# @route GET /checkout/json
|
14
|
+
def invoice_json
|
15
|
+
render :json => @invoice.as_json(
|
16
|
+
:include => [
|
17
|
+
:customer,
|
18
|
+
:shipping_address,
|
19
|
+
:billing_address,
|
20
|
+
:invoice_transactions,
|
21
|
+
{
|
22
|
+
:line_items => {
|
23
|
+
:include => {
|
24
|
+
:variant => {
|
25
|
+
:include => [
|
26
|
+
{ :product_images => { :methods => :urls }},
|
27
|
+
{ :product => { :include => { :product_images => { :methods => :urls }}}}
|
28
|
+
],
|
29
|
+
:methods => :title
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
33
|
+
},
|
34
|
+
{ :invoice_packages => { :include => [:shipping_package, :shipping_method] }},
|
35
|
+
{ :discounts => { :include => :gift_card }}
|
36
|
+
]
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
# @route GET /checkout/stripe/json
|
41
|
+
def stripe_json
|
42
|
+
sc = @site.store_config
|
43
|
+
u = logged_in_user
|
44
|
+
render :json => {
|
45
|
+
:stripe_key => sc.stripe_publishable_key.strip,
|
46
|
+
:customer_id => u.stripe_customer_id,
|
47
|
+
:card_last4 => u.card_last4,
|
48
|
+
:card_brand => u.card_brand,
|
49
|
+
:card_exp_month => u.card_exp_month,
|
50
|
+
:card_exp_year => u.card_exp_year
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
#===========================================================================
|
55
|
+
|
56
|
+
# Step 1 - Login or register
|
57
|
+
# @route GET /checkout
|
58
|
+
def index
|
59
|
+
if logged_in?
|
60
|
+
if @invoice.customer_id.nil?
|
61
|
+
@invoice.customer_id = logged_in_user.id
|
62
|
+
@invoice.save
|
63
|
+
end
|
64
|
+
#redirect_to '/checkout/addresses'
|
65
|
+
#return
|
66
|
+
|
67
|
+
@invoice.verify_invoice_packages
|
68
|
+
|
69
|
+
# See if any there are any empty invoice packages
|
70
|
+
#@invoice.invoice_packages.each do |op|
|
71
|
+
# count = 0
|
72
|
+
# @invoice.line_items.each do |li|
|
73
|
+
# count = count + 1 if li.invoice_package_id == op.id
|
74
|
+
# end
|
75
|
+
# op.destroy if count == 0
|
76
|
+
#end
|
77
|
+
#
|
78
|
+
## See if any line items aren't associated with an invoice package
|
79
|
+
#line_items_attached = true
|
80
|
+
#@invoice.line_items.each do |li|
|
81
|
+
# line_items_attached = false if li.invoice_package_id.nil?
|
82
|
+
#end
|
83
|
+
#
|
84
|
+
#ops = @invoice.invoice_packages
|
85
|
+
#if ops.count == 0 || !line_items_attached
|
86
|
+
# @invoice.calculate
|
87
|
+
# LineItem.where(:invoice_id => @invoice.id).update_all(:invoice_package_id => nil)
|
88
|
+
# InvoicePackage.where(:invoice_id => @invoice.id).destroy_all
|
89
|
+
# InvoicePackage.create_for_invoice(@invoice)
|
90
|
+
#end
|
91
|
+
|
92
|
+
#render :file => "caboose/checkout/checkout_#{@site.store_config.pp_name}"
|
93
|
+
render :file => "caboose/checkout/checkout"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# Step 3 - Shipping method
|
98
|
+
# @route GET /checkout/shipping/json
|
99
|
+
def shipping_json
|
100
|
+
render :json => { :error => 'Not logged in.' } and return if !logged_in?
|
101
|
+
render :json => { :error => 'No shippable items.' } and return if !@invoice.has_shippable_items?
|
102
|
+
render :json => { :error => 'Empty shipping address.' } and return if @invoice.shipping_address.nil?
|
103
|
+
|
104
|
+
@invoice.calculate
|
105
|
+
|
106
|
+
#ops = @invoice.invoice_packages
|
107
|
+
#if params[:recalculate_invoice_packages] || ops.count == 0
|
108
|
+
# # Remove any invoice packages
|
109
|
+
# LineItem.where(:invoice_id => @invoice.id).update_all(:invoice_package_id => nil)
|
110
|
+
# InvoicePackage.where(:invoice_id => @invoice.id).destroy_all
|
111
|
+
#
|
112
|
+
# # Calculate what shipping packages we'll need
|
113
|
+
# InvoicePackage.create_for_invoice(@invoice)
|
114
|
+
#end
|
115
|
+
|
116
|
+
# Now get the rates for those packages
|
117
|
+
rates = ShippingCalculator.rates(@invoice)
|
118
|
+
render :json => rates
|
119
|
+
end
|
120
|
+
|
121
|
+
# Step 5 - Update Stripe Details
|
122
|
+
# @route PUT /checkout/stripe-details
|
123
|
+
def update_stripe_details
|
124
|
+
render :json => false and return if !logged_in?
|
125
|
+
|
126
|
+
sc = @site.store_config
|
127
|
+
Stripe.api_key = sc.stripe_secret_key.strip
|
128
|
+
|
129
|
+
u = logged_in_user
|
130
|
+
|
131
|
+
c = nil
|
132
|
+
if u.stripe_customer_id
|
133
|
+
c = Stripe::Customer.retrieve(u.stripe_customer_id)
|
134
|
+
begin
|
135
|
+
c.source = params[:token]
|
136
|
+
c.save
|
137
|
+
rescue
|
138
|
+
c = nil
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
if c.nil?
|
143
|
+
c = Stripe::Customer.create(
|
144
|
+
:source => params[:token],
|
145
|
+
:email => u.email,
|
146
|
+
:metadata => { :user_id => u.id }
|
147
|
+
)
|
148
|
+
end
|
149
|
+
|
150
|
+
u.stripe_customer_id = c.id
|
151
|
+
u.card_last4 = params[:card][:last4]
|
152
|
+
u.card_brand = params[:card][:brand]
|
153
|
+
u.card_exp_month = params[:card][:exp_month]
|
154
|
+
u.card_exp_year = params[:card][:exp_year]
|
155
|
+
u.save
|
156
|
+
|
157
|
+
render :json => {
|
158
|
+
:success => true,
|
159
|
+
:customer_id => u.stripe_customer_id
|
160
|
+
}
|
161
|
+
end
|
162
|
+
|
163
|
+
# @route POST /checkout/confirm
|
164
|
+
def confirm
|
165
|
+
render :json => { :error => 'Not logged in.' } and return if !logged_in?
|
166
|
+
#render :json => { :error => 'Invalid billing address.' } and return if @invoice.billing_address.nil?
|
167
|
+
render :json => { :error => 'Invalid shipping address.' } and return if @invoice.has_shippable_items? && @invoice.shipping_address.nil?
|
168
|
+
render :json => { :error => 'Invalid shipping methods.' } and return if @invoice.has_shippable_items? && @invoice.has_empty_shipping_methods?
|
169
|
+
|
170
|
+
resp = Caboose::StdClass.new
|
171
|
+
sc = @site.store_config
|
172
|
+
|
173
|
+
# Make sure all the variants still exist
|
174
|
+
@invoice.line_items.each do |li|
|
175
|
+
v = Variant.where(:id => li.variant_id).first
|
176
|
+
if v.nil? || v.status == 'Deleted'
|
177
|
+
render :json => { :error => 'One or more of the products you are purchasing are no longer available.' }
|
178
|
+
return
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
error = false
|
183
|
+
requires_payment = @invoice.line_items.count > 0 && @invoice.total > 0 && @invoice.payment_terms == Invoice::PAYMENT_TERMS_PIA
|
184
|
+
if requires_payment
|
185
|
+
|
186
|
+
ot = nil
|
187
|
+
case sc.pp_name
|
188
|
+
when StoreConfig::PAYMENT_PROCESSOR_AUTHNET
|
189
|
+
|
190
|
+
when StoreConfig::PAYMENT_PROCESSOR_STRIPE
|
191
|
+
Stripe.api_key = sc.stripe_secret_key.strip
|
192
|
+
begin
|
193
|
+
c = Stripe::Charge.create(
|
194
|
+
:amount => (@invoice.total * 100).to_i,
|
195
|
+
:currency => 'usd',
|
196
|
+
:customer => logged_in_user.stripe_customer_id,
|
197
|
+
:capture => false,
|
198
|
+
:metadata => { :invoice_id => @invoice.id },
|
199
|
+
:statement_descriptor => "Invoice ##{@invoice.id}"
|
200
|
+
)
|
201
|
+
rescue Exception => ex
|
202
|
+
render :json => { :error => ex.message }
|
203
|
+
return
|
204
|
+
end
|
205
|
+
ot = Caboose::InvoiceTransaction.create(
|
206
|
+
:invoice_id => @invoice.id,
|
207
|
+
:transaction_id => c.id,
|
208
|
+
:transaction_type => c.captured ? Caboose::InvoiceTransaction::TYPE_AUTHCAP : Caboose::InvoiceTransaction::TYPE_AUTHORIZE,
|
209
|
+
:payment_processor => sc.pp_name,
|
210
|
+
:amount => c.amount/100.0,
|
211
|
+
:date_processed => DateTime.now.utc,
|
212
|
+
:success => c.status == 'succeeded'
|
213
|
+
)
|
214
|
+
end
|
215
|
+
|
216
|
+
if !ot.success
|
217
|
+
render :json => { :error => error }
|
218
|
+
return
|
219
|
+
else
|
220
|
+
@invoice.financial_status = Invoice::FINANCIAL_STATUS_AUTHORIZED
|
221
|
+
@invoice.take_gift_card_funds
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
@invoice.status = Invoice::STATUS_PENDING
|
226
|
+
@invoice.invoice_number = @site.store_config.next_invoice_number
|
227
|
+
|
228
|
+
# Send out emails
|
229
|
+
begin
|
230
|
+
InvoicesMailer.configure_for_site(@site.id).customer_new_invoice(@invoice).deliver
|
231
|
+
InvoicesMailer.configure_for_site(@site.id).fulfillment_new_invoice(@invoice).deliver
|
232
|
+
rescue
|
233
|
+
puts "=================================================================="
|
234
|
+
puts "Error sending out invoice confirmation emails for invoice ID #{@invoice.id}"
|
235
|
+
puts "=================================================================="
|
236
|
+
end
|
237
|
+
|
238
|
+
# Emit invoice event
|
239
|
+
Caboose.plugin_hook('invoice_authorized', @invoice) if @invoice.total > 0
|
240
|
+
|
241
|
+
# Save the invoice
|
242
|
+
@invoice.save
|
243
|
+
|
244
|
+
# Decrement quantities of variants
|
245
|
+
@invoice.decrement_quantities
|
246
|
+
|
247
|
+
# Clear the cart and re-initialize
|
248
|
+
session[:cart_id] = nil
|
249
|
+
init_cart
|
250
|
+
|
251
|
+
resp.success = true
|
252
|
+
resp.redirect = '/checkout/thanks'
|
253
|
+
render :json => resp
|
254
|
+
end
|
255
|
+
|
256
|
+
# @route GET /checkout/thanks
|
257
|
+
def thanks
|
258
|
+
@logged_in_user = logged_in_user
|
259
|
+
|
260
|
+
# Find the last invoice for the user
|
261
|
+
@last_invoice = Invoice.where(:customer_id => @logged_in_user.id).reorder("id desc").limit(1).first
|
262
|
+
add_ga_event('Ecommerce', 'Checkout', 'Payment', (@last_invoice.total*100).to_i)
|
263
|
+
end
|
264
|
+
|
265
|
+
#===========================================================================
|
266
|
+
|
267
|
+
# @route GET /checkout/state-options
|
268
|
+
def state_options
|
269
|
+
options = Caboose::States.all.collect { |abbr, state| { 'value' => abbr, 'text' => abbr }}
|
270
|
+
render :json => options
|
271
|
+
end
|
272
|
+
|
273
|
+
# @route GET /checkout/total
|
274
|
+
def verify_total
|
275
|
+
total = 0.00
|
276
|
+
if logged_in?
|
277
|
+
@invoice.calculate
|
278
|
+
total = @invoice.total
|
279
|
+
end
|
280
|
+
render :json => total.to_f
|
281
|
+
end
|
282
|
+
|
283
|
+
# @route GET /checkout/address
|
284
|
+
def address
|
285
|
+
render :json => {
|
286
|
+
:shipping_address => @invoice.shipping_address,
|
287
|
+
:billing_address => @invoice.billing_address
|
288
|
+
}
|
289
|
+
end
|
290
|
+
|
291
|
+
# @route PUT /checkout/addresses
|
292
|
+
def update_addresses
|
293
|
+
|
294
|
+
# Grab or create addresses
|
295
|
+
shipping_address = if @invoice.shipping_address then @invoice.shipping_address else Address.new end
|
296
|
+
billing_address = if @invoice.billing_address then @invoice.billing_address else Address.new end
|
297
|
+
|
298
|
+
has_shippable_items = @invoice.has_shippable_items?
|
299
|
+
|
300
|
+
# Shipping address
|
301
|
+
if has_shippable_items
|
302
|
+
shipping_address.first_name = params[:shipping][:first_name]
|
303
|
+
shipping_address.last_name = params[:shipping][:last_name]
|
304
|
+
shipping_address.company = params[:shipping][:company]
|
305
|
+
shipping_address.address1 = params[:shipping][:address1]
|
306
|
+
shipping_address.address2 = params[:shipping][:address2]
|
307
|
+
shipping_address.city = params[:shipping][:city]
|
308
|
+
shipping_address.state = params[:shipping][:state]
|
309
|
+
shipping_address.zip = params[:shipping][:zip]
|
310
|
+
end
|
311
|
+
|
312
|
+
# Billing address
|
313
|
+
if has_shippable_items && params[:use_as_billing]
|
314
|
+
billing_address.update_attributes(shipping_address.attributes)
|
315
|
+
else
|
316
|
+
billing_address.first_name = params[:billing][:first_name]
|
317
|
+
billing_address.last_name = params[:billing][:last_name]
|
318
|
+
billing_address.company = params[:billing][:company]
|
319
|
+
billing_address.address1 = params[:billing][:address1]
|
320
|
+
billing_address.address2 = params[:billing][:address2]
|
321
|
+
billing_address.city = params[:billing][:city]
|
322
|
+
billing_address.state = params[:billing][:state]
|
323
|
+
billing_address.zip = params[:billing][:zip]
|
324
|
+
end
|
325
|
+
|
326
|
+
# Save address info; generate ids
|
327
|
+
render :json => { :success => false, :errors => shipping_address.errors.full_messages, :address => 'shipping' } and return if has_shippable_items && !shipping_address.save
|
328
|
+
render :json => { :success => false, :errors => billing_address.errors.full_messages, :address => 'billing' } and return if !billing_address.save
|
329
|
+
|
330
|
+
# Associate address info with invoice
|
331
|
+
@invoice.shipping_address_id = shipping_address.id
|
332
|
+
@invoice.billing_address_id = billing_address.id
|
333
|
+
|
334
|
+
#render :json => { :redirect => 'checkout/shipping' }
|
335
|
+
render :json => { :success => @invoice.save, :errors => @invoice.errors.full_messages }
|
336
|
+
end
|
337
|
+
|
338
|
+
# @route PUT /checkout/shipping-address
|
339
|
+
def update_shipping_address
|
340
|
+
resp = Caboose::StdClass.new
|
341
|
+
|
342
|
+
# Grab or create addresses
|
343
|
+
sa = @invoice.shipping_address
|
344
|
+
if sa.nil?
|
345
|
+
sa = Address.create
|
346
|
+
@invoice.shipping_address_id = sa.id
|
347
|
+
@invoice.save
|
348
|
+
end
|
349
|
+
|
350
|
+
save = true
|
351
|
+
recalc_shipping = false
|
352
|
+
params.each do |name, value|
|
353
|
+
case name
|
354
|
+
when 'address1' then recalc_shipping = true if sa.address1 != value
|
355
|
+
when 'address2' then recalc_shipping = true if sa.address2 != value
|
356
|
+
when 'city' then recalc_shipping = true if sa.city != value
|
357
|
+
when 'state' then recalc_shipping = true if sa.state != value
|
358
|
+
when 'zip' then recalc_shipping = true if sa.zip != value
|
359
|
+
end
|
360
|
+
case name
|
361
|
+
when 'name' then sa.name = value
|
362
|
+
when 'first_name' then sa.first_name = value
|
363
|
+
when 'last_name' then sa.last_name = value
|
364
|
+
when 'street' then sa.street = value
|
365
|
+
when 'address1' then sa.address1 = value
|
366
|
+
when 'address2' then sa.address2 = value
|
367
|
+
when 'company' then sa.company = value
|
368
|
+
when 'city' then sa.city = value
|
369
|
+
when 'state' then sa.state = value
|
370
|
+
when 'province' then sa.province = value
|
371
|
+
when 'province_code' then sa.province_code = value
|
372
|
+
when 'zip' then sa.zip = value
|
373
|
+
when 'country' then sa.country = value
|
374
|
+
when 'country_code' then sa.country_code = value
|
375
|
+
when 'phone' then sa.phone = value
|
376
|
+
end
|
377
|
+
end
|
378
|
+
if recalc_shipping
|
379
|
+
@invoice.invoice_packages.each do |op|
|
380
|
+
op.shipping_method_id = nil
|
381
|
+
op.total = nil
|
382
|
+
op.save
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
386
|
+
resp.success = save && sa.save
|
387
|
+
render :json => resp
|
388
|
+
end
|
389
|
+
|
390
|
+
# @route PUT /checkout/billing-address
|
391
|
+
def update_billing_address
|
392
|
+
|
393
|
+
# Grab or create addresses
|
394
|
+
ba = @invoice.billing_address
|
395
|
+
if ba.nil?
|
396
|
+
ba = Address.create
|
397
|
+
@invoice.billing_address_id = ba.id
|
398
|
+
@invoice.save
|
399
|
+
end
|
400
|
+
|
401
|
+
ba.first_name = params[:first_name]
|
402
|
+
ba.last_name = params[:last_name]
|
403
|
+
ba.company = params[:company]
|
404
|
+
ba.address1 = params[:address1]
|
405
|
+
ba.address2 = params[:address2]
|
406
|
+
ba.city = params[:city]
|
407
|
+
ba.state = params[:state]
|
408
|
+
ba.zip = params[:zip]
|
409
|
+
ba.save
|
410
|
+
|
411
|
+
render :json => { :success => true }
|
412
|
+
end
|
413
|
+
|
414
|
+
# @route POST /checkout/attach-user
|
415
|
+
def attach_user
|
416
|
+
render :json => { :success => false, :errors => ['User is not logged in'] } and return if !logged_in?
|
417
|
+
@invoice.customer_id = logged_in_user.id
|
418
|
+
#Caboose.log("Attaching user to invoice: customer_id = #{@invoice.customer_id}")
|
419
|
+
render :json => { :success => @invoice.save, :errors => @invoice.errors.full_messages, :logged_in => logged_in? }
|
420
|
+
end
|
421
|
+
|
422
|
+
# @route POST /checkout/guest
|
423
|
+
def attach_guest
|
424
|
+
resp = Caboose::StdClass.new
|
425
|
+
email = params[:email]
|
426
|
+
|
427
|
+
if email != params[:confirm_email]
|
428
|
+
resp.error = "Emails do not match."
|
429
|
+
elsif Caboose::User.where(:email => email, :is_guest => false).exists?
|
430
|
+
resp.error = "A user with that email address already exists."
|
431
|
+
else
|
432
|
+
user = Caboose::User.where(:email => email, :is_guest => true).first
|
433
|
+
if user.nil?
|
434
|
+
user = Caboose::User.create(:email => email)
|
435
|
+
user.is_guest = true
|
436
|
+
user.save
|
437
|
+
user = Caboose::User.where(:email => email).first
|
438
|
+
end
|
439
|
+
@invoice.customer_id = user.id
|
440
|
+
login_user(user)
|
441
|
+
|
442
|
+
if !@invoice.valid?
|
443
|
+
resp.errors = @invoice.errors.full_messages
|
444
|
+
else
|
445
|
+
@invoice.save
|
446
|
+
resp.redirect = '/checkout/addresses'
|
447
|
+
end
|
448
|
+
end
|
449
|
+
render :json => resp
|
450
|
+
end
|
451
|
+
|
452
|
+
# @route PUT /checkout/shipping
|
453
|
+
def update_shipping
|
454
|
+
op = InvoicePackage.find(params[:invoice_package_id])
|
455
|
+
op.shipping_method_id = params[:shipping_method_id]
|
456
|
+
op.total = params[:total]
|
457
|
+
op.save
|
458
|
+
op.invoice.calculate
|
459
|
+
|
460
|
+
render :json => { :success => true }
|
461
|
+
end
|
462
|
+
|
463
|
+
end
|
464
|
+
end
|
@@ -279,7 +279,8 @@ module Caboose
|
|
279
279
|
Invoice::STATUS_CART,
|
280
280
|
Invoice::STATUS_PENDING,
|
281
281
|
Invoice::STATUS_READY_TO_SHIP,
|
282
|
-
Invoice::STATUS_SHIPPED,
|
282
|
+
Invoice::STATUS_SHIPPED,
|
283
|
+
Invoice::STATUS_PAID,
|
283
284
|
Invoice::STATUS_CANCELED
|
284
285
|
]
|
285
286
|
options = statuses.collect{ |s| { 'text' => s.capitalize, 'value' => s }}
|
@@ -56,10 +56,90 @@ module Caboose
|
|
56
56
|
|
57
57
|
when 'stripe'
|
58
58
|
# TODO: Implement manual invoice payment for stripe
|
59
|
-
|
60
59
|
end
|
61
60
|
render :layout => false
|
62
61
|
end
|
62
|
+
|
63
|
+
# @route POST /my-account/confirm
|
64
|
+
def confirm
|
65
|
+
Caboose::log(params)
|
66
|
+
sc = @site.store_config
|
67
|
+
@invoice = Invoice.find(params[:id])
|
68
|
+
|
69
|
+
# Make sure all the variants still exist
|
70
|
+
@invoice.line_items.each do |li|
|
71
|
+
v = Variant.where(:id => li.variant_id).first
|
72
|
+
if v.nil? || v.status == 'Deleted'
|
73
|
+
render :json => { :error => 'One or more of the products you are purchasing are no longer available.' }
|
74
|
+
return
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
error = false
|
79
|
+
requires_payment = @invoice.line_items.count > 0 && @invoice.total > 0
|
80
|
+
if requires_payment
|
81
|
+
ot = nil
|
82
|
+
|
83
|
+
Stripe.api_key = sc.stripe_secret_key.strip
|
84
|
+
begin
|
85
|
+
c = Stripe::Charge.create(
|
86
|
+
:amount => (@invoice.total * 100).to_i,
|
87
|
+
:currency => 'usd',
|
88
|
+
:customer => logged_in_user.stripe_customer_id,
|
89
|
+
:capture => false,
|
90
|
+
:metadata => { :invoice_id => @invoice.id },
|
91
|
+
:statement_descriptor => "Invoice ##{@invoice.id}"
|
92
|
+
)
|
93
|
+
rescue Exception => ex
|
94
|
+
render :json => { :error => ex.message }
|
95
|
+
return
|
96
|
+
end
|
97
|
+
ot = Caboose::InvoiceTransaction.create(
|
98
|
+
:invoice_id => @invoice.id,
|
99
|
+
:transaction_id => c.id,
|
100
|
+
:transaction_type => c.captured ? Caboose::InvoiceTransaction::TYPE_AUTHCAP : Caboose::InvoiceTransaction::TYPE_AUTHORIZE,
|
101
|
+
:payment_processor => sc.pp_name,
|
102
|
+
:amount => c.amount/100.0,
|
103
|
+
:date_processed => DateTime.now.utc,
|
104
|
+
:success => c.status == 'succeeded'
|
105
|
+
)
|
106
|
+
|
107
|
+
if !ot.success
|
108
|
+
render :json => { :error => error }
|
109
|
+
return
|
110
|
+
else
|
111
|
+
capture_resp = @invoice.capture_funds
|
112
|
+
if capture_resp.success == true
|
113
|
+
@invoice.take_gift_card_funds
|
114
|
+
@invoice.status = Caboose::Invoice::STATUS_PAID
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
@invoice.invoice_number = @site.store_config.next_invoice_number
|
120
|
+
|
121
|
+
# Send out emails
|
122
|
+
begin
|
123
|
+
InvoicesMailer.configure_for_site(@site.id).customer_new_invoice(@invoice).deliver
|
124
|
+
InvoicesMailer.configure_for_site(@site.id).fulfillment_new_invoice(@invoice).deliver
|
125
|
+
rescue
|
126
|
+
puts "=================================================================="
|
127
|
+
puts "Error sending out invoice confirmation emails for invoice ID #{@invoice.id}"
|
128
|
+
puts "=================================================================="
|
129
|
+
end
|
130
|
+
|
131
|
+
# Save the invoice
|
132
|
+
@invoice.save
|
133
|
+
|
134
|
+
# Decrement quantities of variants
|
135
|
+
@invoice.decrement_quantities
|
136
|
+
|
137
|
+
render :json => {
|
138
|
+
:success => true,
|
139
|
+
:message => "Thank you for your payment!"
|
140
|
+
}
|
141
|
+
return
|
142
|
+
end
|
63
143
|
|
64
144
|
# @route GET /my-account/invoices/:id/json
|
65
145
|
def invoice_json
|
@@ -19,9 +19,9 @@ module Caboose
|
|
19
19
|
#end
|
20
20
|
|
21
21
|
# Sends a confirmation email to the customer about a new invoice
|
22
|
-
def customer_new_invoice(invoice)
|
22
|
+
def customer_new_invoice(invoice)
|
23
23
|
@invoice = invoice
|
24
|
-
mail(:to => invoice.customer.email, :subject => 'Thank you for your
|
24
|
+
mail(:to => invoice.customer.email, :subject => 'Thank you for your order!')
|
25
25
|
end
|
26
26
|
|
27
27
|
# Sends a notification email to the fulfillment dept about a new invoice
|
@@ -55,6 +55,7 @@ module Caboose
|
|
55
55
|
STATUS_CANCELED = 'canceled'
|
56
56
|
STATUS_READY_TO_SHIP = 'ready to ship'
|
57
57
|
STATUS_SHIPPED = 'shipped'
|
58
|
+
STATUS_PAID = 'paid'
|
58
59
|
STATUS_TESTING = 'testing'
|
59
60
|
|
60
61
|
# New
|
@@ -89,6 +90,7 @@ module Caboose
|
|
89
90
|
scope :pending , where('status = ?', 'pending')
|
90
91
|
scope :canceled , where('status = ?', 'canceled')
|
91
92
|
scope :shipped , where('status = ?', 'shipped')
|
93
|
+
scope :paid , where('status = ?', 'paid')
|
92
94
|
scope :test , where('status = ?', 'testing')
|
93
95
|
|
94
96
|
scope :authorized , where('financial_status = ?', 'authorized')
|
@@ -101,7 +103,7 @@ module Caboose
|
|
101
103
|
#
|
102
104
|
|
103
105
|
validates :status, :inclusion => {
|
104
|
-
:in => ['cart', 'pending', 'canceled', 'ready to ship', 'shipped', 'testing'],
|
106
|
+
:in => ['cart', 'pending', 'canceled', 'ready to ship', 'shipped', 'paid', 'testing'],
|
105
107
|
:message => "%{value} is not a valid status. Must be either 'pending' or 'shipped'"
|
106
108
|
}
|
107
109
|
|
@@ -15,8 +15,11 @@ store_config = @invoice.site.store_config
|
|
15
15
|
<p><input type='button' value='< Back' class='btn' onclick="window.location='/my-account/invoices';" /></p>
|
16
16
|
|
17
17
|
<% content_for :caboose_js do %>
|
18
|
+
<%= javascript_include_tag 'https://js.stripe.com/v2/' %>
|
19
|
+
<%= javascript_include_tag 'caboose/jquery.payment' %>
|
18
20
|
<%= javascript_include_tag 'caboose/model/all' %>
|
19
21
|
<%= javascript_include_tag 'caboose/my_account_edit_invoice' %>
|
22
|
+
<%= javascript_include_tag 'caboose/my_account_payment_method_controller' %>
|
20
23
|
<script type='text/javascript'>
|
21
24
|
|
22
25
|
var controller = false;
|
@@ -32,4 +35,20 @@ $(document).ready(function() {
|
|
32
35
|
|
33
36
|
<% content_for :caboose_css do %>
|
34
37
|
<%= stylesheet_link_tag 'caboose/my_account_edit_invoice' %>
|
38
|
+
<style type='text/css'>
|
39
|
+
.stripe_form { width: 100%; }
|
40
|
+
.stripe_form .card_number_container { position: relative; width: 100%; } .stripe_form .card_number_container input { padding-left: 30px; height: 37px; font-size: 15px; width: 100%; border-color: #b9b9b9; border-style: solid; border-width: 1px 1px 0px 1px; }
|
41
|
+
.stripe_form .card_exp_container { position: relative; width: 50% !important; float: left; } .stripe_form .card_exp_container input { padding-left: 30px; height: 37px; font-size: 15px; width: 100%; border-color: #b9b9b9; border-style: solid; border-width: 1px 1px 0px 1px; }
|
42
|
+
.stripe_form .card_cvc_container { position: relative; width: 50%; float: left; } .stripe_form .card_cvc_container input { padding-left: 30px; height: 37px; font-size: 15px; width: 100%; border-color: #b9b9b9; border-style: solid; border-width: 1px 1px 0px 0px; }
|
43
|
+
.stripe_form .card_name_container { position: relative; width: 50%; float: left; } .stripe_form .card_name_container input { padding-left: 10px; height: 37px !important; font-size: 15px; width: 100%; border-color: #b9b9b9; border-style: solid; border-width: 1px 0px 1px 1px; }
|
44
|
+
.stripe_form .card_zip_container { position: relative; width: 50%; float: left; margin-bottom: 4px; } .stripe_form .card_zip_container input { padding-left: 10px; height: 37px; font-size: 15px; width: 100%; border-color: #b9b9b9; border-style: solid; border-width: 1px 1px 1px 0px; }
|
45
|
+
|
46
|
+
.stripe_form .card_number_container .icon { position: absolute; top: 3px; left: 1px; transform-origin: 50% 50% 0; pointer-events: none; }
|
47
|
+
.stripe_form .card_exp_container .icon { position: absolute; top: 3px; left: 1px; transform-origin: 50% 50% 0; pointer-events: none; }
|
48
|
+
.stripe_form .card_cvc_container .icon { position: absolute; top: 3px; left: 1px; transform-origin: 50% 50% 0; pointer-events: none; }
|
49
|
+
|
50
|
+
.stripe_form .note { width: 100%; margin-bottom: 10px !important; text-align: center; }
|
51
|
+
.stripe_form .payment_controls { clear: left; margin-top: 4px !important; }
|
52
|
+
|
53
|
+
</style>
|
35
54
|
<% end %>
|
data/lib/caboose/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: caboose-cms
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.65
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- William Barry
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-09-
|
11
|
+
date: 2016-09-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pg
|
@@ -600,6 +600,7 @@ files:
|
|
600
600
|
- app/assets/javascripts/caboose/model/pager.js
|
601
601
|
- app/assets/javascripts/caboose/model/s3.js
|
602
602
|
- app/assets/javascripts/caboose/my_account_edit_invoice.js
|
603
|
+
- app/assets/javascripts/caboose/my_account_payment_method_controller.js
|
603
604
|
- app/assets/javascripts/caboose/product.js
|
604
605
|
- app/assets/javascripts/caboose/product_new.js
|
605
606
|
- app/assets/javascripts/caboose/product_old.js
|
@@ -743,6 +744,7 @@ files:
|
|
743
744
|
- app/assets/templates/caboose/product/images.jst.ejs
|
744
745
|
- app/assets/templates/caboose/product/images_old.jst.ejs
|
745
746
|
- app/assets/templates/caboose/product/options.jst.ejs
|
747
|
+
- app/controllers/caboose/#checkout_controller.rb#
|
746
748
|
- app/controllers/caboose/ab_options_controller.rb
|
747
749
|
- app/controllers/caboose/ab_variants_controller.rb
|
748
750
|
- app/controllers/caboose/admin_controller.rb
|