0

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 ?

  • What event are you hooking onto? I've had success using sales_quote_item_set_product – Ricky Odin Matthews May 30 '18 at 10:16
  • hi @dharth, have you got the correct answer for this? – jafar pinjar Aug 1 '19 at 12:43
2

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

      }

   }
  • I tried but problem is still the same, values are ok on item but not on total. On table quote the grand_total, subtotal_with_discount doesn't take discount – dharth May 30 '18 at 14:20
  • Maybe I need to add my values to the total like that : $total->addTotalAmount() ? – dharth May 30 '18 at 14:23
  • @dharth yes you have to set the values in $total. Here is an example : $discountAmount = [customDiscountTotal]; $total->setDiscountAmount([customDiscountTotal]); $total->setBaseDiscountAmount([customDiscountTotal]); $total->setTaxAmount([customTaxTotal]); $total->setBaseTaxAmount([customTaxTotal]); $total->addTotalAmount($this->getCode(), $discountAmount); $total->addBaseTotalAmount($this->getCode(), $discountAmount); Note : customDiscountTotal is sum of custom discount amount applied to each product in cart . – Renu Mishra Jun 5 '18 at 13:35
  • @RenuMishra can we use $quote->collectTotals() method to get total? – Umar Jul 4 '18 at 8:56
  • @umar yes, It is possible to get Grand Total Sub Total : $quote->collectTotals()->getSubtotal(); Grand Total :$quote->collectTotals()->getGrandTotal(); – Renu Mishra Jul 6 '18 at 10:01

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.