Magento 2 Apply discount from checkout second page

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 go to payment express, it shows the discounted amount.

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

I took reference from to apply discount

From what I can see the value is updated in the modal just not on the view on the site bar, a point in the right direction would be great.

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>

Open in new window


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;
   }
}

Open in new window

Jeremy LeysTechnical LeadAsked:
Who is Participating?
 
Jeremy LeysConnect With a Mentor Technical LeadAuthor Commented:
I got the solution,

Actually the methodology that i followed works perfect for cart page Model file
[Namespace]/[ModuleName]/Model/Total/Quote/Custom.php

Open in new window

is not called on checkout process, On checkout need to follow the default magento mechnaism 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>

Open in new window


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


<?php

namespace Namespace]\[ModuleName]\Api;

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

Open in new window


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;
    }

Open in new window


   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;
    }

Open in new window


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

  storage.post(
        urlBuilder.createUrl('/modulename/mine/use-reward', {}), {}
    )

Open in new window

0
 
Jeremy LeysTechnical LeadAuthor Commented:
0
 
Jeremy LeysTechnical LeadAuthor Commented:
Ignore the link above it is for M1 and isn't useful in this scenario
0
 
Jeremy LeysTechnical LeadAuthor Commented:
Resolved by question writer
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.