2

In magento 2 cart page how add a more than one discount

I want be like this:

enter image description here

But i get like this

enter image description here

app/code/Bg/SpecialPromotion/view/frontend/web/js/view/checkout/cart/total/fee.js

 define([
    'ko',
    'uiComponent',
    'Magento_Checkout/js/model/quote',
    'Magento_Catalog/js/price-utils',
    'Magento_Checkout/js/model/totals'

], function (ko, Component, quote, priceUtils, totals) {
    'use strict';
    var show_hide_Extrafee_blockConfig = window.checkoutConfig.show_hide_Extrafee_block;
    var fee_label = window.checkoutConfig.fee_label;
    var custom_fee_amount = window.checkoutConfig.custom_fee_amount;

    return Component.extend({

        totals: quote.getTotals(),
        canVisibleExtrafeeBlock: show_hide_Extrafee_blockConfig,
        getFormattedPrice: ko.observable(priceUtils.formatPrice(custom_fee_amount, quote.getPriceFormat())),
        getFeeLabel:ko.observable(fee_label),

        isDisplayed: function () {
            return this.getValue() != 0;
        },
        getValue: function() {
            var price = 0;
            if (this.totals() && totals.getSegment('fee')) {
                price = totals.getSegment('fee').value;
            }
            return price;
        }
    });
});

app/code/Bg/SpecialPromotion/view/frontend/template/checkout/cart/total/fee.html

<!-- ko if: isDisplayed() -->
<tr class="totals fee excl" >
    <th class="mark" colspan="1" scope="row" data-bind="text: getFeeLabel()"></th>
    <td class="amount">
        <span class="price" data-bind="text: getFormattedPrice()"></span>
    </td>
</tr>
<!-- /ko -->

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="fee" instance="Bg\SpecialPromotion\Model\Quote\Total\Fee" sort_order="150"/>
        </group>
    </section>
 <section name="order_invoice">
        <group name="totals">
            <item name="fee" instance="Bg\SpecialPromotion\Model\Invoice\Total\Fee" sort_order="160"/>
        </group>
    </section>
 <section name="order_creditmemo">
        <group name="totals">
            <item name="fee" instance="Bg\SpecialPromotion\Model\Creditmemo\Total\Fee" sort_order="160"/>
        </group>
    </section>
</config>

app/code/Bg/SpecialPromotion/Model/Quote/Total/Fee.php

<?php
namespace Bg\SpecialPromotion\Model\Quote\Total;

use Magento\Store\Model\ScopeInterface;

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

    protected $helperData;
    protected $_priceCurrency;


    protected $quoteValidator = null;

    public function __construct(\Magento\Quote\Model\QuoteValidator $quoteValidator,
                                \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
                                \Bg\SpecialPromotion\Helper\Data $helperData)
    {
        $this->quoteValidator = $quoteValidator;
        $this->_priceCurrency = $priceCurrency;
        $this->helperData = $helperData;
    }

    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);
        if (!count($shippingAssignment->getItems())) {
            return $this;
        }
        // $test = $this->helperData->getExtrafee();
        // print_r($test);exit;

        $enabled = $this->helperData->isModuleEnabled();
        $minimumOrderAmount = $this->helperData->getMinimumOrderAmount();
        $subtotal = $total->getTotalAmount('subtotal');
        if ($enabled && $minimumOrderAmount <= $subtotal) {
              $fee = $this->helperData->getExtrafee();
            //Try to test with sample value
             // $fee=-50;
            $total->setTotalAmount('fee', $fee);
            $total->setBaseTotalAmount('fee', $fee);
            $total->setFee($fee);
            $quote->setFee($fee);


            $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
            $productMetadata = $objectManager->get('Magento\Framework\App\ProductMetadataInterface');
            $version = (float)$productMetadata->getVersion(); 

            if($version > 2.1)
            {
                //$total->setGrandTotal($total->getGrandTotal() + $fee);
            }
            else
            {
                $total->setGrandTotal($total->getGrandTotal()+$fee);
            }

        }
        return $this;
    }

    /**
     * @param \Magento\Quote\Model\Quote $quote
     * @param \Magento\Quote\Model\Quote\Address\Total $total
     * @return array
     */
    public function fetch(\Magento\Quote\Model\Quote $quote, \Magento\Quote\Model\Quote\Address\Total $total)
    {

        $enabled = $this->helperData->isModuleEnabled();
        $minimumOrderAmount = $this->helperData->getMinimumOrderAmount();
        $subtotal = $quote->getSubtotal();
        $fee = $quote->getFee();

        $result = [];
        if ($enabled && ($minimumOrderAmount <= $subtotal) && $fee) {
            $result = [
                'code' => 'fee',
                'title' => $this->helperData->getFeeLabel(),
                'value' => $fee
            ];
        }
        return $result;
    }

    /**
     * Get Subtotal label
     *
     * @return \Magento\Framework\Phrase
     */
    public function getLabel()
    {
        return __('Extra Fee');
    }

    /**
     * @param \Magento\Quote\Model\Quote\Address\Total $total
     */
    protected function clearValues(\Magento\Quote\Model\Quote\Address\Total $total)
    {
        $total->setTotalAmount('subtotal', 0);
        $total->setBaseTotalAmount('subtotal', 0);
        $total->setTotalAmount('tax', 0);
        $total->setBaseTotalAmount('tax', 0);
        $total->setTotalAmount('discount_tax_compensation', 0);
        $total->setBaseTotalAmount('discount_tax_compensation', 0);
        $total->setTotalAmount('shipping_discount_tax_compensation', 0);
        $total->setBaseTotalAmount('shipping_discount_tax_compensation', 0);
        $total->setSubtotalInclTax(0);
        $total->setBaseSubtotalInclTax(0);

    }
}

app/code/Bg/SpecialPromotion/Helper/Data.php

 <?php

    namespace Bg\SpecialPromotion\Helper;
    use Magento\Framework\App\Helper\AbstractHelper;
    use Magento\Framework\App\Helper\Context;
    use Magento\Framework\App\Config\ScopeConfigInterface;
    use Magento\Store\Model\ScopeInterface;
    use Magento\SalesRule\Model\RuleFactory;
    use \Magento\Framework\Serialize\Serializer\Json;
    use \Magento\SalesRule\Model\Rule;
    class Data extends AbstractHelper
    {


        protected $scopeConfig;
        protected $_ruleFactory;

        public function __construct(
            Context $context,
            ScopeConfigInterface $scopeInterface,
             RuleFactory $ruleFactory ,
            Rule  $ruleModel   ) {
            parent::__construct($context);
            $this->scopeConfig = $scopeInterface;
            $this->_ruleFactory = $ruleFactory;
            $this->ruleModel=$ruleModel;
        }
        public function isModuleEnabled()
        {
            return  1;
        }
        public function getMinimumOrderAmount()
        {

            return 1;
        }

        public function getExtrafee()
        {
            $amount = $this->getFinalRule();
            $amt = array();
           foreach ($amount as $key => $value) {
            $amt[] = $value['amount'];
           }
           $sum_of_amount = array_sum($amt);
            return $sum_of_amount;
        }
         public function getFeeLabel()
        {
           $name = $this->getFinalRule();
            $label = array();
           foreach ($name as $key => $value) {
            $label[] = $value['name'];
           }
            // $label = 'Special Discount';
            return $label;
        }
 public function getFinalRule()
    {
      $activeRule = $this->getActiveRule();
      $result =array();
      $rule_info = array();

      foreach ($activeRule as $key => $rule) {

             $id = $rule['rule_id'];
             $action = $rule['simple_action'];
             $name   = $rule['description'];
             $discount_amount = $rule['discount_amount'];
             $max_discount  =  $rule['max_discount'];
             $discount_qty =  $rule['discount_qty'];
             $discount_step = $rule['discount_step'];
             $priceselector = $rule['priceselector'];
             $apply_discount_to =$rule['apply_discount_to'];
             // $apply_to_shipping = $rule['apply_to_shipping'];
             // $stop_rules_processing = $rule[' stop_rules_processing'];


        switch($action){

        case "thecheapest":
                $cartItem = $this->getCartItem();
                $amt = array();
                foreach ($cartItem as $key => $item) {
                  $qty = $item->getQty();
                  if($qty >= 2)
                  {
                    if($priceselector == 0)
                    {
                      $price = $item->getProduct()->getFinalPrice();
                    }
                    else if($priceselector == 2)
                    {
                      $price = $item->getProduct()->getPrice();
                    }
                    else
                    {
                      $price = $item->getProduct()->getFinalPrice();
                    }
                    if(($qty%2==0))
                    {
                       $x_product = ($qty/2);
                       $final_amt = ($price * $x_product);
                       $amt[] = $final_amt;
                    }
                    else
                    {
                      $x_odd = $qty - 1;
                      $x_product = ($x_odd/2);
                      $final_amt = (($price * $x_product));
                      $amt[] = $final_amt;
                    }
                   }
                  } 

                $amount = array_sum($amt);
                $finalDiscount = -$amount;
                $rule_info[]= [
                  'name' => $name,
                  'amount'=> $finalDiscount,

                ];
                break;

        case "moneyamount":
              $cartTotal = $this->getCartTotal();
              if($cartTotal >= $discount_step)
              {
                 $get_x = $cartTotal/$discount_step;
                 $lower_round_off = floor($get_x);
                 $final_amt = $lower_round_off * $discount_amount;
              }
              else
              {
                $final_amt =0;
              }
               $finalDiscount = -$final_amt;
               $rule_info[] = [
                        'name' => $name,
                        'amount'=> $finalDiscount,
                      ];
       break;

        } // end  of swich case

      } // end of for loop
      return $rule_info;
    }
    }
  • Try this solution...Use subtract instead of add in custom price - magento.stackexchange.com/questions/92774/…, Ping me if you want demo – Ranganathan Sep 3 at 10:15
  • Hope this will help you... https://www.magestore.com/magento-2-tutorial/how-to-add-magento-2-custom-discount/ – Partab Saifuddin Zakir Sep 3 at 10:30
  • custom price will appear, its not appear one by one in car summary – divya sekar Sep 3 at 10:51
  • @Ranganathan how to show a discount one by one in cart page – divya sekar Sep 6 at 6:00
  • Found solution or not? – Ranganathan Sep 6 at 11:21
2

Try to get additional fee from config provider

app/code/Bg/SpecialPromotion/Helper/Data.php

<?php
    namespace Bg\SpecialPromotion\Helper;

    use Magento\Framework\App\Helper\AbstractHelper;
    use Magento\Framework\App\Helper\Context;
    use Magento\Framework\App\Config\ScopeConfigInterface;
    use Magento\Store\Model\ScopeInterface;
    use Magento\SalesRule\Model\RuleFactory;
    use \Magento\Framework\Serialize\Serializer\Json;
    use \Magento\SalesRule\Model\Rule;

    class Data extends AbstractHelper
    {
        protected $scopeConfig;
        protected $_ruleFactory;
        protected $ruleModel;

        public function __construct(
            Context $context,
            ScopeConfigInterface $scopeInterface,
            RuleFactory $ruleFactory ,
            Rule  $ruleModel
        ) {
            parent::__construct($context);
            $this->scopeConfig = $scopeInterface;
            $this->_ruleFactory = $ruleFactory;
            $this->ruleModel=$ruleModel;
        }

        public function isModuleEnabled()
        {
            return  true;
        }

        public function getMinimumOrderAmount()
        {
            return true;
        }

        public function getExtrafee()
        {
            $amount = $this->getFinalRule();
            $amt = array();
            foreach ($amount as $key => $value) {
                $amt[] = $value['amount'];
            }
            $sum_of_amount = array_sum($amt);
            return $sum_of_amount;
        }

        public function getFeeLabel()
        {
            $name = $this->getFinalRule();
            $label = array();
            foreach ($name as $key => $value) {
                $label[] = $value['name'];
            }
            // $label = 'Special Discount';
            return $label;
        }

        public function getShippingPrices()
        {
            $data = $this->getFinalRule();
            $shippingData = array();
            foreach ($data as $key => $value) {
               $shippingData[$key] = [
                           'title' => $value['name'],
                           'value'=> $value['amount']
            ];
            }
            return $shippingData;
        }

        public function getFinalRule()
        {
            $activeRule = $this->getActiveRule();
            $result =array();
            $rule_info = array();
            foreach ($activeRule as $key => $rule) {

                $id                = $rule['rule_id'];
                $action            = $rule['simple_action'];
                $name              = $rule['description'];
                $discount_amount   = $rule['discount_amount'];
                $max_discount      =  $rule['max_discount'];
                $discount_qty      =  $rule['discount_qty'];
                $discount_step     = $rule['discount_step'];
                $priceselector     = $rule['priceselector'];
                $apply_discount_to = $rule['apply_discount_to'];
                //$apply_to_shipping = $rule['apply_to_shipping'];
                //$stop_rules_processing = $rule[' stop_rules_processing'];


                switch($action){
                    case "thecheapest":
                        $cartItem = $this->getCartItem();
                        $amt = array();
                        foreach ($cartItem as $key => $item) {
                            $qty = $item->getQty();
                            if($qty >= 2) {
                                if($priceselector == 0) {
                                    $price = $item->getProduct()->getFinalPrice();
                                } else if($priceselector == 2) {
                                    $price = $item->getProduct()->getPrice();
                                } else {
                                $price = $item->getProduct()->getFinalPrice();
                                }
                                if(($qty%2==0)) {
                                    $x_product = ($qty/2);
                                    $final_amt = ($price * $x_product);
                                    $amt[] = $final_amt;
                                } else {
                                    $x_odd = $qty - 1;
                                    $x_product = ($x_odd/2);
                                    $final_amt = (($price * $x_product));
                                    $amt[] = $final_amt;
                                }
                            }
                        } 

                        $amount = array_sum($amt);
                        $finalDiscount = -$amount;
                        $rule_info[]= [
                            'name' => $name,
                            'amount'=> $finalDiscount
                        ];
                    break;

                    case "moneyamount":
                        $cartTotal = $this->getCartTotal();
                        if($cartTotal >= $discount_step) {
                            $get_x = $cartTotal/$discount_step;
                            $lower_round_off = floor($get_x);
                            $final_amt = $lower_round_off * $discount_amount;
                        } else {
                            $final_amt =0;
                        }
                        $finalDiscount = -$final_amt;
                        $rule_info[] = [
                            'name' => $name,
                            'amount'=> $finalDiscount,
                        ];
                    break;
                } // end  of swich case
            } // end of for loop
            return $rule_info;
        }
    }

app/code/Bg/SpecialPromotion/Model/ExtrafeeConfigProvider.php

<?php
namespace Bg\SpecialPromotion\Model;

use Magento\Checkout\Model\ConfigProviderInterface;

class ExtrafeeConfigProvider implements ConfigProviderInterface
{
    /**
     * @var \Magecomp\Extrafee\Helper\Data
     */
    protected $dataHelper;

    /**
     * @var \Magento\Checkout\Model\Session
     */
    protected $checkoutSession;

    /**
     * @var \Psr\Log\LoggerInterface
     */
    protected $logger;

    /**
     * @param \Bg/SpecialPromotion\Helper\Data $dataHelper
     * @param \Magento\Checkout\Model\Session $checkoutSession
     * @param \Psr\Log\LoggerInterface $logger
     */
    public function __construct(
        \Bg\SpecialPromotion\Helper\Data $dataHelper,
        \Magento\Checkout\Model\Session $checkoutSession,
        \Psr\Log\LoggerInterface $logger
    ) {
        $this->dataHelper = $dataHelper;
        $this->checkoutSession = $checkoutSession;
        $this->logger = $logger;
    }

    /**
     * @return array
     */
    public function getConfig()
    {
        $ExtrafeeConfig = [];
        $enabled = $this->dataHelper->isModuleEnabled();
        $minimumOrderAmount = $this->dataHelper->getMinimumOrderAmount();
        $ExtrafeeConfig['fee_label'] = $this->dataHelper->getFeeLabel();
        $quote = $this->checkoutSession->getQuote();
        $subtotal = $quote->getSubtotal();
        $ExtrafeeConfig['custom_fee_amount'] = $this->dataHelper->getExtrafee();
        $ExtrafeeConfig['custom_shipping'] = $this->dataHelper->getShippingPrices();
        $ExtrafeeConfig['show_hide_Extrafee_block'] = ($enabled && ($minimumOrderAmount <= $subtotal) && $quote->getFee()) ? true : false;
        $ExtrafeeConfig['show_hide_Extrafee_shipblock'] = ($enabled && ($minimumOrderAmount <= $subtotal)) ? true : false;
        return $ExtrafeeConfig;
    }
}

app/code/Bg/SpecialPromotion/view/frontend/web/js/view/checkout/cart/total/fee.js

define([
    'ko',
    'uiComponent',
    'Magento_Checkout/js/model/quote',
    'Magento_Catalog/js/price-utils',
    'Magento_Checkout/js/model/totals'

], function (ko, Component, quote, priceUtils, totals) {
    'use strict';
        var show_hide_Extrafee_blockConfig = window.checkoutConfig.show_hide_Extrafee_block;
        var fee_label = window.checkoutConfig.fee_label;
        var custom_fee_amount = window.checkoutConfig.custom_fee_amount;
        var custom_shipping = window.checkoutConfig.custom_shipping;

        return Component.extend({

            totals: quote.getTotals(),
            canVisibleExtrafeeBlock: show_hide_Extrafee_blockConfig,
            getFormattedPrice: ko.observable(priceUtils.formatPrice(custom_fee_amount, quote.getPriceFormat())),
            getFeeLabel:ko.observable(fee_label),

            isDisplayed: function () {
                return this.getValue() != 0;
            },
            getValue: function() {
                var price = 0;
                if (this.totals() && totals.getSegment('fee')) {
                    price = totals.getSegment('fee').value;
                }
                return price;
            },
            rawHtml: function() {
               var $html = '';
                _.each(custom_shipping, function (item) {
                $html += '<tr class="totals fee excl" >';
                $html += '<th class="mark" colspan="1" scope="row">'+item.title+'</th>';
                $html += '<td class="amount">';
                $html += '<span class="price">'+priceUtils.formatPrice(item.value)+'</span>';
                $html += '</td>';
                $html += '</tr>';
            });
            return $html;
        }
    });
});

app/code/Bg/SpecialPromotion/view/frontend/template/checkout/cart/total/fee.html

<!-- ko if: isDisplayed() -->
    <tr data-bind="html: rawHtml()"></tr>
<!-- /ko -->

Have tested in my local env, try to code like Magento zendframework format. Your code is not aligned properly. And add comments before every function like ExtrafeeConfigProvider.php file. Happy coding :-)

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.