From b84e8630333a98e63f1a69b08cf9a9e7283e2590 Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Mon, 7 Oct 2013 14:36:20 +0200 Subject: [PATCH] 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