Question

I am using Magento 2 enterprise edition (2.0.6)

I want to apply discount on sub total, Discount is applied from cart page (added a button on cart which applies the discount) and then if I go to checkout discount is visible there.

Now I am trying to add button on checkout second page to apply discount. The discount is applied but the order summary is not updated. If I click on button (checkout page) and goto payment express, it shows the discounted amount.

even if i goto cart page after applying discount on checkout it is visible on cart and then visible on checkout also.

I took reference from how to add fee to order totals in magento2 to apply discount

Below is my code

[Namespace]/[ModuleName]/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="custom" instance="[Namespace]\[ModuleName]\Model\Total\Quote\Custom" sort_order="420">
      </item>
    </group>
  </section>
</config>

I created Model under [Namespace]/[ModuleName]/Model/Total/Quote/Custom.php

namespace [Namespace]\[ModuleName]\Model\Total\Quote;  

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

   protected $_priceCurrency;

   public function __construct(
       \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
       \Magento\Checkout\Model\Session                     $checkoutSession,
       \[Namespace]/[ModuleName]\Helper\Data $helper
   ){
       $this->_priceCurrency = $priceCurrency;
       $this->checkoutSession             = $checkoutSession;
       $this->helper = $helper;
   }
   public function getDiscountAmount()
    {
        return $this->helper->getDiscountAmount();
    }
   /**
    * @param \Magento\Quote\Model\Quote $quote
    * @param \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment
    * @param \Magento\Quote\Model\Quote\Address\Total $total
    * @return $this|bool
    */
   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);
      $address             = $shippingAssignment->getShipping()->getAddress();
      $label               = 'My Custom Discount';
      $discountAmount      = -self::getDiscountAmount();   
      $appliedCartDiscount = 0;
      if ($address->getAddressType() == 'shipping') 
      { 
          if($total->getDiscountDescription()) 
          {
            // If a discount exists in cart and another discount is applied, the add both discounts.
            $appliedCartDiscount = $total->getDiscountAmount();
            $discountAmount      = $total->getDiscountAmount()+$discountAmount;
            $label               = $total->getDiscountDescription().', '.$label;
          }    

          $total->setDiscountDescription($label);
          $total->setDiscountAmount($discountAmount);
          $total->setBaseDiscountAmount($discountAmount);
          $total->setSubtotalWithDiscount($total->getSubtotal() + $discountAmount);
          $total->setBaseSubtotalWithDiscount($total->getBaseSubtotal() + $discountAmount);

          if(isset($appliedCartDiscount)) 
          {
            $total->addTotalAmount($this->getCode(), $discountAmount - $appliedCartDiscount);
            $total->addBaseTotalAmount($this->getCode(), $discountAmount - $appliedCartDiscount);
          } 
          else 
          {
            $total->addTotalAmount($this->getCode(), $discountAmount);
            $total->addBaseTotalAmount($this->getCode(), $discountAmount);
          }
      }
      return $this;
   }
}
Was it helpful?

Solution

I got the solution,

below is the explanation of process to approach the result. Please modify accordingly.

Actually the methodology that i followed works perfect for cart page Model file [Namespace]/[ModuleName]/Model/Total/Quote/Custom.php is not called on checkout process, On checkout need to follow the default Magento mechanism using webapi.xml

I followed the process of reward module in enterprise edition

[Namespace]/[ModuleName]/etc/webapi.xml

<?xml version="1.0"?>
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">
    <route url="/V1/rewardpoints/mine/use-reward" method="POST">
        <service class="[Namespace]\[ModuleName]\Api\RewardManagementInterface" method="set"/>
        <resources>
            <resource ref="self" />
        </resources>
        <data>
            <parameter name="cartId" force="true">%cart_id%</parameter>
        </data>
    </route>
</routes>

[Namespace]/[ModuleName]/Api/RewardManagementInterface.php

<?php

namespace Namespace]\[ModuleName]\Api;

interface RewardManagementInterface
{
    public function set($cartId);
}

create model to extend this interface and have the functionality in the function set($cartId)

as below

public function __construct(
        \Magento\Quote\Api\CartRepositoryInterface $quoteRepository,
        \[Namespace]\[ModuleName]\Helper\Data $helper,
        \[Namespace]\[ModuleName]\Model\PaymentDataImporter $importer
    ) {
        $this->quoteRepository = $quoteRepository;
        $this->helper = $helper;
        $this->importer = $importer;
    }

    /**
     * {@inheritdoc}
     */
    public function set($cartId)
    {
        if ($this->helper->getEnabled()) 
        {
            /* @var $quote \Magento\Quote\Model\Quote */
            $quote = $this->quoteRepository->getActive($cartId);
            $this->importer->import($quote, $quote->getPayment(), true);
            $quote->collectTotals();
            $this->quoteRepository->save($quote);
            return true;
        }
        return false;
    }

create another model PaymentDataImporter which will actually apply discount on checkout process

public function __construct(
        \[Namespace]\[ModuleName]\Helper\Data $helper,
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
    ) {
        $this->_scopeConfig = $scopeConfig;
        $this->helper = $helper;

    }

    public function import($quote, $payment, $useRewardPoints)
    {
        $discount = $this->helper->getDiscountAmount();
        $quote->getBaseGrandTotal()-$discount;
        return $this;
    }

most important your js action should give call to this webapi stuff

storage.post(
        urlBuilder.createUrl('/modulename/mine/use-reward', {}), {}
    )
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top