Magento 2: Das Ändern des Produktpreises in Controller funktioniert derzeit nicht!


9

Ich habe versucht, den Preis meiner Produkte folgendermaßen zu ändern:

Controller.php:

[BEARBEITEN]

   <?php

namespace MassiveArt\ShoppingCart\Controller\Index;

use Magento\Catalog\Model\ProductFactory;
use Magento\Checkout\Model\Cart;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Framework\Controller\Result\JsonFactory;
use Magento\Framework\Data\Form\FormKey;

class Index extends Action
{
    /**
     * @var FormKey
     */
    protected $formKey;

    /**
     * @var Session
     */
    protected $checkoutSession;

    /**
     * @var Cart
     */
    protected $cart;

    /**
     * @var ProductFactory
     */
    protected $productFactory;

    /**
     * Constructor.
     *
     * @param Context                         $context
     * @param \Magento\Checkout\Model\Session $checkoutSession
     * @param \Magento\Customer\Model\Session $customerSession
     * @param JsonFactory                     $resultJsonFactory
     * @param FormKey                         $formKey
     * @param Cart                            $cart
     * @param ProductFactory                  $productFactory
     */
    public function __construct(
        Context $context,
        \Magento\Checkout\Model\Session $checkoutSession,
        \Magento\Customer\Model\Session $customerSession,
        JsonFactory $resultJsonFactory,
        FormKey $formKey,
        Cart $cart,
        ProductFactory $productFactory
    ) {
        $this->checkoutSession = $checkoutSession;
        $this->customerSession = $customerSession;
        $this->formKey = $formKey;
        $this->resultJsonFactory = $resultJsonFactory;
        $this->cart = $cart;
        $this->productFactory = $productFactory;
        parent::__construct($context);
    }

    public function execute()
    {
        try {

            // Set result data and pass back
            $result = $this->resultJsonFactory->create();


            $allItems = $this->checkoutSession->getQuote()->getAllVisibleItems();
            foreach ($allItems as $item) {
                $item = ( $item->getParentItem() ? $item->getParentItem() : $item );
                $price = 100; //set your price here
                $item->setCustomPrice($price);
                $item->setOriginalCustomPrice($price);
                $item->setSubtotal($price);
                $item->getProduct()->setIsSuperMode(true);
            }
            $this->checkoutSession->setTotalsCollectedFlag(false);
            $this->checkoutSession->getQuote()->save();
            $this->checkoutSession->getQuote()->setTotalsCollectedFlag(false);
            $this->setTotalsCollectedFlag(false);

            $result->setData(['message' => __("Products added succesfully")]);

            return $result;
        } catch (\Exception $e) {
            $result->setData(['error' => __($e->getMessage())]);
            return $result;
        }
    }
}

(BEARBEITEN) Mit dem neuen Code ändert sich der Preis, die Zwischensumme jedoch nicht! Wie Sie hier sehen können: Geben Sie hier die Bildbeschreibung ein

Danke im Voraus!


Hallo, kannst du das näher erläutern? Welchen Controller verwenden Sie und was ist Ihre Aufgabe? Möchten Sie den Preis ändern, wenn ein Kunde ein Produkt in den Warenkorb legt?
Sony

Hallo Sony, nein, ich möchte den Preis ändern, wenn auf eine Schaltfläche geklickt wird, nicht, wenn ein Produkt in den Warenkorb gelegt wird. Im Moment möchte ich nur den Preis aller Produkte zum Testen auf 100 $ ändern. Ich werde meine Frage aktualisieren, um Ihnen etwas mehr Code zu zeigen
Felix Schönherr

Entschuldigung, ich habe Angst, nicht zu verstehen, was Sie versuchen. Wenn ich mir Ihren Code ansehe, möchten Sie die Preise der Artikel in Ihrem Warenkorb ändern. In der Tat rufen Sie die quotevon der checkoutSession. Ich bin etwas verwirrt.
Sony

Ja, ich möchte die Preise der Artikel in meinem Warenkorb ändern. Ich habe auch einige andere Dinge ausprobiert, um dies zu erreichen, und das letzte, das ich ausprobiert habe, ist der aktuelle Code mit Anführungszeichen.
Felix Schönherr

Die Preisänderung funktioniert nicht mit dem Controller, für den Sie ein Plugin oder einen Observer benötigen.
Aasim Goriya

Antworten:


5

Ich verstehe, ich denke, Sie sind auf dem richtigen Weg, aber ich denke, Sie müssen das Zitat speichern. Wenn Sie sich diese Klasse ansehen: \Magento\Checkout\Controller\Cart\Add Sie können in Zeile 114 sehen:

$this->cart->addProduct($product, $params);
            if (!empty($related)) {
                $this->cart->addProductsByIds(explode(',', $related));
            }

            $this->cart->save();

Ich ändere den Preis von dem Ereignis, das am Ende der addProduct()Methode aufgerufen wird, und Magento speichert den Wagen am Ende. In Ihrem Fall müssen Sie das Angebot also in Ihrem Controller speichern.


Ok, der Preis wird jetzt geändert (siehe meine aktualisierte Frage), aber die Zwischensumme ändert sich nicht, irgendwelche Ideen?
Felix Schönherr

Auch wenn Sie dann auf Kasse klicken, ist der Preis wieder der gleiche
Felix Schönherr

Ich denke, Sie müssen sich das Quote-Modell ansehen, insbesondere die Methode collectTotals (). Sie müssen das Flag $ this-> setTotalsCollectedFlag (false) setzen, das Magento zur erneuten Berechnung auffordert.
Sony

Leider hat das bei mir nicht funktioniert :(
Felix Schönherr

Versuchte es auf viele verschiedene Arten und es hat nie funktioniert.
Felix Schönherr


3

Sie möchten die Zeilensumme und nicht die Zwischensumme aktualisieren, verwenden Sie die Methode $item->setRowTotal()oder $item->setBaseRowTotal(). Es kann auch hilfreich sein, $item->save()vor dem Ende der Schleife hinzuzufügen .

Zwischensumme ist die Zwischensumme für Bestellung / Warenkorb.


Leider hat sich daran nichts geändert. Aber danke für deine Antwort
Felix Schönherr

3

@ felix, du musst setSubtotal()ein Angebot machen. Zwischensumme außerhalb f setzen or loop.

$subTotal = $cart->getQuote()->setSubtotal($price);
$this->checkoutSession->getQuote()->save();

so was

foreach ($allItems as $item) {
                $item = ( $item->getParentItem() ? $item->getParentItem() : $item );
                $price = 100; //set your price here
                $item->setCustomPrice($price);
                $item->setOriginalCustomPrice($price);
                $item->getProduct()->setIsSuperMode(true);
            }
            $subtotalprice=100;
            $subTotal = $cart->getQuote()->setSubtotal($subtotalprice);
            $this->checkoutSession->setTotalsCollectedFlag(false);
            $this->checkoutSession->getQuote()->save();

Hinweis: Code getestet


May hat für dich gearbeitet, aber nicht für mich.
Felix Schönherr

Haben Sie dies versucht ($ subTotal = $ cart-> getQuote () -> setSubtotal ($ subtotalprice);) außerhalb dieser for-Schleife
Arunprabakaran M

Ja, ich habe genau das getan, was du gesagt hast
Felix Schönherr

setSubtotal funktioniert nur nicht. richtig? andere Set-Methoden funktionieren gut wie Setprice? richtig?
Arunprabakaran M

Ja richtig ....
Felix Schönherr

3

Für den Upadate-Warenkorbpreis müssen Sie anstelle der Checkout-Sitzung den Modellwagen verwenden. Laden Sie den Artikel aus dem Warenkorb und aktualisieren Sie ihn.

<?php 
$items = $this->cart->getQuote()->getAllItems(); //Magento\Checkout\Model\Cart $cart
foreach($items as $item) {

    $item = $this->cart->getQuote()->getItemById($item->getId());
    if (!$item) {
      continue;
    }

    $price = 100;
    $item->setCustomPrice($price);
    $item->setOriginalCustomPrice($price);
    $item->getProduct()->setIsSuperMode(true);
    $item->save();           
}
$this->cart->save();
?>

Eigentlich funktioniert es nicht, sorry
Felix Schönherr

Es ist mein Arbeitscode, ich erstelle ein Angebot nach benutzerdefiniertem Preis per API. Es muss funktionieren. Möglicherweise sind alle Modulkonflikte auf Ihrer Seite
Ketan Borada

0

Versuchen Sie den folgenden Code:

Sie müssen die process()Funktion für Ihre Anforderung ändern .

Hersteller / Magento / Modul-Verkaufsregel / Modell / Validator.php

/**
     * Quote item discount calculation process
     *
     * @param AbstractItem $item
     * @return $this
     */
    public function process(AbstractItem $item)
    {
        $item->setDiscountAmount(0);
        $item->setBaseDiscountAmount(0);
        $item->setDiscountPercent(0);
        $itemPrice = $this->getItemPrice($item);
        if ($itemPrice < 0) {
            return $this;
        }

        $appliedRuleIds = $this->rulesApplier->applyRules(
            $item,
            $this->_getRules($item->getAddress()),
            $this->_skipActionsValidation,
            $this->getCouponCode()
        );
        $this->rulesApplier->setAppliedRuleIds($item, $appliedRuleIds);
        /*Your custom code START here*/
        $item = ( $item->getParentItem() ? $item->getParentItem() : $item );
        $price = 499; //set your price here
        $item->setCustomPrice($price);
        $item->setOriginalCustomPrice($price);
        $item->getProduct()->setIsSuperMode(true);
        //echo "sku: ".$item->getSku()."=== Name: ".$item->getName();die;
        /* Your custom code END here */
        return $this;
    }

HINWEIS: Ändern Sie keine Magento-Kerndateien. Plugin dafür erstellen.

Ich hoffe es wird helfen ... !!!


Wenn ich jedoch ein Plugin für diese und eine andere Erweiterung erstelle, die im selben Store ausgeführt wird, wird auch ein Plugin der Datei Validator.php erstellt, von dem nur eines funktioniert. wahr?
Felix Schönherr

@felix: Nein, Sie müssen nur ein Plugin für die Prozessfunktion der Datei validator.php erstellen. Es wird für alle Stores ausgeführt. Nehmen Sie zunächst eine Änderung in der Kerndatei vor und überprüfen Sie, ob Ihre Anforderung erfüllt ist oder nicht. Wenn alle mit dieser Änderung einverstanden sind, nachdem Sie das Plugin dafür erstellt haben.
Balwant Singh

Ok, werde es morgen versuchen und dir dann eine Antwort geben.
Felix Schönherr

Dies änderte nur den Preis in der Zusammenfassung des Warenkorbs, aber der Preis der Produkte bleibt einfach gleich
Felix Schönherr
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.