Kasa Magento 2 - dodaj niestandardowe pole między adresem wysyłki a metodą wysyłki

21

Usiłuję dodać niestandardowe pole między sekcją adresu wysyłki i metody wysyłki . Chcę, aby wartości tego pola były przechowywane zarówno w tabelach, jak quotei sales_orderostatecznie. Jest to podobne do dodawania pola „komentarz do zamówienia”, ale pole to powinno pojawić się zaraz za sekcją adresu wysyłki i przed sekcją metody wysyłki.

Przejrzałem przewodniki deweloperów Magento, jak dodać niestandardowe pole i niestandardowy formularz do kasy i zaimplementowałem rozwiązanie do pewnego stopnia.

Co zrobiłem do tej pory:

  1. Zaktualizowałem checkout_index_index.xmlukład, dodałem nowy uiComponent(kontener) pod pozycją „adres wysyłki”.
  2. Dodano element (pole), którego potrzebuję wewnątrz kontenera.
  3. Zastąp /js/view/shipping.jsi shipping.phtmlw moim module niestandardowym.
  4. Wywołano wyżej utworzony pojemnik shipping.phtmlmiędzy adresem wysyłki zamówienia a metodą wysyłki (coś podobnego do dodania nowego statycznego formularza)

Teraz żądane pole jest renderowane w kasie na stronie dokładnie tam, gdzie chcę. Ale spotkałem się z poniższymi problemami.

  1. Jak uzyskać dostęp do wartości niestandardowego pola, które dodałem powyżej? Próbuję zapisać wartość w atrybucie rozszerzenia shippingAddress. Dodałem do niego mixin, setShippingInformationActionktóry próbuje wykonać poniższe czynności

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

Ale powyższy kod faktycznie zawodzi, ponieważ elementu nie ma w shipping-address-fieldset. Mogę być w stanie uzyskać wartość przez windowelement. Ale czy istnieje sposób, aby uzyskać do tego dostęp za pośrednictwem Magento?

  1. Czy istnieje sposób na zapisanie wartości tego elementu w lokalnej pamięci podręcznej ( Magento_Checkout/js/checkout-data), aby wartość ta pozostała nawet po odświeżeniu strony?
ShanR
źródło
Proszę odnieść się do poniższego linku, mam nadzieję, że pomoże ci magento.stackexchange.com/questions/187847/…
Pradeep Kumar

Odpowiedzi:

1

Na podstawie twojego pytania zakładam, że masz już skonfigurowane atrybuty rozszerzenia. Przeprowadziłem podobną modyfikację i mam nadzieję, że moja odpowiedź pomoże.

W swoim module niestandardowym utwórz plik config-wymagany, aby rozszerzyć domyślny procesor wysyłający / domyślny

Przestrzeń nazw / CustomModule / view / frontend / Requjs-config.js
var config = {
    „mapa”: {
        „*”: {
            „Magento_Checkout / js / model / shipping-save-processor / default”: „Namespace_CustomModule / js / model / shipping-save-processor / default”
        }
    }
};

Dodaj swój atrybut rozszerzenia do ładunku.

/ * globalne definiowanie, alert * /
definiować(
    [
        „jquery”,
        „ko”,
        „Magento_Checkout / js / model / quote”,
        „Magento_Checkout / js / model / resource-url-manager”,
        „mag / magazyn”,
        „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”
    ],
    funkcja (
        $,
        ko
        zacytować,
        resourceUrlManager,
        przechowywanie,
        paymentService,
        methodConverter,
        errorProcessor,
        fullScreenLoader,
        selectBillingAddressAction
    ) {
        „stosować ścisłe”;

        powrót {
            saveShippingInformation: function () {
                zmienna ładowność;

                if (! quote.billingAddress ()) {
                    selectBillingAddressAction (quote.shippingAddress ());
                }
                // Dodanie atrybutów rozszerzenia do adresu wysyłki
                ładunek = {
                    addressInformation: {
                        shipping_address: quote.shippingAddress (),
                        billing_address: quote.billingAddress (),
                        shipping_method_code: quote.shippingMethod (). code_code,
                        shipping_carrier_code: quote.shippingMethod (). przewoźnik_kod,
                        extension_attributes: {
                            custom_field: $ ('# custom_field'). val (), 
                        }
                    }
                };

                fullScreenLoader.startLoader ();

                return storage.post (
                    resourceUrlManager.getUrlForSetShippingInformation (wycena),
                    JSON.stringify (ładunek)
                ).gotowy(
                    funkcja (odpowiedź) {
                        quote.setTotals (response.totals);
                        paymentService.setPaymentMethods (methodConverter (response.payment_methods));
                        fullScreenLoader.stopLoader ();
                    }
                ).zawieść(
                    funkcja (odpowiedź) {
                        errorProcessor.process (odpowiedź);
                        fullScreenLoader.stopLoader ();
                    }
                );
            }
        };
    }
);

Zapisz atrybut do swojego cytatu za pomocą wtyczki (Nie jestem pewien, czy mógłbyś użyć obserwatora tutaj Nie sprawdziłem).

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

klasa SaveAddressInformation
{
    chroniony $ quoteRepository;
    funkcja publiczna __construct (
        \ Magento \ Quote \ Model \ QuoteRepository $ quoteRepository
    ) {
        $ this-> quoteRepository = $ quoteRepository;
    }
    / **
     * @param \ Magento \ Checkout \ Model \ ShippingInformationManagement $ Temat
     * @param $ cartId
     * @param \ Magento \ Checkout \ Api \ Data \ ShippingInformationInterface $ addressInformation
     * /
    funkcja publiczna beforeSaveAddressInformation (
        \ Magento \ Checkout \ Model \ ShippingInformationManagement $ Temat,
        $ cartId,
        \ Magento \ Checkout \ Api \ Data \ ShippingInformationInterface $ addressInformation
    ) {
        $ extensionAttributes = $ addressInformation-> getExtensionAttributes ();
        $ customField = $ extensionAttributes-> getCustomField ();
        $ quote = $ this-> quoteRepository-> getActive ($ cartId);
        $ quote-> setCustomField ($ customField);

    }
}

Zapisz atrybut do swojego zamówienia za pomocą 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

klasa SaveCustomFieldToOrder implementuje ObserverInterface
{
    / **
     * @var \ Magento \ Framework \ ObjectManagerInterface
     * /
    chroniony $ _objectManager;

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

    wykonanie funkcji publicznej (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 ());

        zwróć $ to;
    }
}

NathanielR
źródło
Zastępowanie podstawowych metod nie jest zbyt szczęśliwe. Co jeśli inny moduł zastąpi twój? magento.stackexchange.com/questions/135969/…
vaso123 27.03.2018
dobra uwaga, nie był świadomy alternatywnej metody. dzięki za zwrócenie na to uwagi.
NathanielR
@ vaso123 Wygląda na to, że czegoś też nie jestem świadomy, ponieważ tutaj Nathaniel stworzył wtyczkę i jednego obserwatora zdarzeń, dzięki czemu podstawowa funkcja jest tutaj nadpisana. Czy mógłbyś wyjaśnić to trochę więcej, byłoby to naprawdę pomocne ... Dzięki
Sarvagya,
@ Sarvagya Kiedy używasz wymaga js, nie używaj map *, zamiast tego użyj mixin.
vaso123
@ vaso123 Wydaje mi się, że odnosi się do Magento_Checkout / js / model / shipping-save-processor / default ':' Namespace_CustomModule / js / model / shipping-save-process / default ', który, jak rozumiem, zastępuje Magento_Checkout / js / model / shipping -save-process / default. } minęło trochę czasu, odkąd to napisałem, więc Sarvagya, popraw mnie, jeśli się mylę.
NathanielR
0

Utwórz wtyczkę dla tej \Magento\Checkout\Block\Checkout\LayoutProcessor::processmetody.

Wprowadź wpis w pliku di.xml na tej ścieżce

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

Utwórz klasę wtyczek w tym katalogu.

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

2 => Utwórz klasę wtyczek w tym katalogu. 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;
}

}

Po wykonaniu tej czynności sprawdź stronę kasy.

Bandini
źródło