spree_frontend 3.7.14.1 → 4.0.0.beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/app/assets/javascripts/spree/frontend/checkout/address.js +42 -14
- data/app/assets/javascripts/spree/frontend/checkout/address_book.js +56 -0
- data/app/assets/javascripts/spree/frontend/product.js +54 -39
- data/app/assets/javascripts/spree/frontend.js +4 -1
- data/app/assets/stylesheets/spree/frontend/_variables.scss +1 -1
- data/app/assets/stylesheets/spree/frontend/address_book.scss +8 -0
- data/app/assets/stylesheets/spree/frontend/frontend_bootstrap.css.scss +13 -35
- data/app/assets/stylesheets/spree/frontend.css +1 -0
- data/app/controllers/concerns/spree/checkout/address_book.rb +53 -0
- data/app/controllers/spree/addresses_controller.rb +72 -0
- data/app/controllers/spree/checkout_controller.rb +2 -0
- data/app/controllers/spree/orders_controller.rb +0 -55
- data/app/controllers/spree/products_controller.rb +5 -1
- data/app/controllers/spree/store_controller.rb +1 -1
- data/app/helpers/spree/addresses_helper.rb +36 -0
- data/app/helpers/spree/frontend_helper.rb +16 -15
- data/app/views/kaminari/{twitter-bootstrap-3 → twitter-bootstrap-4}/_first_page.html.erb +2 -2
- data/app/views/kaminari/{twitter-bootstrap-3 → twitter-bootstrap-4}/_gap.html.erb +5 -1
- data/app/views/kaminari/{twitter-bootstrap-3 → twitter-bootstrap-4}/_last_page.html.erb +2 -2
- data/app/views/kaminari/{twitter-bootstrap-3 → twitter-bootstrap-4}/_next_page.html.erb +2 -2
- data/app/views/kaminari/{twitter-bootstrap-3 → twitter-bootstrap-4}/_page.html.erb +8 -2
- data/app/views/kaminari/{twitter-bootstrap-3 → twitter-bootstrap-4}/_paginator.html.erb +1 -1
- data/app/views/kaminari/{twitter-bootstrap-3 → twitter-bootstrap-4}/_prev_page.html.erb +2 -2
- data/app/views/spree/address/_form.html.erb +27 -24
- data/app/views/spree/addresses/_form.html.erb +18 -0
- data/app/views/spree/addresses/destroy.js.erb +2 -0
- data/app/views/spree/addresses/edit.html.erb +23 -0
- data/app/views/spree/addresses/new.html.erb +23 -0
- data/app/views/spree/checkout/_address.html.erb +61 -37
- data/app/views/spree/checkout/_confirm.html.erb +12 -10
- data/app/views/spree/checkout/_delivery.html.erb +27 -15
- data/app/views/spree/checkout/_payment.html.erb +14 -9
- data/app/views/spree/checkout/_summary.html.erb +59 -57
- data/app/views/spree/checkout/edit.html.erb +6 -6
- data/app/views/spree/checkout/payment/_gateway.html.erb +43 -35
- data/app/views/spree/layouts/spree_application.html.erb +5 -2
- data/app/views/spree/orders/_form.html.erb +38 -25
- data/app/views/spree/orders/edit.html.erb +28 -22
- data/app/views/spree/orders/show.html.erb +2 -1
- data/app/views/spree/products/_cart_form.html.erb +28 -26
- data/app/views/spree/products/_product.html.erb +7 -8
- data/app/views/spree/products/_promotions.html.erb +13 -11
- data/app/views/spree/products/_properties.html.erb +10 -3
- data/app/views/spree/products/_thumbnails.html.erb +5 -7
- data/app/views/spree/products/show.html.erb +8 -8
- data/app/views/spree/shared/_filters.html.erb +29 -9
- data/app/views/spree/shared/_header.html.erb +2 -2
- data/app/views/spree/shared/_login_bar.html.erb +9 -3
- data/app/views/spree/shared/_main_nav_bar.html.erb +15 -15
- data/app/views/spree/shared/_nav_bar.html.erb +2 -2
- data/app/views/spree/shared/_order_details.html.erb +143 -89
- data/app/views/spree/shared/_products.html.erb +2 -2
- data/app/views/spree/shared/_search.html.erb +19 -12
- data/app/views/spree/shared/_sidebar.html.erb +1 -1
- data/app/views/spree/shared/_taxonomies.html.erb +7 -3
- data/config/routes.rb +2 -0
- data/lib/spree/frontend/engine.rb +4 -0
- data/lib/spree/frontend.rb +3 -3
- data/spree_frontend.gemspec +4 -3
- metadata +48 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 032eb15c7d9d5a00cb97125d37d91cbb268790c76dd89cb24353f40eb8480212
|
4
|
+
data.tar.gz: d01986aec09bef01b96c731618a44da04905f59e985c00437a80c386ee949baf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 365cddc404a1130ca0588af7d20309095eebcf2c2a4dbb3770b69fa38db9f03bd7b55596b1b53ec0d35c83a32e7c68ffe9b82db292d7d43d0017b55d90b2126c
|
7
|
+
data.tar.gz: 37ad01b825d249d64ef77f4adbdea1fa048aa1206c7882df64be6e97d663e18cd3b121d9fcb4e1fd75c2440d68ce26047ef0cf2f8a01184c4a7a5cf10b61e6b4
|
data/Gemfile
CHANGED
@@ -5,20 +5,48 @@ Spree.ready(function ($) {
|
|
5
5
|
var countryId = getCountryId(region)
|
6
6
|
if (countryId != null) {
|
7
7
|
if (Spree.Checkout[countryId] == null) {
|
8
|
-
$.
|
9
|
-
|
8
|
+
$.ajax({
|
9
|
+
async: false, method: 'GET', url: '/api/v2/storefront/countries/' + countryId + '?include=states', dataType: 'json'
|
10
10
|
}).done(function (data) {
|
11
|
+
var json = data.included; var xStates = []
|
12
|
+
for (var i = 0; i < json.length; i++) {
|
13
|
+
var obj = json[i]; xStates.push({ 'id': obj.id, 'name': obj.attributes.name })
|
14
|
+
}
|
11
15
|
Spree.Checkout[countryId] = {
|
12
|
-
states:
|
13
|
-
states_required: data.states_required
|
16
|
+
states: xStates,
|
17
|
+
states_required: data.data.attributes.states_required,
|
18
|
+
zipcode_required: data.data.attributes.zipcode_required
|
14
19
|
}
|
15
20
|
Spree.fillStates(Spree.Checkout[countryId], region)
|
21
|
+
Spree.toggleZipcode(Spree.Checkout[countryId], region)
|
16
22
|
})
|
17
23
|
} else {
|
18
24
|
Spree.fillStates(Spree.Checkout[countryId], region)
|
25
|
+
Spree.toggleZipcode(Spree.Checkout[countryId], region)
|
19
26
|
}
|
20
27
|
}
|
21
28
|
}
|
29
|
+
|
30
|
+
Spree.toggleZipcode = function (data, region) {
|
31
|
+
var zipcodeRequired = data.zipcode_required
|
32
|
+
var zipcodePara = $('#' + region + 'zipcode')
|
33
|
+
var zipcodeInput = zipcodePara.find('input')
|
34
|
+
var zipcodeSpanRequired = zipcodePara.find('abbr')
|
35
|
+
|
36
|
+
if (zipcodeRequired) {
|
37
|
+
zipcodeInput.prop('required', true)
|
38
|
+
zipcodeSpanRequired.show()
|
39
|
+
// zipcodeInput.prop('disabled', false)
|
40
|
+
// zipcodePara.show()
|
41
|
+
} else {
|
42
|
+
zipcodeInput.val('')
|
43
|
+
zipcodeInput.prop('required', false)
|
44
|
+
zipcodeSpanRequired.hide()
|
45
|
+
// zipcodeInput.prop('disabled', true)
|
46
|
+
// zipcodePara.hide()
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
22
50
|
Spree.fillStates = function (data, region) {
|
23
51
|
var selected, statesWithBlank
|
24
52
|
var statesRequired = data.states_required
|
@@ -26,16 +54,12 @@ Spree.ready(function ($) {
|
|
26
54
|
var statePara = $('#' + region + 'state')
|
27
55
|
var stateSelect = statePara.find('select')
|
28
56
|
var stateInput = statePara.find('input')
|
29
|
-
var stateSpanRequired = statePara.find('
|
57
|
+
var stateSpanRequired = statePara.find('abbr')
|
58
|
+
|
30
59
|
if (states.length > 0) {
|
31
60
|
selected = parseInt(stateSelect.val())
|
32
61
|
stateSelect.html('')
|
33
|
-
statesWithBlank = [
|
34
|
-
{
|
35
|
-
name: '',
|
36
|
-
id: ''
|
37
|
-
}
|
38
|
-
].concat(states)
|
62
|
+
statesWithBlank = [{name: '', id: ''}].concat(states)
|
39
63
|
$.each(statesWithBlank, function (idx, state) {
|
40
64
|
var opt = $(document.createElement('option')).attr('value', state.id).html(state.name)
|
41
65
|
if (selected === state.id) {
|
@@ -43,12 +67,17 @@ Spree.ready(function ($) {
|
|
43
67
|
}
|
44
68
|
stateSelect.append(opt)
|
45
69
|
})
|
70
|
+
stateSelect.prop('required', false)
|
46
71
|
stateSelect.prop('disabled', false).show()
|
47
72
|
stateInput.hide().prop('disabled', true)
|
48
73
|
statePara.show()
|
49
|
-
stateSpanRequired.
|
74
|
+
stateSpanRequired.hide()
|
75
|
+
stateSelect.removeClass('required')
|
76
|
+
|
50
77
|
if (statesRequired) {
|
51
78
|
stateSelect.addClass('required')
|
79
|
+
stateSpanRequired.show()
|
80
|
+
stateSelect.prop('required', true)
|
52
81
|
}
|
53
82
|
stateSelect.removeClass('hidden')
|
54
83
|
stateInput.removeClass('required')
|
@@ -57,7 +86,7 @@ Spree.ready(function ($) {
|
|
57
86
|
stateInput.show()
|
58
87
|
if (statesRequired) {
|
59
88
|
stateSpanRequired.show()
|
60
|
-
stateInput.addClass('required')
|
89
|
+
stateInput.addClass('required form-control')
|
61
90
|
} else {
|
62
91
|
stateInput.val('')
|
63
92
|
stateSpanRequired.hide()
|
@@ -93,7 +122,6 @@ Spree.ready(function ($) {
|
|
93
122
|
Spree.updateState('s')
|
94
123
|
}
|
95
124
|
}
|
96
|
-
|
97
125
|
function getCountryId (region) {
|
98
126
|
return $('#' + region + 'country select').val()
|
99
127
|
}
|
@@ -0,0 +1,56 @@
|
|
1
|
+
(function ($) {
|
2
|
+
$(document).ready(function () {
|
3
|
+
if ($('.select_address').length > 0) {
|
4
|
+
$('input#order_use_billing').unbind('change')
|
5
|
+
|
6
|
+
hide_address_form('billing')
|
7
|
+
hide_address_form('shipping')
|
8
|
+
|
9
|
+
if ($('input#order_use_billing').is(':checked')) {
|
10
|
+
$('#shipping .select_address').hide()
|
11
|
+
}
|
12
|
+
|
13
|
+
$('input#order_use_billing').click(function () {
|
14
|
+
if ($(this).is(':checked')) {
|
15
|
+
$('#shipping .select_address').hide()
|
16
|
+
hide_address_form('shipping')
|
17
|
+
} else {
|
18
|
+
$('#shipping .select_address').show()
|
19
|
+
if ($("input[name='order[ship_address_id]']:checked").val() == '0') {
|
20
|
+
show_address_form('shipping')
|
21
|
+
} else {
|
22
|
+
hide_address_form('shipping')
|
23
|
+
}
|
24
|
+
}
|
25
|
+
})
|
26
|
+
|
27
|
+
$("input[name='order[bill_address_id]']:radio").change(function () {
|
28
|
+
if ($("input[name='order[bill_address_id]']:checked").val() == '0') {
|
29
|
+
show_address_form('billing')
|
30
|
+
} else {
|
31
|
+
hide_address_form('billing')
|
32
|
+
}
|
33
|
+
})
|
34
|
+
|
35
|
+
$("input[name='order[ship_address_id]']:radio").change(function () {
|
36
|
+
if ($("input[name='order[ship_address_id]']:checked").val() == '0') {
|
37
|
+
show_address_form('shipping')
|
38
|
+
} else {
|
39
|
+
hide_address_form('shipping')
|
40
|
+
}
|
41
|
+
})
|
42
|
+
}
|
43
|
+
})
|
44
|
+
|
45
|
+
function hide_address_form (address_type) {
|
46
|
+
$('#' + address_type + ' .inner').hide()
|
47
|
+
$('#' + address_type + ' .inner input').prop('disabled', true)
|
48
|
+
$('#' + address_type + ' .inner select').prop('disabled', true)
|
49
|
+
}
|
50
|
+
|
51
|
+
function show_address_form (address_type) {
|
52
|
+
$('#' + address_type + ' .inner').show()
|
53
|
+
$('#' + address_type + ' .inner input').prop('disabled', false)
|
54
|
+
$('#' + address_type + ' .inner select').prop('disabled', false)
|
55
|
+
}
|
56
|
+
})(jQuery)
|
@@ -3,83 +3,98 @@
|
|
3
3
|
|
4
4
|
Spree.ready(function ($) {
|
5
5
|
Spree.addImageHandlers = function () {
|
6
|
-
var thumbnails = $(
|
7
|
-
|
8
|
-
($(
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
6
|
+
var thumbnails = $("#product-images ul.thumbnails");
|
7
|
+
|
8
|
+
($("#main-image")).data("selectedThumb", ($("#main-image img")).attr("src"));
|
9
|
+
|
10
|
+
thumbnails
|
11
|
+
.find("li")
|
12
|
+
.eq(0)
|
13
|
+
.addClass("selected")
|
14
|
+
.find('img')
|
15
|
+
.addClass('border-primary');
|
16
|
+
|
17
|
+
thumbnails.find("a").on("click", function (event) {
|
18
|
+
($("#main-image")).data("selectedThumb", ($(event.currentTarget)).attr("href"));
|
19
|
+
($("#main-image")).data("selectedThumbId", ($(event.currentTarget)).parent().attr("id"));
|
20
|
+
thumbnails.find("li").removeClass("selected");
|
21
|
+
thumbnails.find('img').removeClass('border-primary');
|
22
|
+
$(this).find('img').addClass('border-primary');
|
23
|
+
($(event.currentTarget)).parent("li").addClass("selected");
|
17
24
|
return false
|
18
|
-
})
|
25
|
+
});
|
19
26
|
|
20
27
|
thumbnails.find('li').on('mouseenter', function (event) {
|
21
|
-
|
22
|
-
|
23
|
-
|
28
|
+
$(this).find('img').addClass('border-success');
|
29
|
+
return ($('#main-image img')).attr({
|
30
|
+
src: $(event.currentTarget).find('a').attr('href'),
|
31
|
+
alt: $(event.currentTarget).find('img').attr('alt')
|
32
|
+
});
|
33
|
+
});
|
24
34
|
|
25
35
|
return thumbnails.find('li').on('mouseleave', function (event) {
|
26
|
-
|
27
|
-
|
28
|
-
|
36
|
+
$(this).find('img').removeClass('border-success');
|
37
|
+
return $('#main-image img').attr({
|
38
|
+
src: $('#main-image').data('selectedThumb'),
|
39
|
+
alt: $('#main-image').data('selectedThumbAlt')
|
40
|
+
});
|
41
|
+
});
|
29
42
|
}
|
30
43
|
|
31
44
|
Spree.showVariantImages = function (variantId) {
|
32
45
|
($('li.vtmb')).hide();
|
33
|
-
($('li.tmb-' + variantId)).show()
|
34
|
-
var currentThumb = $('#' + ($('#main-image')).data('selectedThumbId'))
|
46
|
+
($('li.tmb-' + variantId)).show();
|
47
|
+
var currentThumb = $('#' + ($('#main-image')).data('selectedThumbId'));
|
35
48
|
|
36
49
|
if (!currentThumb.hasClass('vtmb + variantId')) {
|
37
|
-
var thumb = $(($('#product-images ul.thumbnails li:visible.vtmb')).eq(0))
|
50
|
+
var thumb = $(($('#product-images ul.thumbnails li:visible.vtmb')).eq(0));
|
38
51
|
|
39
52
|
if (!(thumb.length > 0)) {
|
40
|
-
thumb = $(($('#product-images ul.thumbnails li:visible')).eq(0))
|
53
|
+
thumb = $(($('#product-images ul.thumbnails li:visible')).eq(0));
|
41
54
|
}
|
42
55
|
|
43
|
-
var newImg = thumb.find('a').attr('href')
|
56
|
+
var newImg = thumb.find('a').attr('href');
|
44
57
|
|
45
58
|
var newAlt = thumb.find('img').attr('alt');
|
46
|
-
($('#product-images ul.thumbnails li')).removeClass('selected')
|
59
|
+
($('#product-images ul.thumbnails li')).removeClass('selected');
|
47
60
|
thumb.addClass('selected');
|
48
61
|
($('#main-image img')).attr({ 'src': newImg, 'alt': newAlt });
|
49
|
-
($('#main-image')).data({ 'selectedThumb': newImg, 'selectedThumbAlt': newAlt })
|
50
|
-
return ($('#main-image')).data('selectedThumbId', thumb.attr('id'))
|
62
|
+
($('#main-image')).data({ 'selectedThumb': newImg, 'selectedThumbAlt': newAlt });
|
63
|
+
return ($('#main-image')).data('selectedThumbId', thumb.attr('id'));
|
51
64
|
}
|
52
65
|
}
|
53
66
|
|
54
67
|
Spree.updateVariantPrice = function (variant) {
|
55
|
-
var variantPrice = variant.data('price')
|
68
|
+
var variantPrice = variant.data('price');
|
56
69
|
|
57
70
|
if (variantPrice) {
|
58
|
-
return ($('.price.selling')).text(variantPrice)
|
71
|
+
return ($('.price.selling')).text(variantPrice);
|
59
72
|
}
|
60
73
|
}
|
61
74
|
|
62
75
|
Spree.disableCartForm = function (variant) {
|
63
|
-
var inStock = variant.data('in-stock')
|
64
|
-
return $('#add-to-cart-button').attr('disabled', !inStock)
|
76
|
+
var inStock = variant.data('in-stock');
|
77
|
+
return $('#add-to-cart-button').attr('disabled', !inStock);
|
65
78
|
}
|
66
79
|
|
67
|
-
var radios = $("#product-variants input[type='radio']")
|
80
|
+
var radios = $("#product-variants input[type='radio']");
|
68
81
|
|
69
82
|
if (radios.length > 0) {
|
70
|
-
var selectedRadio = $("#product-variants input[type='radio'][checked='checked']")
|
71
|
-
Spree.showVariantImages(selectedRadio.attr('value'))
|
72
|
-
Spree.updateVariantPrice(selectedRadio)
|
73
|
-
Spree.disableCartForm(selectedRadio)
|
83
|
+
var selectedRadio = $("#product-variants input[type='radio'][checked='checked']");
|
84
|
+
Spree.showVariantImages(selectedRadio.attr('value'));
|
85
|
+
Spree.updateVariantPrice(selectedRadio);
|
86
|
+
Spree.disableCartForm(selectedRadio);
|
74
87
|
|
75
88
|
radios.click(function (event) {
|
76
|
-
|
77
|
-
|
78
|
-
|
89
|
+
$("#product-variants").find('li.active').removeClass("active");
|
90
|
+
$(this).closest("li").addClass("active");
|
91
|
+
Spree.showVariantImages(this.value);
|
92
|
+
Spree.updateVariantPrice($(this));
|
93
|
+
return Spree.disableCartForm($(this));
|
79
94
|
})
|
80
95
|
}
|
81
96
|
|
82
|
-
return Spree.addImageHandlers()
|
97
|
+
return Spree.addImageHandlers();
|
83
98
|
})
|
84
99
|
|
85
100
|
Spree.ready(function () {
|
@@ -1,4 +1,6 @@
|
|
1
|
-
//= require
|
1
|
+
//= require jquery3
|
2
|
+
//= require popper
|
3
|
+
//= require bootstrap
|
2
4
|
//= require jquery.payment
|
3
5
|
//= require spree
|
4
6
|
//= require polyfill.min
|
@@ -8,6 +10,7 @@
|
|
8
10
|
//= require spree/frontend/cart
|
9
11
|
//= require spree/frontend/checkout
|
10
12
|
//= require spree/frontend/checkout/address
|
13
|
+
//= require spree/frontend/checkout/address_book
|
11
14
|
//= require spree/frontend/checkout/payment
|
12
15
|
//= require spree/frontend/product
|
13
16
|
|
@@ -1,18 +1,17 @@
|
|
1
1
|
//Add your custom bootstrap variables here, see https://github.com/twbs/bootstrap-sass/blob/master/assets/stylesheets/bootstrap/_variables.scss for full list of variables.
|
2
2
|
|
3
|
-
@import "
|
4
|
-
@import "variables";
|
3
|
+
@import "./variables";
|
5
4
|
@import "bootstrap";
|
5
|
+
@import "glyphicons";
|
6
6
|
|
7
7
|
// -- Spree Custom Header and Footer ---------------------
|
8
8
|
#spree-header {
|
9
|
-
background-color: $
|
10
|
-
margin-bottom: $line-height-
|
9
|
+
background-color: $primary;
|
10
|
+
margin-bottom: $line-height-base;
|
11
11
|
padding-top: 0.25em;
|
12
12
|
|
13
13
|
#header {
|
14
|
-
background: rgba($gray-
|
15
|
-
padding: $line-height-computed 0;
|
14
|
+
background: rgba($gray-900, 0.4);
|
16
15
|
}
|
17
16
|
|
18
17
|
#logo {
|
@@ -24,33 +23,17 @@
|
|
24
23
|
}
|
25
24
|
}
|
26
25
|
|
27
|
-
|
28
|
-
|
29
|
-
padding-top: 0;
|
30
|
-
padding-bottom: 10px;
|
31
|
-
line-height: $line-height-computed;
|
32
|
-
}
|
26
|
+
.navbar {
|
27
|
+
padding: 0;
|
33
28
|
}
|
34
29
|
|
35
30
|
.nav a {
|
36
31
|
color: white;
|
37
32
|
|
38
33
|
&:hover, &:focus {
|
39
|
-
background: rgba($gray-
|
34
|
+
background: rgba($gray-900, 0.4);
|
40
35
|
}
|
41
36
|
}
|
42
|
-
|
43
|
-
.navbar {
|
44
|
-
border: 0;
|
45
|
-
margin-bottom: 0;
|
46
|
-
}
|
47
|
-
}
|
48
|
-
|
49
|
-
#spree-footer {
|
50
|
-
background: $gray-dark;
|
51
|
-
padding-top: $padding-base-horizontal;
|
52
|
-
margin-top: $line-height-computed;
|
53
|
-
color: white;
|
54
37
|
}
|
55
38
|
|
56
39
|
// -- Spree Layout Custom Rules -------------------------
|
@@ -59,12 +42,12 @@
|
|
59
42
|
.alert-error { @extend .alert-danger; }
|
60
43
|
.alert-alert { @extend .alert-info; }
|
61
44
|
|
62
|
-
.
|
63
|
-
|
45
|
+
.list-unstyled {
|
46
|
+
@include list-unstyled();
|
64
47
|
}
|
65
48
|
|
66
49
|
.progress-steps {
|
67
|
-
margin-top: $line-height-
|
50
|
+
margin-top: $line-height-base;
|
68
51
|
}
|
69
52
|
|
70
53
|
h1 {
|
@@ -92,13 +75,8 @@ table {
|
|
92
75
|
}
|
93
76
|
}
|
94
77
|
|
95
|
-
|
96
|
-
|
97
|
-
color: lighten($brand-primary, 20);
|
98
|
-
|
99
|
-
&:hover {
|
100
|
-
color: lighten($brand-primary, 10);
|
101
|
-
}
|
78
|
+
#product-thumbnails {
|
79
|
+
list-style: none;
|
102
80
|
}
|
103
81
|
|
104
82
|
// Updated credit-card image
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# https://github.com/spree-contrib/spree_address_book/blob/master/app/controllers/spree/checkout_controller_decorator.rb
|
2
|
+
module Spree
|
3
|
+
module Checkout
|
4
|
+
module AddressBook
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
after_action :normalize_addresses, only: :update
|
9
|
+
before_action :set_addresses, only: :update
|
10
|
+
end
|
11
|
+
|
12
|
+
protected
|
13
|
+
|
14
|
+
def set_addresses
|
15
|
+
return unless params[:order] && params[:state] == 'address'
|
16
|
+
|
17
|
+
if params[:order][:ship_address_id].to_i > 0
|
18
|
+
params[:order].delete(:ship_address_attributes)
|
19
|
+
|
20
|
+
Spree::Address.find(params[:order][:ship_address_id]).user_id != try_spree_current_user&.id && raise('Frontend address forging')
|
21
|
+
else
|
22
|
+
params[:order].delete(:ship_address_id)
|
23
|
+
end
|
24
|
+
|
25
|
+
if params[:order][:bill_address_id].to_i > 0
|
26
|
+
params[:order].delete(:bill_address_attributes)
|
27
|
+
|
28
|
+
Spree::Address.find(params[:order][:bill_address_id]).user_id != try_spree_current_user&.id && raise('Frontend address forging')
|
29
|
+
else
|
30
|
+
params[:order].delete(:bill_address_id)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def normalize_addresses
|
35
|
+
return unless params[:state] == 'address' && @order.bill_address_id && @order.ship_address_id
|
36
|
+
|
37
|
+
# ensure that there is no validation errors and addresses were saved
|
38
|
+
return unless @order.bill_address && @order.ship_address
|
39
|
+
|
40
|
+
bill_address = @order.bill_address
|
41
|
+
ship_address = @order.ship_address
|
42
|
+
if @order.bill_address_id != @order.ship_address_id && bill_address == ship_address
|
43
|
+
@order.update_column(:bill_address_id, ship_address.id)
|
44
|
+
bill_address.destroy
|
45
|
+
else
|
46
|
+
bill_address.update_attribute(:user_id, try_spree_current_user&.id)
|
47
|
+
end
|
48
|
+
|
49
|
+
ship_address.update_attribute(:user_id, try_spree_current_user&.id)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# https://github.com/spree-contrib/spree_address_book/blob/master/app/controllers/spree/addresses_controller.rb
|
2
|
+
module Spree
|
3
|
+
class AddressesController < Spree::StoreController
|
4
|
+
helper Spree::AddressesHelper
|
5
|
+
load_and_authorize_resource class: Spree::Address
|
6
|
+
|
7
|
+
def index
|
8
|
+
@addresses = spree_current_user.addresses
|
9
|
+
end
|
10
|
+
|
11
|
+
def create
|
12
|
+
@address = spree_current_user.addresses.build(address_params)
|
13
|
+
if @address.save
|
14
|
+
flash[:notice] = Spree.t(:successfully_created, scope: :address_book)
|
15
|
+
redirect_to :index
|
16
|
+
else
|
17
|
+
render :new
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def edit
|
22
|
+
session['spree_user_return_to'] = request.env['HTTP_REFERER']
|
23
|
+
end
|
24
|
+
|
25
|
+
def new
|
26
|
+
@address = Spree::Address.default
|
27
|
+
end
|
28
|
+
|
29
|
+
def update
|
30
|
+
if @address.editable?
|
31
|
+
if @address.update_attributes(address_params)
|
32
|
+
flash[:notice] = Spree.t(:successfully_updated, scope: :address_book)
|
33
|
+
redirect_back_or_default(addresses_path)
|
34
|
+
else
|
35
|
+
render :edit
|
36
|
+
end
|
37
|
+
else
|
38
|
+
new_address = @address.clone
|
39
|
+
new_address.attributes = address_params
|
40
|
+
@address.update_attribute(:deleted_at, Time.current)
|
41
|
+
if new_address.save
|
42
|
+
flash[:notice] = Spree.t(:successfully_updated, scope: :address_book)
|
43
|
+
redirect_back_or_default(addresses_path)
|
44
|
+
else
|
45
|
+
render :edit
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def destroy
|
51
|
+
@address.destroy
|
52
|
+
|
53
|
+
flash[:notice] = Spree.t(:successfully_removed, scope: :address_book)
|
54
|
+
redirect_to(request.env['HTTP_REFERER'] || addresses_path) unless request.xhr?
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def address_params
|
60
|
+
params[:address].permit(:address,
|
61
|
+
:firstname,
|
62
|
+
:lastname,
|
63
|
+
:address1,
|
64
|
+
:address2,
|
65
|
+
:city,
|
66
|
+
:state_id,
|
67
|
+
:zipcode,
|
68
|
+
:country_id,
|
69
|
+
:phone)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -4,6 +4,8 @@ module Spree
|
|
4
4
|
# checkout which has nothing to do with updating an order that this approach
|
5
5
|
# is waranted.
|
6
6
|
class CheckoutController < Spree::StoreController
|
7
|
+
include Spree::Checkout::AddressBook
|
8
|
+
|
7
9
|
before_action :set_cache_header, only: [:edit]
|
8
10
|
before_action :load_order_with_lock
|
9
11
|
before_action :ensure_valid_state_lock_version, only: [:update]
|
@@ -6,7 +6,6 @@ module Spree
|
|
6
6
|
respond_to :html
|
7
7
|
|
8
8
|
before_action :assign_order_with_lock, only: :update
|
9
|
-
skip_before_action :verify_authenticity_token, only: [:populate]
|
10
9
|
|
11
10
|
def show
|
12
11
|
@order = Order.includes(line_items: [variant: [:option_values, :images, :product]], bill_address: :state, ship_address: :state).find_by!(number: params[:id])
|
@@ -38,60 +37,6 @@ module Spree
|
|
38
37
|
associate_user
|
39
38
|
end
|
40
39
|
|
41
|
-
# Adds a new item to the order (creating a new order if none already exists)
|
42
|
-
def populate
|
43
|
-
ActiveSupport::Deprecation.warn(<<-DEPRECATION, caller)
|
44
|
-
OrdersController#populate is deprecated and will be removed in Spree 4.0.
|
45
|
-
Please use `/api/v2/storefront/cart/add_item` endpoint instead.
|
46
|
-
See documentation: https://github.com/spree/spree/blob/master/api/docs/v2/storefront/index.yaml#L42
|
47
|
-
DEPRECATION
|
48
|
-
|
49
|
-
order = current_order(create_order_if_necessary: true)
|
50
|
-
variant = Spree::Variant.find(params[:variant_id])
|
51
|
-
quantity = params[:quantity].to_i
|
52
|
-
options = params[:options] || {}
|
53
|
-
|
54
|
-
# 2,147,483,647 is crazy. See issue #2695.
|
55
|
-
if quantity.between?(1, 2_147_483_647)
|
56
|
-
begin
|
57
|
-
result = cart_add_item_service.call(order: order,
|
58
|
-
variant: variant,
|
59
|
-
quantity: quantity,
|
60
|
-
options: options)
|
61
|
-
if result.failure?
|
62
|
-
error = result.value.errors.full_messages.join(', ')
|
63
|
-
else
|
64
|
-
order.update_line_item_prices!
|
65
|
-
order.create_tax_charge!
|
66
|
-
order.update_with_updater!
|
67
|
-
end
|
68
|
-
rescue ActiveRecord::RecordInvalid => e
|
69
|
-
error = e.record.errors.full_messages.join(', ')
|
70
|
-
end
|
71
|
-
else
|
72
|
-
error = Spree.t(:please_enter_reasonable_quantity)
|
73
|
-
end
|
74
|
-
|
75
|
-
if error
|
76
|
-
flash[:error] = error
|
77
|
-
redirect_back_or_default(spree.root_path)
|
78
|
-
else
|
79
|
-
respond_with(order) do |format|
|
80
|
-
format.html { redirect_to(cart_path(variant_id: variant.id)) }
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
def populate_redirect
|
86
|
-
ActiveSupport::Deprecation.warn(<<-DEPRECATION, caller)
|
87
|
-
OrdersController#populate is deprecated and will be removed in Spree 4.0.
|
88
|
-
Please use `/api/v2/storefront/cart/add_item` endpoint instead.
|
89
|
-
See documentation: https://github.com/spree/spree/blob/master/api/docs/v2/storefront/index.yaml#L42
|
90
|
-
DEPRECATION
|
91
|
-
flash[:error] = Spree.t(:populate_get_error)
|
92
|
-
redirect_to cart_path
|
93
|
-
end
|
94
|
-
|
95
40
|
def empty
|
96
41
|
current_order.try(:empty!)
|
97
42
|
|