4

I have write module for set custom price of product when adding to cart but my code not working.

     namespace Navin\Testcart\Observer;

        use Magento\Framework\Event\ObserverInterface;
        use Magento\Framework\App\RequestInterface;

        class CustomPrice implements ObserverInterface
        {
            public function invoke(\Magento\Framework\Event\Observer $observer) {
                //echo "test";exit();
                 $item=$observer->getEvent()->getData('quote_item');
                 $product=$observer->getEvent()->getData('product');
                $item = ( $item->getParentItem() ? $item->getParentItem() : $item );
                // Load the custom price
                $price = $product->getPrice()+10; // 10 is custom price. It will increase in product price.
                // Set the custom price
                $item->setCustomPrice($price);
                $item->setOriginalCustomPrice($price);
                // Enable super mode on the product.
                $item->getProduct()->setIsSuperMode(true);
            }

        }
  

Help for resolve my issue.

2
  • Please add more details about your issue? Which event you want to catch? Commented Sep 23, 2016 at 5:51
  • Did you found solution?? Commented Apr 10, 2017 at 6:36

3 Answers 3

6

Please use this even checkout_cart_product_add_after, and also I suggest you that

ObserverInterface has only one method which is execute, so write your code in this method.

And do not use parent Item because while you are adding to cart any item then price depend upon child item so the best way is to use directly that item object that you are getting. So best practice is to use that item itself.

And also return $this object at the end of your code inside execute method.

For eg: namespace Navin\Testcart\Observer;

use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\RequestInterface;

class CustomPrice implements ObserverInterface
{
    public function execute(\Magento\Framework\Event\Observer $observer) {

        $item=$observer->getEvent()->getData('quote_item');
        $product=$observer->getEvent()->getData('product');
        // here i am using item's product final price
        $price = $item->getProduct()->getFinalPrice()+10; // 10 is custom price. It will increase in product price.
        // Set the custom price
        $item->setCustomPrice($price);
        $item->setOriginalCustomPrice($price);
        // Enable super mode on the product.
        $item->getProduct()->setIsSuperMode(true);
        return $this;
    }

}

Hope this will help you. :)

5
  • not working i have try @Rose Hale Commented Sep 23, 2016 at 13:52
  • When i apply wrong coupon code product price become 0 in row total. If i apply again, price display correct. Do you know why this happen? It happen only first time.
    – user55548
    Commented Nov 19, 2018 at 10:22
  • This is not work if when bundle product is in cart in magento-2.1 @Rose Hale. Commented Nov 20, 2018 at 10:34
  • 1
    Working.. Thanks @Rose Hale.. Commented Apr 4, 2019 at 5:45
  • hi @Rose, same code i am using in controller, its not working for me, here is my question,magento.stackexchange.com/questions/274172/… Commented May 13, 2019 at 15:17
2

A before plugin for the Quote class' AddProduct function might be a better way to do what you're trying to do. From the devdocs, best practice is

Events SHOULD NOT change a state of observable objects.

whereas a plugin

is a class that modifies the behavior of public class functions by intercepting a function call and running code before, after, or around that function call. This allows you to substitute or extend the behavior of original, public methods for any class or interface.

Basically with a plugin you'd modify the price of the product before the quote object is created rather than changing the price of the quote object after it is created.

There's some good discussion about plugins vs observers and which is better. The general consensus seems to be that observers are a legacy Magento 1 thing whereas plugins are the new hotness, but both work. You can read more of the discussion here if you'd like.

Here's how you could do what you're after with a plugin.

Define the plugin in app/code/YourName/YourModule/etc/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Quote\Model\Quote">
    <plugin name="change_price_plugin" type="YourName\YourBuilder\Plugin\QuotePlugin"
            sortOrder="10" disabled="false"/>
</type>

Then in app/code/YourName/YourModule/Plugin/QuotePlugin.php

<?php

namespace YourName\YourModule\Plugin;

class QuotePlugin
{
    /**
     * @param \Magento\Quote\Model\Quote $subject
     * @param \Magento\Catalog\Model\Product $product
     * @param null|float|\Magento\Framework\DataObject $request
     * @param null|string $processMode
     * @throws \Exception
     * @return array
     */
    public function beforeAddProduct(
        $subject,
        $product,
        $request = null,
        $processMode = \Magento\Catalog\Model\Product\Type\AbstractType::PROCESS_MODE_FULL
    ){          
        $newPrice = $product->getFinalPrice() + 10;
        $product->setPrice($newPrice);
        $request['custom_price'] = $newPrice;

        return [$product, $request, $processMode];
    }       
} 
2
  • This seems to be a best aproach to the solution but do you know why it doesn't work for grouped products?
    – Strife86
    Commented Oct 17, 2020 at 3:47
  • Any idea about how can i add product custom special price(Sale price) the same waay?
    – Nafsss
    Commented Jan 8, 2021 at 9:25
0

public function execute(Observer $observer) {

    /** @var $item \Magento\Quote\Model\Quote\Item */       $item = $observer->getEvent()->getQuote()->getAllVisibleItems();        if ($item) {
            foreach ($item->getQuote()->getAllItems() as $bundleitems) {
                /** @var $bundleitems\Magento\Quote\Model\Quote\Item */
                //Skip the bundle product
                if ($bundleitems->getProduct()->getTypeId() == Type::TYPE_BUNDLE) {
                    continue;
                }
                $bundleitems->setCustomPrice(1.00);
                $bundleitems->setOriginalCustomPrice(1.00);
                $bundleitems->getProduct()->setIsSuperMode(true);

            }           }       return $this;   }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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