LineItem in den Warenkorb hinzufügen

Hallo Zusammen,

aktuell versuche ich einen Artikel in meinem Controller in den Warenkorb hinzuzufügen. Dabei gehe ich wie folgt vor:

$id = Uuid::randomHex();
$cart = $this->cartService->getCart($salesChannelContext->getToken(), $salesChannelContext);
$lineItem = new LineItem($id, "testitem", NULL, 1);
$lineItem->setLabel("TEST");
$lineItem->setGood(false);
$lineItem->setStackable(true);
$lineItem->setRemovable(true);
$price = new AbsolutePriceDefinition(10.00, $salesChannelContext->getContext()->getCurrencyPrecision());
$lineItem->setPriceDefinition($price);
$abcolutPrice = new CalculatedPrice( 10.00, 10.00, new CalculatedTaxCollection(), new TaxRuleCollection());
$lineItem->setPrice($abcolutPrice);
$cart->add($lineItem);

 Wenn ich mir jetzt direkt danach die variable $cart mit einem print\_r ausgebe, dann ist auch das Lineitem enthalten. Der Warenkorb im Frontend und in der Datenbank ist jedoch leer. Folgendes

$cart->getLineItems();

liefert ebenfalls das Item zurück, welches ich zuvor angelegt habe

Shopware\Core\Checkout\Cart\LineItem\LineItemCollection Object
(
    [elements:protected] => Array
        (
            [45f17ef07a204e35bf093ced862dc456] => Shopware\Core\Checkout\Cart\LineItem\LineItem Object
                (
                    [id:protected] => 45f17ef07a204e35bf093ced862dc456
                    [referencedId:protected] => 
                    [label:protected] => TEST
                    [quantity:protected] => 1
                    [type:protected] => testitem
                    [payload:protected] => Array
                        (
                        )

                    [priceDefinition:protected] => Shopware\Core\Checkout\Cart\Price\Struct\AbsolutePriceDefinition Object
                        (
                            [price:protected] => 10
                            [filter:protected] => 
                            [precision:protected] => 2
                            [extensions:protected] => Array
                                (
                                )

                        )

                    [price:protected] => Shopware\Core\Checkout\Cart\Price\Struct\CalculatedPrice Object
                        (
                            [unitPrice:protected] => 10
                            [quantity:protected] => 1
                            [totalPrice:protected] => 10
                            [calculatedTaxes:protected] => Shopware\Core\Checkout\Cart\Tax\Struct\CalculatedTaxCollection Object
                                (
                                    [elements:protected] => Array
                                        (
                                        )

                                    [extensions:protected] => Array
                                        (
                                        )

                                )

                            [taxRules:protected] => Shopware\Core\Checkout\Cart\Tax\Struct\TaxRuleCollection Object
                                (
                                    [elements:protected] => Array
                                        (
                                        )

                                    [extensions:protected] => Array
                                        (
                                        )

                                )

                            [referencePrice:protected] => 
                            [listPrice:protected] => 
                            [extensions:protected] => Array
                                (
                                )

                        )

                    [good:protected] => 
                    [description:protected] => 
                    [cover:protected] => 
                    [deliveryInformation:protected] => 
                    [children:protected] => Shopware\Core\Checkout\Cart\LineItem\LineItemCollection Object
                        (
                            [elements:protected] => Array
                                (
                                )

                            [extensions:protected] => Array
                                (
                                )

                        )

                    [requirement:protected] => 
                    [removable:protected] => 1
                    [stackable:protected] => 1
                    [quantityInformation:protected] => 
                    [modified:protected] => 
                    [extensions:protected] => Array
                        (
                        )

                )

        )

    [extensions:protected] => Array
        (
        )

)

Hat hier jemand eine Idee was ich Falsch mache?

Hi,

Dir fehlt der persist in die Datenbank, Du fügst das Item nur einer ArrayCollection hinzu.

Beispiel https://github.com/shopware/platform/blob/fb4bc791e185512bfde8cd0ea462b0cf527cf82f/src/Core/Checkout/Cart/SalesChannel/CartService.php#L236

@mowlwurf‍ schonmal vielen Dank für deine Antwort. Leider bringt das persist den Artikel auch nicht in den Warenkorb.
 

$this->persister->save($cart, $salesChannelContext);

Hast du noch eine Weitere Idee?

Der Persister macht eine Order aus dem Cart… Du musst den Cart meiner Meinung nach processen:

 $cart = $this-\>cartProcessor-\>process($cart, $salesChannelContext, new CartBehavior());

mit 

 Shopware\Core\Checkout\Cart\Processor

@mowlwurf‍, ich konnte jetzt erfolgreich einen Artikel hinzufügen der bereits existiert.

$cart = $this->cartService->getCart($context->getToken(), $context);
$lineItem = new LineItem($productId, "product", NULL, 1);
$lineItem->setLabel("TEST");
$lineItem->setGood(false);
$lineItem->setStackable(true);
$lineItem->setRemovable(true);
$lineItem->setReferencedId($productId);
$cart->add($lineItem);
$this->cartPersister->save($cart,$context);

Was leider nicht funktioniert ist ein customType für ein LineItem. Gibt es eine Idee wie ich diesen hinzuzufügen kann? Ich würde gerne ein LineItem “on the fly erstellen” und das Hinzufügen unter einem anderem Type.

Sorry, erst jetzt gelesen. ganz grob so:

$lineItem = new LineItem(
                Uuid::randomHex(),
                'custom'
            );
            $lineItem->setStackable(true);
            $lineItem->setRemovable(true);
            $lineItem->setLabel($label);
            $lineItem->setPriceDefinition($quantityPriceDefinition);
            $lineItem->setQuantity($quantity);
            $lineItem->setDeliveryInformation(new DeliveryInformation(100, 10.0, false));
            $this->cartService->add($cart,$lineItem, $salesChannelContext);
            $this->cartService->recalculate($cart, $salesChannelContext);

Wobei die quantityPriceDefinition auch eine andere Art der PriceDefinition sein kann.

Aber problematisch ist leider zur Zeit, dass custom LineItems nicht richtig kalkuliert werden!

https://issues.shopware.com/issues/NEXT-6936

1 „Gefällt mir“

@binaermanufaktur‍ Zu den Custom Line Items habe ich wahrscheinlich noch einen Bug gefunden. Wenn man das Line Item in den Warenkorb legt und durch den Checkout geht, dann verliert die Bestellung den Shipping Type. Kannst du das so nachvollziehen? 

@mfischer schrieb:

@binaermanufaktur‍ Zu den Custom Line Items habe ich wahrscheinlich noch einen Bug gefunden. Wenn man das Line Item in den Warenkorb legt und durch den Checkout geht, dann verliert die Bestellung den Shipping Type. Kannst du das so nachvollziehen? 

 Da hat mir anscheinend nur die Delivery Information gefehlt.

$lineItem->setDeliveryInformation(new DeliveryInformation(1000, 0.00, true));

 

Hallo,

ich versuche derzeit was ähnliches in meinem Controller, und zwar möchte ich einen Rabatt anhand einer vorigen Auswahl in den Warenkorb legen, wenn ich die Daten ausgebe, dann ist der Artikel zwar vorhanden, jedoch wird er nicht im Frontend ausgegeben.

Wäre über jede Hilfe dankbar

 /**
     *
     * @Route("/checkout/addBonus", name="frontend.checkout.addBonus"), methods={"GET"})
     */
    public function addBonus(Request $request, SalesChannelContext $context)
    {
        $data = $request->request;

        $cart = $this->cartService->getCart($context->getToken(), $context);

        $products = $this->findProducts($cart);

        if ($products->count() === 0) {
            return;
        }

        $discountLineItem = $this->createDiscount();

        // declare price definition to define how this price is calculated
        $definition = new AbsolutePriceDefinition("-" . $data->get("add_bonus_balance"), 2, null);

        $discountLineItem->setPriceDefinition($definition);

        // calculate price
        $discountLineItem->setPrice($this->calculator->calculate(
            $definition->getPrice(),
            $cart->getLineItems()->getPrices(),
            $context
        ));

        // add discount to new cart
        $this->cartService->add($cart, $discountLineItem, $context);
        $this->cartService->recalculate($cart, $context);

        return $this->forwardToRoute($data->get("redirectTo"));
    }

    private function findProducts(Cart $cart): LineItemCollection
    {
        return $cart->getLineItems()->filter(function (LineItem $item) {
            if ($item->getType() !== LineItem::PRODUCT_LINE_ITEM_TYPE) {
                return false;
            }

            return $item;
        });
    }

    private function createDiscount(): LineItem
    {
        $discountLineItem = new LineItem(Uuid::randomHex(), 'aws-bonus-voucher', null, 1);

        $discountLineItem->setLabel('Bonus');
        $discountLineItem->setGood(false);
        $discountLineItem->setStackable(false);
        $discountLineItem->setRemovable(false);

        return $discountLineItem;
    }

 

PUSH

Keiner ne Info hierzu?

Hallo @Anel‍,

so genau kann ich dir leider keine Antwort geben. Da liegt es wohl an folgender Zeile:

$discountLineItem = new LineItem(Uuid::randomHex(), ‚aws-bonus-voucher‘, null, 1);

Hier versuchst du ein Lineitem mit dem Type ‚aws-bonus-voucher‘ hinzuzufügen. Diesen Type gibt es jedoch nicht. Wie man diesen erstellt war mir auch noch unklar.

@mfischer‍ Hab es auch mit den Shopware eigenen Typen versucht (z.B. custom)

https://docs.shopware.com/en/shopware-platform-dev-en/how-to/cart-add-discount
Hier wird ja auch ein “eigener Typ” sozusagen verwendet. Bisher gab es weder auf gitter noch hier Hilfe.  Crying

Habe es bereits mit mehreren Varianten probiert, das Item ist wie gesagt im dump vorhanden, jedoch nicht im frontend.

Das ist leider im Shop unseren Kunden ein wichtiger Aspekt.

Falls noch jemand auf dasselbe Problem stößt, hier mein Code.

public function addBonus(Request $request, SalesChannelContext $context)
    {
        $this->denyAccessUnlessLoggedIn();

        $data = $request->request;

        $cart = $this->cartService->getCart($context->getToken(), $context);

        //check if products are in cart
        $products = $this->findProducts($cart);

        $bonus = $this->findCustomBonus($cart);

        if ($products->count() === 0) {
            return;
        }

        if($bonus->count() !== 0){
            return $this->forwardToRoute($data->get("redirectTo"));
        }

        //create a discount
        $discountLineItem = $this->createDiscount();

        $definition = new QuantityPriceDefinition("-" . $data->get("add_bonus_balance"), new TaxRuleCollection(), $context->getContext()->getCurrencyPrecision(), 1, true);

        $discountLineItem->setPriceDefinition($definition);

        // add discount to new cart
        $cart->add($discountLineItem, $context);
        $this->cartService->recalculate($cart, $context);

        return $this->forwardToRoute($data->get("redirectTo"));
    }

    private function findProducts(Cart $cart): LineItemCollection
    {
        return $cart->getLineItems()->filter(function (LineItem $item) {
            if ($item->getType() !== LineItem::PRODUCT_LINE_ITEM_TYPE) {
                return false;
            }

            return $item;
        });
    }

    private function findCustomBonus(Cart $cart): LineItemCollection
    {
        return $cart->getLineItems()->filter(function (LineItem $item) {
            if ($item->getType() !== LineItem::CUSTOM_LINE_ITEM_TYPE) {
                return false;
            }

            if($item->getDescription() !== 'avs-custom-bonus'){
                return false;
            }

            return $item;
        });
    }

    private function createDiscount(): LineItem
    {
        $discountLineItem = new LineItem(Uuid::randomHex(), 'custom');

        $discountLineItem->setLabel('Bonusguthaben');
        $discountLineItem->setGood(false);
        $discountLineItem->setStackable(false);
        $discountLineItem->setDescription("avs-custom-bonus");
        $discountLineItem->setRemovable(true);
        $discountLineItem->setPayload([]);

        return $discountLineItem;
    }

 

1 „Gefällt mir“