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.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/app/assets/javascripts/spree/frontend/checkout/address.js +42 -14
  4. data/app/assets/javascripts/spree/frontend/checkout/address_book.js +56 -0
  5. data/app/assets/javascripts/spree/frontend/product.js +54 -39
  6. data/app/assets/javascripts/spree/frontend.js +4 -1
  7. data/app/assets/stylesheets/spree/frontend/_variables.scss +1 -1
  8. data/app/assets/stylesheets/spree/frontend/address_book.scss +8 -0
  9. data/app/assets/stylesheets/spree/frontend/frontend_bootstrap.css.scss +13 -35
  10. data/app/assets/stylesheets/spree/frontend.css +1 -0
  11. data/app/controllers/concerns/spree/checkout/address_book.rb +53 -0
  12. data/app/controllers/spree/addresses_controller.rb +72 -0
  13. data/app/controllers/spree/checkout_controller.rb +2 -0
  14. data/app/controllers/spree/orders_controller.rb +0 -55
  15. data/app/controllers/spree/products_controller.rb +5 -1
  16. data/app/controllers/spree/store_controller.rb +1 -1
  17. data/app/helpers/spree/addresses_helper.rb +36 -0
  18. data/app/helpers/spree/frontend_helper.rb +16 -15
  19. data/app/views/kaminari/{twitter-bootstrap-3 → twitter-bootstrap-4}/_first_page.html.erb +2 -2
  20. data/app/views/kaminari/{twitter-bootstrap-3 → twitter-bootstrap-4}/_gap.html.erb +5 -1
  21. data/app/views/kaminari/{twitter-bootstrap-3 → twitter-bootstrap-4}/_last_page.html.erb +2 -2
  22. data/app/views/kaminari/{twitter-bootstrap-3 → twitter-bootstrap-4}/_next_page.html.erb +2 -2
  23. data/app/views/kaminari/{twitter-bootstrap-3 → twitter-bootstrap-4}/_page.html.erb +8 -2
  24. data/app/views/kaminari/{twitter-bootstrap-3 → twitter-bootstrap-4}/_paginator.html.erb +1 -1
  25. data/app/views/kaminari/{twitter-bootstrap-3 → twitter-bootstrap-4}/_prev_page.html.erb +2 -2
  26. data/app/views/spree/address/_form.html.erb +27 -24
  27. data/app/views/spree/addresses/_form.html.erb +18 -0
  28. data/app/views/spree/addresses/destroy.js.erb +2 -0
  29. data/app/views/spree/addresses/edit.html.erb +23 -0
  30. data/app/views/spree/addresses/new.html.erb +23 -0
  31. data/app/views/spree/checkout/_address.html.erb +61 -37
  32. data/app/views/spree/checkout/_confirm.html.erb +12 -10
  33. data/app/views/spree/checkout/_delivery.html.erb +27 -15
  34. data/app/views/spree/checkout/_payment.html.erb +14 -9
  35. data/app/views/spree/checkout/_summary.html.erb +59 -57
  36. data/app/views/spree/checkout/edit.html.erb +6 -6
  37. data/app/views/spree/checkout/payment/_gateway.html.erb +43 -35
  38. data/app/views/spree/layouts/spree_application.html.erb +5 -2
  39. data/app/views/spree/orders/_form.html.erb +38 -25
  40. data/app/views/spree/orders/edit.html.erb +28 -22
  41. data/app/views/spree/orders/show.html.erb +2 -1
  42. data/app/views/spree/products/_cart_form.html.erb +28 -26
  43. data/app/views/spree/products/_product.html.erb +7 -8
  44. data/app/views/spree/products/_promotions.html.erb +13 -11
  45. data/app/views/spree/products/_properties.html.erb +10 -3
  46. data/app/views/spree/products/_thumbnails.html.erb +5 -7
  47. data/app/views/spree/products/show.html.erb +8 -8
  48. data/app/views/spree/shared/_filters.html.erb +29 -9
  49. data/app/views/spree/shared/_header.html.erb +2 -2
  50. data/app/views/spree/shared/_login_bar.html.erb +9 -3
  51. data/app/views/spree/shared/_main_nav_bar.html.erb +15 -15
  52. data/app/views/spree/shared/_nav_bar.html.erb +2 -2
  53. data/app/views/spree/shared/_order_details.html.erb +143 -89
  54. data/app/views/spree/shared/_products.html.erb +2 -2
  55. data/app/views/spree/shared/_search.html.erb +19 -12
  56. data/app/views/spree/shared/_sidebar.html.erb +1 -1
  57. data/app/views/spree/shared/_taxonomies.html.erb +7 -3
  58. data/config/routes.rb +2 -0
  59. data/lib/spree/frontend/engine.rb +4 -0
  60. data/lib/spree/frontend.rb +3 -3
  61. data/spree_frontend.gemspec +4 -3
  62. metadata +48 -25
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3d7b525197ea5f15936c929c11e7dff9764860989da1a71e2d06210b8438f8b6
4
- data.tar.gz: 76628938c32b584a1cdd5c0c7360f1d513f180a167759dc3a9923fd576cf891b
3
+ metadata.gz: 032eb15c7d9d5a00cb97125d37d91cbb268790c76dd89cb24353f40eb8480212
4
+ data.tar.gz: d01986aec09bef01b96c731618a44da04905f59e985c00437a80c386ee949baf
5
5
  SHA512:
6
- metadata.gz: 198334d1b2e77eafc559292383a2fb9d405ef0032cfc1d957ed45e810976043e376d940328886509cd70865a3e9058ba45add6c0b5662a58f28bf3b661d18df8
7
- data.tar.gz: 97249566c4d0e3e203f4f65d52e006a680407246c618b0fc075fb640e2e6cd7d0e6187859c3b7b7223f5d7c75d14f7346019d1cb82c3e019b92cf5c754264f8f
6
+ metadata.gz: 365cddc404a1130ca0588af7d20309095eebcf2c2a4dbb3770b69fa38db9f03bd7b55596b1b53ec0d35c83a32e7c68ffe9b82db292d7d43d0017b55d90b2126c
7
+ data.tar.gz: 37ad01b825d249d64ef77f4adbdea1fa048aa1206c7882df64be6e97d663e18cd3b121d9fcb4e1fd75c2440d68ce26047ef0cf2f8a01184c4a7a5cf10b61e6b4
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- eval(File.read(File.dirname(__FILE__) + '/../common_spree_dependencies.rb'))
1
+ eval_gemfile('../common_spree_dependencies.rb')
2
2
 
3
3
  gem 'spree_core', path: '../core'
4
4
  gem 'spree_api', path: '../api'
@@ -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
- $.get(Spree.routes.states_search, {
9
- country_id: countryId
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: data.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('[id$="state-required"]')
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.show()
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 = $('#product-images ul.thumbnails');
7
- ($('#main-image')).data('selectedThumb', ($('#main-image img')).attr('src'));
8
- ($('#main-image')).data('selectedThumbAlt', ($('#main-image img')).attr('alt'))
9
- thumbnails.find('li').eq(0).addClass('selected')
10
-
11
- thumbnails.find('a').on('click', function (event) {
12
- ($('#main-image')).data('selectedThumb', ($(event.currentTarget)).attr('href'));
13
- ($('#main-image')).data('selectedThumbId', ($(event.currentTarget)).parent().attr('id'));
14
- ($('#main-image')).data('selectedThumbAlt', ($(event.currentTarget)).find('img').attr('alt'))
15
- thumbnails.find('li').removeClass('selected');
16
- ($(event.currentTarget)).parent('li').addClass('selected')
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
- return ($('#main-image img'))
22
- .attr({ 'src': ($(event.currentTarget)).find('a').attr('href'), 'alt': ($(event.currentTarget)).find('img').attr('alt') })
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
- return ($('#main-image img'))
27
- .attr({ 'src': ($('#main-image')).data('selectedThumb'), 'alt': ($('#main-image')).data('selectedThumbAlt') })
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
- Spree.showVariantImages(this.value)
77
- Spree.updateVariantPrice($(this))
78
- return Spree.disableCartForm($(this))
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 bootstrap-sprockets
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,4 +1,4 @@
1
1
  /*--------------------------------
2
2
  Colors
3
3
  --------------------------------*/
4
- $brand-primary: #1c5c92;
4
+ $primary: #1c5c92;
@@ -0,0 +1,8 @@
1
+ div#checkout #checkout_form_address {
2
+ #billing, #shipping {
3
+ .select_address label { float: none; }
4
+ input[type=radio] { width: auto; }
5
+ }
6
+ }
7
+
8
+ .hidden { display: none; }
@@ -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 "bootstrap-sprockets";
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: $brand-primary;
10
- margin-bottom: $line-height-computed;
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-darker, 0.4);
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
- @media (max-width: 767px) {
28
- .navbar-nav > li > a {
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-darker, 0.4);
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
- .product-body {
63
- height: 170px;
45
+ .list-unstyled {
46
+ @include list-unstyled();
64
47
  }
65
48
 
66
49
  .progress-steps {
67
- margin-top: $line-height-computed;
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
- // Footer links
96
- #footer-left a {
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
@@ -1,5 +1,6 @@
1
1
  /*
2
2
  * This is a manifest file that includes stylesheets for spree_frontend
3
3
  *= require spree/frontend/frontend_bootstrap
4
+ *= require spree/frontend/address_book
4
5
  *= require_self
5
6
  */
@@ -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