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ę!

Felix Schönherr
źródło
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.

Sony
źródło
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

Zrobiłem fragment, który pozwala ci zmienić cenę. W rzeczywistości zmienia cenę po dodaniu produktu do koszyka. Innymi słowy, zmienia ceny twoich produktów w ofercie. https://gist.github.com/0-Sony/d9d2ea792b5533bfeaff28827e6f207a

Mam nadzieję, że to pomoże.

Sony
źródło
Przepraszam, że to nie pomaga, nie mogę użyć obserwatora, muszę użyć kontrolera
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.

coderGeek
źródło
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

Arunprabakaran M
źródło
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();
?>
Ketan Borada
źródło
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 ... !!!

Balwant Singh
źródło
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