From 4e5cbd46f50287b96b1bafd6e3d53bc05246113e Mon Sep 17 00:00:00 2001 From: Martin Tomov Date: Fri, 6 May 2016 08:31:33 +0100 Subject: [PATCH 1/2] Improve coupon code JS applicator - separate Coupon code application from Saving & processing a payment => allows users to first apply a code, and subsequently add payment details when they are certain of the final amount to be paid. - Add new button Apply Code - Separate payment js from coupon code js - allows for easier override as they are now in separate files. - Allow customisation of the CSS classes applied on success and on error via data attributes `data-success-class` and `data-success-error`. - Fix a refresh bug on coupon code application error - before, the page was refreshed even after displaying an AJAX brought error message. See issue & fix @Spree https://github.com/spree/spree/pull/7040 - Fixes a JS warning that a Synchronous AJAX request was executed, which could impact JS performance as it waits for response from the server before continuing the execution of the JS. (Was coming from the `async:false` setting in `Spree.ajax`) - Switch to using the Spree API action for applying a code instead of the Frontend controller one at StoreController#apply_code. TODO: Delete the StoreController#apply_code similarly to Spree as it's not used anymore. See: https://github.com/spree/spree/pull/7284 --- CHANGELOG.md | 5 +++ core/config/locales/en.yml | 1 + .../spree/frontend/checkout.js.coffee | 9 ++--- .../frontend/checkout/coupon-code.js.coffee | 34 ++++++++++++++++++ .../spree/frontend/checkout/payment.js.coffee | 36 ------------------- .../views/spree/checkout/_payment.html.erb | 8 +++++ frontend/spec/features/checkout_spec.rb | 15 ++++---- 7 files changed, 60 insertions(+), 48 deletions(-) create mode 100644 frontend/app/assets/javascripts/spree/frontend/checkout/coupon-code.js.coffee diff --git a/CHANGELOG.md b/CHANGELOG.md index b4eb7fd2866..a9eebaa64de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -136,6 +136,11 @@ * Partials are rendered on pages owned by the partials as tabs as a top bar * Admin-nav has a sub-menu for the settings now +* Coupon code application has been separated from the Continue button on the Payment checkout page + + * JavaScript for it has been moved from address.js into its own `spree/frontend/checkout/coupon-code` + * Numerous small nuisances have been fixed [#1090](https://github.com/solidusio/solidus/pull/1090) + ## Solidus 1.2.0 (2016-01-26) * Admin menu has been moved from top of the page to the left side. diff --git a/core/config/locales/en.yml b/core/config/locales/en.yml index a2ac69b663d..2e75d53a75d 100644 --- a/core/config/locales/en.yml +++ b/core/config/locales/en.yml @@ -783,6 +783,7 @@ en: analytics_desc_list_4: It's completely free! analytics_trackers: Analytics Trackers and: and + apply_code: Apply Code approve: approve approver: Approver approved_at: Approved at diff --git a/frontend/app/assets/javascripts/spree/frontend/checkout.js.coffee b/frontend/app/assets/javascripts/spree/frontend/checkout.js.coffee index 7b062b128a0..50a2350678b 100644 --- a/frontend/app/assets/javascripts/spree/frontend/checkout.js.coffee +++ b/frontend/app/assets/javascripts/spree/frontend/checkout.js.coffee @@ -1,7 +1,8 @@ -//= require jquery.payment -//= require_self -//= require spree/frontend/checkout/address -//= require spree/frontend/checkout/payment +#= require jquery.payment +#= require_self +#= require spree/frontend/checkout/address +#= require spree/frontend/checkout/payment +#= require spree/frontend/checkout/coupon-code Spree.disableSaveOnClick = -> ($ 'form.edit_order').submit -> diff --git a/frontend/app/assets/javascripts/spree/frontend/checkout/coupon-code.js.coffee b/frontend/app/assets/javascripts/spree/frontend/checkout/coupon-code.js.coffee new file mode 100644 index 00000000000..d51da6007ab --- /dev/null +++ b/frontend/app/assets/javascripts/spree/frontend/checkout/coupon-code.js.coffee @@ -0,0 +1,34 @@ +Spree.onCouponCodeApply = (e) -> + couponCodeField = $('#order_coupon_code') + couponCode = $.trim(couponCodeField.val()) + return if couponCode == '' + + couponStatus = $("#coupon_status") + successClass = couponStatus.data('success-class') || 'success' + errorClass = couponStatus.data('error-class') || 'error' + url = Spree.url(Spree.routes.apply_coupon_code(Spree.current_order_id), + { + order_token: Spree.current_order_token, + coupon_code: couponCode + } + ) + + couponStatus.removeClass([successClass,errorClass].join(" ")); + + req = Spree.ajax + method: "PUT", + url: url + + req.done (data) -> + window.location.reload(); + couponCodeField.val('') + couponStatus.addClass(successClass).html("Coupon code applied successfully.") + + req.fail (xhr) -> + # handler = JSON.parse(xhr.responseText) + handler = xhr.responseJSON + couponStatus.addClass(errorClass).html(handler["error"]) + +Spree.ready ($) -> + $('#coupon-code-apply-button').click (e) -> + Spree.onCouponCodeApply(e) diff --git a/frontend/app/assets/javascripts/spree/frontend/checkout/payment.js.coffee b/frontend/app/assets/javascripts/spree/frontend/checkout/payment.js.coffee index 747016a7d71..b02182a080e 100644 --- a/frontend/app/assets/javascripts/spree/frontend/checkout/payment.js.coffee +++ b/frontend/app/assets/javascripts/spree/frontend/checkout/payment.js.coffee @@ -40,40 +40,4 @@ Spree.ready ($) -> # i.e. if user enters invalid data ($ 'input[type="radio"]:checked').click() - $('#checkout_form_payment').submit -> - # Coupon code application may take a number of seconds. - # Informing the user that this is happening is a good way to indicate some progress to them. - # In addition to this, if the coupon code FAILS then they don't lose their just-entered payment data. - coupon_code_field = $('#order_coupon_code') - coupon_code = $.trim(coupon_code_field.val()) - if (coupon_code != '') - if $('#coupon_status').length == 0 - coupon_status = $("
") - coupon_code_field.parent().append(coupon_status) - else - coupon_status = $("#coupon_status") - - url = Spree.url(Spree.routes.apply_coupon_code(Spree.current_order_id), - { - order_token: Spree.current_order_token, - coupon_code: coupon_code - } - ) - - coupon_status.removeClass(); - Spree.ajax({ - async: false, - method: "PUT", - url: url, - success: (data) -> - coupon_code_field.val('') - coupon_status.addClass("success").html("Coupon code applied successfully.") - return true - error: (xhr) -> - handler = JSON.parse(xhr.responseText) - coupon_status.addClass("error").html(handler["error"]) - $('.continue').attr('disabled', false) - return false - }) - Spree.onPayment() diff --git a/frontend/app/views/spree/checkout/_payment.html.erb b/frontend/app/views/spree/checkout/_payment.html.erb index bce0c229faa..1fb48707ae6 100644 --- a/frontend/app/views/spree/checkout/_payment.html.erb +++ b/frontend/app/views/spree/checkout/_payment.html.erb @@ -59,7 +59,15 @@

<%= form.label :coupon_code %>
<%= form.text_field :coupon_code %> +

+
+
+ diff --git a/frontend/spec/features/checkout_spec.rb b/frontend/spec/features/checkout_spec.rb index 4efe0fa82a9..d1c742fee80 100644 --- a/frontend/spec/features/checkout_spec.rb +++ b/frontend/spec/features/checkout_spec.rb @@ -317,7 +317,7 @@ end end - context "in coupon promotion, submits coupon along with payment", js: true do + context "Coupon promotions", js: true do let!(:promotion) { create(:promotion, name: "Huhuhu", code: "huhu") } let!(:calculator) { Spree::Calculator::FlatPercentItemTotal.create(preferred_flat_percent: "10") } let!(:action) { Spree::Promotion::Actions::CreateItemAdjustments.create(calculator: calculator) } @@ -336,20 +336,19 @@ expect(page).to have_current_path(spree.checkout_state_path("payment")) end - it "makes sure payment reflects order total with discounts" do + it "applies them & refreshes the page on user clicking the Apply Code button" do fill_in "Coupon Code", with: promotion.codes.first.value - click_on "Save and Continue" + click_on "Apply Code" expect(page).to have_content(promotion.name) - expect(Spree::Payment.first.amount.to_f).to eq Spree::Order.last.total.to_f + expect(page).to have_content("-$2.00") end - context "invalid coupon" do - it "doesnt create a payment record" do + context "with invalid coupon" do + it "doesnt apply the promotion" do fill_in "Coupon Code", with: 'invalid' - click_on "Save and Continue" + click_on "Apply Code" - expect(Spree::Payment.count).to eq 0 expect(page).to have_content(Spree.t(:coupon_code_not_found)) end end From 3f559e4fa764bdd599e7f18a283d5dec341c0938 Mon Sep 17 00:00:00 2001 From: Martin Tomov Date: Fri, 6 May 2016 09:01:25 +0100 Subject: [PATCH 2/2] Rely on pre-configured CSS classes for coupon status messages. - Specify your own class as a main one, ex: `callout` - The JS applicator will automatically add `success` or `alert` classes as appropriate --- .../spree/frontend/checkout/coupon-code.js.coffee | 4 ++-- .../app/assets/stylesheets/spree/frontend/screen.css.scss | 2 +- frontend/app/views/spree/checkout/_payment.html.erb | 6 ++---- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/frontend/app/assets/javascripts/spree/frontend/checkout/coupon-code.js.coffee b/frontend/app/assets/javascripts/spree/frontend/checkout/coupon-code.js.coffee index d51da6007ab..a8168c0f44f 100644 --- a/frontend/app/assets/javascripts/spree/frontend/checkout/coupon-code.js.coffee +++ b/frontend/app/assets/javascripts/spree/frontend/checkout/coupon-code.js.coffee @@ -4,8 +4,8 @@ Spree.onCouponCodeApply = (e) -> return if couponCode == '' couponStatus = $("#coupon_status") - successClass = couponStatus.data('success-class') || 'success' - errorClass = couponStatus.data('error-class') || 'error' + successClass = 'success' + errorClass = 'alert' url = Spree.url(Spree.routes.apply_coupon_code(Spree.current_order_id), { order_token: Spree.current_order_token, diff --git a/frontend/app/assets/stylesheets/spree/frontend/screen.css.scss b/frontend/app/assets/stylesheets/spree/frontend/screen.css.scss index 96932dbb25d..bcbb7ac1cef 100644 --- a/frontend/app/assets/stylesheets/spree/frontend/screen.css.scss +++ b/frontend/app/assets/stylesheets/spree/frontend/screen.css.scss @@ -920,7 +920,7 @@ p[data-hook="use_billing"] { &.success { color: $c_green; } - &.error { + &.error, &.alert { color: $c_red; } } diff --git a/frontend/app/views/spree/checkout/_payment.html.erb b/frontend/app/views/spree/checkout/_payment.html.erb index 1fb48707ae6..14e89417496 100644 --- a/frontend/app/views/spree/checkout/_payment.html.erb +++ b/frontend/app/views/spree/checkout/_payment.html.erb @@ -62,11 +62,9 @@ +

-
-
+