From 4a0403040c1e485553d330541362741ba10cbc93 Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Mon, 7 Oct 2013 10:46:12 +0200 Subject: [PATCH 01/12] add tax files --- templates/admin/default/configuration.html | 7 + templates/admin/default/tax-rule-edit.html | 256 +++++++++++++++++++++ templates/admin/default/taxes-rules.html | 90 ++++++++ 3 files changed, 353 insertions(+) create mode 100644 templates/admin/default/tax-rule-edit.html create mode 100644 templates/admin/default/taxes-rules.html 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/tax-rule-edit.html b/templates/admin/default/tax-rule-edit.html new file mode 100644 index 000000000..b5ac36973 --- /dev/null +++ b/templates/admin/default/tax-rule-edit.html @@ -0,0 +1,256 @@ +{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"} +
+ +
+ + + +
+
+ +
+ {intl l="Edit tax rule $TITLE"} +
+ +
+ +
+ +
+ + + + +
+
+ +
+ +

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

+

+ Italy + England + Japan +

+ +
+
+ +
+
+

Create a tax rule

+
+
+ +
+

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

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

List of taxes

+
+
+
Cras justo odio
+
Dapibus ac facilisis in
+
Morbi leo risus
+
Porta ac consectetur ac
+
Vestibulum at eros
+
+ +
+ +
+
+ +
+
+ +
+ + {* Confirmation dialog *} + + {capture "confirmation_dialog"} + +
+
+ +
+
+ + {/capture} + + {include + file = "includes/generic-create-dialog.html" + + dialog_id = "confirmation_dialog" + dialog_title = {intl l="Create a new tax rule"} + dialog_body = {$smarty.capture.confirmation_dialog nofilter} + + dialog_ok_label = {intl l="Create this tax rule"} + + form_action = {url path='/admin/categories/create'} + + form_error_message = $form_error_message + } + +{/block} + +{block name="javascript-initialization"} + + {javascripts file='assets/js/bootstrap-select/bootstrap-select.js'} + + {/javascripts} + + {javascripts file='assets/js/main.js'} + + {/javascripts} + + + {literal} + + {/literal} + +{/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..a0284d107 --- /dev/null +++ b/templates/admin/default/taxes-rules.html @@ -0,0 +1,90 @@ +{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'} + +
+
+
+
+ + + + + + + + + + + + + + + + +
+ {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"}
Eco taxeLorem ipsum dolor sit amet, consectetur adipisicing elit. Consequatur, aperiam, voluptatibus odio numquam adipisci! +
+ {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.delete"} + + {/loop} +
+
+
+
+
+
+ + {module_include location='taxes_rules_bottom'} + +
+
+ +{* -- Delete category 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} \ No newline at end of file From 0efb01220cc352c1d3d9d126b423a9e5c56e5e51 Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Mon, 7 Oct 2013 11:06:54 +0200 Subject: [PATCH 02/12] add tax admin css --- .../Controller/Admin/TaxRuleController.php | 45 +++++++++++ .../default/assets/less/thelia/thelia.less | 76 +++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 core/lib/Thelia/Controller/Admin/TaxRuleController.php diff --git a/core/lib/Thelia/Controller/Admin/TaxRuleController.php b/core/lib/Thelia/Controller/Admin/TaxRuleController.php new file mode 100644 index 000000000..2a4f37a77 --- /dev/null +++ b/core/lib/Thelia/Controller/Admin/TaxRuleController.php @@ -0,0 +1,45 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Controller\Admin; + +/** + * Class TaxRuleController + * @package Thelia\Controller\Admin + * @author Manuel Raynaud + */ +class TaxRuleController extends BaseAdminController +{ + public function defaultAction() + { + if (null !== $response = $this->checkAuth("admin.taxes-rules.view")) return $response; + return $this->render("taxes-rules", array("display_taxes_rules" => 20)); + } + + public function updateAction($tax_rule_id){ + return $this->render("tax-rule-edit", array( + "tax_rule_id" => $tax_rule_id + )); + } + +} \ No newline at end of file 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 From fe3aea4ab72fbe9024faecf874fb29d6f17a8a26 Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Mon, 7 Oct 2013 11:57:43 +0200 Subject: [PATCH 03/12] tax types --- .../Thelia/Config/Resources/routing/admin.xml | 13 ++++ .../Thelia/Exception/TaxEngineException.php | 2 + .../Thelia/TaxEngine/TaxType/BaseTaxType.php | 3 +- .../TaxType/FeatureFixAmountTaxType.php | 72 +++++++++++++++++++ .../TaxType/FeatureSlicePercentTaxType.php | 2 +- .../TaxEngine/TaxType/FixAmountTaxType.php | 2 +- .../TaxEngine/TaxType/PricePercentTaxType.php | 2 +- install/insert.sql | 24 +++++-- templates/admin/default/taxes-rules.html | 14 ++-- 9 files changed, 120 insertions(+), 14 deletions(-) create mode 100755 core/lib/Thelia/TaxEngine/TaxType/FeatureFixAmountTaxType.php diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index 2f85b57bc..8121a1ef4 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -777,6 +777,19 @@ + + + + Thelia\Controller\Admin\TaxRuleController::defaultAction + + + + Thelia\Controller\Admin\TaxRuleController::updateAction + \d+ + + + + diff --git a/core/lib/Thelia/Exception/TaxEngineException.php b/core/lib/Thelia/Exception/TaxEngineException.php index 86f8952b9..c36f7428c 100755 --- a/core/lib/Thelia/Exception/TaxEngineException.php +++ b/core/lib/Thelia/Exception/TaxEngineException.php @@ -43,6 +43,8 @@ class TaxEngineException extends \RuntimeException 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/TaxEngine/TaxType/BaseTaxType.php b/core/lib/Thelia/TaxEngine/TaxType/BaseTaxType.php index 149e3f1df..ef010a406 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; /** @@ -38,7 +39,7 @@ abstract class BaseTaxType public abstract function pricePercentRetriever(); - public abstract function fixAmountRetriever(); + public abstract function fixAmountRetriever(Product $product); public abstract function 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..ea88dc494 --- /dev/null +++ b/core/lib/Thelia/TaxEngine/TaxType/FeatureFixAmountTaxType.php @@ -0,0 +1,72 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\TaxEngine\TaxType; + +use Thelia\Exception\TaxEngineException; +use Thelia\Model\FeatureProductQuery; +use Thelia\Model\Product; +use Thelia\Type\FloatType; + +/** + * + * @author Etienne Roudeix + * + */ +class FeatureFixAmountTaxType extends BaseTaxType +{ + public function calculate($untaxedPrice) + { + return $this->getRequirement("amount"); + } + + public function pricePercentRetriever() + { + return 0; + } + + public function fixAmountRetriever(Product $product) + { + $featureId = $this->getRequirement("featureId"); + + $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( + 'featureId' => new ModelType('Feature'), + ); + } +} diff --git a/core/lib/Thelia/TaxEngine/TaxType/FeatureSlicePercentTaxType.php b/core/lib/Thelia/TaxEngine/TaxType/FeatureSlicePercentTaxType.php index 911439574..fc599c7b5 100755 --- a/core/lib/Thelia/TaxEngine/TaxType/FeatureSlicePercentTaxType.php +++ b/core/lib/Thelia/TaxEngine/TaxType/FeatureSlicePercentTaxType.php @@ -42,7 +42,7 @@ class featureSlicePercentTaxType extends BaseTaxType } - public function fixAmountRetriever() + public function fixAmountRetriever(\Thelia\Model\Product $product) { } diff --git a/core/lib/Thelia/TaxEngine/TaxType/FixAmountTaxType.php b/core/lib/Thelia/TaxEngine/TaxType/FixAmountTaxType.php index acd52bf8a..6f16560d8 100755 --- a/core/lib/Thelia/TaxEngine/TaxType/FixAmountTaxType.php +++ b/core/lib/Thelia/TaxEngine/TaxType/FixAmountTaxType.php @@ -41,7 +41,7 @@ class FixAmountTaxType extends BaseTaxType 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..b3fbd59b0 100755 --- a/core/lib/Thelia/TaxEngine/TaxType/PricePercentTaxType.php +++ b/core/lib/Thelia/TaxEngine/TaxType/PricePercentTaxType.php @@ -41,7 +41,7 @@ class PricePercentTaxType extends BaseTaxType return ($this->getRequirement("percent") * 0.01); } - public function fixAmountRetriever() + public function fixAmountRetriever(\Thelia\Model\Product $product) { return 0; } diff --git a/install/insert.sql b/install/insert.sql index d91c511dc..c99f99920 100755 --- a/install/insert.sql +++ b/install/insert.sql @@ -1149,25 +1149,37 @@ 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()), + (3, 'FeatureFixAmountTaxType', 'eyJmZWF0dXJlIjowfQ==', 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'), + (3, 'fr_FR', 'Ecotaxe UE'), + (3, 'en_US', 'EU ecotax'); 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, 'fr_FR', 'TVA française à 19.6% avec ecotaxe'), + (1, 'en_US', 'French 19.6% VAT plus ecotax'), + (2, 'fr_FR', 'TVA française à 5.5% avec ecotaxe'), + (2, 'en_US', 'French 5.5% VAT plus ecotax'); 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, 3, 1, NOW(), NOW()), + (1, 64, 1, 2, NOW(), NOW()), + (2, 64, 3, 1, NOW(), NOW()), + (2, 64, 2, 2, NOW(), NOW()); INSERT INTO `order_status`(`id`, `code`, `created_at`, `updated_at`) VALUES (1, 'not_paid', NOW(), NOW()), diff --git a/templates/admin/default/taxes-rules.html b/templates/admin/default/taxes-rules.html index a0284d107..f1edc9bd9 100644 --- a/templates/admin/default/taxes-rules.html +++ b/templates/admin/default/taxes-rules.html @@ -40,21 +40,27 @@ + + {loop type="tax-rule" name="taxes-rules"} + - Eco taxe - Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequatur, aperiam, voluptatibus odio numquam adipisci! + {$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.delete"} + {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.taxes-rules.change"} {/loop}
- + + + {/loop} +
From b84e8630333a98e63f1a69b08cf9a9e7283e2590 Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Mon, 7 Oct 2013 14:36:20 +0200 Subject: [PATCH 04/12] fix tests --- core/lib/Thelia/Action/Order.php | 1 + .../Thelia/Exception/TaxEngineException.php | 1 + core/lib/Thelia/Model/TaxRule.php | 6 +- core/lib/Thelia/TaxEngine/Calculator.php | 24 +++- .../Thelia/TaxEngine/TaxType/BaseTaxType.php | 7 +- .../TaxType/FeatureFixAmountTaxType.php | 10 +- .../TaxType/FeatureSlicePercentTaxType.php | 9 +- .../TaxEngine/TaxType/FixAmountTaxType.php | 5 - .../TaxEngine/TaxType/PricePercentTaxType.php | 5 - core/lib/Thelia/Tests/Action/OrderTest.php | 2 +- .../Thelia/Tests/TaxEngine/CalculatorTest.php | 66 +++++++++ core/lib/Thelia/Type/ModelValidIdType.php | 70 ++++++++++ install/faker_add_ecotax.php | 128 ++++++++++++++++++ install/insert.sql | 18 +-- 14 files changed, 306 insertions(+), 46 deletions(-) create mode 100755 core/lib/Thelia/Type/ModelValidIdType.php create mode 100755 install/faker_add_ecotax.php 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/Exception/TaxEngineException.php b/core/lib/Thelia/Exception/TaxEngineException.php index c36f7428c..8150d7169 100755 --- a/core/lib/Thelia/Exception/TaxEngineException.php +++ b/core/lib/Thelia/Exception/TaxEngineException.php @@ -40,6 +40,7 @@ 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; diff --git a/core/lib/Thelia/Model/TaxRule.php b/core/lib/Thelia/Model/TaxRule.php index e66e013d0..72d8ae851 100755 --- a/core/lib/Thelia/Model/TaxRule.php +++ b/core/lib/Thelia/Model/TaxRule.php @@ -16,14 +16,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/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 ef010a406..1e0a11ca7 100755 --- a/core/lib/Thelia/TaxEngine/TaxType/BaseTaxType.php +++ b/core/lib/Thelia/TaxEngine/TaxType/BaseTaxType.php @@ -35,14 +35,17 @@ abstract class BaseTaxType { protected $requirements = null; - public abstract function calculate($untaxedPrice); - public abstract function pricePercentRetriever(); 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 index ea88dc494..32c78c1ac 100755 --- a/core/lib/Thelia/TaxEngine/TaxType/FeatureFixAmountTaxType.php +++ b/core/lib/Thelia/TaxEngine/TaxType/FeatureFixAmountTaxType.php @@ -26,6 +26,7 @@ use Thelia\Exception\TaxEngineException; use Thelia\Model\FeatureProductQuery; use Thelia\Model\Product; use Thelia\Type\FloatType; +use Thelia\Type\ModelValidIdType; /** * @@ -34,11 +35,6 @@ use Thelia\Type\FloatType; */ class FeatureFixAmountTaxType extends BaseTaxType { - public function calculate($untaxedPrice) - { - return $this->getRequirement("amount"); - } - public function pricePercentRetriever() { return 0; @@ -46,7 +42,7 @@ class FeatureFixAmountTaxType extends BaseTaxType public function fixAmountRetriever(Product $product) { - $featureId = $this->getRequirement("featureId"); + $featureId = $this->getRequirement("feature"); $query = FeatureProductQuery::create() ->filterByProduct($product) @@ -66,7 +62,7 @@ class FeatureFixAmountTaxType extends BaseTaxType public function getRequirementsList() { return array( - 'featureId' => new ModelType('Feature'), + 'feature' => new ModelValidIdType('Feature'), ); } } diff --git a/core/lib/Thelia/TaxEngine/TaxType/FeatureSlicePercentTaxType.php b/core/lib/Thelia/TaxEngine/TaxType/FeatureSlicePercentTaxType.php index fc599c7b5..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,11 +32,6 @@ use Thelia\Type\ModelType; */ class featureSlicePercentTaxType extends BaseTaxType { - public function calculate($untaxedPrice) - { - - } - public function pricePercentRetriever() { @@ -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 6f16560d8..e62136d99 100755 --- a/core/lib/Thelia/TaxEngine/TaxType/FixAmountTaxType.php +++ b/core/lib/Thelia/TaxEngine/TaxType/FixAmountTaxType.php @@ -31,11 +31,6 @@ use Thelia\Type\FloatType; */ class FixAmountTaxType extends BaseTaxType { - public function calculate($untaxedPrice) - { - return $this->getRequirement("amount"); - } - public function pricePercentRetriever() { return 0; diff --git a/core/lib/Thelia/TaxEngine/TaxType/PricePercentTaxType.php b/core/lib/Thelia/TaxEngine/TaxType/PricePercentTaxType.php index b3fbd59b0..342f51a6d 100755 --- a/core/lib/Thelia/TaxEngine/TaxType/PricePercentTaxType.php +++ b/core/lib/Thelia/TaxEngine/TaxType/PricePercentTaxType.php @@ -31,11 +31,6 @@ 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); 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 c99f99920..ec88c0866 100755 --- a/install/insert.sql +++ b/install/insert.sql @@ -1150,18 +1150,14 @@ 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()), - (2, 'PricePercentTaxType', 'eyJwZXJjZW50Ijo1LjV9', NOW(), NOW()), - (3, 'FeatureFixAmountTaxType', 'eyJmZWF0dXJlIjowfQ==', 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'), (2, 'fr_FR', 'TVA française à 5.5%'), - (2, 'en_US', 'French 5.5% VAT'), - (3, 'fr_FR', 'Ecotaxe UE'), - (3, 'en_US', 'EU ecotax'); - + (2, 'en_US', 'French 5.5% VAT'); INSERT INTO `tax_rule` (`id`, `is_default`, `created_at`, `updated_at`) VALUES (1, 1, NOW(), NOW()), @@ -1169,16 +1165,14 @@ INSERT INTO `tax_rule` (`id`, `is_default`, `created_at`, `updated_at`) INSERT INTO `tax_rule_i18n` (`id`, `locale`, `title`) VALUES - (1, 'fr_FR', 'TVA française à 19.6% avec ecotaxe'), - (1, 'en_US', 'French 19.6% VAT plus ecotax'), - (2, 'fr_FR', 'TVA française à 5.5% avec ecotaxe'), - (2, 'en_US', 'French 5.5% VAT plus ecotax'); + (1, 'fr_FR', 'TVA française à 19.6%'), + (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, 3, 1, NOW(), NOW()), (1, 64, 1, 2, NOW(), NOW()), - (2, 64, 3, 1, NOW(), NOW()), (2, 64, 2, 2, NOW(), NOW()); INSERT INTO `order_status`(`id`, `code`, `created_at`, `updated_at`) VALUES From 942638281a83da9b212db9672f1d2b25c6626d37 Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Mon, 7 Oct 2013 17:18:38 +0200 Subject: [PATCH 05/12] tax edition --- core/lib/Thelia/Config/Resources/config.xml | 2 + .../Thelia/Config/Resources/routing/admin.xml | 4 +- .../Controller/Admin/TaxRuleController.php | 157 ++++++++++++++++-- .../Thelia/Core/Event/Tax/TaxRuleEvent.php | 53 ++++++ core/lib/Thelia/Core/Event/TheliaEvents.php | 7 + .../lib/Thelia/Core/Template/Loop/Country.php | 1 + .../Smarty/Plugins/DataAccessFunctions.php | 18 +- core/lib/Thelia/Form/TaxRuleCreationForm.php | 60 +++++++ .../Thelia/Form/TaxRuleModificationForm.php | 52 ++++++ templates/admin/default/tax-rule-edit.html | 151 ++++++++++------- templates/admin/default/taxes-rules.html | 2 +- 11 files changed, 419 insertions(+), 88 deletions(-) create mode 100644 core/lib/Thelia/Core/Event/Tax/TaxRuleEvent.php create mode 100644 core/lib/Thelia/Form/TaxRuleCreationForm.php create mode 100644 core/lib/Thelia/Form/TaxRuleModificationForm.php diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index d4d63ac77..706c2f84d 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -111,6 +111,8 @@
+ + diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index 8121a1ef4..f8cd21c9b 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -779,11 +779,11 @@ - + Thelia\Controller\Admin\TaxRuleController::defaultAction - + Thelia\Controller\Admin\TaxRuleController::updateAction \d+ diff --git a/core/lib/Thelia/Controller/Admin/TaxRuleController.php b/core/lib/Thelia/Controller/Admin/TaxRuleController.php index 2a4f37a77..223e73fa1 100644 --- a/core/lib/Thelia/Controller/Admin/TaxRuleController.php +++ b/core/lib/Thelia/Controller/Admin/TaxRuleController.php @@ -23,23 +23,154 @@ namespace Thelia\Controller\Admin; -/** - * Class TaxRuleController - * @package Thelia\Controller\Admin - * @author Manuel Raynaud - */ -class TaxRuleController extends BaseAdminController +use Thelia\Core\Event\Tax\TaxRuleEvent; +use Thelia\Core\Event\TheliaEvents; +use Thelia\Form\TaxRuleCreationForm; +use Thelia\Form\TaxRuleModificationForm; +use Thelia\Model\CountryQuery; +use Thelia\Model\TaxRuleQuery; + +class TaxRuleController extends AbstractCrudController { - public function defaultAction() + public function __construct() { - if (null !== $response = $this->checkAuth("admin.taxes-rules.view")) return $response; - return $this->render("taxes-rules", array("display_taxes_rules" => 20)); + 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 + ); } - public function updateAction($tax_rule_id){ - return $this->render("tax-rule-edit", array( - "tax_rule_id" => $tax_rule_id - )); + protected function getCreationForm() + { + return new TaxRuleCreationForm($this->getRequest()); + } + + protected function getUpdateForm() + { + return new TaxRuleModificationForm($this->getRequest()); + } + + protected function getCreationEvent($formData) + { + $event = new TaxRuleEvent(); + + /* @todo fill event */ + + return $event; + } + + protected function getUpdateEvent($formData) + { + $event = new TaxRuleEvent(); + + /* @todo fill event */ + + return $event; + } + + protected function getDeleteEvent() + { + $event = new TaxRuleEvent(); + + /* @todo fill event */ + + 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 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() + { + return array( + 'tax_rule_id' => $this->getRequest()->get('tax_rule_id'), + 'country_isoalpha3' => $this->getRequest()->get('country_isoalpha3'), + ); + } + + protected function renderListTemplate($currentOrder) + { + // We always return to the feature edition form + return $this->render( + 'taxes-rules', + array() + ); + } + + protected function renderEditionTemplate() + { + /* check the country exists */ + $country = CountryQuery::create()->findOneByIsoalpha3($this->getRequest()->get('country_isoalpha3')); + if(null === $country) { + $this->redirectToListTemplate(); + } + + // We always return to the feature edition form + return $this->render('tax-rule-edit', $this->getViewArguments()); + } + + protected function redirectToEditionTemplate() + { + // We always return to the feature edition form + $this->redirectToRoute( + "admin.configuration.taxes-rules.update", + $this->getViewArguments() + ); + } + + protected function redirectToListTemplate() + { + $this->redirectToRoute( + "admin.configuration.taxes-rules.list", + array() + ); } } \ 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..d12d81fba --- /dev/null +++ b/core/lib/Thelia/Core/Event/Tax/TaxRuleEvent.php @@ -0,0 +1,53 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event\Tax; +use Thelia\Core\Event\ActionEvent; +use Thelia\Model\TaxRule; + +class TaxRuleEvent extends ActionEvent +{ + protected $taxRule = null; + + 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; + } +} diff --git a/core/lib/Thelia/Core/Event/TheliaEvents.php b/core/lib/Thelia/Core/Event/TheliaEvents.php index f0dc68702..a6ca5b238 100755 --- a/core/lib/Thelia/Core/Event/TheliaEvents.php +++ b/core/lib/Thelia/Core/Event/TheliaEvents.php @@ -503,6 +503,13 @@ 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"; + // -- Product templates management ----------------------------------------- const TEMPLATE_CREATE = "action.createTemplate"; diff --git a/core/lib/Thelia/Core/Template/Loop/Country.php b/core/lib/Thelia/Core/Template/Loop/Country.php index 3a05b684a..f41173a33 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/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/Form/TaxRuleCreationForm.php b/core/lib/Thelia/Form/TaxRuleCreationForm.php new file mode 100644 index 000000000..a54e8b0c5 --- /dev/null +++ b/core/lib/Thelia/Form/TaxRuleCreationForm.php @@ -0,0 +1,60 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + +use Symfony\Component\Validator\Constraints; +use Symfony\Component\Validator\Constraints\NotBlank; +use Thelia\Core\Translation\Translator; + +class TaxRuleCreationForm extends BaseForm +{ + protected function buildForm() + { + $this->formBuilder + ->add("title" , "text" , array( + "constraints" => array( + new NotBlank() + ), + "label" => Translator::getInstance()->trans("Title *"), + "label_attr" => array( + "for" => "title" + )) + ) + ->add("locale" , "text" , array( + "constraints" => array( + new NotBlank() + )) + ) + ->add("feature_id", "hidden", array( + "constraints" => array( + new NotBlank() + )) + ) + ; + } + + 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..44cde86cd --- /dev/null +++ b/core/lib/Thelia/Form/TaxRuleModificationForm.php @@ -0,0 +1,52 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + +use Symfony\Component\Validator\Constraints; +use Symfony\Component\Validator\Constraints\GreaterThan; + +class TaxRuleModificationForm extends FeatureCreationForm +{ + use StandardDescriptionFieldsTrait; + + protected function buildForm() + { + $this->formBuilder + ->add("id", "hidden", array( + "constraints" => array( + new GreaterThan( + array('value' => 0) + ) + ) + )) + ; + + // Add standard description fields + $this->addStandardDescFields(); + } + + public function getName() + { + return "thelia_tax_rule_modification"; + } +} diff --git a/templates/admin/default/tax-rule-edit.html b/templates/admin/default/tax-rule-edit.html index b5ac36973..e58b67ddf 100644 --- a/templates/admin/default/tax-rule-edit.html +++ b/templates/admin/default/tax-rule-edit.html @@ -5,6 +5,9 @@ {block name="check-permissions"}admin.configuration.taxes-rules.edit{/block} {block name="main-content"} + +{assign oder_tab {$smarty.get.tab|default:"data"}} +
@@ -13,86 +16,106 @@
  • {intl l="Home"}
  • {intl l="Configuration"}
  • {intl l="Taxes rules"}
  • -
  • {intl l='Editing tax rule "%name"' name="{$TITLE}"}
  • +
  • {intl l='Editing tax rule'}
  • + {loop type="tax-rule" name="tax-rule" id=$tax_rule_id} +
    -
    - {intl l="Edit tax rule $TITLE"} -
    + - +
    +
    + + TODO + {form name="thelia.admin.taxrule.modification"} + + + + + + + + {/form} -
    - -
    - - - - -
    - +
    -

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

    -

    - Italy - England - Japan -

    +
    + {intl l="Manage taxes"} +
    -
    -
    +
    + + +
    -
    -
    -

    Create a tax rule

    -
    -
    +

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

    +

    + Italy + England + Japan +

    -
    -

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

    +
    +
    + +
    +
    +

    Create a tax rule

    +
    +
    + +
    +

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

    +
    + +
    +
    -
    - -
    + {intl l="Apply"} - {intl l="Apply"} - -
    -
    - -
    -
    -

    List of taxes

    -
    -
    Cras justo odio
    -
    Dapibus ac facilisis in
    -
    Morbi leo risus
    -
    Porta ac consectetur ac
    -
    Vestibulum at eros
    -
    - @@ -102,6 +125,8 @@
    + {/loop} +
    {* Confirmation dialog *} diff --git a/templates/admin/default/taxes-rules.html b/templates/admin/default/taxes-rules.html index f1edc9bd9..bc6cb4ed3 100644 --- a/templates/admin/default/taxes-rules.html +++ b/templates/admin/default/taxes-rules.html @@ -49,7 +49,7 @@
    {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"} From 0f6951bc21257a875532cf3074665f4666907fe5 Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Tue, 8 Oct 2013 16:02:58 +0200 Subject: [PATCH 06/12] tax rule update and delation --- core/lib/Thelia/Action/TaxRule.php | 113 ++++++++++++++++++ core/lib/Thelia/Config/Resources/action.xml | 5 + .../Thelia/Config/Resources/routing/admin.xml | 10 +- .../Controller/Admin/TaxRuleController.php | 36 +++--- .../Thelia/Core/Event/Tax/TaxRuleEvent.php | 45 +++++++ core/lib/Thelia/Form/TaxRuleCreationForm.php | 42 ++++--- .../Thelia/Form/TaxRuleModificationForm.php | 47 +++++++- templates/admin/default/tax-rule-edit.html | 64 +++++++++- templates/admin/default/taxes-rules.html | 14 ++- 9 files changed, 331 insertions(+), 45 deletions(-) create mode 100644 core/lib/Thelia/Action/TaxRule.php diff --git a/core/lib/Thelia/Action/TaxRule.php b/core/lib/Thelia/Action/TaxRule.php new file mode 100644 index 000000000..9fda846e1 --- /dev/null +++ b/core/lib/Thelia/Action/TaxRule.php @@ -0,0 +1,113 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Action; + +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Thelia\Core\Event\Tax\TaxRuleEvent; +use Thelia\Core\Event\TheliaEvents; +use Thelia\Model\TaxRule as TaxRuleModel; +use Thelia\Model\TaxRuleQuery; + +class TaxRule extends BaseAction implements EventSubscriberInterface +{ + /** + * @param TaxRuleEvent $event + */ + public function create(TaxRuleEvent $event) + { + $product = new TaxRuleModel(); + + $product + ->setDispatcher($this->getDispatcher()) + + ->setRef($event->getRef()) + ->setTitle($event->getTitle()) + ->setLocale($event->getLocale()) + ->setVisible($event->getVisible()) + + // Set the default tax rule to this product + ->setTaxRule(TaxRuleQuery::create()->findOneByIsDefault(true)) + + //public function create($defaultCategoryId, $basePrice, $priceCurrencyId, $taxRuleId, $baseWeight) { + + ->create( + $event->getDefaultCategory(), + $event->getBasePrice(), + $event->getCurrencyId(), + $event->getTaxRuleId(), + $event->getBaseWeight() + ); + ; + + $event->setTaxRule($product); + } + + /** + * @param TaxRuleEvent $event + */ + public function update(TaxRuleEvent $event) + { + if (null !== $taxRule = TaxRuleQuery::create()->findPk($event->getId())) { + + $taxRule + ->setLocale($event->getLocale()) + ->setTitle($event->getTitle()) + ->setDescription($event->getDescription()) + ->save() + ; + + + + $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_DELETE => array("delete", 128), + + ); + } +} diff --git a/core/lib/Thelia/Config/Resources/action.xml b/core/lib/Thelia/Config/Resources/action.xml index 87575f59b..67c14bce5 100755 --- a/core/lib/Thelia/Config/Resources/action.xml +++ b/core/lib/Thelia/Config/Resources/action.xml @@ -106,6 +106,11 @@ + + + + + diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index f8cd21c9b..8d60250a4 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -783,11 +783,19 @@ Thelia\Controller\Admin\TaxRuleController::defaultAction - + Thelia\Controller\Admin\TaxRuleController::updateAction \d+ + + Thelia\Controller\Admin\TaxRuleController::processUpdateAction + + + + Thelia\Controller\Admin\TaxRuleController::deleteAction + + diff --git a/core/lib/Thelia/Controller/Admin/TaxRuleController.php b/core/lib/Thelia/Controller/Admin/TaxRuleController.php index 223e73fa1..3756f686c 100644 --- a/core/lib/Thelia/Controller/Admin/TaxRuleController.php +++ b/core/lib/Thelia/Controller/Admin/TaxRuleController.php @@ -71,9 +71,14 @@ class TaxRuleController extends AbstractCrudController protected function getUpdateEvent($formData) { - $event = new TaxRuleEvent(); + $event = new TaxRuleEvent( + TaxRuleQuery::create()->findPk($formData['id']) + ); - /* @todo fill event */ + $event->setLocale($formData['locale']); + $event->setId($formData['id']); + $event->setTitle($formData['title']); + $event->setDescription($formData['description']); return $event; } @@ -82,7 +87,9 @@ class TaxRuleController extends AbstractCrudController { $event = new TaxRuleEvent(); - /* @todo fill event */ + $event->setId( + $this->getRequest()->get('tax_rule_id', 0) + ); return $event; } @@ -128,10 +135,17 @@ class TaxRuleController extends AbstractCrudController } protected function getViewArguments() + { + return array( + 'tab' => $this->getRequest()->get('tab', 'data'), + 'country' => $this->getRequest()->get('country', CountryQuery::create()->findOneByByDefault(1)->getIsoalpha3()), + ); + } + + protected function getRouteArguments() { return array( 'tax_rule_id' => $this->getRequest()->get('tax_rule_id'), - 'country_isoalpha3' => $this->getRequest()->get('country_isoalpha3'), ); } @@ -146,14 +160,8 @@ class TaxRuleController extends AbstractCrudController protected function renderEditionTemplate() { - /* check the country exists */ - $country = CountryQuery::create()->findOneByIsoalpha3($this->getRequest()->get('country_isoalpha3')); - if(null === $country) { - $this->redirectToListTemplate(); - } - // We always return to the feature edition form - return $this->render('tax-rule-edit', $this->getViewArguments()); + return $this->render('tax-rule-edit', array_merge($this->getViewArguments(), $this->getRouteArguments())); } protected function redirectToEditionTemplate() @@ -161,15 +169,15 @@ class TaxRuleController extends AbstractCrudController // We always return to the feature edition form $this->redirectToRoute( "admin.configuration.taxes-rules.update", - $this->getViewArguments() + $this->getViewArguments(), + $this->getRouteArguments() ); } protected function redirectToListTemplate() { $this->redirectToRoute( - "admin.configuration.taxes-rules.list", - array() + "admin.configuration.taxes-rules.list" ); } diff --git a/core/lib/Thelia/Core/Event/Tax/TaxRuleEvent.php b/core/lib/Thelia/Core/Event/Tax/TaxRuleEvent.php index d12d81fba..93cfced8e 100644 --- a/core/lib/Thelia/Core/Event/Tax/TaxRuleEvent.php +++ b/core/lib/Thelia/Core/Event/Tax/TaxRuleEvent.php @@ -29,6 +29,11 @@ class TaxRuleEvent extends ActionEvent { protected $taxRule = null; + protected $locale; + protected $id; + protected $title; + protected $description; + public function __construct(TaxRule $taxRule = null) { $this->taxRule = $taxRule; @@ -50,4 +55,44 @@ class TaxRuleEvent extends ActionEvent 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; + } } diff --git a/core/lib/Thelia/Form/TaxRuleCreationForm.php b/core/lib/Thelia/Form/TaxRuleCreationForm.php index a54e8b0c5..4b9a66f7b 100644 --- a/core/lib/Thelia/Form/TaxRuleCreationForm.php +++ b/core/lib/Thelia/Form/TaxRuleCreationForm.php @@ -25,31 +25,27 @@ 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 { - protected function buildForm() + protected function buildForm($change_mode = false) { $this->formBuilder - ->add("title" , "text" , array( + ->add("locale", "text", array( + "constraints" => array(new NotBlank()) + )) + ->add("country", "text", array( "constraints" => array( - new NotBlank() + new Constraints\Callback( + array( + "methods" => array( + array($this, "verifyCountry"), + ), + ) + ), ), - "label" => Translator::getInstance()->trans("Title *"), - "label_attr" => array( - "for" => "title" - )) - ) - ->add("locale" , "text" , array( - "constraints" => array( - new NotBlank() - )) - ) - ->add("feature_id", "hidden", array( - "constraints" => array( - new NotBlank() - )) - ) + )) ; } @@ -57,4 +53,14 @@ 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 44cde86cd..9b80916ef 100644 --- a/core/lib/Thelia/Form/TaxRuleModificationForm.php +++ b/core/lib/Thelia/Form/TaxRuleModificationForm.php @@ -23,21 +23,50 @@ namespace Thelia\Form; use Symfony\Component\Validator\Constraints; -use Symfony\Component\Validator\Constraints\GreaterThan; +use Symfony\Component\Validator\ExecutionContextInterface; +use Thelia\Model\TaxRuleQuery; -class TaxRuleModificationForm extends FeatureCreationForm +class TaxRuleModificationForm extends TaxRuleCreationForm { use StandardDescriptionFieldsTrait; protected function buildForm() { + parent::buildForm(true); + $this->formBuilder ->add("id", "hidden", array( + "required" => true, "constraints" => array( - new GreaterThan( - array('value' => 0) + new Constraints\NotBlank(), + new Constraints\Callback( + array( + "methods" => array( + array($this, "verifyTaxRuleId"), + ), + ) + ), + ) + )) + ->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"), + ), + ) + ), + ) )) ; @@ -49,4 +78,14 @@ class TaxRuleModificationForm extends FeatureCreationForm { 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/templates/admin/default/tax-rule-edit.html b/templates/admin/default/tax-rule-edit.html index e58b67ddf..a953ed19d 100644 --- a/templates/admin/default/tax-rule-edit.html +++ b/templates/admin/default/tax-rule-edit.html @@ -7,6 +7,7 @@ {block name="main-content"} {assign oder_tab {$smarty.get.tab|default:"data"}} +{assign asked_country {$smarty.get.country|default:{country ask="default" attr="isoalpha3"}}}
    @@ -19,7 +20,7 @@
  • {intl l='Editing tax rule'}
  • - {loop type="tax-rule" name="tax-rule" id=$tax_rule_id} + {loop type="tax-rule" name="tax-rule" id=$tax_rule_id backend_context="1" lang=$edit_language_id}
    @@ -32,16 +33,67 @@
    - TODO +
    + {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} + {/form} +
    @@ -55,7 +107,7 @@
    diff --git a/templates/admin/default/taxes-rules.html b/templates/admin/default/taxes-rules.html index bc6cb4ed3..387f70e08 100644 --- a/templates/admin/default/taxes-rules.html +++ b/templates/admin/default/taxes-rules.html @@ -49,11 +49,11 @@
    {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}
    @@ -93,4 +93,14 @@ form_content = {$smarty.capture.tax_rule_delete_dialog nofilter} } +{/block} + +{block name="javascript-initialization"} + + + {/block} \ No newline at end of file From 52a582435ec14db43370c7a82d69e158598804f5 Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Wed, 9 Oct 2013 10:16:46 +0200 Subject: [PATCH 07/12] tax rule modification --- core/lib/Thelia/Config/Resources/routing/admin.xml | 4 ++-- core/lib/Thelia/Form/TaxRuleModificationForm.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index 8d60250a4..ca9465967 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -788,11 +788,11 @@ \d+ - + Thelia\Controller\Admin\TaxRuleController::processUpdateAction - + Thelia\Controller\Admin\TaxRuleController::deleteAction diff --git a/core/lib/Thelia/Form/TaxRuleModificationForm.php b/core/lib/Thelia/Form/TaxRuleModificationForm.php index 9b80916ef..62aa90118 100644 --- a/core/lib/Thelia/Form/TaxRuleModificationForm.php +++ b/core/lib/Thelia/Form/TaxRuleModificationForm.php @@ -71,7 +71,7 @@ class TaxRuleModificationForm extends TaxRuleCreationForm ; // Add standard description fields - $this->addStandardDescFields(); + $this->addStandardDescFields(array('postscriptum', 'chapo', 'locale')); } public function getName() From a8594ef6af1159c0a3a48c1943da81bfc616ed08 Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Wed, 9 Oct 2013 15:03:07 +0200 Subject: [PATCH 08/12] tax rule edition admin --- core/lib/Thelia/Config/Resources/config.xml | 2 + core/lib/Thelia/Core/Template/Loop/Tax.php | 167 ++++++++++++++++++ .../Core/Template/Loop/TaxRuleCountry.php | 160 +++++++++++++++++ install/insert.sql | 4 +- templates/admin/default/tax-rule-edit.html | 44 +++-- 5 files changed, 361 insertions(+), 16 deletions(-) create mode 100644 core/lib/Thelia/Core/Template/Loop/Tax.php create mode 100644 core/lib/Thelia/Core/Template/Loop/TaxRuleCountry.php diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index 706c2f84d..71ecede6e 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -45,7 +45,9 @@ + + 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..57174759e --- /dev/null +++ b/core/lib/Thelia/Core/Template/Loop/TaxRuleCountry.php @@ -0,0 +1,160 @@ +. */ +/* */ +/*************************************************************************************/ + +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) || (null !== $country && null !== $taxes)) { + throw new \InvalidArgumentException('You must provide either `country` or `taxes` parameter in tax-rule-country loop'); + } + + if(null !== $country) { + $search->filterByCountryId($country); + + /* manage tax translation */ + $this->configureI18nProcessing( + $search, + array('TITLE', 'DESCRIPTION'), + TaxTableMap::TABLE_NAME, + 'TAX_ID' + ); + } + + 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 . '?', 64, \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' + ); + } + + $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 !== $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')) + ; + } + + 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')) + ; + } + + $loopResult->addRow($loopResultRow); + } + + return $loopResult; + } +} diff --git a/install/insert.sql b/install/insert.sql index ec88c0866..8e6585a5b 100755 --- a/install/insert.sql +++ b/install/insert.sql @@ -1172,8 +1172,8 @@ INSERT INTO `tax_rule_i18n` (`id`, `locale`, `title`) INSERT INTO `tax_rule_country` (`tax_rule_id`, `country_id`, `tax_id`, `position`, `created_at`, `updated_at`) VALUES - (1, 64, 1, 2, NOW(), NOW()), - (2, 64, 2, 2, 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/tax-rule-edit.html b/templates/admin/default/tax-rule-edit.html index a953ed19d..ac2537c96 100644 --- a/templates/admin/default/tax-rule-edit.html +++ b/templates/admin/default/tax-rule-edit.html @@ -7,7 +7,7 @@ {block name="main-content"} {assign oder_tab {$smarty.get.tab|default:"data"}} -{assign asked_country {$smarty.get.country|default:{country ask="default" attr="isoalpha3"}}} +{assign asked_country {$smarty.get.country|default:{country ask="default" attr="id"}}}
    @@ -107,16 +107,21 @@

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

    - Italy - England - Japan + + {loop type="tax-rule-country" name="same-country-list" tax_rule=$ID taxes="1,2,3"} + {$COUNTRY_TITLE} + {/loop} + + {elseloop rel="same-country-list"} + {intl l="NONE"} + {/elseloop}

    @@ -124,16 +129,29 @@
    -

    Create a tax rule

    +

    {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} - {$POSITION}
    + + {if $LOOP_COUNT == $LOOP_TOTAL}
    + {/if} + {/loop}