Magento2: Shipping modules does not update rate on zipcode changes in guest-checkout page.

Created on 30 Jan 2018  ·  8Comments  ·  Source: magento/magento2

Hi guys, I'm with problems in my custom shipping module, I try this issue, but it is closed ...

Preconditions

Magento CE 2.2.2 - with sample data;
PHP 7.0.24;
Only native modules and my custom shipping module are active.

Steps to reproduce

  1. Add a product in cart.
  2. Go to checkout page (without any authentication).
  3. Try changing address fields one by one.
  4. Try change only zipcode filed.

Expected result

  1. Custom Module should update the rate for shipping each time I change the zip code.

Actual result

  1. The shipping rates are not refreshed when zipcode is changed.

Extra Info:

My module was developed following this simple example and this shipping validators from official documentation.

Bellow some of my files, checkout_index_index.xml:

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
   <body>
      <referenceBlock name="checkout.root">
         <arguments>
                <argument name="jsLayout" xsi:type="array">
                    <item name="components" xsi:type="array">
                        <item name="checkout" xsi:type="array">
                            <item name="children" xsi:type="array">
                                <item name="steps" xsi:type="array">
                                    <item name="children" xsi:type="array">
                                        <item name="shipping-step" xsi:type="array">
                                            <item name="children" xsi:type="array">
                                                <item name="step-config" xsi:type="array">
                                                    <item name="children" xsi:type="array">
                                                        <item name="shipping-rates-validation" xsi:type="array">
                                                            <item name="children" xsi:type="array">
                                                                <item name="inchoo" xsi:type="array">
                                                                    <item name="component" xsi:type="string">Inchoo_Shipping/js/view/inchoo</item>
                                                                </item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

checkout_cart_index.xml:

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="checkout.cart.shipping">
            <arguments>
                <argument name="jsLayout" xsi:type="array">
                    <item name="components" xsi:type="array">
                        <item name="summary-block-config" xsi:type="array">
                            <item name="children" xsi:type="array">
                                <item name="shipping-rates-validation" xsi:type="array">
                                    <item name="children" xsi:type="array">
                                        <item name="inchoo" xsi:type="array">
                                            <item name="component" xsi:type="string">Inchoo_Shipping/js/view/inchoo</item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

My inchoo.js in Inchoo/Shipping/view/frontend/web/js/view/inchoo.js, with this content:

define([
    'uiComponent',
    'Magento_Checkout/js/model/shipping-rates-validator',
    'Magento_Checkout/js/model/shipping-rates-validation-rules',
    '../model/inchoo-validatior',
    '../model/inchoo-rules'
],function (
        Component,
        defaultShippingRatesValidator,
        defaultShippingRatesValidationRules,
        shippingRatesValidator,
        shippingRatesValidationRules
    ) {
        'use strict';
        defaultShippingRatesValidator.registerValidator('carrierName', shippingRatesValidator);
        defaultShippingRatesValidationRules.registerRules('carrierName', shippingRatesValidationRules);
        return Component;
    }
);

My inchoo-rules.js:

define(
    [],
    function () {
        'use strict';
        return {
            getRules: function() {
                return {
                    'postcode': {
                        'required': true
                    }
                };
            }
        };
    }
)

And Finally my inchoo-validator.js:

define(
    [
        'jquery',
        'mageUtils',

        './inchoo-rules',
        'mage/translate'
    ],
    function ($, utils, validationRules, $t) {
        'use strict';
        return {
            validationErrors: [],
            validate: function(address) {
                var self = this;
                this.validationErrors = [];
                $.each(validationRules.getRules(), function(field, rule) {
                    if (rule.required && utils.isEmpty(address[field])) {
                        var message = $t('Field ') + field + $t(' is required.');
                        self.validationErrors.push(message);
                    }
                });
                return !Boolean(this.validationErrors.length);
            }
        };
    }
);

I've noticed that inchoo.js file is not loaded.
And when a change postcode value, nothing happens as well.

Thanks in advance.

Format is valid non-issue

Most helpful comment

Hi @luizpaulofranz I had the same problem. The problem is on your xml definition of the rates validation:

<item name="shipping-rates-validation" xsi:type="array">
                                                            <item name="children" xsi:type="array">
                                                                <item name="inchoo" xsi:type="array">
                                                                    <item name="component" xsi:type="string">Inchoo_Shipping/js/view/inchoo</item>
                                                                </item>
                                                            </item>
                                                        </item>

In your xml, when you define the js validator:

<item name="inchoo" xsi:type="array">

You must change the name to:

<item name="inchoo-rates-validation" xsi:type="array">

And inchoo must be the same as carrier code of your shipping method. The problem is when magento try lo find and load all validators in :

...vendor/magento/module-checkout/Block/Checkout/LayoutProcessor.php

on method processShippingChildrenComponents

    private function processShippingChildrenComponents($shippingRatesLayout)
    {
        $activeCarriers = $this->getShippingConfig()->getActiveCarriers(
            $this->getStoreResolver()->getCurrentStoreId()
        );
        foreach (array_keys($shippingRatesLayout) as $carrierName) {
            $carrierKey = str_replace('-rates-validation', '', $carrierName);
            if (!array_key_exists($carrierKey, $activeCarriers)) {
                unset($shippingRatesLayout[$carrierName]);
            }
        }
        return $shippingRatesLayout;
    }

If magento does not find the same name as carrier, unset the file in layout.

Regards
Mauro M. Martinez

All 8 comments

@luizpaulofranz this kind of issue should post on https://magento.stackexchange.com/

Hi @luizpaulofranz I had the same problem. The problem is on your xml definition of the rates validation:

<item name="shipping-rates-validation" xsi:type="array">
                                                            <item name="children" xsi:type="array">
                                                                <item name="inchoo" xsi:type="array">
                                                                    <item name="component" xsi:type="string">Inchoo_Shipping/js/view/inchoo</item>
                                                                </item>
                                                            </item>
                                                        </item>

In your xml, when you define the js validator:

<item name="inchoo" xsi:type="array">

You must change the name to:

<item name="inchoo-rates-validation" xsi:type="array">

And inchoo must be the same as carrier code of your shipping method. The problem is when magento try lo find and load all validators in :

...vendor/magento/module-checkout/Block/Checkout/LayoutProcessor.php

on method processShippingChildrenComponents

    private function processShippingChildrenComponents($shippingRatesLayout)
    {
        $activeCarriers = $this->getShippingConfig()->getActiveCarriers(
            $this->getStoreResolver()->getCurrentStoreId()
        );
        foreach (array_keys($shippingRatesLayout) as $carrierName) {
            $carrierKey = str_replace('-rates-validation', '', $carrierName);
            if (!array_key_exists($carrierKey, $activeCarriers)) {
                unset($shippingRatesLayout[$carrierName]);
            }
        }
        return $shippingRatesLayout;
    }

If magento does not find the same name as carrier, unset the file in layout.

Regards
Mauro M. Martinez

Hi @luizpaulofranz
Did you help the last comment from @mauromm

Hi, thanks for reply.
I follow your tips, but here, it does not work yet ...

I change the checkout_index_index.xml to:

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="checkout.root">
            <arguments>
                <argument name="jsLayout" xsi:type="array">
                    <item name="components" xsi:type="array">
                        <item name="checkout" xsi:type="array">
                            <item name="children" xsi:type="array">
                                <item name="steps" xsi:type="array">
                                    <item name="children" xsi:type="array">
                                        <item name="shipping-step" xsi:type="array">
                                            <item name="children" xsi:type="array">
                                                <item name="step-config" xsi:type="array">
                                                    <item name="children" xsi:type="array">
                                                        <item name="shipping-rates-validation" xsi:type="array">
                                                            <item name="children" xsi:type="array">
                                                                <item name="inchoo-rates-validation" xsi:type="array">
                                                                    <item name="component" xsi:type="string">Inchoo_Shipping/js/view/shipping-rates-validation</item>
                                                                </item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

And in my Model\Carrier\Example

All shipping code references are with "inchoo" value.

@mauromm can you see my code here? I just can't see what is wrong.

Thanks in advance.

Hi, I found the problem, thanks to @mauromm.
In my etc/adminhtml/system.xml, my code was:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
    <system>
        <section id="carriers" translate="label" type="text" sortOrder="320" showInDefault="1" showInWebsite="1" showInStore="1">
            <!--Esse id deve ser igual ao codigo desse carrier, setado na model-->
            <group id="example" translate="label" type="text" sortOrder="0" showInDefault="1" showInWebsite="1" showInStore="1">
...

I've just changed the <group id="example" ... to <group id="inchoo" ..., and all starts to work! This ID must be equal to the carrier code defined in my model.

Thanks again to @mauromm. This issue can be closed.

Hi @luizpaulofranz
Thanks for you answer

@luizpaulofranz, thank you for your report.
This seems to be correct Magento behavior. Please refer to the Community Forums or the Magento Stack Exchange site for advice or general discussion about this.
Otherwise you may submit Pull Request with the suggested changes.

Was this page helpful?
0 / 5 - 0 ratings