/** * Check if this coupon can be applied when other coupons had previously * been applied. * * @param CartInterface $cart Cart * @param CouponInterface $coupon Coupon * * @throws CouponNotStackableException Coupon is not stackable */ public function validateStackableCoupon(CartInterface $cart, CouponInterface $coupon) { $cartCoupons = $this->cartCouponRepository->findBy(['cart' => $cart]); /** * If there are no previously applied coupons we can skip the check. */ if (0 == count($cartCoupons)) { return; } $appliedCouponsCanBeStacked = array_reduce($cartCoupons, function ($previousCouponsAreStackable, CartCouponInterface $cartCoupon) { return $previousCouponsAreStackable && $cartCoupon->getCoupon()->getStackable(); }, true); /** * Checked coupon can be stackable and everything that was * previously applied is also stackable. */ if ($coupon->getStackable() && $appliedCouponsCanBeStacked) { return; } throw new CouponNotStackableException(); }