diff --git a/core/lib/Thelia/Core/Template/Loop/Address.php b/core/lib/Thelia/Core/Template/Loop/Address.php index 757cc11b8..3ac9370f8 100755 --- a/core/lib/Thelia/Core/Template/Loop/Address.php +++ b/core/lib/Thelia/Core/Template/Loop/Address.php @@ -87,7 +87,7 @@ class Address extends BaseLoop $customer = $this->getCustomer(); if ($customer === 'current') { - $currentCustomer = $this->request->getSession()->getCustomerUser(); + $currentCustomer = $this->securityContext->getCustomerUser(); if ($currentCustomer === null) { return new LoopResult(); } else { diff --git a/core/lib/Thelia/Core/Template/Loop/Customer.php b/core/lib/Thelia/Core/Template/Loop/Customer.php index 1a4b84105..ad801dc5f 100755 --- a/core/lib/Thelia/Core/Template/Loop/Customer.php +++ b/core/lib/Thelia/Core/Template/Loop/Customer.php @@ -80,7 +80,7 @@ class Customer extends BaseLoop $current = $this->getCurrent(); if ($current === true) { - $currentCustomer = $this->request->getSession()->getCustomerUser(); + $currentCustomer = $this->securityContext->getCustomerUser(); if ($currentCustomer === null) { return new LoopResult(); } else { diff --git a/core/lib/Thelia/Core/Template/Loop/Product.php b/core/lib/Thelia/Core/Template/Loop/Product.php index 4d785b8b0..f52b314a9 100755 --- a/core/lib/Thelia/Core/Template/Loop/Product.php +++ b/core/lib/Thelia/Core/Template/Loop/Product.php @@ -34,6 +34,7 @@ use Thelia\Core\Template\Loop\Argument\Argument; use Thelia\Log\Tlog; use Thelia\Model\CategoryQuery; +use Thelia\Model\CountryQuery; use Thelia\Model\Map\FeatureProductTableMap; use Thelia\Model\Map\ProductPriceTableMap; use Thelia\Model\Map\ProductSaleElementsTableMap; @@ -333,10 +334,10 @@ class Product extends BaseI18nLoop foreach($isProductPriceLeftJoinList as $pSE => $isProductPriceLeftJoin) { $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('MAX(' . implode(' OR ', $booleanMatchedNewnessList) . ')', 'main_product_is_new'); - $search->withColumn('MAX(' . implode(' OR ', $booleanMatchedPriceList) . ')', 'real_highest_price'); - $search->withColumn('MIN(' . implode(' OR ', $booleanMatchedPriceList) . ')', 'real_lowest_price'); + $search->withColumn('ROUND(MAX(' . implode(' OR ', $booleanMatchedPromoList) . '), 2)', 'main_product_is_promo'); + $search->withColumn('ROUND(MAX(' . implode(' OR ', $booleanMatchedNewnessList) . '), 2)', 'main_product_is_new'); + $search->withColumn('ROUND(MAX(' . implode(' OR ', $booleanMatchedPriceList) . '), 2)', 'real_highest_price'); + $search->withColumn('ROUND(MIN(' . implode(' OR ', $booleanMatchedPriceList) . '), 2)', 'real_lowest_price'); $current = $this->getCurrent(); @@ -518,7 +519,10 @@ class Product extends BaseI18nLoop ->set("DESCRIPTION", $product->getVirtualColumn('i18n_DESCRIPTION')) ->set("POSTSCRIPTUM", $product->getVirtualColumn('i18n_POSTSCRIPTUM')) ->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_NEW", $product->getVirtualColumn('main_product_is_new')) ->set("POSITION", $product->getPosition()) diff --git a/core/lib/Thelia/Exception/TaxEngineException.php b/core/lib/Thelia/Exception/TaxEngineException.php index b51aeef44..2a2718d4b 100755 --- a/core/lib/Thelia/Exception/TaxEngineException.php +++ b/core/lib/Thelia/Exception/TaxEngineException.php @@ -31,6 +31,9 @@ class TaxEngineException extends \RuntimeException const UNDEFINED_PRODUCT = 501; const UNDEFINED_COUNTRY = 502; + const UNDEFINED_TAX_RULES_COLLECTION = 503; + + const BAD_AMOUNT_FORMAT = 601; public function __construct($message, $code = null, $previous = null) { if($code === null) { diff --git a/core/lib/Thelia/Model/Product.php b/core/lib/Thelia/Model/Product.php index 6c7ffbe44..66e2a80ad 100755 --- a/core/lib/Thelia/Model/Product.php +++ b/core/lib/Thelia/Model/Product.php @@ -2,8 +2,10 @@ namespace Thelia\Model; +use Propel\Runtime\Exception\PropelException; use Thelia\Model\Base\Product as BaseProduct; use Thelia\Tools\URL; +use Thelia\TaxEngine\Calculator; class Product extends BaseProduct { @@ -11,4 +13,21 @@ class Product extends BaseProduct { 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(); + } } diff --git a/core/lib/Thelia/Model/Tax.php b/core/lib/Thelia/Model/Tax.php index ed61876ae..21efbae6a 100755 --- a/core/lib/Thelia/Model/Tax.php +++ b/core/lib/Thelia/Model/Tax.php @@ -2,8 +2,45 @@ namespace Thelia\Model; +use Thelia\Exception\TaxEngineException; 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; + } } diff --git a/core/lib/Thelia/Model/TaxRuleQuery.php b/core/lib/Thelia/Model/TaxRuleQuery.php index 833048fcf..b14e0f55d 100755 --- a/core/lib/Thelia/Model/TaxRuleQuery.php +++ b/core/lib/Thelia/Model/TaxRuleQuery.php @@ -4,7 +4,8 @@ namespace Thelia\Model; use Propel\Runtime\ActiveQuery\Criteria; 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. @@ -18,14 +19,26 @@ use Thelia\Model\Base\TaxRuleQuery as BaseTaxRuleQuery; */ class TaxRuleQuery extends BaseTaxRuleQuery { - public function getTaxCalculatorCollection(Product $product, Country $country) - { - $search = TaxRuleCountryQuery::create() - ->filterByCountry($country, Criteria::EQUAL) - ->filterByTaxRuleId($product->getTaxRuleId()) - ->orderByPosition() - ->find(); + const ALIAS_FOR_TAX_RULE_COUNTRY_POSITION = 'taxRuleCountryPosition'; + const ALIAS_FOR_TAX_RATE_SUM = 'taxRateSum'; - 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 diff --git a/core/lib/Thelia/TaxEngine/Calculator.php b/core/lib/Thelia/TaxEngine/Calculator.php index 2648b4d6d..b0dcbb2fa 100755 --- a/core/lib/Thelia/TaxEngine/Calculator.php +++ b/core/lib/Thelia/TaxEngine/Calculator.php @@ -36,7 +36,7 @@ class Calculator { protected $taxRuleQuery = null; - protected $taxRulesCollection = null; + protected $taxRulesGroupedCollection = null; protected $product = null; protected $country = null; @@ -44,12 +44,14 @@ class Calculator public function __construct() { $this->taxRuleQuery = new TaxRuleQuery(); - - return $this; } public function load(Product $product, Country $country) { + $this->product = null; + $this->country = null; + $this->taxRulesGroupedCollection = null; + if($product->getId() === null) { throw new TaxEngineException('Product id is empty in Calculator::load', TaxEngineException::UNDEFINED_PRODUCT); } @@ -60,13 +62,29 @@ class Calculator $this->product = $product; $this->country = $country; - $this->taxRulesCollection = $this->taxRuleQuery->getTaxCalculatorCollection($product, $country); + $this->taxRulesGroupedCollection = $this->taxRuleQuery->getTaxCalculatorGroupedCollection($product, $country); return $this; } 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(); } } diff --git a/templates/default/category.html b/templates/default/category.html index dd5c6a20a..4aae69cec 100755 --- a/templates/default/category.html +++ b/templates/default/category.html @@ -26,6 +26,8 @@

#TITLE

#DESCRIPTION

+

Starting by #BEST_PRICE € HT (#BEST_TAXED_PRICE € TTC)

+ {ifloop rel="ft"}
Features