Magento 2: Zmiana ceny produktu w kontrolerze nie działa w tej chwili!


9

Próbowałem zmienić cenę moich produktów w ten sposób:

Controller.php:

[EDYTOWAĆ]

   <?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;
        }
    }
}

(EDYCJA) Wraz z nowym kodem cena się zmienia, ale suma częściowa nie! Jak widać tutaj: wprowadź opis zdjęcia tutaj

Z góry dziękuję!


Cześć, możesz opracować? z którego kontrolera korzystasz i jakie jest Twoje zadanie? Czy chcesz zmienić cenę, gdy klient doda produkt do koszyka?
Sony

Witaj Sony, nie chcę zmienić ceny, jeśli klikniesz przycisk, a nie jeśli produkt zostanie dodany do koszyka. Na razie chcę tylko zmienić cenę wszystkich produktów na 100 $ za testowanie. Zaktualizuję moje pytanie, aby pokazać ci trochę więcej kodu
Felix Schönherr

Przepraszam, boję się nie zrozumieć, co próbujesz. Kiedy patrzę na twój kod, chcesz zmienić ceny przedmiotów, które są w twoim koszyku. Rzeczywiście dzwonisz quotez checkoutSession. Jestem trochę zmieszany.
Sony

Tak, chcę zmienić ceny produktów w moim koszyku. Próbowałem też innych rzeczy, aby to osiągnąć, a ostatnim, który wypróbowałem, jest obecny kod z cytatem.
Felix Schönherr

Zmiana ceny nie będzie działać przy użyciu kontrolera, do którego musisz użyć wtyczki lub obserwatora.
Aasim Goriya

Odpowiedzi:


5

Rozumiem, myślę, że masz rację, ale myślę, że musisz zapisać cytat. Jeśli spojrzysz na tę klasę: \Magento\Checkout\Controller\Cart\Add możesz zobaczyć w linii 114:

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

            $this->cart->save();

Zmieniam cenę wydarzenia, które jest wywoływane na końcu addProduct()metody, a Magento zapisuje wózek na końcu. W twoim przypadku musisz zapisać wycenę w swoim kontrolerze.


Ok, cena się teraz zmienia (spójrz na moje zaktualizowane pytanie), ale suma częściowa się nie zmieni, jakieś pomysły?
Felix Schönherr

również jeśli klikniesz na kasę, cena będzie znowu taka sama
Felix Schönherr

Myślę, że musisz rzucić okiem na model wyceny, zwłaszcza na metodę collectTotals (). Musisz ustawić flagę $ this-> setTotalsCollectedFlag (false), która prosi Magento o ponowne obliczenie.
Sony

Niestety nie zadziałało to dla mnie :(
Felix Schönherr

Wypróbowałem to na wiele różnych sposobów i nigdy nie zadziałało.
Felix Schönherr


3

Chcesz zaktualizować sumę wierszy, a nie sumę częściową, użyj metody $item->setRowTotal()lub $item->setBaseRowTotal(). Może także pomóc dodać $item->save()przed końcem pętli.

Suma częściowa to suma częściowa zamówienia / koszyka.


Niestety nic to nie zmieniło. Ale dziękuję za odpowiedź
Felix Schönherr

3

@ Felix, musisz ustawić setSubtotal()wycenę. Ustaw sumę częściową poza f or loop.

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

lubię to

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();

Uwaga: kod przetestowany


Może pracował dla ciebie, ale nie dla mnie.
Felix Schönherr

Czy próbowałeś tego ($ subTotal = $ cart-> getQuote () -> setSubtotal ($ subtotalprice);) poza tym dla pętli
Arunprabakaran M

tak, zrobiłem to dokładnie tak, jak powiedziałeś
Felix Schönherr

setSubtotal nie działa. poprawny? inne metody ustawiania działają dobrze jak setprice? poprawny?
Arunprabakaran M

Tak poprawnie ....
Felix Schönherr

3

Aby uzyskać cenę koszyka Upadate, zamiast sesji zakupu należy użyć modelu koszyka. Załaduj przedmiot z koszyka i zaktualizuj go.

<?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();
?>

Właściwie to nie działa, przepraszam
Felix Schönherr

To mój działający kod, tworzę wycenę według ceny niestandardowej według API. Musi być Work. Może to być konflikt modułu z twoją stroną
Ketan Borada,

0

Wypróbuj poniższy kod:

musisz zmodyfikować process()funkcję dla swoich wymagań.

vendor / magento / module-sales-rule / Model / 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;
    }

UWAGA: Nie modyfikuj plików podstawowych Magento. Utwórz wtyczkę do tego.

Mam nadzieję, że to pomoże ... !!!


Ale jeśli utworzę wtyczkę dla tego i jednego innego rozszerzenia, które działa w tym samym sklepie, również utworzę wtyczkę Validator.php, tylko jedna będzie działać. prawdziwe?
Felix Schönherr

@ felix: Nie, wystarczy utworzyć wtyczkę dla funkcji procesu pliku validator.php. będzie działał dla wszystkich twoich sklepów. po pierwsze dokonujesz zmian w pliku podstawowym i sprawdzasz, czy twoje wymaganie jest spełnione czy nie? Jeśli wszystko jest w porządku z tą modyfikacją, to po utworzeniu wtyczki do tego.
Balwant Singh

Ok, spróbuję tego jutro, a następnie udzieli odpowiedzi.
Felix Schönherr

To tylko zmieniło cenę w podsumowaniu koszyka, ale cena produktów pozostała taka sama
Felix Schönherr
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.