diff --git a/Helper/Cart.php b/Helper/Cart.php
new file mode 100644
index 0000000..d407e90
--- /dev/null
+++ b/Helper/Cart.php
@@ -0,0 +1,70 @@
+quoteRepository = $quoteRepository;
+ $this->messageManager = $messageManager;
+ }
+
+ /************************************************************************/
+
+ public function applyCoupon(\Magento\Quote\Model\Quote $quote, string $coupon): void {
+
+ try {
+ $quote->setCouponCode($coupon);
+ $this->quoteRepository->save($quote->collectTotals());
+ }
+
+ catch (LocalizedException $e) {
+ $this->messageManager->addError(
+ __("Discount code $coupon couldn't be applied: " .
+ $e->getMessage())
+ );
+ }
+
+ catch (\Exception $e) {
+ $this->messageManager->addError(
+ __("Discount code $coupon couldn't be applied or is invalid")
+ );
+ }
+
+ if ($quote->getCouponCode() != $coupon) {
+ $this->messageManager->addError(
+ __("Discount code $coupon is invalid. Verify that it's correct and try again.")
+ );
+ }
+ }
+}
+
diff --git a/Observer/Discountcodeurl/CheckoutCartSaveAfter.php b/Observer/Discountcodeurl/CheckoutCartSaveAfter.php
index ad96715..ff7ee5b 100644
--- a/Observer/Discountcodeurl/CheckoutCartSaveAfter.php
+++ b/Observer/Discountcodeurl/CheckoutCartSaveAfter.php
@@ -17,45 +17,41 @@ class CheckoutCartSaveAfter implements \Magento\Framework\Event\ObserverInterfac
*/
private $config;
- /**
- * @var \Magento\Quote\Api\CartRepositoryInterface
- */
- private $quoteRepository;
-
/**
* @var \Crankycyclops\DiscountCodeUrl\Helper\Cookie
*/
private $cookieHelper;
/**
- * @var \Magento\Framework\Message\ManagerInterface
+ * @var \Crankycyclops\DiscountCodeUrl\Helper\Cart
*/
- private $messageManager;
+ private $cartHelper;
/************************************************************************/
/**
* Constructor
*
+ * @param \Crankycyclops\DiscountCodeUrl\Helper\Config $config
* @param \Crankycyclops\DiscountCodeUrl\Helper\Cookie $cookieHelper
+ * @param \Crankycyclops\DiscountCodeUrl\Helper\Cart $cartHelper
*/
public function __construct(
\Crankycyclops\DiscountCodeUrl\Helper\Config $config,
- \Magento\Quote\Api\CartRepositoryInterface $quoteRepository,
\Crankycyclops\DiscountCodeUrl\Helper\Cookie $cookieHelper,
- \Magento\Framework\Message\ManagerInterface $messageManager
+ \Crankycyclops\DiscountCodeUrl\Helper\Cart $cartHelper
) {
$this->config = $config;
- $this->quoteRepository = $quoteRepository;
$this->cookieHelper = $cookieHelper;
- $this->messageManager = $messageManager;
+ $this->cartHelper = $cartHelper;
}
/************************************************************************/
/**
* If a coupon code was set in the URL at any point during the session,
- * apply it as soon as the cart is created.
+ * apply it as soon as the cart is created and re-apply it every time it's
+ * updated to keep the total price current.
*
* @param \Magento\Framework\Event\Observer $observer
*
@@ -72,30 +68,7 @@ public function execute(\Magento\Framework\Event\Observer $observer): void {
$cart = $observer->getData('cart');
if ($cart) {
-
- try {
- $cart->getQuote()->setCouponCode($coupon);
- $this->quoteRepository->save($cart->getQuote()->collectTotals());
- }
-
- catch (LocalizedException $e) {
- $this->messageManager->addError(
- __("Discount code $coupon couldn't be applied: " .
- $e->getMessage())
- );
- }
-
- catch (\Exception $e) {
- $this->messageManager->addError(
- __("Discount code $coupon couldn't be applied or is invalid")
- );
- }
-
- if ($cart->getQuote()->getCouponCode() != $coupon) {
- $this->messageManager->addError(
- __("Discount code $coupon is invalid. Verify that it's correct and try again.")
- );
- }
+ $this->cartHelper->applyCoupon($cart->getQuote(), $coupon);
}
}
}
diff --git a/Plugin/Framework/App/FrontControllerInterface.php b/Plugin/Framework/App/FrontControllerInterface.php
index dd2eaca..b334807 100644
--- a/Plugin/Framework/App/FrontControllerInterface.php
+++ b/Plugin/Framework/App/FrontControllerInterface.php
@@ -27,6 +27,11 @@ class FrontControllerInterface {
*/
private $cookieHelper;
+ /**
+ * @var \Crankycyclops\DiscountCodeUrl\Helper\Cart
+ */
+ private $cartHelper;
+
/**
* @var \Magento\SalesRule\Model\Coupon
*/
@@ -42,6 +47,11 @@ class FrontControllerInterface {
*/
private $registry;
+ /**
+ * @var \Magento\Checkout\Model\Session
+ */
+ private $checkoutSession;
+
/************************************************************************/
/**
@@ -50,24 +60,30 @@ class FrontControllerInterface {
* @param \Magento\Framework\App\RequestInterface $request
* @param \Crankycyclops\DiscountCodeUrl\Helper\Config $config
* @param \Crankycyclops\DiscountCodeUrl\Helper\Cookie $cookieHelper
+ * @param \Crankycyclops\DiscountCodeUrl\Helper\Cart $cartHelper
* @param \Magento\SalesRule\Model\Coupon $couponModel
* @param \Magento\SalesRule\Model\Rule $ruleModel
* @param \Magento\Framework\Registry $registry
+ * @param \Magento\Checkout\Model\Session $checkoutSession
*/
public function __construct(
\Magento\Framework\App\RequestInterface $request,
\Crankycyclops\DiscountCodeUrl\Helper\Config $config,
\Crankycyclops\DiscountCodeUrl\Helper\Cookie $cookieHelper,
+ \Crankycyclops\DiscountCodeUrl\Helper\Cart $cartHelper,
\Magento\SalesRule\Model\Coupon $couponModel,
\Magento\SalesRule\Model\Rule $ruleModel,
- \Magento\Framework\Registry $registry
+ \Magento\Framework\Registry $registry,
+ \Magento\Checkout\Model\Session $checkoutSession
) {
$this->request = $request;
$this->config = $config;
$this->cookieHelper = $cookieHelper;
+ $this->cartHelper = $cartHelper;
$this->couponModel = $couponModel;
$this->ruleModel = $ruleModel;
$this->registry = $registry;
+ $this->checkoutSession = $checkoutSession;
}
/************************************************************************/
@@ -216,5 +232,41 @@ public function beforeDispatch(\Magento\Framework\App\FrontControllerInterface $
}
}
}
+
+ /************************************************************************/
+
+ /**
+ * If a quote already exists, we need to apply the discount code to it
+ * automatically (if possible) and before the response is rendered. This
+ * covers us in the case that a user applies a discount code to the URL
+ * after having a cart that's already full (which means the save cart
+ * observer won't execute and therefore won't update the quote's price.) I
+ * can't do this in beforeDispatch, because based on my own testing, it
+ * seems that the session classes don't get populated until after
+ * FrontController::dispatch() finishes.
+ *
+ * @param \Magento\Framework\App\FrontControllerInterface $subject (not used)
+ * @param ResponseInterface|ResultInterface Return value of FrontController::dispatch()
+ *
+ * @return ResponseInterface|ResultInterface
+ */
+ public function afterDispatch(\Magento\Framework\App\FrontControllerInterface $subject, $result) {
+
+ if ($this->config->isEnabled()) {
+
+ // If a quote already exists, apply the
+ // discount automatically (if possible)
+ $coupon = $this->registry->registry('crankycyclops_discounturl_coupon');
+
+ if ($coupon && $this->checkoutSession->hasQuote()) {
+ $this->cartHelper->applyCoupon(
+ $this->checkoutSession->getQuote(),
+ $coupon
+ );
+ }
+ }
+
+ return $result;
+ }
}