If you want to set custom discount or fee at cart level in Magento 2, you can use the following code. It is common if you set a discount, you have to subtract the discount amount from the cart price and if you want to set custom fee on cart price, then you can add it.
Step 1 :
First you have to create a sales.xml file on app/code/Magemeta/Cartfee/etc
<?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="Magemeta\Cartfee\Model\Quote\Address\Total\CustomDiscount" sort_order="400"/>
</group>
</section>
</config>
Step 2 :
Create the file CustomDiscount.php on this path app\code\Magemeta\Cartfee\Model\Quote\Address\Total
namespace Magemeta\Cartfee\Model\Quote\Address\Total;
class CustomDiscount extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal
{
/**
* @var \Magento\Framework\Pricing\PriceCurrencyInterface
*/
protected $priceCurrency;
/**
* @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency [description]
*/
public function __construct(
\Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency
) {
$this->priceCurrency = $priceCurrency;
}
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);
$customDiscount = -10;
$total->addTotalAmount('customdiscount', $customDiscount);
$total->addBaseTotalAmount('customdiscount', $customDiscount);
$quote->setCustomDiscount($customDiscount);
return $this;
}
/**
* Assign subtotal amount and label to address object
*
* @param \Magento\Quote\Model\Quote $quote
* @param Address\Total $total
* @return array
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function fetch(\Magento\Quote\Model\Quote $quote, \Magento\Quote\Model\Quote\Address\Total $total)
{
return [
'code' => 'Custom_Discount',
'title' => $this->getLabel(),
'value' => 10
];
}
/**
* get label
* @return string
*/
public function getLabel()
{
return __('Custom Discount');
}
}
Step 3 :
Create file checkout_cart_index.xml on path app\code\Magemeta\Cartfee\view\frontend\layout
<?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">Magemeta_Cartfee/js/view/checkout/summary/custom-discount</item>
<item name="sortOrder" xsi:type="string">20</item>
<item name="config" xsi:type="array"
<item name="customdiscount" xsi:type="string" translate="true">Custom Discount</item>
</item>
</item>
</item>
</item>
</item>
</argument>
</arguments>
</referenceBlock>
</body>
</page>
Step 4 :
Create another file on same location.
<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">Magemeta_Cartfee/js/view/checkout/cart/totals/custom-discount</item>
<item name="sortOrder" xsi:type="string">20</item>
<item name="config" xsi:type="array">
<item name="template" xsi:type="string">Magemeta_Cartfee/checkout/cart/totals/custom-discount</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
Step 5 :
Create a file custom-discount.js on path app/code/Magemeta/Cartfee/view/frontend/web/js/view/checkout/cart/totals
define(
[
'Magemeta_Cartfee/js/view/checkout/summary/custom-discount'
],
function (Component) {
'use strict';
return Component.extend({
/**
* @override
*/
isDisplayed: function () {
return true;
}
});
}
);
Step 6 :
Create a file on this path custom-discount.js app/code/Magemeta/Cartfee/view/frontend/web/js/view/checkout/summary
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: 'Magemeta_Cartfee/checkout/summary/custom-discount'
},
totals: quote.getTotals(),
isDisplayedCustomdiscountTotal : function () {
return true;
},
getCustomdiscountTotal : function () {
var price = 10;
return this.getFormattedPrice(price);
}
});
}
)
Step 7 :
Create a file custom-discount.html on path app/code/Magemeta/Cartfee/view/frontend/web/template/checkout/cart/totals
<!-- if: isDisplayedCustomdiscountTotal() -->
<tr class="totals customdiscount excl">
<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>
<!-- /if -->
Step 8 :
Create a file custom-discount.html on path app/code/Magemeta/Cartfee/view/frontend/web/template/checkout/summary
<!-- if: isDisplayedCustomdiscountTotal() -->
<tr class="totals coupon-discount excl">
<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>
<!-- /if -->
Now you can see the custom discount amount on your cart and checkout page.