diff --git a/core/lib/Thelia/TaxEngine/Calculator.php b/core/lib/Thelia/TaxEngine/Calculator.php index f8c527cd1..b5a2f995e 100755 --- a/core/lib/Thelia/TaxEngine/Calculator.php +++ b/core/lib/Thelia/TaxEngine/Calculator.php @@ -73,11 +73,16 @@ class Calculator return $this; } - public function getTaxAmount($untaxedPrice) + public function getTaxAmountFromUntaxedPrice($untaxedPrice) { return $this->getTaxedPrice($untaxedPrice) - $untaxedPrice; } + public function getTaxAmountFromTaxedPrice($taxedPrice) + { + return $taxedPrice - $this->getUntaxedPrice($taxedPrice); + } + public function getTaxedPrice($untaxedPrice) { if(null === $this->taxRulesCollection) { @@ -111,4 +116,72 @@ class Calculator return $taxedPrice; } + + public function getUntaxedPrice($taxedPrice) + { + if(null === $this->taxRulesCollection) { + throw new TaxEngineException('Tax rules collection is empty in Calculator::getTaxAmount', TaxEngineException::UNDEFINED_TAX_RULES_COLLECTION); + } + + if(false === filter_var($taxedPrice, FILTER_VALIDATE_FLOAT)) { + throw new TaxEngineException('BAD AMOUNT FORMAT', TaxEngineException::BAD_AMOUNT_FORMAT); + } + + $taxRule = $this->taxRulesCollection->getLast(); + + $untaxedPrice = $taxedPrice; + $currentPosition = (int)$taxRule->getTaxRuleCountryPosition(); + $currentFixTax = 0; + $currentTaxFactor = 0; + + do { + $position = (int)$taxRule->getTaxRuleCountryPosition(); + + $taxType = $taxRule->getTypeInstance(); + $taxType->loadRequirements( $taxRule->getRequirements() ); + + if($currentPosition !== $position) { + $untaxedPrice -= $currentFixTax; + $untaxedPrice = $untaxedPrice / (1+$currentTaxFactor); + $currentFixTax = 0; + $currentTaxFactor = 0; + $currentPosition = $position; + } + + $currentFixTax += $taxType->fixAmountRetriever(); + $currentTaxFactor += $taxType->pricePercentRetriever(); + + + } while($taxRule = $this->taxRulesCollection->getPrevious()); + + $untaxedPrice -= $currentFixTax; + $untaxedPrice = $untaxedPrice / (1+$currentTaxFactor); + + /*do { + + $taxType = $taxRule->getTypeInstance(); + $taxType->loadRequirements( $taxRule->getRequirements() ); + + $untaxedPrice -= $taxType->fixAmountRetriever(); + + } while($taxRule = $this->taxRulesCollection->getPrevious()); + + $taxRule = $this->taxRulesCollection->getLast(); + + $currentTaxFactor = 0; + do { + + $taxType = $taxRule->getTypeInstance(); + $taxType->loadRequirements( $taxRule->getRequirements() ); + + $currentTaxFactor += $taxType->pricePercentRetriever($untaxedPrice); + + $toto = true; + + } while($taxRule = $this->taxRulesCollection->getPrevious()); + + $untaxedPrice = $untaxedPrice / (1+$currentTaxFactor);*/ + + return $untaxedPrice; + } } diff --git a/core/lib/Thelia/TaxEngine/TaxType/BaseTaxType.php b/core/lib/Thelia/TaxEngine/TaxType/BaseTaxType.php index 7f487bf64..149e3f1df 100755 --- a/core/lib/Thelia/TaxEngine/TaxType/BaseTaxType.php +++ b/core/lib/Thelia/TaxEngine/TaxType/BaseTaxType.php @@ -36,6 +36,10 @@ abstract class BaseTaxType public abstract function calculate($untaxedPrice); + public abstract function pricePercentRetriever(); + + public abstract function fixAmountRetriever(); + public abstract function getRequirementsList(); public function loadRequirements($requirementsValues) diff --git a/core/lib/Thelia/TaxEngine/TaxType/FeatureSlicePercentTaxType.php b/core/lib/Thelia/TaxEngine/TaxType/FeatureSlicePercentTaxType.php index 4485f1e21..911439574 100755 --- a/core/lib/Thelia/TaxEngine/TaxType/FeatureSlicePercentTaxType.php +++ b/core/lib/Thelia/TaxEngine/TaxType/FeatureSlicePercentTaxType.php @@ -37,6 +37,16 @@ class featureSlicePercentTaxType extends BaseTaxType } + public function pricePercentRetriever() + { + + } + + public function fixAmountRetriever() + { + + } + public function getRequirementsList() { return array( diff --git a/core/lib/Thelia/TaxEngine/TaxType/FixAmountTaxType.php b/core/lib/Thelia/TaxEngine/TaxType/FixAmountTaxType.php index c533d0ec3..acd52bf8a 100755 --- a/core/lib/Thelia/TaxEngine/TaxType/FixAmountTaxType.php +++ b/core/lib/Thelia/TaxEngine/TaxType/FixAmountTaxType.php @@ -36,6 +36,16 @@ class FixAmountTaxType extends BaseTaxType return $this->getRequirement("amount"); } + public function pricePercentRetriever() + { + return 0; + } + + public function fixAmountRetriever() + { + return $this->getRequirement("amount"); + } + public function getRequirementsList() { return array( diff --git a/core/lib/Thelia/TaxEngine/TaxType/PricePercentTaxType.php b/core/lib/Thelia/TaxEngine/TaxType/PricePercentTaxType.php index 1d7152fcf..a8cd8c759 100755 --- a/core/lib/Thelia/TaxEngine/TaxType/PricePercentTaxType.php +++ b/core/lib/Thelia/TaxEngine/TaxType/PricePercentTaxType.php @@ -36,6 +36,16 @@ class PricePercentTaxType extends BaseTaxType return $untaxedPrice * $this->getRequirement("percent") * 0.01; } + public function pricePercentRetriever() + { + return ($this->getRequirement("percent") * 0.01); + } + + public function fixAmountRetriever() + { + return 0; + } + public function getRequirementsList() { return array( @@ -43,3 +53,5 @@ class PricePercentTaxType extends BaseTaxType ); } } + +//600 / (1 + 0,10 + 0,10) =/= 600 / (1 + 0,10 ) + 600 / (1 + 0,10 ) \ No newline at end of file diff --git a/core/lib/Thelia/Tests/TaxEngine/CalculatorTest.php b/core/lib/Thelia/Tests/TaxEngine/CalculatorTest.php index 165d5d517..e0443c5ba 100755 --- a/core/lib/Thelia/Tests/TaxEngine/CalculatorTest.php +++ b/core/lib/Thelia/Tests/TaxEngine/CalculatorTest.php @@ -112,17 +112,17 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase * @expectedException \Thelia\Exception\TaxEngineException * @expectedExceptionCode 503 */ - public function testGetTaxAmountBadTaxRulesCollection() + public function testGetTaxedPriceBadTaxRulesCollection() { $calculator = new Calculator(); - $calculator->getTaxAmount(500); + $calculator->getTaxedPrice(500); } /** * @expectedException \Thelia\Exception\TaxEngineException * @expectedExceptionCode 601 */ - public function testGetTaxAmountBadAmount() + public function testGetTaxedPriceBadAmount() { $taxRulesCollection = new ObjectCollection(); @@ -131,12 +131,11 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase $rewritingUrlQuery = $this->getProperty('taxRulesCollection'); $rewritingUrlQuery->setValue($calculator, $taxRulesCollection); - $calculator->getTaxAmount('foo'); + $calculator->getTaxedPrice('foo'); } - public function testGetTaxAmountAndGetTaxedPrice() + public function testGetTaxedPriceAndGetTaxAmountFromUntaxedPrice() { - /* consecutives taxes */ $taxRulesCollection = new ObjectCollection(); $taxRulesCollection->setModel('\Thelia\Model\Tax'); @@ -144,14 +143,24 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase $tax->setType('PricePercentTaxType') ->setRequirements(array('percent' => 10)) ->setVirtualColumn('taxRuleCountryPosition', 1); - $taxRulesCollection->append($tax); $tax = new Tax(); $tax->setType('PricePercentTaxType') ->setRequirements(array('percent' => 8)) + ->setVirtualColumn('taxRuleCountryPosition', 1); + $taxRulesCollection->append($tax); + + $tax = new Tax(); + $tax->setType('FixAmountTaxType') + ->setRequirements(array('amount' => 5)) ->setVirtualColumn('taxRuleCountryPosition', 2); + $taxRulesCollection->append($tax); + $tax = new Tax(); + $tax->setType('PricePercentTaxType') + ->setRequirements(array('percent' => 1)) + ->setVirtualColumn('taxRuleCountryPosition', 3); $taxRulesCollection->append($tax); $calculator = new Calculator(); @@ -159,19 +168,22 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase $rewritingUrlQuery = $this->getProperty('taxRulesCollection'); $rewritingUrlQuery->setValue($calculator, $taxRulesCollection); - $taxAmount = $calculator->getTaxAmount(500); + $taxAmount = $calculator->getTaxAmountFromUntaxedPrice(500); $taxedPrice = $calculator->getTaxedPrice(500); /* * expect : - * tax 1 = 500*0.10 = 50 // amout with tax 1 : 550 - * tax 2 = 550*0.08 = 44 // amout with tax 2 : 594 - * total tax amount = 94 + * tax 1 = 500*0.10 = 50 + 500*0.08 = 40 // amount with tax 1 : 590 + * tax 2 = 5 // amount with tax 2 : 595 + * tax 3 = 595 * 0.01 = 5.95 // amount with tax 3 : 600.95 + * total tax amount = 100.95 */ - $this->assertEquals(94, $taxAmount); - $this->assertEquals(594, $taxedPrice); + $this->assertEquals(100.95, $taxAmount); + $this->assertEquals(600.95, $taxedPrice); + } - /* same position taxes */ + public function testGetUntaxedPriceAndGetTaxAmountFromTaxedPrice() + { $taxRulesCollection = new ObjectCollection(); $taxRulesCollection->setModel('\Thelia\Model\Tax'); @@ -179,14 +191,24 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase $tax->setType('PricePercentTaxType') ->setRequirements(array('percent' => 10)) ->setVirtualColumn('taxRuleCountryPosition', 1); - $taxRulesCollection->append($tax); $tax = new Tax(); $tax->setType('PricePercentTaxType') ->setRequirements(array('percent' => 8)) ->setVirtualColumn('taxRuleCountryPosition', 1); + $taxRulesCollection->append($tax); + $tax = new Tax(); + $tax->setType('FixAmountTaxType') + ->setRequirements(array('amount' => 5)) + ->setVirtualColumn('taxRuleCountryPosition', 2); + $taxRulesCollection->append($tax); + + $tax = new Tax(); + $tax->setType('PricePercentTaxType') + ->setRequirements(array('percent' => 1)) + ->setVirtualColumn('taxRuleCountryPosition', 3); $taxRulesCollection->append($tax); $calculator = new Calculator(); @@ -194,16 +216,17 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase $rewritingUrlQuery = $this->getProperty('taxRulesCollection'); $rewritingUrlQuery->setValue($calculator, $taxRulesCollection); - $taxAmount = $calculator->getTaxAmount(500); - $taxedPrice = $calculator->getTaxedPrice(500); + $taxAmount = $calculator->getTaxAmountFromTaxedPrice(600.95); + $untaxedPrice = $calculator->getUntaxedPrice(600.95); /* * expect : - * tax 1 = 500*0.10 = 50 // amout with tax 1 : 550 - * tax 2 = 500*0.08 = 40 // amout with tax 2 : 590 - * total tax amount = 90 + * tax 3 = 600.95 - 600.95 / (1 + 0.01) = 5,95 // amount without tax 3 : 595 + * tax 2 = 5 // amount without tax 2 : 590 + * tax 1 = 590 - 590 / (1 + 0.08 + 0.10) = 90 // amount without tax 1 : 500 + * total tax amount = 100.95 */ - $this->assertEquals(90, $taxAmount); - $this->assertEquals(590, $taxedPrice); + $this->assertEquals(100.95, $taxAmount); + $this->assertEquals(500, $untaxedPrice); } }