Paiement Magento 2 - ajoutez un champ personnalisé entre l'adresse de livraison et la méthode d'expédition

21

J'essaie d'ajouter un champ personnalisé entre l' adresse de livraison et les sections de méthode d'expédition . Et je veux que les valeurs de ce champ soient stockées dans les deux quoteet les sales_ordertables en fin de compte. C'est quelque chose de similaire à l'ajout d'un champ "commentaire de commande", mais ce champ doit apparaître juste après la section d'adresse de livraison et avant la section méthode d'expédition.

J'ai parcouru les guides de développement de Magento sur la façon d'ajouter un champ personnalisé et un formulaire personnalisé à la caisse et j'ai implémenté une solution dans une certaine mesure.

Ce que j'ai fait jusqu'à présent:

  1. Mise à jour de la checkout_index_index.xmlmise en page, ajout d'un nouveau uiComponent(un conteneur) sous l'article "shippingAddress".
  2. Ajout de l'élément (champ) dont j'ai besoin à l'intérieur du conteneur.
  3. Remplacez le /js/view/shipping.jset shipping.phtmldans mon module personnalisé.
  4. Appelé le conteneur ci-dessus à l'intérieur shipping.phtmlentre l'adresse de livraison et la méthode d'expédition (quelque chose de similaire à l'ajout d'un nouveau formulaire statique)

Maintenant, le champ que je veux est affiché sur la caisse à la page exactement où je veux. Mais j'ai rencontré des problèmes ci-dessous.

  1. Comment accéder à la valeur du champ personnalisé que j'ai ajouté ci-dessus? J'essaie d'enregistrer la valeur dans un attribut d'extension shippingAddress. J'ai ajouté un mixin à l' setShippingInformationActionintérieur qui essaie de faire ce qui suit

    shippingAddress['extension_attributes']['custom_field'] = shippingAddress.customAttributes['custom_field'];

Mais le code ci-dessus échoue en fait puisque l'élément n'est pas dans le shipping-address-fieldset. Je pourrais peut-être obtenir la valeur à travers l' windowélément. Mais existe-t-il un moyen d'y accéder via Magento?

  1. Existe-t-il un moyen de sauvegarder la valeur de cet élément dans le cache local storage ( Magento_Checkout/js/checkout-data) afin que la valeur persiste même après une actualisation de page?
ShanR
la source
2
Jetez un oeil à ce sujet - magento.stackexchange.com/questions/135969/…
igloczek
Veuillez vous référer au lien ci-dessous j'espère que cela vous aidera magento.stackexchange.com/questions/187847/…
Pradeep Kumar

Réponses:

1

Sur la base de votre question, je suppose que vos attributs d'extension sont déjà configurés. J'ai effectué une modification similaire et j'espère que ma réponse vous aidera.

Dans votre module personnalisé, créez un fichier requirejs-config pour étendre le processeur d'expédition par défaut / default

Espace de noms / CustomModule / view / frontend / requirejs-config.js
var config = {
    "carte": {
        "*": {
            'Magento_Checkout / js / model / shipping-save-processor / default': 'Namespace_CustomModule / js / model / shipping-save-processor / default'
        }
    }
};

Ajoutez votre attribut d'extension à la charge utile.

/ * définition globale, alerte * /
définir(
    [
        «jquery»,
        «ko»,
        'Magento_Checkout / js / model / quote',
        'Magento_Checkout / js / model / resource-url-manager',
        «mage / stockage»,
        «Magento_Checkout / js / model / payment-service»,
        'Magento_Checkout / js / model / payment / method-converter',
        «Magento_Checkout / js / model / error-processor»,
        'Magento_Checkout / js / model / full-screen-loader',
        'Magento_Checkout / js / action / select-billing-address'
    ],
    une fonction (
        $,
        ko,
        citation,
        resourceUrlManager,
        espace de rangement,
        paymentService,
        methodConverter,
        errorProcessor,
        fullScreenLoader,
        selectBillingAddressAction
    ) {
        «utiliser strictement»;

        revenir {
            saveShippingInformation: function () {
                var charge utile;

                if (! quote.billingAddress ()) {
                    selectBillingAddressAction (quote.shippingAddress ());
                }
                // Ajout des attributs d'extension à votre adresse de livraison
                charge utile = {
                    addressInformation: {
                        shipping_address: quote.shippingAddress (),
                        billing_address: quote.billingAddress (),
                        shipping_method_code: quote.shippingMethod (). method_code,
                        shipping_carrier_code: quote.shippingMethod (). carrier_code,
                        extension_attributes: {
                            custom_field: $ ('# custom_field'). val (), 
                        }
                    }
                };

                fullScreenLoader.startLoader ();

                return storage.post (
                    resourceUrlManager.getUrlForSetShippingInformation (devis),
                    JSON.stringify (charge utile)
                ).terminé(
                    fonction (réponse) {
                        quote.setTotals (response.totals);
                        paymentService.setPaymentMethods (methodConverter (response.payment_methods));
                        fullScreenLoader.stopLoader ();
                    }
                ).échouer(
                    fonction (réponse) {
                        errorProcessor.process (réponse);
                        fullScreenLoader.stopLoader ();
                    }
                );
            }
        };
    }
);

Enregistrez l'attribut dans votre devis avec un plugin (je ne sais pas si vous pouvez utiliser un observateur ici, je n'ai pas vérifié).

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">
    <type name="Magento\Checkout\Model\ShippingInformationManagement">
        <plugin name="Namespace_CustomModule_save_delivery_date_in_quote" type="Namespace\CustomModule\Plugin\Checkout\SaveAddressInformation" />
    </type>

</config>

SaveAddressInformation.php

classe SaveAddressInformation
{
    $ quoteRepository protégé;
    fonction publique __construct (
        \ Magento \ Quote \ Model \ QuoteRepository $ quoteRepository
    ) {
        $ this-> quoteRepository = $ quoteRepository;
    }
    / **
     * @param \ Magento \ Checkout \ Model \ ShippingInformationManagement $ subject
     * @param $ cartId
     * @param \ Magento \ Checkout \ Api \ Data \ ShippingInformationInterface $ addressInformation
     * /
    fonction publique beforeSaveAddressInformation (
        \ Magento \ Checkout \ Model \ ShippingInformationManagement $ subject,
        $ cartId,
        \ Magento \ Checkout \ Api \ Data \ ShippingInformationInterface $ addressInformation
    ) {
        $ extensionAttributes = $ addressInformation-> getExtensionAttributes ();
        $ customField = $ extensionAttributes-> getCustomField ();
        $ quote = $ this-> quoteRepository-> getActive ($ cartId);
        $ quote-> setCustomField ($ customField);

    }
}

Enregistrez l'attribut dans votre commande avec un observateur events.xml

<?xml version="1.0" encoding="UTF-8"?>
<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="unique_observer_name" instance="Namespace\CustomModule\Observer\SaveCustomFieldToOrder"/>
    </event>
</config>

SaveCustomFieldToOrder.php

La classe SaveCustomFieldToOrder implémente ObserverInterface
{
    / **
     * @var \ Magento \ Framework \ ObjectManagerInterface
     * /
    protected $ _objectManager;

    / **
     * @param \ Magento \ Framework \ ObjectManagerInterface $ objectmanager
     * /
    fonction publique __construct (\ Magento \ Framework \ ObjectManagerInterface $ objectmanager)
    {
        $ this -> _ objectManager = $ objectmanager;
    }

    fonction publique exécuter (EventObserver $ observer)
    {
        $ order = $ observer-> getOrder ();
        $ quoteRepository = $ this -> _ objectManager-> create ('Magento \ Quote \ Model \ QuoteRepository');
        / ** @var \ Magento \ Quote \ Model \ Quote $ quote * /
        $ quote = $ quoteRepository-> get ($ order-> getQuoteId ());
        $ order-> setCustomField ($ quote-> getCustomField ());

        retourner $ this;
    }
}

NathanielR
la source
Surcharger les méthodes de base n'est pas trop chanceux. Et si un autre module remplace le vôtre? magento.stackexchange.com/questions/135969/…
vaso123
bon point, n'était pas au courant de la méthode alternative. merci de l'avoir signalé.
NathanielR
@ vaso123 Il semble que je ne sois pas non plus au courant de quelque chose car ici Nathaniel a créé un plugin et un observateur d'événements afin que la fonction de base soit remplacée ici. Pourriez-vous s'il vous plaît l'expliquer un peu plus, ce serait vraiment utile ... Merci
Sarvagya
@Sarvagya Lorsque vous utilisez require js, ne l'utilisez pas map *, utilisez plutôt mixin.
vaso123
@ vaso123 Je pense qu'il fait référence à Magento_Checkout / js / model / shipping-save-processor / default ':' Namespace_CustomModule / js / model / shipping-save-processor / default 'qui, comme je le comprends, remplace Magento_Checkout / js / model / shipping -save-processor / default. } ça fait un moment que je n'ai pas écrit ceci donc Sarvagya veuillez me corriger si je me trompe.
NathanielR
0

Créez un plugin pour cette \Magento\Checkout\Block\Checkout\LayoutProcessor::processméthode.

Faites une entrée dans di.xml sur ce chemin

app/code/CompanyName/Module/etc/frontend/di.xml

Créez une classe de plugin sur ce répertoire.

app/code/CompanyName\Module\Model\Plugin\Checkout

2 => Créer une classe de plugin sur ce répertoire. app/code/CompanyName\Module\Model\Plugin\Checkout

    $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
    ['shippingAddress']['children']['shipping-address-fieldset']['children']['custom_field'] = [
        'component' => 'Magento_Ui/js/form/element/abstract',
        'config' => [
            'customScope' => 'shippingAddress.custom_attributes',
            'template' => 'ui/form/field',
            'elementTmpl' => 'ui/form/element/input',
            'options' => [],
            'id' => 'custom-field'
        ],
        'dataScope' => 'shippingAddress.custom_attributes.custom_field',
        'label' => 'Custom Field',
        'provider' => 'checkoutProvider',
        'visible' => true,
        'validation' => [],
        'sortOrder' => 250,
        'id' => 'custom-field'
    ];


    return $jsLayout;
}

}

Une fois cela fait, consultez la page de paiement.

Bandini
la source