Magento – Magento 2 – Add Custom Discount to Order Totals on Cart page

cartdiscountmagento2

protected function productpointAjax()
{

    $layout = $this->_view->getLayout();
    $this->checkoutSession->setCartWasUpdated(true); 
    $totalsBlock = $layout->createBlock('Magento\Checkout\Block\Cart\Totals')->setTemplate('Magento_Checkout::cart/totals.phtml');
    return $totalsBlock->toHtml();
}

config.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
    <sales>
         <quote>
            <totals>
                <productpoint>
                    <class>productpoint/quote/address/total/productpoint</class>
                    <after>subtotal</after>
                    <before>tax</before>
                </productpoint>
            </totals>
         </quote>
    </sales>
</config>

Namespace\Modulename\Model\Quote\Address\Total\Productpoint.php

<?php
namespace Ei\Productpoint\Model\Quote\Address\Total;

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

    protected $ProductPointCode = '';
    protected $EstimatePoints  = '';


    public function __construct(
        \Ei\Productpoint\Helper\Data $productpointHelper,
        \Magento\Checkout\Model\Session $checkoutSession,
        array $data = []
    ){

        parent::__construct($data);
        $this->checkoutSession = $checkoutSession;
        $this->productpointHelper = $productpointHelper;
        $this->moduleStatus = $this->productpointHelper->getModuleStatus();
        $this->minPointsConfig  = $this->productpointHelper->getMinimumPoints();
        $this->productPoints    = $this->productpointHelper->getCustomerProductPointsAssigned();
        $this->ProductPointCode = $this->productpointHelper->getCode();
        $this->EstimatePoints  = $this->checkoutSession->getEstimatePoints();
        $this->PointsRedeem  = $this->checkoutSession->getPointsRedeem();
        $this->PointsPrice  = $this->checkoutSession->getPointsPrice();
    }

    //In function collect() you can add whatever amount you want to the order totals
    public function collect(\Magento\Quote\Model\Quote\Address $address)
    {

        parent::collect($address);

        $this->_setAmount(0);
        $this->_setBaseAmount(0);

        $items = $this->_getAddressItems($address);
        if (!count($items)) {
            return $this; //this makes only address type shipping to come through
        }

        $quote = $address->getQuote();

                //check if module enabled, minpoints < points assigned and productpoint redeemed only then display in grand_total block        
        if( ($this->ProductPointCode == $this->EstimatePoints) && ($this->moduleStatus == 1) && ($this->minPointsConfig < $this->productPoints) ){

                $exist_amount = $quote->getProductpointAmount();
                $productPointPrice = $this->productpointHelper->getPrice($this->PointsRedeem);
                $balance = $productPointPrice - $exist_amount;

        $address->setProductpointAmount($balance);
        $address->setBaseProductpointAmount($balance);

        $quote->setProductpointAmount($balance);

        $address->setGrandTotal($address->getGrandTotal() - $address->getProductpointAmount());
                $address->setBaseGrandTotal($address->getBaseGrandTotal() - $address->getBaseProductpointAmount());
            }    

    }

    //The function fetch() is used for display purposes
    public function fetch(\Magento\Quote\Model\Quote\Address $address)
    {
                //check if module enabled, minpoints < points assigned and productpoint redeemed only then display in grand_total block        
                if(($this->ProductPointCode == $this->EstimatePoints) && ($this->moduleStatus == 1) && ($this->minPointsConfig < $this->productPoints)){

                $amount = $address->getProductpointAmount();
                $address->addTotal(array(
                'code'  => $this->productpointHelper->getCode(),
                'title' => __('Points Redeem ('.$this->PointsRedeem.'&nbsp;points)'),
                'value' => '-'.$amount
        ));

                return $this;
            }    

    }
}

It throws below exception

There has been an error processing your request Notice: Undefined
index: components in
app\code\Magento\Checkout\Block\Cart\CartTotalsProcessor.php on line
18

Whenever the totals are calculated for a quote, it should also call my class and add custom discount if applicable. The two main functions here
are collect() and fetch(). In collect function you add whatever amount you want to the order totals, and fetch() is used for display purposes.

How can I show custom discount on cart page by adding it to totals block ?

P.S. The above code works well with version 1.8/1.9

Reference link 1/2

Best Answer

You can follow this link : 'how to add fee to order totals in magento2'. This link have detail how to add fee in total you can add your custom discount same way.

Related Topic