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\Condition\Implementation\ConditionInterface;
use Thelia\Core\Event\Coupon\CouponConsumeEvent; use Thelia\Core\Event\Coupon\CouponConsumeEvent;
use Thelia\Core\Event\Coupon\CouponCreateOrUpdateEvent; use Thelia\Core\Event\Coupon\CouponCreateOrUpdateEvent;
use Thelia\Core\Event\Order\OrderEvent;
use Thelia\Core\Event\TheliaEvents; use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\HttpFoundation\Request; use Thelia\Core\HttpFoundation\Request;
use Thelia\Coupon\CouponFactory; use Thelia\Coupon\CouponFactory;
@@ -122,13 +123,6 @@ class Coupon extends BaseAction implements EventSubscriberInterface
$request->getSession()->setConsumedCoupons($consumedCoupons); $request->getSession()->setConsumedCoupons($consumedCoupons);
$totalDiscount = $couponManager->getDiscount(); $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 $request
->getSession() ->getSession()
@@ -206,6 +200,47 @@ class Coupon extends BaseAction implements EventSubscriberInterface
$event->setCouponModel($coupon); $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. * 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_CREATE => array("create", 128),
TheliaEvents::COUPON_UPDATE => array("update", 128), TheliaEvents::COUPON_UPDATE => array("update", 128),
TheliaEvents::COUPON_CONSUME => array("consume", 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 = $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()); $order->setPostage($event->getPostage());
$event->setOrder($order); $event->setOrder($order);
@@ -178,6 +189,8 @@ class Order extends BaseAction implements EventSubscriberInterface
OrderStatusQuery::create()->findOneByCode(OrderStatus::CODE_NOT_PAID)->getId() OrderStatusQuery::create()->findOneByCode(OrderStatus::CODE_NOT_PAID)->getId()
); );
/* refresh discount @todo */
/* memorize discount */ /* memorize discount */
$placedOrder->setDiscount( $placedOrder->setDiscount(
$cart->getDiscount() $cart->getDiscount()
@@ -267,10 +280,7 @@ class Order extends BaseAction implements EventSubscriberInterface
} }
} }
/* discount @todo */ /* memorize coupons @todo */
/* refresh discount */
/* memorize coupons */
$con->commit(); $con->commit();
@@ -420,6 +430,7 @@ class Order extends BaseAction implements EventSubscriberInterface
return array( return array(
TheliaEvents::ORDER_SET_DELIVERY_ADDRESS => array("setDeliveryAddress", 128), TheliaEvents::ORDER_SET_DELIVERY_ADDRESS => array("setDeliveryAddress", 128),
TheliaEvents::ORDER_SET_DELIVERY_MODULE => array("setDeliveryModule", 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_INVOICE_ADDRESS => array("setInvoiceAddress", 128),
TheliaEvents::ORDER_SET_PAYMENT_MODULE => array("setPaymentModule", 128), TheliaEvents::ORDER_SET_PAYMENT_MODULE => array("setPaymentModule", 128),
TheliaEvents::ORDER_PAY => array("create", 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_ADDRESS = "action.order.setDeliveryAddress";
const ORDER_SET_DELIVERY_MODULE = "action.order.setDeliveryModule"; 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_INVOICE_ADDRESS = "action.order.setInvoiceAddress";
const ORDER_SET_PAYMENT_MODULE = "action.order.setPaymentModule"; const ORDER_SET_PAYMENT_MODULE = "action.order.setPaymentModule";
const ORDER_PAY = "action.order.pay"; const ORDER_PAY = "action.order.pay";

View File

@@ -82,15 +82,8 @@ class CouponManager
if (count($this->coupons) > 0) { if (count($this->coupons) > 0) {
$couponsKept = $this->sortCoupons($this->coupons); $couponsKept = $this->sortCoupons($this->coupons);
$isRemovingPostage = $this->isCouponRemovingPostage($couponsKept);
$discount = $this->getEffect($couponsKept); $discount = $this->getEffect($couponsKept);
if ($isRemovingPostage) {
$postage = $this->facade->getCheckoutPostagePrice();
$discount += $postage;
}
// Just In Case test // Just In Case test
$checkoutTotalPrice = $this->facade->getCartTotalPrice(); $checkoutTotalPrice = $this->facade->getCartTotalPrice();
if ($discount >= $checkoutTotalPrice) { if ($discount >= $checkoutTotalPrice) {
@@ -103,23 +96,24 @@ class CouponManager
/** /**
* Check if there is a Coupon removing Postage * Check if there is a Coupon removing Postage
*
* @param array $couponsKept Array of CouponInterface sorted
*
* @return bool * @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 */ /** @var CouponInterface $coupon */
foreach ($couponsKept as $coupon) { foreach ($couponsKept as $coupon) {
if ($coupon->isRemovingPostage()) { 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 Propel\Runtime\Exception\PropelException;
use Thelia\Controller\Front\BaseFrontController; use Thelia\Controller\Front\BaseFrontController;
use Thelia\Core\Event\Order\OrderEvent;
use Thelia\Form\Exception\FormValidationException; use Thelia\Form\Exception\FormValidationException;
use Thelia\Core\Event\Cart\CartEvent; use Thelia\Core\Event\Cart\CartEvent;
use Thelia\Core\Event\TheliaEvents; use Thelia\Core\Event\TheliaEvents;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Thelia\Form\CartAdd; use Thelia\Form\CartAdd;
use Thelia\Model\AddressQuery;
class CartController extends BaseFrontController class CartController extends BaseFrontController
{ {
@@ -53,6 +55,8 @@ class CartController extends BaseFrontController
$this->getDispatcher()->dispatch(TheliaEvents::CART_ADDITEM, $cartEvent); $this->getDispatcher()->dispatch(TheliaEvents::CART_ADDITEM, $cartEvent);
$this->afterModifyCart();
$this->redirectSuccess(); $this->redirectSuccess();
} catch (PropelException $e) { } catch (PropelException $e) {
@@ -83,6 +87,8 @@ class CartController extends BaseFrontController
try { try {
$this->dispatch(TheliaEvents::CART_UPDATEITEM, $cartEvent); $this->dispatch(TheliaEvents::CART_UPDATEITEM, $cartEvent);
$this->afterModifyCart();
$this->redirectSuccess(); $this->redirectSuccess();
} catch (PropelException $e) { } catch (PropelException $e) {
$this->getParserContext()->setGeneralError($e->getMessage()); $this->getParserContext()->setGeneralError($e->getMessage());
@@ -98,6 +104,8 @@ class CartController extends BaseFrontController
try { try {
$this->getDispatcher()->dispatch(TheliaEvents::CART_DELETEITEM, $cartEvent); $this->getDispatcher()->dispatch(TheliaEvents::CART_DELETEITEM, $cartEvent);
$this->afterModifyCart();
$this->redirectSuccess(); $this->redirectSuccess();
} catch (PropelException $e) { } catch (PropelException $e) {
\Thelia\Log\Tlog::getInstance()->error(sprintf("error during deleting cartItem with message : %s", $e->getMessage())); \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; 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 Propel\Runtime\Exception\PropelException;
use Thelia\Controller\Front\BaseFrontController; use Thelia\Controller\Front\BaseFrontController;
use Thelia\Core\Event\Coupon\CouponConsumeEvent; use Thelia\Core\Event\Coupon\CouponConsumeEvent;
use Thelia\Core\Event\Order\OrderEvent;
use Thelia\Form\CouponCode; use Thelia\Form\CouponCode;
use Thelia\Form\Exception\FormValidationException; use Thelia\Form\Exception\FormValidationException;
use Thelia\Core\Event\TheliaEvents; use Thelia\Core\Event\TheliaEvents;
use Thelia\Log\Tlog; use Thelia\Log\Tlog;
use Thelia\Model\Order; use Thelia\Model\AddressQuery;
/** /**
* Class CouponController * Class CouponController
@@ -65,6 +66,25 @@ class CouponController extends BaseFrontController
// Dispatch Event to the Action // Dispatch Event to the Action
$this->getDispatcher()->dispatch(TheliaEvents::COUPON_CONSUME, $couponConsumeEvent); $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) { } catch (FormValidationException $e) {
$message = sprintf('Please check your coupon code: %s', $e->getMessage()); $message = sprintf('Please check your coupon code: %s', $e->getMessage());
} catch (PropelException $e) { } 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_ADDRESS, $orderEvent);
$this->getDispatcher()->dispatch(TheliaEvents::ORDER_SET_DELIVERY_MODULE, $orderEvent); $this->getDispatcher()->dispatch(TheliaEvents::ORDER_SET_DELIVERY_MODULE, $orderEvent);
$this->getDispatcher()->dispatch(TheliaEvents::ORDER_SET_POSTAGE, $orderEvent);
$this->redirectToRoute("order.invoice"); $this->redirectToRoute("order.invoice");

View File

@@ -134,6 +134,9 @@
<tr > <tr >
<th class="coupon"><label for="coupon">{intl l="You may have a coupon ?"}</label></th> <th class="coupon"><label for="coupon">{intl l="You may have a coupon ?"}</label></th>
<td class="coupon"> <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'} {form_field form=$form field='coupon-code'}
<div class="{if $error}has-error{/if}"> <div class="{if $error}has-error{/if}">
<div class="input-group"> <div class="input-group">