0

Is there a way to modify the value of the Quote item/Product item before being saved in the Quote Item table? Let say I added a product in the cart, I can see that this product is added in the Quote Item Table in the DB. Now what I want is update that value first before saving it in the DB. So basically I want to make the value of the item is_virtual set to 1. The original Product is set to is_virtual = 0 but what I want is when I add this product to cart I want to update the value in the Quote_item table for column is_virtual and set it to 1. How can I achieve this? I think it can be done via plugin or observer? Like before_set_product or something. Is this possible and available? How do I do this?

Update: Just for reference I followed this same idea

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="checkout_cart_product_add_after">
        <observer name="set_is_virtual" instance="Vendor\Checkout\Observer\UpdateIsVirtual" />
    </event>
</config>

And the observer is like this

<?php
namespace Vendor\Checkout\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\RequestInterface;

class UpdateIsVirtual implements ObserverInterface
{
    public function execute(\Magento\Framework\Event\Observer $observer) {
        $item = $observer->getEvent()->getData('quote_item');
        $item = ( $item->getParentItem() ? $item->getParentItem() : $item );
    
        $item->setIsVirtual(1);
    }

}

This doesn't update the entry in the Quote Item table. I want the entry in the Quote Item table to be updated as well as it's the most important thing I need to accomplish

1 Answer 1

2

Actually is_virtual is set on beforeSave in Magento\Quote\Model\Quote\Item. So you would need a plugin after beforeSave

/**
 * Quote Item Before Save prepare data process
 *
 * @return $this
 */
public function beforeSave()
{
    parent::beforeSave();
    $this->setIsVirtual($this->getProduct()->getIsVirtual());
    if ($this->getQuote()) {
        $this->setQuoteId($this->getQuote()->getId());
    }
    return $this;
}

Create a plugin as below

File: app/code/VendorName/ModuleName/etc/frontend/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\Item">
        <plugin name="vendorname_modulename_set_is_virtual" type="VendorName\ModuleName\Plugin\SetQuoteItemIsVirtual"/>
    </type>
</config>

File: app/code/VendorName/ModuleName/Plugin/SetQuoteItemIsVirtual.php

<?php

namespace VendorName\ModuleName\Plugin;

use Magento\Quote\Model\Quote\Item;

/**
 * Set quote item is virtual
 */
class SetQuoteItemIsVirtual
{
    /**
     * @param Item $subject
     */
    public function afterBeforeSave(Item $subject)
    {
        $subject->setIsVirtual(1);
    }
}
3
  • Tried this approach but when I check the database it didn't update the record in the DB. That's the most important thing I want to do. I want to update the record in the DB Aug 4, 2020 at 13:50
  • I have edited the answer. Try this new solution. Aug 5, 2020 at 5:36
  • I want to save during go to checkout, not to load cart page only. Aug 3, 2022 at 7:54

Your Answer

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

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