Skip to content

Commit 4857815

Browse files
authored
Merge pull request #2327 from nebulab/coupon-code-into-summary
Move checkout coupon code section into summary
2 parents 146c69d + 212287a commit 4857815

File tree

11 files changed

+260
-68
lines changed

11 files changed

+260
-68
lines changed

frontend/app/assets/javascripts/spree/frontend/checkout/coupon-code.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
Spree.onCouponCodeApply = function(e) {
2+
e.preventDefault();
23
var couponCodeField = $("#order_coupon_code");
34
var couponCode = $.trim(couponCodeField.val());
45
if (couponCode === "") {

frontend/app/assets/stylesheets/spree/frontend/screen.css.scss

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -948,9 +948,35 @@ p[data-hook="use_billing"] {
948948
padding: 5px;
949949
}
950950

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+
951976
#coupon_status {
977+
margin-top: 10px;
952978
font-weight: bold;
953-
font-size: 125%;
979+
font-size: 100%;
954980
&.success {
955981
color: $c_green;
956982
}

frontend/app/controllers/spree/checkout_controller.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,23 @@ def completion_route
166166
spree.order_path(@order)
167167
end
168168

169+
def apply_coupon_code
170+
if update_params[:coupon_code].present?
171+
@order.coupon_code = update_params[:coupon_code]
172+
173+
handler = PromotionHandler::Coupon.new(@order).apply
174+
175+
if handler.error.present?
176+
flash.now[:error] = handler.error
177+
elsif handler.success
178+
flash[:success] = handler.success
179+
end
180+
181+
setup_for_current_state
182+
respond_with(@order) { |format| format.html { render :edit } } && return
183+
end
184+
end
185+
169186
def setup_for_current_state
170187
method_name = :"before_#{@order.state}"
171188
send(method_name) if respond_to?(method_name, true)

frontend/app/controllers/spree/orders_controller.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,5 +120,20 @@ def assign_order
120120
redirect_to(root_path) && return
121121
end
122122
end
123+
124+
def apply_coupon_code
125+
if order_params[:coupon_code].present?
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
123138
end
124139
end

frontend/app/controllers/spree/store_controller.rb

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,6 @@ def cart_link
1616

1717
private
1818

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-
3719
def config_locale
3820
Spree::Frontend::Config[:locale]
3921
end
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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: :coupon_code %>
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>

frontend/app/views/spree/checkout/_payment.html.erb

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,6 @@
5656
<% end %>
5757
</ul>
5858
<br style="clear:both;" />
59-
<p class='field' data-hook='coupon_code'>
60-
<%= form.label :coupon_code %>
61-
<%= form.text_field :coupon_code %>
62-
<button type="button" class="button" id="coupon-code-apply-button">
63-
<%= t('spree.apply_code') %>
64-
</button>
65-
66-
</p>
67-
<div id='coupon_status'></div>
68-
6959
</div>
7060
</fieldset>
7161

frontend/app/views/spree/checkout/_summary.html.erb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,7 @@
7070
</tr>
7171
</tbody>
7272
</table>
73+
74+
<% if order.state == 'payment' %>
75+
<%= render 'coupon_code', order: order %>
76+
<% end %>

frontend/spec/controllers/spree/checkout_controller_spec.rb

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,4 +478,62 @@ def post_address
478478
post :update, params: { state: "payment" }
479479
}.to change { order.line_items.to_a.size }.from(1).to(0)
480480
end
481+
482+
context 'trying to apply a coupon code' do
483+
let(:order) { create(:order_with_line_items, state: 'payment', guest_token: 'a token') }
484+
let(:coupon_code) { "coupon_code" }
485+
486+
before { cookies.signed[:guest_token] = order.guest_token }
487+
488+
context "when coupon code is empty" do
489+
let(:coupon_code) { "" }
490+
491+
it 'does not try to apply coupon code' do
492+
expect(Spree::PromotionHandler::Coupon).not_to receive :new
493+
494+
put :update, params: { state: order.state, order: { coupon_code: coupon_code } }
495+
496+
expect(response).to redirect_to(spree.checkout_state_path('confirm'))
497+
end
498+
end
499+
500+
context "when coupon code is applied" do
501+
let(:promotion_handler) { instance_double('Spree::PromotionHandler::Coupon', error: nil, success: 'Coupon Applied!') }
502+
503+
it "continues checkout flow normally" do
504+
expect(Spree::PromotionHandler::Coupon)
505+
.to receive_message_chain(:new, :apply)
506+
.and_return(promotion_handler)
507+
508+
put :update, params: { state: order.state, order: { coupon_code: coupon_code } }
509+
510+
expect(response).to render_template :edit
511+
expect(flash.now[:success]).to eq('Coupon Applied!')
512+
end
513+
514+
context "when coupon code is not applied" do
515+
let(:promotion_handler) { instance_double('Spree::PromotionHandler::Coupon', error: 'Some error', success: false) }
516+
517+
it "setups the current step correctly before rendering" do
518+
expect(Spree::PromotionHandler::Coupon)
519+
.to receive_message_chain(:new, :apply)
520+
.and_return(promotion_handler)
521+
expect(controller).to receive(:setup_for_current_state)
522+
523+
put :update, params: { state: order.state, order: { coupon_code: coupon_code } }
524+
end
525+
526+
it "render cart with coupon error" do
527+
expect(Spree::PromotionHandler::Coupon)
528+
.to receive_message_chain(:new, :apply)
529+
.and_return(promotion_handler)
530+
531+
put :update, params: { state: order.state, order: { coupon_code: coupon_code } }
532+
533+
expect(response).to render_template :edit
534+
expect(flash.now[:error]).to eq('Some error')
535+
end
536+
end
537+
end
538+
end
481539
end

frontend/spec/controllers/spree/orders_controller_spec.rb

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,53 @@
128128
put :update, params: { checkout: true }
129129
expect(response).to redirect_to checkout_state_path('address')
130130
end
131+
132+
context 'trying to apply a coupon code' do
133+
let(:order) { create(:order_with_line_items, state: 'cart') }
134+
let(:coupon_code) { "coupon_code" }
135+
136+
context "when coupon code is empty" do
137+
let(:coupon_code) { "" }
138+
139+
it 'does not try to apply coupon code' do
140+
expect(Spree::PromotionHandler::Coupon).not_to receive :new
141+
142+
put :update, params: { state: order.state, order: { coupon_code: coupon_code } }
143+
144+
expect(response).to redirect_to(spree.cart_path)
145+
end
146+
end
147+
148+
context "when coupon code is applied" do
149+
let(:promotion_handler) { instance_double('Spree::PromotionHandler::Coupon', error: nil, success: 'Coupon Applied!') }
150+
151+
it "continues checkout flow normally" do
152+
expect(Spree::PromotionHandler::Coupon)
153+
.to receive_message_chain(:new, :apply)
154+
.and_return(promotion_handler)
155+
156+
put :update, params: { state: order.state, order: { coupon_code: coupon_code } }
157+
158+
expect(response).to redirect_to(spree.cart_path)
159+
expect(flash.now[:success]).to eq('Coupon Applied!')
160+
end
161+
162+
context "when coupon code is not applied" do
163+
let(:promotion_handler) { instance_double('Spree::PromotionHandler::Coupon', error: 'Some error', success: false) }
164+
165+
it "render cart with coupon error" do
166+
expect(Spree::PromotionHandler::Coupon)
167+
.to receive_message_chain(:new, :apply)
168+
.and_return(promotion_handler)
169+
170+
put :update, params: { state: order.state, order: { coupon_code: coupon_code } }
171+
172+
expect(response).to render_template :edit
173+
expect(flash.now[:error]).to eq('Some error')
174+
end
175+
end
176+
end
177+
end
131178
end
132179
end
133180

0 commit comments

Comments
 (0)