In this article, we will learn about to add custom discount in Magento 2.
Store owners implement sales promotion techniques, and offering discounts is one of them.
Discount offers are the short term tactics to boost your sale.
Simply applying discount, you may require to Programmatically Add custom discounts in Magento 2 as a part of the marketing strategies and increase the sale.
Steps to Add A Custom Discount Programmatically in Magento 2
Step 1 : Register file sales.xml located in
app/code/Mageants/Blog/etc/sales.xml
<?xml version="1.0"?> <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="Mageants\Blog\Model\Total\Quote\Custom" sort_order="400"/> </group> </section> </config> |
Step 2 : Add discount to change the total in the model at
app/code/Mageants/Blog/Model/Total/Quote/Custom.php
<?php namespace Mageants\Blog\Model\Total\Quote; /** * @param \Magento\Quote\Model\Quote $quote * @param \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment * @param \Magento\Quote\Model\Quote\Address\Total $total * @return $this|bool */ use Magento\Quote\Model\Quote; use Magento\Quote\Api\Data\ShippingAssignmentInterface; use Magento\Quote\Model\Quote\Address\Total; class Custom extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal { /** * @var \Magento\Framework\Pricing\PriceCurrencyInterface */ protected $_priceCurrency; /** * Custom constructor. * @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency */ public function __construct( \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency ){ $this->_priceCurrency = $priceCurrency; } public function collect( Quote $quote, ShippingAssignmentInterface $shippingAssignment, Total $total ) { parent::collect($quote, $shippingAssignment, $total); $baseDiscount = 10; $discount = $this->_priceCurrency->convert($baseDiscount); $total->addTotalAmount('customdiscount', -$discount); $total->addBaseTotalAmount('customdiscount', -$baseDiscount); $total->setBaseGrandTotal($total->getBaseGrandTotal() - $baseDiscount); $quote->setCustomDiscount(-$discount); return $this; } } |
Now, you will see the Grand Total was changed. But there is no total discount information. Because the Magento use knockout js to show the total.
Step 3 : Add the total in the Layout file resided at
app/code/Mageants/Blog/view/frontend/layout/checkout_cart_index.xml
<?xml version="1.0"?> <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="customdiscount" xsi:type="array"> <item name="component" xsi:type="string">Mageants_Blog/js/view/checkout/cart/totals/customdiscount</item> <item name="sortOrder" xsi:type="string">20</item> <item name="config" xsi:type="array"> <item name="template" xsi:type="string">Mageants_Blog/checkout/cart/totals/customdiscount</item> <item name="customdiscount" xsi:type="string" translate="true">Custom Discount</item> </item> </item> </item> </item> </item> </argument> </arguments> </referenceBlock> </body> </page> |
Step 4 : View Model KnockOut at
app/code/Mageants/Blog/view/frontend/web/js/view/checkout/cart/totals/ customdiscount.js
define( [ 'jquery', 'Magento_Checkout/js/view/summary/abstract-total', 'Magento_Checkout/js/model/quote', 'Magento_Checkout/js/model/totals', 'Magento_Catalog/js/price-utils' ], function ($,Component,quote,totals,priceUtils) { "use strict"; return Component.extend({ defaults: { template: 'Mageants/Blog/checkout/cart/totals/customdiscount' }, totals: quote.getTotals(), isDisplayedCustomdiscountTotal : function () { return true; }, getCustomdiscountTotal : function () { var price = - 10; return this.getFormattedPrice(price); } }); } ); |
Also Read: How To Add A Custom Filter To The Product Grid In Magento 2?
Step 5 : The total discount will be shown in the template knockout,
app/code/Mageants/Blog/view/frontend/web/template/checkout/cart/totals/ customdiscount.html
<!-- ko if: isDisplayedCustomdiscountTotal() --> <tr class="border border-gray"> <th class="mark" colspan="1" scope="row" data-bind="text: customdiscount"></th> <td class="amount"> <span class="price" data-bind="text: getCustomdiscountTotal(), attr: {'data-th': customdiscount}"></span> </td> </tr> <!-- /ko --> |
Step 6 : Add the total in the Layout file resided at
app/code/Mageants/Blog/view/frontend/layout/checkout_index_index.xml
<?xml version="1.0"?> <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.root"> <arguments> <argument name="jsLayout" xsi:type="array"> <item name="components" xsi:type="array"> <item name="checkout" xsi:type="array"> <item name="children" xsi:type="array"> <item name="sidebar" xsi:type="array"> <item name="children" xsi:type="array"> <item name="summary" xsi:type="array"> <item name="children" xsi:type="array"> <item name="totals" xsi:type="array"> <item name="children" xsi:type="array"> <item name="customdiscount" xsi:type="array"> <item name="component" xsi:type="string"> Mageants_Blog/js/view/checkout/summary/customdiscount </item> <item name="sortOrder" xsi:type="string">20</item> <item name="config" xsi:type="array"> <item name="template" xsi:type="string">Mageants_Blog/checkout/summary/customdiscount</item> <item name="title" xsi:type="string" translate="true">Custom Discount</item> </item> </item> </item> </item> <item name="cart_items" xsi:type="array"> <item name="children" xsi:type="array"> <item name="details" xsi:type="array"> <item name="children" xsi:type="array"> <item name="subtotal" xsi:type="array"> <item name="component" xsi:type="string">Magento_Tax/js/view/checkout/summary/item/details/subtotal</item> </item> </item> </item> </item> </item> </item> </item> </item> </item> </item> </item> </item> </argument> </arguments> </referenceBlock> </body> </page> |
Step 7 : View Model KnockOut at
app/code/Mageants/Blog/view/frontend/web/js/view/checkout/summary/ customdiscount.js
define( [ 'jquery', 'Magento_Checkout/js/view/summary/abstract-total', 'Magento_Checkout/js/model/quote', 'Magento_Checkout/js/model/totals', 'Magento_Catalog/js/price-utils' ], function ($,Component,quote,totals,priceUtils) { "use strict"; return Component.extend({ defaults: { template: 'Mageants/Blog/checkout/summary/customdiscount' }, totals: quote.getTotals(), isDisplayedCustomdiscountTotal : function () { return true; }, getCustomdiscountTotal : function () { var price = - 10; return this.getFormattedPrice(price); } }); } ); |
Step 8 : The total discount will be shown in the template knockout,
app/code/Mageants/Blog/view/frontend/web/template/checkout/summary/ customdiscount.html
<!-- ko if: isDisplayedCustomdiscountTotal() --> <tr class="border border-gray"> <th class="mark" colspan="1" scope="row" data-bind="text: title"></th> <td class="amount"> <span class="price" data-bind="text: getCustomdiscountTotal()"></span> </td> </tr> <!-- /ko --> |
Finally, you can see the custom discount amount on your cart and checkout page.
Conclusion:
Using above article, you can easily “Add Custom Discount” in Magento 2. If you have any query regarding above code implementation then you can contact us or let us know in comment section.