diff --git a/core/lib/Thelia/Action/TaxRule.php b/core/lib/Thelia/Action/TaxRule.php index 9fda846e1..b3656d993 100644 --- a/core/lib/Thelia/Action/TaxRule.php +++ b/core/lib/Thelia/Action/TaxRule.php @@ -23,9 +23,12 @@ 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; @@ -83,6 +86,51 @@ class TaxRule extends BaseAction implements EventSubscriberInterface } } + /** + * @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 */ @@ -106,6 +154,7 @@ class TaxRule extends BaseAction implements EventSubscriberInterface 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/config.xml b/core/lib/Thelia/Config/Resources/config.xml index 71ecede6e..39ba508fd 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -114,6 +114,7 @@
+ diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index ca9465967..ff829f67f 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -792,6 +792,10 @@ Thelia\Controller\Admin\TaxRuleController::processUpdateAction + + Thelia\Controller\Admin\TaxRuleController::processUpdateTaxesAction + + Thelia\Controller\Admin\TaxRuleController::deleteAction diff --git a/core/lib/Thelia/Controller/Admin/TaxRuleController.php b/core/lib/Thelia/Controller/Admin/TaxRuleController.php index 3756f686c..b50a39638 100644 --- a/core/lib/Thelia/Controller/Admin/TaxRuleController.php +++ b/core/lib/Thelia/Controller/Admin/TaxRuleController.php @@ -27,6 +27,7 @@ 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; @@ -71,9 +72,7 @@ class TaxRuleController extends AbstractCrudController protected function getUpdateEvent($formData) { - $event = new TaxRuleEvent( - TaxRuleQuery::create()->findPk($formData['id']) - ); + $event = new TaxRuleEvent(); $event->setLocale($formData['locale']); $event->setId($formData['id']); @@ -83,6 +82,17 @@ class TaxRuleController extends AbstractCrudController 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(); @@ -112,6 +122,16 @@ class TaxRuleController extends AbstractCrudController 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; @@ -134,11 +154,11 @@ class TaxRuleController extends AbstractCrudController return $object->getId(); } - protected function getViewArguments() + protected function getViewArguments($country = null) { return array( 'tab' => $this->getRequest()->get('tab', 'data'), - 'country' => $this->getRequest()->get('country', CountryQuery::create()->findOneByByDefault(1)->getIsoalpha3()), + 'country' => $country === null ? $this->getRequest()->get('country', CountryQuery::create()->findOneByByDefault(1)->getId()) : $country, ); } @@ -164,12 +184,12 @@ class TaxRuleController extends AbstractCrudController return $this->render('tax-rule-edit', array_merge($this->getViewArguments(), $this->getRouteArguments())); } - protected function redirectToEditionTemplate() + protected function redirectToEditionTemplate($request = null, $country = null) { // We always return to the feature edition form $this->redirectToRoute( "admin.configuration.taxes-rules.update", - $this->getViewArguments(), + $this->getViewArguments($country), $this->getRouteArguments() ); } @@ -181,4 +201,70 @@ class TaxRuleController extends AbstractCrudController ); } + 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/Event/Tax/TaxRuleEvent.php b/core/lib/Thelia/Core/Event/Tax/TaxRuleEvent.php index 93cfced8e..e364bfd84 100644 --- a/core/lib/Thelia/Core/Event/Tax/TaxRuleEvent.php +++ b/core/lib/Thelia/Core/Event/Tax/TaxRuleEvent.php @@ -33,6 +33,8 @@ class TaxRuleEvent extends ActionEvent protected $id; protected $title; protected $description; + protected $countryList; + protected $taxList; public function __construct(TaxRule $taxRule = null) { @@ -95,4 +97,26 @@ class TaxRuleEvent extends ActionEvent { 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 a6ca5b238..e2e0d128c 100755 --- a/core/lib/Thelia/Core/Event/TheliaEvents.php +++ b/core/lib/Thelia/Core/Event/TheliaEvents.php @@ -509,6 +509,7 @@ final class TheliaEvents 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 ----------------------------------------- diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php index e7613bbac..76be30ad0 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php @@ -182,7 +182,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 +193,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/Form/TaxRuleCreationForm.php b/core/lib/Thelia/Form/TaxRuleCreationForm.php index 4b9a66f7b..a069bd005 100644 --- a/core/lib/Thelia/Form/TaxRuleCreationForm.php +++ b/core/lib/Thelia/Form/TaxRuleCreationForm.php @@ -35,17 +35,6 @@ class TaxRuleCreationForm extends BaseForm ->add("locale", "text", array( "constraints" => array(new NotBlank()) )) - ->add("country", "text", array( - "constraints" => array( - new Constraints\Callback( - array( - "methods" => array( - array($this, "verifyCountry"), - ), - ) - ), - ), - )) ; } @@ -53,14 +42,4 @@ class TaxRuleCreationForm extends BaseForm { return "thelia_tax_rule_creation"; } - - public function verifyCountry($value, ExecutionContextInterface $context) - { - $country = CountryQuery::create() - ->findOneByIsoalpha3($value); - - if (null === $country) { - $context->addViolation("Country ISOALPHA3 not found"); - } - } } diff --git a/core/lib/Thelia/Form/TaxRuleModificationForm.php b/core/lib/Thelia/Form/TaxRuleModificationForm.php index 62aa90118..5884e4b57 100644 --- a/core/lib/Thelia/Form/TaxRuleModificationForm.php +++ b/core/lib/Thelia/Form/TaxRuleModificationForm.php @@ -48,26 +48,6 @@ class TaxRuleModificationForm extends TaxRuleCreationForm ), ) )) - ->add("tab", "text", array( - "constraints" => array( - new Constraints\Choice( - array( - 'choices' => array('data', 'taxes'), - ) - ) - ), - )) - ->add("country", "text", array( - "constraints" => array( - new Constraints\Callback( - array( - "methods" => array( - array($this, "verifyCountry"), - ), - ) - ), - ) - )) ; // Add standard description fields diff --git a/core/lib/Thelia/Form/TaxRuleTaxListUpdateForm.php b/core/lib/Thelia/Form/TaxRuleTaxListUpdateForm.php index 62aa90118..1d96c7e4d 100644 --- a/core/lib/Thelia/Form/TaxRuleTaxListUpdateForm.php +++ b/core/lib/Thelia/Form/TaxRuleTaxListUpdateForm.php @@ -24,15 +24,19 @@ 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 TaxRuleModificationForm extends TaxRuleCreationForm +class TaxRuleTaxListUpdateForm extends BaseForm { - use StandardDescriptionFieldsTrait; - protected function buildForm() { - parent::buildForm(true); + $countryList = array(); + foreach(CountryQuery::create()->find() as $country) { + $countryList[$country->getId()] = $country->getId(); + } $this->formBuilder ->add("id", "hidden", array( @@ -48,35 +52,35 @@ class TaxRuleModificationForm extends TaxRuleCreationForm ), ) )) - ->add("tab", "text", array( - "constraints" => array( - new Constraints\Choice( - array( - 'choices' => array('data', 'taxes'), - ) - ) + ->add("tax_list", "hidden", array( + "required" => true, + "attr" => array( + "id" => 'tax_list', ), - )) - ->add("country", "text", array( "constraints" => array( new Constraints\Callback( array( "methods" => array( - array($this, "verifyCountry"), + array($this, "verifyTaxList"), ), ) ), ) )) + ->add("country_list", "choice", array( + "choices" => $countryList, + "required" => true, + "multiple" => true, + "constraints" => array( + new Constraints\NotBlank(), + ) + )) ; - - // Add standard description fields - $this->addStandardDescFields(array('postscriptum', 'chapo', 'locale')); } public function getName() { - return "thelia_tax_rule_modification"; + return "thelia_tax_rule_taxlistupdate"; } public function verifyTaxRuleId($value, ExecutionContextInterface $context) @@ -88,4 +92,36 @@ class TaxRuleModificationForm extends TaxRuleCreationForm $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/templates/admin/default/tax-rule-edit.html b/templates/admin/default/tax-rule-edit.html index e23f5a7c2..c236e7bc4 100644 --- a/templates/admin/default/tax-rule-edit.html +++ b/templates/admin/default/tax-rule-edit.html @@ -6,7 +6,7 @@ {block name="main-content"} -{assign oder_tab {$smarty.get.tab|default:"data"}} +{assign oder_tab {$smarty.get.tab|default:$smarty.post.tab|default:'data'}} {assign asked_country {$smarty.get.country|default:{country ask="default" attr="id"}}}
@@ -152,13 +152,23 @@

{/if} -
{$TAX_TITLE} - {$POSITION}
+
{$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"} + {intl l="Apply"}
@@ -204,48 +214,64 @@
{* 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"} - {capture "confirmation_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 :"}

- {loop type="country" name="country-list"} - + {/loop}
-
- {/capture} + {/form_field} - {include - file = "includes/generic-create-dialog.html" + {/capture} - dialog_id = "confirmation_dialog" - dialog_title = {intl l="Edit tax rule taxes"} - dialog_body = {$smarty.capture.confirmation_dialog nofilter} + {include + file = "includes/generic-create-dialog.html" - dialog_ok_label = {intl l="Edit tax rule taxes"} + dialog_id = "tax_list_update_dialog" + dialog_title = {intl l="Update tax rule taxes"} + dialog_body = {$smarty.capture.tax_list_update_dialog nofilter} - form_action = {url path='/admin/categories/create'} + dialog_ok_label = {intl l="Edit tax rule taxes"} + dialog_cancel_label = {intl l="Cancel"} - form_error_message = $form_error_message - } + 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} @@ -253,11 +279,15 @@