diff --git a/core/lib/Thelia/Config/Resources/smarty-plugin.xml b/core/lib/Thelia/Config/Resources/smarty-plugin.xml index 903bb114e..222874903 100644 --- a/core/lib/Thelia/Config/Resources/smarty-plugin.xml +++ b/core/lib/Thelia/Config/Resources/smarty-plugin.xml @@ -38,6 +38,11 @@ + + + + + diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/CartPostage.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/CartPostage.php new file mode 100644 index 000000000..9bf98dd43 --- /dev/null +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/CartPostage.php @@ -0,0 +1,208 @@ +container = $container; + + $this->request = $container->get('request'); + } + + /** + * Get postage amount for cart + * + * @param array $params Block parameters + * @param mixed $content Block content + * @param \Smarty_Internal_Template $template Template + * @param bool $repeat Control how many times + * the block is displayed + * + * @return mixed + */ + public function postage($params, $content, $template, &$repeat) + { + + if (! $repeat) { + return (null !== $this->countryId) ? $content : ""; + } + + $customer = $this->request->getSession()->getCustomerUser(); + $country = $this->getDeliveryCountry($customer); + + if (null !== $country) { + $this->countryId = $country->getId(); + // try to get the cheapest delivery for this country + $this->getCheapestDelivery($country); + } + + $template->assign('country_id', $this->countryId); + $template->assign('delivery_id', $this->deliveryId); + $template->assign('postage', $this->postage ?: 0.0); + $template->assign('is_customizable', $this->isCustomizable); + } + + /** + * Retrieve the delivery country for a customer + * + * The rules : + * - the country of the delivery address of the customer related to the + * cart if it exists + * - the country saved in cookie if customer have changed + * the default country + * - the default country for the shop if it exists + * + * + * @param \Thelia\Model\Customer $customer + * @return \Thelia\Model\Country + */ + protected function getDeliveryCountry(Customer $customer = null) + { + + // get country from customer addresses + if (null !== $customer) { + $address = AddressQuery::create() + ->filterByCustomerId($customer->getId()) + ->filterByIsDefault(1) + ->findOne() + ; + + if (null !== $address) { + $this->isCustomizable = false; + + return $address->getCountry(); + } + } + + // get country from cookie + $cookieName = ConfigQuery::read('front_cart_country_cookie_name', 'fcccn'); + if ($this->request->cookies->has($cookieName)) { + $cookieVal = $this->request->cookies->getInt($cookieName, 0); + if (0 !== $cookieVal) { + $country = CountryQuery::create()->findPk($cookieVal); + if (null !== $country) { + return $country; + } + } + } + + // get default country for store. + try { + $country = Country::getDefaultCountry(); + + return $country; + } catch (\LogicException $e) { + ; + } + + return null; + + } + + /** + * Retrieve the cheapest delivery for country + * + * @param \Thelia\Model\Country $country + * @return DeliveryModuleInterface + */ + protected function getCheapestDelivery(Country $country) + { + + $deliveryModules = ModuleQuery::create() + ->filterByActivate(1) + ->filterByType(BaseModule::DELIVERY_MODULE_TYPE, Criteria::EQUAL) + ->find(); + ; + + foreach ($deliveryModules as $deliveryModule) { + + /** @var DeliveryModuleInterface $moduleInstance */ + $moduleInstance = $this->container->get(sprintf('module.%s', $deliveryModule->getCode())); + + if (false === $moduleInstance instanceof DeliveryModuleInterface) { + throw new \RuntimeException(sprintf("delivery module %s is not a Thelia\Module\DeliveryModuleInterface", $deliveryModule->getCode())); + } + + try { + // Check if module is valid, by calling isValidDelivery(), + // or catching a DeliveryException. + if ($moduleInstance->isValidDelivery($country)) { + + $postage = $moduleInstance->getPostage($country); + if (null === $this->postage || $this->postage > $postage) { + $this->postage = $postage; + $this->deliveryId = $deliveryModule->getId(); + } + } + } catch (DeliveryException $ex) { + // Module is not available + } + + } + + } + + /** + * Defines the various smarty plugins handled by this class + * + * @return SmartyPluginDescriptor[] smarty plugin descriptors + */ + public function getPluginDescriptors() + { + return array( + new SmartyPluginDescriptor('block', 'postage', $this, 'postage') + ); + } +} diff --git a/core/lib/Thelia/Tools/Redirect.php b/core/lib/Thelia/Tools/Redirect.php index e183079d5..faad58b2e 100644 --- a/core/lib/Thelia/Tools/Redirect.php +++ b/core/lib/Thelia/Tools/Redirect.php @@ -12,16 +12,22 @@ namespace Thelia\Tools; +use Symfony\Component\HttpFoundation\Cookie; use Symfony\Component\HttpFoundation\RedirectResponse; use Thelia\Log\Tlog; class Redirect { - public static function exec($url, $status = 302) + public static function exec($url, $status = 302, $cookies = array()) { if (false == Tlog::getInstance()->showRedirect($url)) { $response = new RedirectResponse($url, $status); - + foreach ($cookies as $cookie) { + if (!$cookie instanceof Cookie) { + throw new \InvalidArgumentException(sprintf('Third parameter is not a valid Cookie object.')); + } + $response->headers->setCookie($cookie); + } $response->send(); } } diff --git a/local/modules/Front/Config/front.xml b/local/modules/Front/Config/front.xml index 7d78aa46d..319d9b4c2 100644 --- a/local/modules/Front/Config/front.xml +++ b/local/modules/Front/Config/front.xml @@ -123,6 +123,11 @@ Front\Controller\CartController::changeItem cart + + + Front\Controller\CartController::changeCountry + cart + diff --git a/local/modules/Front/Controller/CartController.php b/local/modules/Front/Controller/CartController.php index ceda20751..587866950 100644 --- a/local/modules/Front/Controller/CartController.php +++ b/local/modules/Front/Controller/CartController.php @@ -23,6 +23,7 @@ namespace Front\Controller; use Propel\Runtime\Exception\PropelException; +use Symfony\Component\HttpFoundation\Cookie; use Symfony\Component\HttpFoundation\Request; use Thelia\Controller\Front\BaseFrontController; use Thelia\Core\Event\Cart\CartEvent; @@ -32,7 +33,9 @@ use Thelia\Form\CartAdd; use Thelia\Form\Exception\FormValidationException; use Thelia\Log\Tlog; use Thelia\Model\AddressQuery; +use Thelia\Model\ConfigQuery; use Thelia\Module\Exception\DeliveryException; +use Thelia\Tools\URL; class CartController extends BaseFrontController { @@ -116,6 +119,19 @@ class CartController extends BaseFrontController } + public function changeCountry() + { + $redirectUrl = URL::getInstance()->absoluteUrl("/cart"); + $deliveryId = $this->getRequest()->get("country"); + $cookieName = ConfigQuery::read('front_cart_country_cookie_name', 'fcccn'); + $cookieExpires = ConfigQuery::read('front_cart_country_cookie_expires', 2592000); + $cookieExpires = intval($cookieExpires) ?: 2592000; + + $cookie = new Cookie($cookieName, $deliveryId, time() + $cookieExpires, '/'); + + $this->redirect($redirectUrl, 302, array($cookie)); + } + /** * use Thelia\Cart\CartTrait for searching current cart or create a new one * diff --git a/setup/insert.sql b/setup/insert.sql index c53ff0a40..a8a1bb212 100644 --- a/setup/insert.sql +++ b/setup/insert.sql @@ -43,7 +43,9 @@ INSERT INTO `config` (`name`, `value`, `secured`, `hidden`, `created_at`, `updat ('thelia_major_version','2', 1, 1, NOW(), NOW()), ('thelia_minus_version','0', 1, 1, NOW(), NOW()), ('thelia_release_version','1', 1, 1, NOW(), NOW()), -('thelia_extra_version','', 1, 1, NOW(), NOW()); +('thelia_extra_version','', 1, 1, NOW(), NOW()), +('front_cart_country_cookie_name','fcccn', 1, 1, NOW(), NOW()), +('front_cart_country_cookie_expires','2592000', 1, 1, NOW(), NOW()); INSERT INTO `config_i18n` (`id`, `locale`, `title`, `description`, `chapo`, `postscriptum`) VALUES diff --git a/setup/update/2.0.1.sql b/setup/update/2.0.1.sql index f3d7be46f..cc368353a 100644 --- a/setup/update/2.0.1.sql +++ b/setup/update/2.0.1.sql @@ -6,6 +6,10 @@ UPDATE `config` SET `value`='2.0.1' WHERE `name`='thelia_version'; UPDATE `config` SET `value`='1' WHERE `name`='thelia_release_version'; UPDATE `config` SET `value`='' WHERE `name`='thelia_extra_version'; +INSERT INTO `config` (`name`, `value`, `secured`, `hidden`, `created_at`, `updated_at`) VALUES +('front_cart_country_cookie_name','fcccn', 1, 1, NOW(), NOW()); +INSERT INTO `config` (`name`, `value`, `secured`, `hidden`, `created_at`, `updated_at`) VALUES +('front_cart_country_cookie_expires','2592000', 1, 1, NOW(), NOW()); ALTER TABLE `module` ADD INDEX `idx_module_activate` (`activate`); diff --git a/templates/frontOffice/default/I18n/fr_FR.php b/templates/frontOffice/default/I18n/fr_FR.php index fef729162..ab8754e16 100644 --- a/templates/frontOffice/default/I18n/fr_FR.php +++ b/templates/frontOffice/default/I18n/fr_FR.php @@ -57,6 +57,7 @@ return array( 'Edit' => 'Editer', 'Edit this address' => 'Editer cette adresse', 'Email address' => 'Adresse e-mail', + 'Estimated shipping ' => 'Estimation des frais de port', 'Facebook' => 'Facebook', 'Follow us' => 'Suivez-nous', 'Follow us introduction' => 'Abonnez vous à nos pages', @@ -100,6 +101,7 @@ return array( 'Next product' => 'Produit suivant.', 'No Content in this folder.' => 'Aucun contenu dans ce dossier.', 'No articles currently' => 'Aucun article en ce moment', + 'No deliveries available for this cart and this country' => 'Aucun mode de livraison disponible pour ce panier et ce pays', 'No products available in this category' => 'Aucun produit dans cette catégorie.', 'No results found' => 'Aucun résultat', 'No.' => 'N°', @@ -166,6 +168,7 @@ return array( 'Secure payment' => 'Paiement sécurisé', 'Select Country' => 'Choisissez un pays', 'Select Title' => 'Civilité', + 'Select your country:' => 'Sélectionnez votre pays :', 'Send' => 'Envoyer', 'Send us a message' => 'Envoyez nous un message.', 'Shipping Tax' => 'Frais de livraison', @@ -214,7 +217,10 @@ return array( 'Your order will be confirmed by us upon receipt of your payment.' => 'Votre commande sera confirmée à réception de votre paiement.', 'Youtube' => 'Youtube', 'deliveries' => 'Livraisons', + 'for' => 'pour', 'instead of' => 'au lieu de', 'missing or invalid data' => 'Information érronée ou incomplète', 'per page' => 'par page', + 'update' => 'mettre à jour', + 'with:' => 'avec :', ); diff --git a/templates/frontOffice/default/cart.html b/templates/frontOffice/default/cart.html index bb5f644be..366ebd6fe 100644 --- a/templates/frontOffice/default/cart.html +++ b/templates/frontOffice/default/cart.html @@ -115,16 +115,56 @@ {$real_price * $QUANTITY} {currency attr="symbol"} - {/loop} + {postage} + {assign var="postageAmount" value=$postage } + + +
+

+ {intl l="Estimated shipping "} + {if $is_customizable == false} + {loop type="country" name="countryLoop" id="$country_id"} + {intl l="for"} {$TITLE} + {/loop} + {/if} +

+ {if $is_customizable} +
+ + + {intl l="update"} +
+ {/if} + {if $delivery_id != 0 } +
+ {intl l="with:"} {loop type="delivery" name="deliveryLoop" id=$delivery_id}{$TITLE} {/loop} +
+ {else} +
+ {intl l="No deliveries available for this cart and this country"} +
+ {/if} +
+ + {$postage} {currency attr="symbol"} + - + {$postage} {currency attr="symbol"} + + {/postage} - +   {intl l="Total"}
- {cart attr="total_taxed_price_without_discount"} {currency attr="symbol"} + {assign var="totalAmount" value={cart attr='total_taxed_price_without_discount'} + $postageAmount } + {$totalAmount} {currency attr="symbol"}
@@ -169,6 +209,11 @@ $("select[name=quantity]").change(function(){ $(this).parents('form').submit(); }); + $(".btn-change-country").click(function(e){ + e.preventDefault(); + var $form = $(this).parents('form'); + $form.submit(); + }) }); {/block}