Ustawianie zaawansowanych ograniczeń wysyłki w Magento 2

Opublikowany: 2017-05-17

W tym artykule wyjaśnimy, jak ukryć metodę wysyłki po spełnieniu określonych warunków.

W niektórych sytuacjach właściciele sklepów mogą chcieć ograniczyć opcje wysyłki, ponieważ:

  • produkt ma duże gabaryty i wagę, dlatego nie może być wysyłany w żaden standardowy sposób,
  • warunki przechowywania mrożonego nie pozwalają na dostarczenie produktu na czas
  • wysyłka jest ograniczona ze względu na lokalizację klienta (kraj, region, miasto )
  • C art Total nie pozwala kupującemu na zakwalifikowanie się do jakichkolwiek ofert wysyłkowych,
  • itp.

Domyślny wybór opcji wysyłki Magento nie zapewnia dużej elastyczności. Możliwe jest ograniczenie wysyłki tylko do niektórych krajów i regionów lub gdy suma koszyka jest mniejsza niż ustalona kwota.

Jeśli uważasz, że to nie wystarczy, czytaj dalej.

Podpowiem Ci, jak stworzyć własną wtyczkę, która pozwoli Ci ograniczyć opcje wysyłki zgodnie z Twoim modelem biznesowym, celami i warunkami.

NOTATKA

Nie będę przechodził przez konkretne kroki niezbędne do stworzenia rozszerzenia dla Magento 2. Możesz zobaczyć, jak to zrobić tutaj lub tutaj.

W celu dynamicznego wyłączenia dowolnej metody wysyłki potrzebujemy nowego zestawu klas w naszym rozszerzeniu – są to 2 wtyczki . Pierwszy będzie odpowiedzialny za walidację metod wysyłki, a drugi za ich filtrowanie.

Krótko mówiąc, każda metoda, która nie przejdzie walidacji, zostanie oznaczona jako „ is_disabled ”, a w następnym kroku wszystkie metody „ is_disabled ” zostaną odfiltrowane i usunięte z głównej listy.

Zaczynajmy.

* Ponieważ podejście, które zamierzam opisać, opiera się na zasadach stosowanych w rozszerzeniu Shipping Suite , będę używał nazwy dostawcy 'Mageworx' i nazwy rozszerzenia 'ShippingRules'. NOTATKA! Aby uniknąć błędów, musisz je zastąpić własnymi nazwiskami!

Najpierw stwórzmy wtyczkę (klasę), która będzie używana do filtrowania. Oto jak:

 > MageWorx\Zasady wysyłki\Model\Wtyczka\Wysyłka\Stawka\Wynik\Dołącz 
 przestrzeń nazw MageWorx\ShippingRules\Model\Plugin\Shipping\Rate\Result;

klasa Dołącz
{
    /**
     * @var \Magento\Checkout\Model\Sesja|\Magento\Backend\Model\Sesja\Cytat
     */
    chroniona sesja $;

    /**
     * @param \Magento\Checkout\Model\Session $checkoutSession
     * @param \Magento\Backend\Model\Session\Quote $backendQuoteSession
     * @param \Magento\Framework\App\State $state
     * @internal param Sesja $sesja
     */
    funkcja publiczna __konstrukcja(
        \Magento\Checkout\Model\Session $checkoutSession,
        \Magento\Backend\Model\Session\Quote $backendQuoteSession,
        \Magento\Framework\App\Stan $state
    ) {
        if ($state->getAreaCode() == \Magento\Framework\App\Area::AREA_ADMINHTML) {
            $this->session = $backendQuoteSession;
        } w przeciwnym razie {
            $to->sesja = $checkoutSession;
        }
    }

    /**
     * Przed dołączeniem sprawdź poprawność każdej metody wysyłki.
     * Zastosuj działanie reguł, jeśli walidacja się powiodła.
     * Może oznaczyć niektóre reguły jako wyłączone. Wyłączone zasady zostaną usunięte w klasie
     * @patrz MageWorx\Zasady wysyłki\Model\Wtyczka\Wysyłka\Stawka\Wynik\GetAllRates
     * poprzez sprawdzenie wartości tego znaku w obiekcie oceny.
     *
     * UWAGA: Jeśli masz problemy z zasadami i metodami wysyłki, rozpocznij debugowanie tutaj.
     *
     * @param \Magento\Shipping\Model\Rate\Result $subject
     * @param \Magento\Wycena\Model\Wycena\Adres\RateResult\AbstractResult|\Magento\Shipping\Model\Rate\Result $result
     * @tablica powrotu
     */
    funkcja publiczna beforeAppend($subject, $result)
    {
        if (!$result instanceof \Magento\Quote\Model\Quote\Address\RateResult\Method) {
            return [$wynik];
        }

        $filtableMethods = [
            'flatrate_flatrate',
            'ups_XDM',
            'ups_XPR',
            'ups_WXS',
            „metoda_przewoźnika”,
            // ... dodaj tutaj swoje kody metod
        ];
        $methodCode = $result->getCarrier() . '_' . $result->getMethod();
        if (!in_array($methodCode, $filtableMethods)) {
            return [$wynik];
        }

        /** @var \Magento\Cytat\Model\Cytat $cytat */
        $wycena = $to->sesja->getQuote();
        $quoteItems = $quote->getAllItems();
        $heavyWeightFlag = fałsz;
        foreach ($quoteItems jako $item) {
            if ($item->getWeight() > 100) {
                $heavyWeightFlag = prawda;
                kontynuować;
            }
        }

        if ($heavyWeightFlag == true) {
            $result->setIsDisabled(prawda);
        }

        return [$wynik];
    }
}

W treści wtyczki uruchamiamy 3 testy:

1.

!$result instanceof \Magento\Cytat\Model\Cytat\Adres\RateResult\Metoda

– zapewnia, że ​​w punkcie wejścia otrzymamy to, czego potrzebujemy: czyli przykład metody wysyłki. Jeśli tak nie jest, po prostu zwracamy go tak, jak jest.

2.

 !in_array($methodCode, $filtableMethods)

– następnie sprawdzamy, czy aktualna metoda znajduje się na liście metod do filtrowania. Jeśli tak nie jest, zwracamy go bez zmian.

3.

 $heavyWeightFlag == prawda

– to ostatnia i najważniejsza kontrola. Jeśli flaga zostanie zastosowana do wartości rzeczywistej, bieżąca metoda zostanie wyłączona: $result->setIsDisabled(true);

Postaramy się odfiltrować co najmniej jeden produkt dodany do koszyka i ważący powyżej 100 standardowych jednostek (funtów lub kilogramów).
Dostępne metody filtrowania to 'flatrate_flatrate','ups_XDM','ups_XPR','ups_WXS','carrier_method' . Są one zakodowane na stałe i przechowywane w tablicy $filtableMethods .

Operujemy na kodzie wykorzystując cały kod metody wysyłki, który z reguły składa się z kodu przewoźnika ($result->getCarrier()) oraz kodu samej metody ($result->getMethod()) połączonego z „ _” .

Produkty potrzebne do sprawdzenia pobierane są bezpośrednio z aktualnej wyceny klienta.
NOTATKA

Mały kawałek kodu w konstruktorze klasy tablicy pozwoli Ci zdefiniować cytat zarówno na frontendzie, jak i na backendzie (pod warunkiem, że zamówienie zostało utworzone w panelu administracyjnym).

Korzystając z \Magento\Framework\App\State możemy sprawdzić w jakim obszarze aktualnie się znajdujemy i wybrać odpowiedni cytat:
1. \Magento\Backend\Model\Session\Cytat dla administratora
2. \Magento\Checkout\Model\Session dla frontendu

Otóż ​​to!

Teraz możemy zweryfikować metody wysyłki i przejść do kolejnego etapu – stworzenia wtyczki do wyłączania nieprawidłowych (zgodnie z naszymi warunkami) metod wysyłki.

Oto jak:

 > MageWorx \ Zasady wysyłki \ Model \ Wtyczka \ Wysyłka \ Stawka \ Wynik \ GetAllRates 
 /**
 * Prawa autorskie 2016 MageWorx. Wszelkie prawa zastrzeżone.
 * Zobacz LICENSE.txt, aby uzyskać szczegółowe informacje na temat licencji.
 */

przestrzeń nazw MageWorx\ShippingRules\Model\Plugin\Shipping\Rate\Result;

klasa GetAllRates
{

    /**
     * Wyłącz zaznaczone stawki wysyłki.
     *
     * UWAGA: Jeśli nie widzisz niektórych stawek wysyłki, rozpocznij debugowanie od tego miejsca. Najpierw zaznacz „is_disabled”
     * param w obiekcie stawki wysyłki.
     *
     * @param \Magento\Shipping\Model\Rate\Result $subject
     * @param array $result
     * @tablica powrotu
     */
    funkcja publiczna afterGetAllRates($subject, $result)
    {
        foreach ($wynik jako $klucz => $stawka) {
            if ($rate->getIsDisabled()) {
                unset($wynik[$klucz]);
            }
        }

        zwróć $wynik;
    }
}

Ta wtyczka służy do pobierania danych o wszystkich dostępnych metodach wysyłki i sprawdzania każdej z nich. Jeśli jakaś z metod ma oznaczenie „is_disabled” , po prostu wykluczamy ją z listy, co pozwala nam zobaczyć tylko te metody, które odpowiadają warunkom utworzonym w walidatorze. Metody te są wykluczane na dowolnej stronie witryny, niezależnie od tego, czy jest to szacunkowa blokada wysyłki w koszyku, czy strona kasy.

Teraz, aby sprawdzić, jak działają nasze wtyczki, musimy je zarejestrować w pliku:

> MageWorx/Zasady wysyłki/etc/di.xml 
 <?xml version="1.0"?>
<config xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Shipping\Model\Rate\Result">
        <nazwa wtyczki="mageworx_shippingrules_update_rate_result"
                type="MageWorx\Zasady wysyłki\Model\Wtyczka\Wysyłka\Stawka\Wynik\Dołącz"
                sortOrder="10"
                wyłączone="false"/>
        <nazwa wtyczki="mageworx_shippingrules_update_disabled_or_enabled_rates"
                type="MageWorx\Zasady wysyłki\Model\Wtyczka\Wysyłka\Stawka\Wynik\GetAllRates"
                sortOrder="11"
                wyłączone="false"/>
    </type>
</config>

NOTATKA

Ze względów opisowych wtyczki są podzielone na 2 różne klasy. W zwykłym scenariuszu możesz użyć tylko 1 klasy, aby zmodyfikować 2 różne metody klasy Magento\Shipping\Model\Rate\Result.

Dlaczego to działa w ten sposób?

Magento\Shipping\Model\Rate\Result to główna klasa Magento 2 odpowiedzialna za procesję metod wysyłki. Jego metoda getAllRates służy do pobierania list metod wysyłki.

Tymczasem dodawanie metod wysyłki odbywa się zwykle za pomocą metody „dołącz”. Mając zwalidowane metody podczas dołączania i wykluczając je z kolekcji, możemy otrzymać listę poprawnych metod.

Sama walidacja również może być modyfikowana.

Nasze rozszerzenie ma dużą specjalną klasę, która przechowuje kolekcję niestandardowych filtrów z różnymi warunkami (takimi jak store_id, customer_group_id, data od/do, dni tygodnia itp . ). ma też osobną klasę z kolekcją akcji, które należy zastosować do metody wysyłki (np . włączyć lub wyłączyć, przepisać jej koszt według innych warunków, dodać dodatkowe koszty lub rabaty itp. )

Wynik pierwszej wtyczki w debugowaniu wygląda mniej więcej tak (dla produktu o wadze 1 jednostki):
1

Tak to wygląda w koszyku (ups_WXS jest nadal dostępny, ponieważ limit wagi nie został przekroczony):

2

Jeśli jednak zmienisz wagę produktu na 101, ta metoda wysyłki stanie się niedostępna:

3

Staje się dostępny ponownie, jeśli wykluczysz go z listy:
4

5

Przy kasie:

f3d3cac03678318af2d569d757fc7e79

NOTATKA

Listę wszystkich dostępnych metod wysyłki systemu możesz uzyskać bezpośrednio w kodzie w następujący sposób:

 /**
 * Zwróć tablicę przewoźników.
 * Jeśli $isActiveOnlyFlag jest ustawione na true, zwróci tylko aktywnych przewoźników
 *
 * @param bool $isActiveOnlyFlag
 * @tablica powrotu
 */
funkcja publiczna getAvailableMethods($isActiveOnlyFlag = false)
{
    $carriers = $this->shippingConfig->getAllCarriers();
    foreach ($carriers as $carrierCode => $carrierModel) {
        if (!$carrierModel->isActive() && (bool)$isActiveOnlyFlag === true) {
            kontynuować;
        }
        $carrierMethods = $carrierModel->getAllowedMethods();
        if (!$carrierMethods) {
            kontynuować;
        }
        foreach ($carrierMethods as $methodCode => $methodTitle) {
            $metody[] = $kod przewoźnika . '_' . $kod metody;
        }
    }

    return !pusty($metody) ? $metody : [];
}

Gdzie `$this->shippingConfig` jest instancją klasy `Magento\Shipping\Model\Config` . Korzystając z tego kodu, możesz stworzyć model źródłowy dla selektora metod wysyłki w ustawieniach rozszerzenia (dzięki temu nie będziesz musiał go na stałe zakodować we wtyczce).

Ostatni ale nie mniej ważny.

Jeśli nie chcesz tworzyć własnego rozszerzenia do wyłączania metod wysyłki, możesz skorzystać z naszego rozwiązania Shipping Suite dla Magento 2 .

Rozszerzenie pozwala wykluczyć dowolną metodę wysyłki w razie potrzeby za pomocą kilku kliknięć myszą.
1. Utwórz nową regułę wysyłki z następującym warunkiem:

8

2. Wybierz z listy akcję Ukryj metodę wysyłki i wybierz, które metody mają być wyłączone:

9

NOTATKA

Jeśli nie znajdziesz atrybutu „waga” na liście warunków, sprawdź, czy można go używać w regułach promocji:

10

Jeśli masz jakieś pytania lub pomysły, jak jeszcze bardziej ulepszyć nasze rozszerzenie , podziel się swoją opinią w sekcji komentarzy poniżej.