tax engine retriever

This commit is contained in:
Etienne Roudeix
2013-09-13 13:59:16 +02:00
parent e7368fa9f0
commit ecc419fbdf
6 changed files with 155 additions and 23 deletions

View File

@@ -73,11 +73,16 @@ class Calculator
return $this; return $this;
} }
public function getTaxAmount($untaxedPrice) public function getTaxAmountFromUntaxedPrice($untaxedPrice)
{ {
return $this->getTaxedPrice($untaxedPrice) - $untaxedPrice; return $this->getTaxedPrice($untaxedPrice) - $untaxedPrice;
} }
public function getTaxAmountFromTaxedPrice($taxedPrice)
{
return $taxedPrice - $this->getUntaxedPrice($taxedPrice);
}
public function getTaxedPrice($untaxedPrice) public function getTaxedPrice($untaxedPrice)
{ {
if(null === $this->taxRulesCollection) { if(null === $this->taxRulesCollection) {
@@ -111,4 +116,72 @@ class Calculator
return $taxedPrice; 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;
}
} }

View File

@@ -36,6 +36,10 @@ abstract class BaseTaxType
public abstract function calculate($untaxedPrice); public abstract function calculate($untaxedPrice);
public abstract function pricePercentRetriever();
public abstract function fixAmountRetriever();
public abstract function getRequirementsList(); public abstract function getRequirementsList();
public function loadRequirements($requirementsValues) public function loadRequirements($requirementsValues)

View File

@@ -37,6 +37,16 @@ class featureSlicePercentTaxType extends BaseTaxType
} }
public function pricePercentRetriever()
{
}
public function fixAmountRetriever()
{
}
public function getRequirementsList() public function getRequirementsList()
{ {
return array( return array(

View File

@@ -36,6 +36,16 @@ class FixAmountTaxType extends BaseTaxType
return $this->getRequirement("amount"); return $this->getRequirement("amount");
} }
public function pricePercentRetriever()
{
return 0;
}
public function fixAmountRetriever()
{
return $this->getRequirement("amount");
}
public function getRequirementsList() public function getRequirementsList()
{ {
return array( return array(

View File

@@ -36,6 +36,16 @@ class PricePercentTaxType extends BaseTaxType
return $untaxedPrice * $this->getRequirement("percent") * 0.01; return $untaxedPrice * $this->getRequirement("percent") * 0.01;
} }
public function pricePercentRetriever()
{
return ($this->getRequirement("percent") * 0.01);
}
public function fixAmountRetriever()
{
return 0;
}
public function getRequirementsList() public function getRequirementsList()
{ {
return array( return array(
@@ -43,3 +53,5 @@ class PricePercentTaxType extends BaseTaxType
); );
} }
} }
//600 / (1 + 0,10 + 0,10) =/= 600 / (1 + 0,10 ) + 600 / (1 + 0,10 )

View File

@@ -112,17 +112,17 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase
* @expectedException \Thelia\Exception\TaxEngineException * @expectedException \Thelia\Exception\TaxEngineException
* @expectedExceptionCode 503 * @expectedExceptionCode 503
*/ */
public function testGetTaxAmountBadTaxRulesCollection() public function testGetTaxedPriceBadTaxRulesCollection()
{ {
$calculator = new Calculator(); $calculator = new Calculator();
$calculator->getTaxAmount(500); $calculator->getTaxedPrice(500);
} }
/** /**
* @expectedException \Thelia\Exception\TaxEngineException * @expectedException \Thelia\Exception\TaxEngineException
* @expectedExceptionCode 601 * @expectedExceptionCode 601
*/ */
public function testGetTaxAmountBadAmount() public function testGetTaxedPriceBadAmount()
{ {
$taxRulesCollection = new ObjectCollection(); $taxRulesCollection = new ObjectCollection();
@@ -131,12 +131,11 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase
$rewritingUrlQuery = $this->getProperty('taxRulesCollection'); $rewritingUrlQuery = $this->getProperty('taxRulesCollection');
$rewritingUrlQuery->setValue($calculator, $taxRulesCollection); $rewritingUrlQuery->setValue($calculator, $taxRulesCollection);
$calculator->getTaxAmount('foo'); $calculator->getTaxedPrice('foo');
} }
public function testGetTaxAmountAndGetTaxedPrice() public function testGetTaxedPriceAndGetTaxAmountFromUntaxedPrice()
{ {
/* consecutives taxes */
$taxRulesCollection = new ObjectCollection(); $taxRulesCollection = new ObjectCollection();
$taxRulesCollection->setModel('\Thelia\Model\Tax'); $taxRulesCollection->setModel('\Thelia\Model\Tax');
@@ -144,14 +143,24 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase
$tax->setType('PricePercentTaxType') $tax->setType('PricePercentTaxType')
->setRequirements(array('percent' => 10)) ->setRequirements(array('percent' => 10))
->setVirtualColumn('taxRuleCountryPosition', 1); ->setVirtualColumn('taxRuleCountryPosition', 1);
$taxRulesCollection->append($tax); $taxRulesCollection->append($tax);
$tax = new Tax(); $tax = new Tax();
$tax->setType('PricePercentTaxType') $tax->setType('PricePercentTaxType')
->setRequirements(array('percent' => 8)) ->setRequirements(array('percent' => 8))
->setVirtualColumn('taxRuleCountryPosition', 1);
$taxRulesCollection->append($tax);
$tax = new Tax();
$tax->setType('FixAmountTaxType')
->setRequirements(array('amount' => 5))
->setVirtualColumn('taxRuleCountryPosition', 2); ->setVirtualColumn('taxRuleCountryPosition', 2);
$taxRulesCollection->append($tax);
$tax = new Tax();
$tax->setType('PricePercentTaxType')
->setRequirements(array('percent' => 1))
->setVirtualColumn('taxRuleCountryPosition', 3);
$taxRulesCollection->append($tax); $taxRulesCollection->append($tax);
$calculator = new Calculator(); $calculator = new Calculator();
@@ -159,19 +168,22 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase
$rewritingUrlQuery = $this->getProperty('taxRulesCollection'); $rewritingUrlQuery = $this->getProperty('taxRulesCollection');
$rewritingUrlQuery->setValue($calculator, $taxRulesCollection); $rewritingUrlQuery->setValue($calculator, $taxRulesCollection);
$taxAmount = $calculator->getTaxAmount(500); $taxAmount = $calculator->getTaxAmountFromUntaxedPrice(500);
$taxedPrice = $calculator->getTaxedPrice(500); $taxedPrice = $calculator->getTaxedPrice(500);
/* /*
* expect : * expect :
* tax 1 = 500*0.10 = 50 // amout with tax 1 : 550 * tax 1 = 500*0.10 = 50 + 500*0.08 = 40 // amount with tax 1 : 590
* tax 2 = 550*0.08 = 44 // amout with tax 2 : 594 * tax 2 = 5 // amount with tax 2 : 595
* total tax amount = 94 * tax 3 = 595 * 0.01 = 5.95 // amount with tax 3 : 600.95
* total tax amount = 100.95
*/ */
$this->assertEquals(94, $taxAmount); $this->assertEquals(100.95, $taxAmount);
$this->assertEquals(594, $taxedPrice); $this->assertEquals(600.95, $taxedPrice);
}
/* same position taxes */ public function testGetUntaxedPriceAndGetTaxAmountFromTaxedPrice()
{
$taxRulesCollection = new ObjectCollection(); $taxRulesCollection = new ObjectCollection();
$taxRulesCollection->setModel('\Thelia\Model\Tax'); $taxRulesCollection->setModel('\Thelia\Model\Tax');
@@ -179,14 +191,24 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase
$tax->setType('PricePercentTaxType') $tax->setType('PricePercentTaxType')
->setRequirements(array('percent' => 10)) ->setRequirements(array('percent' => 10))
->setVirtualColumn('taxRuleCountryPosition', 1); ->setVirtualColumn('taxRuleCountryPosition', 1);
$taxRulesCollection->append($tax); $taxRulesCollection->append($tax);
$tax = new Tax(); $tax = new Tax();
$tax->setType('PricePercentTaxType') $tax->setType('PricePercentTaxType')
->setRequirements(array('percent' => 8)) ->setRequirements(array('percent' => 8))
->setVirtualColumn('taxRuleCountryPosition', 1); ->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); $taxRulesCollection->append($tax);
$calculator = new Calculator(); $calculator = new Calculator();
@@ -194,16 +216,17 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase
$rewritingUrlQuery = $this->getProperty('taxRulesCollection'); $rewritingUrlQuery = $this->getProperty('taxRulesCollection');
$rewritingUrlQuery->setValue($calculator, $taxRulesCollection); $rewritingUrlQuery->setValue($calculator, $taxRulesCollection);
$taxAmount = $calculator->getTaxAmount(500); $taxAmount = $calculator->getTaxAmountFromTaxedPrice(600.95);
$taxedPrice = $calculator->getTaxedPrice(500); $untaxedPrice = $calculator->getUntaxedPrice(600.95);
/* /*
* expect : * expect :
* tax 1 = 500*0.10 = 50 // amout with tax 1 : 550 * tax 3 = 600.95 - 600.95 / (1 + 0.01) = 5,95 // amount without tax 3 : 595
* tax 2 = 500*0.08 = 40 // amout with tax 2 : 590 * tax 2 = 5 // amount without tax 2 : 590
* total tax amount = 90 * 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(100.95, $taxAmount);
$this->assertEquals(590, $taxedPrice); $this->assertEquals(500, $untaxedPrice);
} }
} }