Solved

Magento 2 Apply discount from checkout second page

Posted on 2016-09-12
4
102 Views
Last Modified: 2016-09-13
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

0
Comment
Question by:jwleys
  • 4
4 Comments
 

Author Comment

by:jwleys
ID: 41796983
0
 

Author Comment

by:jwleys
ID: 41797066
Ignore the link above it is for M1 and isn't useful in this scenario
0
 

Accepted Solution

by:
jwleys earned 0 total points
ID: 41797283
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
 

Author Closing Comment

by:jwleys
ID: 41797342
Resolved by question writer
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Author Note: Since this E-E article was originally written, years ago, formal testing has come into common use in the world of PHP.  PHPUnit (http://en.wikipedia.org/wiki/PHPUnit) and similar technologies have enjoyed wide adoption, making it possib…
SSL stands for “Secure Sockets Layer” and an SSL certificate is a critical component to keeping your website safe, secured, and compliant. Any ecommerce website must have an SSL certificate to ensure the safe handling of sensitive information like…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
The viewer will learn how to dynamically set the form action using jQuery.

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now