coupon management in order and cart process

This commit is contained in:
Etienne Roudeix
2013-12-19 14:17:22 +01:00
parent c981102d3a
commit d7c1ecf09a
8 changed files with 124 additions and 28 deletions

View File

@@ -28,6 +28,7 @@ use Thelia\Condition\ConditionFactory;
use Thelia\Condition\Implementation\ConditionInterface;
use Thelia\Core\Event\Coupon\CouponConsumeEvent;
use Thelia\Core\Event\Coupon\CouponCreateOrUpdateEvent;
use Thelia\Core\Event\Order\OrderEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\HttpFoundation\Request;
use Thelia\Coupon\CouponFactory;
@@ -122,13 +123,6 @@ class Coupon extends BaseAction implements EventSubscriberInterface
$request->getSession()->setConsumedCoupons($consumedCoupons);
$totalDiscount = $couponManager->getDiscount();
// @todo insert false product in cart with the name of the coupon and the discount as negative price
// Decrement coupon quantity
// @todo move this part in after order event
$couponQuery = CouponQuery::create();
$couponModel = $couponQuery->findOneByCode($coupon->getCode());
$couponManager->decrementQuantity($couponModel);
$request
->getSession()
@@ -206,6 +200,47 @@ class Coupon extends BaseAction implements EventSubscriberInterface
$event->setCouponModel($coupon);
}
/**
* @param \Thelia\Core\Event\Order\OrderEvent $event
*/
public function testFreePostage(OrderEvent $event)
{
/** @var CouponManager $couponManager */
$couponManager = $this->container->get('thelia.coupon.manager');
if($couponManager->isCouponRemovingPostage()) {
$order = $event->getOrder();
$order->setPostage(0);
$event->setOrder($order);
$event->stopPropagation();
}
}
/**
* @param \Thelia\Core\Event\Order\OrderEvent $event
*/
public function decreaseCouponQuantity(OrderEvent $event)
{
$request = $this->container->get('request');
/** @var CouponManager $couponManager */
$couponManager = $this->container->get('thelia.coupon.manager');
$consumedCoupons = $request->getSession()->getConsumedCoupons();
if (is_array($consumedCoupons)) {
foreach($consumedCoupons as $couponCode) {
// Decrement coupon quantity
$couponQuery = CouponQuery::create();
$couponModel = $couponQuery->findOneByCode($couponCode);
$couponManager->decrementQuantity($couponModel);
}
}
}
/**
* Returns an array of event names this subscriber listens to.
*
@@ -232,7 +267,9 @@ class Coupon extends BaseAction implements EventSubscriberInterface
TheliaEvents::COUPON_CREATE => array("create", 128),
TheliaEvents::COUPON_UPDATE => array("update", 128),
TheliaEvents::COUPON_CONSUME => array("consume", 128),
TheliaEvents::COUPON_CONDITION_UPDATE => array("updateCondition", 128)
TheliaEvents::COUPON_CONDITION_UPDATE => array("updateCondition", 128),
TheliaEvents::ORDER_SET_POSTAGE => array("testFreePostage", 256),
TheliaEvents::ORDER_BEFORE_PAYMENT => array("decreaseCouponQuantity", 128),
);
}
}

View File

@@ -72,7 +72,18 @@ class Order extends BaseAction implements EventSubscriberInterface
{
$order = $event->getOrder();
$order->setDeliveryModuleId($event->getDeliveryModule());
$order->setPostage($event->getPostage());
$event->setOrder($order);
}
/**
* @param \Thelia\Core\Event\Order\OrderEvent $event
*/
public function setPostage(OrderEvent $event)
{
$order = $event->getOrder();
$order->setPostage($event->getPostage());
$event->setOrder($order);
@@ -178,6 +189,8 @@ class Order extends BaseAction implements EventSubscriberInterface
OrderStatusQuery::create()->findOneByCode(OrderStatus::CODE_NOT_PAID)->getId()
);
/* refresh discount @todo */
/* memorize discount */
$placedOrder->setDiscount(
$cart->getDiscount()
@@ -267,10 +280,7 @@ class Order extends BaseAction implements EventSubscriberInterface
}
}
/* discount @todo */
/* refresh discount */
/* memorize coupons */
/* memorize coupons @todo */
$con->commit();
@@ -420,6 +430,7 @@ class Order extends BaseAction implements EventSubscriberInterface
return array(
TheliaEvents::ORDER_SET_DELIVERY_ADDRESS => array("setDeliveryAddress", 128),
TheliaEvents::ORDER_SET_DELIVERY_MODULE => array("setDeliveryModule", 128),
TheliaEvents::ORDER_SET_POSTAGE => array("setPostage", 128),
TheliaEvents::ORDER_SET_INVOICE_ADDRESS => array("setInvoiceAddress", 128),
TheliaEvents::ORDER_SET_PAYMENT_MODULE => array("setPaymentModule", 128),
TheliaEvents::ORDER_PAY => array("create", 128),

View File

@@ -370,6 +370,7 @@ final class TheliaEvents
*/
const ORDER_SET_DELIVERY_ADDRESS = "action.order.setDeliveryAddress";
const ORDER_SET_DELIVERY_MODULE = "action.order.setDeliveryModule";
const ORDER_SET_POSTAGE = "action.order.setPostage";
const ORDER_SET_INVOICE_ADDRESS = "action.order.setInvoiceAddress";
const ORDER_SET_PAYMENT_MODULE = "action.order.setPaymentModule";
const ORDER_PAY = "action.order.pay";

View File

@@ -82,15 +82,8 @@ class CouponManager
if (count($this->coupons) > 0) {
$couponsKept = $this->sortCoupons($this->coupons);
$isRemovingPostage = $this->isCouponRemovingPostage($couponsKept);
$discount = $this->getEffect($couponsKept);
if ($isRemovingPostage) {
$postage = $this->facade->getCheckoutPostagePrice();
$discount += $postage;
}
// Just In Case test
$checkoutTotalPrice = $this->facade->getCartTotalPrice();
if ($discount >= $checkoutTotalPrice) {
@@ -103,23 +96,24 @@ class CouponManager
/**
* Check if there is a Coupon removing Postage
*
* @param array $couponsKept Array of CouponInterface sorted
*
* @return bool
*/
protected function isCouponRemovingPostage(array $couponsKept)
public function isCouponRemovingPostage()
{
$isRemovingPostage = false;
if (count($this->coupons) == 0) {
return false;
}
$couponsKept = $this->sortCoupons($this->coupons);
/** @var CouponInterface $coupon */
foreach ($couponsKept as $coupon) {
if ($coupon->isRemovingPostage()) {
$isRemovingPostage = true;
return true;
}
}
return $isRemovingPostage;
return false;
}
/**

View File

@@ -24,11 +24,13 @@ namespace Front\Controller;
use Propel\Runtime\Exception\PropelException;
use Thelia\Controller\Front\BaseFrontController;
use Thelia\Core\Event\Order\OrderEvent;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Core\Event\Cart\CartEvent;
use Thelia\Core\Event\TheliaEvents;
use Symfony\Component\HttpFoundation\Request;
use Thelia\Form\CartAdd;
use Thelia\Model\AddressQuery;
class CartController extends BaseFrontController
{
@@ -53,6 +55,8 @@ class CartController extends BaseFrontController
$this->getDispatcher()->dispatch(TheliaEvents::CART_ADDITEM, $cartEvent);
$this->afterModifyCart();
$this->redirectSuccess();
} catch (PropelException $e) {
@@ -83,6 +87,8 @@ class CartController extends BaseFrontController
try {
$this->dispatch(TheliaEvents::CART_UPDATEITEM, $cartEvent);
$this->afterModifyCart();
$this->redirectSuccess();
} catch (PropelException $e) {
$this->getParserContext()->setGeneralError($e->getMessage());
@@ -98,6 +104,8 @@ class CartController extends BaseFrontController
try {
$this->getDispatcher()->dispatch(TheliaEvents::CART_DELETEITEM, $cartEvent);
$this->afterModifyCart();
$this->redirectSuccess();
} catch (PropelException $e) {
\Thelia\Log\Tlog::getInstance()->error(sprintf("error during deleting cartItem with message : %s", $e->getMessage()));
@@ -142,4 +150,25 @@ class CartController extends BaseFrontController
return $cartAdd;
}
protected function afterModifyCart()
{
/* recalculate postage amount */
$order = $this->getSession()->getOrder();
if(null !== $order) {
$deliveryModule = $order->getModuleRelatedByDeliveryModuleId();
$deliveryAddress = AddressQuery::create()->findPk($order->chosenDeliveryAddress);
if(null !== $deliveryModule && null !== $deliveryAddress) {
$moduleInstance = $this->container->get(sprintf('module.%s', $deliveryModule->getCode()));
$postage = $moduleInstance->getPostage($deliveryAddress->getCountry());
$orderEvent = new OrderEvent($order);
$orderEvent->setPostage($postage);
$this->getDispatcher()->dispatch(TheliaEvents::ORDER_SET_POSTAGE, $orderEvent);
}
}
}
}

View File

@@ -25,11 +25,12 @@ namespace Front\Controller;
use Propel\Runtime\Exception\PropelException;
use Thelia\Controller\Front\BaseFrontController;
use Thelia\Core\Event\Coupon\CouponConsumeEvent;
use Thelia\Core\Event\Order\OrderEvent;
use Thelia\Form\CouponCode;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Log\Tlog;
use Thelia\Model\Order;
use Thelia\Model\AddressQuery;
/**
* Class CouponController
@@ -65,6 +66,25 @@ class CouponController extends BaseFrontController
// Dispatch Event to the Action
$this->getDispatcher()->dispatch(TheliaEvents::COUPON_CONSUME, $couponConsumeEvent);
/* recalculate postage amount */
$order = $this->getSession()->getOrder();
if(null !== $order) {
$deliveryModule = $order->getModuleRelatedByDeliveryModuleId();
$deliveryAddress = AddressQuery::create()->findPk($order->chosenDeliveryAddress);
if(null !== $deliveryModule && null !== $deliveryAddress) {
$moduleInstance = $this->container->get(sprintf('module.%s', $deliveryModule->getCode()));
$postage = $moduleInstance->getPostage($deliveryAddress->getCountry());
$orderEvent = new OrderEvent($order);
$orderEvent->setPostage($postage);
$this->getDispatcher()->dispatch(TheliaEvents::ORDER_SET_POSTAGE, $orderEvent);
}
}
$this->redirect($couponCodeForm->getSuccessUrl());
} catch (FormValidationException $e) {
$message = sprintf('Please check your coupon code: %s', $e->getMessage());
} catch (PropelException $e) {

View File

@@ -95,6 +95,7 @@ class OrderController extends BaseFrontController
$this->getDispatcher()->dispatch(TheliaEvents::ORDER_SET_DELIVERY_ADDRESS, $orderEvent);
$this->getDispatcher()->dispatch(TheliaEvents::ORDER_SET_DELIVERY_MODULE, $orderEvent);
$this->getDispatcher()->dispatch(TheliaEvents::ORDER_SET_POSTAGE, $orderEvent);
$this->redirectToRoute("order.invoice");

View File

@@ -134,6 +134,9 @@
<tr >
<th class="coupon"><label for="coupon">{intl l="You may have a coupon ?"}</label></th>
<td class="coupon">
{form_field form=$form field='success_url'}
<input type="hidden" name="{$name}" value="{url path="/order/invoice"}" />
{/form_field}
{form_field form=$form field='coupon-code'}
<div class="{if $error}has-error{/if}">
<div class="input-group">