/** * Cancels order coupons usage when order is canceled or refunded, * or use canceled coupons again if the order is no longer canceled or refunded * * @param OrderEvent $event * @param string $eventName * @param EventDispatcherInterface $dispatcher * @throws \Exception * @throws \Propel\Runtime\Exception\PropelException */ public function orderStatusChange(OrderEvent $event, $eventName, EventDispatcherInterface $dispatcher) { // The order has been canceled or refunded ? if ($event->getOrder()->isCancelled() || $event->getOrder()->isRefunded()) { // Cancel usage of all coupons for this order $usedCoupons = OrderCouponQuery::create()->filterByUsageCanceled(false)->findByOrderId($event->getOrder()->getId()); $customerId = $event->getOrder()->getCustomerId(); /** @var OrderCoupon $usedCoupon */ foreach ($usedCoupons as $usedCoupon) { if (null !== ($couponModel = CouponQuery::create()->findOneByCode($usedCoupon->getCode()))) { // If the coupon still exists, restore one usage to the usage count. $this->couponManager->incrementQuantity($couponModel, $customerId); } // Mark coupon usage as canceled in the OrderCoupon table $usedCoupon->setUsageCanceled(true)->save(); } } else { // Mark canceled coupons for this order as used again $usedCoupons = OrderCouponQuery::create()->filterByUsageCanceled(true)->findByOrderId($event->getOrder()->getId()); $customerId = $event->getOrder()->getCustomerId(); /** @var OrderCoupon $usedCoupon */ foreach ($usedCoupons as $usedCoupon) { if (null !== ($couponModel = CouponQuery::create()->findOneByCode($usedCoupon->getCode()))) { // If the coupon still exists, mark the coupon as used $this->couponManager->decrementQuantity($couponModel, $customerId); } // The coupon is no longer canceled $usedCoupon->setUsageCanceled(false)->save(); } } }
/** * @param \Thelia\Core\Event\Order\OrderEvent $event * * @throws \Exception if something goes wrong. * @param $eventName * @param EventDispatcherInterface $dispatcher */ public function afterOrder(OrderEvent $event, $eventName, EventDispatcherInterface $dispatcher) { /** @var CouponInterface[] $consumedCoupons */ $consumedCoupons = $this->couponManager->getCouponsKept(); if (is_array($consumedCoupons) && count($consumedCoupons) > 0) { $con = Propel::getWriteConnection(OrderCouponTableMap::DATABASE_NAME); $con->beginTransaction(); try { foreach ($consumedCoupons as $couponCode) { $couponQuery = CouponQuery::create(); $couponModel = $couponQuery->findOneByCode($couponCode->getCode()); $couponModel->setLocale($this->getSession()->getLang()->getLocale()); /* decrease coupon quantity */ $this->couponManager->decrementQuantity($couponModel, $event->getOrder()->getCustomerId()); /* memorize coupon */ $orderCoupon = new OrderCoupon(); $orderCoupon->setOrder($event->getOrder())->setCode($couponModel->getCode())->setType($couponModel->getType())->setAmount($couponModel->getAmount())->setTitle($couponModel->getTitle())->setShortDescription($couponModel->getShortDescription())->setDescription($couponModel->getDescription())->setExpirationDate($couponModel->getExpirationDate())->setIsCumulative($couponModel->getIsCumulative())->setIsRemovingPostage($couponModel->getIsRemovingPostage())->setIsAvailableOnSpecialOffers($couponModel->getIsAvailableOnSpecialOffers())->setSerializedConditions($couponModel->getSerializedConditions())->setPerCustomerUsageCount($couponModel->getPerCustomerUsageCount()); $orderCoupon->save(); // Copy order coupon free shipping data for countries and modules $couponCountries = CouponCountryQuery::create()->filterByCouponId($couponModel->getId())->find(); /** @var CouponCountry $couponCountry */ foreach ($couponCountries as $couponCountry) { $occ = new OrderCouponCountry(); $occ->setCouponId($orderCoupon->getId())->setCountryId($couponCountry->getCountryId())->save(); } $couponModules = CouponModuleQuery::create()->filterByCouponId($couponModel->getId())->find(); /** @var CouponModule $couponModule */ foreach ($couponModules as $couponModule) { $ocm = new OrderCouponModule(); $ocm->setCouponId($orderCoupon->getId())->setModuleId($couponModule->getModuleId())->save(); } } $con->commit(); } catch (\Exception $ex) { $con->rollBack(); throw $ex; } } // Clear all coupons. $dispatcher->dispatch(TheliaEvents::COUPON_CLEAR_ALL); }
/** * @covers Thelia\Coupon\CouponManager::decrementQuantity */ public function testDecrementeQuantityIllimited() { $stubFacade = $this->generateFacadeStub(); $stubContainer = $this->getMock('\\Symfony\\Component\\DependencyInjection\\Container'); $coupon = new RemoveXAmount($stubFacade); $date = new \DateTime(); $coupon->set($stubFacade, 'XMAS', '', '', '', array('amount' => 21.0), true, true, true, true, 254, $date->setTimestamp(strtotime("today + 3 months")), new ObjectCollection(), new ObjectCollection(), false); $condition1 = new MatchForTotalAmount($stubFacade); $operators = array(MatchForTotalAmount::CART_TOTAL => Operators::SUPERIOR, MatchForTotalAmount::CART_CURRENCY => Operators::EQUAL); $values = array(MatchForTotalAmount::CART_TOTAL => 40.0, MatchForTotalAmount::CART_CURRENCY => 'EUR'); $condition1->setValidatorsFromForm($operators, $values); $condition2 = new MatchForTotalAmount($stubFacade); $operators = array(MatchForTotalAmount::CART_TOTAL => Operators::INFERIOR, MatchForTotalAmount::CART_CURRENCY => Operators::EQUAL); $values = array(MatchForTotalAmount::CART_TOTAL => 400.0, MatchForTotalAmount::CART_CURRENCY => 'EUR'); $condition2->setValidatorsFromForm($operators, $values); $conditions = new ConditionCollection(); $conditions[] = $condition1; $conditions[] = $condition2; $coupon->setConditions($conditions); $stubFacade->expects($this->any())->method('getCurrentCoupons')->will($this->returnValue(array($coupon))); $stubContainer->expects($this->any())->method('get')->will($this->onConsecutiveCalls($stubFacade)); $couponManager = new CouponManager($stubContainer); $stubModel = $this->getMockBuilder('\\Thelia\\Model\\Coupon')->disableOriginalConstructor()->getMock(); $stubModel->expects($this->any())->method('getMaxUsage')->will($this->returnValue(-1)); $stubModel->expects($this->any())->method('setMaxUsage')->will($this->returnValue(true)); $actual = $couponManager->decrementQuantity($stubModel, null); $expected = false; $this->assertEquals($expected, $actual); }