Magento2: Checkout shipping method is preselected if only one rate available

Created on 23 Aug 2017  Â·  8Comments  Â·  Source: magento/magento2

When you reach checkout and you have more than one rate available in shipping options and choose a rate that suits you , then change shipping country (or whatever affects rate availability) that limits the rates to one option available (disabling the one chosen before) you end up with preselected rate that was not chosen by customer as a silent option .

Preconditions


  1. M 2.1.* (not tested in 2.2 but probably there as well)

Steps to reproduce

  1. reach checkout (I'm using sample data configuration)
  2. default state is US providing two rate options (table rate and fixed)
  3. choose Table Rate
  4. change country to Uruguay (or any other country)
  5. rates are reloaded, fixed option is preselected , this was not customer choice
  6. customer can place a order with options not agreed in clear manner

Expected result

  1. if rates are reloaded and customer manually made option is not available no rates should be selected to indicate the need of making this decision again. Merchant (or a bug in software) cant make that decision for the customer (monetary decision, customer preference etc) if the shipping option they use is not free

Actual result

  1. what happens is that if only one rate is available template has hardcorded option to select that option.

<input class="radio" type="radio" data-bind="attr: { checked: $parent.rates().length == 1, .....>

where

$parent.rates().length == 1 binding decides on frontend (without knowing if this option is ever selected or available in backend on order placement time) template that something should be selected if only one option is available

  1. here's a screen recording http://quick.as/gVYZunk7a

Format is valid

Most helpful comment

Hey @pboisvert

Please open this again as this is a bug and you can't override this feature without replacing whole template and specific template is not a small template but rather large part of checkout where lot of 3rd party extensions meet to customise the features.

If this is a desirable option (feature) please implement this as a method call (like it is when multiple rates are available) that developers can override with mixin, method wrap or at least change without having to implement business logic in template level.

The bug is clearly there cause even if the method is not selected in system level the option is selected as it depends on counting existing rates (often from cache) not on fact if method is actually selected and stored as user selection . On top of that since this a binding to observable this can't be unselected at all with other code easily to change the "feature"

If you needa real life scenario why this is bad then imagine a website that does 15k orders per day:

  1. user arrives to checkout and has a default selected (not stored as a selection in quote shipping address jet) shipping method for incomplete address data lets say 2€, user overviews and applauds for a small rate
  2. user fills up address data and specifies a address that reloads shipping rates and has a new rate calculated per exact details lets say 20€ and automatically selected
  3. since its automatically selected and user can "streamline" to the next screen where shipping choice as a selection is hidden and forgets to verify this little price hike (10*) and this can (and often will) result as cancelled order, increased cost on administrating the order, more support load or returned goods

All 8 comments

This is not a bug but as designed. The goal of checkout is to streamline the flow for shoppers. The method and charge are shown (not hidden) and pre-selecting saves the effort of making a selection when there is only one choice. Clicking Next is implicitly accepting the method and accompanying charge. As such closing this issue.

If there are country specific legislation mandating it must be a selection then please provide references for such so we can consider adding this configuration to the backlog.

Hey @pboisvert

Please open this again as this is a bug and you can't override this feature without replacing whole template and specific template is not a small template but rather large part of checkout where lot of 3rd party extensions meet to customise the features.

If this is a desirable option (feature) please implement this as a method call (like it is when multiple rates are available) that developers can override with mixin, method wrap or at least change without having to implement business logic in template level.

The bug is clearly there cause even if the method is not selected in system level the option is selected as it depends on counting existing rates (often from cache) not on fact if method is actually selected and stored as user selection . On top of that since this a binding to observable this can't be unselected at all with other code easily to change the "feature"

If you needa real life scenario why this is bad then imagine a website that does 15k orders per day:

  1. user arrives to checkout and has a default selected (not stored as a selection in quote shipping address jet) shipping method for incomplete address data lets say 2€, user overviews and applauds for a small rate
  2. user fills up address data and specifies a address that reloads shipping rates and has a new rate calculated per exact details lets say 20€ and automatically selected
  3. since its automatically selected and user can "streamline" to the next screen where shipping choice as a selection is hidden and forgets to verify this little price hike (10*) and this can (and often will) result as cancelled order, increased cost on administrating the order, more support load or returned goods

I will report this again

it is just insane , for this line

checked: $parent.rates().length == 1

you have to rewrite whole template "Magento_Checkout/shipping" cause you can't deselect a radio cause it's not actually selected or rate accepted by customer

will review. Obviously our goal is not not have checkout be complex to modify but that doesn't make the issue a bug. The cart contents are displayed along with shipping rate so it is not hidden--just not as explicit as selecting each time. I can see an argument to make this configurable for merchants that are concerned. Just seems like an extreme use case when only one rate applies and the buyer is switching the country after selecting a different country and shipping rate first.

Hello,

How do we disable this feature? because we set up a free shipping , and sometime the free shipping is auto applied, and we don't want that.

Thank you

rewrite a template, i just replaced the part when template is loaded with ajax as follows

`renderer.render = _.wrap(renderer.render , function (originalMethod, tmplPath) {
var loadPromise = loader.loadTemplate(tmplPath);
return loadPromise.then(renderer.parseTemplate.bind(renderer,tmplPath));
});

renderer.parseTemplate = _.wrap(renderer.parseTemplate , function (originalMethod,tmplPath, html) {
if (tmplPath === "Magento_Checkout/shipping") {
html = html.replace("checked: $parent.rates().length == 1", "checked: $parent.isSelected");
}
return originalMethod(html);
});`

related dependencies are

"Magento_Ui/js/lib/knockout/template/renderer", "Magento_Ui/js/lib/knockout/template/loader"

Also running into this issue in 2.2.

@speedupmate Is the expected behavior that all of the available shipping methods for that shipping address be shown, and if a method has previously been selected then it is selected, but still gives the option to change the shipping method?

@SimonAnguish

expected behaviour is not a selection of method based on available methods array length cause this is a business logic implemented in template level without having a knowledge if this method is actually selected in quote by user or not.

right now template decides if the radio has to be selected by rate array length and has no idea if the rate in that array is a actually selected method.

you can expect different things from this but the selected state always have to come from customer decision or setup decision (usually only once) . Customer decision is reflected in quote state and setup decision can be a parameter that is counted on quote creation time.

Was this page helpful?
0 / 5 - 0 ratings