diff --git a/Readme.md b/Readme.md index 1134ccb68..2a3e9fece 100755 --- a/Readme.md +++ b/Readme.md @@ -5,7 +5,7 @@ Thelia ------ [![Build Status](https://travis-ci.org/thelia/thelia.png?branch=master)](https://travis-ci.org/thelia/thelia) -[Thelia](http://thelia.net) is an open source tool for creating e-business websites and managing online content. This software is published under GPL. +[Thelia](http://thelia.net/v2) is an open source tool for creating e-business websites and managing online content. This software is published under GPL. Here is the current developping next major version. You can download this version for testing or see the code. Here is the most recent developed code for the next major version (v2). You can download this version for testing or having a look on the code (or anything you wish, respecting GPL). See http://thelia.net/v2 web site for more information. diff --git a/composer.json b/composer.json index a3395bcf5..0a4fc0629 100755 --- a/composer.json +++ b/composer.json @@ -28,7 +28,7 @@ "symfony/form": "2.2.*", "symfony/validator": "2.3.*", - "smarty/smarty": "v3.1.15", + "smarty/smarty": "v3.1.14", "kriswallsmith/assetic": "1.2.*@dev", "leafo/lessphp": "0.3.*@dev", "ptachoire/cssembed": "dev-master", diff --git a/composer.lock b/composer.lock index 0e5c079ad..f50fb4a4d 100755 --- a/composer.lock +++ b/composer.lock @@ -3,7 +3,7 @@ "This file locks the dependencies of your project to a known state", "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" ], - "hash": "9c5ea1a9fd0f8ba533c41ff3676e0970", + "hash": "852879ecc2e39e5cf283a3b1c5051a8e", "packages": [ { "name": "ensepar/html2pdf", @@ -507,11 +507,11 @@ }, { "name": "smarty/smarty", - "version": "v3.1.15", + "version": "v3.1.14", "source": { "type": "svn", "url": "http://smarty-php.googlecode.com/svn", - "reference": "/tags/v3.1.15/@4782" + "reference": "/tags/v3.1.14/@4752" }, "require": { "php": ">=5.2" @@ -547,7 +547,7 @@ "keywords": [ "templating" ], - "time": "2013-10-01 21:08:54" + "time": "2013-07-02 16:38:47" }, { "name": "swiftmailer/swiftmailer", diff --git a/core/lib/Thelia/Action/Area.php b/core/lib/Thelia/Action/Area.php new file mode 100644 index 000000000..d9173ae93 --- /dev/null +++ b/core/lib/Thelia/Action/Area.php @@ -0,0 +1,131 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Action; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Thelia\Core\Event\Area\AreaAddCountryEvent; +use Thelia\Core\Event\Area\AreaCreateEvent; +use Thelia\Core\Event\Area\AreaDeleteEvent; +use Thelia\Core\Event\Area\AreaRemoveCountryEvent; +use Thelia\Core\Event\Area\AreaUpdatePostageEvent; +use Thelia\Core\Event\TheliaEvents; +use Thelia\Model\AreaQuery; +use Thelia\Model\CountryQuery; +use Thelia\Action\BaseAction; +use Thelia\Model\Area as AreaModel; + + +/** + * Class Area + * @package Thelia\Action + * @author Manuel Raynaud + */ +class Area extends BaseAction implements EventSubscriberInterface +{ + + public function addCountry(AreaAddCountryEvent $event) + { + if (null !== $country = CountryQuery::create()->findPk($event->getCountryId())) { + $country->setDispatcher($this->getDispatcher()); + $country->setAreaId($event->getAreaId()) + ->save(); + + $event->setArea($country->getArea()); + } + } + + public function removeCountry(AreaRemoveCountryEvent $event) + { + if (null !== $country = CountryQuery::create()->findPk($event->getCountryId())) { + $country->setDispatcher($this->getDispatcher()); + $country->setAreaId(null) + ->save(); + } + } + + public function updatePostage(AreaUpdatePostageEvent $event) + { + if (null !== $area = AreaQuery::create()->findPk($event->getAreaId())) { + $area->setDispatcher($this->getDispatcher()); + $area + ->setPostage($event->getPostage()) + ->save(); + + $event->setArea($area); + } + } + + public function delete(AreaDeleteEvent $event) + { + if (null !== $area = AreaQuery::create()->findPk($event->getAreaId())) { + $area->setDispatcher($this->getDispatcher()); + $area->delete(); + + $event->setArea($area); + } + } + + public function create(AreaCreateEvent $event) + { + $area = new AreaModel(); + + $area + ->setDispatcher($this->getDispatcher()) + ->setName($event->getAreaName()) + ->save(); + + $event->setArea($area); + } + + + /** + * 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::AREA_ADD_COUNTRY => array('addCountry', 128), + TheliaEvents::AREA_REMOVE_COUNTRY => array('removeCountry', 128), + TheliaEvents::AREA_POSTAGE_UPDATE => array('updatePostage', 128), + TheliaEvents::AREA_DELETE => array('delete', 128), + TheliaEvents::AREA_CREATE => array('create', 128) + ); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Action/Country.php b/core/lib/Thelia/Action/Country.php index 9bccfcea5..69bf3c568 100644 --- a/core/lib/Thelia/Action/Country.php +++ b/core/lib/Thelia/Action/Country.php @@ -59,7 +59,19 @@ class Country extends BaseAction implements EventSubscriberInterface public function update(CountryUpdateEvent $event) { + if (null !== $country = CountryQuery::create()->findPk($event->getCountryId())) { + $country + ->setIsocode($event->getIsocode()) + ->setIsoalpha2($event->getIsoAlpha2()) + ->setIsoalpha3($event->getIsoAlpha3()) + ->setLocale($event->getLocale()) + ->setTitle($event->getTitle()) + ->setChapo($event->getChapo()) + ->setDescription($event->getDescription()) + ->save(); + $event->setCountry($country); + } } public function delete(CountryDeleteEvent $event) diff --git a/core/lib/Thelia/Action/Order.php b/core/lib/Thelia/Action/Order.php index b48f72439..eea8b82b7 100755 --- a/core/lib/Thelia/Action/Order.php +++ b/core/lib/Thelia/Action/Order.php @@ -197,6 +197,7 @@ class Order extends BaseAction implements EventSubscriberInterface $taxRuleI18n = I18n::forceI18nRetrieving($this->getSession()->getLang()->getLocale(), 'TaxRule', $product->getTaxRuleId()); $taxDetail = $product->getTaxRule()->getTaxDetail( + $product, $taxCountry, $cartItem->getPrice(), $cartItem->getPromoPrice(), diff --git a/core/lib/Thelia/Action/ShippingZone.php b/core/lib/Thelia/Action/ShippingZone.php new file mode 100644 index 000000000..517a5ca25 --- /dev/null +++ b/core/lib/Thelia/Action/ShippingZone.php @@ -0,0 +1,92 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Action; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Thelia\Core\Event\ShippingZone\ShippingZoneAddAreaEvent; +use Thelia\Core\Event\ShippingZone\ShippingZoneRemoveAreaEvent; +use Thelia\Core\Event\TheliaEvents; +use Thelia\Model\AreaDeliveryModule; +use Thelia\Model\AreaDeliveryModuleQuery; + + +/** + * Class ShippingZone + * @package Thelia\Action + * @author Manuel Raynaud + */ +class ShippingZone extends BaseAction implements EventSubscriberInterface +{ + + public function addArea(ShippingZoneAddAreaEvent $event) + { + $areaDelivery = new AreaDeliveryModule(); + + $areaDelivery + ->setAreaId($event->getAreaId()) + ->setDeliveryModuleId($event->getShoppingZoneId()) + ->save(); + } + + public function removeArea(ShippingZoneRemoveAreaEvent $event) + { + $areaDelivery = AreaDeliveryModuleQuery::create() + ->filterByAreaId($event->getAreaId()) + ->filterByDeliveryModuleId($event->getShoppingZoneId()) + ->findOne(); + + if($areaDelivery) { + $areaDelivery->delete(); + } else { + throw new \RuntimeException(sprintf('areaDeliveryModule not found with area_id = %d and delivery_module_id = %d', $event->getAreaId(), $event->getShoppingZoneId())); + } + } + + /** + * 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::SHIPPING_ZONE_ADD_AREA => array('addArea', 128), + TheliaEvents::SHIPPING_ZONE_REMOVE_AREA => array('removeArea', 128), + ); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Action/TaxRule.php b/core/lib/Thelia/Action/TaxRule.php new file mode 100644 index 000000000..4b24f8cb9 --- /dev/null +++ b/core/lib/Thelia/Action/TaxRule.php @@ -0,0 +1,150 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Action; + +use Propel\Runtime\ActiveQuery\Criteria; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Thelia\Core\Event\Tax\TaxRuleEvent; +use Thelia\Core\Event\TheliaEvents; +use Thelia\Model\TaxRuleCountry; +use Thelia\Model\TaxRuleCountryQuery; +use Thelia\Model\TaxRule as TaxRuleModel; +use Thelia\Model\TaxRuleQuery; + +class TaxRule extends BaseAction implements EventSubscriberInterface +{ + /** + * @param TaxRuleEvent $event + */ + public function create(TaxRuleEvent $event) + { + $taxRule = new TaxRuleModel(); + + $taxRule + ->setDispatcher($this->getDispatcher()) + ->setLocale($event->getLocale()) + ->setTitle($event->getTitle()) + ->setDescription($event->getDescription()) + ; + + $taxRule->save(); + + $event->setTaxRule($taxRule); + } + + /** + * @param TaxRuleEvent $event + */ + public function update(TaxRuleEvent $event) + { + if (null !== $taxRule = TaxRuleQuery::create()->findPk($event->getId())) { + + $taxRule + ->setDispatcher($this->getDispatcher()) + ->setLocale($event->getLocale()) + ->setTitle($event->getTitle()) + ->setDescription($event->getDescription()) + ->save() + ; + + + + $event->setTaxRule($taxRule); + } + } + + /** + * @param TaxRuleEvent $event + */ + public function updateTaxes(TaxRuleEvent $event) + { + if (null !== $taxRule = TaxRuleQuery::create()->findPk($event->getId())) { + + $taxList = json_decode($event->getTaxList(), true); + + /* clean the current tax rule for the countries */ + TaxRuleCountryQuery::create() + ->filterByTaxRule($taxRule) + ->filterByCountryId($event->getCountryList(), Criteria::IN) + ->delete(); + + /* for each country */ + foreach($event->getCountryList() as $country) { + $position = 1; + /* on applique les nouvelles regles */ + foreach($taxList as $tax) { + if(is_array($tax)) { + foreach($tax as $samePositionTax) { + $taxModel = new TaxRuleCountry(); + $taxModel->setTaxRule($taxRule) + ->setCountryId($country) + ->setTaxId($samePositionTax) + ->setPosition($position); + $taxModel->save(); + } + } else { + $taxModel = new TaxRuleCountry(); + $taxModel->setTaxRule($taxRule) + ->setCountryId($country) + ->setTaxId($tax) + ->setPosition($position); + $taxModel->save(); + } + $position++; + } + } + + $event->setTaxRule($taxRule); + } + } + + /** + * @param TaxRuleEvent $event + */ + public function delete(TaxRuleEvent $event) + { + if (null !== $taxRule = TaxRuleQuery::create()->findPk($event->getId())) { + + $taxRule + ->delete() + ; + + $event->setTaxRule($taxRule); + } + } + + /** + * {@inheritDoc} + */ + public static function getSubscribedEvents() + { + return array( + TheliaEvents::TAX_RULE_CREATE => array("create", 128), + TheliaEvents::TAX_RULE_UPDATE => array("update", 128), + TheliaEvents::TAX_RULE_TAXES_UPDATE => array("updateTaxes", 128), + TheliaEvents::TAX_RULE_DELETE => array("delete", 128), + + ); + } +} diff --git a/core/lib/Thelia/Config/Resources/action.xml b/core/lib/Thelia/Config/Resources/action.xml index a9b3e247d..b3bc085bf 100755 --- a/core/lib/Thelia/Config/Resources/action.xml +++ b/core/lib/Thelia/Config/Resources/action.xml @@ -106,6 +106,11 @@ + + + + + @@ -121,6 +126,16 @@ + + + + + + + + + + diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index 4c19827f2..f74fecdfc 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -7,6 +7,7 @@ + @@ -45,7 +46,9 @@ + + @@ -111,6 +114,10 @@
+ + + + @@ -119,6 +126,13 @@ + + + + + + + diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index 5df02e5bd..55ee6a90f 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -405,29 +405,6 @@ Thelia\Controller\Admin\FolderController::updatePositionAction - - - - Thelia\Controller\Admin\CountryController::defaultAction - - - - Thelia\Controller\Admin\CountryController::createAction - - - - Thelia\Controller\Admin\CountryController::updateAction - \d+ - - - - Thelia\Controller\Admin\CountryController::deleteAction - - - - Thelia\Controller\Admin\CountryController::toggleDefaultAction - - Thelia\Controller\Admin\ContentController::createAction @@ -706,21 +683,79 @@ \d+ + + Thelia\Controller\Admin\ShippingZoneController::addArea + + + + Thelia\Controller\Admin\ShippingZoneController::removeArea + + - Thelia\Controller\Admin\ShippingConfigurationController::indexAction + Thelia\Controller\Admin\AreaController::defaultAction - - Thelia\Controller\Admin\ShippingConfigurationController::updateAction - \d+ + + Thelia\Controller\Admin\AreaController::updateAction + \d+ + + + + Thelia\Controller\Admin\AreaController::deleteAction + + + + Thelia\Controller\Admin\AreaController::createAction + + + + Thelia\Controller\Admin\AreaController::updatePostageAction + \d+ + + + + Thelia\Controller\Admin\AreaController::addCountry + + + + Thelia\Controller\Admin\AreaController::removeCountry + + + + Thelia\Controller\Admin\CountryController::defaultAction + + + + Thelia\Controller\Admin\CountryController::createAction + + + + Thelia\Controller\Admin\CountryController::updateAction + \d+ + + + + Thelia\Controller\Admin\CountryController::processUpdateAction + \d+ + + + + Thelia\Controller\Admin\CountryController::deleteAction + + + + Thelia\Controller\Admin\CountryController::toggleDefaultAction + + + @@ -787,6 +822,35 @@ + + + + Thelia\Controller\Admin\TaxRuleController::defaultAction + + + + Thelia\Controller\Admin\TaxRuleController::updateAction + \d+ + + + + Thelia\Controller\Admin\TaxRuleController::createAction + + + + Thelia\Controller\Admin\TaxRuleController::processUpdateAction + + + + Thelia\Controller\Admin\TaxRuleController::processUpdateTaxesAction + + + + Thelia\Controller\Admin\TaxRuleController::deleteAction + + + + diff --git a/core/lib/Thelia/Controller/Admin/AreaController.php b/core/lib/Thelia/Controller/Admin/AreaController.php new file mode 100644 index 000000000..d6ac7918a --- /dev/null +++ b/core/lib/Thelia/Controller/Admin/AreaController.php @@ -0,0 +1,326 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Controller\Admin; + +use Thelia\Core\Event\Area\AreaAddCountryEvent; +use Thelia\Core\Event\Area\AreaCreateEvent; +use Thelia\Core\Event\Area\AreaDeleteEvent; +use Thelia\Core\Event\Area\AreaRemoveCountryEvent; +use Thelia\Core\Event\Area\AreaUpdateEvent; +use Thelia\Core\Event\Area\AreaUpdatePostageEvent; +use Thelia\Core\Event\TheliaEvents; +use Thelia\Form\Area\AreaCountryForm; +use Thelia\Form\Area\AreaCreateForm; +use Thelia\Form\Area\AreaModificationForm; +use Thelia\Form\Area\AreaPostageForm; +use Thelia\Form\Exception\FormValidationException; +use Thelia\Model\AreaQuery; + +/** + * Class AreaController + * @package Thelia\Controller\Admin + * @author Manuel Raynaud + */ +class AreaController extends AbstractCrudController +{ + + public function __construct() + { + parent::__construct( + 'area', + null, + null, + + 'admin.area.default', + 'admin.area.create', + 'admin.area.update', + 'admin.area.delete', + + TheliaEvents::AREA_CREATE, + TheliaEvents::AREA_UPDATE, + TheliaEvents::AREA_DELETE + ); + } + + protected function getAreaId() + { + return $this->getRequest()->get('area_id', 0); + } + + /** + * Return the creation form for this object + */ + protected function getCreationForm() + { + return new AreaCreateForm($this->getRequest()); + } + + /** + * Return the update form for this object + */ + protected function getUpdateForm() + { + return new AreaModificationForm($this->getRequest()); + } + + /** + * Hydrate the update form for this object, before passing it to the update template + * + * @param unknown $object + */ + protected function hydrateObjectForm($object) + { + $data = array( + 'name' => $object->getName() + ); + + return new AreaModificationForm($this->getRequest(), 'form', $data); + } + + /** + * Creates the creation event with the provided form data + * + * @param unknown $formData + * + * @return \Thelia\Core\Event\Area\AreaCreateEvent + */ + protected function getCreationEvent($formData) + { + $event = new AreaCreateEvent(); + + return $this->hydrateEvent($event, $formData); + } + + /** + * Creates the update event with the provided form data + * + * @param unknown $formData + */ + protected function getUpdateEvent($formData) + { + $event = new AreaUpdateEvent(); + + return $this->hydrateEvent($event, $formData); + } + + private function hydrateEvent($event, $formData) + { + $event->setAreaName($formData['name']); + + return $event; + } + + /** + * Creates the delete event with the provided form data + */ + protected function getDeleteEvent() + { + return new AreaDeleteEvent($this->getAreaId()); + } + + /** + * Return true if the event contains the object, e.g. the action has updated the object in the event. + * + * @param \Thelia\Core\Event\Area\AreaEvent $event + */ + protected function eventContainsObject($event) + { + return $event->hasArea(); + } + + /** + * Get the created object from an event. + * + * @param \Thelia\Core\Event\Area\AreaEvent $event + */ + protected function getObjectFromEvent($event) + { + return $event->getArea(); + } + + /** + * Load an existing object from the database + */ + protected function getExistingObject() + { + return AreaQuery::create()->findPk($this->getAreaId()); + } + + /** + * Returns the object label form the object event (name, title, etc.) + * + * @param \Thelia\Model\Area $object + */ + protected function getObjectLabel($object) + { + return $object->getName(); + } + + /** + * Returns the object ID from the object + * + * @param \Thelia\Model\Area $object + */ + protected function getObjectId($object) + { + return $object->getId(); + } + + /** + * Render the main list template + * + * @param unknown $currentOrder, if any, null otherwise. + */ + protected function renderListTemplate($currentOrder) + { + return $this->render("shipping-configuration"); + } + + /** + * Render the edition template + */ + protected function renderEditionTemplate() + { + return $this->render('shipping-configuration-edit',array( + 'area_id' => $this->getAreaId() + )); + } + + /** + * Redirect to the edition template + */ + protected function redirectToEditionTemplate() + { + $this->redirectToRoute('admin.configuration.shipping-configuration.update.view', array(), array( + "area_id" => $this->getAreaId() + ) + ); + } + + /** + * Redirect to the list template + */ + protected function redirectToListTemplate() + { + $this->redirectToRoute('admin.configuration.shipping-configuration.default'); + } + + /** + * add a country to a define area + */ + public function addCountry() + { + // Check current user authorization + if (null !== $response = $this->checkAuth($this->updatePermissionIdentifier)) return $response; + + $areaCountryForm = new AreaCountryForm($this->getRequest()); + $error_msg = null; + try { + + $form = $this->validateForm($areaCountryForm); + + $event = new AreaAddCountryEvent($form->get('area_id')->getData(), $form->get('country_id')->getData()); + + $this->dispatch(TheliaEvents::AREA_ADD_COUNTRY, $event); + + if (! $this->eventContainsObject($event)) + throw new \LogicException( + $this->getTranslator()->trans("No %obj was updated.", array('%obj', $this->objectName))); + + // Log object modification + if (null !== $changedObject = $this->getObjectFromEvent($event)) { + $this->adminLogAppend(sprintf("%s %s (ID %s) modified, new country added", ucfirst($this->objectName), $this->getObjectLabel($changedObject), $this->getObjectId($changedObject))); + } + + // Redirect to the success URL + $this->redirect($areaCountryForm->getSuccessUrl()); + + } catch (FormValidationException $ex) { + // Form cannot be validated + $error_msg = $this->createStandardFormValidationErrorMessage($ex); + } catch (\Exception $ex) { + // Any other error + $error_msg = $ex->getMessage(); + } + + $this->setupFormErrorContext( + $this->getTranslator()->trans("%obj modification", array('%obj' => $this->objectName)), $error_msg, $areaCountryForm); + + // At this point, the form has errors, and should be redisplayed. + return $this->renderEditionTemplate(); + } + + public function removeCountry() + { + // Check current user authorization + if (null !== $response = $this->checkAuth($this->updatePermissionIdentifier)) return $response; + $request = $this->getRequest(); + $removeCountryEvent = new AreaRemoveCountryEvent($request->request->get('areai_id', 0), $request->request->get('country_id', 0)); + + $this->dispatch(TheliaEvents::AREA_REMOVE_COUNTRY, $removeCountryEvent); + + $this->redirectToEditionTemplate(); + } + + public function updatePostageAction() + { + if (null !== $response = $this->checkAuth($this->updatePermissionIdentifier)) return $response; + + $areaUpdateForm = new AreaPostageForm($this->getRequest()); + $error_msg = null; + + try { + $form = $this->validateForm($areaUpdateForm); + + $event = new AreaUpdatePostageEvent($form->get('area_id')->getData()); + $event->setPostage($form->get('postage')->getData()); + + $this->dispatch(TheliaEvents::AREA_POSTAGE_UPDATE, $event); + + if (! $this->eventContainsObject($event)) + throw new \LogicException( + $this->getTranslator()->trans("No %obj was updated.", array('%obj', $this->objectName))); + + // Log object modification + if (null !== $changedObject = $this->getObjectFromEvent($event)) { + $this->adminLogAppend(sprintf("%s %s (ID %s) modified, country remove", ucfirst($this->objectName), $this->getObjectLabel($changedObject), $this->getObjectId($changedObject))); + } + + // Redirect to the success URL + $this->redirect($areaUpdateForm->getSuccessUrl()); + } catch (FormValidationException $ex) { + // Form cannot be validated + $error_msg = $this->createStandardFormValidationErrorMessage($ex); + } catch (\Exception $ex) { + // Any other error + $error_msg = $ex->getMessage(); + } + + $this->setupFormErrorContext( + $this->getTranslator()->trans("%obj modification", array('%obj' => $this->objectName)), $error_msg, $areaUpdateForm); + + // At this point, the form has errors, and should be redisplayed. + return $this->renderEditionTemplate(); + } +} diff --git a/core/lib/Thelia/Controller/Admin/BaseAdminController.php b/core/lib/Thelia/Controller/Admin/BaseAdminController.php index 5d99a877b..9adb7a19a 100755 --- a/core/lib/Thelia/Controller/Admin/BaseAdminController.php +++ b/core/lib/Thelia/Controller/Admin/BaseAdminController.php @@ -246,7 +246,7 @@ class BaseAdminController extends BaseController * @param unknown $routeId the route ID, as found in Config/Resources/routing/admin.xml * @param unknown $urlParameters the URL parametrs, as a var/value pair array */ - public function redirectToRoute($routeId, $urlParameters = array(), $routeParameters = array()) + public function redirectToRoute($routeId, array $urlParameters = array(), array $routeParameters = array()) { $this->redirect(URL::getInstance()->absoluteUrl($this->getRoute($routeId, $routeParameters), $urlParameters)); } diff --git a/core/lib/Thelia/Controller/Admin/CountryController.php b/core/lib/Thelia/Controller/Admin/CountryController.php index a272f7364..91160311f 100644 --- a/core/lib/Thelia/Controller/Admin/CountryController.php +++ b/core/lib/Thelia/Controller/Admin/CountryController.php @@ -39,24 +39,6 @@ use Thelia\Model\CountryQuery; class CountryController extends AbstractCrudController { - /** - * @param string $objectName the lower case object name. Example. "message" - * - * @param string $defaultListOrder the default object list order, or null if list is not sortable. Example: manual - * @param string $orderRequestParameterName Name of the request parameter that set the list order (null if list is not sortable) - * - * @param string $viewPermissionIdentifier the 'view' permission identifier. Example: "admin.configuration.message.view" - * @param string $createPermissionIdentifier the 'create' permission identifier. Example: "admin.configuration.message.create" - * @param string $updatePermissionIdentifier the 'update' permission identifier. Example: "admin.configuration.message.update" - * @param string $deletePermissionIdentifier the 'delete' permission identifier. Example: "admin.configuration.message.delete" - * - * @param string $createEventIdentifier the dispatched create TheliaEvent identifier. Example: TheliaEvents::MESSAGE_CREATE - * @param string $updateEventIdentifier the dispatched update TheliaEvent identifier. Example: TheliaEvents::MESSAGE_UPDATE - * @param string $deleteEventIdentifier the dispatched delete TheliaEvent identifier. Example: TheliaEvents::MESSAGE_DELETE - * - * @param string $visibilityToggleEventIdentifier the dispatched visibility toggle TheliaEvent identifier, or null if the object has no visible options. Example: TheliaEvents::MESSAGE_TOGGLE_VISIBILITY - * @param string $changePositionEventIdentifier the dispatched position change TheliaEvent identifier, or null if the object has no position. Example: TheliaEvents::MESSAGE_UPDATE_POSITION - */ public function __construct() { parent::__construct( @@ -129,7 +111,7 @@ class CountryController extends AbstractCrudController */ protected function getUpdateEvent($formData) { - $event = new CountryUpdateEvent(); + $event = new CountryUpdateEvent($formData['id']); return $this->hydrateEvent($event, $formData); } @@ -139,6 +121,8 @@ class CountryController extends AbstractCrudController $event ->setLocale($formData['locale']) ->setTitle($formData['title']) + ->setChapo($formData['chapo']) + ->setDescription($formData['description']) ->setIsocode($formData['isocode']) ->setIsoAlpha2($formData['isoalpha2']) ->setIsoAlpha3($formData['isoalpha3']) @@ -236,7 +220,10 @@ class CountryController extends AbstractCrudController */ protected function redirectToEditionTemplate() { - $this->redirectToRoute('admin.configuration.countries.update', array(), $this->getRequest()->get('country_id', 0)); + $this->redirectToRoute('admin.configuration.countries.update', array(), array( + "country_id" => $this->getRequest()->get('country_id', 0) + ) + ); } /** diff --git a/core/lib/Thelia/Controller/Admin/ShippingZoneController.php b/core/lib/Thelia/Controller/Admin/ShippingZoneController.php index 0084c861b..d68de4808 100644 --- a/core/lib/Thelia/Controller/Admin/ShippingZoneController.php +++ b/core/lib/Thelia/Controller/Admin/ShippingZoneController.php @@ -22,6 +22,12 @@ /*************************************************************************************/ namespace Thelia\Controller\Admin; +use Thelia\Core\Event\ShippingZone\ShippingZoneAddAreaEvent; +use Thelia\Core\Event\ShippingZone\ShippingZoneRemoveAreaEvent; +use Thelia\Core\Event\TheliaEvents; +use Thelia\Form\Exception\FormValidationException; +use Thelia\Form\ShippingZone\ShippingZoneAddArea; +use Thelia\Form\ShippingZone\ShippingZoneRemoveArea; /** * Class ShippingZoneController @@ -30,6 +36,8 @@ namespace Thelia\Controller\Admin; */ class ShippingZoneController extends BaseAdminController { + public $objectName = 'areaDeliveryModule'; + public function indexAction() { if (null !== $response = $this->checkAuth("admin.shipping-zones.view")) return $response; @@ -38,8 +46,99 @@ class ShippingZoneController extends BaseAdminController public function updateAction($shipping_zones_id) { + if (null !== $response = $this->checkAuth("admin.shipping-zones.view")) return $response; return $this->render("shipping-zones-edit", array( "shipping_zones_id" => $shipping_zones_id )); } + + /** + * @return mixed|\Symfony\Component\HttpFoundation\Response + */ + public function addArea() + { + if (null !== $response = $this->checkAuth("admin.shipping-zones.update")) return $response; + + $shippingAreaForm = new ShippingZoneAddArea($this->getRequest()); + $error_msg = null; + + try { + $form = $this->validateForm($shippingAreaForm); + + $event = new ShippingZoneAddAreaEvent( + $form->get('area_id')->getData(), + $form->get('shipping_zone_id')->getData() + ); + + $this->dispatch(TheliaEvents::SHIPPING_ZONE_ADD_AREA, $event); + + // Redirect to the success URL + $this->redirect($shippingAreaForm->getSuccessUrl()); + + } catch (FormValidationException $ex) { + // Form cannot be validated + $error_msg = $this->createStandardFormValidationErrorMessage($ex); + } catch (\Exception $ex) { + // Any other error + $error_msg = $ex->getMessage(); + } + + $this->setupFormErrorContext( + $this->getTranslator()->trans("%obj modification", array('%obj' => $this->objectName)), $error_msg, $shippingAreaForm); + + // At this point, the form has errors, and should be redisplayed. + return $this->renderEditionTemplate(); + } + + public function removeArea() + { + if (null !== $response = $this->checkAuth("admin.shipping-zones.update")) return $response; + + $shippingAreaForm = new ShippingZoneRemoveArea($this->getRequest()); + $error_msg = null; + + try { + $form = $this->validateForm($shippingAreaForm); + + $event = new ShippingZoneRemoveAreaEvent( + $form->get('area_id')->getData(), + $form->get('shipping_zone_id')->getData() + ); + + $this->dispatch(TheliaEvents::SHIPPING_ZONE_REMOVE_AREA, $event); + + // Redirect to the success URL + $this->redirect($shippingAreaForm->getSuccessUrl()); + + } catch (FormValidationException $ex) { + // Form cannot be validated + $error_msg = $this->createStandardFormValidationErrorMessage($ex); + } catch (\Exception $ex) { + // Any other error + $error_msg = $ex->getMessage(); + } + + $this->setupFormErrorContext( + $this->getTranslator()->trans("%obj modification", array('%obj' => $this->objectName)), $error_msg, $shippingAreaForm); + + // At this point, the form has errors, and should be redisplayed. + return $this->renderEditionTemplate(); + } + + /** + * Render the edition template + */ + protected function renderEditionTemplate() + { + return $this->render("shipping-zones-edit", array( + "shipping_zones_id" => $this->getShippingZoneId() + )); + } + + protected function getShippingZoneId() + { + return $this->getRequest()->get('shipping_zone_id', 0); + } + + } diff --git a/core/lib/Thelia/Controller/Admin/TaxRuleController.php b/core/lib/Thelia/Controller/Admin/TaxRuleController.php new file mode 100644 index 000000000..b0ceba67e --- /dev/null +++ b/core/lib/Thelia/Controller/Admin/TaxRuleController.php @@ -0,0 +1,287 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Controller\Admin; + +use Thelia\Core\Event\Tax\TaxRuleEvent; +use Thelia\Core\Event\TheliaEvents; +use Thelia\Form\TaxRuleCreationForm; +use Thelia\Form\TaxRuleModificationForm; +use Thelia\Form\TaxRuleTaxListUpdateForm; +use Thelia\Model\CountryQuery; +use Thelia\Model\TaxRuleQuery; + +class TaxRuleController extends AbstractCrudController +{ + public function __construct() + { + parent::__construct( + 'taxrule', + 'manual', + 'order', + + 'admin.configuration.taxrule.view', + 'admin.configuration.taxrule.create', + 'admin.configuration.taxrule.update', + 'admin.configuration.taxrule.delete', + + TheliaEvents::TAX_RULE_CREATE, + TheliaEvents::TAX_RULE_UPDATE, + TheliaEvents::TAX_RULE_DELETE + ); + } + + protected function getCreationForm() + { + return new TaxRuleCreationForm($this->getRequest()); + } + + protected function getUpdateForm() + { + return new TaxRuleModificationForm($this->getRequest()); + } + + protected function getCreationEvent($formData) + { + $event = new TaxRuleEvent(); + + $event->setLocale($formData['locale']); + $event->setTitle($formData['title']); + $event->setDescription($formData['description']); + + return $event; + } + + protected function getUpdateEvent($formData) + { + $event = new TaxRuleEvent(); + + $event->setLocale($formData['locale']); + $event->setId($formData['id']); + $event->setTitle($formData['title']); + $event->setDescription($formData['description']); + + return $event; + } + + protected function getUpdateTaxListEvent($formData) + { + $event = new TaxRuleEvent(); + + $event->setId($formData['id']); + $event->setTaxList($formData['tax_list']); + $event->setCountryList($formData['country_list']); + + return $event; + } + + protected function getDeleteEvent() + { + $event = new TaxRuleEvent(); + + $event->setId( + $this->getRequest()->get('tax_rule_id', 0) + ); + + return $event; + } + + protected function eventContainsObject($event) + { + return $event->hasTaxRule(); + } + + protected function hydrateObjectForm($object) + { + $data = array( + 'id' => $object->getId(), + 'locale' => $object->getLocale(), + 'title' => $object->getTitle(), + 'description' => $object->getDescription(), + ); + + // Setup the object form + return new TaxRuleModificationForm($this->getRequest(), "form", $data); + } + + protected function hydrateTaxUpdateForm($object) + { + $data = array( + 'id' => $object->getId(), + ); + + // Setup the object form + return new TaxRuleTaxListUpdateForm($this->getRequest(), "form", $data); + } + + protected function getObjectFromEvent($event) + { + return $event->hasTaxRule() ? $event->getTaxRule() : null; + } + + protected function getExistingObject() + { + return TaxRuleQuery::create() + ->joinWithI18n($this->getCurrentEditionLocale()) + ->findOneById($this->getRequest()->get('tax_rule_id')); + } + + protected function getObjectLabel($object) + { + return $object->getTitle(); + } + + protected function getObjectId($object) + { + return $object->getId(); + } + + protected function getViewArguments($country = null, $tab = null) + { + return array( + 'tab' => $tab === null ? $this->getRequest()->get('tab', 'data') : $tab, + 'country' => $country === null ? $this->getRequest()->get('country', CountryQuery::create()->findOneByByDefault(1)->getId()) : $country, + ); + } + + protected function getRouteArguments($tax_rule_id = null) + { + return array( + 'tax_rule_id' => $tax_rule_id === null ? $this->getRequest()->get('tax_rule_id') : $tax_rule_id, + ); + } + + protected function renderListTemplate($currentOrder) + { + // We always return to the feature edition form + return $this->render( + 'taxes-rules', + array() + ); + } + + protected function renderEditionTemplate() + { + // We always return to the feature edition form + return $this->render('tax-rule-edit', array_merge($this->getViewArguments(), $this->getRouteArguments())); + } + + protected function redirectToEditionTemplate($request = null, $country = null) + { + // We always return to the feature edition form + $this->redirectToRoute( + "admin.configuration.taxes-rules.update", + $this->getViewArguments($country), + $this->getRouteArguments() + ); + } + + /** + * Put in this method post object creation processing if required. + * + * @param TaxRuleEvent $createEvent the create event + * @return Response a response, or null to continue normal processing + */ + protected function performAdditionalCreateAction($createEvent) + { + $this->redirectToRoute( + "admin.configuration.taxes-rules.update", + $this->getViewArguments(), + $this->getRouteArguments($createEvent->getTaxRule()->getId()) + ); + } + + protected function redirectToListTemplate() + { + $this->redirectToRoute( + "admin.configuration.taxes-rules.list" + ); + } + + public function updateAction() + { + if (null !== $response = $this->checkAuth($this->updatePermissionIdentifier)) return $response; + + $object = $this->getExistingObject(); + + if ($object != null) { + + // Hydrate the form abd pass it to the parser + $changeTaxesForm = $this->hydrateTaxUpdateForm($object); + + // Pass it to the parser + $this->getParserContext()->addForm($changeTaxesForm); + } + + return parent::updateAction(); + } + + public function processUpdateTaxesAction() + { + // Check current user authorization + if (null !== $response = $this->checkAuth('admin.configuration.taxrule.update')) return $response; + + $error_msg = false; + + // Create the form from the request + $changeForm = new TaxRuleTaxListUpdateForm($this->getRequest()); + + try { + // Check the form against constraints violations + $form = $this->validateForm($changeForm, "POST"); + + // Get the form field values + $data = $form->getData(); + + $changeEvent = $this->getUpdateTaxListEvent($data); + + $this->dispatch(TheliaEvents::TAX_RULE_TAXES_UPDATE, $changeEvent); + + if (! $this->eventContainsObject($changeEvent)) + throw new \LogicException( + $this->getTranslator()->trans("No %obj was updated.", array('%obj', $this->objectName))); + + // Log object modification + if (null !== $changedObject = $this->getObjectFromEvent($changeEvent)) { + $this->adminLogAppend(sprintf("%s %s (ID %s) modified", ucfirst($this->objectName), $this->getObjectLabel($changedObject), $this->getObjectId($changedObject))); + } + + if ($response == null) { + $this->redirectToEditionTemplate($this->getRequest(), isset($data['country_list'][0]) ? $data['country_list'][0] : null); + } else { + return $response; + } + } catch (FormValidationException $ex) { + // Form cannot be validated + $error_msg = $this->createStandardFormValidationErrorMessage($ex); + } catch (\Exception $ex) { + // Any other error + $error_msg = $ex->getMessage(); + } + + $this->setupFormErrorContext($this->getTranslator()->trans("%obj modification", array('%obj' => 'taxrule')), $error_msg, $changeForm, $ex); + + // At this point, the form has errors, and should be redisplayed. + return $this->renderEditionTemplate(); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/DependencyInjection/Compiler/RegisterRouterPass.php b/core/lib/Thelia/Core/DependencyInjection/Compiler/RegisterRouterPass.php index 7d7ab086f..8fb086403 100755 --- a/core/lib/Thelia/Core/DependencyInjection/Compiler/RegisterRouterPass.php +++ b/core/lib/Thelia/Core/DependencyInjection/Compiler/RegisterRouterPass.php @@ -58,6 +58,7 @@ class RegisterRouterPass implements CompilerPassInterface $priority = isset($attributes[0]["priority"]) ? $attributes[0]["priority"] : 0; $router = $container->getDefinition($id); $router->addMethodCall("setOption", array("matcher_cache_class", $container::camelize("ProjectUrlMatcher".$id))); + $router->addMethodCall("setOption", array("generator_cache_class", $container::camelize("ProjectUrlGenerator".$id))); $chainRouter->addMethodCall("add", array(new Reference($id), $priority)); @@ -76,7 +77,8 @@ class RegisterRouterPass implements CompilerPassInterface array( "cache_dir" => $container->getParameter("kernel.cache_dir"), "debug" => $container->getParameter("kernel.debug"), - "matcher_cache_class" => $container::camelize("ProjectUrlMatcher".$moduleCode) + "matcher_cache_class" => $container::camelize("ProjectUrlMatcher".$moduleCode), + "generator_cache_class" => $container::camelize("ProjectUrlGenerator".$moduleCode), ), new Reference("request.context") ) diff --git a/core/lib/Thelia/Core/Event/Area/AreaAddCountryEvent.php b/core/lib/Thelia/Core/Event/Area/AreaAddCountryEvent.php new file mode 100644 index 000000000..b6af3c5b3 --- /dev/null +++ b/core/lib/Thelia/Core/Event/Area/AreaAddCountryEvent.php @@ -0,0 +1,86 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event\Area; + + +/** + * Class AreaAddCountryEvent + * @package Thelia\Core\Event\Area + * @author Manuel Raynaud + */ +class AreaAddCountryEvent extends AreaEvent +{ + protected $area_id; + protected $country_id; + + function __construct($area_id, $country_id) + { + $this->area_id = $area_id; + $this->country_id = $country_id; + } + + /** + * @param mixed $area_id + * + * @return $this + */ + public function setAreaId($area_id) + { + $this->area_id = $area_id; + + return $this; + } + + /** + * @return mixed + */ + public function getAreaId() + { + return $this->area_id; + } + + /** + * @param mixed $country_id + * + * @return $this + */ + public function setCountryId($country_id) + { + $this->country_id = $country_id; + + return $this; + } + + /** + * @return mixed + */ + public function getCountryId() + { + return $this->country_id; + } + + + + +} \ No newline at end of file diff --git a/core/lib/Thelia/Controller/Admin/ShippingConfigurationController.php b/core/lib/Thelia/Core/Event/Area/AreaCreateEvent.php similarity index 68% rename from core/lib/Thelia/Controller/Admin/ShippingConfigurationController.php rename to core/lib/Thelia/Core/Event/Area/AreaCreateEvent.php index 92b73a83e..d63afa5b9 100644 --- a/core/lib/Thelia/Controller/Admin/ShippingConfigurationController.php +++ b/core/lib/Thelia/Core/Event/Area/AreaCreateEvent.php @@ -1,7 +1,7 @@ . */ +/* along with this program. If not, see . */ /* */ /*************************************************************************************/ -namespace Thelia\Controller\Admin; +namespace Thelia\Core\Event\Area; + /** - * Class ShippingConfigurationController - * @package Thelia\Controller\Admin + * Class AreaCreateEvent + * @package Thelia\Core\Event\Area * @author Manuel Raynaud */ -class ShippingConfigurationController extends BaseAdminController +class AreaCreateEvent extends AreaEvent { - public function indexAction() + protected $name; + + /** + * @param mixed $name + */ + public function setAreaName($name) { - if (null !== $response = $this->checkAuth("admin.shipping-configuration.view")) return $response; - return $this->render("shipping-configuration", array("display_shipping_configuration" => 20)); + $this->name = $name; } - public function updateAction($shipping_configuration_id) + /** + * @return mixed + */ + public function getAreaName() { - return $this->render("shipping-configuration-edit", array( - "shipping_configuration_id" => $shipping_configuration_id - )); + return $this->name; } -} + + +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/Area/AreaDeleteEvent.php b/core/lib/Thelia/Core/Event/Area/AreaDeleteEvent.php new file mode 100644 index 000000000..86f936140 --- /dev/null +++ b/core/lib/Thelia/Core/Event/Area/AreaDeleteEvent.php @@ -0,0 +1,65 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event\Area; + + +/** + * Class AreaDeleteEvent + * @package Thelia\Core\Event\Area + * @author Manuel Raynaud + */ +class AreaDeleteEvent extends AreaEvent +{ + /** + * @var int area id + */ + protected $area_id; + + public function __construct($area_id) + { + $this->area_id = $area_id; + } + + /** + * @param null $area_id + * + * @return $this + */ + public function setAreaId($area_id) + { + $this->area_id = $area_id; + + return $this; + } + + /** + * @return null + */ + public function getAreaId() + { + return $this->area_id; + } + + +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/Area/AreaEvent.php b/core/lib/Thelia/Core/Event/Area/AreaEvent.php new file mode 100644 index 000000000..892d00843 --- /dev/null +++ b/core/lib/Thelia/Core/Event/Area/AreaEvent.php @@ -0,0 +1,66 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event\Area; +use Thelia\Core\Event\ActionEvent; + + +/** + * Class AreaEvent + * @package Thelia\Core\Event\Shipping + * @author Manuel Raynaud + */ +class AreaEvent extends ActionEvent +{ + protected $area; + + public function __construct($area = null) + { + $this->area = $area; + } + + /** + * @param mixed $area + * + * @return $this + */ + public function setArea($area) + { + $this->area = $area; + + return $this; + } + + /** + * @return mixed + */ + public function getArea() + { + return $this->area; + } + + public function hasArea() + { + return null !== $this->area; + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/Area/AreaRemoveCountryEvent.php b/core/lib/Thelia/Core/Event/Area/AreaRemoveCountryEvent.php new file mode 100644 index 000000000..84c8f10d2 --- /dev/null +++ b/core/lib/Thelia/Core/Event/Area/AreaRemoveCountryEvent.php @@ -0,0 +1,35 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event\Area; + + +/** + * Class AreaRemoveCountryEvent + * @package Thelia\Core\Event\Area + * @author Manuel Raynaud + */ +class AreaRemoveCountryEvent extends AreaAddCountryEvent +{ + +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/Area/AreaUpdateEvent.php b/core/lib/Thelia/Core/Event/Area/AreaUpdateEvent.php new file mode 100644 index 000000000..f5f7c8704 --- /dev/null +++ b/core/lib/Thelia/Core/Event/Area/AreaUpdateEvent.php @@ -0,0 +1,35 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event\Area; + + +/** + * Class AreaUpdateEvent + * @package Thelia\Core\Event\Area + * @author Manuel Raynaud + */ +class AreaUpdateEvent extends AreaCreateEvent +{ + +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/Area/AreaUpdatePostageEvent.php b/core/lib/Thelia/Core/Event/Area/AreaUpdatePostageEvent.php new file mode 100644 index 000000000..5f799b93c --- /dev/null +++ b/core/lib/Thelia/Core/Event/Area/AreaUpdatePostageEvent.php @@ -0,0 +1,85 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event\Area; + + +/** + * Class AreaUpdatePostageEvent + * @package Thelia\Core\Event\Area + * @author Manuel Raynaud + */ +class AreaUpdatePostageEvent extends AreaEvent +{ + protected $area_id; + protected $postage; + + function __construct($area_id) + { + $this->area_id = $area_id; + } + + /** + * @param mixed $area_id + * + * @return $this + */ + public function setAreaId($area_id) + { + $this->area_id = $area_id; + + return $this; + } + + /** + * @return mixed + */ + public function getAreaId() + { + return $this->area_id; + } + + /** + * @param mixed $postage + * + * @return $this + */ + public function setPostage($postage) + { + $this->postage = $postage; + + return $this; + } + + /** + * @return mixed + */ + public function getPostage() + { + return $this->postage; + } + + + + +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/Country/CountryUpdateEvent.php b/core/lib/Thelia/Core/Event/Country/CountryUpdateEvent.php index 5c4ad1cf3..496904172 100644 --- a/core/lib/Thelia/Core/Event/Country/CountryUpdateEvent.php +++ b/core/lib/Thelia/Core/Event/Country/CountryUpdateEvent.php @@ -31,5 +31,90 @@ namespace Thelia\Core\Event\Country; */ class CountryUpdateEvent extends CountryCreateEvent { + protected $country_id; + + protected $chapo; + protected $description; + protected $postscriptum; + + function __construct($country_id) + { + $this->country_id = $country_id; + } + + /** + * @param mixed $chapo + */ + public function setChapo($chapo) + { + $this->chapo = $chapo; + + return $this; + } + + /** + * @return mixed + */ + public function getChapo() + { + return $this->chapo; + } + + /** + * @param mixed $description + */ + public function setDescription($description) + { + $this->description = $description; + + return $this; + } + + /** + * @return mixed + */ + public function getDescription() + { + return $this->description; + } + + /** + * @param mixed $postscriptum + */ + public function setPostscriptum($postscriptum) + { + $this->postscriptum = $postscriptum; + + return $this; + } + + /** + * @return mixed + */ + public function getPostscriptum() + { + return $this->postscriptum; + } + + /** + * @param mixed $country_id + */ + public function setCountryId($country_id) + { + $this->country_id = $country_id; + + return $this; + } + + /** + * @return mixed + */ + public function getCountryId() + { + return $this->country_id; + } + + + } \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/ShippingZone/ShippingZoneAddAreaEvent.php b/core/lib/Thelia/Core/Event/ShippingZone/ShippingZoneAddAreaEvent.php new file mode 100644 index 000000000..d1e406646 --- /dev/null +++ b/core/lib/Thelia/Core/Event/ShippingZone/ShippingZoneAddAreaEvent.php @@ -0,0 +1,87 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event\ShippingZone; +use Thelia\Core\Event\ActionEvent; + + +/** + * Class ShippingZoneAddAreaEvent + * @package Thelia\Core\Event\ShippingZone + * @author Manuel Raynaud + */ +class ShippingZoneAddAreaEvent extends ActionEvent +{ + protected $area_id; + protected $shopping_zone_id; + + function __construct($area_id, $shopping_zone_id) + { + $this->area_id = $area_id; + $this->shopping_zone_id = $shopping_zone_id; + } + + /** + * @param mixed $area_id + * + * @return $this + */ + public function setAreaId($area_id) + { + $this->area_id = $area_id; + + return $this; + } + + /** + * @return mixed + */ + public function getAreaId() + { + return $this->area_id; + } + + /** + * @param mixed $shopping_zone_id + * + * @return $this + */ + public function setShoppingZoneId($shopping_zone_id) + { + $this->shopping_zone_id = $shopping_zone_id; + + return $this; + } + + /** + * @return mixed + */ + public function getShoppingZoneId() + { + return $this->shopping_zone_id; + } + + + + +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/ShippingZone/ShippingZoneRemoveAreaEvent.php b/core/lib/Thelia/Core/Event/ShippingZone/ShippingZoneRemoveAreaEvent.php new file mode 100644 index 000000000..6dc6094d6 --- /dev/null +++ b/core/lib/Thelia/Core/Event/ShippingZone/ShippingZoneRemoveAreaEvent.php @@ -0,0 +1,35 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event\ShippingZone; + + +/** + * Class ShippingZoneRemoveAreaEvent + * @package Thelia\Core\Event\ShippingZone + * @author Manuel Raynaud + */ +class ShippingZoneRemoveAreaEvent extends ShippingZoneAddAreaEvent +{ + +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/Tax/TaxRuleEvent.php b/core/lib/Thelia/Core/Event/Tax/TaxRuleEvent.php new file mode 100644 index 000000000..e364bfd84 --- /dev/null +++ b/core/lib/Thelia/Core/Event/Tax/TaxRuleEvent.php @@ -0,0 +1,122 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event\Tax; +use Thelia\Core\Event\ActionEvent; +use Thelia\Model\TaxRule; + +class TaxRuleEvent extends ActionEvent +{ + protected $taxRule = null; + + protected $locale; + protected $id; + protected $title; + protected $description; + protected $countryList; + protected $taxList; + + public function __construct(TaxRule $taxRule = null) + { + $this->taxRule = $taxRule; + } + + public function hasTaxRule() + { + return ! is_null($this->taxRule); + } + + public function getTaxRule() + { + return $this->taxRule; + } + + public function setTaxRule(TaxRule $taxRule) + { + $this->taxRule = $taxRule; + + return $this; + } + + public function setDescription($description) + { + $this->description = $description; + } + + public function getDescription() + { + return $this->description; + } + + public function setId($id) + { + $this->id = $id; + } + + public function getId() + { + return $this->id; + } + + public function setTitle($title) + { + $this->title = $title; + } + + public function getTitle() + { + return $this->title; + } + + public function setLocale($locale) + { + $this->locale = $locale; + } + + public function getLocale() + { + return $this->locale; + } + + public function setCountryList($countryList) + { + $this->countryList = $countryList; + } + + public function getCountryList() + { + return $this->countryList; + } + + public function setTaxList($taxList) + { + $this->taxList = $taxList; + } + + public function getTaxList() + { + return $this->taxList; + } + + +} diff --git a/core/lib/Thelia/Core/Event/TheliaEvents.php b/core/lib/Thelia/Core/Event/TheliaEvents.php index 4e4f55ba8..aa365e54a 100755 --- a/core/lib/Thelia/Core/Event/TheliaEvents.php +++ b/core/lib/Thelia/Core/Event/TheliaEvents.php @@ -232,6 +232,30 @@ final class TheliaEvents const BEFORE_UPDATECOUNTRY = "action.before_updateCountry"; const AFTER_UPDATECOUNTRY = "action.after_updateCountry"; + // -- AREA CONFIGURATION MANAGEMENT + + const AREA_CREATE = 'action.createArea'; + const AREA_UPDATE = 'action.updateArea'; + const AREA_DELETE = 'action.deleteArea'; + + const AREA_ADD_COUNTRY = 'action.area.addCountry'; + const AREA_REMOVE_COUNTRY = 'action.area.removeCountry'; + const AREA_POSTAGE_UPDATE = 'action.area.postageUpdate'; + + const BEFORE_CREATEAREA = 'action.before_createArea'; + const AFTER_CREATEAREA = 'action.after_createArea'; + + const BEFORE_UPDATEAREA = 'action.before_updateArea'; + const AFTER_UPDATEAREA = 'action.after_updateArea'; + + const BEFORE_DELETEAREA = 'action.before_deleteArea'; + const AFTER_DELETEAREA = 'action.after_deleteArea'; + + // -- SHIPPING ZONE MANAGEMENT + + const SHIPPING_ZONE_ADD_AREA = 'action.shippingZone.addArea'; + const SHIPPING_ZONE_REMOVE_AREA = 'action.shippingZone.removeArea'; + // -- Categories Associated Content ---------------------------------------- const BEFORE_CREATECATEGORY_ASSOCIATED_CONTENT = "action.before_createCategoryAssociatedContent"; @@ -519,6 +543,14 @@ final class TheliaEvents const CHANGE_DEFAULT_CURRENCY = 'action.changeDefaultCurrency'; + // -- Tax Rules management --------------------------------------------- + + const TAX_RULE_CREATE = "action.createTaxRule"; + const TAX_RULE_UPDATE = "action.updateTaxRule"; + const TAX_RULE_DELETE = "action.deleteTaxRule"; + const TAX_RULE_SET_DEFAULT = "action.setDefaultTaxRule"; + const TAX_RULE_TAXES_UPDATE = "action.updateTaxesTaxRule"; + // -- Product templates management ----------------------------------------- const TEMPLATE_CREATE = "action.createTemplate"; diff --git a/core/lib/Thelia/Core/Template/Loop/Area.php b/core/lib/Thelia/Core/Template/Loop/Area.php new file mode 100644 index 000000000..4d43f524b --- /dev/null +++ b/core/lib/Thelia/Core/Template/Loop/Area.php @@ -0,0 +1,144 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Template\Loop; +use Propel\Runtime\ActiveQuery\Criteria; +use Thelia\Core\Template\Element\BaseLoop; +use Thelia\Core\Template\Element\LoopResult; +use Thelia\Core\Template\Element\LoopResultRow; +use Thelia\Core\Template\Loop\Argument\Argument; +use Thelia\Core\Template\Loop\Argument\ArgumentCollection; +use Thelia\Model\AreaQuery; + + +/** + * Class Area + * @package Thelia\Core\Template\Loop + * @author Manuel Raynaud + */ +class Area extends BaseLoop +{ + public $timestampable = true; + + /** + * + * define all args used in your loop + * + * + * example : + * + * public function getArgDefinitions() + * { + * return new ArgumentCollection( + * Argument::createIntListTypeArgument('id'), + * new Argument( + * 'ref', + * new TypeCollection( + * new Type\AlphaNumStringListType() + * ) + * ), + * Argument::createIntListTypeArgument('category'), + * Argument::createBooleanTypeArgument('new'), + * Argument::createBooleanTypeArgument('promo'), + * Argument::createFloatTypeArgument('min_price'), + * Argument::createFloatTypeArgument('max_price'), + * Argument::createIntTypeArgument('min_stock'), + * Argument::createFloatTypeArgument('min_weight'), + * Argument::createFloatTypeArgument('max_weight'), + * Argument::createBooleanTypeArgument('current'), + * + * ); + * } + * + * @return \Thelia\Core\Template\Loop\Argument\ArgumentCollection + */ + protected function getArgDefinitions() + { + return new ArgumentCollection( + Argument::createIntListTypeArgument('id'), + Argument::createIntTypeArgument('with_zone'), + Argument::createIntTypeArgument('without_zone') + ); + } + + /** + * + * this function have to be implement in your own loop class. + * + * All loops parameters can be accessible via getter. + * + * for example, ref parameter is accessible through getRef method + * + * @param $pagination + * + * @return mixed + */ + public function exec(&$pagination) + { + $id = $this->getId(); + + $search = AreaQuery::create(); + + if ($id) { + $search->filterById($id, Criteria::IN); + } + + $withZone = $this->getWith_zone(); + + if ($withZone) { + $search->joinAreaDeliveryModule('with_zone') + ->where('`with_zone`.delivery_module_id '.Criteria::EQUAL.' ?', $withZone, \PDO::PARAM_INT); + } + + $withoutZone = $this->getWithout_zone(); + + if($withoutZone) + { + $search->joinAreaDeliveryModule('without_zone', Criteria::LEFT_JOIN) + ->addJoinCondition('without_zone', 'delivery_module_id '.Criteria::EQUAL.' ?', $withoutZone, null, \PDO::PARAM_INT) + ->where('`without_zone`.delivery_module_id '.Criteria::ISNULL); + } + + //echo $search->toString(); exit; + + $areas = $this->search($search, $pagination); + + $loopResult = new LoopResult($areas); + + foreach ($areas as $area) { + $loopResultRow = new LoopResultRow($loopResult, $area, $this->versionable, $this->timestampable, $this->countable); + + $loopResultRow + ->set('ID', $area->getId()) + ->set('NAME', $area->getName()) + ->set('POSTAGE', $area->getPostage()) + ; + + $loopResult->addRow($loopResultRow); + } + + return $loopResult; + } + + +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Template/Loop/Country.php b/core/lib/Thelia/Core/Template/Loop/Country.php index c3271a6ac..a44e49277 100755 --- a/core/lib/Thelia/Core/Template/Loop/Country.php +++ b/core/lib/Thelia/Core/Template/Loop/Country.php @@ -113,6 +113,7 @@ class Country extends BaseI18nLoop ->set("CHAPO", $country->getVirtualColumn('i18n_CHAPO')) ->set("DESCRIPTION", $country->getVirtualColumn('i18n_DESCRIPTION')) ->set("POSTSCRIPTUM", $country->getVirtualColumn('i18n_POSTSCRIPTUM')) + ->set("IS_DEFAULT", $country->getByDefault() === 1 ? "1" : "0") ->set("ISOCODE", $country->getIsocode()) ->set("ISOALPHA2", $country->getIsoalpha2()) ->set("ISOALPHA3", $country->getIsoalpha3()) diff --git a/core/lib/Thelia/Core/Template/Loop/Tax.php b/core/lib/Thelia/Core/Template/Loop/Tax.php new file mode 100644 index 000000000..1ddf18824 --- /dev/null +++ b/core/lib/Thelia/Core/Template/Loop/Tax.php @@ -0,0 +1,167 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Template\Loop; + +use Propel\Runtime\ActiveQuery\Criteria; +use Thelia\Core\Template\Element\BaseI18nLoop; +use Thelia\Core\Template\Element\LoopResult; +use Thelia\Core\Template\Element\LoopResultRow; + +use Thelia\Core\Template\Loop\Argument\ArgumentCollection; +use Thelia\Core\Template\Loop\Argument\Argument; + +use Thelia\Model\Base\TaxRuleCountryQuery; +use Thelia\Type\TypeCollection; +use Thelia\Type; +use Thelia\Model\TaxQuery; + +/** + * + * Tax loop + * + * + * Class Tax + * @package Thelia\Core\Template\Loop + * @author Etienne Roudeix + */ +class Tax extends BaseI18nLoop +{ + public $timestampable = true; + + /** + * @return ArgumentCollection + */ + protected function getArgDefinitions() + { + return new ArgumentCollection( + Argument::createIntListTypeArgument('id'), + Argument::createIntListTypeArgument('exclude'), + Argument::createIntListTypeArgument('tax_rule'), + Argument::createIntListTypeArgument('exclude_tax_rule'), + Argument::createIntTypeArgument('country'), + new Argument( + 'order', + new TypeCollection( + new Type\EnumListType(array('id', 'id_reverse', 'alpha', 'alpha_reverse')) + ), + 'alpha' + ) + ); + } + + /** + * @param $pagination + * + * @return \Thelia\Core\Template\Element\LoopResult + */ + public function exec(&$pagination) + { + $search = TaxQuery::create(); + + /* manage translations */ + $locale = $this->configureI18nProcessing($search, array('TITLE', 'DESCRIPTION')); + + $id = $this->getId(); + + if (null !== $id) { + $search->filterById($id, Criteria::IN); + } + + $exclude = $this->getExclude(); + + if (null !== $exclude) { + $search->filterById($exclude, Criteria::NOT_IN); + } + + $country = $this->getCountry(); + + $taxRule = $this->getTax_rule(); + if(null !== $taxRule && null !== $country) { + $search->filterByTaxRuleCountry( + TaxRuleCountryQuery::create() + ->filterByCountryId($country, Criteria::EQUAL) + ->filterByTaxRuleId($taxRule, Criteria::IN) + ->find(), + Criteria::IN + ); + } + + $excludeTaxRule = $this->getExclude_tax_rule(); + if(null !== $excludeTaxRule && null !== $country) { + $excludedTaxes = TaxRuleCountryQuery::create() + ->filterByCountryId($country, Criteria::EQUAL) + ->filterByTaxRuleId($excludeTaxRule, Criteria::IN) + ->find(); + /*DOES NOT WORK + * $search->filterByTaxRuleCountry( + $excludedTaxes, + Criteria::NOT_IN + );*/ + foreach($excludedTaxes as $excludedTax) { + $search->filterByTaxRuleCountry($excludedTax, Criteria::NOT_EQUAL); + } + } + + $orders = $this->getOrder(); + + foreach ($orders as $order) { + switch ($order) { + case "id": + $search->orderById(Criteria::ASC); + break; + case "id_reverse": + $search->orderById(Criteria::DESC); + break; + case "alpha": + $search->addAscendingOrderByColumn('i18n_TITLE'); + break; + case "alpha_reverse": + $search->addDescendingOrderByColumn('i18n_TITLE'); + break; + } + } + + /* perform search */ + $taxes = $this->search($search, $pagination); + + $loopResult = new LoopResult($taxes); + + foreach ($taxes as $tax) { + + $loopResultRow = new LoopResultRow($loopResult, $tax, $this->versionable, $this->timestampable, $this->countable); + + $loopResultRow + ->set("ID" , $tax->getId()) + ->set("IS_TRANSLATED" , $tax->getVirtualColumn('IS_TRANSLATED')) + ->set("LOCALE" , $locale) + ->set("TITLE" , $tax->getVirtualColumn('i18n_TITLE')) + ->set("DESCRIPTION" , $tax->getVirtualColumn('i18n_DESCRIPTION')) + ; + + $loopResult->addRow($loopResultRow); + } + + return $loopResult; + } +} diff --git a/core/lib/Thelia/Core/Template/Loop/TaxRuleCountry.php b/core/lib/Thelia/Core/Template/Loop/TaxRuleCountry.php new file mode 100644 index 000000000..91616f398 --- /dev/null +++ b/core/lib/Thelia/Core/Template/Loop/TaxRuleCountry.php @@ -0,0 +1,162 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Template\Loop; + +use Propel\Runtime\ActiveQuery\Criteria; +use Propel\Runtime\ActiveQuery\Join; +use Thelia\Core\Template\Element\BaseI18nLoop; +use Thelia\Core\Template\Element\LoopResult; +use Thelia\Core\Template\Element\LoopResultRow; + +use Thelia\Core\Template\Loop\Argument\ArgumentCollection; +use Thelia\Core\Template\Loop\Argument\Argument; + +use Thelia\Model\Map\CountryTableMap; +use Thelia\Model\Map\TaxRuleCountryTableMap; +use Thelia\Model\Map\TaxTableMap; +use Thelia\Type\TypeCollection; +use Thelia\Type; +use Thelia\Model\TaxRuleCountryQuery; + +/** + * + * TaxRuleCountry loop + * + * + * Class TaxRuleCountry + * @package Thelia\Core\Template\Loop + * @author Etienne Roudeix + */ +class TaxRuleCountry extends BaseI18nLoop +{ + public $timestampable = true; + + /** + * @return ArgumentCollection + */ + protected function getArgDefinitions() + { + return new ArgumentCollection( + Argument::createIntTypeArgument('country'), + Argument::createIntListTypeArgument('taxes'), + Argument::createIntTypeArgument('tax_rule', null, true) + ); + } + + /** + * @param $pagination + * + * @return \Thelia\Core\Template\Element\LoopResult + */ + public function exec(&$pagination) + { + $search = TaxRuleCountryQuery::create(); + + $country = $this->getCountry(); + $taxes = $this->getTaxes(); + + if((null === $country && null === $taxes)) { + throw new \InvalidArgumentException('You must provide either `country` or `taxes` parameter in tax-rule-country loop'); + } + + if((null === $country && null !== $taxes)) { + throw new \InvalidArgumentException('You must provide `country` parameter with `taxes` parameter in tax-rule-country loop'); + } + + if(null !== $taxes) { + $search->groupByCountryId(); + + $originalCountryJoin = new Join(); + $originalCountryJoin->addExplicitCondition(TaxRuleCountryTableMap::TABLE_NAME, 'TAX_RULE_ID', null, TaxRuleCountryTableMap::TABLE_NAME, 'TAX_RULE_ID', 'origin'); + $originalCountryJoin->addExplicitCondition(TaxRuleCountryTableMap::TABLE_NAME, 'TAX_ID', null, TaxRuleCountryTableMap::TABLE_NAME, 'TAX_ID', 'origin'); + $originalCountryJoin->addExplicitCondition(TaxRuleCountryTableMap::TABLE_NAME, 'POSITION', null, TaxRuleCountryTableMap::TABLE_NAME, 'POSITION', 'origin'); + $originalCountryJoin->addExplicitCondition(TaxRuleCountryTableMap::TABLE_NAME, 'COUNTRY_ID', null, TaxRuleCountryTableMap::TABLE_NAME, 'COUNTRY_ID', 'origin', Criteria::NOT_EQUAL); + $originalCountryJoin->setJoinType(Criteria::LEFT_JOIN); + + $search->addJoinObject($originalCountryJoin, 's_to_o'); + $search->where('`origin`.`COUNTRY_ID`' . Criteria::EQUAL . '?', $country, \PDO::PARAM_INT); + + $search->having('COUNT(*)=?', count($taxes), \PDO::PARAM_INT); + + /* manage tax translation */ + $this->configureI18nProcessing( + $search, + array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), + CountryTableMap::TABLE_NAME, + 'COUNTRY_ID' + ); + } elseif(null !== $country) { + $search->filterByCountryId($country); + + /* manage tax translation */ + $this->configureI18nProcessing( + $search, + array('TITLE', 'DESCRIPTION'), + TaxTableMap::TABLE_NAME, + 'TAX_ID' + ); + } + + $taxRule = $this->getTax_rule(); + $search->filterByTaxRuleId($taxRule); + + $search->orderByPosition(Criteria::ASC); + + /* perform search */ + $taxRuleCountries = $this->search($search, $pagination); + + $loopResult = new LoopResult($taxRuleCountries); + + foreach ($taxRuleCountries as $taxRuleCountry) { + + $loopResultRow = new LoopResultRow($loopResult, $taxRuleCountry, $this->versionable, $this->timestampable, $this->countable); + + if(null !== $taxes) { + $loopResultRow + ->set("TAX_RULE" , $taxRuleCountry->getTaxRuleId()) + ->set("COUNTRY" , $taxRuleCountry->getCountryId()) + ->set("COUNTRY_TITLE" , $taxRuleCountry->getVirtualColumn(CountryTableMap::TABLE_NAME . '_i18n_TITLE')) + ->set("COUNTRY_CHAPO" , $taxRuleCountry->getVirtualColumn(CountryTableMap::TABLE_NAME . '_i18n_CHAPO')) + ->set("COUNTRY_DESCRIPTION" , $taxRuleCountry->getVirtualColumn(CountryTableMap::TABLE_NAME . '_i18n_DESCRIPTION')) + ->set("COUNTRY_POSTSCRIPTUM" , $taxRuleCountry->getVirtualColumn(CountryTableMap::TABLE_NAME . '_i18n_POSTSCRIPTUM')) + ; + }elseif(null !== $country) { + $loopResultRow + ->set("TAX_RULE" , $taxRuleCountry->getTaxRuleId()) + ->set("COUNTRY" , $taxRuleCountry->getCountryId()) + ->set("TAX" , $taxRuleCountry->getTaxId()) + ->set("POSITION" , $taxRuleCountry->getPosition()) + ->set("TAX_TITLE" , $taxRuleCountry->getVirtualColumn(TaxTableMap::TABLE_NAME . '_i18n_TITLE')) + ->set("TAX_DESCRIPTION" , $taxRuleCountry->getVirtualColumn(TaxTableMap::TABLE_NAME . '_i18n_DESCRIPTION')) + ; + } + + + + $loopResult->addRow($loopResultRow); + } + + return $loopResult; + } +} diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php index 17d9e37a3..594b45ae9 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php @@ -163,16 +163,16 @@ class DataAccessFunctions extends AbstractSmartyPlugin public function countryDataAccess($params, $smarty) { - if (array_key_exists('defaultCountry', self::$dataAccessCache)) { - $defaultCountry = self::$dataAccessCache['defaultCountry']; - } else { - $defaultCountry = CountryQuery::create()->findOneByByDefault(1); - self::$dataAccessCache['defaultCountry'] = $defaultCountry; - } - - switch ($params["attr"]) { + switch ($params["ask"]) { case "default": - return $defaultCountry->getId(); + /*if (array_key_exists('defaultCountry', self::$dataAccessCache)) { + $defaultCountry = self::$dataAccessCache['defaultCountry']; + } else { + $defaultCountry = CountryQuery::create()->findOneByByDefault(1); + self::$dataAccessCache['defaultCountry'] = $defaultCountry; + }*/ + $defaultCountry = CountryQuery::create()->filterByByDefault(1)->limit(1); + return $this->dataAccessWithI18n("defaultCountry", $params, $defaultCountry); } } diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php index e7613bbac..37be09824 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php @@ -151,6 +151,11 @@ class Form extends AbstractSmartyPlugin $template->assign("options", $formFieldView->vars); + /* access to choices */ + if(isset($formFieldView->vars['choices'])) { + $template->assign("choices", $formFieldView->vars['choices']); + } + $value = $formFieldView->vars["value"]; /* FIXME: doesnt work. We got "This form should not contain extra fields." error. // We have a collection @@ -182,7 +187,8 @@ $this->assignFieldValues($template, $formFieldView->vars["full_name"], $fieldVar public function renderHiddenFormField($params, \Smarty_Internal_Template $template) { - $field = ''; + $attrFormat = '%s="%s"'; + $field = ''; $instance = $this->getInstanceFromParams($params); @@ -192,7 +198,13 @@ $this->assignFieldValues($template, $formFieldView->vars["full_name"], $fieldVar foreach ($formView->getIterator() as $row) { if ($this->isHidden($row) && $row->isRendered() === false) { - $return .= sprintf($field, $row->vars["full_name"], $row->vars["value"]); + $attributeList = array(); + if(isset($row->vars["attr"])) { + foreach($row->vars["attr"] as $attrKey => $attrValue) { + $attributeList[] = sprintf($attrFormat, $attrKey, $attrValue); + } + } + $return .= sprintf($field, $row->vars["full_name"], $row->vars["value"], implode(' ', $attributeList)); } } diff --git a/core/lib/Thelia/Exception/TaxEngineException.php b/core/lib/Thelia/Exception/TaxEngineException.php index 86f8952b9..8150d7169 100755 --- a/core/lib/Thelia/Exception/TaxEngineException.php +++ b/core/lib/Thelia/Exception/TaxEngineException.php @@ -40,9 +40,12 @@ class TaxEngineException extends \RuntimeException const UNDEFINED_REQUIREMENTS = 504; const UNDEFINED_REQUIREMENT_VALUE = 505; const UNDEFINED_TAX_RULE = 506; + const NO_TAX_IN_TAX_RULES_COLLECTION = 507; const BAD_AMOUNT_FORMAT = 601; + const FEATURE_BAD_EXPECTED_VALUE = 701; + public function __construct($message, $code = null, $previous = null) { if ($code === null) { diff --git a/core/lib/Thelia/Form/Area/AreaCountryForm.php b/core/lib/Thelia/Form/Area/AreaCountryForm.php new file mode 100644 index 000000000..c511e0b3c --- /dev/null +++ b/core/lib/Thelia/Form/Area/AreaCountryForm.php @@ -0,0 +1,89 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Form\Area; + +use Thelia\Core\Translation\Translator; +use Symfony\Component\Validator\Constraints\GreaterThan; +use Symfony\Component\Validator\Constraints\NotBlank; +use Thelia\Form\BaseForm; + + +/** + * Class AreaCountryForm + * @package Thelia\Form\Area + * @author Manuel Raynaud + */ +class AreaCountryForm extends BaseForm +{ + + /** + * + * in this function you add all the fields you need for your Form. + * Form this you have to call add method on $this->formBuilder attribute : + * + * $this->formBuilder->add("name", "text") + * ->add("email", "email", array( + * "attr" => array( + * "class" => "field" + * ), + * "label" => "email", + * "constraints" => array( + * new \Symfony\Component\Validator\Constraints\NotBlank() + * ) + * ) + * ) + * ->add('age', 'integer'); + * + * @return null + */ + protected function buildForm() + { + $this->formBuilder + ->add('area_id', 'integer', array( + 'constraints' => array( + new GreaterThan(array('value' => 0)), + new NotBlank() + ) + + )) + ->add('country_id', 'integer', array( + 'constraints' => array( + new GreaterThan(array('value' => 0)), + new NotBlank() + ), + 'label_attr' => array( + 'for' => 'area_country' + ), + 'label' => Translator::getInstance()->trans('Country') + )); + } + + /** + * @return string the name of you form. This name must be unique + */ + public function getName() + { + return 'thelia_area_country'; + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Form/Area/AreaCreateForm.php b/core/lib/Thelia/Form/Area/AreaCreateForm.php new file mode 100644 index 000000000..590001867 --- /dev/null +++ b/core/lib/Thelia/Form/Area/AreaCreateForm.php @@ -0,0 +1,79 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Form\Area; +use Thelia\Core\Translation\Translator; +use Symfony\Component\Validator\Constraints\NotBlank; +use Thelia\Form\BaseForm; + + +/** + * Class AreaCreateForm + * @package Thelia\Form\Shipping + * @author Manuel Raynaud + */ +class AreaCreateForm extends BaseForm +{ + + /** + * + * in this function you add all the fields you need for your Form. + * Form this you have to call add method on $this->formBuilder attribute : + * + * $this->formBuilder->add("name", "text") + * ->add("email", "email", array( + * "attr" => array( + * "class" => "field" + * ), + * "label" => "email", + * "constraints" => array( + * new \Symfony\Component\Validator\Constraints\NotBlank() + * ) + * ) + * ) + * ->add('age', 'integer'); + * + * @return null + */ + protected function buildForm() + { + $this->formBuilder + ->add('name', 'text', array( + 'constraints' => array( + new NotBlank() + ), + 'label_attr' => array('for' => 'shipping_name'), + 'label' => Translator::getInstance()->trans('shipping area name') + )) + + ; + } + + /** + * @return string the name of you form. This name must be unique + */ + public function getName() + { + return 'thelia_area_creation'; + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Form/Area/AreaModificationForm.php b/core/lib/Thelia/Form/Area/AreaModificationForm.php new file mode 100644 index 000000000..eefcb825a --- /dev/null +++ b/core/lib/Thelia/Form/Area/AreaModificationForm.php @@ -0,0 +1,49 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Form\Area; +use Symfony\Component\Validator\Constraints\GreaterThan; +use Thelia\Form\Area\AreaCreateForm; + + +/** + * Class AreaModificationForm + * @package Thelia\Form\Shipping + * @author Manuel Raynaud + */ +class AreaModificationForm extends AreaCreateForm +{ + public function buildForm() + { + parent::buildForm(); + + $this->formBuilder + ->add("id", "hidden", array("constraints" => array(new GreaterThan(array('value' => 0))))) + ; + } + + public function getName() + { + return 'thelia_area_modification'; + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Form/Area/AreaPostageForm.php b/core/lib/Thelia/Form/Area/AreaPostageForm.php new file mode 100644 index 000000000..ba24499e8 --- /dev/null +++ b/core/lib/Thelia/Form/Area/AreaPostageForm.php @@ -0,0 +1,88 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Form\Area; + +use Symfony\Component\Validator\Constraints\GreaterThan; +use Symfony\Component\Validator\Constraints\GreaterThanOrEqual; +use Symfony\Component\Validator\Constraints\NotBlank; +use Thelia\Form\BaseForm; +use Thelia\Core\Translation\Translator; + + +/** + * Class AreaPostageForm + * @package Thelia\Form\Area + * @author Manuel Raynaud + */ +class AreaPostageForm extends BaseForm +{ + + /** + * + * in this function you add all the fields you need for your Form. + * Form this you have to call add method on $this->formBuilder attribute : + * + * $this->formBuilder->add("name", "text") + * ->add("email", "email", array( + * "attr" => array( + * "class" => "field" + * ), + * "label" => "email", + * "constraints" => array( + * new \Symfony\Component\Validator\Constraints\NotBlank() + * ) + * ) + * ) + * ->add('age', 'integer'); + * + * @return null + */ + protected function buildForm() + { + $this->formBuilder + ->add('area_id', 'integer', array( + 'constraints' => array( + new GreaterThan(array('value' => 0)), + new NotBlank() + ) + )) + ->add('postage', 'number', array( + 'constraints' => array( + new GreaterThanOrEqual(array('value' => 0)), + new NotBlank() + ), + 'label_attr' => array('for' => 'area_postage'), + 'label' => Translator::getInstance()->trans('Postage') + )) + ; + } + + /** + * @return string the name of you form. This name must be unique + */ + public function getName() + { + return 'thelia_area_postage'; + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Form/Image/DocumentModification.php b/core/lib/Thelia/Form/Image/DocumentModification.php index 31de5af98..dbb85f5b3 100644 --- a/core/lib/Thelia/Form/Image/DocumentModification.php +++ b/core/lib/Thelia/Form/Image/DocumentModification.php @@ -122,16 +122,6 @@ abstract class DocumentModification extends BaseForm ) ) ) - ->add( - 'postscriptum', - 'text', - array( - 'constraints' => array(), - 'label' => Translator::getInstance()->trans('Post Scriptum'), - 'label_attr' => array( - 'for' => 'postscriptum' - ) - ) - ); + ; } } diff --git a/core/lib/Thelia/Form/Image/ImageModification.php b/core/lib/Thelia/Form/Image/ImageModification.php index e95a39c37..368f82410 100644 --- a/core/lib/Thelia/Form/Image/ImageModification.php +++ b/core/lib/Thelia/Form/Image/ImageModification.php @@ -130,16 +130,6 @@ abstract class ImageModification extends BaseForm ) ) ) - ->add( - 'postscriptum', - 'text', - array( - 'constraints' => array(), - 'label' => Translator::getInstance()->trans('Post Scriptum'), - 'label_attr' => array( - 'for' => 'postscriptum' - ) - ) - ); + ; } } diff --git a/core/lib/Thelia/Form/ShippingZone/ShippingZoneAddArea.php b/core/lib/Thelia/Form/ShippingZone/ShippingZoneAddArea.php new file mode 100644 index 000000000..81dd422b6 --- /dev/null +++ b/core/lib/Thelia/Form/ShippingZone/ShippingZoneAddArea.php @@ -0,0 +1,87 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Form\ShippingZone; + +use Thelia\Core\Translation\Translator; +use Symfony\Component\Validator\Constraints\GreaterThan; +use Symfony\Component\Validator\Constraints\NotBlank; +use Thelia\Form\BaseForm; + + +/** + * Class ShippingZoneAddArea + * @package Thelia\Form\ShippingZone + * @author Manuel Raynaud + */ +class ShippingZoneAddArea extends BaseForm +{ + + /** + * + * in this function you add all the fields you need for your Form. + * Form this you have to call add method on $this->formBuilder attribute : + * + * $this->formBuilder->add("name", "text") + * ->add("email", "email", array( + * "attr" => array( + * "class" => "field" + * ), + * "label" => "email", + * "constraints" => array( + * new \Symfony\Component\Validator\Constraints\NotBlank() + * ) + * ) + * ) + * ->add('age', 'integer'); + * + * @return null + */ + protected function buildForm() + { + $this->formBuilder + ->add('area_id', 'integer', array( + 'constraints' => array( + new NotBlank(), + new GreaterThan(array('value' => 0)) + ), + 'label_attr' => array('for' => 'shipping_area'), + 'label' => Translator::getInstance()->trans('Area') + )) + ->add('shipping_zone_id', 'integer', array( + 'constraints' => array( + new NotBlank(), + new GreaterThan(array('value' => 0)) + ) + )) + ; + } + + /** + * @return string the name of you form. This name must be unique + */ + public function getName() + { + return 'thelia_shippingzone_area'; + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Form/ShippingZone/ShippingZoneRemoveArea.php b/core/lib/Thelia/Form/ShippingZone/ShippingZoneRemoveArea.php new file mode 100644 index 000000000..5c4e5597b --- /dev/null +++ b/core/lib/Thelia/Form/ShippingZone/ShippingZoneRemoveArea.php @@ -0,0 +1,42 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Form\ShippingZone; + + +/** + * Class ShippingZoneRemoveArea + * @package Thelia\Form\ShippingZone + * @author Manuel Raynaud + */ +class ShippingZoneRemoveArea extends ShippingZoneAddArea +{ + + /** + * @return string the name of you form. This name must be unique + */ + public function getName() + { + return 'thelia_shippingzone_remove_area'; + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Form/TaxRuleCreationForm.php b/core/lib/Thelia/Form/TaxRuleCreationForm.php new file mode 100644 index 000000000..be3556321 --- /dev/null +++ b/core/lib/Thelia/Form/TaxRuleCreationForm.php @@ -0,0 +1,49 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + +use Symfony\Component\Validator\Constraints; +use Symfony\Component\Validator\Constraints\NotBlank; +use Thelia\Core\Translation\Translator; +use Thelia\Model\CountryQuery; + +class TaxRuleCreationForm extends BaseForm +{ + use StandardDescriptionFieldsTrait; + + protected function buildForm($change_mode = false) + { + $this->formBuilder + ->add("locale", "text", array( + "constraints" => array(new NotBlank()) + )) + ; + + $this->addStandardDescFields(array('postscriptum', 'chapo', 'locale')); + } + + public function getName() + { + return "thelia_tax_rule_creation"; + } +} diff --git a/core/lib/Thelia/Form/TaxRuleModificationForm.php b/core/lib/Thelia/Form/TaxRuleModificationForm.php new file mode 100644 index 000000000..3ec8e1f87 --- /dev/null +++ b/core/lib/Thelia/Form/TaxRuleModificationForm.php @@ -0,0 +1,66 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + +use Symfony\Component\Validator\Constraints; +use Symfony\Component\Validator\ExecutionContextInterface; +use Thelia\Model\TaxRuleQuery; + +class TaxRuleModificationForm extends TaxRuleCreationForm +{ + protected function buildForm() + { + parent::buildForm(true); + + $this->formBuilder + ->add("id", "hidden", array( + "required" => true, + "constraints" => array( + new Constraints\NotBlank(), + new Constraints\Callback( + array( + "methods" => array( + array($this, "verifyTaxRuleId"), + ), + ) + ), + ) + )) + ; + } + + public function getName() + { + return "thelia_tax_rule_modification"; + } + + public function verifyTaxRuleId($value, ExecutionContextInterface $context) + { + $taxRule = TaxRuleQuery::create() + ->findPk($value); + + if (null === $taxRule) { + $context->addViolation("Tax rule ID not found"); + } + } +} diff --git a/core/lib/Thelia/Form/TaxRuleTaxListUpdateForm.php b/core/lib/Thelia/Form/TaxRuleTaxListUpdateForm.php new file mode 100644 index 000000000..1d96c7e4d --- /dev/null +++ b/core/lib/Thelia/Form/TaxRuleTaxListUpdateForm.php @@ -0,0 +1,127 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + +use Symfony\Component\Validator\Constraints; +use Symfony\Component\Validator\ExecutionContextInterface; +use Thelia\Model\CountryQuery; +use Thelia\Model\TaxQuery; +use Thelia\Model\TaxRuleQuery; +use Thelia\Type\JsonType; + +class TaxRuleTaxListUpdateForm extends BaseForm +{ + protected function buildForm() + { + $countryList = array(); + foreach(CountryQuery::create()->find() as $country) { + $countryList[$country->getId()] = $country->getId(); + } + + $this->formBuilder + ->add("id", "hidden", array( + "required" => true, + "constraints" => array( + new Constraints\NotBlank(), + new Constraints\Callback( + array( + "methods" => array( + array($this, "verifyTaxRuleId"), + ), + ) + ), + ) + )) + ->add("tax_list", "hidden", array( + "required" => true, + "attr" => array( + "id" => 'tax_list', + ), + "constraints" => array( + new Constraints\Callback( + array( + "methods" => array( + array($this, "verifyTaxList"), + ), + ) + ), + ) + )) + ->add("country_list", "choice", array( + "choices" => $countryList, + "required" => true, + "multiple" => true, + "constraints" => array( + new Constraints\NotBlank(), + ) + )) + ; + } + + public function getName() + { + return "thelia_tax_rule_taxlistupdate"; + } + + public function verifyTaxRuleId($value, ExecutionContextInterface $context) + { + $taxRule = TaxRuleQuery::create() + ->findPk($value); + + if (null === $taxRule) { + $context->addViolation("Tax rule ID not found"); + } + } + + public function verifyTaxList($value, ExecutionContextInterface $context) + { + $jsonType = new JsonType(); + if(!$jsonType->isValid($value)) { + $context->addViolation("Tax list is not valid JSON"); + } + + $taxList = json_decode($value, true); + + /* check we have 2 level max */ + + foreach($taxList as $taxLevel1) { + if(is_array($taxLevel1)) { + foreach($taxLevel1 as $taxLevel2) { + if(is_array($taxLevel2)) { + $context->addViolation("Bad tax list JSON"); + } else { + $taxModel = TaxQuery::create()->findPk($taxLevel2); + if (null === $taxModel) { + $context->addViolation("Tax ID not found in tax list JSON"); + } + } + } + } else { + $taxModel = TaxQuery::create()->findPk($taxLevel1); + if (null === $taxModel) { + $context->addViolation("Tax ID not found in tax list JSON"); + } + } + } + } +} diff --git a/core/lib/Thelia/Model/Area.php b/core/lib/Thelia/Model/Area.php index 2a91e7cd3..f826c0fcd 100755 --- a/core/lib/Thelia/Model/Area.php +++ b/core/lib/Thelia/Model/Area.php @@ -2,8 +2,49 @@ namespace Thelia\Model; +use Propel\Runtime\Connection\ConnectionInterface; +use Thelia\Core\Event\Area\AreaEvent; +use Thelia\Core\Event\TheliaEvents; use Thelia\Model\Base\Area as BaseArea; class Area extends BaseArea { + use \Thelia\Model\Tools\ModelEventDispatcherTrait; + + public function preInsert(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::BEFORE_CREATEAREA, new AreaEvent($this)); + + return true; + } + + public function postInsert(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_CREATEAREA, new AreaEvent($this)); + } + + public function preUpdate(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::BEFORE_UPDATEAREA, new AreaEvent($this)); + + return true; + } + + public function postUpdate(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_UPDATEAREA, new AreaEvent($this)); + } + + public function preDelete(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::BEFORE_DELETEAREA, new AreaEvent($this)); + + return true; + } + + public function postDelete(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_DELETEAREA, new AreaEvent($this)); + } + } diff --git a/core/lib/Thelia/Model/TaxRule.php b/core/lib/Thelia/Model/TaxRule.php index e66e013d0..7758acdf2 100755 --- a/core/lib/Thelia/Model/TaxRule.php +++ b/core/lib/Thelia/Model/TaxRule.php @@ -3,11 +3,14 @@ namespace Thelia\Model; use Thelia\Model\Base\TaxRule as BaseTaxRule; +use Thelia\Model\Tools\ModelEventDispatcherTrait; use Thelia\TaxEngine\Calculator; use Thelia\TaxEngine\OrderProductTaxCollection; class TaxRule extends BaseTaxRule { + use ModelEventDispatcherTrait; + /** * @param Country $country * @param $untaxedAmount @@ -16,14 +19,14 @@ class TaxRule extends BaseTaxRule * * @return OrderProductTaxCollection */ - public function getTaxDetail(Country $country, $untaxedAmount, $untaxedPromoAmount, $askedLocale = null) + public function getTaxDetail(Product $product, Country $country, $untaxedAmount, $untaxedPromoAmount, $askedLocale = null) { $taxCalculator = new Calculator(); $taxCollection = new OrderProductTaxCollection(); - $taxCalculator->loadTaxRule($this, $country)->getTaxedPrice($untaxedAmount, $taxCollection, $askedLocale); + $taxCalculator->loadTaxRule($this, $country, $product)->getTaxedPrice($untaxedAmount, $taxCollection, $askedLocale); $promoTaxCollection = new OrderProductTaxCollection(); - $taxCalculator->loadTaxRule($this, $country)->getTaxedPrice($untaxedPromoAmount, $promoTaxCollection, $askedLocale); + $taxCalculator->loadTaxRule($this, $country, $product)->getTaxedPrice($untaxedPromoAmount, $promoTaxCollection, $askedLocale); foreach($taxCollection as $index => $tax) { $tax->setPromoAmount($promoTaxCollection->getKey($index)->getAmount()); diff --git a/core/lib/Thelia/Model/Tools/PositionManagementTrait.php b/core/lib/Thelia/Model/Tools/PositionManagementTrait.php index edbbad62b..e8d64d07e 100644 --- a/core/lib/Thelia/Model/Tools/PositionManagementTrait.php +++ b/core/lib/Thelia/Model/Tools/PositionManagementTrait.php @@ -120,10 +120,10 @@ trait PositionManagementTrait { try { $this ->setPosition($result->getPosition()) - ->save() + ->save($cnx) ; - $result->setDispatcher($this->getDispatcher())->setPosition($my_position)->save(); + $result->setDispatcher($this->getDispatcher())->setPosition($my_position)->save($cnx); $cnx->commit(); } diff --git a/core/lib/Thelia/TaxEngine/Calculator.php b/core/lib/Thelia/TaxEngine/Calculator.php index 8039dec39..a067f200d 100755 --- a/core/lib/Thelia/TaxEngine/Calculator.php +++ b/core/lib/Thelia/TaxEngine/Calculator.php @@ -76,7 +76,7 @@ class Calculator return $this; } - public function loadTaxRule(TaxRule $taxRule, Country $country) + public function loadTaxRule(TaxRule $taxRule, Country $country, Product $product) { $this->product = null; $this->country = null; @@ -88,8 +88,12 @@ class Calculator if($country->getId() === null) { throw new TaxEngineException('Country id is empty in Calculator::loadTaxRule', TaxEngineException::UNDEFINED_COUNTRY); } + if($product->getId() === null) { + throw new TaxEngineException('Product id is empty in Calculator::load', TaxEngineException::UNDEFINED_PRODUCT); + } $this->country = $country; + $this->product = $product; $this->taxRulesCollection = $this->taxRuleQuery->getTaxCalculatorCollection($taxRule, $country); @@ -117,7 +121,11 @@ class Calculator public function getTaxedPrice($untaxedPrice, &$taxCollection = null, $askedLocale = null) { if(null === $this->taxRulesCollection) { - throw new TaxEngineException('Tax rules collection is empty in Calculator::getTaxAmount', TaxEngineException::UNDEFINED_TAX_RULES_COLLECTION); + throw new TaxEngineException('Tax rules collection is empty in Calculator::getTaxedPrice', TaxEngineException::UNDEFINED_TAX_RULES_COLLECTION); + } + + if(null === $this->product) { + throw new TaxEngineException('Product is empty in Calculator::getTaxedPrice', TaxEngineException::UNDEFINED_PRODUCT); } if(false === filter_var($untaxedPrice, FILTER_VALIDATE_FLOAT)) { @@ -143,7 +151,7 @@ class Calculator $currentPosition = $position; } - $taxAmount = round($taxType->calculate($taxedPrice), 2); + $taxAmount = round($taxType->calculate($this->product, $taxedPrice), 2); $currentTax += $taxAmount; if(null !== $taxCollection) { @@ -167,12 +175,20 @@ class Calculator throw new TaxEngineException('Tax rules collection is empty in Calculator::getTaxAmount', TaxEngineException::UNDEFINED_TAX_RULES_COLLECTION); } + if(null === $this->product) { + throw new TaxEngineException('Product is empty in Calculator::getTaxedPrice', TaxEngineException::UNDEFINED_PRODUCT); + } + if(false === filter_var($taxedPrice, FILTER_VALIDATE_FLOAT)) { throw new TaxEngineException('BAD AMOUNT FORMAT', TaxEngineException::BAD_AMOUNT_FORMAT); } $taxRule = $this->taxRulesCollection->getLast(); + if(null === $taxRule) { + throw new TaxEngineException('Tax rules collection got no tax ', TaxEngineException::NO_TAX_IN_TAX_RULES_COLLECTION); + } + $untaxedPrice = $taxedPrice; $currentPosition = (int)$taxRule->getTaxRuleCountryPosition(); $currentFixTax = 0; @@ -192,7 +208,7 @@ class Calculator $currentPosition = $position; } - $currentFixTax += $taxType->fixAmountRetriever(); + $currentFixTax += $taxType->fixAmountRetriever($this->product); $currentTaxFactor += $taxType->pricePercentRetriever(); diff --git a/core/lib/Thelia/TaxEngine/TaxType/BaseTaxType.php b/core/lib/Thelia/TaxEngine/TaxType/BaseTaxType.php index 149e3f1df..1e0a11ca7 100755 --- a/core/lib/Thelia/TaxEngine/TaxType/BaseTaxType.php +++ b/core/lib/Thelia/TaxEngine/TaxType/BaseTaxType.php @@ -23,6 +23,7 @@ namespace Thelia\TaxEngine\TaxType; use Thelia\Exception\TaxEngineException; +use Thelia\Model\Product; use Thelia\Type\TypeInterface; /** @@ -34,14 +35,17 @@ abstract class BaseTaxType { protected $requirements = null; - public abstract function calculate($untaxedPrice); - public abstract function pricePercentRetriever(); - public abstract function fixAmountRetriever(); + public abstract function fixAmountRetriever(Product $product); public abstract function getRequirementsList(); + public function calculate(Product $product, $untaxedPrice) + { + return $untaxedPrice * $this->pricePercentRetriever() + $this->fixAmountRetriever($product); + } + public function loadRequirements($requirementsValues) { $this->requirements = $this->getRequirementsList(); diff --git a/core/lib/Thelia/TaxEngine/TaxType/FeatureFixAmountTaxType.php b/core/lib/Thelia/TaxEngine/TaxType/FeatureFixAmountTaxType.php new file mode 100755 index 000000000..32c78c1ac --- /dev/null +++ b/core/lib/Thelia/TaxEngine/TaxType/FeatureFixAmountTaxType.php @@ -0,0 +1,68 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\TaxEngine\TaxType; + +use Thelia\Exception\TaxEngineException; +use Thelia\Model\FeatureProductQuery; +use Thelia\Model\Product; +use Thelia\Type\FloatType; +use Thelia\Type\ModelValidIdType; + +/** + * + * @author Etienne Roudeix + * + */ +class FeatureFixAmountTaxType extends BaseTaxType +{ + public function pricePercentRetriever() + { + return 0; + } + + public function fixAmountRetriever(Product $product) + { + $featureId = $this->getRequirement("feature"); + + $query = FeatureProductQuery::create() + ->filterByProduct($product) + ->filterByFeatureId($featureId) + ->findOne(); + + $taxAmount = $query->getFreeTextValue(); + + $testInt = new FloatType(); + if(!$testInt->isValid($taxAmount)) { + throw new TaxEngineException('Feature value does not match FLOAT format', TaxEngineException::FEATURE_BAD_EXPECTED_VALUE); + } + + return $taxAmount; + } + + public function getRequirementsList() + { + return array( + 'feature' => new ModelValidIdType('Feature'), + ); + } +} diff --git a/core/lib/Thelia/TaxEngine/TaxType/FeatureSlicePercentTaxType.php b/core/lib/Thelia/TaxEngine/TaxType/FeatureSlicePercentTaxType.php index 911439574..311a83272 100755 --- a/core/lib/Thelia/TaxEngine/TaxType/FeatureSlicePercentTaxType.php +++ b/core/lib/Thelia/TaxEngine/TaxType/FeatureSlicePercentTaxType.php @@ -23,7 +23,7 @@ namespace Thelia\TaxEngine\TaxType; use Thelia\Type\FloatToFloatArrayType; -use Thelia\Type\ModelType; +use Thelia\Type\ModelValidIdType; /** * @@ -32,17 +32,12 @@ use Thelia\Type\ModelType; */ class featureSlicePercentTaxType extends BaseTaxType { - public function calculate($untaxedPrice) - { - - } - public function pricePercentRetriever() { } - public function fixAmountRetriever() + public function fixAmountRetriever(\Thelia\Model\Product $product) { } @@ -50,7 +45,7 @@ class featureSlicePercentTaxType extends BaseTaxType public function getRequirementsList() { return array( - 'featureId' => new ModelType('Currency'), + 'featureId' => new ModelValidIdType('Currency'), 'slices' => new FloatToFloatArrayType(), ); } diff --git a/core/lib/Thelia/TaxEngine/TaxType/FixAmountTaxType.php b/core/lib/Thelia/TaxEngine/TaxType/FixAmountTaxType.php index acd52bf8a..e62136d99 100755 --- a/core/lib/Thelia/TaxEngine/TaxType/FixAmountTaxType.php +++ b/core/lib/Thelia/TaxEngine/TaxType/FixAmountTaxType.php @@ -31,17 +31,12 @@ use Thelia\Type\FloatType; */ class FixAmountTaxType extends BaseTaxType { - public function calculate($untaxedPrice) - { - return $this->getRequirement("amount"); - } - public function pricePercentRetriever() { return 0; } - public function fixAmountRetriever() + public function fixAmountRetriever(\Thelia\Model\Product $product) { return $this->getRequirement("amount"); } diff --git a/core/lib/Thelia/TaxEngine/TaxType/PricePercentTaxType.php b/core/lib/Thelia/TaxEngine/TaxType/PricePercentTaxType.php index a8cd8c759..342f51a6d 100755 --- a/core/lib/Thelia/TaxEngine/TaxType/PricePercentTaxType.php +++ b/core/lib/Thelia/TaxEngine/TaxType/PricePercentTaxType.php @@ -31,17 +31,12 @@ use Thelia\Type\FloatType; */ class PricePercentTaxType extends BaseTaxType { - public function calculate($untaxedPrice) - { - return $untaxedPrice * $this->getRequirement("percent") * 0.01; - } - public function pricePercentRetriever() { return ($this->getRequirement("percent") * 0.01); } - public function fixAmountRetriever() + public function fixAmountRetriever(\Thelia\Model\Product $product) { return 0; } diff --git a/core/lib/Thelia/Tests/Action/OrderTest.php b/core/lib/Thelia/Tests/Action/OrderTest.php index 67628e718..7d0918650 100644 --- a/core/lib/Thelia/Tests/Action/OrderTest.php +++ b/core/lib/Thelia/Tests/Action/OrderTest.php @@ -347,7 +347,7 @@ class OrderTest extends \PHPUnit_Framework_TestCase /* check tax */ $orderProductTaxList = $orderProduct->getOrderProductTaxes(); - foreach ($cartItem->getProduct()->getTaxRule()->getTaxDetail($validDeliveryAddress->getCountry(), $cartItem->getPrice(), $cartItem->getPromoPrice()) as $index => $tax) { + foreach ($cartItem->getProduct()->getTaxRule()->getTaxDetail($cartItem->getProduct(), $validDeliveryAddress->getCountry(), $cartItem->getPrice(), $cartItem->getPromoPrice()) as $index => $tax) { $orderProductTax = $orderProductTaxList[$index]; $this->assertEquals($tax->getAmount(), $orderProductTax->getAmount()); $this->assertEquals($tax->getPromoAmount(), $orderProductTax->getPromoAmount()); diff --git a/core/lib/Thelia/Tests/TaxEngine/CalculatorTest.php b/core/lib/Thelia/Tests/TaxEngine/CalculatorTest.php index f8c6ec6c0..0dbbc73bb 100755 --- a/core/lib/Thelia/Tests/TaxEngine/CalculatorTest.php +++ b/core/lib/Thelia/Tests/TaxEngine/CalculatorTest.php @@ -126,14 +126,64 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase { $taxRulesCollection = new ObjectCollection(); + $aProduct = ProductQuery::create()->findOne(); + if(null === $aProduct) { + return; + } + $calculator = new Calculator(); $rewritingUrlQuery = $this->getProperty('taxRulesCollection'); $rewritingUrlQuery->setValue($calculator, $taxRulesCollection); + $product = $this->getProperty('product'); + $product->setValue($calculator, $aProduct); + $calculator->getTaxedPrice('foo'); } + /** + * @expectedException \Thelia\Exception\TaxEngineException + * @expectedExceptionCode 501 + */ + public function testGetUntaxedPriceAndGetTaxAmountFromTaxedPriceWithNoProductLoaded() + { + $taxRulesCollection = new ObjectCollection(); + $taxRulesCollection->setModel('\Thelia\Model\Tax'); + + $calculator = new Calculator(); + + $rewritingUrlQuery = $this->getProperty('taxRulesCollection'); + $rewritingUrlQuery->setValue($calculator, $taxRulesCollection); + + $calculator->getTaxAmountFromTaxedPrice(600.95); + } + + /** + * @expectedException \Thelia\Exception\TaxEngineException + * @expectedExceptionCode 507 + */ + public function testGetUntaxedPriceAndGetTaxAmountFromTaxedPriceWithEmptyTaxRuleCollection() + { + $taxRulesCollection = new ObjectCollection(); + $taxRulesCollection->setModel('\Thelia\Model\Tax'); + + $aProduct = ProductQuery::create()->findOne(); + if(null === $aProduct) { + return; + } + + $calculator = new Calculator(); + + $rewritingUrlQuery = $this->getProperty('taxRulesCollection'); + $rewritingUrlQuery->setValue($calculator, $taxRulesCollection); + + $product = $this->getProperty('product'); + $product->setValue($calculator, $aProduct); + + $calculator->getTaxAmountFromTaxedPrice(600.95); + } + public function testGetTaxedPriceAndGetTaxAmountFromUntaxedPrice() { $taxRulesCollection = new ObjectCollection(); @@ -163,11 +213,19 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase ->setVirtualColumn('taxRuleCountryPosition', 3); $taxRulesCollection->append($tax); + $aProduct = ProductQuery::create()->findOne(); + if(null === $aProduct) { + return; + } + $calculator = new Calculator(); $rewritingUrlQuery = $this->getProperty('taxRulesCollection'); $rewritingUrlQuery->setValue($calculator, $taxRulesCollection); + $product = $this->getProperty('product'); + $product->setValue($calculator, $aProduct); + $taxAmount = $calculator->getTaxAmountFromUntaxedPrice(500); $taxedPrice = $calculator->getTaxedPrice(500); @@ -211,11 +269,19 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase ->setVirtualColumn('taxRuleCountryPosition', 3); $taxRulesCollection->append($tax); + $aProduct = ProductQuery::create()->findOne(); + if(null === $aProduct) { + return; + } + $calculator = new Calculator(); $rewritingUrlQuery = $this->getProperty('taxRulesCollection'); $rewritingUrlQuery->setValue($calculator, $taxRulesCollection); + $product = $this->getProperty('product'); + $product->setValue($calculator, $aProduct); + $taxAmount = $calculator->getTaxAmountFromTaxedPrice(600.95); $untaxedPrice = $calculator->getUntaxedPrice(600.95); diff --git a/core/lib/Thelia/Type/ModelValidIdType.php b/core/lib/Thelia/Type/ModelValidIdType.php new file mode 100755 index 000000000..9ae94e497 --- /dev/null +++ b/core/lib/Thelia/Type/ModelValidIdType.php @@ -0,0 +1,70 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Type; + +use Propel\Runtime\ActiveQuery\ModelCriteria; +use Thelia\Exception\TypeException; + +/** + * + * @author Etienne Roudeix + * + */ +class ModelValidIdType implements TypeInterface +{ + protected $expectedModelActiveRecordQuery = null; + + /** + * @param $expectedModelActiveRecord + * @throws TypeException + */ + public function __construct($expectedModelActiveRecord) + { + $class = '\\Thelia\\Model\\' . $expectedModelActiveRecord . 'Query'; + + if (!(class_exists($class) || !new $class instanceof ModelCriteria)) { + throw new TypeException('MODEL NOT FOUND', TypeException::MODEL_NOT_FOUND); + } + + $this->expectedModelActiveRecordQuery = $class; + } + + public function getType() + { + return 'Model valid Id type'; + } + + public function isValid($value) + { + $queryClass = $this->expectedModelActiveRecordQuery; + + return null !== $queryClass::create()->findPk($value); + } + + public function getFormattedValue($value) + { + $queryClass = $this->expectedModelActiveRecordQuery; + + return $this->isValid($value) ? $queryClass::create()->findPk($value) : null; + } +} diff --git a/install/faker_add_ecotax.php b/install/faker_add_ecotax.php new file mode 100755 index 000000000..4a9c8de39 --- /dev/null +++ b/install/faker_add_ecotax.php @@ -0,0 +1,128 @@ +boot(); + +$faker = Faker\Factory::create(); + +$con = \Propel\Runtime\Propel::getConnection( + Thelia\Model\Map\ProductTableMap::DATABASE_NAME +); +$con->beginTransaction(); + +// Intialize URL management + +try { + $options = getopt('f::e::'); + + $forceEcotaxFeatureId = $options['f']; + if(null !== $forceEcotaxFeatureId && !filter_var($forceEcotaxFeatureId, FILTER_VALIDATE_INT)) { + exit('[ERROR] bad value for f option\n'); + } + + $forceEcotaxId = $options['e']; + if(null !== $forceEcotaxId && !filter_var($forceEcotaxId, FILTER_VALIDATE_INT)) { + exit('[ERROR] bad value for e option\n'); + } + + echo "Adding Ecotax feature\n"; + $feature = null; + if(null !== $forceEcotaxFeatureId) { + $feature = \Thelia\Model\FeatureQuery::create()->findPk($forceEcotaxFeatureId); + if(null === $feature) { + echo "Feature `$forceEcotaxFeatureId` not found\n"; + } + } + if(null === $feature) { + $feature = new \Thelia\Model\Feature(); + $feature->setVisible(1); + $feature->save(); + echo sprintf("Ecotax feature added with ID \n", $feature->getId()); + } + + $fr = \Thelia\Model\Base\FeatureI18nQuery::create() + ->filterByLocale('fr_FR') + ->filterByFeature($feature) + ->findOne(); + if(null === $fr) { + $fr = new \Thelia\Model\FeatureI18n(); + $fr->setLocale('fr_FR') + ->setFeature($feature); + } + $fr->setTitle('Ecotaxe'); + $fr->save($con); + + $us = \Thelia\Model\Base\FeatureI18nQuery::create() + ->filterByLocale('en_US') + ->filterByFeature($feature) + ->findOne(); + if(null === $us) { + $us = new \Thelia\Model\FeatureI18n(); + $us->setLocale('en_US') + ->setFeature($feature); + } + $us->setTitle('Ecotax'); + $us->save($con); + + echo "Adding ecotax\n"; + + $tax = null; + if(null !== $forceEcotaxId) { + $tax = \Thelia\Model\TaxQuery::create()->findPk($forceEcotaxId); + if(null === $tax) { + echo "Tax `$forceEcotaxId` not found\n"; + } + } + if(null === $tax) { + $tax = new \Thelia\Model\Tax(); + $tax->setType('FeatureFixAmountTaxType') + ->setSerializedRequirements( + base64_encode(sprintf('{"feature":%s}', $feature->getId())) + ); + $tax->save(); + echo sprintf("Ecotax added with ID \n", $tax->getId()); + } + + $fr = \Thelia\Model\Base\TaxI18nQuery::create() + ->filterByLocale('fr_FR') + ->filterByTax($tax) + ->findOne(); + if(null === $fr) { + $fr = new \Thelia\Model\TaxI18n(); + $fr->setLocale('fr_FR') + ->setTax($tax); + } + $fr->setTitle('Ecotaxe'); + $fr->save($con); + + $us = \Thelia\Model\Base\TaxI18nQuery::create() + ->filterByLocale('en_US') + ->filterByTax($tax) + ->findOne(); + if(null === $us) { + $us = new \Thelia\Model\TaxI18n(); + $us->setLocale('en_US') + ->setTax($tax); + } + $us->setTitle('Ecotax'); + $us->save($con); + + $con->commit(); + + echo "Successfully terminated.\n"; + +} catch (Exception $e) { + echo "error : ".$e->getMessage()."\n"; + $con->rollBack(); +} \ No newline at end of file diff --git a/install/insert.sql b/install/insert.sql index d91c511dc..8e6585a5b 100755 --- a/install/insert.sql +++ b/install/insert.sql @@ -1149,25 +1149,31 @@ INSERT INTO `country_i18n` (`id`, `locale`, `title`, `description`, `chapo`, `po INSERT INTO `tax` (`id`, `type`, `serialized_requirements`, `created_at`, `updated_at`) VALUES - (1, 'PricePercentTaxType', 'eyJwZXJjZW50IjoxOS42fQ==', NOW(), NOW()); + (1, 'PricePercentTaxType', 'eyJwZXJjZW50IjoxOS42fQ==', NOW(), NOW()), + (2, 'PricePercentTaxType', 'eyJwZXJjZW50Ijo1LjV9', NOW(), NOW()); INSERT INTO `tax_i18n` (`id`, `locale`, `title`) VALUES (1, 'fr_FR', 'TVA française à 19.6%'), - (1, 'en_US', 'French 19.6% VAT'); - + (1, 'en_US', 'French 19.6% VAT'), + (2, 'fr_FR', 'TVA française à 5.5%'), + (2, 'en_US', 'French 5.5% VAT'); INSERT INTO `tax_rule` (`id`, `is_default`, `created_at`, `updated_at`) VALUES - (1, 1, NOW(), NOW()); + (1, 1, NOW(), NOW()), + (2, 0, NOW(), NOW()); INSERT INTO `tax_rule_i18n` (`id`, `locale`, `title`) VALUES (1, 'fr_FR', 'TVA française à 19.6%'), - (1, 'en_US', 'French 19.6% VAT'); + (1, 'en_US', 'French 19.6% VAT'), + (2, 'fr_FR', 'TVA française à 5.5%'), + (2, 'en_US', 'French 5.5% VAT'); INSERT INTO `tax_rule_country` (`tax_rule_id`, `country_id`, `tax_id`, `position`, `created_at`, `updated_at`) VALUES - (1, 64, 1, 1, NOW(), NOW()); + (1, 64, 1, 1, NOW(), NOW()), + (2, 64, 2, 1, NOW(), NOW()); INSERT INTO `order_status`(`id`, `code`, `created_at`, `updated_at`) VALUES (1, 'not_paid', NOW(), NOW()), diff --git a/templates/admin/default/assets/less/thelia/thelia.less b/templates/admin/default/assets/less/thelia/thelia.less index 11dc5bd74..4838ddda7 100644 --- a/templates/admin/default/assets/less/thelia/thelia.less +++ b/templates/admin/default/assets/less/thelia/thelia.less @@ -326,3 +326,79 @@ height: 30px; } } + +// -- Drag & drop -- +.take{ + + .draggable{ + border: 2px dashed @gray-light; + margin-bottom: 10px; + padding: 10px; + + &:last-child{ + margin-bottom: 0; + } + } + + .over{ + .drop-message{ + border-color: @brand-primary; + color: @brand-primary; + } + } + +} + +.place{ + + .over{ + .drop-message{ + border-color: @brand-primary; + color: @brand-primary; + } + } + + .panel-body{ + + .draggable, .drag{ + margin: 5px 0; + padding: 10px; + border: 1px dashed @gray-light; + } + + .drop-group{ + padding: 10px; + border: 2px dashed @gray-light; + margin-bottom: 10px; + + &:last-child{ + margin-bottom: 0; + } + } + + } + +} + +.take, .place{ + + .drop-message{ + width: 50%; + margin: 10px auto; + padding: 10px; + color: @gray; + border: 2px dashed @gray; + text-align: center; + .opacity(0.5); + + .glyphicon{ + display: block; + font-size: @font-size-large; + margin-bottom: 10px; + } + } + + .ui-draggable-dragging{ + z-index: 100; + } +} \ No newline at end of file diff --git a/templates/admin/default/category-edit.html b/templates/admin/default/category-edit.html index f8b564822..78cb7b681 100755 --- a/templates/admin/default/category-edit.html +++ b/templates/admin/default/category-edit.html @@ -66,7 +66,7 @@ {form_hidden_fields form=$form} {form_field form=$form field='success_url'} - + {/form_field} {form_field form=$form field='locale'} diff --git a/templates/admin/default/configuration.html b/templates/admin/default/configuration.html index 50e9296ac..b5484a9af 100644 --- a/templates/admin/default/configuration.html +++ b/templates/admin/default/configuration.html @@ -58,6 +58,13 @@ {/loop} + {loop type="auth" name="pcc6" roles="ADMIN" permissions="admin.configuration.taxe-rules"} + + {intl l='Taxes rules'} + + + {/loop} + {module_include location='catalog_configuration_bottom'} diff --git a/templates/admin/default/countries.html b/templates/admin/default/countries.html index 6de45aa38..6791131df 100644 --- a/templates/admin/default/countries.html +++ b/templates/admin/default/countries.html @@ -52,17 +52,17 @@ {loop name="countries" type="country" backend_context="1" lang=$lang_id order=$order} {$ID} - {$TITLE} + {$TITLE}
- +{*
- + *} {$ISOCODE} {$ISOALPHA3} diff --git a/templates/admin/default/country-edit.html b/templates/admin/default/country-edit.html index b5d68e46b..447a6b355 100644 --- a/templates/admin/default/country-edit.html +++ b/templates/admin/default/country-edit.html @@ -30,8 +30,8 @@
{form name="thelia.admin.country.modification"} - - + + {include file = "includes/inner-form-toolbar.html"}
{* Be sure to get the country ID, even if the form could not be validated *} @@ -40,8 +40,12 @@ {form_hidden_fields form=$form} {form_field form=$form field='success_url'} - - {/form_field} + + {/form_field} + + {form_field form=$form field='locale'} + + {/form_field} {if $form_error}
{$form_error_message}
{/if} @@ -74,51 +78,26 @@
{/form_field} -
- -
- {intl l="Translations"} -
- {loop type="lang" name="lang"} -
-
-
-

- {intl l=$TITLE} {$TITLE} -

-
-
- {form_field form=$form field='title'} -
- - -
- {/form_field} - {form_field form=$form field='chapo'} -
- - -
- {/form_field} - {form_field form=$form field='description'} -
- - -
- {/form_field} -
+ {form_field form=$form field='title'} +
+ +
-
- {/loop} - -
- + {/form_field} + {form_field form=$form field='chapo'} +
+ + +
+ {/form_field} + {form_field form=$form field='description'} +
+ + +
+ {/form_field}
-
{/form} diff --git a/templates/admin/default/shipping-configuration-edit.html b/templates/admin/default/shipping-configuration-edit.html index b17dc6de4..9e0268d0f 100644 --- a/templates/admin/default/shipping-configuration-edit.html +++ b/templates/admin/default/shipping-configuration-edit.html @@ -8,12 +8,12 @@
- + {loop name="area-edit" type="area" id=$area_id}
@@ -21,30 +21,40 @@
- {intl l='Edit shipping configuration %title' title=$TITLE} + {intl l='Edit shipping configuration %title' title=$NAME}
+ {form name="thelia.admin.area.country"} +
+ {form_hidden_fields form=$form} - - + {form_field form=$form field='success_url'} + + {/form_field} + + {form_field form=$form field='area_id'} + + {/form_field} + {form_field form=$form field='country_id'} +
- + {loop name="country-without-area" type="country" with_area="0" backend_context="1" lang=$lang_id} + + {/loop}
- + {/form_field}
- + {/form}
@@ -57,44 +67,46 @@ + {loop name="country-area" type="country" area=$area_id backend_context="1"} - Wallis-et-Futuna + {$TITLE} - - - - - - - Polynésie française - - - - - - - - USA - Alabama - - + + {/loop} -
- -
- + {form name="thelia.admin.area.postage"} + + {form_hidden_fields form=$form} + + {form_field form=$form field='success_url'} + + {/form_field} + + {form_field form=$form field='area_id'} + + {/form_field} + {form_field form=$form field='postage'} + +
+ + {if $error } + {$message} + {/if}
+ {/form_field} + {/form} @@ -106,14 +118,23 @@
+ {/loop} + {elseloop rel="area-edit"} +
+
+ {intl l="No area defined with this id"} +
+
+ {/elseloop}
{* Delete related content confirmation dialog *} {capture "delete_country_dialog"} - + + {/capture} {include @@ -123,7 +144,7 @@ dialog_title = {intl l="Remove country"} dialog_message = {intl l="Do you really want to remove this country ?"} - form_action = {url path=''} + form_action = {url path='/admin/configuration/shipping_configuration/country/remove'} form_content = {$smarty.capture.delete_country_dialog nofilter} } {/block} @@ -135,4 +156,12 @@ {javascripts file='assets/js/bootstrap-select/bootstrap-select.js'} {/javascripts} + + {/block} \ No newline at end of file diff --git a/templates/admin/default/shipping-configuration.html b/templates/admin/default/shipping-configuration.html index 067256d5f..d4c8147c2 100644 --- a/templates/admin/default/shipping-configuration.html +++ b/templates/admin/default/shipping-configuration.html @@ -41,66 +41,24 @@ + {loop name="area-list" type="area" backend_context="1"} - France + {$NAME} {module_include location='shipping_configuration_table_row'} - {if ! $SECURED} -
- {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.shipping-configuration.change"} - - {/loop} - {loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.configuration.shipping-configuration.delete"} - - {/loop} -
- {else} - - {/if} - - - - Outre-Mer DOM - - {module_include location='shipping_configuration_table_row'} - - - {if ! $SECURED} -
- {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.shipping-configuration.change"} - - {/loop} - {loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.configuration.shipping-configuration.delete"} - - {/loop} -
- {else} - - {/if} - - - - Outre-Mer TOM - - {module_include location='shipping_configuration_table_row'} - - - {if ! $SECURED} -
- {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.shipping-configuration.change"} - - {/loop} - {loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.configuration.shipping-configuration.delete"} - - {/loop} -
- {else} - - {/if} +
+ {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.shipping-configuration.change"} + + {/loop} + {loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.configuration.shipping-configuration.delete"} + + {/loop} +
+ {/loop}
@@ -117,16 +75,23 @@ {* Capture the dialog body, to pass it to the generic dialog *} {capture "creation_dialog"} + {form name="thelia.admin.area.create"} + {form_hidden_fields form=$form} - + {form_field form=$form field='success_url'} + {* on success, redirect to the edition page, _ID_ is replaced with the created object ID, see controller *} + + {/form_field} + {form_field form=$form field="name"}
- - + +
+ {/form_field} {module_include location='shipping_configuration_create_form'} - + {/form} {/capture} {include @@ -139,7 +104,7 @@ dialog_ok_label = {intl l="Create this shipping configuration"} dialog_cancel_label = {intl l="Cancel"} - form_action = {url path='/admin/configuration/configuration/shipping_configuration/create'} + form_action = {url path='/admin/configuration/shipping_configuration/create'} form_enctype = '' form_error_message = $form_error_message } @@ -147,7 +112,7 @@ {* Delete confirmation dialog *} {capture "delete_dialog"} - + {module_include location='shipping_configuration_delete_form'} @@ -163,4 +128,14 @@ form_action = {url path='/admin/configuration/shipping_configuration/delete'} form_content = {$smarty.capture.delete_dialog nofilter} } +{/block} + +{block name="javascript-initialization"} + {/block} \ No newline at end of file diff --git a/templates/admin/default/shipping-zones-edit.html b/templates/admin/default/shipping-zones-edit.html index c330f9064..139e3d164 100644 --- a/templates/admin/default/shipping-zones-edit.html +++ b/templates/admin/default/shipping-zones-edit.html @@ -26,25 +26,33 @@
- -
- + {form name="thelia.shopping_zone_area"} + + {form_hidden_fields form=$form} + {form_field form=$form field='success_url'} + {* the url the user is redirected to on login success *} + {/form_field} + + {form_field form=$form field='shipping_zone_id'} + + {/form_field} + + {form_field form=$form field='area_id'} +
- + {loop name="area.module.not_associated" type="area" without_zone=$shipping_zones_id} + + {/loop}
- + {/form_field}
- + {/form}
@@ -57,30 +65,16 @@ + {loop type="area" name="area.module.associated" with_zone=$shipping_zones_id} - France + {$NAME} - - - - - - - Zone 1 - - - - - - - - Zone 2 - - + + {/loop}
@@ -97,7 +91,22 @@ {* Delete related content confirmation dialog *} {capture "delete_zone_dialog"} - + {form name="thelia.shopping_zone_remove_area"} + {form_hidden_fields form=$form} + + {form_field form=$form field='success_url'} + {* the url the user is redirected to on login success *} + {/form_field} + + {form_field form=$form field='shipping_zone_id'} + + {/form_field} + + {form_field form=$form field='area_id'} + + {/form_field} + + {/form} {/capture} {include @@ -107,7 +116,7 @@ dialog_title = {intl l="Remove zone"} dialog_message = {intl l="Do you really want to remove this zone ?"} - form_action = {url path=''} + form_action = {url path='/admin/configuration/shipping_zones/area/remove'} form_content = {$smarty.capture.delete_zone_dialog nofilter} } {/block} @@ -119,4 +128,12 @@ {javascripts file='assets/js/bootstrap-select/bootstrap-select.js'} {/javascripts} + + {/block} \ No newline at end of file diff --git a/templates/admin/default/shipping-zones.html b/templates/admin/default/shipping-zones.html index 20ffef799..5eeed61c4 100644 --- a/templates/admin/default/shipping-zones.html +++ b/templates/admin/default/shipping-zones.html @@ -36,57 +36,21 @@ + {loop type="delivery" name="delivery.list" backend_context="1"} - So Colissimo + {$TITLE} {module_include location='shipping_zones_table_row'} - {if ! $SECURED} -
- {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.shipping-zones.change"} - - {/loop} -
- {else} - - {/if} +
+ {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.shipping-zones.change"} + + {/loop} +
- - - Chronopost - - {module_include location='shipping_zones_table_row'} - - - {if ! $SECURED} -
- {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.shipping-zones.change"} - - {/loop} -
- {else} - - {/if} - - - - Kiala - - {module_include location='shipping_zones_table_row'} - - - {if ! $SECURED} -
- {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.shipping-zones.change"} - - {/loop} -
- {else} - - {/if} - - + + {/loop}
@@ -98,24 +62,4 @@
- - {* Delete confirmation dialog *} - - {capture "delete_dialog"} - - - {module_include location='shipping_zones_delete_form'} - - {/capture} - - {include - file = "includes/generic-confirm-dialog.html" - - dialog_id = "delete_dialog" - dialog_title = {intl l="Delete shipping zone"} - dialog_message = {intl l="Do you really want to delete this shipping zone ?"} - - form_action = {url path='/admin/configuration/shipping_zones/delete'} - form_content = {$smarty.capture.delete_dialog nofilter} - } {/block} \ No newline at end of file diff --git a/templates/admin/default/tax-rule-edit.html b/templates/admin/default/tax-rule-edit.html new file mode 100644 index 000000000..c236e7bc4 --- /dev/null +++ b/templates/admin/default/tax-rule-edit.html @@ -0,0 +1,397 @@ +{extends file="admin-layout.tpl"} + +{block name="page-title"}{intl l='Edit a tax rule'}{/block} + +{block name="check-permissions"}admin.configuration.taxes-rules.edit{/block} + +{block name="main-content"} + +{assign oder_tab {$smarty.get.tab|default:$smarty.post.tab|default:'data'}} +{assign asked_country {$smarty.get.country|default:{country ask="default" attr="id"}}} + +
+ +
+ + + + {loop type="tax-rule" name="tax-rule" id=$tax_rule_id backend_context="1" lang=$edit_language_id} + +
+
+ + + +
+
+ +
+ + {form name="thelia.admin.taxrule.modification"} + +
+ + {include + file = "includes/inner-form-toolbar.html" + hide_submit_buttons = false + + page_url = {url path="/admin/configuration/taxes_rules/update/$tax_rule_id" tab=data} + close_url = {url path="/admin/configuration/taxes_rules"} + } + + {* Be sure to get the product ID, even if the form could not be validated *} + + + {form_hidden_fields form=$form} + + {form_field form=$form field='success_url'} + + {/form_field} + + {form_field form=$form field='locale'} + + {/form_field} + + {if $form_error}
{$form_error_message}
{/if} + + {form_field form=$form field='title'} +
+ + +
+ {/form_field} + + {form_field form=$form field='description'} +
+ + + +
+ {/form_field} + +
+
+
+ +
+

{intl l='Tax rule created on %date_create. Last modification: %date_change' date_create={format_date date=$CREATE_DATE} date_change={format_date date=$UPDATE_DATE}}

+
+
+
+
+ +
+ {/form} +
+ +
+ +
+ +
+ {intl l="Manage taxes"} +
+ +
+ +
+ + +
+
+ +

{intl l="Countries that have the same tax rule"} :

+

+ + {$matchedCountries.first=$asked_country} + + {loop type="tax-rule-country" name="same-country-list" tax_rule=$ID taxes="1,2,3" country=$asked_country} + {$matchedCountries[]=$COUNTRY} + {$COUNTRY_TITLE} + {/loop} + + {elseloop rel="same-country-list"} + {intl l="NONE"} + {/elseloop} +

+ +
+
+ +
+
+

{intl l="Manage the tax rule taxes appliance order"}

+
+
+ {assign lastPosition 0} + {loop type="tax-rule-country" name="existing-tax-list" tax_rule=$ID country=$asked_country} + {if $POSITION != $lastPosition} + {assign lastPosition $POSITION} + {if $LOOP_COUNT > 1} +
+ {/if} +
+

+ + {intl l="Add tax to this group"} +

+ {/if} + +
{$TAX_TITLE}
+ + {if $LOOP_COUNT == $LOOP_TOTAL} +
+ {/if} + {/loop} + + {elseloop rel="existing-tax-list"} +
+

+ + {intl l="Add tax to this group"} +

+
+ + {/elseloop} + +
+ +
+ + {intl l="Apply"} + +
+
+ +
+
+

Available taxes

+
+
+ {loop type="tax" name="tax-list" exclude_tax_rule=$ID country=$asked_country} +
{$TITLE}
+ {/loop} +
+ +
+ +
+
+ +
+
+ +
+
+ + {/loop} + +
+ + {* Confirmation dialog *} + {form name="thelia.admin.taxrule.taxlistupdate"} + + {if $form_error_message} + {$taxUpdateError = true} + {else} + {$taxUpdateError = false} + {/if} + + {* Capture the dialog body, to pass it to the generic dialog *} + {capture "tax_list_update_dialog"} + + + + + {form_hidden_fields form=$form} + + {form_field form=$form field='country_list'} + +

{intl l="Tax rule taxes will be update for the following countries :"}

+
+ +
+ + {/form_field} + + {/capture} + + {include + file = "includes/generic-create-dialog.html" + + dialog_id = "tax_list_update_dialog" + dialog_title = {intl l="Update tax rule taxes"} + dialog_body = {$smarty.capture.tax_list_update_dialog nofilter} + + dialog_ok_label = {intl l="Edit tax rule taxes"} + dialog_cancel_label = {intl l="Cancel"} + + form_action = {url path="/admin/configuration/taxes_rules/saveTaxes"} + form_enctype = {form_enctype form=$form} + form_error_message = $form_error_message + } + + {/form} + +{/block} + +{block name="javascript-initialization"} + + {javascripts file='assets/js/bootstrap-select/bootstrap-select.js'} + + {/javascripts} + + {javascripts file='assets/js/main.js'} + + {/javascripts} + + + + + +{/block} \ No newline at end of file diff --git a/templates/admin/default/taxes-rules.html b/templates/admin/default/taxes-rules.html new file mode 100644 index 000000000..67e8b414a --- /dev/null +++ b/templates/admin/default/taxes-rules.html @@ -0,0 +1,168 @@ +{extends file="admin-layout.tpl"} + +{block name="page-title"}{intl l='Taxes rules'}{/block} + +{block name="check-permissions"}admin.taxes-rules.view{/block} + +{block name="main-content"} +
+ +
+ + + + {module_include location='taxes_rules_top'} + +
+
+
+
+ + + + + + + + + + + + {loop type="tax-rule" name="taxes-rules"} + + + + + + + + {/loop} + + +
+ {intl l="Taxes rules"} + {loop type="auth" name="can_create" roles="ADMIN" permissions="admin.taxes-rules.create"} + + + + {/loop} +
{intl l="Name"}{intl l="Description"}{intl l="Actions"}
{$TITLE}{$DESCRIPTION} +
+ {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.taxes-rules.change"} + + {/loop} + + {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.taxes-rules.change"} + + {/loop} +
+
+
+
+
+
+ + {module_include location='taxes_rules_bottom'} + +
+
+ +{* -- Add tax rule confirmation dialog ----------------------------------- *} +{form name="thelia.admin.taxrule.add"} + +{if $form_error_message} + {$taxCreateError = true} +{else} + {$taxCreateError = false} +{/if} + +{* Capture the dialog body, to pass it to the generic dialog *} +{capture "tax_rule_create_dialog"} + + {form_hidden_fields form=$form} + + {form_field form=$form field='locale'} + + {/form_field} + + {if $form_error}
{$form_error_message}
{/if} + + {form_field form=$form field='title'} +
+ + +
+ {/form_field} + + {form_field form=$form field='description'} +
+ + + +
+ {/form_field} + +{/capture} + + {include + file = "includes/generic-create-dialog.html" + + dialog_id = "tax_rule_create_dialog" + dialog_title = {intl l="Create a new tax rule"} + dialog_body = {$smarty.capture.tax_rule_create_dialog nofilter} + + dialog_ok_label = {intl l="Create"} + dialog_cancel_label = {intl l="Cancel"} + + form_action = {url path="/admin/configuration/taxes_rules/add"} + form_enctype = {form_enctype form=$form} + form_error_message = $form_error_message + } + +{/form} + +{* -- Delete tax rule confirmation dialog ----------------------------------- *} + +{capture "tax_rule_delete_dialog"} + + + {module_include location='tax_rule_delete_form'} + +{/capture} + +{include + file = "includes/generic-confirm-dialog.html" + + dialog_id = "tax_rule_delete_dialog" + dialog_title = {intl l="Delete tax rule"} + dialog_message = {intl l="Do you really want to delete this tax rule ?"} + + form_action = {url path='/admin/configuration/taxes_rules/delete'} + form_content = {$smarty.capture.tax_rule_delete_dialog nofilter} +} + +{/block} + +{block name="javascript-initialization"} + + + +{/block} \ No newline at end of file