From 12c21b1239115300e6c83a7eb08c82f896ed61f7 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Thu, 17 Apr 2014 19:46:21 +0200 Subject: [PATCH] Fixes #308 --- core/lib/Thelia/Action/Order.php | 1015 +++++++++-------- .../Thelia/Core/Template/Loop/Delivery.php | 10 +- .../Thelia/Module/AbstractDeliveryModule.php | 2 + .../Thelia/Module/DeliveryModuleInterface.php | 2 + local/modules/Colissimo/Colissimo.php | 93 +- .../Front/Controller/CartController.php | 358 +++--- .../Front/Controller/CouponController.php | 224 ++-- 7 files changed, 871 insertions(+), 833 deletions(-) diff --git a/core/lib/Thelia/Action/Order.php b/core/lib/Thelia/Action/Order.php index a8a8d5af9..78534b268 100644 --- a/core/lib/Thelia/Action/Order.php +++ b/core/lib/Thelia/Action/Order.php @@ -1,504 +1,511 @@ -. */ -/* */ -/*************************************************************************************/ - -namespace Thelia\Action; - -use Symfony\Component\EventDispatcher\EventDispatcherInterface; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Thelia\Cart\CartTrait; -use Thelia\Core\Event\Order\OrderAddressEvent; -use Thelia\Core\Event\Order\OrderEvent; -use Thelia\Core\Event\Order\OrderManualEvent; -use Thelia\Core\Event\Order\OrderPaymentEvent; -use Thelia\Core\Event\TheliaEvents; -use Thelia\Core\HttpFoundation\Request; -use Thelia\Core\Security\SecurityContext; -use Thelia\Core\Template\ParserInterface; -use Thelia\Exception\TheliaProcessException; -use Thelia\Mailer\MailerFactory; -use Thelia\Model\AddressQuery; -use Thelia\Model\Cart as CartModel; -use Thelia\Model\ConfigQuery; -use Thelia\Model\Currency as CurrencyModel; -use Thelia\Model\Customer as CustomerModel; -use Thelia\Model\Lang as LangModel; -use Thelia\Model\Map\OrderTableMap; -use Thelia\Model\MessageQuery; -use Thelia\Model\Order as ModelOrder; -use Thelia\Model\OrderAddress; -use Thelia\Model\OrderProduct; -use Thelia\Model\OrderProductAttributeCombination; -use Thelia\Model\OrderStatus; -use Thelia\Model\OrderStatusQuery; -use Thelia\Tools\I18n; - -/** - * - * Class Order - * @package Thelia\Action - * @author Etienne Roudeix - */ -class Order extends BaseAction implements EventSubscriberInterface -{ - use CartTrait; - - /** - * @var \Thelia\Core\HttpFoundation\Request - */ - protected $request; - /** - * @var MailerFactory - */ - protected $mailer; - /** - * @var ParserInterface - */ - protected $parser; - /** - * @var SecurityContext - */ - protected $securityContext; - - public function __construct(Request $request, ParserInterface $parser, MailerFactory $mailer, SecurityContext $securityContext) - { - $this->request = $request; - $this->parser = $parser; - $this->mailer = $mailer; - $this->securityContext = $securityContext; - } - - /** - * @param \Thelia\Core\Event\Order\OrderEvent $event - */ - public function setDeliveryAddress(OrderEvent $event) - { - $order = $event->getOrder(); - - $order->chosenDeliveryAddress = $event->getDeliveryAddress(); - - $event->setOrder($order); - } - - /** - * @param \Thelia\Core\Event\Order\OrderEvent $event - */ - public function setDeliveryModule(OrderEvent $event) - { - $order = $event->getOrder(); - - $order->setDeliveryModuleId($event->getDeliveryModule()); - - $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); - } - - /** - * @param \Thelia\Core\Event\Order\OrderEvent $event - */ - public function setInvoiceAddress(OrderEvent $event) - { - $order = $event->getOrder(); - - $order->chosenInvoiceAddress = $event->getInvoiceAddress(); - - $event->setOrder($order); - } - - /** - * @param \Thelia\Core\Event\Order\OrderEvent $event - */ - public function setPaymentModule(OrderEvent $event) - { - $order = $event->getOrder(); - - $order->setPaymentModuleId($event->getPaymentModule()); - - $event->setOrder($order); - } - - protected function createOrder(EventDispatcherInterface $dispatcher, ModelOrder $sessionOrder, CurrencyModel $currency, LangModel $lang, CartModel $cart, CustomerModel $customer) - { - $con = \Propel\Runtime\Propel::getConnection( - OrderTableMap::DATABASE_NAME - ); - - $con->beginTransaction(); - - $placedOrder = $sessionOrder->copy(); - $placedOrder->setDispatcher($dispatcher); - - $deliveryAddress = AddressQuery::create()->findPk($sessionOrder->chosenDeliveryAddress); - $taxCountry = $deliveryAddress->getCountry(); - $invoiceAddress = AddressQuery::create()->findPk($sessionOrder->chosenInvoiceAddress); - $cartItems = $cart->getCartItems(); - - /* fulfill order */ - $placedOrder->setCustomerId($customer->getId()); - $placedOrder->setCurrencyId($currency->getId()); - $placedOrder->setCurrencyRate($currency->getRate()); - $placedOrder->setLangId($lang->getId()); - - /* hard save the delivery and invoice addresses */ - $deliveryOrderAddress = new OrderAddress(); - $deliveryOrderAddress - ->setCustomerTitleId($deliveryAddress->getTitleId()) - ->setCompany($deliveryAddress->getCompany()) - ->setFirstname($deliveryAddress->getFirstname()) - ->setLastname($deliveryAddress->getLastname()) - ->setAddress1($deliveryAddress->getAddress1()) - ->setAddress2($deliveryAddress->getAddress2()) - ->setAddress3($deliveryAddress->getAddress3()) - ->setZipcode($deliveryAddress->getZipcode()) - ->setCity($deliveryAddress->getCity()) - ->setPhone($deliveryAddress->getPhone()) - ->setCountryId($deliveryAddress->getCountryId()) - ->save($con) - ; - - $invoiceOrderAddress = new OrderAddress(); - $invoiceOrderAddress - ->setCustomerTitleId($invoiceAddress->getTitleId()) - ->setCompany($invoiceAddress->getCompany()) - ->setFirstname($invoiceAddress->getFirstname()) - ->setLastname($invoiceAddress->getLastname()) - ->setAddress1($invoiceAddress->getAddress1()) - ->setAddress2($invoiceAddress->getAddress2()) - ->setAddress3($invoiceAddress->getAddress3()) - ->setZipcode($invoiceAddress->getZipcode()) - ->setCity($invoiceAddress->getCity()) - ->setPhone($invoiceAddress->getPhone()) - ->setCountryId($invoiceAddress->getCountryId()) - ->save($con) - ; - - $placedOrder->setDeliveryOrderAddressId($deliveryOrderAddress->getId()); - $placedOrder->setInvoiceOrderAddressId($invoiceOrderAddress->getId()); - - $placedOrder->setStatusId( - OrderStatusQuery::getNotPaidStatus()->getId() - ); - - /* memorize discount */ - $placedOrder->setDiscount( - $cart->getDiscount() - ); - - $placedOrder->save($con); - - /* fulfill order_products and decrease stock */ - - foreach ($cartItems as $cartItem) { - $product = $cartItem->getProduct(); - - /* get translation */ - $productI18n = I18n::forceI18nRetrieving($lang->getLocale(), 'Product', $product->getId()); - - $pse = $cartItem->getProductSaleElements(); - - /* check still in stock */ - if ($cartItem->getQuantity() > $pse->getQuantity()) { - throw new TheliaProcessException("Not enough stock", TheliaProcessException::CART_ITEM_NOT_ENOUGH_STOCK, $cartItem); - } - - /* decrease stock */ - $pse->setQuantity( - $pse->getQuantity() - $cartItem->getQuantity() - ); - $pse->save($con); - - /* get tax */ - $taxRuleI18n = I18n::forceI18nRetrieving($lang->getLocale(), 'TaxRule', $product->getTaxRuleId()); - - $taxDetail = $product->getTaxRule()->getTaxDetail( - $product, - $taxCountry, - $cartItem->getPrice(), - $cartItem->getPromoPrice(), - $lang->getLocale() - ); - - $orderProduct = new OrderProduct(); - $orderProduct - ->setOrderId($placedOrder->getId()) - ->setProductRef($product->getRef()) - ->setProductSaleElementsRef($pse->getRef()) - ->setTitle($productI18n->getTitle()) - ->setChapo($productI18n->getChapo()) - ->setDescription($productI18n->getDescription()) - ->setPostscriptum($productI18n->getPostscriptum()) - ->setQuantity($cartItem->getQuantity()) - ->setPrice($cartItem->getPrice()) - ->setPromoPrice($cartItem->getPromoPrice()) - ->setWasNew($pse->getNewness()) - ->setWasInPromo($cartItem->getPromo()) - ->setWeight($pse->getWeight()) - ->setTaxRuleTitle($taxRuleI18n->getTitle()) - ->setTaxRuleDescription($taxRuleI18n->getDescription()) - ->setEanCode($pse->getEanCode()) - ->setCartIemId($cartItem->getId()) - ->setDispatcher($dispatcher) - ->save($con) - ; - - /* fulfill order_product_tax */ - foreach ($taxDetail as $tax) { - $tax->setOrderProductId($orderProduct->getId()); - $tax->save($con); - } - - /* fulfill order_attribute_combination and decrease stock */ - foreach ($pse->getAttributeCombinations() as $attributeCombination) { - $attribute = I18n::forceI18nRetrieving($lang->getLocale(), 'Attribute', $attributeCombination->getAttributeId()); - $attributeAv = I18n::forceI18nRetrieving($lang->getLocale(), 'AttributeAv', $attributeCombination->getAttributeAvId()); - - $orderAttributeCombination = new OrderProductAttributeCombination(); - $orderAttributeCombination - ->setOrderProductId($orderProduct->getId()) - ->setAttributeTitle($attribute->getTitle()) - ->setAttributeChapo($attribute->getChapo()) - ->setAttributeDescription($attribute->getDescription()) - ->setAttributePostscriptum($attribute->getPostscriptum()) - ->setAttributeAvTitle($attributeAv->getTitle()) - ->setAttributeAvChapo($attributeAv->getChapo()) - ->setAttributeAvDescription($attributeAv->getDescription()) - ->setAttributeAvPostscriptum($attributeAv->getPostscriptum()) - ->save($con); - } - } - - $con->commit(); - - return $placedOrder; - } - - /** - * Create an order outside of the front-office context, e.g. manually from the back-office. - */ - public function createManual(OrderManualEvent $event) - { - $placedOrder = $this->createOrder( - $event->getDispatcher(), - $event->getOrder(), - $event->getCurrency(), - $event->getLang(), - $event->getCart(), - $event->getCustomer() - ); - } - - /** - * @param OrderEvent $event - * - * @throws \Thelia\Exception\TheliaProcessException - */ - public function create(OrderEvent $event) - { - $session = $this->getSession(); - - $placedOrder = $this->createOrder( - $event->getDispatcher(), - $event->getOrder(), - $session->getCurrency(), - $session->getLang(), - $session->getCart(), - $this->securityContext->getCustomerUser() - ); - - $event->getDispatcher()->dispatch(TheliaEvents::ORDER_BEFORE_PAYMENT, new OrderEvent($placedOrder)); - - /* but memorize placed order */ - $event->setOrder(new \Thelia\Model\Order()); - $event->setPlacedOrder($placedOrder); - - /* empty cart */ - $dispatcher = $event->getDispatcher(); - - /* call pay method */ - $payEvent = new OrderPaymentEvent($placedOrder); - - $dispatcher->dispatch(TheliaEvents::MODULE_PAY, $payEvent); - - if ($payEvent->hasResponse()) { - $event->setResponse($payEvent->getResponse()); - } - } - - /** - * @param \Thelia\Core\Event\Order\OrderEvent $event - */ - public function sendOrderEmail(OrderEvent $event) - { - $contact_email = ConfigQuery::read('store_email'); - - if ($contact_email) { - - $message = MessageQuery::create() - ->filterByName('order_confirmation') - ->findOne(); - - if (false === $message) { - throw new \Exception("Failed to load message 'order_confirmation'."); - } - - $order = $event->getOrder(); - $customer = $order->getCustomer(); - - $this->parser->assign('order_id', $order->getId()); - $this->parser->assign('order_ref', $order->getRef()); - - $message - ->setLocale($order->getLang()->getLocale()); - - $instance = \Swift_Message::newInstance() - ->addTo($customer->getEmail(), $customer->getFirstname()." ".$customer->getLastname()) - ->addFrom($contact_email, ConfigQuery::read('store_name')) - ; - - // Build subject and body - - $message->buildMessage($this->parser, $instance); - - $this->getMailer()->send($instance); - } - } - - /** - * - * return an instance of \Swift_Mailer with good Transporter configured. - * - * @return \Swift_Mailer - */ - public function getMailer() - { - return $this->mailer->getSwiftMailer(); - } - - /** - * @param OrderEvent $event - */ - public function updateStatus(OrderEvent $event) - { - $order = $event->getOrder(); - - $order->setStatusId($event->getStatus()); - $order->save(); - - $event->setOrder($order); - } - - /** - * @param OrderEvent $event - */ - public function updateDeliveryRef(OrderEvent $event) - { - $order = $event->getOrder(); - - $order->setDeliveryRef($event->getDeliveryRef()); - $order->save(); - - $event->setOrder($order); - } - - /** - * @param OrderAddressEvent $event - */ - public function updateAddress(OrderAddressEvent $event) - { - $orderAddress = $event->getOrderAddress(); - - $orderAddress - ->setCustomerTitleId($event->getTitle()) - ->setCompany($event->getCompany()) - ->setFirstname($event->getFirstname()) - ->setLastname($event->getLastname()) - ->setAddress1($event->getAddress1()) - ->setAddress2($event->getAddress2()) - ->setAddress3($event->getAddress3()) - ->setZipcode($event->getZipcode()) - ->setCity($event->getCity()) - ->setCountryId($event->getCountry()) - ->setPhone($event->getPhone()) - ; - $orderAddress->save(); - - $event->setOrderAddress($orderAddress); - } - - /** - * Returns an array of event names this subscriber wants to listen to. - * - * The array keys are event names and the value can be: - * - * * The method name to call (priority defaults to 0) - * * An array composed of the method name to call and the priority - * * An array of arrays composed of the method names to call and respective - * priorities, or 0 if unset - * - * For instance: - * - * * array('eventName' => 'methodName') - * * array('eventName' => array('methodName', $priority)) - * * array('eventName' => array(array('methodName1', $priority), array('methodName2')) - * - * @return array The event names to listen to - * - * @api - */ - public static function getSubscribedEvents() - { - 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), - TheliaEvents::ORDER_BEFORE_PAYMENT => array("sendOrderEmail", 128), - TheliaEvents::ORDER_UPDATE_STATUS => array("updateStatus", 128), - TheliaEvents::ORDER_UPDATE_DELIVERY_REF => array("updateDeliveryRef", 128), - TheliaEvents::ORDER_UPDATE_ADDRESS => array("updateAddress", 128), - TheliaEvents::ORDER_CREATE_MANUAL => array("createManual", 128), - ); - } - - /** - * Returns the session from the current request - * - * @return \Thelia\Core\HttpFoundation\Session\Session - */ - protected function getSession() - { - return $this->request->getSession(); - } -} +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Action; + +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Thelia\Cart\CartTrait; +use Thelia\Core\Event\Order\OrderAddressEvent; +use Thelia\Core\Event\Order\OrderEvent; +use Thelia\Core\Event\Order\OrderManualEvent; +use Thelia\Core\Event\Order\OrderPaymentEvent; +use Thelia\Core\Event\TheliaEvents; +use Thelia\Core\HttpFoundation\Request; +use Thelia\Core\Security\SecurityContext; +use Thelia\Core\Template\ParserInterface; +use Thelia\Exception\TheliaProcessException; +use Thelia\Mailer\MailerFactory; +use Thelia\Model\AddressQuery; +use Thelia\Model\Cart as CartModel; +use Thelia\Model\ConfigQuery; +use Thelia\Model\Currency as CurrencyModel; +use Thelia\Model\Customer as CustomerModel; +use Thelia\Model\Lang as LangModel; +use Thelia\Model\Map\OrderTableMap; +use Thelia\Model\MessageQuery; +use Thelia\Model\Order as ModelOrder; +use Thelia\Model\OrderAddress; +use Thelia\Model\OrderProduct; +use Thelia\Model\OrderProductAttributeCombination; +use Thelia\Model\OrderStatus; +use Thelia\Model\OrderStatusQuery; +use Thelia\Tools\I18n; + +/** + * + * Class Order + * @package Thelia\Action + * @author Etienne Roudeix + */ +class Order extends BaseAction implements EventSubscriberInterface +{ + use CartTrait; + + /** + * @var \Thelia\Core\HttpFoundation\Request + */ + protected $request; + /** + * @var MailerFactory + */ + protected $mailer; + /** + * @var ParserInterface + */ + protected $parser; + /** + * @var SecurityContext + */ + protected $securityContext; + + public function __construct(Request $request, ParserInterface $parser, MailerFactory $mailer, SecurityContext $securityContext) + { + $this->request = $request; + $this->parser = $parser; + $this->mailer = $mailer; + $this->securityContext = $securityContext; + } + + /** + * @param \Thelia\Core\Event\Order\OrderEvent $event + */ + public function setDeliveryAddress(OrderEvent $event) + { + $order = $event->getOrder(); + + $order->chosenDeliveryAddress = $event->getDeliveryAddress(); + + $event->setOrder($order); + } + + /** + * @param \Thelia\Core\Event\Order\OrderEvent $event + */ + public function setDeliveryModule(OrderEvent $event) + { + $order = $event->getOrder(); + + $deliveryModuleId = $event->getDeliveryModule(); + + $order->setDeliveryModuleId($deliveryModuleId); + + // Reset postage cost if the delivery module had been removed + if ($deliveryModuleId <= 0) { + $this->setPostage(0); + } + + $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); + } + + /** + * @param \Thelia\Core\Event\Order\OrderEvent $event + */ + public function setInvoiceAddress(OrderEvent $event) + { + $order = $event->getOrder(); + + $order->chosenInvoiceAddress = $event->getInvoiceAddress(); + + $event->setOrder($order); + } + + /** + * @param \Thelia\Core\Event\Order\OrderEvent $event + */ + public function setPaymentModule(OrderEvent $event) + { + $order = $event->getOrder(); + + $order->setPaymentModuleId($event->getPaymentModule()); + + $event->setOrder($order); + } + + protected function createOrder(EventDispatcherInterface $dispatcher, ModelOrder $sessionOrder, CurrencyModel $currency, LangModel $lang, CartModel $cart, CustomerModel $customer) + { + $con = \Propel\Runtime\Propel::getConnection( + OrderTableMap::DATABASE_NAME + ); + + $con->beginTransaction(); + + $placedOrder = $sessionOrder->copy(); + $placedOrder->setDispatcher($dispatcher); + + $deliveryAddress = AddressQuery::create()->findPk($sessionOrder->chosenDeliveryAddress); + $taxCountry = $deliveryAddress->getCountry(); + $invoiceAddress = AddressQuery::create()->findPk($sessionOrder->chosenInvoiceAddress); + $cartItems = $cart->getCartItems(); + + /* fulfill order */ + $placedOrder->setCustomerId($customer->getId()); + $placedOrder->setCurrencyId($currency->getId()); + $placedOrder->setCurrencyRate($currency->getRate()); + $placedOrder->setLangId($lang->getId()); + + /* hard save the delivery and invoice addresses */ + $deliveryOrderAddress = new OrderAddress(); + $deliveryOrderAddress + ->setCustomerTitleId($deliveryAddress->getTitleId()) + ->setCompany($deliveryAddress->getCompany()) + ->setFirstname($deliveryAddress->getFirstname()) + ->setLastname($deliveryAddress->getLastname()) + ->setAddress1($deliveryAddress->getAddress1()) + ->setAddress2($deliveryAddress->getAddress2()) + ->setAddress3($deliveryAddress->getAddress3()) + ->setZipcode($deliveryAddress->getZipcode()) + ->setCity($deliveryAddress->getCity()) + ->setPhone($deliveryAddress->getPhone()) + ->setCountryId($deliveryAddress->getCountryId()) + ->save($con) + ; + + $invoiceOrderAddress = new OrderAddress(); + $invoiceOrderAddress + ->setCustomerTitleId($invoiceAddress->getTitleId()) + ->setCompany($invoiceAddress->getCompany()) + ->setFirstname($invoiceAddress->getFirstname()) + ->setLastname($invoiceAddress->getLastname()) + ->setAddress1($invoiceAddress->getAddress1()) + ->setAddress2($invoiceAddress->getAddress2()) + ->setAddress3($invoiceAddress->getAddress3()) + ->setZipcode($invoiceAddress->getZipcode()) + ->setCity($invoiceAddress->getCity()) + ->setPhone($invoiceAddress->getPhone()) + ->setCountryId($invoiceAddress->getCountryId()) + ->save($con) + ; + + $placedOrder->setDeliveryOrderAddressId($deliveryOrderAddress->getId()); + $placedOrder->setInvoiceOrderAddressId($invoiceOrderAddress->getId()); + + $placedOrder->setStatusId( + OrderStatusQuery::getNotPaidStatus()->getId() + ); + + /* memorize discount */ + $placedOrder->setDiscount( + $cart->getDiscount() + ); + + $placedOrder->save($con); + + /* fulfill order_products and decrease stock */ + + foreach ($cartItems as $cartItem) { + $product = $cartItem->getProduct(); + + /* get translation */ + $productI18n = I18n::forceI18nRetrieving($lang->getLocale(), 'Product', $product->getId()); + + $pse = $cartItem->getProductSaleElements(); + + /* check still in stock */ + if ($cartItem->getQuantity() > $pse->getQuantity()) { + throw new TheliaProcessException("Not enough stock", TheliaProcessException::CART_ITEM_NOT_ENOUGH_STOCK, $cartItem); + } + + /* decrease stock */ + $pse->setQuantity( + $pse->getQuantity() - $cartItem->getQuantity() + ); + $pse->save($con); + + /* get tax */ + $taxRuleI18n = I18n::forceI18nRetrieving($lang->getLocale(), 'TaxRule', $product->getTaxRuleId()); + + $taxDetail = $product->getTaxRule()->getTaxDetail( + $product, + $taxCountry, + $cartItem->getPrice(), + $cartItem->getPromoPrice(), + $lang->getLocale() + ); + + $orderProduct = new OrderProduct(); + $orderProduct + ->setOrderId($placedOrder->getId()) + ->setProductRef($product->getRef()) + ->setProductSaleElementsRef($pse->getRef()) + ->setTitle($productI18n->getTitle()) + ->setChapo($productI18n->getChapo()) + ->setDescription($productI18n->getDescription()) + ->setPostscriptum($productI18n->getPostscriptum()) + ->setQuantity($cartItem->getQuantity()) + ->setPrice($cartItem->getPrice()) + ->setPromoPrice($cartItem->getPromoPrice()) + ->setWasNew($pse->getNewness()) + ->setWasInPromo($cartItem->getPromo()) + ->setWeight($pse->getWeight()) + ->setTaxRuleTitle($taxRuleI18n->getTitle()) + ->setTaxRuleDescription($taxRuleI18n->getDescription()) + ->setEanCode($pse->getEanCode()) + ->setCartIemId($cartItem->getId()) + ->setDispatcher($dispatcher) + ->save($con) + ; + + /* fulfill order_product_tax */ + foreach ($taxDetail as $tax) { + $tax->setOrderProductId($orderProduct->getId()); + $tax->save($con); + } + + /* fulfill order_attribute_combination and decrease stock */ + foreach ($pse->getAttributeCombinations() as $attributeCombination) { + $attribute = I18n::forceI18nRetrieving($lang->getLocale(), 'Attribute', $attributeCombination->getAttributeId()); + $attributeAv = I18n::forceI18nRetrieving($lang->getLocale(), 'AttributeAv', $attributeCombination->getAttributeAvId()); + + $orderAttributeCombination = new OrderProductAttributeCombination(); + $orderAttributeCombination + ->setOrderProductId($orderProduct->getId()) + ->setAttributeTitle($attribute->getTitle()) + ->setAttributeChapo($attribute->getChapo()) + ->setAttributeDescription($attribute->getDescription()) + ->setAttributePostscriptum($attribute->getPostscriptum()) + ->setAttributeAvTitle($attributeAv->getTitle()) + ->setAttributeAvChapo($attributeAv->getChapo()) + ->setAttributeAvDescription($attributeAv->getDescription()) + ->setAttributeAvPostscriptum($attributeAv->getPostscriptum()) + ->save($con); + } + } + + $con->commit(); + + return $placedOrder; + } + + /** + * Create an order outside of the front-office context, e.g. manually from the back-office. + */ + public function createManual(OrderManualEvent $event) + { + $placedOrder = $this->createOrder( + $event->getDispatcher(), + $event->getOrder(), + $event->getCurrency(), + $event->getLang(), + $event->getCart(), + $event->getCustomer() + ); + } + + /** + * @param OrderEvent $event + * + * @throws \Thelia\Exception\TheliaProcessException + */ + public function create(OrderEvent $event) + { + $session = $this->getSession(); + + $placedOrder = $this->createOrder( + $event->getDispatcher(), + $event->getOrder(), + $session->getCurrency(), + $session->getLang(), + $session->getCart(), + $this->securityContext->getCustomerUser() + ); + + $event->getDispatcher()->dispatch(TheliaEvents::ORDER_BEFORE_PAYMENT, new OrderEvent($placedOrder)); + + /* but memorize placed order */ + $event->setOrder(new \Thelia\Model\Order()); + $event->setPlacedOrder($placedOrder); + + /* empty cart */ + $dispatcher = $event->getDispatcher(); + + /* call pay method */ + $payEvent = new OrderPaymentEvent($placedOrder); + + $dispatcher->dispatch(TheliaEvents::MODULE_PAY, $payEvent); + + if ($payEvent->hasResponse()) { + $event->setResponse($payEvent->getResponse()); + } + } + + /** + * @param \Thelia\Core\Event\Order\OrderEvent $event + */ + public function sendOrderEmail(OrderEvent $event) + { + $contact_email = ConfigQuery::read('store_email'); + + if ($contact_email) { + + $message = MessageQuery::create() + ->filterByName('order_confirmation') + ->findOne(); + + if (false === $message) { + throw new \Exception("Failed to load message 'order_confirmation'."); + } + + $order = $event->getOrder(); + $customer = $order->getCustomer(); + + $this->parser->assign('order_id', $order->getId()); + $this->parser->assign('order_ref', $order->getRef()); + + $message + ->setLocale($order->getLang()->getLocale()); + + $instance = \Swift_Message::newInstance() + ->addTo($customer->getEmail(), $customer->getFirstname()." ".$customer->getLastname()) + ->addFrom($contact_email, ConfigQuery::read('store_name')) + ; + + // Build subject and body + + $message->buildMessage($this->parser, $instance); + + $this->getMailer()->send($instance); + } + } + + /** + * + * return an instance of \Swift_Mailer with good Transporter configured. + * + * @return \Swift_Mailer + */ + public function getMailer() + { + return $this->mailer->getSwiftMailer(); + } + + /** + * @param OrderEvent $event + */ + public function updateStatus(OrderEvent $event) + { + $order = $event->getOrder(); + + $order->setStatusId($event->getStatus()); + $order->save(); + + $event->setOrder($order); + } + + /** + * @param OrderEvent $event + */ + public function updateDeliveryRef(OrderEvent $event) + { + $order = $event->getOrder(); + + $order->setDeliveryRef($event->getDeliveryRef()); + $order->save(); + + $event->setOrder($order); + } + + /** + * @param OrderAddressEvent $event + */ + public function updateAddress(OrderAddressEvent $event) + { + $orderAddress = $event->getOrderAddress(); + + $orderAddress + ->setCustomerTitleId($event->getTitle()) + ->setCompany($event->getCompany()) + ->setFirstname($event->getFirstname()) + ->setLastname($event->getLastname()) + ->setAddress1($event->getAddress1()) + ->setAddress2($event->getAddress2()) + ->setAddress3($event->getAddress3()) + ->setZipcode($event->getZipcode()) + ->setCity($event->getCity()) + ->setCountryId($event->getCountry()) + ->setPhone($event->getPhone()) + ; + $orderAddress->save(); + + $event->setOrderAddress($orderAddress); + } + + /** + * Returns an array of event names this subscriber wants to listen to. + * + * The array keys are event names and the value can be: + * + * * The method name to call (priority defaults to 0) + * * An array composed of the method name to call and the priority + * * An array of arrays composed of the method names to call and respective + * priorities, or 0 if unset + * + * For instance: + * + * * array('eventName' => 'methodName') + * * array('eventName' => array('methodName', $priority)) + * * array('eventName' => array(array('methodName1', $priority), array('methodName2')) + * + * @return array The event names to listen to + * + * @api + */ + public static function getSubscribedEvents() + { + 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), + TheliaEvents::ORDER_BEFORE_PAYMENT => array("sendOrderEmail", 128), + TheliaEvents::ORDER_UPDATE_STATUS => array("updateStatus", 128), + TheliaEvents::ORDER_UPDATE_DELIVERY_REF => array("updateDeliveryRef", 128), + TheliaEvents::ORDER_UPDATE_ADDRESS => array("updateAddress", 128), + TheliaEvents::ORDER_CREATE_MANUAL => array("createManual", 128), + ); + } + + /** + * Returns the session from the current request + * + * @return \Thelia\Core\HttpFoundation\Session\Session + */ + protected function getSession() + { + return $this->request->getSession(); + } +} diff --git a/core/lib/Thelia/Core/Template/Loop/Delivery.php b/core/lib/Thelia/Core/Template/Loop/Delivery.php index 22ac946e7..a379f9c3a 100644 --- a/core/lib/Thelia/Core/Template/Loop/Delivery.php +++ b/core/lib/Thelia/Core/Template/Loop/Delivery.php @@ -30,6 +30,7 @@ use Thelia\Model\CountryQuery; use Thelia\Model\Module; use Thelia\Module\BaseModule; use Thelia\Module\DeliveryModuleInterface; +use Thelia\Module\Exception\DeliveryException; /** * Class Delivery @@ -76,7 +77,7 @@ class Delivery extends BaseSpecificModule try { // Check if module is valid, by calling isValidDelivery(), - // or catching a DELIVERY_MODULE_UNAVAILABLE OrderException. + // or catching a DeliveryException. if ($moduleInstance->isValidDelivery($country)) { @@ -93,11 +94,8 @@ class Delivery extends BaseSpecificModule $loopResult->addRow($loopResultRow); } - } catch (OrderException $ex) { - // Re-throw an unknown exception - if ($ex->getCode() !== OrderException::DELIVERY_MODULE_UNAVAILABLE) { - throw $ex; - } + } catch (DeliveryException $ex) { + // Module is not available } } diff --git a/core/lib/Thelia/Module/AbstractDeliveryModule.php b/core/lib/Thelia/Module/AbstractDeliveryModule.php index 80c0072f2..9e9710534 100644 --- a/core/lib/Thelia/Module/AbstractDeliveryModule.php +++ b/core/lib/Thelia/Module/AbstractDeliveryModule.php @@ -24,6 +24,7 @@ namespace Thelia\Module; use Thelia\Model\Country; +use Thelia\Module\Exception\DeliveryException; abstract class AbstractDeliveryModule extends BaseModule implements DeliveryModuleInterface { @@ -46,6 +47,7 @@ abstract class AbstractDeliveryModule extends BaseModule implements DeliveryModu * @param Country $country the country to deliver to. * * @return float the delivery price + * @throws DeliveryException if the postage price cannot be calculated. */ public abstract function getPostage(Country $country); } \ No newline at end of file diff --git a/core/lib/Thelia/Module/DeliveryModuleInterface.php b/core/lib/Thelia/Module/DeliveryModuleInterface.php index 2cabd5f87..1f6bc5f70 100644 --- a/core/lib/Thelia/Module/DeliveryModuleInterface.php +++ b/core/lib/Thelia/Module/DeliveryModuleInterface.php @@ -24,6 +24,7 @@ namespace Thelia\Module; use Thelia\Model\Country; +use Thelia\Module\Exception\DeliveryException; interface DeliveryModuleInterface extends BaseModuleInterface { @@ -46,6 +47,7 @@ interface DeliveryModuleInterface extends BaseModuleInterface * @param Country $country the country to deliver to. * * @return float the delivery price + * @throws DeliveryException if the postage price cannot be calculated. */ public function getPostage(Country $country); } diff --git a/local/modules/Colissimo/Colissimo.php b/local/modules/Colissimo/Colissimo.php index 90d32df35..eb6b53dda 100755 --- a/local/modules/Colissimo/Colissimo.php +++ b/local/modules/Colissimo/Colissimo.php @@ -25,15 +25,14 @@ namespace Colissimo; use Colissimo\Model\ColissimoFreeshippingQuery; use Propel\Runtime\Connection\ConnectionInterface; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; -use Symfony\Component\HttpFoundation\Request; +use Thelia\Core\Translation\Translator; use Thelia\Exception\OrderException; use Thelia\Install\Database; use Thelia\Model\Country; -use Thelia\Module\BaseModule; -use Thelia\Module\DeliveryModuleInterface; +use Thelia\Module\AbstractDeliveryModule; +use Thelia\Module\Exception\DeliveryException; -class Colissimo extends BaseModule implements DeliveryModuleInterface +class Colissimo extends AbstractDeliveryModule { protected $request; protected $dispatcher; @@ -44,13 +43,38 @@ class Colissimo extends BaseModule implements DeliveryModuleInterface public static function getPrices() { - if(null === self::$prices) { + if (null === self::$prices) { self::$prices = json_decode(file_get_contents(sprintf('%s%s', __DIR__, self::JSON_PRICE_RESOURCE)), true); } return self::$prices; } + public function isValidDelivery(Country $country) { + + $areaId = $country->getAreaId(); + + $prices = self::getPrices(); + + /* Check if Colissimo delivers the area */ + if (isset($prices[$areaId]) && isset($prices[$areaId]["slices"])) { + + // Yes ! Check if the cart weight is below slice limit + $areaPrices = $prices[$areaId]["slices"]; + ksort($areaPrices); + + /* Check cart weight is below the maximum weight */ + end($areaPrices); + $maxWeight = key($areaPrices); + + $cartWeight = $this->getRequest()->getSession()->getCart()->getWeight(); + + if ($cartWeight <= $maxWeight) return true; + } + + return false; + } + /** * @param $areaId * @param $weight @@ -61,29 +85,36 @@ class Colissimo extends BaseModule implements DeliveryModuleInterface public static function getPostageAmount($areaId, $weight) { $freeshipping = ColissimoFreeshippingQuery::create()->getLast(); - $postage=0; - if(!$freeshipping) { + $postage = 0; + if (!$freeshipping) { $prices = self::getPrices(); /* check if Colissimo delivers the asked area */ - if(!isset($prices[$areaId]) || !isset($prices[$areaId]["slices"])) { - throw new OrderException("Colissimo delivery unavailable for the chosen delivery country", OrderException::DELIVERY_MODULE_UNAVAILABLE); + if (!isset($prices[$areaId]) || !isset($prices[$areaId]["slices"])) { + throw new DeliveryException( + Translator::getInstance()->trans("Colissimo delivery unavailable for the delivery country") + ); } $areaPrices = $prices[$areaId]["slices"]; ksort($areaPrices); - /* check this weight is not too much */ + /* Check cart weight is below the maximum weight */ end($areaPrices); $maxWeight = key($areaPrices); - if($weight > $maxWeight) { - throw new OrderException(sprintf("Colissimo delivery unavailable for this cart weight (%s kg)", $weight), OrderException::DELIVERY_MODULE_UNAVAILABLE); + if ($weight > $maxWeight) { + throw new DeliveryException( + Translator::getInstance()->trans( + "Colissimo delivery unavailable for this cart weight (%weight kg)", + array("%weight" => $weight) + ) + ); } $postage = current($areaPrices); - while(prev($areaPrices)) { - if($weight > key($areaPrices)) { + while (prev($areaPrices)) { + if ($weight > key($areaPrices)) { break; } @@ -94,29 +125,9 @@ class Colissimo extends BaseModule implements DeliveryModuleInterface } - public function setRequest(Request $request) - { - $this->request = $request; - } - - public function getRequest() - { - return $this->request; - } - - public function setDispatcher(EventDispatcherInterface $dispatcher) - { - $this->dispatcher = $dispatcher; - } - - public function getDispatcher() - { - return $this->dispatcher; - } - public function postActivation(ConnectionInterface $con = null) { - $database = new Database($con->getWrappedConnection()); + $database = new Database($con); $database->insertSql(null, array(__DIR__ . '/Config/thelia.sql')); } @@ -131,7 +142,7 @@ class Colissimo extends BaseModule implements DeliveryModuleInterface */ public function getPostage(Country $country) { - $cartWeight = $this->getContainer()->get('request')->getSession()->getCart()->getWeight(); + $cartWeight = $this->getRequest()->getSession()->getCart()->getWeight(); $postage = self::getPostageAmount( $country->getAreaId(), @@ -140,10 +151,4 @@ class Colissimo extends BaseModule implements DeliveryModuleInterface return $postage; } - - public function getCode() - { - return 'Colissimo'; - } - -} +} \ No newline at end of file diff --git a/local/modules/Front/Controller/CartController.php b/local/modules/Front/Controller/CartController.php index 59110d62a..ed3875756 100644 --- a/local/modules/Front/Controller/CartController.php +++ b/local/modules/Front/Controller/CartController.php @@ -1,173 +1,185 @@ -. */ -/* */ -/*************************************************************************************/ -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 -{ - use \Thelia\Cart\CartTrait; - - public function addItem() - { - $request = $this->getRequest(); - - $cartAdd = $this->getAddCartForm($request); - $message = null; - - try { - $form = $this->validateForm($cartAdd); - - $cartEvent = $this->getCartEvent(); - $cartEvent->setNewness($form->get("newness")->getData()); - $cartEvent->setAppend($form->get("append")->getData()); - $cartEvent->setQuantity($form->get("quantity")->getData()); - $cartEvent->setProductSaleElementsId($form->get("product_sale_elements_id")->getData()); - $cartEvent->setProduct($form->get("product")->getData()); - - $this->getDispatcher()->dispatch(TheliaEvents::CART_ADDITEM, $cartEvent); - - $this->afterModifyCart(); - - $this->redirectSuccess(); - - } catch (PropelException $e) { - \Thelia\Log\Tlog::getInstance()->error(sprintf("Failed to add item to cart with message : %s", $e->getMessage())); - $message = "Failed to add this article to your cart, please try again"; - } catch (FormValidationException $e) { - $message = $e->getMessage(); - } - - // If Ajax Request - if ($this->getRequest()->isXmlHttpRequest()) { - $request = $this->getRequest(); - $request->attributes->set('_view', "includes/mini-cart"); - } - - if ($message) { - $cartAdd->setErrorMessage($message); - $this->getParserContext()->addForm($cartAdd); - } - } - - public function changeItem() - { - $cartEvent = $this->getCartEvent(); - $cartEvent->setCartItem($this->getRequest()->get("cart_item")); - $cartEvent->setQuantity($this->getRequest()->get("quantity")); - - try { - $this->dispatch(TheliaEvents::CART_UPDATEITEM, $cartEvent); - - $this->afterModifyCart(); - - $this->redirectSuccess(); - } catch (PropelException $e) { - $this->getParserContext()->setGeneralError($e->getMessage()); - } - - } - - public function deleteItem() - { - $cartEvent = $this->getCartEvent(); - $cartEvent->setCartItem($this->getRequest()->get("cart_item")); - - 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())); - $this->getParserContext()->setGeneralError($e->getMessage()); - } - - } - - /** - * use Thelia\Cart\CartTrait for searching current cart or create a new one - * - * @return \Thelia\Core\Event\Cart\CartEvent - */ - protected function getCartEvent() - { - $cart = $this->getCart($this->getDispatcher(), $this->getRequest()); - - return new CartEvent($cart); - } - - /** - * Find the good way to construct the cart form - * - * @param Request $request - * @return CartAdd - */ - private function getAddCartForm(Request $request) - { - if ($request->isMethod("post")) { - $cartAdd = new CartAdd($request); - } else { - $cartAdd = new CartAdd( - $request, - "form", - array(), - array( - 'csrf_protection' => false, - ) - ); - } - - 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); - } - } - } - -} +. */ +/* */ +/*************************************************************************************/ +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; +use Thelia\Module\Exception\DeliveryException; + +class CartController extends BaseFrontController +{ + use \Thelia\Cart\CartTrait; + + public function addItem() + { + $request = $this->getRequest(); + + $cartAdd = $this->getAddCartForm($request); + $message = null; + + try { + $form = $this->validateForm($cartAdd); + + $cartEvent = $this->getCartEvent(); + $cartEvent->setNewness($form->get("newness")->getData()); + $cartEvent->setAppend($form->get("append")->getData()); + $cartEvent->setQuantity($form->get("quantity")->getData()); + $cartEvent->setProductSaleElementsId($form->get("product_sale_elements_id")->getData()); + $cartEvent->setProduct($form->get("product")->getData()); + + $this->getDispatcher()->dispatch(TheliaEvents::CART_ADDITEM, $cartEvent); + + $this->afterModifyCart(); + + $this->redirectSuccess(); + + } catch (PropelException $e) { + \Thelia\Log\Tlog::getInstance()->error(sprintf("Failed to add item to cart with message : %s", $e->getMessage())); + $message = "Failed to add this article to your cart, please try again"; + } catch (FormValidationException $e) { + $message = $e->getMessage(); + } + + // If Ajax Request + if ($this->getRequest()->isXmlHttpRequest()) { + $request = $this->getRequest(); + $request->attributes->set('_view', "includes/mini-cart"); + } + + if ($message) { + $cartAdd->setErrorMessage($message); + $this->getParserContext()->addForm($cartAdd); + } + } + + public function changeItem() + { + $cartEvent = $this->getCartEvent(); + $cartEvent->setCartItem($this->getRequest()->get("cart_item")); + $cartEvent->setQuantity($this->getRequest()->get("quantity")); + + try { + $this->dispatch(TheliaEvents::CART_UPDATEITEM, $cartEvent); + + $this->afterModifyCart(); + + $this->redirectSuccess(); + } catch (PropelException $e) { + $this->getParserContext()->setGeneralError($e->getMessage()); + } + + } + + public function deleteItem() + { + $cartEvent = $this->getCartEvent(); + $cartEvent->setCartItem($this->getRequest()->get("cart_item")); + + 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())); + $this->getParserContext()->setGeneralError($e->getMessage()); + } + + } + + /** + * use Thelia\Cart\CartTrait for searching current cart or create a new one + * + * @return \Thelia\Core\Event\Cart\CartEvent + */ + protected function getCartEvent() + { + $cart = $this->getCart($this->getDispatcher(), $this->getRequest()); + + return new CartEvent($cart); + } + + /** + * Find the good way to construct the cart form + * + * @param Request $request + * @return CartAdd + */ + private function getAddCartForm(Request $request) + { + if ($request->isMethod("post")) { + $cartAdd = new CartAdd($request); + } else { + $cartAdd = new CartAdd( + $request, + "form", + array(), + array( + 'csrf_protection' => false, + ) + ); + } + + 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())); + + $orderEvent = new OrderEvent($order); + + try { + $postage = $moduleInstance->getPostage($deliveryAddress->getCountry()); + + $orderEvent->setPostage($postage); + + $this->getDispatcher()->dispatch(TheliaEvents::ORDER_SET_POSTAGE, $orderEvent); + } + catch (DeliveryException $ex) { + // The postage has been chosen, but changes in the cart causes an exception. + // Reset the postage data in the order + $orderEvent->setDeliveryModule(0); + + $this->getDispatcher()->dispatch(TheliaEvents::ORDER_SET_DELIVERY_MODULE, $orderEvent); + } + } + } + } + +} diff --git a/local/modules/Front/Controller/CouponController.php b/local/modules/Front/Controller/CouponController.php index ba7433612..185041ce1 100644 --- a/local/modules/Front/Controller/CouponController.php +++ b/local/modules/Front/Controller/CouponController.php @@ -1,106 +1,118 @@ -. */ -/* */ -/*************************************************************************************/ -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\AddressQuery; - -/** - * Class CouponController - * @package Thelia\Controller\Front - * @author Guillaume MOREL - */ -class CouponController extends BaseFrontController -{ - - /** - * Test Coupon consuming - */ - public function consumeAction() - { - $this->checkAuth(); - $this->checkCartNotEmpty(); - - $message = false; - $couponCodeForm = new CouponCode($this->getRequest()); - - try { - $form = $this->validateForm($couponCodeForm, 'post'); - - $couponCode = $form->get('coupon-code')->getData(); - - if (null === $couponCode || empty($couponCode)) { - $message = true; - throw new \Exception('Coupon code can\'t be empty'); - } - - $couponConsumeEvent = new CouponConsumeEvent($couponCode); - - // 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) { - $this->getParserContext()->setGeneralError($e->getMessage()); - } catch (\Exception $e) { - $message = sprintf('Sorry, an error occurred: %s', $e->getMessage()); - } - - if ($message !== false) { - Tlog::getInstance()->error(sprintf("Error during order delivery process : %s. Exception was %s", $message, $e->getMessage())); - - $couponCodeForm->setErrorMessage($message); - - $this->getParserContext() - ->addForm($couponCodeForm) - ->setGeneralError($message); - } - } -} +. */ +/* */ +/*************************************************************************************/ +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\AddressQuery; +use Thelia\Module\Exception\DeliveryException; + +/** + * Class CouponController + * @package Thelia\Controller\Front + * @author Guillaume MOREL + */ +class CouponController extends BaseFrontController +{ + + /** + * Test Coupon consuming + */ + public function consumeAction() + { + $this->checkAuth(); + $this->checkCartNotEmpty(); + + $message = false; + $couponCodeForm = new CouponCode($this->getRequest()); + + try { + $form = $this->validateForm($couponCodeForm, 'post'); + + $couponCode = $form->get('coupon-code')->getData(); + + if (null === $couponCode || empty($couponCode)) { + $message = true; + throw new \Exception('Coupon code can\'t be empty'); + } + + $couponConsumeEvent = new CouponConsumeEvent($couponCode); + + // 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())); + + $orderEvent = new OrderEvent($order); + + try { + $postage = $moduleInstance->getPostage($deliveryAddress->getCountry()); + + $orderEvent->setPostage($postage); + + $this->getDispatcher()->dispatch(TheliaEvents::ORDER_SET_POSTAGE, $orderEvent); + } + catch (DeliveryException $ex) { + // The postage has been chosen, but changes dues to coupon causes an exception. + // Reset the postage data in the order + $orderEvent->setDeliveryModule(0); + + $this->getDispatcher()->dispatch(TheliaEvents::ORDER_SET_DELIVERY_MODULE, $orderEvent); + } + } + } + + $this->redirect($couponCodeForm->getSuccessUrl()); + + } catch (FormValidationException $e) { + $message = sprintf('Please check your coupon code: %s', $e->getMessage()); + } catch (PropelException $e) { + $this->getParserContext()->setGeneralError($e->getMessage()); + } catch (\Exception $e) { + $message = sprintf('Sorry, an error occurred: %s', $e->getMessage()); + } + + if ($message !== false) { + Tlog::getInstance()->error(sprintf("Error during order delivery process : %s. Exception was %s", $message, $e->getMessage())); + + $couponCodeForm->setErrorMessage($message); + + $this->getParserContext() + ->addForm($couponCodeForm) + ->setGeneralError($message); + } + } +}