Magento – How to Add Custom Quote Discount on Product Line

discountmagento2quote

I'm trying to add custom discount amount on quote to specific product line,
I saw event sales_quote_address_discount_item, when I use it like that :

    $item = $observer->getData('item');
    $item->setDiscountAmount(10);
    $item->setBaseDiscountAmount(10);
    $item->save();

In database (quote_item) I can see that column 'discount_amount' and 'base_discount_amount' contains my amount, but nothing on quote table and on quote_address.

How can I apply from code a custom discount on one specific product in quote ?

Best Answer

We are saving custom discount on line item level i.e in quote_item table

Please follow the below steps:

  1. Create sales.xml file in your custom module inside etc directory

    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Sales:etc/sales.xsd">
        <section name="quote">
          <group name="totals">
            <item name="customdiscount" instance="[VendorName]\[Namespace]\Model\Quote\Address\Total\Discount" sort_order="500"/>
          </group>
       </section>
    </config>
    
  2. create discount.php in [VendorName]/[Namespace]/Model/Quote/Address/Total

Note : This is not the complete code but it will help you to save the custom discount on item level.

    namespace [VendorName]\[Namespace]\Model\Quote\Address\Total;

    use Magento\Catalog\Model\ProductRepository;

    class Discount extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal
       {

/** @var $_productRepository */
protected $_productRepository;

/**
 * Discount constructor.
 * @param ProductRepository $productRepository
 */
public function __construct(
    ProductRepository $productRepository

) {
    $this->setCode('customdiscount');
    $this->_productRepository = $productRepository;

}

/**
 * Collect address discount amount
 *
 * @param \Magento\Quote\Model\Quote $quote
 * @param \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment
 * @param \Magento\Quote\Model\Quote\Address\Total $total
 * @return $this
 */
public function collect(
    \Magento\Quote\Model\Quote $quote,
    \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment,
    \Magento\Quote\Model\Quote\Address\Total $total
) {
    $data = $quote->getItems();
    if (!count($data)) {
        return $this;
    }
    parent::collect($quote, $shippingAssignment, $total);

        /** Custom Discount is saved in line item level (i.e in quote_item) */
        foreach ($data as $item) {
            if ($item['has_children']) {
                $product = $this->_productRepository->get($item['sku']);
            } else {
                $product = $this->_productRepository->getById($item['product_id']);
            }
                           $item->setDiscountAmount([setyourcustomdiscount]);
                            $item->setBaseDiscountAmount([setyourcustomdiscount]);
                            $item->setTaxAmount([setcustomTax]);
                            $item->setBaseTaxAmount([setcustomTax]);

      }

   }
Related Topic