diff --git a/core/lib/Thelia/Action/Order.php b/core/lib/Thelia/Action/Order.php index 15266fac1..4a982673a 100755 --- a/core/lib/Thelia/Action/Order.php +++ b/core/lib/Thelia/Action/Order.php @@ -23,15 +23,17 @@ namespace Thelia\Action; +use Propel\Runtime\Exception\PropelException; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Thelia\Core\Event\CartEvent; use Thelia\Core\Event\OrderEvent; use Thelia\Core\Event\TheliaEvents; -use Thelia\Model\ProductPrice; -use Thelia\Model\ProductPriceQuery; -use Thelia\Model\CartItem; -use Thelia\Model\CartItemQuery; +use Thelia\Model\Base\AddressQuery; +use Thelia\Model\ModuleQuery; +use Thelia\Model\OrderStatus; +use Thelia\Model\Map\OrderTableMap; +use Thelia\Model\OrderAddress; +use Thelia\Model\OrderStatusQuery; use Thelia\Model\ConfigQuery; /** @@ -67,6 +69,135 @@ class Order extends BaseAction implements EventSubscriberInterface $event->setOrder($order); } + /** + * @param \Thelia\Core\Event\OrderEvent $event + */ + public function setInvoiceAddress(OrderEvent $event) + { + $order = $event->getOrder(); + + $order->chosenInvoiceAddress = $event->getInvoiceAddress(); + + $event->setOrder($order); + } + + /** + * @param \Thelia\Core\Event\OrderEvent $event + */ + public function setPaymentModule(OrderEvent $event) + { + $order = $event->getOrder(); + + $order->setPaymentModuleId($event->getPaymentModule()); + + $event->setOrder($order); + } + + /** + * @param \Thelia\Core\Event\OrderEvent $event + */ + public function create(OrderEvent $event) + { + $con = \Propel\Runtime\Propel::getConnection( + OrderTableMap::DATABASE_NAME + ); + + $con->beginTransaction(); + + $sessionOrder = $event->getOrder(); + + /* use a copy to avoid errored reccord in session */ + $placedOrder = $sessionOrder->copy(); + + $customer = $this->getSecurityContext()->getCustomerUser(); + $currency = $this->getSession()->getCurrency(); + $lang = $this->getSession()->getLang(); + $deliveryAddress = AddressQuery::create()->findPk($sessionOrder->chosenDeliveryAddress); + $invoiceAddress = AddressQuery::create()->findPk($sessionOrder->chosenInvoiceAddress); + + $paymentModule = ModuleQuery::findPk($placedOrder->getPaymentModuleId()); + + /* 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()) + ->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()) + ->setCountryId($invoiceAddress->getCountryId()) + ->save($con) + ; + + $placedOrder->setDeliveryOrderAddressId($deliveryOrderAddress->getId()); + $placedOrder->setInvoiceOrderAddressId($invoiceOrderAddress->getId()); + + $placedOrder->setStatusId( + OrderStatusQuery::create()->findOneByCode(OrderStatus::CODE_NOT_PAID)->getId() + ); + + $placedOrder->save($con); + + /* fulfill order_products and decrease stock // @todo dispatch event */ + + /* discount @todo */ + + $con->commit(); + + /* T1style : dispatch mail event ? */ + + /* clear session ? */ + + /* call pay method */ + $paymentModuleReflection = new \ReflectionClass($paymentModule->getFullNamespace()); + $paymentModuleInstance = $paymentModuleReflection->newInstance(); + + $paymentModuleInstance->setRequest($this->request); + $paymentModuleInstance->setDispatcher($this->dispatcher); + + $paymentModuleInstance->pay(); + } + + /** + * @param \Thelia\Core\Event\OrderEvent $event + */ + public function setReference(OrderEvent $event) + { + $x = true; + + $this->setRef($this->generateRef()); + } + + public function generateRef() + { + return sprintf('O', uniqid('', true), $this->getId()); + } + /** * Returns an array of event names this subscriber wants to listen to. * @@ -92,6 +223,40 @@ 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_INVOICE_ADDRESS => array("setInvoiceAddress", 128), + TheliaEvents::ORDER_SET_PAYMENT_MODULE => array("setPaymentModule", 128), + TheliaEvents::ORDER_PAY => array("create", 128), + TheliaEvents::ORDER_SET_REFERENCE => array("setReference", 128), ); } + + /** + * Return the security context + * + * @return SecurityContext + */ + protected function getSecurityContext() + { + return $this->container->get('thelia.securityContext'); + } + + /** + * @return \Symfony\Component\HttpFoundation\Request + */ + protected function getRequest() + { + return $this->container->get('request'); + } + + /** + * Returns the session from the current request + * + * @return \Thelia\Core\HttpFoundation\Session\Session + */ + protected function getSession() + { + $request = $this->getRequest(); + + return $request->getSession(); + } } diff --git a/core/lib/Thelia/Cart/CartTrait.php b/core/lib/Thelia/Cart/CartTrait.php index 8589f25b5..8ced1b6c1 100755 --- a/core/lib/Thelia/Cart/CartTrait.php +++ b/core/lib/Thelia/Cart/CartTrait.php @@ -139,4 +139,6 @@ trait CartTrait return $id; } + + abstract public function getDispatcher(); } diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index 5f9af7f08..43e48f6e4 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -228,6 +228,7 @@ + diff --git a/core/lib/Thelia/Config/Resources/routing/front.xml b/core/lib/Thelia/Config/Resources/routing/front.xml index c1e153af0..f254a817e 100755 --- a/core/lib/Thelia/Config/Resources/routing/front.xml +++ b/core/lib/Thelia/Config/Resources/routing/front.xml @@ -112,6 +112,9 @@ cart + + + Thelia\Controller\Front\OrderController::deliver order_delivery @@ -123,7 +126,7 @@ - Thelia\Controller\Front\OrderController::pay + Thelia\Controller\Front\OrderController::invoice order_invoice @@ -132,12 +135,9 @@ order_invoice - - - - - Thelia\Controller\Front\DeliveryController::select - \d+ + + Thelia\Controller\Front\OrderController::pay + order_payment diff --git a/core/lib/Thelia/Controller/Front/BaseFrontController.php b/core/lib/Thelia/Controller/Front/BaseFrontController.php index 74e918b2d..b8a7c6a98 100755 --- a/core/lib/Thelia/Controller/Front/BaseFrontController.php +++ b/core/lib/Thelia/Controller/Front/BaseFrontController.php @@ -72,7 +72,13 @@ class BaseFrontController extends BaseController if(null === $order || null === $order->chosenDeliveryAddress || null === $order->getDeliveryModuleId()) { $this->redirectToRoute("order.delivery"); } + } - + protected function checkValidInvoice() + { + $order = $this->getSession()->getOrder(); + if(null === $order || null === $order->chosenInvoiceAddress || null === $order->getPaymentModuleId()) { + $this->redirectToRoute("order.invoice"); + } } } diff --git a/core/lib/Thelia/Controller/Front/DeliveryController.php b/core/lib/Thelia/Controller/Front/DeliveryController.php deleted file mode 100644 index ef5913bc9..000000000 --- a/core/lib/Thelia/Controller/Front/DeliveryController.php +++ /dev/null @@ -1,55 +0,0 @@ -. */ -/* */ -/*************************************************************************************/ - -namespace Thelia\Controller\Front; -use Thelia\Model\ModuleQuery; -use Thelia\Tools\URL; - -/** - * Class DeliveryController - * @package Thelia\Controller\Front - * @author Manuel Raynaud - */ -class DeliveryController extends BaseFrontController -{ - public function select($delivery_id) - { - if ($this->getSecurityContext()->hasCustomerUser() === false) { - $this->redirect(URL::getInstance()->getIndexPage()); - } - - $request = $this->getRequest(); - - $deliveryModule = ModuleQuery::create() - ->filterById($delivery_id) - ->filterByActivate(1) - ->findOne() - ; - - if ($deliveryModule) { - $request->getSession()->setDelivery($delivery_id); - } else { - $this->pageNotFound(); - } - } -} diff --git a/core/lib/Thelia/Controller/Front/OrderController.php b/core/lib/Thelia/Controller/Front/OrderController.php index 75fa91b36..53d1e070b 100755 --- a/core/lib/Thelia/Controller/Front/OrderController.php +++ b/core/lib/Thelia/Controller/Front/OrderController.php @@ -121,7 +121,7 @@ class OrderController extends BaseFrontController * set invoice address * set payment module */ - public function pay() + public function invoice() { $this->checkAuth(); $this->checkCartNotEmpty(); @@ -134,23 +134,23 @@ class OrderController extends BaseFrontController try { $form = $this->validateForm($orderPayment, "post"); - $deliveryAddressId = $form->get("delivery-address")->getData(); - $deliveryModuleId = $form->get("delivery-module")->getData(); + $invoiceAddressId = $form->get("invoice-address")->getData(); + $paymentModuleId = $form->get("payment-module")->getData(); /* check that the invoice address belongs to the current customer */ - $deliveryAddress = AddressQuery::create()->findPk($deliveryAddressId); - if($deliveryAddress->getCustomerId() !== $this->getSecurityContext()->getCustomerUser()->getId()) { + $invoiceAddress = AddressQuery::create()->findPk($invoiceAddressId); + if($invoiceAddress->getCustomerId() !== $this->getSecurityContext()->getCustomerUser()->getId()) { throw new \Exception("Invoice address does not belong to the current customer"); } $orderEvent = $this->getOrderEvent(); - $orderEvent->setInvoiceAddress($deliveryAddressId); - $orderEvent->setPaymentModule($deliveryModuleId); + $orderEvent->setInvoiceAddress($invoiceAddressId); + $orderEvent->setPaymentModule($paymentModuleId); - $this->getDispatcher()->dispatch(TheliaEvents::ORDER_SET_DELIVERY_ADDRESS, $orderEvent); - $this->getDispatcher()->dispatch(TheliaEvents::ORDER_SET_DELIVERY_MODULE, $orderEvent); + $this->getDispatcher()->dispatch(TheliaEvents::ORDER_SET_INVOICE_ADDRESS, $orderEvent); + $this->getDispatcher()->dispatch(TheliaEvents::ORDER_SET_PAYMENT_MODULE, $orderEvent); - $this->redirectToRoute("order.invoice"); + $this->redirectToRoute("order.payment.process"); } catch (FormValidationException $e) { $message = sprintf("Please check your input: %s", $e->getMessage()); @@ -161,7 +161,7 @@ class OrderController extends BaseFrontController } if ($message !== false) { - Tlog::getInstance()->error(sprintf("Error during order delivery process : %s. Exception was %s", $message, $e->getMessage())); + Tlog::getInstance()->error(sprintf("Error during order payment process : %s. Exception was %s", $message, $e->getMessage())); $orderPayment->setErrorMessage($message); @@ -173,6 +173,25 @@ class OrderController extends BaseFrontController } + public function pay() + { + /* check customer */ + $this->checkAuth(); + + /* check cart count */ + $this->checkCartNotEmpty(); + + /* check delivery address and module */ + $this->checkValidDelivery(); + + /* check invoice address and payment module */ + $this->checkValidInvoice(); + + $orderEvent = $this->getOrderEvent(); + + $this->getDispatcher()->dispatch(TheliaEvents::ORDER_PAY, $orderEvent); + } + protected function getOrderEvent() { $order = $this->getOrder($this->getRequest()); diff --git a/core/lib/Thelia/Core/Event/OrderEvent.php b/core/lib/Thelia/Core/Event/OrderEvent.php index 349fd53a1..a156b753f 100755 --- a/core/lib/Thelia/Core/Event/OrderEvent.php +++ b/core/lib/Thelia/Core/Event/OrderEvent.php @@ -33,6 +33,7 @@ class OrderEvent extends ActionEvent protected $deliveryModule = null; protected $paymentModule = null; protected $postage = null; + protected $ref = null; /** * @param Order $order @@ -55,7 +56,7 @@ class OrderEvent extends ActionEvent */ public function setInvoiceAddress($address) { - $this->deliveryAddress = $address; + $this->invoiceAddress = $address; } /** @@ -90,6 +91,14 @@ class OrderEvent extends ActionEvent $this->postage = $postage; } + /** + * @param $ref + */ + public function setRef($ref) + { + $this->ref = $ref; + } + /** * @return null|Order */ @@ -137,4 +146,12 @@ class OrderEvent extends ActionEvent { return $this->postage; } + + /** + * @return null|int + */ + public function getRef() + { + return $this->ref; + } } diff --git a/core/lib/Thelia/Core/Event/TheliaEvents.php b/core/lib/Thelia/Core/Event/TheliaEvents.php index b99a5af1b..75f5314f0 100755 --- a/core/lib/Thelia/Core/Event/TheliaEvents.php +++ b/core/lib/Thelia/Core/Event/TheliaEvents.php @@ -252,9 +252,12 @@ final class TheliaEvents /** * Order linked event */ - const ORDER_SET_BILLING_ADDRESS = "action.order.setBillingAddress"; const ORDER_SET_DELIVERY_ADDRESS = "action.order.setDeliveryAddress"; const ORDER_SET_DELIVERY_MODULE = "action.order.setDeliveryModule"; + const ORDER_SET_INVOICE_ADDRESS = "action.order.setInvoiceAddress"; + const ORDER_SET_PAYMENT_MODULE = "action.order.setPaymentModule"; + const ORDER_PAY = "action.order.pay"; + const ORDER_SET_REFERENCE = "action.order.setReference"; /** * Sent on image processing diff --git a/core/lib/Thelia/Core/Template/Element/BaseI18nLoop.php b/core/lib/Thelia/Core/Template/Element/BaseI18nLoop.php index 283aad797..557c64901 100644 --- a/core/lib/Thelia/Core/Template/Element/BaseI18nLoop.php +++ b/core/lib/Thelia/Core/Template/Element/BaseI18nLoop.php @@ -65,6 +65,8 @@ abstract class BaseI18nLoop extends BaseLoop { /* manage translations */ + $fr = $this->getForce_return(); + return ModelCriteriaTools::getI18n( $this->getBackend_context(), $this->getLang(), diff --git a/core/lib/Thelia/Core/Template/Loop/Argument/Argument.php b/core/lib/Thelia/Core/Template/Loop/Argument/Argument.php index 54c2e3bf2..418a76220 100755 --- a/core/lib/Thelia/Core/Template/Loop/Argument/Argument.php +++ b/core/lib/Thelia/Core/Template/Loop/Argument/Argument.php @@ -58,7 +58,19 @@ class Argument public function setValue($value) { - $this->value = $value === null ? null : (string) $value; + $x = $value === null; + + if($value === null) { + $this->value = null; + } else { + if(false === $value) { + /* (string) $value = "" */ + $this->value = 0; + } else { + $this->value = (string) $value; + } + } + //$this->value = $value === null ? null : (string) $value; } public static function createAnyTypeArgument($name, $default=null, $mandatory=false, $empty=true) diff --git a/core/lib/Thelia/Core/Template/Loop/Cart.php b/core/lib/Thelia/Core/Template/Loop/Cart.php index 3c8724d68..16c108135 100755 --- a/core/lib/Thelia/Core/Template/Loop/Cart.php +++ b/core/lib/Thelia/Core/Template/Loop/Cart.php @@ -110,4 +110,13 @@ class Cart extends BaseLoop return $result; } + /** + * Return the event dispatcher, + * + * @return \Symfony\Component\EventDispatcher\EventDispatcher + */ + public function getDispatcher() + { + return $this->dispatcher; + } } diff --git a/core/lib/Thelia/Core/Template/Loop/Feature.php b/core/lib/Thelia/Core/Template/Loop/Feature.php index f5c66d2e6..380333e38 100755 --- a/core/lib/Thelia/Core/Template/Loop/Feature.php +++ b/core/lib/Thelia/Core/Template/Loop/Feature.php @@ -31,10 +31,12 @@ use Thelia\Core\Template\Element\LoopResultRow; use Thelia\Core\Template\Loop\Argument\ArgumentCollection; use Thelia\Core\Template\Loop\Argument\Argument; -use Thelia\Model\Base\CategoryQuery; -use Thelia\Model\Base\ProductCategoryQuery; -use Thelia\Model\Base\FeatureQuery; +use Thelia\Model\CategoryQuery; +use Thelia\Model\FeatureI18nQuery; +use Thelia\Model\ProductCategoryQuery; +use Thelia\Model\FeatureQuery; use Thelia\Model\Map\ProductCategoryTableMap; +use Thelia\Model\ProductQuery; use Thelia\Type\TypeCollection; use Thelia\Type; use Thelia\Type\BooleanOrBothType; @@ -71,7 +73,8 @@ class Feature extends BaseI18nLoop new Type\EnumListType(array('alpha', 'alpha-reverse', 'manual', 'manual_reverse')) ), 'manual' - ) + ), + Argument::createAnyTypeArgument('title') ); } @@ -134,6 +137,23 @@ class Feature extends BaseI18nLoop ); } + $title = $this->getTitle(); + + if (null !== $title) { + //find all feture that match exactly this title and find with all locales. + $features = FeatureI18nQuery::create() + ->filterByTitle($title, Criteria::LIKE) + ->select('id') + ->find(); + + if($features) { + $search->filterById( + $features, + Criteria::IN + ); + } + } + $orders = $this->getOrder(); foreach ($orders as $order) { diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php index ffad52785..fe203e7b8 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php @@ -24,6 +24,7 @@ namespace Thelia\Core\Template\Smarty\Plugins; use Propel\Runtime\ActiveQuery\ModelCriteria; +use Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher; use Symfony\Component\HttpFoundation\Request; use Thelia\Core\Template\Smarty\AbstractSmartyPlugin; use Thelia\Core\Security\SecurityContext; @@ -53,12 +54,14 @@ class DataAccessFunctions extends AbstractSmartyPlugin private $securityContext; protected $parserContext; protected $request; + protected $dispatcher; - public function __construct(Request $request, SecurityContext $securityContext, ParserContext $parserContext) + public function __construct(Request $request, SecurityContext $securityContext, ParserContext $parserContext, ContainerAwareEventDispatcher $dispatcher) { $this->securityContext = $securityContext; $this->parserContext = $parserContext; $this->request = $request; + $this->dispatcher = $dispatcher; } /** @@ -195,6 +198,12 @@ class DataAccessFunctions extends AbstractSmartyPlugin return $order->getPostage(); case 'delivery_address': return $order->chosenDeliveryAddress; + case 'invoice_address': + return $order->chosenInvoiceAddress; + case 'delivery_module': + return $order->getDeliveryModuleId(); + case 'payment_module': + return $order->getPaymentModuleId(); } throw new \InvalidArgumentException(sprintf("%s has no '%s' attribute", 'Order', $attribute)); @@ -320,4 +329,14 @@ class DataAccessFunctions extends AbstractSmartyPlugin new SmartyPluginDescriptor('function', 'order', $this, 'orderDataAccess'), ); } + + /** + * Return the event dispatcher, + * + * @return \Symfony\Component\EventDispatcher\EventDispatcher + */ + public function getDispatcher() + { + return $this->dispatcher; + } } diff --git a/core/lib/Thelia/Coupon/CouponBaseAdapter.php b/core/lib/Thelia/Coupon/CouponBaseAdapter.php index f9fae8651..046b4ac81 100644 --- a/core/lib/Thelia/Coupon/CouponBaseAdapter.php +++ b/core/lib/Thelia/Coupon/CouponBaseAdapter.php @@ -266,4 +266,14 @@ class CouponBaseAdapter implements CouponAdapterInterface { return $this->container->get('thelia.constraint.validator'); } + + /** + * Return the event dispatcher, + * + * @return \Symfony\Component\EventDispatcher\EventDispatcher + */ + public function getDispatcher() + { + return $this->container->get('event_dispatcher'); + } } diff --git a/core/lib/Thelia/Form/OrderDelivery.php b/core/lib/Thelia/Form/OrderDelivery.php index 3ef1444f6..e23ae92b2 100755 --- a/core/lib/Thelia/Form/OrderDelivery.php +++ b/core/lib/Thelia/Form/OrderDelivery.php @@ -85,6 +85,13 @@ class OrderDelivery extends BaseForm if(null === $module) { $context->addViolation("Delivery module ID not found"); } + + $moduleReflection = new \ReflectionClass($module->getFullNamespace()); + if ($moduleReflection->isSubclassOf("Thelia\Module\DeliveryModuleInterface") === false) { + $context->addViolation( + sprintf("delivery module %s is not a Thelia\Module\DeliveryModuleInterface", $module->getCode()) + ); + } } public function getName() diff --git a/core/lib/Thelia/Form/OrderPayment.php b/core/lib/Thelia/Form/OrderPayment.php index d3ebe4daf..6a6305971 100755 --- a/core/lib/Thelia/Form/OrderPayment.php +++ b/core/lib/Thelia/Form/OrderPayment.php @@ -80,11 +80,18 @@ class OrderPayment extends BaseForm ->filterByType(BaseModule::PAYMENT_MODULE_TYPE) ->filterByActivate(1) ->filterById($value) - ->find(); + ->findOne(); if(null === $module) { $context->addViolation("Payment module ID not found"); } + + $moduleReflection = new \ReflectionClass($module->getFullNamespace()); + if ($moduleReflection->isSubclassOf("Thelia\Module\PaymentModuleInterface") === false) { + $context->addViolation( + sprintf("delivery module %s is not a Thelia\Module\PaymentModuleInterface", $module->getCode()) + ); + } } public function getName() diff --git a/core/lib/Thelia/Model/Map/OrderStatusTableMap.php b/core/lib/Thelia/Model/Map/OrderStatusTableMap.php index bc283a3e8..f29ed9464 100644 --- a/core/lib/Thelia/Model/Map/OrderStatusTableMap.php +++ b/core/lib/Thelia/Model/Map/OrderStatusTableMap.php @@ -150,7 +150,7 @@ class OrderStatusTableMap extends TableMap $this->setUseIdGenerator(true); // columns $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); - $this->addColumn('CODE', 'Code', 'VARCHAR', false, 45, null); + $this->addColumn('CODE', 'Code', 'VARCHAR', true, 45, null); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); } // initialize() diff --git a/core/lib/Thelia/Model/Map/OrderTableMap.php b/core/lib/Thelia/Model/Map/OrderTableMap.php index ae43bd768..7daabb665 100644 --- a/core/lib/Thelia/Model/Map/OrderTableMap.php +++ b/core/lib/Thelia/Model/Map/OrderTableMap.php @@ -215,7 +215,7 @@ class OrderTableMap extends TableMap $this->addForeignKey('CUSTOMER_ID', 'CustomerId', 'INTEGER', 'customer', 'ID', true, null, null); $this->addForeignKey('INVOICE_ORDER_ADDRESS_ID', 'InvoiceOrderAddressId', 'INTEGER', 'order_address', 'ID', true, null, null); $this->addForeignKey('DELIVERY_ORDER_ADDRESS_ID', 'DeliveryOrderAddressId', 'INTEGER', 'order_address', 'ID', true, null, null); - $this->addColumn('INVOICE_DATE', 'InvoiceDate', 'DATE', true, null, null); + $this->addColumn('INVOICE_DATE', 'InvoiceDate', 'DATE', false, null, null); $this->addForeignKey('CURRENCY_ID', 'CurrencyId', 'INTEGER', 'currency', 'ID', true, null, null); $this->addColumn('CURRENCY_RATE', 'CurrencyRate', 'FLOAT', true, null, null); $this->addColumn('TRANSACTION_REF', 'TransactionRef', 'VARCHAR', false, 100, null); diff --git a/core/lib/Thelia/Model/Order.php b/core/lib/Thelia/Model/Order.php index e2eb43971..c5d03b7e7 100755 --- a/core/lib/Thelia/Model/Order.php +++ b/core/lib/Thelia/Model/Order.php @@ -2,13 +2,28 @@ namespace Thelia\Model; +use Propel\Runtime\Connection\ConnectionInterface; +use Thelia\Core\Event\OrderEvent; +use Thelia\Core\Event\TheliaEvents; use Thelia\Model\Base\Order as BaseOrder; class Order extends BaseOrder { + use \Thelia\Model\Tools\ModelEventDispatcherTrait; + public $chosenDeliveryAddress = null; public $chosenInvoiceAddress = null; + /** + * {@inheritDoc} + */ + public function preInsert(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::ORDER_SET_REFERENCE, new OrderEvent($this)); + + return true; + } + /** * calculate the total amount * diff --git a/core/lib/Thelia/Model/OrderStatus.php b/core/lib/Thelia/Model/OrderStatus.php index 2927019d0..f78e9c79d 100755 --- a/core/lib/Thelia/Model/OrderStatus.php +++ b/core/lib/Thelia/Model/OrderStatus.php @@ -4,6 +4,11 @@ namespace Thelia\Model; use Thelia\Model\Base\OrderStatus as BaseOrderStatus; -class OrderStatus extends BaseOrderStatus { - +class OrderStatus extends BaseOrderStatus +{ + const CODE_NOT_PAID = "not_paid"; + const CODE_PAID = "paid"; + const CODE_PROCESSED = "processed"; + const CODE_SENT = "sent"; + const CODE_CANCELED = "canceled"; } diff --git a/core/lib/Thelia/Module/BaseModule.php b/core/lib/Thelia/Module/BaseModule.php index 56b2c23af..f559c1fd5 100755 --- a/core/lib/Thelia/Module/BaseModule.php +++ b/core/lib/Thelia/Module/BaseModule.php @@ -105,7 +105,7 @@ abstract class BaseModule extends ContainerAware $image = new ModuleImage(); $image->setModuleId($module->getId()); $image->setPosition($imagePosition); - $image->save(); + $image->save($con); $imageDirectory = sprintf("%s/../../../../local/media/images/module", __DIR__); $imageFileName = sprintf("%s-%d-%s", $module->getCode(), $image->getId(), $fileName); @@ -131,7 +131,7 @@ abstract class BaseModule extends ContainerAware } $image->setFile($imageFileName); - $image->save(); + $image->save($con); $con->commit(); $imagePosition++; diff --git a/core/lib/Thelia/Tests/Command/ModuleActivateCommandTest.php b/core/lib/Thelia/Tests/Command/ModuleActivateCommandTest.php index e488e60ff..1d6d08e92 100755 --- a/core/lib/Thelia/Tests/Command/ModuleActivateCommandTest.php +++ b/core/lib/Thelia/Tests/Command/ModuleActivateCommandTest.php @@ -68,14 +68,11 @@ class ModuleActivateCommandTest extends \PHPUnit_Framework_TestCase */ public function testModuleActivateCommandUnknownModule() { - $module = ModuleQuery::create()->findOne(); $testedModule = ModuleQuery::create()->findOneByCode('Letshopethismoduledoesnotexists'); - if(null !== $module && null == $testedModule) { + if(null == $testedModule) { $application = new Application($this->getKernel()); - $module->setActivate(BaseModule::IS_NOT_ACTIVATED); - $module->save(); $moduleActivate = new ModuleActivateCommand(); $moduleActivate->setContainer($this->getContainer()); diff --git a/install/insert.sql b/install/insert.sql index f44374d4b..aa7573d12 100755 --- a/install/insert.sql +++ b/install/insert.sql @@ -1167,3 +1167,22 @@ INSERT INTO `tax_rule_i18n` (`id`, `locale`, `title`) INSERT INTO `tax_rule_country` (`tax_rule_id`, `country_id`, `tax_id`, `position`, `created_at`, `updated_at`) VALUES (1, 64, 1, 1, NOW(), NOW()); + +INSERT INTO `order_status`(`id`, `code`, `created_at`, `updated_at`) VALUES +(1, 'not_paid', NOW(), NOW()), +(2, 'paid', NOW(), NOW()), +(3, 'processing', NOW(), NOW()), +(4, 'sent', NOW(), NOW()), +(5, 'canceled', NOW(), NOW()); + +INSERT INTO `order_status_i18n` (`id`, `locale`, `title`, `description`, `chapo`, `postscriptum`) VALUES +(1, 'en_US', 'Not paid', '', '', ''), +(1, 'fr_FR', 'Non payée', '', '', ''), +(2, 'en_US', 'Paid', '', '', ''), +(2, 'fr_FR', 'Payée', '', '', ''), +(3, 'en_US', 'Processing', '', '', ''), +(3, 'fr_FR', 'Traitement', '', '', ''), +(4, 'en_US', 'Sent', '', '', ''), +(4, 'fr_FR', 'Envoyée', '', '', ''), +(5, 'en_US', 'Canceled', '', '', ''), +(5, 'fr_FR', 'Annulée', '', '', ''); diff --git a/install/thelia.sql b/install/thelia.sql index 398cb04c2..bd983d26d 100755 --- a/install/thelia.sql +++ b/install/thelia.sql @@ -641,7 +641,7 @@ CREATE TABLE `order` `customer_id` INTEGER NOT NULL, `invoice_order_address_id` INTEGER NOT NULL, `delivery_order_address_id` INTEGER NOT NULL, - `invoice_date` DATE NOT NULL, + `invoice_date` DATE, `currency_id` INTEGER NOT NULL, `currency_rate` FLOAT NOT NULL, `transaction_ref` VARCHAR(100) COMMENT 'transaction reference - usually use to identify a transaction with banking modules', @@ -788,10 +788,11 @@ DROP TABLE IF EXISTS `order_status`; CREATE TABLE `order_status` ( `id` INTEGER NOT NULL AUTO_INCREMENT, - `code` VARCHAR(45), + `code` VARCHAR(45) NOT NULL, `created_at` DATETIME, `updated_at` DATETIME, - PRIMARY KEY (`id`) + PRIMARY KEY (`id`), + UNIQUE INDEX `code_UNIQUE` (`code`) ) ENGINE=InnoDB; -- --------------------------------------------------------------------- diff --git a/local/config/schema.xml b/local/config/schema.xml index f33cedbe5..b767580ef 100755 --- a/local/config/schema.xml +++ b/local/config/schema.xml @@ -500,7 +500,7 @@ - + @@ -613,11 +613,14 @@ - + + + + diff --git a/local/modules/Cheque/Cheque.php b/local/modules/Cheque/Cheque.php index d6b462194..f4438db4e 100755 --- a/local/modules/Cheque/Cheque.php +++ b/local/modules/Cheque/Cheque.php @@ -56,7 +56,7 @@ class Cheque extends BaseModule implements PaymentModuleInterface public function pay() { - // TODO: Implement pay() method. + // no special process, waiting for the cheque. } public function install() diff --git a/templates/admin/default/admin-layout.tpl b/templates/admin/default/admin-layout.tpl index 8221fa90a..b80d5d13c 100644 --- a/templates/admin/default/admin-layout.tpl +++ b/templates/admin/default/admin-layout.tpl @@ -51,27 +51,27 @@
-
-
{intl l='Version %ver' ver="{$THELIA_VERSION}"}
+
+
{intl l='Version %ver' ver="{$THELIA_VERSION}"}
+ + +
{module_include location='inside_topbar'} - -
- -
- {intl l="View shop"} - - - -
- -
+
@@ -86,96 +86,98 @@
diff --git a/templates/admin/default/assets/less/thelia/grid.less b/templates/admin/default/assets/less/thelia/grid.less new file mode 100644 index 000000000..6ea63b46b --- /dev/null +++ b/templates/admin/default/assets/less/thelia/grid.less @@ -0,0 +1,11 @@ +@media (max-width: @screen-desktop) { + + .navbar-form{ + width: 100%; + + .form-group{ + width: 94%; + } + } + +} \ No newline at end of file diff --git a/templates/admin/default/assets/less/thelia/navbar.less b/templates/admin/default/assets/less/thelia/navbar.less index 26f9cd569..a0080e775 100755 --- a/templates/admin/default/assets/less/thelia/navbar.less +++ b/templates/admin/default/assets/less/thelia/navbar.less @@ -30,4 +30,8 @@ .navbar-default .navbar-toggle .icon-bar{ background-color: @btn-primary-color; +} + +.navbar-form{ + padding: 0; } \ No newline at end of file diff --git a/templates/admin/default/assets/less/thelia/thelia.less b/templates/admin/default/assets/less/thelia/thelia.less index 466f9d419..822130a5c 100644 --- a/templates/admin/default/assets/less/thelia/thelia.less +++ b/templates/admin/default/assets/less/thelia/thelia.less @@ -2,6 +2,7 @@ @import "navbar.less"; @import "scaffolding.less"; @import "type.less"; +@import "grid.less"; @import "breadcrumbs.less"; @import "forms.less"; @import "datepicker.less"; diff --git a/templates/admin/default/customers.html b/templates/admin/default/customers.html index d69ce970b..6a10b7801 100644 --- a/templates/admin/default/customers.html +++ b/templates/admin/default/customers.html @@ -65,7 +65,7 @@
{loop name="customer_list" type="customer" current="false" visible="*" last_order="1" backend_context="1" page={$customer_page} limit={$display_customer}} - +
{$REF}{$REF} {$COMPANY} diff --git a/templates/admin/default/modules.html b/templates/admin/default/modules.html index e69de29bb..787e00a5b 100644 --- a/templates/admin/default/modules.html +++ b/templates/admin/default/modules.html @@ -0,0 +1,272 @@ +{extends file="admin-layout.tpl"} + +{block name="page-title"}{intl l='Modules'}{/block} + +{block name="check-permissions"}admin.modules.view{/block} + +{block name="main-content"} +
+ +
+ +
+ + {loop type="auth" name="can_create" roles="ADMIN" permissions="admin.modules.install"} + + {intl l="Install a new module"} + + {/loop} +
+ + {module_include location='modules_top'} + +
+
+
+ + + + + + + + + {module_include location='modules_table_header'} + + + + + + + + + + + + {module_include location='modules_table_row'} + + + + + + + + + {module_include location='modules_table_row'} + + + + + + + + + {module_include location='modules_table_row'} + + + + +
+ {intl l='Transport modules'} +
{intl l="Name"}{intl l="Description"}{intl l="Enable/Disable"}{intl l="Actions"}
TinymceEos minima maiores doloribus mollitia perspiciatis esse iusto odit error delectus aliquid! Eius, pariatur accusantium odit quidem laboriosam. +
+ +
+
+
+ + {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.modules.documentation"} + + {/loop} + + {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.modules.edit"} + + {/loop} + + {loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.modules.delete"} + + {/loop} +
+
So colissimoEos minima maiores doloribus mollitia perspiciatis esse iusto odit error delectus aliquid +
+ +
+
+
+ + {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.modules.documentation"} + + {/loop} + + {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.modules.edit"} + + {/loop} + + {loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.modules.delete"} + + {/loop} +
+
Title metaEos minima maiores doloribus mollitia perspiciatis esse iusto odit error delectus aliquid +
+ +
+
+
+ + {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.modules.documentation"} + + {/loop} + + {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.modules.edit"} + + {/loop} + + {loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.modules.delete"} + + {/loop} +
+
+
+ +
+ + + + + + + + + {module_include location='modules_table_header'} + + + + + + + + + + + + {module_include location='modules_table_row'} + + + + + + + + + {module_include location='modules_table_row'} + + + + + + + + + {module_include location='modules_table_row'} + + + + +
+ {intl l='Delivery modules'} +
{intl l="Name"}{intl l="Description"}{intl l="Enable/Disable"}{intl l="Actions"}
TinymceEos minima maiores doloribus mollitia perspiciatis esse iusto odit error delectus aliquid! Eius, pariatur accusantium odit quidem laboriosam. +
+ +
+
+
+ + {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.modules.documentation"} + + {/loop} + + {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.modules.edit"} + + {/loop} + + {loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.modules.delete"} + + {/loop} +
+
So colissimoEos minima maiores doloribus mollitia perspiciatis esse iusto odit error delectus aliquid +
+ +
+
+
+ + {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.modules.documentation"} + + {/loop} + + {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.modules.edit"} + + {/loop} + + {loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.modules.delete"} + + {/loop} +
+
Title metaEos minima maiores doloribus mollitia perspiciatis esse iusto odit error delectus aliquid +
+ +
+
+
+ + {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.modules.documentation"} + + {/loop} + + {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.modules.edit"} + + {/loop} + + {loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.modules.delete"} + + {/loop} +
+
+
+
+
+ + {module_include location='modules_bottom'} + +
+
+ +{* Delete module confirmation dialog *} + +{capture "delete_module_dialog"} + + +{/capture} + +{include + file = "includes/generic-confirm-dialog.html" + + dialog_id = "delete_module_dialog" + dialog_title = {intl l="Delete a module"} + dialog_message = {intl l="Do you really want to delete this module ?"} + + form_action = {url path='/admin/modules/delete'} + form_content = {$smarty.capture.delete_module_dialog nofilter} +} + +{/block} + +{block name="javascript-initialization"} + + {javascripts file='assets/js/bootstrap-switch/bootstrap-switch.js'} + + {/javascripts} +{/block} \ No newline at end of file diff --git a/templates/default/order_invoice.html b/templates/default/order_invoice.html index 5fc55c0df..6a5b493a4 100644 --- a/templates/default/order_invoice.html +++ b/templates/default/order_invoice.html @@ -262,17 +262,24 @@
Choose your payment method
+ + {if $error} + {$message} + {/if} +
    {loop type="payment" name="payments" force_return="true"} + {assign "paymentModuleId" $ID} + {loop type="image" name="paymentspicture" source="module" source_id=$ID force_return="true" width="100" height="72"}
  • -
    @@ -288,7 +295,7 @@ {/form_field} Back - + {/form} diff --git a/templates/default/order_payment.html b/templates/default/order_payment.html new file mode 100644 index 000000000..884230258 --- /dev/null +++ b/templates/default/order_payment.html @@ -0,0 +1,60 @@ +{extends file="layout.tpl"} + +{block name="breadcrumb"} + +{/block} + +{block name="main-content"} +
    +
    + +

    Your Cart

    + + + +
    +
    +

    You chose to pay by : Cheque

    +
    +
    +

    Thank you for the trust you place in us.

    +

    A summary of your order email has been sent to the following address: email@toto.com

    +

    Your order will be confirmed by us upon receipt of your payment.

    + +
    +
    Order number :
    +
    PRO123456788978979
    +
    Date :
    +
    02/12/2013
    +
    Total :
    +
    $216.25
    +
    +
    +
    + + Go home + +
    + +
    +{/block} + +{block name="javascript-initialization"} + +{/block} \ No newline at end of file diff --git a/templates/default/product.html b/templates/default/product.html index 2a7e81bc4..f5224a9d2 100644 --- a/templates/default/product.html +++ b/templates/default/product.html @@ -18,8 +18,16 @@
    - - + {loop name="brand.feature" type="feature" product="{$ID}" title="brand"} + {loop name="brand.value" type="feature_value" feature="{$ID}" product="{product attr="id"}"} + + {/loop} + {/loop} + +