Magento 2 checkout - добавьте произвольное поле между адресом доставки и способом доставки

21

Я пытаюсь добавить настраиваемое поле между адресом доставки и разделами метода доставки . И я хочу , значение этого поля должны быть сохранено в обоих quoteи sales_orderтаблицах , в конечном счете. Это похоже на добавление поля «Комментарий к заказу», но это поле должно появиться сразу после раздела адреса доставки и перед разделом метода доставки.

Я просмотрел руководства разработчика Magento о том, как добавить настраиваемое поле и настраиваемую форму к оформлению заказа, и в определенной степени реализовал решение.

Что я сделал до сих пор:

  1. Обновлен checkout_index_index.xmlмакет, добавлен новый uiComponent(контейнер) под пунктом «shippingAddress».
  2. Добавлен элемент (поле), который мне нужен внутри контейнера.
  3. Переопределите /js/view/shipping.jsи shipping.phtmlв моем пользовательском модуле.
  4. Вызванный выше сделанный контейнер внутри shipping.phtmlмежду адресом доставки и способом доставки (что-то похожее на добавление новой статической формы)

Теперь нужное поле отображается на одностраничной кассе именно там, где я хочу. Но я столкнулся с нижеприведенными проблемами.

  1. Как получить доступ к значению настраиваемого поля, которое я добавил выше? Я пытаюсь сохранить значение в атрибуте расширения shippingAddress. Я добавил миксин setShippingInformationActionвнутрь, чтобы попытаться сделать ниже

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

Но приведенный выше код фактически завершается сбоем, так как элемент отсутствует в shipping-address-fieldset. Я мог бы получить значение через windowэлемент. Но есть ли способ получить доступ к этому через Magento?

  1. Есть ли способ сохранить значение этого элемента в локальном кеш-хранилище ( Magento_Checkout/js/checkout-data), чтобы оно сохранялось даже после обновления страницы?
ShanR
источник
2
Взгляните на это - magento.stackexchange.com/questions/135969/…
igloczek
Пожалуйста, обратитесь по ссылке ниже, я надеюсь, что это поможет вам magento.stackexchange.com/questions/187847/…
Прадип Кумар

Ответы:

1

Исходя из вашего вопроса, я предполагаю, что у вас уже установлены атрибуты расширений. Я провел аналогичную модификацию, и, надеюсь, мой ответ поможет.

В вашем пользовательском модуле создайте файл requirejs-config, чтобы расширить стандартный процессор доставки / default

Пространство имен / CustomModule / просмотр / интерфейс / requirejs-config.js
var config = {
    "карта": {
        "*": {
            'Magento_Checkout / js / model / shipping-save-processor / default': 'Namespace_CustomModule / js / model / shipping-save-processor / default'
        }
    }
};

Добавьте свой атрибут расширения в полезную нагрузку.

/ * глобальное определение, оповещение * /
определить (
    [
        'JQuery',
        «Ко»,
        'Magento_Checkout / JS / модель / кавычка',
        'Magento_Checkout / JS / модель / ресурсы URL-менеджер',
        «Маг / хранение»,
        'Magento_Checkout / JS / модель / платежно-сервис',
        'Magento_Checkout / JS / модель / оплаты / метод-конвертер',
        'Magento_Checkout / JS / модель / ошибки процессора',
        'Magento_Checkout / JS / модель / полноэкранный-погрузчик',
        'Magento_Checkout / JS / действие / выбрать-биллинг-адрес'
    ],
    функция (
        $,
        ко,
        цитата,
        resourceUrlManager,
        место хранения,
        paymentService,
        methodConverter,
        errorProcessor,
        fullScreenLoader,
        selectBillingAddressAction
    ) {
        «использовать строгое»;

        возвращение {
            saveShippingInformation: function () {
                полезная нагрузка var;

                if (! quote.billingAddress ()) {
                    selectBillingAddressAction (quote.shippingAddress ());
                }
                // Добавление атрибутов расширения к вашему адресу доставки
                полезная нагрузка = {
                    информация об адресе: {
                        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 ();

                возврат хранилища.пост (
                    resourceUrlManager.getUrlForSetShippingInformation (цитата),
                    JSON.stringify (полезная нагрузка)
                ).сделано(
                    функция (ответ) {
                        quote.setTotals (response.totals);
                        paymentService.setPaymentMethods (methodConverter (response.payment_methods));
                        fullScreenLoader.stopLoader ();
                    }
                ).провал(
                    функция (ответ) {
                        errorProcessor.process (ответ);
                        fullScreenLoader.stopLoader ();
                    }
                );
            }
        };
    }
);

Сохраните атрибут к вашей цитате с помощью плагина (не уверен, что вы могли бы использовать наблюдателя здесь, я не проверял).

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

Класс SaveAddressInformation
{
    защищенный $ quoteRepository;
    публичная функция __construct (
        \ Magento \ Quote \ Model \ QuoteRepository $ quoteРепозиторий
    ) {
        $ this-> quoteRepository = $ quoteRepository;
    }
    / **
     * @param \ Magento \ Checkout \ Model \ ShippingInformationManagement $ subject
     * @param $ cartId
     * @param \ Magento \ Checkout \ Api \ Data \ ShippingInformationInterface $ addressInformation
     * /
    публичная функция beforeSaveAddressInformation (
        \ Magento \ Оформить заказ \ Модель \ ShippingInformationManagement $ subject,
        $ CartId,
        \ Magento \ Checkout \ Api \ Data \ ShippingInformationInterface $ addressInformation
    ) {
        $ extensionAttributes = $ addressInformation-> getExtensionAttributes ();
        $ customField = $ extensionAttributes-> getCustomField ();
        $ quote = $ this-> quoteRepository-> getActive ($ cartId);
        $ Цитирует> setCustomField ($ customField);

    }
}

Сохраните атрибут в вашем заказе с помощью Observer 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

Класс SaveCustomFieldToOrder реализует ObserverInterface
{
    / **
     * @var \ Magento \ Framework \ ObjectManagerInterface
     * /
    защищенный $ _objectManager;

    / **
     * @param \ Magento \ Framework \ ObjectManagerInterface $ objectmanager
     * /
    публичная функция __construct (\ Magento \ Framework \ ObjectManagerInterface $ objectmanager)
    {
        $ this -> _ objectManager = $ objectmanager;
    }

    публичная функция execute (EventObserver $ наблюдатель)
    {
        $ order = $ наблюдатель-> getOrder ();
        $ quoteRepository = $ this -> _ objectManager-> create ('Magento \ Quote \ Model \ QuoteRepository');
        / ** @var \ Magento \ Quote \ Model \ Quote $ quote * /
        $ quote = $ quoteRepository-> get ($ order-> getQuoteId ());
        $ order-> setCustomField ($ quote-> getCustomField ());

        вернуть $ this;
    }
}

NathanielR
источник
Переопределение основных методов не слишком удачно. Что если другой модуль переопределит ваш? magento.stackexchange.com/questions/135969/...
vaso123
Хорошая мысль, не знал об альтернативном методе. спасибо за указание на это.
NathanielR
@ vaso123 Похоже, я тоже ничего не знаю, потому что здесь Натаниэль создал плагин и одного наблюдателя событий, поэтому основная функция здесь переопределяется. Не могли бы вы объяснить это немного больше, это было бы очень полезно ... Спасибо
Сарвагья
@Sarvagya Когда вы используете require js, не используйте map *, вместо этого используйте mixin.
vaso123
@ vaso123 Я полагаю, он ссылается на Magento_Checkout / js / model / shipping-save-processor / default ':' Namespace_CustomModule / js / model / shipping-save-processor / default ', который, как я понимаю, заменяет Magento_Checkout / js / model / shipping -save-процессор / по умолчанию. } Прошло много времени с тех пор, как я написал это, поэтому Сарвагья поправьте меня, если я ошибаюсь.
NathanielR
0

Создайте плагин для этого \Magento\Checkout\Block\Checkout\LayoutProcessor::processметода.

Сделайте запись в di.xml по этому пути

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

Создайте класс плагина в этом каталоге.

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

2 => Создать класс плагина в этом каталоге. 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;
}

}

Как только это будет сделано, проверьте страницу оформления заказа.

Бандини
источник