diff --git a/core/lib/Thelia/Action/Order.php b/core/lib/Thelia/Action/Order.php index a77a030eff..7973788786 100644 --- a/core/lib/Thelia/Action/Order.php +++ b/core/lib/Thelia/Action/Order.php @@ -33,9 +33,10 @@ use Thelia\Model\Lang as LangModel; use Thelia\Model\Map\OrderTableMap; use Thelia\Model\ModuleQuery; -use Thelia\Model\Order as OrderModel; use Thelia\Model\Order as ModelOrder; +use Thelia\Model\Order as OrderModel; use Thelia\Model\OrderAddress; +use Thelia\Model\OrderAddressQuery; use Thelia\Model\OrderProduct; use Thelia\Model\OrderProductAttributeCombination; use Thelia\Model\OrderProductTax; @@ -153,6 +154,7 @@ public function setPaymentModule(OrderEvent $event) * @param CartModel $cart * @param UserInterface $customer * @param bool $manageStock decrement stock when order is created if true + * @param bool $useOrderDefinedAddresses if true, the delivery and invoice OrderAddresses will be used instead of creating new OrderAdresses using Order::getChoosenXXXAddress() * @return ModelOrder * @throws \Exception * @throws \Propel\Runtime\Exception\PropelException @@ -164,7 +166,8 @@ protected function createOrder( LangModel $lang, CartModel $cart, UserInterface $customer, - $manageStock + $manageStock, + $useOrderDefinedAddresses = false ) { $con = Propel::getConnection( OrderTableMap::DATABASE_NAME @@ -173,11 +176,18 @@ protected function createOrder( $con->beginTransaction(); $placedOrder = $sessionOrder->copy(); + + // Be sure to create a brand new order, as copy raises the modified flag for all fields + // and will also copy order reference and id. + $placedOrder->setId(null)->setRef(null)->setNew(true); + + // Dates should be marked as not updated so that Propel will update them. + $placedOrder->resetModified(OrderTableMap::CREATED_AT); + $placedOrder->resetModified(OrderTableMap::UPDATED_AT); + $placedOrder->resetModified(OrderTableMap::VERSION_CREATED_AT); + $placedOrder->setDispatcher($dispatcher); - $deliveryAddress = AddressQuery::create()->findPk($sessionOrder->getChoosenDeliveryAddress()); - $taxCountry = $deliveryAddress->getCountry(); - $invoiceAddress = AddressQuery::create()->findPk($sessionOrder->getChoosenInvoiceAddress()); $cartItems = $cart->getCartItems(); /* fulfill order */ @@ -185,46 +195,57 @@ protected function createOrder( $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()) - ->setCellphone($deliveryAddress->getCellphone()) - ->setCountryId($deliveryAddress->getCountryId()) - ->setStateId($deliveryAddress->getStateId()) - ->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()) - ->setCellphone($invoiceAddress->getCellphone()) - ->setCountryId($invoiceAddress->getCountryId()) - ->setStateId($deliveryAddress->getStateId()) - ->save($con) - ; - - $placedOrder->setDeliveryOrderAddressId($deliveryOrderAddress->getId()); - $placedOrder->setInvoiceOrderAddressId($invoiceOrderAddress->getId()); + + if ($useOrderDefinedAddresses) { + $taxCountry = + OrderAddressQuery::create() + ->findPk($placedOrder->getDeliveryOrderAddressId()) + ->getCountry() + ; + } else { + $deliveryAddress = AddressQuery::create()->findPk($sessionOrder->getChoosenDeliveryAddress()); + $invoiceAddress = AddressQuery::create()->findPk($sessionOrder->getChoosenInvoiceAddress()); + + /* 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()) + ->setCellphone($deliveryAddress->getCellphone()) + ->setCountryId($deliveryAddress->getCountryId()) + ->setStateId($deliveryAddress->getStateId()) + ->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()) + ->setCellphone($invoiceAddress->getCellphone()) + ->setCountryId($invoiceAddress->getCountryId()) + ->setStateId($deliveryAddress->getStateId()) + ->save($con); + + $placedOrder->setDeliveryOrderAddressId($deliveryOrderAddress->getId()); + $placedOrder->setInvoiceOrderAddressId($invoiceOrderAddress->getId()); + + $taxCountry = $deliveryAddress->getCountry(); + } $placedOrder->setStatusId( OrderStatusQuery::getNotPaidStatus()->getId() @@ -361,6 +382,7 @@ protected function createOrder( /** * Create an order outside of the front-office context, e.g. manually from the back-office. + * @param OrderManualEvent $event */ public function createManual(OrderManualEvent $event) { @@ -377,7 +399,8 @@ public function createManual(OrderManualEvent $event) $event->getLang(), $event->getCart(), $event->getCustomer(), - $paymentModuleInstance->manageStockOnCreation() + $paymentModuleInstance->manageStockOnCreation(), + $event->getUseOrderDefinedAddresses() ) ); @@ -502,9 +525,8 @@ public function updateStatus(OrderEvent $event) } /** - * @param ModelOrder $order - * @param $newStatus - * @param $canceledStatus + * @param ModelOrder $order + * @param $newStatus $newStatus the new status ID * @throws \Thelia\Exception\TheliaProcessException */ public function updateQuantity(ModelOrder $order, $newStatus) diff --git a/core/lib/Thelia/Core/Event/Order/OrderManualEvent.php b/core/lib/Thelia/Core/Event/Order/OrderManualEvent.php index d9dc25c3ef..e27c122822 100644 --- a/core/lib/Thelia/Core/Event/Order/OrderManualEvent.php +++ b/core/lib/Thelia/Core/Event/Order/OrderManualEvent.php @@ -12,11 +12,11 @@ namespace Thelia\Core\Event\Order; -use Thelia\Model\Order; -use Thelia\Model\Currency; -use Thelia\Model\Lang; use Thelia\Model\Cart; +use Thelia\Model\Currency; use Thelia\Model\Customer; +use Thelia\Model\Lang; +use Thelia\Model\Order; class OrderManualEvent extends OrderEvent { @@ -24,6 +24,7 @@ class OrderManualEvent extends OrderEvent protected $lang = null; protected $cart = null; protected $customer = null; + protected $useOrderDefinedAddresses = false; /** * @param \Thelia\Model\Order $order @@ -34,8 +35,9 @@ class OrderManualEvent extends OrderEvent */ public function __construct(Order $order, Currency $currency, Lang $lang, Cart $cart, Customer $customer) { + parent::__construct($order); + $this - ->setOrder($order) ->setCurrency($currency) ->setLang($lang) ->setCart($cart) @@ -43,229 +45,97 @@ public function __construct(Order $order, Currency $currency, Lang $lang, Cart $ ; } - /** - * @param Order $order - */ - public function setOrder(Order $order) - { - $this->order = $order; - - return $this; - } - - /** - * @param Order $order - */ - public function setPlacedOrder(Order $order) + public function getCurrency() { - $this->placedOrder = $order; - - return $this; + return $this->currency; } /** - * @param $address + * @param Currency $currency + * @return $this */ - public function setInvoiceAddress($address) + public function setCurrency($currency) { - $this->invoiceAddress = $address; + $this->currency = $currency; return $this; } /** - * @param $address + * @return Lang */ - public function setDeliveryAddress($address) + public function getLang() { - $this->deliveryAddress = $address; - - return $this; + return $this->lang; } /** - * @param $module + * @param Lang $lang + * @return $this */ - public function setDeliveryModule($module) + public function setLang($lang) { - $this->deliveryModule = $module; + $this->lang = $lang; return $this; } /** - * @param $module + * @return Cart */ - public function setPaymentModule($module) + public function getCart() { - $this->paymentModule = $module; - - return $this; + return $this->cart; } /** - * @param $postage + * @param Cart $cart + * @return $this */ - public function setPostage($postage) + public function setCart($cart) { - $this->postage = $postage; + $this->cart = $cart; return $this; } /** - * @param $ref + * @return Customer */ - public function setRef($ref) + public function getCustomer() { - $this->ref = $ref; - - return $this; + return $this->customer; } /** - * @param $status + * @param Customer $customer + * @return $this */ - public function setStatus($status) + public function setCustomer($customer) { - $this->status = $status; + $this->customer = $customer; return $this; } /** - * @param $deliveryRef - */ - public function setDeliveryRef($deliveryRef) - { - $this->deliveryRef = $deliveryRef; - } - - /** - * @return null|Order - */ - public function getOrder() - { - return $this->order; - } - - /** - * @return null|Order - */ - public function getPlacedOrder() - { - return $this->placedOrder; - } - - /** - * @return null|int - */ - public function getInvoiceAddress() - { - return $this->invoiceAddress; - } - - /** - * @return null|int - */ - public function getDeliveryAddress() - { - return $this->deliveryAddress; - } - - /** - * @return null|int - */ - public function getDeliveryModule() - { - return $this->deliveryModule; - } - - /** - * @return null|int - */ - public function getPaymentModule() - { - return $this->paymentModule; - } - - /** - * @return null|int + * @return boolean */ - public function getPostage() + public function getUseOrderDefinedAddresses() { - return $this->postage; + return $this->useOrderDefinedAddresses; } /** - * @return null|int + * If true, the order will be created using the delivery and invoice addresses defined in $this->order instead of + * creating new OrderAdresses using the Order::getChoosenXXXAddress(). + * + * @param boolean $useOrderDefinedAddresses + * @return $this */ - public function getRef() - { - return $this->ref; - } - - /** - * @return null|int - */ - public function getStatus() - { - return $this->status; - } - - /** - * @return null|string - */ - public function getDeliveryRef() - { - return $this->deliveryRef; - } - - public function getCurrency() - { - return $this->currency; - } - - public function setCurrency($currency) - { - $this->currency = $currency; - - return $this; - } - - public function getLang() + public function setUseOrderDefinedAddresses($useOrderDefinedAddresses) { - return $this->lang; - } - - public function setLang($lang) - { - $this->lang = $lang; - - return $this; - } - - public function getCart() - { - return $this->cart; - } - - public function setCart($cart) - { - $this->cart = $cart; - - return $this; - } - - public function getCustomer() - { - return $this->customer; - } - - public function setCustomer($customer) - { - $this->customer = $customer; - + $this->useOrderDefinedAddresses = $useOrderDefinedAddresses; return $this; } } diff --git a/core/lib/Thelia/Model/Order.php b/core/lib/Thelia/Model/Order.php index 70734ab6ef..bf2fe70b80 100644 --- a/core/lib/Thelia/Model/Order.php +++ b/core/lib/Thelia/Model/Order.php @@ -15,13 +15,15 @@ class Order extends BaseOrder { use ModelEventDispatcherTrait; + /** @var int|null */ protected $choosenDeliveryAddress = null; + /** @var int|null */ protected $choosenInvoiceAddress = null; protected $disableVersioning = false; /** - * @param Address $choosenDeliveryAddress + * @param int $choosenDeliveryAddress the choosen delivery address ID * @return $this */ public function setChoosenDeliveryAddress($choosenDeliveryAddress) @@ -57,7 +59,7 @@ public function isVersioningNecessary($con = null) } /** - * @return Address + * @return int|null the choosen delivery address ID */ public function getChoosenDeliveryAddress() { @@ -65,7 +67,7 @@ public function getChoosenDeliveryAddress() } /** - * @param Address $choosenInvoiceAddress + * @param int $choosenInvoiceAddress the choosen invoice address * @return $this */ public function setChoosenInvoiceAddress($choosenInvoiceAddress) @@ -76,7 +78,7 @@ public function setChoosenInvoiceAddress($choosenInvoiceAddress) } /** - * @return Address + * @return int|null the choosen invoice address ID */ public function getChoosenInvoiceAddress() { diff --git a/tests/phpunit/Thelia/Tests/Action/OrderTest.php b/tests/phpunit/Thelia/Tests/Action/OrderTest.php index b99722a89e..8ad176a76f 100644 --- a/tests/phpunit/Thelia/Tests/Action/OrderTest.php +++ b/tests/phpunit/Thelia/Tests/Action/OrderTest.php @@ -18,6 +18,7 @@ use Thelia\Action\Order; use Thelia\Core\Event\Order\OrderAddressEvent; use Thelia\Core\Event\Order\OrderEvent; +use Thelia\Core\Event\Order\OrderManualEvent; use Thelia\Core\HttpFoundation\Request; use Thelia\Core\HttpFoundation\Session\Session; use Thelia\Core\Security\SecurityContext; @@ -392,6 +393,116 @@ public function testCreate() return $placedOrder; } + /** + * @depends testCreate + * + * @param OrderModel $order + */ + public function testCreateManual(OrderModel $order) + { + $orderCopy = $order->copy(); + + $validDeliveryAddress = AddressQuery::create()->findOneByCustomerId($this->customer->getId()); + $validInvoiceAddress = AddressQuery::create()->filterById($validDeliveryAddress->getId(), Criteria::NOT_EQUAL)->findOneByCustomerId($this->customer->getId()); + + $orderManuelEvent = new OrderManualEvent( + $orderCopy, + $this->cart->getCurrency(), + $this->request->getSession()->getLang(), + $this->cart, + $this->customer + ); + $orderManuelEvent->setDispatcher($this->orderEvent->getDispatcher()); + $orderManuelEvent->getOrder()->setChoosenDeliveryAddress($validDeliveryAddress->getId()); + $orderManuelEvent->getOrder()->setChoosenInvoiceAddress($validInvoiceAddress->getId()); + + $deliveryModuleId = $orderCopy->getDeliveryModuleId(); + $paymentModuleId = $orderCopy->getPaymentModuleId(); + + $this->orderAction->createManual($orderManuelEvent); + + $placedOrder = $orderManuelEvent->getPlacedOrder(); + + $this->assertNotNull($placedOrder); + $this->assertNotNull($placedOrder->getId()); + + /* check customer */ + $this->assertEquals($this->customer->getId(), $placedOrder->getCustomerId(), 'customer i does not match'); + + /* check delivery address */ + $deliveryOrderAddress = $placedOrder->getOrderAddressRelatedByDeliveryOrderAddressId(); + $this->assertEquals($validDeliveryAddress->getCustomerTitle()->getId(), $deliveryOrderAddress->getCustomerTitleId(), 'delivery address title does not match'); + $this->assertEquals($validDeliveryAddress->getCompany(), $deliveryOrderAddress->getCompany(), 'delivery address company does not match'); + $this->assertEquals($validDeliveryAddress->getFirstname(), $deliveryOrderAddress->getFirstname(), 'delivery address fistname does not match'); + $this->assertEquals($validDeliveryAddress->getLastname(), $deliveryOrderAddress->getLastname(), 'delivery address lastname does not match'); + $this->assertEquals($validDeliveryAddress->getAddress1(), $deliveryOrderAddress->getAddress1(), 'delivery address address1 does not match'); + $this->assertEquals($validDeliveryAddress->getAddress2(), $deliveryOrderAddress->getAddress2(), 'delivery address address2 does not match'); + $this->assertEquals($validDeliveryAddress->getAddress3(), $deliveryOrderAddress->getAddress3(), 'delivery address address3 does not match'); + $this->assertEquals($validDeliveryAddress->getZipcode(), $deliveryOrderAddress->getZipcode(), 'delivery address zipcode does not match'); + $this->assertEquals($validDeliveryAddress->getCity(), $deliveryOrderAddress->getCity(), 'delivery address city does not match'); + $this->assertEquals($validDeliveryAddress->getPhone(), $deliveryOrderAddress->getPhone(), 'delivery address phone does not match'); + $this->assertEquals($validDeliveryAddress->getCountryId(), $deliveryOrderAddress->getCountryId(), 'delivery address country does not match'); + + /* check invoice address */ + $invoiceOrderAddress = $placedOrder->getOrderAddressRelatedByInvoiceOrderAddressId(); + $this->assertEquals($validInvoiceAddress->getCustomerTitle()->getId(), $invoiceOrderAddress->getCustomerTitleId(), 'invoice address title does not match'); + $this->assertEquals($validInvoiceAddress->getCompany(), $invoiceOrderAddress->getCompany(), 'invoice address company does not match'); + $this->assertEquals($validInvoiceAddress->getFirstname(), $invoiceOrderAddress->getFirstname(), 'invoice address fistname does not match'); + $this->assertEquals($validInvoiceAddress->getLastname(), $invoiceOrderAddress->getLastname(), 'invoice address lastname does not match'); + $this->assertEquals($validInvoiceAddress->getAddress1(), $invoiceOrderAddress->getAddress1(), 'invoice address address1 does not match'); + $this->assertEquals($validInvoiceAddress->getAddress2(), $invoiceOrderAddress->getAddress2(), 'invoice address address2 does not match'); + $this->assertEquals($validInvoiceAddress->getAddress3(), $invoiceOrderAddress->getAddress3(), 'invoice address address3 does not match'); + $this->assertEquals($validInvoiceAddress->getZipcode(), $invoiceOrderAddress->getZipcode(), 'invoice address zipcode does not match'); + $this->assertEquals($validInvoiceAddress->getCity(), $invoiceOrderAddress->getCity(), 'invoice address city does not match'); + $this->assertEquals($validInvoiceAddress->getPhone(), $invoiceOrderAddress->getPhone(), 'invoice address phone does not match'); + $this->assertEquals($validInvoiceAddress->getCountryId(), $invoiceOrderAddress->getCountryId(), 'invoice address country does not match'); + + /* check currency */ + $this->assertEquals($this->cart->getCurrencyId(), $placedOrder->getCurrencyId(), 'currency id does not match'); + $this->assertEquals($this->cart->getCurrency()->getRate(), $placedOrder->getCurrencyRate(), 'currency rate does not match'); + + /* check delivery module */ + $this->assertEquals(20, $placedOrder->getPostage(), 'postage does not match'); + $this->assertEquals($deliveryModuleId, $placedOrder->getDeliveryModuleId(), 'delivery module does not match'); + + /* check payment module */ + $this->assertEquals($paymentModuleId, $placedOrder->getPaymentModuleId(), 'payment module does not match'); + + /* check status */ + $this->assertEquals(OrderStatus::CODE_NOT_PAID, $placedOrder->getOrderStatus()->getCode(), 'status does not match'); + + /* check lang */ + $this->assertEquals($this->request->getSession()->getLang()->getId(), $placedOrder->getLangId(), 'lang does not match'); + + + // without address duplication + $copyOrder = $order->copy(); + + $orderManuelEvent + ->setOrder($copyOrder) + ->setUseOrderDefinedAddresses(true); + + $validDeliveryAddressId = $orderCopy->getDeliveryOrderAddressId(); + $validInvoiceAddressId = $orderCopy->getInvoiceOrderAddressId(); + + $this->orderAction->createManual($orderManuelEvent); + + $placedOrder = $orderManuelEvent->getPlacedOrder(); + + $this->assertNotNull($placedOrder); + $this->assertNotNull($placedOrder->getId()); + + /* check delivery address */ + $deliveryOrderAddress = $placedOrder->getOrderAddressRelatedByDeliveryOrderAddressId(); + $this->assertEquals($validDeliveryAddressId, $deliveryOrderAddress->getId(), 'delivery address title does not match'); + + /* check invoice address */ + $invoiceOrderAddress = $placedOrder->getOrderAddressRelatedByInvoiceOrderAddressId(); + $this->assertEquals($validInvoiceAddressId, $invoiceOrderAddress->getId(), 'invoice address title does not match'); + + return $placedOrder; + } + /** * @depends testCreate *