I want to apply custom discount amount to cart programmatically. I have tried doing it in following 2 ways, none of which work:
METHOD 1:
I tried following the default way in which Magento2 applies sales-rule
discounts. I did it by creating following files in my module:
etc\sales.xml
<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="discount" instance="Vendorname\Modulenmae\Model\CustomFolderName\Quote\Discount" sort_order="400"/>
</group>
</section>
</config>
frontend\layout\checkout_cart_index.xml
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="checkout.cart.totals">
<arguments>
<argument name="jsLayout" xsi:type="array">
<item name="components" xsi:type="array">
<item name="block-totals" xsi:type="array">
<item name="children" xsi:type="array">
<item name="before_grandtotal" xsi:type="array">
<item name="children" xsi:type="array">
<item name="discount" xsi:type="array">
<item name="config" xsi:type="array">
<item name="title" xsi:type="string" translate="true">My Custom Discount</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</argument>
</arguments>
</referenceBlock>
</body>
</page>
Model File
class Discount extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal
{
public function collect(
\Magento\Quote\Model\Quote $quote,
\Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment,
\Magento\Quote\Model\Quote\Address\Total $total
) {
parent::collect($quote, $shippingAssignment, $total);
$label = 'My Custom Discount';
$discountAmount = -10;
$total->setDiscountDescription($label);
$total->setDiscountAmount($discountAmount);
$total->setBaseDiscountAmount($discountAmount);
$total->setSubtotalWithDiscount($total->getSubtotal() + $discountAmount);
$total->setBaseSubtotalWithDiscount($total->getBaseSubtotal() + $discountAmount);
return $this;
}
//fetch function is also defined in this class. Since it is only used for display purposes I have not added its code in this question.
}
However, with this method, my custom discount gets applied but Magento's default sales rules
like coupon code
, etc. stop working. They throw errors like Invalid Coupon Code
even when the coupon code is completely valid. If I revert my changes, the default coupon codes start working again.
METHOD 2:
Another method i tried is applying discount by observing the sales_quote_collect_totals_after
event. It is working fine, but i think method 1 might be the best way to achieve it.
Any ideas as to how can I do it correctly ?
Best Answer
Thanks @R.S. . I found the solution by referring repo created by @R.S. here: https://github.com/magepal/stackexchange/tree/develop/104112 after some minor modifications.
sales.xml
Model file
checkout_cart_index.xml
checkout_index_index.xml
Fetch is not showing the custom discount description. I have opened its ticket here: https://github.com/magento/magento2/issues/3594