9

I tried to change the Price of my Products like this:

Controller.php:

[EDIT]

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

(EDIT) With the new code the price changes, but the subtotal not! As you can see here: enter image description here

Thanks in advance!

  • Hi, can you elaborate? which controller do you use, and what is your task? Do you want to change the price when a customer adds a product to the cart? – Sony Aug 28 at 9:49
  • Hello Sony, no i want to change the price, if a button is clicked, not if a product is getting added to cart. For now i just want to change the price of all products to 100$ for testing. I will update my question to show you some more code – Felix Schönherr Aug 28 at 9:58
  • Sorry, I am afraid to not understand what you are trying. When I look at your code, you look to want to change the prices of items which are in your basket. Indeed you are calling the quote from the checkoutSession . I am a bit confused. – Sony Aug 28 at 10:12
  • Yes I want to change the prices of the items in my basket. I tried some other stuff as well to achieve this and the last one I tried is the current code with quote. – Felix Schönherr Aug 28 at 11:56
  • The price change will not work using the controller you need to use plugin or observer for that. – Aasim Goriya Sep 3 at 6:11
5
+150

I get it, I think you are in the right way, but I think you have to save the quote. If you take a look on this class : \Magento\Checkout\Controller\Cart\Add you can see at Line 114 :

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

            $this->cart->save();

I change the price from the event which is called at the end of the addProduct() method, and Magento saves the cart at the end. So in your case, you have to save the quote in your controller.

  • Ok, Price gets changed now (look at my updated Question), but the subtotal wont change, any ideas? – Felix Schönherr Aug 28 at 14:50
  • also if you then click on checkout, the price is the same again – Felix Schönherr Aug 28 at 14:57
  • I think you have to take a look on the Quote Model, especially at the collectTotals() method. You have to set the flag $this->setTotalsCollectedFlag(false) which ask to Magento to calculate again. – Sony Aug 28 at 15:09
  • Unfortunately this did not work for me :( – Felix Schönherr Aug 29 at 5:41
  • Tried it in a lot of different ways and it never worked. – Felix Schönherr Aug 29 at 5:42
3

I did a snippet which allows you to change the price. Actually, it changes the price after you add product in your basket. In other words, it changes the prices of your items in your quote. https://gist.github.com/0-Sony/d9d2ea792b5533bfeaff28827e6f207a

Hope it helps.

  • Sorry it does not help, i cant use an observer, i need to use my controller – Felix Schönherr Aug 28 at 13:40
3

You want to update the row total and not the subtotal, use method $item->setRowTotal() or $item->setBaseRowTotal(). Also, it might help to add $item->save() before the end of the loop.

Subtotal is the order/cart subtotal.

  • Unfortunately this changed nothing. But thanks for your answer – Felix Schönherr Sep 4 at 14:18
3

@felix,You need to set setSubtotal() for a quote. Set Subtotal outside for loop.

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

like this

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

Note: Code Tested

  • May worked for you, but not for me. – Felix Schönherr Sep 5 at 11:13
  • Did you try this( $subTotal = $cart->getQuote()->setSubtotal($subtotalprice);) outside this for loop – Arunprabakaran M Sep 5 at 12:51
  • yes, i did this exactly how you said – Felix Schönherr Sep 5 at 14:02
  • setSubtotal is only not working. correct? other set methods working fine like setprice ? correct? – Arunprabakaran M Sep 5 at 14:03
  • Yes correct.... – Felix Schönherr Sep 5 at 14:06
3

For Upadate cart price you have to use Model cart instead checkout session. Load item from cart and update it.

<?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();
?>
  • Actually it is not working, sorry – Felix Schönherr Sep 5 at 14:05
  • It's my working code,i'm creating Quote by custom price by API.It must Work.may be any module conflicts your side – Ketan Borada Sep 6 at 12:05
0

Try below code:

you need to modify process() function for your requirement.

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

NOTE: Don't modify magento core files. Create plugin for this.

I hope it will help...!!!

  • But if I create a plugin for this and one other extension, which runs on the same store, also creates a plugin of the Validator.php only one will be working. true? – Felix Schönherr Aug 28 at 12:50
  • @felix : No, you just need to create plugin for process function of validator.php file. it will run for your all stores.first you just make change in core file and check once your requirement is fulfil or not? If all are okay with this modification then after you create plugin for this. – Balwant Singh Aug 28 at 12:54
  • Ok, will try this tomorrow and will then give you a reply. – Felix Schönherr Aug 28 at 13:39
  • This only changed the Price in the summary of the cart, but the price of the products just stay the same – Felix Schönherr Aug 29 at 5:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.