Set custom price of product when adding to cart code not working
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. :)
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];
}
}