Magento 2: Geteilte Reihenfolge für jeden Artikel

7

Ich muss meine Bestellungen für jeden Artikel aufteilen (da ich für jeden einzelnen Artikel in meinem Warenkorb einen Bestellstatus und einen Lieferschein benötige).

Ich habe versucht, dies anhand der folgenden Ressourcen zu tun:

Magento2 Split Order basierend auf dem Anbieter

So teilen Sie die Reihenfolge in Magento 2

Magento Mehrfachbestellung an einer Kasse oder Auftragsaufteilung

Aber ich kann es nicht zum Laufen bringen, die erste Bestellung wird erstellt und die zweite stürzt ab. (Onepage-Checkout aktiviert)

Was mache ich falsch?

Magento / Quote / Model / QuoteManagement.php

public function placeOrder($cartId, PaymentInterface $paymentMethod = null)
{
    $quote = $this->quoteRepository->getActive($cartId);
    if ($paymentMethod) {
        $paymentMethod->setChecks([
            \Magento\Payment\Model\Method\AbstractMethod::CHECK_USE_CHECKOUT,
            \Magento\Payment\Model\Method\AbstractMethod::CHECK_USE_FOR_COUNTRY,
            \Magento\Payment\Model\Method\AbstractMethod::CHECK_USE_FOR_CURRENCY,
            \Magento\Payment\Model\Method\AbstractMethod::CHECK_ORDER_TOTAL_MIN_MAX,
            \Magento\Payment\Model\Method\AbstractMethod::CHECK_ZERO_TOTAL,
        ]);
        $quote->getPayment()->setQuote($quote);

        $data = $paymentMethod->getData();
        $quote->getPayment()->importData($data);
    }

    if ($quote->getCheckoutMethod() === self::METHOD_GUEST) {
        $quote->setCustomerId(null);
        $quote->setCustomerEmail($quote->getBillingAddress()->getEmail());
        $quote->setCustomerIsGuest(true);
        $quote->setCustomerGroupId(\Magento\Customer\Api\Data\GroupInterface::NOT_LOGGED_IN_ID);
    }


    $this->eventManager->dispatch('checkout_submit_before', ['quote' => $quote]);

    $tempQuote = $quote;

    foreach($tempQuote->getAllItems() as $tempItem) {

        foreach($quote->getAllItems() as $item) {

            $quote->getItemsCollection()->removeItemByKey($item->getId());   
        }

        $quote->getItemsCollection()->addItem($tempItem);
        $quote->setTotalsCollectedFlag(false)->collectTotals();
        $order = $this->submit($quote);
        $orders[] = $order;
        $quote = $tempQuote;

        if (null == $order) {
            throw new LocalizedException(
                __('An error occurred on the server. Please try to place the order again.')
            );
        }


        $this->checkoutSession->setLastQuoteId($quote->getId());
        $this->checkoutSession->setLastSuccessQuoteId($quote->getId());
        $this->checkoutSession->setLastOrderId($order->getId());
        $this->checkoutSession->setLastRealOrderId($order->getIncrementId());
        $this->checkoutSession->setLastOrderStatus($order->getStatus());

    }


    $this->eventManager->dispatch('checkout_submit_all_after', ['orders' => $orders, 'quote' => $quote]);

    return $orders;
}

Ich habe die Kerndateien nur zum Testen bearbeitet. Ich werde ein Plugin oder ein Überschreiben für die placeOrder-Methode erstellen, sobald es funktioniert.

TrytoFly
quelle
Wie legen Sie die Gesamt- und Zwischensumme jeder Bestellung nach der Auftragsaufteilung fest?
user00247
Wie können wir Bestellungen mithilfe eines Zahlungsgateways eines
Drittanbieters aufteilen

Antworten:

3

Ich habe dies auf meiner eigenen lokalen Implementierung von Magento 2.2 Enterprise überprüft und es funktioniert folgendermaßen:

    public function placeOrder($cartId, PaymentInterface $paymentMethod = null)
{
    $quote = $this->quoteRepository->getActive($cartId);
    $paymentMethodString = $quote->getPayment()->getMethod(); // edit 19.10.17

    // get data from addresses and remove ids
    $billingAddress = $quote->getBillingAddress()->getData();
    $shippingAddress = $quote->getShippingAddress()->getData();
    unset($billingAddress['id']);
    unset($billingAddress['quote_id']);
    unset($shippingAddress['id']);
    unset($shippingAddress['quote_id']);

    foreach($quote->getAllItems() as $item) {
        // init Quote Split
        $quoteSplit = $this->quoteFactory->create();
        $quoteSplit->setStoreId($quote->getStoreId());
        $quoteSplit->setCustomer($quote->getCustomer());
        $quoteSplit->setCustomerIsGuest($quote->getCustomerIsGuest());
        if ($quote->getCheckoutMethod() === self::METHOD_GUEST) {
            $quoteSplit->setCustomerEmail($quote->getBillingAddress()->getEmail());
            $quoteSplit->setCustomerGroupId(\Magento\Customer\Api\Data\GroupInterface::NOT_LOGGED_IN_ID);
        }

        // save quoteSplit in order to have a quote id for item
        $this->quoteRepository->save($quoteSplit);

        // add item
        $item->setId(null); // init item id for force to be added to quoteSplit collection
        $quoteSplit->addItem($item);

        // set addresses
        $quoteSplit->getBillingAddress()->setData($billingAddress);
        $quoteSplit->getShippingAddress()->setData($shippingAddress);

        // recollect totals into the quote
        $quoteSplit->setTotalsCollectedFlag(false)->collectTotals();

        // set payment method // edit 19.10.17
        $quoteSplit->getPayment()->setMethod($paymentMethodString);
        if ($paymentMethod) {
            $quoteSplit->getPayment()->setQuote($quoteSplit);
            $data = $paymentMethod->getData();
            $quoteSplit->getPayment()->importData($data);
        }

        // dispatch this event as Magento standard once per each quote split
        $this->eventManager->dispatch('checkout_submit_before', ['quote' => $quoteSplit]);
        $this->quoteRepository->save($quoteSplit);
        $order = $this->submit($quoteSplit);
        $orders[] = $order;

        if (null == $order) {
            throw new LocalizedException(
                __('An error occurred on the server. Please try to place the order again.')
            );
        }

    }
    // disable origin quote
    $quote->setIsActive(false);
    $this->quoteRepository->save($quote); // edit 19.10.17

    $this->checkoutSession->setLastQuoteId($quoteSplit->getId());
    $this->checkoutSession->setLastSuccessQuoteId($quoteSplit->getId());
    $this->checkoutSession->setLastOrderId($order->getId());
    $this->checkoutSession->setLastRealOrderId($order->getIncrementId());
    $this->checkoutSession->setLastOrderStatus($order->getStatus());

    $this->eventManager->dispatch('checkout_submit_all_after', ['orders' => $orders, 'quote' => $quote]);

    /**
     * the API declaration and interface describe this function returning int, you can't return an array.
     * in order to do that you will have to create a new end point for that.
     */
    return $order->getId();
}

Bitte lassen Sie mich wissen, ob dies das Problem für Sie behebt oder ob Sie einen Fehler erhalten haben.

Matias Hidalgo
quelle
Vielen Dank für Ihre Antwort, ich weiß nicht, ob es noch funktioniert, da Magento Probleme hat, die Zahlungsmethode (CE 2.2) zu erhalten. Call to a member function getData() on nullauf $data = $paymentMethod->getData();.
TrytoFly
2
Ok, ich habe ein paar Änderungen vorgenommen, aber du hast mich gerettet! Ich werde den Beitrag mit kleinen Änderungen bearbeiten, hoffe, dass auch jemand anderes davon profitieren kann!
TrytoFly
Das ist großartig. TrytoFly, danke für die Antwort und behebe das Problem. Es wird sicher anderen helfen. Ich war gestern unterwegs und habe es heute gefunden.
Matias Hidalgo
@MatiasHidalgo Wie kann ich die Gesamtsumme und Zwischensumme jeder Bestellung nach der Auftragsaufteilung festlegen?
user00247
@ user00247 Die Zeile "$ quoteSplit-> setTotalsCollectedFlag (false) -> collectTotals ()" sollte diese Funktion ausführen. Wenn Sie einen benutzerdefinierten Gesamtbetrag wünschen, sollte es besser sein, einen benutzerdefinierten Gesamtbetrag hinzuzufügen oder einen Rabatt auf die Angebotselemente anzuwenden. .. nur zu denken, wenn Sie nur GT und ST einstellen, wird wahrscheinlich später Fehler verursachen
Matias Hidalgo
0

Mit Multentipping, das mit Magento 2 geliefert wird und die separate Bestellung für jedes Artikelprodukt im Warenkorb ermöglicht, können Sie dies problemlos tun. Wenn Sie es auch für die normale Kaufabwicklung implementieren möchten, müssen Sie nur das Plugin auf die Magento\Quote\Model\Quote\ItemKlasse und ihre RepresentProduct-Funktion anwenden . Fügen Sie diesen Code in Ihr eindi.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\Quote\Model\Quote\Item">
        <plugin name="orders-quote-item" type="Vendor\Module\Plugin\Quote\Item" />
</type>
</config>

Und im Plugin dh Item.php folgenden Code einfügen

use Magento\Quote\Model\Quote\Item as QuoteItem;
class Item
{
    public function aroundRepresentProduct(QuoteItem $subject, \Closure $proceed, $product)
    {
        return false;
    }
}

Alles erledigt. Sie können mich gerne anrufen, wenn Sie ein anderes Problem haben.

Vivek Kumar
quelle
Das vorgeschlagene Plugin dient zum Hinzufügen eines Artikels gleichzeitig zum Warenkorb. Ich würde jedoch eine Möglichkeit benötigen, die Bestellung in mehrere Bestellungen aufzuteilen, nicht nur in mehrere Artikel in meinem Warenkorb. Obwohl immer noch ein hilfreiches Plugin.
TrytoFly
@TrytoFly Entschuldigung, ich habe Ihre Frage falsch gestellt. Sollte ich diese Antwort löschen, wenn sie nicht hilfreich war?
Vivek Kumar
Ich würde es verlassen, vielleicht stolpert jemand über diesen Thread und sucht nach genau diesem Plugin.
TrytoFly