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.