Magento 2 - Comment ajouter un champ personnalisé à la caisse puis l'envoyer

49

Tous les tutoriels ne couvrent que l’ajout de champs, mais la sauvegarde de la valeur de ce fichier est ignorée. Je ne sais pas pourquoi, c'est la partie la plus importante de l'ajout de tout champ ou formulaire.

J'ai essayé de suivre la documentation de Magento , mais ... ça craint.

À des fins de test, j'essaie d'ajouter d'autres champs à l'adresse d'expédition, simplement pour ignorer les étendues personnalisées, les ensembles de données personnalisés, les fournisseurs de données personnalisés et d'autres éléments non documentés, ce qui me semble trop étrange.

Je n'ai aucune idée de ce que signifie cette forme "statique" ou "dynamique". Pour moi, tous les formulaires de paiement sont construits de manière dynamique sur les modèles KnockoutJS, mais ... lorsque j'essaie de manière "statique", je peux ajouter des entrées ici (donc c'est un formulaire statique ou pas?).

J'essaie d'abord de déboguer pourquoi les observables Knockout ignorent simplement mes champs lors de l'analyse et de l'envoi de données. J'ai trouvé que mes champs ont un nameparamètre vide , mais je ne parviens pas à résoudre ce problème. IMO il devrait être passé au moteur de rendu d'interface utilisateur via un inputNameparamètre, comme toutes les autres options telles que disabled, placeholderetc.

Deuxièmement, j'ai essayé d'utiliser la méthode "dynamique" pour créer un plugin avec LayoutProcessoret transmettre exactement les mêmes données ... et maintenant, j'ai des champs avec names, mais l'envoi ne fonctionne toujours pas du tout.

Après avoir fouillé dans JS, j’ai trouvé que la préparation de cette demande était conservée dans un module-checkout/view/frontend/web/js/model/shipping-save-processor/default.jsfichier, qui dépend du lieu module-checkout/view/frontend/web/js/model/quote.jsoù les observables Knockout sont définis / créés.

D'une manière ou d'une autre, module-checkout/view/frontend/web/js/model/address-converter.jsmettez à jour ces observables et dépend module-checkout/view/frontend/web/js/model/new-customer-address.jsoù j'ai finalement trouvé quelques options de configuration intéressantes - liste de tous les champs d'adresse.

Lorsque j'ajoute mes champs ici, les scripts commencent à être analysés et envoyés, OFC j'en reçois 500, le backend b / c ne les reconnaît pas ... (ne demandez pas, je ne suis pas un développeur backend)

Alors voici mes questions:

  • C'est une bonne façon de gérer ce type de personnalisation? (b / c semble bizarre pour moi)
  • Comment envoyer des valeurs de champs non liées à de nouvelles adresses? Je n'ai vu aucune configuration similaire nulle part. Dans mon cas, j'aimerais envoyer un commentaire de commande (textarea) et une demande de facture (case à cocher). Les deux ne doivent pas être enregistrés en tant qu’adresse, car certains utilisateurs souhaiteront peut-être enregistrer cette adresse pour une utilisation ultérieure.
  • Existe-t-il une documentation sur les formulaires "statiques" et "dynamiques" ou quelques exemples / comparaisons? Ça vaut la peine d'y penser de cette façon?

Question existentielle supplémentaire:

  • Pourquoi est-ce si incohérent? Pourquoi dois-je définir des tonnes de paramètres dans des fichiers XML / PHP, alors que Magento ne peut tout simplement que restituer une entrée et que je dois tout gérer moi-même?
igloczek
la source
3
Magento Devdocs a récemment ajouté de nouveaux documents sur l'utilisation des composants de l'interface utilisateur. Nous sommes en train de rédiger un tout nouveau guide ... mais nous avons encore du chemin à faire. Veuillez consulter devdocs.magento.com/guides/v2.1/ui_comp_guide/bk-ui_comps.html . Malheureusement, nous n'avons pas encore complété les rubriques sur les sources de données, ce dont vous avez apparemment besoin. Une rubrique sur le processus de configuration utilisant des composants d'interface utilisateur peut vous aider. Je vais travailler pour trouver plus de réponses.
Tanberry
Pourquoi ce doit être un cauchemar d'ajouter un champ simple à la caisse? Je ne peux tout simplement pas comprendre. Et presque tout est si difficile
slayerbleast
@slayerbleast World est en train de changer, le rendu côté serveur est en train de mourir. Donc, c'est différent, pas plus difficile sans aucune raison.
igloczek

Réponses:

55

Je vais essayer de répondre à vos questions.

  1. Non . Ce n'est pas une façon correcte d'ajouter des attributs personnalisés au formulaire d'adresse de livraison. Vous n'avez pas besoin de modifier new-customer-address.js. En effet, ce fichier JS répertorie tous les attributs d'adresse prédéfinis et correspond à l'interface principale correspondante, \Magento\Quote\Api\Data\AddressInterfacemais Magento permet de transmettre tous les attributs personnalisés au système principal sans modifier les composants backend / frontend .

    Le composant JS mentionné a une customAttributespropriété. Vos attributs personnalisés seront automatiquement gérés s'ils $dataScopePrefixsont ' shippindAddress.custom_attributes'.

  2. Si j'ai bien compris votre question, vous avez des données qui ne font pas partie de l'adresse du client mais vous devez également les envoyer au backend. La réponse à cette question est:

    Cela dépend . Par exemple, vous pouvez choisir l’approche suivante: ajouter un formulaire personnalisé à la page de paiement qui inclut tous vos champs supplémentaires (like comment, invoice request etc) , ajouter une logique JS qui gérera ce formulaire en fonction de certains événements et fournir un service personnalisé qui recevra les données de frontend et stockera quelque part pour une utilisation future.

  3. Tous les documents officiels liés au paiement se trouvent à l' adresse http://devdocs.magento.com/guides/v2.1/howdoi/checkout/checkout_overview.html . Le terme statique fait référence aux formulaires dans lesquels tous les champs sont déjà connus / prédéfinis (par exemple: le formulaire aura toujours deux champs de texte avec des étiquettes prédéfinies) et ne peut pas être modifié en fonction de certains paramètres du backend.

    De tels formulaires peuvent être déclarés en utilisant layout XML configuration. D'autre part, le terme dynamique fait référence aux formulaires dont l'ensemble de champs peut changer (par exemple: le formulaire de paiement peut avoir plus / moins de champs en fonction des paramètres de configuration).

    Dans ce cas, le seul moyen de déclarer un tel formulaire est d'utiliser un LayoutProcessorplugin.

  4. :) Magento essaie de couvrir autant que possible les cas d’utilisation pouvant être significatifs pour les marchands lors de l’utilisation / personnalisation de Magento. Parfois, cela conduit à une situation où certains cas d'utilisation simples deviennent plus complexes.

J'espère que cela t'aides.

=============================================== ========================

OK ... Permet d'écrire du code;)

  1. Code PHP insérant un champ supplémentaire dans LayoutProcessor

========

/**
 * @author aakimov
 */
$customAttributeCode = 'custom_field';
$customField = [
    'component' => 'Magento_Ui/js/form/element/abstract',
    'config' => [
        // customScope is used to group elements within a single form (e.g. they can be validated separately)
        'customScope' => 'shippingAddress.custom_attributes',
        'customEntry' => null,
        'template' => 'ui/form/field',
        'elementTmpl' => 'ui/form/element/input',
        'tooltip' => [
            'description' => 'Yes, this works. I tested it. Sacrificed my lunch break but verified this approach.',
        ],
    ],
    'dataScope' => 'shippingAddress.custom_attributes' . '.' . $customAttributeCode,
    'label' => 'Custom Attribute',
    'provider' => 'checkoutProvider',
    'sortOrder' => 0,
    'validation' => [
       'required-entry' => true
    ],
    'options' => [],
    'filterBy' => null,
    'customEntry' => null,
    'visible' => true,
];

$jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children'][$customAttributeCode] = $customField;

return $jsLayout;

Comme je l'ai déjà mentionné, cela ajoutera votre champ à la customAttributespropriété de l'objet adresse JS. Cette propriété a été conçue pour contenir des attributs d'adresse EAV personnalisés et est liée à la \Magento\Quote\Model\Quote\Address\CustomAttributeListInterface::getAttributesméthode.

Le code ci-dessus gérera automatiquement la persistance du stockage local sur le client. Vous pouvez obtenir votre valeur de champ à partir du stockage local en utilisant checkoutData.getShippingAddressFromData()(où checkoutDataest Magento_Checkout/js/checkout-data).

  1. Ajoutez mixin pour modifier le comportement de 'Magento_Checkout / js / action / set-shipping-information' (ce composant est responsable de la soumission des données entre les étapes d'expédition et de facturation).

========

2.1. Créeryour_module_name/view/frontend/requirejs-config.js


/**
 * @author aakimov
 */
var config = {
    config: {
        mixins: {
            'Magento_Checkout/js/action/set-shipping-information': {
                '<your_module_name>/js/action/set-shipping-information-mixin': true
            }
        }
    }
};

2.2. Créez votre_nom_module / view / frontend / web / js / action / set-shipping-information-mixin.js


/**
 * @author aakimov
 */
/*jshint browser:true jquery:true*/
/*global alert*/
define([
    'jquery',
    'mage/utils/wrapper',
    'Magento_Checkout/js/model/quote'
], function ($, wrapper, quote) {
    'use strict';

    return function (setShippingInformationAction) {

        return wrapper.wrap(setShippingInformationAction, function (originalAction) {
            var shippingAddress = quote.shippingAddress();
            if (shippingAddress['extension_attributes'] === undefined) {
                shippingAddress['extension_attributes'] = {};
            }

            // you can extract value of extension attribute from any place (in this example I use customAttributes approach)
            shippingAddress['extension_attributes']['custom_field'] = shippingAddress.customAttributes['custom_field'];
            // pass execution to original action ('Magento_Checkout/js/action/set-shipping-information')
            return originalAction();
        });
    };
});
  1. Créez votre nom_module / etc / extension_attributes.xml

========

<?xml version="1.0"?>
<!--
/**
 * @author aakimov
 */
-->
<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="custom_field" type="string" />
    </extension_attributes>
</config>

Cela ajoutera un attribut d’extension au modèle d’adresse du côté serveur. Les attributs d'extension sont l'un des points d'extension fournis par Magento. Pour accéder à vos données sur le backend, vous pouvez utiliser:

// Magento will generate interface that includes your custom attribute
$value = $address->getExtensionAttributes()->getCustomField();

Espérons que cela aidera et sera ajouté à la documentation officielle.

aakimov
la source
Merci pour la réponse Alex! J'ai essayé custom_attributesbien, mais ça ne marche pas pour moi. Voici à quoi ressemble une partie de LayoutProcessor.php` - gist.github.com/Igloczek/eaf4d2d7a0a04bd950110296ec3f7727 Mais shipping-info même localStorage checkout-datane contient pas ces données.
igloczek
S'il vous plaît voir ma réponse mise à jour ci-dessus;)
aakimov
4
Le document officiel sur ce sujet est déjà disponible! devdocs.magento.com/guides/v2.1/howdoi/checkout/…
Alex
1
Une étape supplémentaire est-elle nécessaire pour que les valeurs soient sauvegardées contre la commande?
Alex Hadley
Je pense que si vous avez un formulaire statique, il est préférable d’insérer un champ dans LayoutProcessor via XML comme dans cet exemple: devdocs.magento.com/guides/v2.1/howdoi/checkout/…
cjohansson
-1

D'après mon expérience, m2 utilise xml pour définir des composants tels que des champs, etc. C'est une aide pour le débogage, une interaction avec les données plus facile. Sur le terrain des frontaux, vous devriez essayer de remplacer les modèles de caisse et d'y ajouter vos propres champs personnalisés. Avec KO vous aide à travailler et à relier des données de front et de back-end

Mrtuvn
la source
4
C'est un conseil erroné, les modèles de commande b / c ne contiennent pas et ne doivent jamais contenir de champs de saisie ajoutés manuellement. Nous devons utiliser KO pour restituer des modèles dans des régions sélectionnées (tout est construit à l'aide de composants d'interface utilisateur)
mercredi
Pourriez-vous partager un exemple d'ajout de composants ui de champs personnalisés dans l'interface?
Mrtuvn
Comme @igloczek le dit, c'est un conseil erroné, car les modèles de caisse ne doivent jamais contenir de champs de saisie ajoutés manuellement.
diazwatson