diff --git a/core/lib/Thelia/Action/Cart.php b/core/lib/Thelia/Action/Cart.php index 6c783f196..a9cdb66dc 100644 --- a/core/lib/Thelia/Action/Cart.php +++ b/core/lib/Thelia/Action/Cart.php @@ -15,12 +15,14 @@ namespace Thelia\Action; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Thelia\Core\Event\Cart\CartEvent; +use Thelia\Core\Event\Currency\CurrencyChangeEvent; use Thelia\Core\Event\TheliaEvents; -use Thelia\Model\ProductPrice; -use Thelia\Model\ProductPriceQuery; +use Thelia\Model\Base\ProductSaleElementsQuery; +use Thelia\Model\Currency; use Thelia\Model\CartItem; use Thelia\Model\CartItemQuery; use Thelia\Model\ConfigQuery; +use Thelia\Model\Tools\ProductPriceTools; /** * @@ -32,6 +34,7 @@ use Thelia\Model\ConfigQuery; */ class Cart extends BaseAction implements EventSubscriberInterface { + /** * * add an article in the current cart @@ -44,6 +47,7 @@ class Cart extends BaseAction implements EventSubscriberInterface $newness = $event->getNewness(); $append = $event->getAppend(); $quantity = $event->getQuantity(); + $currency = $cart->getCurrency(); $productSaleElementsId = $event->getProductSaleElementsId(); $productId = $event->getProduct(); @@ -51,13 +55,16 @@ class Cart extends BaseAction implements EventSubscriberInterface $cartItem = $this->findItem($cart->getId(), $productId, $productSaleElementsId); if ($cartItem === null || $newness) { - $productPrice = ProductPriceQuery::create() - ->filterByProductSaleElementsId($productSaleElementsId) - ->findOne(); - $event->setCartItem( - $this->doAddItem($event->getDispatcher(), $cart, $productId, $productPrice->getProductSaleElements(), $quantity, $productPrice) - ); + $productSaleElements = ProductSaleElementsQuery::create() + ->findPk($productSaleElementsId); + + if (null !== $productSaleElements) { + $productPrices = $productSaleElements->getPricesByCurrency($currency); + $event->setCartItem( + $this->doAddItem($event->getDispatcher(), $cart, $productId, $productSaleElements, $quantity, $productPrices) + ); + } } if ($append && $cartItem !== null) { @@ -125,6 +132,45 @@ class Cart extends BaseAction implements EventSubscriberInterface } } + public function updateCart(CurrencyChangeEvent $event) + { + $session = $event->getRequest()->getSession(); + $cart = $session->getCart(); + if (null !== $cart) { + $this->updateCartPrices($cart, $event->getCurrency()); + } + } + + /** + * + * Refresh article's price + * + * @param \Thelia\Model\Cart $cart + * @param \Thelia\Model\Currency $currency + */ + public function updateCartPrices(\Thelia\Model\Cart $cart, Currency $currency) + { + + // cart item + foreach ($cart->getCartItems() as $cartItem) { + $productSaleElements = $cartItem->getProductSaleElements(); + + $productPrice = $productSaleElements->getPricesByCurrency($currency); + + $cartItem + ->setPrice($productPrice->getPrice()) + ->setPromoPrice($productPrice->getPromoPrice()); + + $cartItem->save(); + } + + // update the currency cart + $cart->setCurrencyId($currency->getId()); + $cart->save(); + + } + + /** * Returns an array of event names this subscriber wants to listen to. * @@ -152,6 +198,7 @@ class Cart extends BaseAction implements EventSubscriberInterface TheliaEvents::CART_DELETEITEM => array("deleteItem", 128), TheliaEvents::CART_UPDATEITEM => array("changeItem", 128), TheliaEvents::CART_CLEAR => array("clear", 128), + TheliaEvents::CHANGE_DEFAULT_CURRENCY => array("updateCart", 128), ); } @@ -175,15 +222,16 @@ class Cart extends BaseAction implements EventSubscriberInterface /** * try to attach a new item to an existing cart * - * @param \Thelia\Model\Cart $cart - * @param int $productId - * @param \Thelia\Model\ProductSaleElements $productSaleElements - * @param float $quantity - * @param ProductPrice $productPrice + * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $dispatcher + * @param \Thelia\Model\Cart $cart + * @param int $productId + * @param \Thelia\Model\ProductSaleElements $productSaleElements + * @param float $quantity + * @param ProductPriceTools $productPrices * * @return CartItem */ - protected function doAddItem(EventDispatcherInterface $dispatcher, \Thelia\Model\Cart $cart, $productId, \Thelia\Model\ProductSaleElements $productSaleElements, $quantity, ProductPrice $productPrice) + protected function doAddItem(EventDispatcherInterface $dispatcher, \Thelia\Model\Cart $cart, $productId, \Thelia\Model\ProductSaleElements $productSaleElements, $quantity, ProductPriceTools $productPrices) { $cartItem = new CartItem(); $cartItem->setDisptacher($dispatcher); @@ -192,8 +240,8 @@ class Cart extends BaseAction implements EventSubscriberInterface ->setProductId($productId) ->setProductSaleElementsId($productSaleElements->getId()) ->setQuantity($quantity) - ->setPrice($productPrice->getPrice()) - ->setPromoPrice($productPrice->getPromoPrice()) + ->setPrice($productPrices->getPrice()) + ->setPromoPrice($productPrices->getPromoPrice()) ->setPromo($productSaleElements->getPromo()) ->setPriceEndOfLife(time() + ConfigQuery::read("cart.priceEOF", 60*60*24*30)) ->save(); diff --git a/core/lib/Thelia/Cart/CartTrait.php b/core/lib/Thelia/Cart/CartTrait.php index 8cc837a36..9c969683d 100644 --- a/core/lib/Thelia/Cart/CartTrait.php +++ b/core/lib/Thelia/Cart/CartTrait.php @@ -89,6 +89,7 @@ trait CartTrait { $cart = new CartModel(); $cart->setToken($this->generateCookie($session)); + $cart->setCurrency($session->getCurrency(true)); if (null !== $customer = $session->getCustomerUser()) { $cart->setCustomer($customer); diff --git a/core/lib/Thelia/Controller/Admin/ConfigurationController.php b/core/lib/Thelia/Controller/Admin/ConfigurationController.php index 5d091a976..88c828561 100644 --- a/core/lib/Thelia/Controller/Admin/ConfigurationController.php +++ b/core/lib/Thelia/Controller/Admin/ConfigurationController.php @@ -15,7 +15,6 @@ namespace Thelia\Controller\Admin; use Thelia\Core\Security\AccessManager; use Thelia\Core\Security\Resource\AdminResources; - /** * Class ConfigurationController * @package Thelia\Controller\Admin @@ -31,4 +30,4 @@ class ConfigurationController extends BaseAdminController return $this->render('configuration'); } -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Controller/Admin/CustomerExportController.php b/core/lib/Thelia/Controller/Admin/CustomerExportController.php index b4a6f1448..5e9900dba 100644 --- a/core/lib/Thelia/Controller/Admin/CustomerExportController.php +++ b/core/lib/Thelia/Controller/Admin/CustomerExportController.php @@ -15,7 +15,6 @@ namespace Thelia\Controller\Admin; use Thelia\Core\HttpFoundation\Response; use Thelia\Core\Security\AccessManager; use Thelia\Core\Security\Resource\AdminResources; -use Thelia\Model\CustomerQuery; use Thelia\Model\NewsletterQuery; /** @@ -64,4 +63,4 @@ class CustomerExportController extends BaseAdminController } -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Controller/Admin/ExportController.php b/core/lib/Thelia/Controller/Admin/ExportController.php index 7bdcd401d..279ed8b4c 100644 --- a/core/lib/Thelia/Controller/Admin/ExportController.php +++ b/core/lib/Thelia/Controller/Admin/ExportController.php @@ -15,7 +15,6 @@ namespace Thelia\Controller\Admin; use Thelia\Core\Security\AccessManager; use Thelia\Core\Security\Resource\AdminResources; - /** * Class ExportController * @package Thelia\Controller\Admin @@ -32,4 +31,4 @@ class ExportController extends BaseAdminController return $this->render('export'); } -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Controller/Admin/ToolsController.php b/core/lib/Thelia/Controller/Admin/ToolsController.php index 0f99ded04..9d19cccd9 100644 --- a/core/lib/Thelia/Controller/Admin/ToolsController.php +++ b/core/lib/Thelia/Controller/Admin/ToolsController.php @@ -15,7 +15,6 @@ namespace Thelia\Controller\Admin; use Thelia\Core\Security\AccessManager; use Thelia\Core\Security\Resource\AdminResources; - /** * Class ToolsController * @package Thelia\Controller\Admin @@ -31,4 +30,4 @@ class ToolsController extends BaseAdminController return $this->render('tools'); } -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Controller/Admin/TranslationsController.php b/core/lib/Thelia/Controller/Admin/TranslationsController.php index f28ea5792..93aab31cb 100644 --- a/core/lib/Thelia/Controller/Admin/TranslationsController.php +++ b/core/lib/Thelia/Controller/Admin/TranslationsController.php @@ -16,7 +16,6 @@ use Symfony\Component\Finder\Finder; use Thelia\Core\Security\Resource\AdminResources; use Thelia\Core\Security\AccessManager; use Thelia\Core\Translation\Translator; -use Thelia\Log\Tlog; use Thelia\Model\Module; use Thelia\Model\ModuleQuery; use Thelia\Core\Template\TemplateHelper; @@ -147,8 +146,7 @@ class TranslationsController extends BaseAdminController ; $hasAdminIncludes = $finder->count() > 0; - } - catch (\InvalidArgumentException $ex) { + } catch (\InvalidArgumentException $ex) { $hasAdminIncludes = false; } diff --git a/core/lib/Thelia/Core/Event/Currency/CurrencyChangeEvent.php b/core/lib/Thelia/Core/Event/Currency/CurrencyChangeEvent.php new file mode 100644 index 000000000..75058d45a --- /dev/null +++ b/core/lib/Thelia/Core/Event/Currency/CurrencyChangeEvent.php @@ -0,0 +1,52 @@ + + */ +class CurrencyChangeEvent extends CurrencyEvent +{ + /** @var Request $request */ + protected $request; + + public function __construct(Currency $currency = null, Request $request = null) + { + parent::__construct($currency); + $this->setRequest($request); + } + + /** + * @param Request $request + */ + public function setRequest(Request $request) + { + $this->request = $request; + + return $this; + } + + /** + * @return Request + */ + public function getRequest() + { + return $this->request; + } + +} diff --git a/core/lib/Thelia/Core/Template/Element/BaseLoop.php b/core/lib/Thelia/Core/Template/Element/BaseLoop.php index 2ee3c6ff7..1038541de 100644 --- a/core/lib/Thelia/Core/Template/Element/BaseLoop.php +++ b/core/lib/Thelia/Core/Template/Element/BaseLoop.php @@ -184,7 +184,7 @@ abstract class BaseLoop '%name' => $loopName ] ); - } else if ($value === '') { + } elseif ($value === '') { if (!$argument->empty) { /* check if empty */ $faultActor[] = $argument->name; diff --git a/core/lib/Thelia/Core/Template/TemplateHelper.php b/core/lib/Thelia/Core/Template/TemplateHelper.php index abb0d8649..ef6737890 100644 --- a/core/lib/Thelia/Core/Template/TemplateHelper.php +++ b/core/lib/Thelia/Core/Template/TemplateHelper.php @@ -50,11 +50,11 @@ class TemplateHelper /** * Check if a template definition is the current active template * - * @param TemplateDefinition $tplDefinition - * @return bool true is the given template is the active template + * @param TemplateDefinition $tplDefinition + * @return bool true is the given template is the active template */ - public function isActive(TemplateDefinition $tplDefinition) { - + public function isActive(TemplateDefinition $tplDefinition) + { switch ($tplDefinition->getType()) { case TemplateDefinition::FRONT_OFFICE: $tplVar = 'active-front-template'; diff --git a/core/lib/Thelia/Core/TheliaHttpKernel.php b/core/lib/Thelia/Core/TheliaHttpKernel.php index 126afec14..060871a22 100644 --- a/core/lib/Thelia/Core/TheliaHttpKernel.php +++ b/core/lib/Thelia/Core/TheliaHttpKernel.php @@ -22,7 +22,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpFoundation\Session; -use Thelia\Core\Event\Currency\CurrencyEvent; +use Thelia\Core\Event\Currency\CurrencyChangeEvent; use Thelia\Core\Event\TheliaEvents; use Thelia\Model; @@ -142,7 +142,7 @@ class TheliaHttpKernel extends HttpKernel if ($request->query->has("currency")) { $currency = Model\CurrencyQuery::create()->findOneByCode($request->query->get("currency")); if ($currency) { - $this->container->get("event_dispatcher")->dispatch(TheliaEvents::CHANGE_DEFAULT_CURRENCY, new CurrencyEvent($currency)); + $this->container->get("event_dispatcher")->dispatch(TheliaEvents::CHANGE_DEFAULT_CURRENCY, new CurrencyChangeEvent($currency, $request)); } } else { $currency = $request->getSession()->getCurrency(false); diff --git a/core/lib/Thelia/Model/Product.php b/core/lib/Thelia/Model/Product.php index a8d342f0e..2eb3fb584 100644 --- a/core/lib/Thelia/Model/Product.php +++ b/core/lib/Thelia/Model/Product.php @@ -214,6 +214,7 @@ class Product extends BaseProduct ->setPromoPrice($salePrice) ->setPrice($basePrice) ->setCurrencyId($currencyId) + ->setFromDefaultCurrency(false) ->save($con) ; diff --git a/core/lib/Thelia/Model/ProductSaleElements.php b/core/lib/Thelia/Model/ProductSaleElements.php index ec485d7a7..f2b960343 100644 --- a/core/lib/Thelia/Model/ProductSaleElements.php +++ b/core/lib/Thelia/Model/ProductSaleElements.php @@ -3,6 +3,7 @@ namespace Thelia\Model; use Thelia\Model\Base\ProductSaleElements as BaseProductSaleElements; +use Thelia\Model\Tools\ProductPriceTools; use Thelia\TaxEngine\Calculator; class ProductSaleElements extends BaseProductSaleElements @@ -42,4 +43,51 @@ class ProductSaleElements extends BaseProductSaleElements return round($taxCalculator->load($this->getProduct(), $country)->getTaxedPrice($this->getPromoPrice()), 2); } + + /** + * Get product prices for a specific currency. + * + * When the currency is not the default currency, the product prices for this currency is : + * - calculated according to the product price of the default currency. It happens when no product price exists for + * the currency or when the `from_default_currency` flag is set to `true` + * - set directly in the product price when `from_default_currency` is set to `false` + * + * @param Currency $currency + * @return ProductPriceTools + * @throws \RuntimeException + */ + public function getPricesByCurrency($currency) + { + $defaultCurrency = Currency::getDefaultCurrency(); + + $productPrice = ProductPriceQuery::create() + ->filterByProductSaleElementsId($this->getId()) + ->filterByCurrencyId($currency->getId()) + ->findOne(); + + $price = 0.0; + $promoPrice = 0.0; + + if (null === $productPrice || $productPrice->getFromDefaultCurrency()) { + // need to calculate the prices based on the product prices for the default currency + $productPrice = ProductPriceQuery::create() + ->filterByProductSaleElementsId($this->getId()) + ->filterByCurrencyId($defaultCurrency->getId()) + ->findOne(); + if (null !== $productPrice) { + $price = $productPrice->getPrice() * $currency->getRate() / $defaultCurrency->getRate(); + $promoPrice = $productPrice->getPromoPrice() * $currency->getRate() / $defaultCurrency->getRate(); + } else { + throw new \RuntimeException('Cannot find product prices for currency id: `' . $currency->getId() . '`'); + } + } else { + $price = $productPrice->getPrice(); + $promoPrice = $productPrice->getPromoPrice(); + } + + $productPriceTools = new ProductPriceTools($price, $promoPrice); + + return $productPriceTools; + } + } diff --git a/core/lib/Thelia/Model/Tools/ProductPriceTools.php b/core/lib/Thelia/Model/Tools/ProductPriceTools.php new file mode 100644 index 000000000..d51a27982 --- /dev/null +++ b/core/lib/Thelia/Model/Tools/ProductPriceTools.php @@ -0,0 +1,60 @@ + + */ +class ProductPriceTools +{ + /** + * The value for the price field. + * + * @var double + */ + protected $price; + + /** + * The value for the promoPrice field. + * + * @var double + */ + protected $promoPrice; + + public function __construct($price, $promoPrice) + { + $this->price = $price; + $this->promoPrice = $promoPrice; + } + + /** + * @return float + */ + public function getPrice() + { + return $this->price; + } + + /** + * @return float + */ + public function getPromoPrice() + { + return $this->promoPrice; + } + +}