solidus_frontend 2.6.5 → 2.9.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of solidus_frontend might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +7 -5
- data/app/assets/images/favicon.ico +0 -0
- data/app/assets/javascripts/spree/frontend/checkout/coupon-code.js +2 -1
- data/app/assets/stylesheets/spree/frontend/screen.css.scss +39 -1
- data/app/controllers/spree/checkout_controller.rb +61 -3
- data/app/controllers/spree/coupon_codes_controller.rb +35 -0
- data/app/controllers/spree/locale_controller.rb +1 -1
- data/app/controllers/spree/orders_controller.rb +27 -12
- data/app/controllers/spree/store_controller.rb +0 -18
- data/app/controllers/spree/taxons_controller.rb +6 -3
- data/app/views/spree/checkout/_coupon_code.html.erb +12 -0
- data/app/views/spree/checkout/_delivery.html.erb +6 -2
- data/app/views/spree/checkout/_payment.html.erb +0 -10
- data/app/views/spree/checkout/_summary.html.erb +4 -0
- data/app/views/spree/checkout/payment/_gateway.html.erb +6 -5
- data/app/views/spree/coupon_codes/new.html.erb +6 -0
- data/app/views/spree/orders/_form.html.erb +1 -1
- data/app/views/spree/orders/_line_item.html.erb +3 -5
- data/app/views/spree/orders/edit.html.erb +5 -6
- data/app/views/spree/products/_image.html.erb +4 -1
- data/app/views/spree/products/_thumbnails.html.erb +10 -8
- data/app/views/spree/shared/_image.html.erb +4 -4
- data/app/views/spree/shared/_locale_selector.html.erb +1 -1
- data/app/views/spree/shared/_order_details.html.erb +3 -5
- data/app/views/spree/shared/_products.html.erb +1 -1
- data/config/routes.rb +1 -0
- data/lib/spree/frontend.rb +1 -1
- data/solidus_frontend.gemspec +1 -1
- data/spec/controllers/spree/checkout_controller_spec.rb +109 -9
- data/spec/controllers/spree/checkout_controller_with_views_spec.rb +1 -1
- data/spec/controllers/spree/home_controller_spec.rb +1 -1
- data/spec/controllers/spree/orders_controller_ability_spec.rb +11 -30
- data/spec/controllers/spree/orders_controller_spec.rb +54 -3
- data/spec/controllers/spree/products_controller_spec.rb +3 -3
- data/spec/controllers/spree/taxons_controller_spec.rb +1 -1
- data/spec/features/address_spec.rb +1 -1
- data/spec/features/automatic_promotion_adjustments_spec.rb +2 -2
- data/spec/features/caching/taxons_spec.rb +1 -1
- data/spec/features/checkout_confirm_insufficient_stock_spec.rb +71 -0
- data/spec/features/checkout_spec.rb +34 -25
- data/spec/features/coupon_code_spec.rb +96 -56
- data/spec/features/currency_spec.rb +1 -1
- data/spec/features/first_order_promotion_spec.rb +59 -0
- data/spec/features/free_shipping_promotions_spec.rb +2 -2
- data/spec/features/products_spec.rb +8 -8
- data/spec/features/promotion_code_invalidation_spec.rb +2 -2
- data/spec/features/quantity_promotions_spec.rb +9 -9
- data/spec/spec_helper.rb +1 -1
- metadata +14 -9
- data/spec/support/features/fill_in_with_force.rb +0 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '021429976db5161133e0b99d6fe493da794d0b8c1a54062a3fe1f0dec420fb41'
|
4
|
+
data.tar.gz: 89e3e0326e2aced1f9d1107442816b64a2c554c719f883e408cfc0cb4597b820
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 274a3dceabef1220e03a11f56081ecfb9501076ef83b7a85b5efb7eaa1ee8858612dbcb516aa73451d89141f195dcfa55a64ef4a7601adedb77762ff7047655e
|
7
|
+
data.tar.gz: 53f65dd4e588101f31592f22401617e8cf871fa58c6e3ff1d025e9af0c533890e39cffe65d8e5cde3f8fdd60da845a027bf95ed6a462d209e03c71bd4a07666b
|
data/README.md
CHANGED
@@ -11,19 +11,19 @@ Solidus provides a generator to help with copying the right view into your host
|
|
11
11
|
|
12
12
|
Simply call the generator to copy all views into your host app.
|
13
13
|
|
14
|
-
```
|
14
|
+
```bash
|
15
15
|
$ bundle exec rails g solidus:views:override
|
16
16
|
```
|
17
17
|
|
18
18
|
If you only want to copy certain views into your host app, you can provide the `--only` argument:
|
19
19
|
|
20
|
-
```
|
20
|
+
```bash
|
21
21
|
$ bundle exec rails g solidus:views:override --only products/show
|
22
22
|
```
|
23
23
|
|
24
24
|
The argument to `--only` can also be a substring of the name of the view from the `app/views/spree` folder:
|
25
25
|
|
26
|
-
```
|
26
|
+
```bash
|
27
27
|
$ bundle exec rails g solidus:views:override --only product
|
28
28
|
```
|
29
29
|
|
@@ -31,10 +31,12 @@ This will copy all views whose directory or filename contains the string "produc
|
|
31
31
|
|
32
32
|
### Handle upgrades
|
33
33
|
|
34
|
-
After upgrading
|
34
|
+
After upgrading Solidus to a new version run the generator again and follow on screen instructions.
|
35
35
|
|
36
36
|
## Testing
|
37
37
|
|
38
38
|
Run the tests
|
39
39
|
|
40
|
-
|
40
|
+
```bash
|
41
|
+
bundle exec rspec
|
42
|
+
```
|
Binary file
|
@@ -1,4 +1,5 @@
|
|
1
1
|
Spree.onCouponCodeApply = function(e) {
|
2
|
+
e.preventDefault();
|
2
3
|
var couponCodeField = $("#order_coupon_code");
|
3
4
|
var couponCode = $.trim(couponCodeField.val());
|
4
5
|
if (couponCode === "") {
|
@@ -13,7 +14,7 @@ Spree.onCouponCodeApply = function(e) {
|
|
13
14
|
coupon_code: couponCode
|
14
15
|
};
|
15
16
|
var req = Spree.ajax({
|
16
|
-
method:
|
17
|
+
method: 'POST',
|
17
18
|
url: Spree.routes.apply_coupon_code(Spree.current_order_id),
|
18
19
|
data: JSON.stringify(data),
|
19
20
|
contentType: "application/json"
|
@@ -948,9 +948,35 @@ p[data-hook="use_billing"] {
|
|
948
948
|
padding: 5px;
|
949
949
|
}
|
950
950
|
|
951
|
+
.coupon-code {
|
952
|
+
margin-top: 20px;
|
953
|
+
padding: 10px;
|
954
|
+
|
955
|
+
form {
|
956
|
+
display: flex;
|
957
|
+
flex-flow: row wrap;
|
958
|
+
}
|
959
|
+
|
960
|
+
label {
|
961
|
+
flex: 1 100%;
|
962
|
+
text-align: left;
|
963
|
+
}
|
964
|
+
|
965
|
+
input[type="text"] {
|
966
|
+
flex: 3 0;
|
967
|
+
width: 100%;
|
968
|
+
margin-right: 5px;
|
969
|
+
}
|
970
|
+
|
971
|
+
&-apply-button {
|
972
|
+
white-space: nowrap;
|
973
|
+
}
|
974
|
+
}
|
975
|
+
|
951
976
|
#coupon_status {
|
977
|
+
margin-top: 10px;
|
952
978
|
font-weight: bold;
|
953
|
-
font-size:
|
979
|
+
font-size: 100%;
|
954
980
|
&.success {
|
955
981
|
color: $c_green;
|
956
982
|
}
|
@@ -1066,6 +1092,9 @@ div[data-hook="inside_cart_form"] {
|
|
1066
1092
|
/*--------------------------------------*/
|
1067
1093
|
#order_summary {
|
1068
1094
|
margin-top: 0;
|
1095
|
+
h1 {
|
1096
|
+
padding-left: 10px;
|
1097
|
+
}
|
1069
1098
|
}
|
1070
1099
|
#order {
|
1071
1100
|
p[data-hook="links"] {
|
@@ -1236,6 +1265,15 @@ table.order-summary {
|
|
1236
1265
|
|
1237
1266
|
}
|
1238
1267
|
|
1268
|
+
// # Logo
|
1269
|
+
#logo {
|
1270
|
+
padding: 20px 0;
|
1271
|
+
|
1272
|
+
> a {
|
1273
|
+
display: inline-block;
|
1274
|
+
}
|
1275
|
+
}
|
1276
|
+
|
1239
1277
|
@media only screen and (max-width: 767px) {
|
1240
1278
|
#empty-cart {
|
1241
1279
|
clear: both;
|
@@ -24,6 +24,7 @@ module Spree
|
|
24
24
|
helper 'spree/orders'
|
25
25
|
|
26
26
|
rescue_from Spree::Core::GatewayError, with: :rescue_from_spree_gateway_error
|
27
|
+
rescue_from Spree::Order::InsufficientStock, with: :insufficient_stock_error
|
27
28
|
|
28
29
|
# Updates the order and advances to the next state (when possible.)
|
29
30
|
def update
|
@@ -166,6 +167,24 @@ module Spree
|
|
166
167
|
spree.order_path(@order)
|
167
168
|
end
|
168
169
|
|
170
|
+
def apply_coupon_code
|
171
|
+
if update_params[:coupon_code].present?
|
172
|
+
Spree::Deprecation.warn('This endpoint is deprecated. Please use `Spree::CouponCodesController#create` endpoint instead.')
|
173
|
+
@order.coupon_code = update_params[:coupon_code]
|
174
|
+
|
175
|
+
handler = PromotionHandler::Coupon.new(@order).apply
|
176
|
+
|
177
|
+
if handler.error.present?
|
178
|
+
flash.now[:error] = handler.error
|
179
|
+
elsif handler.success
|
180
|
+
flash[:success] = handler.success
|
181
|
+
end
|
182
|
+
|
183
|
+
setup_for_current_state
|
184
|
+
respond_with(@order) { |format| format.html { render :edit } } && return
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
169
188
|
def setup_for_current_state
|
170
189
|
method_name = :"before_#{@order.state}"
|
171
190
|
send(method_name) if respond_to?(method_name, true)
|
@@ -200,9 +219,14 @@ module Spree
|
|
200
219
|
@wallet_payment_sources = try_spree_current_user.wallet.wallet_payment_sources
|
201
220
|
@default_wallet_payment_source = @wallet_payment_sources.detect(&:default) ||
|
202
221
|
@wallet_payment_sources.first
|
203
|
-
|
204
|
-
|
205
|
-
|
222
|
+
|
223
|
+
@payment_sources = Spree::DeprecatedInstanceVariableProxy.new(
|
224
|
+
self,
|
225
|
+
:deprecated_payment_sources,
|
226
|
+
:@payment_sources,
|
227
|
+
Spree::Deprecation,
|
228
|
+
"Please, do not use @payment_sources anymore, use @wallet_payment_sources instead."
|
229
|
+
)
|
206
230
|
end
|
207
231
|
end
|
208
232
|
|
@@ -215,5 +239,39 @@ module Spree
|
|
215
239
|
def check_authorization
|
216
240
|
authorize!(:edit, current_order, cookies.signed[:guest_token])
|
217
241
|
end
|
242
|
+
|
243
|
+
def insufficient_stock_error
|
244
|
+
packages = @order.shipments.map(&:to_package)
|
245
|
+
if packages.empty?
|
246
|
+
flash[:error] = I18n.t('spree.insufficient_stock_for_order')
|
247
|
+
redirect_to cart_path
|
248
|
+
else
|
249
|
+
availability_validator = Spree::Stock::AvailabilityValidator.new
|
250
|
+
unavailable_items = @order.line_items.reject { |line_item| availability_validator.validate(line_item) }
|
251
|
+
if unavailable_items.any?
|
252
|
+
item_names = unavailable_items.map(&:name).to_sentence
|
253
|
+
flash[:error] = t('spree.inventory_error_flash_for_insufficient_shipment_quantity', unavailable_items: item_names)
|
254
|
+
@order.restart_checkout_flow
|
255
|
+
redirect_to spree.checkout_state_path(@order.state)
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
# This method returns payment sources of the current user. It is no more
|
261
|
+
# used into our frontend. We used to assign the content of this method
|
262
|
+
# into an ivar (@payment_sources) into the checkout payment step. This
|
263
|
+
# method is here only to be able to deprecate this ivar and will be removed.
|
264
|
+
#
|
265
|
+
# DO NOT USE THIS METHOD!
|
266
|
+
#
|
267
|
+
# @return [Array<Spree::PaymentSource>] Payment sources connected to
|
268
|
+
# current user wallet.
|
269
|
+
# @deprecated This method has been added to deprecate @payment_sources
|
270
|
+
# ivar and will be removed. Use @wallet_payment_sources instead.
|
271
|
+
def deprecated_payment_sources
|
272
|
+
try_spree_current_user.wallet.wallet_payment_sources
|
273
|
+
.map(&:payment_source)
|
274
|
+
.select { |ps| ps.is_a?(Spree::CreditCard) }
|
275
|
+
end
|
218
276
|
end
|
219
277
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spree
|
4
|
+
class CouponCodesController < Spree::StoreController
|
5
|
+
before_action :load_order, only: :create
|
6
|
+
around_action :lock_order, only: :create
|
7
|
+
|
8
|
+
def create
|
9
|
+
authorize! :update, @order, cookies.signed[:guest_token]
|
10
|
+
|
11
|
+
if params[:coupon_code].present?
|
12
|
+
@order.coupon_code = params[:coupon_code]
|
13
|
+
handler = PromotionHandler::Coupon.new(@order).apply
|
14
|
+
|
15
|
+
respond_with(@order) do |format|
|
16
|
+
format.html do
|
17
|
+
if handler.successful?
|
18
|
+
flash[:success] = handler.success
|
19
|
+
redirect_to cart_path
|
20
|
+
else
|
21
|
+
flash.now[:error] = handler.error
|
22
|
+
render 'spree/coupon_codes/new'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def load_order
|
32
|
+
@order = current_order
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -7,7 +7,7 @@ module Spree
|
|
7
7
|
requested_locale = params[:switch_to_locale] || params[:locale]
|
8
8
|
|
9
9
|
if requested_locale && available_locales.map(&:to_s).include?(requested_locale)
|
10
|
-
session[
|
10
|
+
session[set_user_language_locale_key] = requested_locale
|
11
11
|
I18n.locale = requested_locale
|
12
12
|
flash.notice = t('spree.locale_changed')
|
13
13
|
else
|
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
module Spree
|
4
4
|
class OrdersController < Spree::StoreController
|
5
|
-
before_action :check_authorization
|
6
5
|
helper 'spree/products', 'spree/orders'
|
7
6
|
|
8
7
|
respond_to :html
|
9
8
|
|
9
|
+
before_action :store_guest_token
|
10
10
|
before_action :assign_order, only: :update
|
11
11
|
# note: do not lock the #edit action because that's where we redirect when we fail to acquire a lock
|
12
12
|
around_action :lock_order, only: :update
|
@@ -15,9 +15,11 @@ module Spree
|
|
15
15
|
|
16
16
|
def show
|
17
17
|
@order = Spree::Order.find_by!(number: params[:id])
|
18
|
+
authorize! :read, @order, cookies.signed[:guest_token]
|
18
19
|
end
|
19
20
|
|
20
21
|
def update
|
22
|
+
authorize! :update, @order, cookies.signed[:guest_token]
|
21
23
|
if @order.contents.update_cart(order_params)
|
22
24
|
@order.next if params.key?(:checkout) && @order.cart?
|
23
25
|
|
@@ -38,12 +40,15 @@ module Spree
|
|
38
40
|
# Shows the current incomplete order from the session
|
39
41
|
def edit
|
40
42
|
@order = current_order || Spree::Order.incomplete.find_or_initialize_by(guest_token: cookies.signed[:guest_token])
|
43
|
+
authorize! :read, @order, cookies.signed[:guest_token]
|
41
44
|
associate_user
|
42
45
|
end
|
43
46
|
|
44
47
|
# Adds a new item to the order (creating a new order if none already exists)
|
45
48
|
def populate
|
46
|
-
@order
|
49
|
+
@order = current_order(create_order_if_necessary: true)
|
50
|
+
authorize! :update, @order, cookies.signed[:guest_token]
|
51
|
+
|
47
52
|
variant = Spree::Variant.find(params[:variant_id])
|
48
53
|
quantity = params[:quantity].present? ? params[:quantity].to_i : 1
|
49
54
|
|
@@ -78,6 +83,7 @@ module Spree
|
|
78
83
|
|
79
84
|
def empty
|
80
85
|
if @order = current_order
|
86
|
+
authorize! :update, @order, cookies.signed[:guest_token]
|
81
87
|
@order.empty!
|
82
88
|
end
|
83
89
|
|
@@ -92,19 +98,12 @@ module Spree
|
|
92
98
|
end
|
93
99
|
end
|
94
100
|
|
95
|
-
|
96
|
-
cookies.permanent.signed[:guest_token] = params[:token] if params[:token]
|
97
|
-
order = Spree::Order.find_by(number: params[:id]) || current_order
|
101
|
+
private
|
98
102
|
|
99
|
-
|
100
|
-
|
101
|
-
else
|
102
|
-
authorize! :create, Spree::Order
|
103
|
-
end
|
103
|
+
def store_guest_token
|
104
|
+
cookies.permanent.signed[:guest_token] = params[:token] if params[:token]
|
104
105
|
end
|
105
106
|
|
106
|
-
private
|
107
|
-
|
108
107
|
def order_params
|
109
108
|
if params[:order]
|
110
109
|
params[:order].permit(*permitted_order_attributes)
|
@@ -120,5 +119,21 @@ module Spree
|
|
120
119
|
redirect_to(root_path) && return
|
121
120
|
end
|
122
121
|
end
|
122
|
+
|
123
|
+
def apply_coupon_code
|
124
|
+
if order_params[:coupon_code].present?
|
125
|
+
Spree::Deprecation.warn('This endpoint is deprecated. Please use `Spree::CouponCodesController#create` endpoint instead.')
|
126
|
+
@order.coupon_code = order_params[:coupon_code]
|
127
|
+
|
128
|
+
handler = PromotionHandler::Coupon.new(@order).apply
|
129
|
+
|
130
|
+
if handler.error.present?
|
131
|
+
flash.now[:error] = handler.error
|
132
|
+
respond_with(@order) { |format| format.html { render :edit } } && return
|
133
|
+
elsif handler.success
|
134
|
+
flash[:success] = handler.success
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
123
138
|
end
|
124
139
|
end
|
@@ -16,24 +16,6 @@ module Spree
|
|
16
16
|
|
17
17
|
private
|
18
18
|
|
19
|
-
# This method is placed here so that the CheckoutController
|
20
|
-
# and OrdersController can both reference it (or any other controller
|
21
|
-
# which needs it)
|
22
|
-
def apply_coupon_code
|
23
|
-
if params[:order] && params[:order][:coupon_code]
|
24
|
-
@order.coupon_code = params[:order][:coupon_code]
|
25
|
-
|
26
|
-
handler = PromotionHandler::Coupon.new(@order).apply
|
27
|
-
|
28
|
-
if handler.error.present?
|
29
|
-
flash.now[:error] = handler.error
|
30
|
-
respond_with(@order) { |format| format.html { render :edit } } && return
|
31
|
-
elsif handler.success
|
32
|
-
flash[:success] = handler.success
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
19
|
def config_locale
|
38
20
|
Spree::Frontend::Config[:locale]
|
39
21
|
end
|
@@ -4,12 +4,11 @@ module Spree
|
|
4
4
|
class TaxonsController < Spree::StoreController
|
5
5
|
helper 'spree/products', 'spree/taxon_filters'
|
6
6
|
|
7
|
+
before_action :load_taxon, only: [:show]
|
8
|
+
|
7
9
|
respond_to :html
|
8
10
|
|
9
11
|
def show
|
10
|
-
@taxon = Spree::Taxon.find_by!(permalink: params[:id])
|
11
|
-
return unless @taxon
|
12
|
-
|
13
12
|
@searcher = build_searcher(params.merge(taxon: @taxon.id, include_images: true))
|
14
13
|
@products = @searcher.retrieve_products
|
15
14
|
@taxonomies = Spree::Taxonomy.includes(root: :children)
|
@@ -17,6 +16,10 @@ module Spree
|
|
17
16
|
|
18
17
|
private
|
19
18
|
|
19
|
+
def load_taxon
|
20
|
+
@taxon = Spree::Taxon.find_by!(permalink: params[:id])
|
21
|
+
end
|
22
|
+
|
20
23
|
def accurate_title
|
21
24
|
if @taxon
|
22
25
|
@taxon.seo_title
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<div class="coupon-code" data-hook='coupon_code'>
|
2
|
+
<%= form_for order, url: update_checkout_path(order.state) do |form| %>
|
3
|
+
<%= form.label :coupon_code %>
|
4
|
+
<%= form.text_field :coupon_code, placeholder: true %>
|
5
|
+
|
6
|
+
<button type="submit" class="button coupon-code-apply-button" id="coupon-code-apply-button">
|
7
|
+
<%= t('spree.apply_code') %>
|
8
|
+
</button>
|
9
|
+
<% end %>
|
10
|
+
|
11
|
+
<div id='coupon_status'></div>
|
12
|
+
</div>
|
@@ -27,7 +27,9 @@
|
|
27
27
|
<% ship_form.object.manifest.each do |item| %>
|
28
28
|
<tr class="stock-item">
|
29
29
|
<td class="item-image">
|
30
|
-
<%= render 'spree/shared/image',
|
30
|
+
<%= render 'spree/shared/image',
|
31
|
+
image: (item.variant.gallery.images.first || item.variant.product.gallery.images.first),
|
32
|
+
size: :mini %>
|
31
33
|
</td>
|
32
34
|
<td class="item-name"><%= item.variant.name %></td>
|
33
35
|
<td class="item-qty"><%= item.quantity %></td>
|
@@ -75,7 +77,9 @@
|
|
75
77
|
<% @differentiator.missing.each do |variant, quantity| %>
|
76
78
|
<tr class="stock-item">
|
77
79
|
<td class="item-image">
|
78
|
-
<%= render 'spree/shared/image',
|
80
|
+
<%= render 'spree/shared/image',
|
81
|
+
image: (variant.gallery.images.first || variant.product.gallery.images.first),
|
82
|
+
size: :mini %>
|
79
83
|
</td>
|
80
84
|
<td class="item-name"><%= variant.name %></td>
|
81
85
|
<td class="item-qty"><%= quantity %></td>
|