Magento 2 Ajouter une liste déroulante à la méthode d'expédition

16

Je développe une méthode d'expédition pour une entreprise logistique. Cette entreprise possède de nombreux bureaux où le client peut obtenir sa commande. Je peux obtenir la liste des bureaux par ville dans l' API, mais je ne sais pas comment mieux représenter cette étape?

Pour l'instant je viens de mettre de nouveaux \Magento\Quote\Model\Quote\Address\RateResult\Method bureaux dans chaque bureau de la ville, dans les grandes villes, c'est un compte> 100 et je pense que ce n'est pas très bien de mettre 100 lignes en caisse.

Ce sera un module public pour différentes conceptions de paiement, alors comment puis-je afficher près de ma méthode d'expédition une liste déroulante avec une liste de bureaux et définir le prix et la méthode après que l'utilisateur en a sélectionné une.

Jamess Moriarty
la source
@Zefiryn J'ai trouvé ce post très intéressant, mais j'ai une question, si je dois montrer dans la sélection non pas les bureaux mais les magasins qui sont à l'intérieur du module d'Amasty, comment je ferais la deuxième partie de votre post? Je veux dire: où est l'endroit où j'appelle l'aide d'Amasty pour remplir le composant xml "vendor_carrier_form"? Merci
maverickk89
Si vous avez une nouvelle question, veuillez la poser en cliquant sur le bouton Poser une question . Incluez un lien vers cette question si cela permet de fournir un contexte. - De l'avis
Jai
ce n'est pas une nouvelle question mais une variation de la manière utilisée par Zefiryn ... parce que j'ai utilisé la première partie du message telle qu'elle est
maverickk89

Réponses:

17

Le paiement Magento ne prend en charge aucun type de formulaire pour les données supplémentaires sur la méthode d'expédition. Mais il fournit un shippingAdditionalblocage dans la caisse qui peut être utilisé pour cela. La solution suivante fonctionnera pour le paiement standard de magento.

Préparons d'abord notre conteneur où nous pouvons mettre une forme. Pour ce faire, créez un fichier dansview/frontend/layout/checkout_index_index.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" 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="shippingAddress" xsi:type="array">
                                                    <item name="children" xsi:type="array">
                                                        <item name="shippingAdditional" xsi:type="array">
                                                            <item name="component" xsi:type="string">uiComponent</item>
                                                            <item name="displayArea" xsi:type="string">shippingAdditional</item>
                                                            <item name="children" xsi:type="array">
                                                                <item name="vendor_carrier_form" xsi:type="array">
                                                                    <item name="component" xsi:type="string">Vendor_Module/js/view/checkout/shipping/form</item>
                                                                </item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

Créez maintenant un fichier dans Vendor/Module/view/frontend/web/js/view/checkout/shipping/form.jslequel sera rendu un modèle de knockout. Son contenu ressemble à ceci

define([
    'jquery',
    'ko',
    'uiComponent',
    'Magento_Checkout/js/model/quote',
    'Magento_Checkout/js/model/shipping-service',
    'Vendor_Module/js/view/checkout/shipping/office-service',
    'mage/translate',
], function ($, ko, Component, quote, shippingService, officeService, t) {
    'use strict';

    return Component.extend({
        defaults: {
            template: 'Vendor_Module/checkout/shipping/form'
        },

        initialize: function (config) {
            this.offices = ko.observableArray();
            this.selectedOffice = ko.observable();
            this._super();
        },

        initObservable: function () {
            this._super();

            this.showOfficeSelection = ko.computed(function() {
                return this.ofices().length != 0
            }, this);

            this.selectedMethod = ko.computed(function() {
                var method = quote.shippingMethod();
                var selectedMethod = method != null ? method.carrier_code + '_' + method.method_code : null;
                return selectedMethod;
            }, this);

            quote.shippingMethod.subscribe(function(method) {
                var selectedMethod = method != null ? method.carrier_code + '_' + method.method_code : null;
                if (selectedMethod == 'carrier_method') {
                    this.reloadOffices();
                }
            }, this);

            this.selectedOffice.subscribe(function(office) {
                if (quote.shippingAddress().extensionAttributes == undefined) {
                    quote.shippingAddress().extensionAttributes = {};
                }
                quote.shippingAddress().extensionAttributes.carrier_office = office;
            });


            return this;
        },

        setOfficeList: function(list) {
            this.offices(list);
        },

        reloadOffices: function() {
            officeService.getOfficeList(quote.shippingAddress(), this);
            var defaultOffice = this.offices()[0];
            if (defaultOffice) {
                this.selectedOffice(defaultOffice);
            }
        },

        getOffice: function() {
            var office;
            if (this.selectedOffice()) {
                for (var i in this.offices()) {
                    var m = this.offices()[i];
                    if (m.name == this.selectedOffice()) {
                        office = m;
                    }
                }
            }
            else {
                office = this.offices()[0];
            }

            return office;
        },

        initSelector: function() {
            var startOffice = this.getOffice();
        }
    });
});

Ce fichier utilise un modèle knockout qui doit être placé dans Vendor/Module/view/frontend/web/template/checkout/shipping/form.html

<div id="carrier-office-list-wrapper" data-bind="visible: selectedMethod() == 'carrier_method'">
    <p data-bind="visible: !showOfficeSelection(), i18n: 'Please provide postcode to see nearest offices'"></p>
    <div data-bind="visible: showOfficeSelection()">
        <p>
            <span data-bind="i18n: 'Select pickup office.'"></span>
        </p>
        <select id="carrier-office-list" data-bind="options: offices(),
                                            value: selectedOffice,
                                            optionsValue: 'name',
                                            optionsText: function(item){return item.location + ' (' + item.name +')';}">
        </select>
    </div>
</div>

Nous avons maintenant un champ de sélection qui sera visible lorsque notre méthode (définie par son code) sera sélectionnée dans le tableau des méthodes d'expédition. Il est temps de le remplir avec quelques options. Comme les valeurs dépendent de l'adresse, le meilleur moyen est de créer un point de terminaison de repos qui fournira les options disponibles. DansVendor/Module/etc/webapi.xml

<?xml version="1.0"?>

<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">

    <!-- Managing Office List on Checkout page -->
    <route url="/V1/module/get-office-list/:postcode/:city" method="GET">
        <service class="Vendor\Module\Api\OfficeManagementInterface" method="fetchOffices"/>
        <resources>
            <resource ref="anonymous" />
        </resources>
    </route>
</routes>

Définissez maintenant l'interface en Vendor/Module/Api/OfficeManagementInterface.phptant que

namespace Vendor\Module\Api;

interface OfficeManagementInterface
{

    /**
     * Find offices for the customer
     *
     * @param string $postcode
     * @param string $city
     * @return \Vendor\Module\Api\Data\OfficeInterface[]
     */
    public function fetchOffices($postcode, $city);
}

Définissez l'interface pour les données de bureau dans Vendor\Module\Api\Data\OfficeInterface.php. Cette interface sera utilisée par le module webapi pour filtrer les données pour la sortie, vous devez donc définir tout ce que vous devez ajouter à la réponse.

namespace Vendor\Module\Api\Data;

/**
 * Office Interface
 */
interface OfficeInterface
{
    /**
     * @return string
     */
    public function getName();

    /**
     * @return string
     */
    public function getLocation();
}

Temps pour les cours réels. Commencez par créer des préférences pour toutes les interfaces dansVendor/Module/etc/di.xml

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Vendor\Module\Api\OfficeManagementInterface" type="Vendor\Module\Model\OfficeManagement" />
    <preference for="Vendor\Module\Api\Data\OfficeInterface" type="Vendor\Module\Model\Office" />
</config>

Créez maintenant une Vendor\Module\Model\OfficeManagement.phpclasse qui fera la logique de la récupération des données.

namespace Vednor\Module\Model;

use Vednor\Module\Api\OfficeManagementInterface;
use Vednor\Module\Api\Data\OfficeInterfaceFactory;

class OfficeManagement implements OfficeManagementInterface
{
    protected $officeFactory;

    /**
     * OfficeManagement constructor.
     * @param OfficeInterfaceFactory $officeInterfaceFactory
     */
    public function __construct(OfficeInterfaceFactory $officeInterfaceFactory)
    {
        $this->officeFactory = $officeInterfaceFactory;
    }

    /**
     * Get offices for the given postcode and city
     *
     * @param string $postcode
     * @param string $limit
     * @return \Vendor\Module\Api\Data\OfficeInterface[]
     */
    public function fetchOffices($postcode, $city)
    {
        $result = [];
        for($i = 0, $i < 4;$i++) {
            $office = $this->officeFactory->create();
            $office->setName("Office {$i}");
            $office->setLocation("Address {$i}");
            $result[] = $office;
        }

        return $result;
    }
}

Et enfin la classe pour OfficeInterfaceenVendor/Module/Model/Office.php

namespace Vendor\Module\Model;

use Magento\Framework\DataObject;
use Vendor\Module\Api\Data\OfficeInterface;

class Office extends DataObject implements OfficeInterface
{
    /**
     * @return string
     */
    public function getName()
    {
        return (string)$this->_getData('name');
    }

    /**
     * @return string
     */
    public function getLocation()
    {
        return (string)$this->_getData('location');
    }
}

Cela devrait afficher le champ de sélection et le mettre à jour lorsque l'adresse est modifiée. Mais il nous manque un élément de plus pour la manipulation frontale. Nous devons créer une fonction qui appellera le point de terminaison. L'appeler est déjà inclus dans Vendor/Module/view/frontend/web/js/view/checkout/shipping/form.jset c'est la Vendor_Module/js/view/checkout/shipping/office-serviceclasse qui devrait aller Vendor/Module/view/frontend/web/js/view/checkout/shipping/office-service.jsavec le code suivant:

define(
    [
        'Vendor_Module/js/view/checkout/shipping/model/resource-url-manager',
        'Magento_Checkout/js/model/quote',
        'Magento_Customer/js/model/customer',
        'mage/storage',
        'Magento_Checkout/js/model/shipping-service',
        'Vendor_Module/js/view/checkout/shipping/model/office-registry',
        'Magento_Checkout/js/model/error-processor'
    ],
    function (resourceUrlManager, quote, customer, storage, shippingService, officeRegistry, errorProcessor) {
        'use strict';

        return {
            /**
             * Get nearest machine list for specified address
             * @param {Object} address
             */
            getOfficeList: function (address, form) {
                shippingService.isLoading(true);
                var cacheKey = address.getCacheKey(),
                    cache = officeRegistry.get(cacheKey),
                    serviceUrl = resourceUrlManager.getUrlForOfficeList(quote);

                if (cache) {
                    form.setOfficeList(cache);
                    shippingService.isLoading(false);
                } else {
                    storage.get(
                        serviceUrl, false
                    ).done(
                        function (result) {
                            officeRegistry.set(cacheKey, result);
                            form.setOfficeList(result);
                        }
                    ).fail(
                        function (response) {
                            errorProcessor.process(response);
                        }
                    ).always(
                        function () {
                            shippingService.isLoading(false);
                        }
                    );
                }
            }
        };
    }
);

Il utilise 2 fichiers js supplémentaires. Vendor_Module/js/view/checkout/shipping/model/resource-url-managercrée une URL vers le point de terminaison et est assez simple

define(
    [
        'Magento_Customer/js/model/customer',
        'Magento_Checkout/js/model/quote',
        'Magento_Checkout/js/model/url-builder',
        'mageUtils'
    ],
    function(customer, quote, urlBuilder, utils) {
        "use strict";
        return {
            getUrlForOfficeList: function(quote, limit) {
                var params = {postcode: quote.shippingAddress().postcode, city: quote.shippingAddress().city};
                var urls = {
                    'default': '/module/get-office-list/:postcode/:city'
                };
                return this.getUrl(urls, params);
            },

            /** Get url for service */
            getUrl: function(urls, urlParams) {
                var url;

                if (utils.isEmpty(urls)) {
                    return 'Provided service call does not exist.';
                }

                if (!utils.isEmpty(urls['default'])) {
                    url = urls['default'];
                } else {
                    url = urls[this.getCheckoutMethod()];
                }
                return urlBuilder.createUrl(url, urlParams);
            },

            getCheckoutMethod: function() {
                return customer.isLoggedIn() ? 'customer' : 'guest';
            }
        };
    }
);

Vendor_Module/js/view/checkout/shipping/model/office-registryest un moyen de conserver le résultat dans le stockage local. Son code est:

define(
    [],
    function() {
        "use strict";
        var cache = [];
        return {
            get: function(addressKey) {
                if (cache[addressKey]) {
                    return cache[addressKey];
                }
                return false;
            },
            set: function(addressKey, data) {
                cache[addressKey] = data;
            }
        };
    }
);

Ok, donc nous devrions tous travailler sur le frontend. Mais maintenant, il y a un autre problème à résoudre. Comme la caisse ne sait rien de ce formulaire, elle n'enverra pas le résultat de la sélection au backend. Pour y arriver, nous devons utiliserextension_attributes fonctionnalité. C'est un moyen dans magento2 d'informer le système que certaines données supplémentaires devraient se trouver dans les autres appels. Sans cela, magento filtrerait ces données et n'atteindrait jamais le code.

Donc, Vendor/Module/etc/extension_attributes.xmldéfinissez d'abord:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
    <extension_attributes for="Magento\Quote\Api\Data\AddressInterface">
        <attribute code="carrier_office" type="string"/>
    </extension_attributes>
</config>

Cette valeur est déjà insérée dans la demande form.jspar this.selectedOffice.subscribe()définition. Ainsi, la configuration ci-dessus ne la transmettra qu'à l'entrée. Pour le récupérer dans le code, créez un pluginVendor/Module/etc/di.xml

<type name="Magento\Quote\Model\Quote\Address">
    <plugin name="inpost-address" type="Vendor\Module\Quote\AddressPlugin" sortOrder="1" disabled="false"/>
</type>

À l'intérieur de cette classe

namespace Vendor\Module\Plugin\Quote;

use Magento\Quote\Model\Quote\Address;
use Vendor\Module\Model\Carrier;

class AddressPlugin
{
    /**
     * Hook into setShippingMethod.
     * As this is magic function processed by __call method we need to hook around __call
     * to get the name of the called method. after__call does not provide this information.
     *
     * @param Address $subject
     * @param callable $proceed
     * @param string $method
     * @param mixed $vars
     * @return Address
     */
    public function around__call($subject, $proceed, $method, $vars)
    {
        $result = $proceed($method, $vars);
        if ($method == 'setShippingMethod'
            && $vars[0] == Carrier::CARRIER_CODE.'_'.Carrier::METHOD_CODE
            && $subject->getExtensionAttributes()
            && $subject->getExtensionAttributes()->getCarrierOffice()
        ) {
            $subject->setCarrierOffice($subject->getExtensionAttributes()->getCarrierOffice());
        }
        elseif (
            $method == 'setShippingMethod'
            && $vars[0] != Carrier::CARRIER_CODE.'_'.Carrier::METHOD_CODE
        ) {
            //reset office when changing shipping method
            $subject->getCarrierOffice(null);
        }
        return $result;
    }
}

Bien sûr, où vous économiserez la valeur dépend entièrement de vos besoins. Le code ci - dessus , il faudrait créer colonne supplémentaire carrier_officedans quote_addresset sales_addresstables et un événement (en Vendor/Module/etc/events.xml)

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="sales_model_service_quote_submit_before">
        <observer name="copy_carrier_office" instance="Vendor\Module\Observer\Model\Order" />
    </event>
</config>

Cela copierait les données enregistrées dans l'adresse de devis vers l'adresse de vente.

J'ai écrit ceci pour mon module pour l'opérateur polonais InPost, j'ai donc changé quelques noms qui pourraient casser le code mais j'espère que cela vous donnera ce dont vous avez besoin.

[ÉDITER]

Modèle de transporteur demandé par @sangan

namespace Vendor\Module\Model;

use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\Phrase;
use Magento\Quote\Model\Quote\Address\RateRequest;
use Magento\Shipping\Model\Carrier\AbstractCarrier;
use Magento\Shipping\Model\Carrier\CarrierInterface;
use Magento\Shipping\Model\Simplexml\ElementFactory;

class Carrier extends AbstractCarrier implements CarrierInterface
{
    const CARRIER_CODE = 'mycarier';

    const METHOD_CODE = 'mymethod';

    /** @var string */
    protected $_code = self::CARRIER_CODE;

    /** @var bool */
    protected $_isFixed = true;

    /**
     * Prepare stores to show on frontend
     *
     * @param RateRequest $request
     * @return \Magento\Framework\DataObject|bool|null
     */
    public function collectRates(RateRequest $request)
    {
        if (!$this->getConfigData('active')) {
            return false;
        }

        /** @var \Magento\Shipping\Model\Rate\Result $result */
        $result = $this->_rateFactory->create();

        /** @var \Magento\Quote\Model\Quote\Address\RateResult\Method $method */
        $method = $this->_rateMethodFactory->create();
        $method->setCarrier($this->_code);
        $method->setCarrierTitle($this->getConfigData('title'));

        $price = $this->getFinalPriceWithHandlingFee(0);
        $method->setMethod(self::METHOD_CODE);
        $method->setMethodTitle(new Phrase('MyMethod'));
        $method->setPrice($price);
        $method->setCost($price);
        $result->append($method);;

        return $result;
    }


    /**
     * @return array
     */
    public function getAllowedMethods()
    {
        $methods = [
            'mymethod' => new Phrase('MyMethod')
        ];
        return $methods;
    }
}
Zefiryn
la source
Merci pour votre réponse étendue, je vais essayer de résoudre mon problème en utilisant votre méthode et je vous répondrai avec le résultat ces jours-ci.
Siarhey Uchukhlebau
@Zefiryn J'ai créé une méthode d'expédition personnalisée, ci-dessous, elle affichera une liste déroulante contenant les numéros de compte d'expédition du client (un attribut client personnalisé a été créé), donc si je dois afficher cette liste déroulante, combien de pourcentage de votre code sera utile? Que dois-je retirer du code que vous avez fourni?
Shireen N
@shireen, je dirais environ 70%. Vous devez changer la partie où il récupère les machines pour les numéros de compte. La définition de l'API sera donc légèrement différente et js en fera partie
Zefiryn
J'ai essayé ce module ... mais il ne montre aucun changement, veuillez donc partager le module de travail.
Sangan
après l'ajout réussi du module .. dans le chargement ajax en chargement continu .. dans l'erreur de console montrant comme ci-dessous: require.js: 166 Erreur non interceptée: erreur de script pour: Vendor_Module / js / view / checkout / shipping / model / office-registry. requirejs.org/docs/errors.html#scripterror
sangan
2

J'ajoute une nouvelle réponse pour développer ce qui était déjà fourni précédemment mais sans le déformer.

C'est la route qui QuoteAddressPluginse connectait:

1. Magento\Checkout\Api\ShippingInformationManagementInterface::saveAddressInformation()
2. Magento\Quote\Model\QuoteRepository::save() 
3. Magento\Quote\Model\QuoteRepository\SaveHandler::save() 
4. Magento\Quote\Model\QuoteRepository\SaveHandler::processShippingAssignment() 
5. Magento\Quote\Model\Quote\ShippingAssignment\ShippingAssignmentPersister::save()
6. Magento\Quote\Model\Quote\ShippingAssignment\ShippingAssignmentProcessor::save()
7. Magento\Quote\Model\Quote\ShippingAssignment\ShippingProcessor::save()
8. Magento\Quote\Model\ShippingMethodManagement::apply() 

La dernière méthode appelait Magento\Quote\Model\Quote\Address::setShippingMethod()ce qui était en fait un appel pour Magento\Quote\Model\Quote\Address::__call()lequel j'ai utilisé. En ce moment, j'ai trouvé un meilleur endroit pour le plugin, c'est la Magento\Quote\Model\ShippingAssignment::setShipping()méthode. La partie plugin peut donc être réécrite pour:

<type name="Magento\Quote\Model\ShippingAssignment">
    <plugin name="carrier-office-plugin" type="Vendor\Module\Plugin\Quote\ShippingAssignmentPlugin" sortOrder="1" disabled="false"/>
</type>

et le plugin lui-même:

namespace Vednor\Module\Plugin\Quote;

use Magento\Quote\Api\Data\AddressInterface;
use Magento\Quote\Api\Data\ShippingInterface;
use Magento\Quote\Model\ShippingAssignment;
use Vendor\Module\Model\Carrier;

/**
 * ShippingAssignmentPlugin
 */
class ShippingAssignmentPlugin
{
    /**
     * Hook into setShipping.
     *
     * @param ShippingAssignment $subject
     * @param ShippingInterface $value
     * @return Address
     */
    public function beforeSetShipping($subject, ShippingInterface $value)
    {
        $method = $value->getMethod();
        /** @var AddressInterface $address */
        $address = $value->getAddress();
        if ($method === Carrier::CARRIER_CODE.'_'.Carrier::METHOD_CODE
            && $address->getExtensionAttributes()
            && $address->getExtensionAttributes()->getCarrierOffice()
        ) {
            $address->setCarrierOffice($address->getExtensionAttributes()->getCarrierOffice());
        }
        elseif ($method !== Carrier::CARRIER_CODE.'_'.Carrier::METHOD_CODE) {
            //reset inpost machine when changing shipping method
            $address->setCarrierOffice(null);
        }
        return [$value];
    }
}
Zefiryn
la source
1

@Zefiryn, je suis tombé sur le problème avec: quote.shippingAddress().extensionAttributes.carrier_office = office;

Lorsque j'entre dans la caisse pour la première fois (nouvelle fenêtre privée) en tant qu'invité (mais la même chose se produit avec le client enregistré), l'attribut office n'est pas enregistré dans la base de données après le premier "Suivant". Bien que dans la console, je vois une sortie correcte pour:console.log(quote.shippingAddress().extensionAttributes.carrier_office);

Lorsque je reviens à la première page de paiement et que je sélectionne à nouveau le bureau, il est enregistré. Quelle pourrait être la raison de ce comportement?

J'ai essayé d'utiliser: address.trigger_reload = new Date().getTime(); rateRegistry.set(address.getKey(), null); rateRegistry.set(address.getCacheKey(), null); quote.shippingAddress(address);

mais sans succès ...

user2089098
la source
0

@Zefiryn, pouvez-vous expliquer en quelques mots comment fonctionne votre plugin ci-dessus? Im peu confus parce que, comme je sais, la méthode __call est exécutée si nous essayons d'exécuter une méthode qui n'existe pas pour un objet particulier. Cela semble être vrai parce que dans app / code / Magento / Quote / Model / Quote / Address.php, je ne vois pas une telle méthode - seulement un commentaire:

/** * Sales Quote address model ... * @method Address setShippingMethod(string $value)

  1. Pourquoi utilisez-vous autour de l'interception quand il n'y a pas d'implémentation de méthode?
  2. Ensuite, je vois $subject->setInpostMachineet $subject->getCarrierOffice(null);cela signifie-t-il que la méthode du plugin ci-dessus sera exécutée à nouveau car il n'y a pas de méthode setInpostMachine () et getCarrierOffice () dans Adress Class? Cela ressemble à une boucle pour moi.
  3. D'où Magento s'exécute setShippingMethod()? Comment cette méthode est-elle utilisée normalement? Je ne trouve aucune interception simillar dans le code Magento.
user2089098
la source
Ok, j'ai donc préparé la réponse sur la base d'un module que j'ai écrit pour les tests, il utilisait le champ inpost_machine, donc celui-ci n'a pas été correctement changé en carrier_office à cet endroit. Deuxièmement, au moment où je développais ce module, je n'ai pas trouvé d'endroit où je pourrais envoyer à la fois le transporteur et l'adresse sélectionnés avec des attributs d'extension sauf l' setShippingMethodappel sur l' AddressInterfaceobjet et comme il n'y a pas une telle méthode, j'ai dû utiliser around__call pour voir si setShippingMethoda été appelé ou un autre champ magique. En ce moment, j'ai trouvé un meilleur endroit et je le publierai dans une nouvelle réponse.
Zefiryn