tax engine
This commit is contained in:
@@ -87,7 +87,7 @@ class Address extends BaseLoop
|
|||||||
$customer = $this->getCustomer();
|
$customer = $this->getCustomer();
|
||||||
|
|
||||||
if ($customer === 'current') {
|
if ($customer === 'current') {
|
||||||
$currentCustomer = $this->request->getSession()->getCustomerUser();
|
$currentCustomer = $this->securityContext->getCustomerUser();
|
||||||
if ($currentCustomer === null) {
|
if ($currentCustomer === null) {
|
||||||
return new LoopResult();
|
return new LoopResult();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ class Customer extends BaseLoop
|
|||||||
$current = $this->getCurrent();
|
$current = $this->getCurrent();
|
||||||
|
|
||||||
if ($current === true) {
|
if ($current === true) {
|
||||||
$currentCustomer = $this->request->getSession()->getCustomerUser();
|
$currentCustomer = $this->securityContext->getCustomerUser();
|
||||||
if ($currentCustomer === null) {
|
if ($currentCustomer === null) {
|
||||||
return new LoopResult();
|
return new LoopResult();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ use Thelia\Core\Template\Loop\Argument\Argument;
|
|||||||
use Thelia\Log\Tlog;
|
use Thelia\Log\Tlog;
|
||||||
|
|
||||||
use Thelia\Model\CategoryQuery;
|
use Thelia\Model\CategoryQuery;
|
||||||
|
use Thelia\Model\CountryQuery;
|
||||||
use Thelia\Model\Map\FeatureProductTableMap;
|
use Thelia\Model\Map\FeatureProductTableMap;
|
||||||
use Thelia\Model\Map\ProductPriceTableMap;
|
use Thelia\Model\Map\ProductPriceTableMap;
|
||||||
use Thelia\Model\Map\ProductSaleElementsTableMap;
|
use Thelia\Model\Map\ProductSaleElementsTableMap;
|
||||||
@@ -333,10 +334,10 @@ class Product extends BaseI18nLoop
|
|||||||
foreach($isProductPriceLeftJoinList as $pSE => $isProductPriceLeftJoin) {
|
foreach($isProductPriceLeftJoinList as $pSE => $isProductPriceLeftJoin) {
|
||||||
$booleanMatchedPriceList[] = 'CASE WHEN `' . $pSE . '`.PROMO=1 THEN `' . $isProductPriceLeftJoin . '`.PROMO_PRICE ELSE `' . $isProductPriceLeftJoin . '`.PRICE END';
|
$booleanMatchedPriceList[] = 'CASE WHEN `' . $pSE . '`.PROMO=1 THEN `' . $isProductPriceLeftJoin . '`.PROMO_PRICE ELSE `' . $isProductPriceLeftJoin . '`.PRICE END';
|
||||||
}
|
}
|
||||||
$search->withColumn('MAX(' . implode(' OR ', $booleanMatchedPromoList) . ')', 'main_product_is_promo');
|
$search->withColumn('ROUND(MAX(' . implode(' OR ', $booleanMatchedPromoList) . '), 2)', 'main_product_is_promo');
|
||||||
$search->withColumn('MAX(' . implode(' OR ', $booleanMatchedNewnessList) . ')', 'main_product_is_new');
|
$search->withColumn('ROUND(MAX(' . implode(' OR ', $booleanMatchedNewnessList) . '), 2)', 'main_product_is_new');
|
||||||
$search->withColumn('MAX(' . implode(' OR ', $booleanMatchedPriceList) . ')', 'real_highest_price');
|
$search->withColumn('ROUND(MAX(' . implode(' OR ', $booleanMatchedPriceList) . '), 2)', 'real_highest_price');
|
||||||
$search->withColumn('MIN(' . implode(' OR ', $booleanMatchedPriceList) . ')', 'real_lowest_price');
|
$search->withColumn('ROUND(MIN(' . implode(' OR ', $booleanMatchedPriceList) . '), 2)', 'real_lowest_price');
|
||||||
|
|
||||||
|
|
||||||
$current = $this->getCurrent();
|
$current = $this->getCurrent();
|
||||||
@@ -518,7 +519,10 @@ class Product extends BaseI18nLoop
|
|||||||
->set("DESCRIPTION", $product->getVirtualColumn('i18n_DESCRIPTION'))
|
->set("DESCRIPTION", $product->getVirtualColumn('i18n_DESCRIPTION'))
|
||||||
->set("POSTSCRIPTUM", $product->getVirtualColumn('i18n_POSTSCRIPTUM'))
|
->set("POSTSCRIPTUM", $product->getVirtualColumn('i18n_POSTSCRIPTUM'))
|
||||||
->set("URL", $product->getUrl($locale))
|
->set("URL", $product->getUrl($locale))
|
||||||
->set("BEST_PRICE", $product->getVirtualColumn('real_lowest_price'))
|
->set("BEST_PRICE", $product->getRealLowestPrice())
|
||||||
|
->set("BEST_TAXED_PRICE", $product->getTaxedPrice(
|
||||||
|
CountryQuery::create()->findOneById(64) // @TODO : make it magic
|
||||||
|
))
|
||||||
->set("IS_PROMO", $product->getVirtualColumn('main_product_is_promo'))
|
->set("IS_PROMO", $product->getVirtualColumn('main_product_is_promo'))
|
||||||
->set("IS_NEW", $product->getVirtualColumn('main_product_is_new'))
|
->set("IS_NEW", $product->getVirtualColumn('main_product_is_new'))
|
||||||
->set("POSITION", $product->getPosition())
|
->set("POSITION", $product->getPosition())
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ class TaxEngineException extends \RuntimeException
|
|||||||
|
|
||||||
const UNDEFINED_PRODUCT = 501;
|
const UNDEFINED_PRODUCT = 501;
|
||||||
const UNDEFINED_COUNTRY = 502;
|
const UNDEFINED_COUNTRY = 502;
|
||||||
|
const UNDEFINED_TAX_RULES_COLLECTION = 503;
|
||||||
|
|
||||||
|
const BAD_AMOUNT_FORMAT = 601;
|
||||||
|
|
||||||
public function __construct($message, $code = null, $previous = null) {
|
public function __construct($message, $code = null, $previous = null) {
|
||||||
if($code === null) {
|
if($code === null) {
|
||||||
|
|||||||
@@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
namespace Thelia\Model;
|
namespace Thelia\Model;
|
||||||
|
|
||||||
|
use Propel\Runtime\Exception\PropelException;
|
||||||
use Thelia\Model\Base\Product as BaseProduct;
|
use Thelia\Model\Base\Product as BaseProduct;
|
||||||
use Thelia\Tools\URL;
|
use Thelia\Tools\URL;
|
||||||
|
use Thelia\TaxEngine\Calculator;
|
||||||
|
|
||||||
class Product extends BaseProduct
|
class Product extends BaseProduct
|
||||||
{
|
{
|
||||||
@@ -11,4 +13,21 @@ class Product extends BaseProduct
|
|||||||
{
|
{
|
||||||
return URL::getInstance()->retrieve('product', $this->getId(), $locale)->toString();
|
return URL::getInstance()->retrieve('product', $this->getId(), $locale)->toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getRealLowestPrice($virtualColumnName = 'real_lowest_price')
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$amount = $this->getVirtualColumn($virtualColumnName);
|
||||||
|
} catch(PropelException $e) {
|
||||||
|
throw new PropelException("Virtual column `$virtualColumnName` does not exist in Product::getRealLowestPrice");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTaxedPrice(Country $country)
|
||||||
|
{
|
||||||
|
$taxCalculator = new Calculator();
|
||||||
|
return $taxCalculator->load($this, $country)->getTaxedPrice();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,45 @@
|
|||||||
|
|
||||||
namespace Thelia\Model;
|
namespace Thelia\Model;
|
||||||
|
|
||||||
|
use Thelia\Exception\TaxEngineException;
|
||||||
use Thelia\Model\Base\Tax as BaseTax;
|
use Thelia\Model\Base\Tax as BaseTax;
|
||||||
|
|
||||||
class Tax extends BaseTax {
|
class Tax extends BaseTax
|
||||||
|
{
|
||||||
|
public function calculateTax($amount)
|
||||||
|
{
|
||||||
|
if(false === filter_var($amount, FILTER_VALIDATE_FLOAT)) {
|
||||||
|
throw new TaxEngineException('BAD AMOUNT FORMAT', TaxEngineException::BAD_AMOUNT_FORMAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
$rate = $this->getRate();
|
||||||
|
|
||||||
|
if($rate === null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $amount * $rate * 0.01;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTaxRuleCountryPosition()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$taxRuleCountryPosition = $this->getVirtualColumn(TaxRuleQuery::ALIAS_FOR_TAX_RULE_COUNTRY_POSITION);
|
||||||
|
} catch(PropelException $e) {
|
||||||
|
throw new PropelException("Virtual column `" . TaxRuleQuery::ALIAS_FOR_TAX_RULE_COUNTRY_POSITION . "` does not exist in Tax::getTaxRuleCountryPosition");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $taxRuleCountryPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTaxRuleRateSum()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$taxRuleRateSum = $this->getVirtualColumn(TaxRuleQuery::ALIAS_FOR_TAX_RATE_SUM);
|
||||||
|
} catch(PropelException $e) {
|
||||||
|
throw new PropelException("Virtual column `" . TaxRuleQuery::ALIAS_FOR_TAX_RATE_SUM . "` does not exist in Tax::getTaxRuleRateSum");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $taxRuleRateSum;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ namespace Thelia\Model;
|
|||||||
|
|
||||||
use Propel\Runtime\ActiveQuery\Criteria;
|
use Propel\Runtime\ActiveQuery\Criteria;
|
||||||
use Thelia\Model\Base\TaxRuleQuery as BaseTaxRuleQuery;
|
use Thelia\Model\Base\TaxRuleQuery as BaseTaxRuleQuery;
|
||||||
|
use Thelia\Model\Map\TaxRuleCountryTableMap;
|
||||||
|
use Thelia\Model\Map\TaxTableMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Skeleton subclass for performing query and update operations on the 'tax_rule' table.
|
* Skeleton subclass for performing query and update operations on the 'tax_rule' table.
|
||||||
@@ -18,14 +19,26 @@ use Thelia\Model\Base\TaxRuleQuery as BaseTaxRuleQuery;
|
|||||||
*/
|
*/
|
||||||
class TaxRuleQuery extends BaseTaxRuleQuery
|
class TaxRuleQuery extends BaseTaxRuleQuery
|
||||||
{
|
{
|
||||||
public function getTaxCalculatorCollection(Product $product, Country $country)
|
const ALIAS_FOR_TAX_RULE_COUNTRY_POSITION = 'taxRuleCountryPosition';
|
||||||
{
|
const ALIAS_FOR_TAX_RATE_SUM = 'taxRateSum';
|
||||||
$search = TaxRuleCountryQuery::create()
|
|
||||||
->filterByCountry($country, Criteria::EQUAL)
|
|
||||||
->filterByTaxRuleId($product->getTaxRuleId())
|
|
||||||
->orderByPosition()
|
|
||||||
->find();
|
|
||||||
|
|
||||||
return $search;
|
public function getTaxCalculatorGroupedCollection(Product $product, Country $country)
|
||||||
|
{
|
||||||
|
$search = TaxQuery::create()
|
||||||
|
->filterByTaxRuleCountry(
|
||||||
|
TaxRuleCountryQuery::create()
|
||||||
|
->filterByCountry($country, Criteria::EQUAL)
|
||||||
|
->filterByTaxRuleId($product->getTaxRuleId())
|
||||||
|
->groupByPosition()
|
||||||
|
->orderByPosition()
|
||||||
|
->find()
|
||||||
|
)
|
||||||
|
->withColumn(TaxRuleCountryTableMap::POSITION, self::ALIAS_FOR_TAX_RULE_COUNTRY_POSITION)
|
||||||
|
->withColumn('ROUND(SUM(' . TaxTableMap::RATE . '), 2)', self::ALIAS_FOR_TAX_RATE_SUM)
|
||||||
|
;
|
||||||
|
|
||||||
|
//var_dump($search->toString());
|
||||||
|
|
||||||
|
return $search->find();
|
||||||
}
|
}
|
||||||
} // TaxRuleQuery
|
} // TaxRuleQuery
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ class Calculator
|
|||||||
{
|
{
|
||||||
protected $taxRuleQuery = null;
|
protected $taxRuleQuery = null;
|
||||||
|
|
||||||
protected $taxRulesCollection = null;
|
protected $taxRulesGroupedCollection = null;
|
||||||
|
|
||||||
protected $product = null;
|
protected $product = null;
|
||||||
protected $country = null;
|
protected $country = null;
|
||||||
@@ -44,12 +44,14 @@ class Calculator
|
|||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->taxRuleQuery = new TaxRuleQuery();
|
$this->taxRuleQuery = new TaxRuleQuery();
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function load(Product $product, Country $country)
|
public function load(Product $product, Country $country)
|
||||||
{
|
{
|
||||||
|
$this->product = null;
|
||||||
|
$this->country = null;
|
||||||
|
$this->taxRulesGroupedCollection = null;
|
||||||
|
|
||||||
if($product->getId() === null) {
|
if($product->getId() === null) {
|
||||||
throw new TaxEngineException('Product id is empty in Calculator::load', TaxEngineException::UNDEFINED_PRODUCT);
|
throw new TaxEngineException('Product id is empty in Calculator::load', TaxEngineException::UNDEFINED_PRODUCT);
|
||||||
}
|
}
|
||||||
@@ -60,13 +62,29 @@ class Calculator
|
|||||||
$this->product = $product;
|
$this->product = $product;
|
||||||
$this->country = $country;
|
$this->country = $country;
|
||||||
|
|
||||||
$this->taxRulesCollection = $this->taxRuleQuery->getTaxCalculatorCollection($product, $country);
|
$this->taxRulesGroupedCollection = $this->taxRuleQuery->getTaxCalculatorGroupedCollection($product, $country);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTaxAmount()
|
public function getTaxAmount()
|
||||||
{
|
{
|
||||||
|
if(null === $this->taxRulesGroupedCollection) {
|
||||||
|
throw new TaxEngineException('Tax rules collection is empty in Calculator::getTaxAmount', TaxEngineException::UNDEFINED_TAX_RULES_COLLECTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
$amount = $this->product->getRealLowestPrice();
|
||||||
|
|
||||||
|
$taxRateAmount = 0;
|
||||||
|
foreach($this->taxRulesGroupedCollection as $taxRule) {
|
||||||
|
$taxRateAmount += $taxRule->getTaxRuleRateSum();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $amount * $taxRateAmount * 0.01;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTaxedPrice()
|
||||||
|
{
|
||||||
|
return $this->product->getRealLowestPrice() + $this->getTaxAmount();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,8 @@
|
|||||||
<h4>#TITLE</h4>
|
<h4>#TITLE</h4>
|
||||||
<p>#DESCRIPTION</p>
|
<p>#DESCRIPTION</p>
|
||||||
|
|
||||||
|
<p>Starting by #BEST_PRICE € HT (#BEST_TAXED_PRICE € TTC)</p>
|
||||||
|
|
||||||
{ifloop rel="ft"}
|
{ifloop rel="ft"}
|
||||||
<h5>Features</h5>
|
<h5>Features</h5>
|
||||||
<ul>
|
<ul>
|
||||||
|
|||||||
Reference in New Issue
Block a user