3

Looking at events.xml of Magento_SalesRule there are two events,

<event name="sales_order_place_after">
    <observer name="salesrule" instance="Magento\SalesRule\Observer\SalesOrderAfterPlaceObserver" />
</event>
<event name="sales_model_service_quote_submit_before">
    <observer name="salesrule" instance="Magento\SalesRule\Observer\AddSalesRuleNameToOrderObserver" />
</event>

but none looks like the one i need. I needed the same for when adding a coupon but i managed to do something if "pluggin in" the canProcessRule method of Magento\SalesRule\Model\Utility but i cant find something similar for when the coupon is removed

Theese operations like add and remove a coupon are made only in JS? There is a controller that process this?

Looking at checkout_index_index.xml layout it pass an item argument Magento_SalesRule/js/view/payment/discount which then loads theese two js

Magento_SalesRule/js/action/set-coupon-code Magento_SalesRule/js/action/cancel-coupon

That by the name itself looks pretty straightforward, one to add and one to remove the coupon

In the cancel-coupon JS doing a console.log to url return:

rest/default/V1/guest-carts/21229ffad7bf01311b645a4423a4ae22/coupons

This is using rest web services? (Kind of same url for when adding a coupon)

There is a way to know when a coupon is removed from the quote/cart?

8

Yes there is.

The event you're looking for is controller_action_predispatch_checkout_cart_couponPost

This is generic event that is dispatched before the action class that adds/removes the coupon is called.

As this is the same event for both add and remove you can add the following code at the top of your observer method to check if this is a remove action:

$controller = $observer->getControllerAction();
$remove = $controller->getRequest()->getParam('remove');

if ($remove) {
    // This is a remove action
} else {
    // This is an add action
    $coupon = $controller->getRequest()->getParam('coupon_code');
}

However, when you add a coupon from the checkout flow it won't work as it directly calls the API and there are no events in Magento 2 web APIs

The solution is to use a plugin on Magento\Quote\Model\CouponManagement on the set method:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Quote\Model\CouponManagement">
        <plugin name="checkout_coupon_apply"
                type="Vendor\Module\Plugin\CheckoutCouponApply"/>
    </type>
</config>

Then your plugin class:

<?php 

namespace Vendor\Module\Plugin;

use Magento\Quote\Model\CouponManagement;

class CheckoutCouponApply {

    public function beforeSet(CouponManagement $subject, $cartId, $couponCode)
    {
         // Do what you need to do
    }
}
3
  • I just noticed that this event applies only for the add/remove coupon when in checkout/cart and not when adding/removing the coupon in the checkout flow, so there is a way to know when the coupon is removed from the cart when in the checkout flow? (This event still great help because i have to do something in that case and not only when adding/removing coupon in checkout flow) Jun 29 '16 at 8:03
  • @GianniDiFalco see my update Jun 29 '16 at 8:42
  • @RaphaelatDigitalPianism, plugin is not firing for me. is this worked for you? Apr 7 at 14:09
4

The coupon code is attached or removed from the quote in this action \Magento\Checkout\Controller\Cart\CouponPost::execute().

The code

$couponCode = $this->getRequest()->getParam('remove') == 1
        ? ''
        : trim($this->getRequest()->getParam('coupon_code'));

determines if the coupon should be added or removed.
If $this->getRequest()->getParam('remove') == 1 it's easy. It means the coupon should be removed.
But if you are try to add a coupon code is more complicated than that. The code may not be valid and it does not get attached to the quote.
I'm not sure about this, but maybe you can try to add a plugin for aroundSave method from the method \Magento\Quote\Api\CartRepositoryInterface::save.
This is the one that saves the quote.
Check the value of the coupon code before the save with $quote->getOrigData('coupon_code') and compare it after the save is done with $quote->getCouponCode() to see if the coupon was applied.

1
  • 1
    I just noticed that this applies only for the add/remove coupon when in checkout/cart and not when adding/removing the coupon in the checkout flow, so there is a way to know when the coupon is removed from the cart when in the checkout flow? (This is still great help because i have to do something in that case and not only when adding/removing coupon in checkout flow) Jun 29 '16 at 8:03

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.