Rajout du dossier core + MAJ .gitignore
This commit is contained in:
130
core/lib/Thelia/TaxEngine/BaseTaxType.php
Normal file
130
core/lib/Thelia/TaxEngine/BaseTaxType.php
Normal file
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\TaxEngine;
|
||||
|
||||
use Thelia\Exception\TaxEngineException;
|
||||
use Thelia\Model\Product;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Etienne Roudeix <eroudeix@openstudio.fr>
|
||||
*
|
||||
*/
|
||||
abstract class BaseTaxType
|
||||
{
|
||||
/**
|
||||
* A var <-> value array which contains TaxtType requirements (e.g. parameters)
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $requirements = array();
|
||||
|
||||
/**
|
||||
* For a price percent tax type, return the percentage (e.g. 20 for 20%) of the product price
|
||||
* to use in tax calculation.
|
||||
*
|
||||
* For other tax types, this method shoud return 0.
|
||||
*
|
||||
* @return number
|
||||
*/
|
||||
public function pricePercentRetriever()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* For constant amount tax type, return the absolute amount to use in tax calculation.
|
||||
*
|
||||
* For other tax types, this method shoud return 0.
|
||||
*
|
||||
* @return number
|
||||
*/
|
||||
public function fixAmountRetriever(Product $product)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requirements definition of this tax type. This is an array of
|
||||
* TaxTypeRequirementDefinition, which defines the name and the type of
|
||||
* the requirements. Example :
|
||||
*
|
||||
* array(
|
||||
* 'percent' => new FloatType()
|
||||
* );
|
||||
*
|
||||
* @return array of TaxTypeRequirementDefinition
|
||||
*/
|
||||
public function getRequirementsDefinition()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name of this tax type.
|
||||
*/
|
||||
abstract public function getTitle();
|
||||
|
||||
public function calculate(Product $product, $untaxedPrice)
|
||||
{
|
||||
return $untaxedPrice * $this->pricePercentRetriever() + $this->fixAmountRetriever($product);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws TaxEngineException
|
||||
* @return array Return the requirements array.
|
||||
*/
|
||||
public function getRequirements()
|
||||
{
|
||||
return $this->requirements;
|
||||
}
|
||||
|
||||
public function loadRequirements($requirementsValues)
|
||||
{
|
||||
$requirements = $this->getRequirementsDefinition();
|
||||
|
||||
if (!is_array($requirements)) {
|
||||
throw new TaxEngineException('getRequirementsDefinition must return an array', TaxEngineException::TAX_TYPE_BAD_ABSTRACT_METHOD);
|
||||
}
|
||||
|
||||
foreach ($requirements as $requirement) {
|
||||
$requirementName = $requirement->getName();
|
||||
|
||||
if (! array_key_exists($requirementName, $requirementsValues)) {
|
||||
throw new TaxEngineException('Cannot load requirements : requirement value for `' . $requirementName . '` not found', TaxEngineException::TAX_TYPE_REQUIREMENT_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (! $requirement->isValueValid($requirementsValues[$requirementName])) {
|
||||
throw new TaxEngineException('Requirement value for `' . $requirementName . '` does not match required type', TaxEngineException::TAX_TYPE_BAD_REQUIREMENT_VALUE);
|
||||
}
|
||||
|
||||
$this->requirements[$requirementName] = $requirementsValues[$requirementName];
|
||||
}
|
||||
}
|
||||
|
||||
public function setRequirement($key, $value)
|
||||
{
|
||||
$this->requirements[$key] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRequirement($key)
|
||||
{
|
||||
if (!array_key_exists($key, $this->requirements)) {
|
||||
throw new TaxEngineException('Requirement value for `' . $key . '` does not exists in BaseTaxType::$requirements', TaxEngineException::UNDEFINED_REQUIREMENT_VALUE);
|
||||
}
|
||||
|
||||
return $this->requirements[$key];
|
||||
}
|
||||
}
|
||||
237
core/lib/Thelia/TaxEngine/Calculator.php
Normal file
237
core/lib/Thelia/TaxEngine/Calculator.php
Normal file
@@ -0,0 +1,237 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\TaxEngine;
|
||||
|
||||
use Thelia\Exception\TaxEngineException;
|
||||
use Thelia\Model\Country;
|
||||
use Thelia\Model\OrderProductTax;
|
||||
use Thelia\Model\Product;
|
||||
use Thelia\Model\State;
|
||||
use Thelia\Model\TaxRule;
|
||||
use Thelia\Model\TaxRuleQuery;
|
||||
use Thelia\Tools\I18n;
|
||||
|
||||
/**
|
||||
* Class Calculator
|
||||
* @package Thelia\TaxEngine
|
||||
* @author Etienne Roudeix <eroudeix@openstudio.fr>
|
||||
*/
|
||||
class Calculator
|
||||
{
|
||||
/**
|
||||
* @var TaxRuleQuery
|
||||
*/
|
||||
protected $taxRuleQuery = null;
|
||||
|
||||
/**
|
||||
* @var null|\Propel\Runtime\Collection\ObjectCollection
|
||||
*/
|
||||
protected $taxRulesCollection = null;
|
||||
|
||||
protected $product = null;
|
||||
protected $country = null;
|
||||
protected $state = null;
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->taxRuleQuery = new TaxRuleQuery();
|
||||
}
|
||||
|
||||
public function load(Product $product, Country $country, State $state = null)
|
||||
{
|
||||
$this->product = null;
|
||||
$this->country = null;
|
||||
$this->state = null;
|
||||
|
||||
$this->taxRulesCollection = null;
|
||||
|
||||
if ($product->getId() === null) {
|
||||
throw new TaxEngineException('Product id is empty in Calculator::load', TaxEngineException::UNDEFINED_PRODUCT);
|
||||
}
|
||||
if ($country->getId() === null) {
|
||||
throw new TaxEngineException('Country id is empty in Calculator::load', TaxEngineException::UNDEFINED_COUNTRY);
|
||||
}
|
||||
|
||||
$this->product = $product;
|
||||
$this->country = $country;
|
||||
$this->state = $state;
|
||||
|
||||
$this->taxRulesCollection = $this->taxRuleQuery->getTaxCalculatorCollection($product->getTaxRule(), $country, $state);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function loadTaxRule(TaxRule $taxRule, Country $country, Product $product, State $state = null)
|
||||
{
|
||||
$this->product = null;
|
||||
$this->country = null;
|
||||
$this->taxRulesCollection = null;
|
||||
|
||||
if ($taxRule->getId() === null) {
|
||||
throw new TaxEngineException('TaxRule id is empty in Calculator::loadTaxRule', TaxEngineException::UNDEFINED_TAX_RULE);
|
||||
}
|
||||
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->state = $state;
|
||||
|
||||
$this->taxRulesCollection = $this->taxRuleQuery->getTaxCalculatorCollection($taxRule, $country, $state);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function loadTaxRuleWithoutProduct(TaxRule $taxRule, Country $country, State $state = null)
|
||||
{
|
||||
$this->product = null;
|
||||
$this->country = null;
|
||||
$this->taxRulesCollection = null;
|
||||
|
||||
if ($taxRule->getId() === null) {
|
||||
throw new TaxEngineException('TaxRule id is empty in Calculator::loadTaxRule', TaxEngineException::UNDEFINED_TAX_RULE);
|
||||
}
|
||||
if ($country->getId() === null) {
|
||||
throw new TaxEngineException('Country id is empty in Calculator::loadTaxRule', TaxEngineException::UNDEFINED_COUNTRY);
|
||||
}
|
||||
|
||||
$this->country = $country;
|
||||
$this->product = new Product();
|
||||
$this->state = $state;
|
||||
|
||||
$this->taxRulesCollection = $this->taxRuleQuery->getTaxCalculatorCollection($taxRule, $country, $state);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getTaxAmountFromUntaxedPrice($untaxedPrice, &$taxCollection = null)
|
||||
{
|
||||
return $this->getTaxedPrice($untaxedPrice, $taxCollection) - $untaxedPrice;
|
||||
}
|
||||
|
||||
public function getTaxAmountFromTaxedPrice($taxedPrice)
|
||||
{
|
||||
return $taxedPrice - $this->getUntaxedPrice($taxedPrice);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $untaxedPrice
|
||||
* @param null $taxCollection returns OrderProductTaxCollection
|
||||
* @param null $askedLocale
|
||||
*
|
||||
* @return int
|
||||
* @throws \Thelia\Exception\TaxEngineException
|
||||
*/
|
||||
public function getTaxedPrice($untaxedPrice, &$taxCollection = null, $askedLocale = null)
|
||||
{
|
||||
if (null === $this->taxRulesCollection) {
|
||||
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)) {
|
||||
throw new TaxEngineException('BAD AMOUNT FORMAT', TaxEngineException::BAD_AMOUNT_FORMAT);
|
||||
}
|
||||
|
||||
$taxedPrice = $untaxedPrice;
|
||||
$currentPosition = 1;
|
||||
$currentTax = 0;
|
||||
|
||||
if (null !== $taxCollection) {
|
||||
$taxCollection = new OrderProductTaxCollection();
|
||||
}
|
||||
foreach ($this->taxRulesCollection as $taxRule) {
|
||||
$position = (int) $taxRule->getTaxRuleCountryPosition();
|
||||
|
||||
$taxType = $taxRule->getTypeInstance();
|
||||
|
||||
if ($currentPosition !== $position) {
|
||||
$taxedPrice += $currentTax;
|
||||
$currentTax = 0;
|
||||
$currentPosition = $position;
|
||||
}
|
||||
|
||||
$taxAmount = $taxType->calculate($this->product, $taxedPrice);
|
||||
$currentTax += $taxAmount;
|
||||
|
||||
if (null !== $taxCollection) {
|
||||
$taxI18n = I18n::forceI18nRetrieving($askedLocale, 'Tax', $taxRule->getId());
|
||||
$orderProductTax = new OrderProductTax();
|
||||
$orderProductTax->setTitle($taxI18n->getTitle());
|
||||
$orderProductTax->setDescription($taxI18n->getDescription());
|
||||
$orderProductTax->setAmount($taxAmount);
|
||||
$taxCollection->addTax($orderProductTax);
|
||||
}
|
||||
}
|
||||
|
||||
$taxedPrice += $currentTax;
|
||||
|
||||
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 (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;
|
||||
$currentTaxFactor = 0;
|
||||
|
||||
do {
|
||||
$position = (int) $taxRule->getTaxRuleCountryPosition();
|
||||
|
||||
$taxType = $taxRule->getTypeInstance();
|
||||
|
||||
if ($currentPosition !== $position) {
|
||||
$untaxedPrice -= $currentFixTax;
|
||||
$untaxedPrice = $untaxedPrice / (1+$currentTaxFactor);
|
||||
$currentFixTax = 0;
|
||||
$currentTaxFactor = 0;
|
||||
$currentPosition = $position;
|
||||
}
|
||||
|
||||
$currentFixTax += $taxType->fixAmountRetriever($this->product);
|
||||
$currentTaxFactor += $taxType->pricePercentRetriever();
|
||||
} while ($taxRule = $this->taxRulesCollection->getPrevious());
|
||||
|
||||
$untaxedPrice -= $currentFixTax;
|
||||
$untaxedPrice = $untaxedPrice / (1+$currentTaxFactor);
|
||||
|
||||
return $untaxedPrice;
|
||||
}
|
||||
}
|
||||
116
core/lib/Thelia/TaxEngine/OrderProductTaxCollection.php
Normal file
116
core/lib/Thelia/TaxEngine/OrderProductTaxCollection.php
Normal file
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\TaxEngine;
|
||||
|
||||
use Thelia\Model\OrderProductTax;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Etienne Roudeix <eroudeix@openstudio.fr>
|
||||
*
|
||||
*/
|
||||
class OrderProductTaxCollection implements \Iterator
|
||||
{
|
||||
private $position;
|
||||
protected $taxes = array();
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
foreach (func_get_args() as $tax) {
|
||||
$this->addTax($tax);
|
||||
}
|
||||
}
|
||||
|
||||
public function isEmpty()
|
||||
{
|
||||
return count($this->taxes) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param OrderProductTax $tax
|
||||
*
|
||||
* @return OrderProductTaxCollection
|
||||
*/
|
||||
public function addTax(OrderProductTax $tax)
|
||||
{
|
||||
$this->taxes[] = $tax;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCount()
|
||||
{
|
||||
return count($this->taxes);
|
||||
}
|
||||
|
||||
/**
|
||||
* (PHP 5 >= 5.0.0)<br/>
|
||||
* Return the current element
|
||||
* @link http://php.net/manual/en/iterator.current.php
|
||||
* @return OrderProductTax
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return $this->taxes[$this->position];
|
||||
}
|
||||
|
||||
/**
|
||||
* (PHP 5 >= 5.0.0)<br/>
|
||||
* Move forward to next element
|
||||
* @link http://php.net/manual/en/iterator.next.php
|
||||
* @return void Any returned value is ignored.
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
$this->position++;
|
||||
}
|
||||
|
||||
/**
|
||||
* (PHP 5 >= 5.0.0)<br/>
|
||||
* Return the key of the current element
|
||||
* @link http://php.net/manual/en/iterator.key.php
|
||||
* @return mixed scalar on success, or null on failure.
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
/**
|
||||
* (PHP 5 >= 5.0.0)<br/>
|
||||
* Checks if current position is valid
|
||||
* @link http://php.net/manual/en/iterator.valid.php
|
||||
* @return boolean The return value will be casted to boolean and then evaluated.
|
||||
* Returns true on success or false on failure.
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
return isset($this->taxes[$this->position]);
|
||||
}
|
||||
|
||||
/**
|
||||
* (PHP 5 >= 5.0.0)<br/>
|
||||
* Rewind the Iterator to the first element
|
||||
* @link http://php.net/manual/en/iterator.rewind.php
|
||||
* @return void Any returned value is ignored.
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
$this->position = 0;
|
||||
}
|
||||
|
||||
public function getKey($key)
|
||||
{
|
||||
return isset($this->taxes[$key]) ? $this->taxes[$key] : null;
|
||||
}
|
||||
}
|
||||
171
core/lib/Thelia/TaxEngine/TaxEngine.php
Normal file
171
core/lib/Thelia/TaxEngine/TaxEngine.php
Normal file
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\TaxEngine;
|
||||
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Thelia\Core\HttpFoundation\Session\Session;
|
||||
use Thelia\Model\AddressQuery;
|
||||
use Thelia\Model\Country;
|
||||
use Thelia\Model\CountryQuery;
|
||||
use Thelia\Model\Customer;
|
||||
use Thelia\Model\State;
|
||||
|
||||
/**
|
||||
* Class TaxEngine
|
||||
*
|
||||
* @package Thelia\TaxEngine
|
||||
* @author Etienne Roudeix <eroudeix@openstudio.fr>
|
||||
*/
|
||||
class TaxEngine
|
||||
{
|
||||
protected $taxCountry = null;
|
||||
protected $taxState = null;
|
||||
protected $typeList = null;
|
||||
|
||||
protected $taxTypesDirectories = array();
|
||||
|
||||
/** @var RequestStack */
|
||||
protected $requestStack;
|
||||
|
||||
public function __construct(RequestStack $requestStack)
|
||||
{
|
||||
$this->requestStack = $requestStack;
|
||||
|
||||
// Intialize the defaults Tax Types
|
||||
$this->taxTypesDirectories['Thelia\\TaxEngine\\TaxType'] = __DIR__ . DS . "TaxType";
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a directroy which contains tax types classes. The tax engine
|
||||
* will scan this directory, and add all the tax type classes.
|
||||
*
|
||||
* @param string $namespace the namespace of the classes in the directory
|
||||
* @param string $path_to_tax_type_classes the path to the directory
|
||||
*/
|
||||
public function addTaxTypeDirectory($namespace, $path_to_tax_type_classes)
|
||||
{
|
||||
$this->taxTypesDirectories[$namespace] = $path_to_tax_type_classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a tax type to the current list.
|
||||
*
|
||||
* @param unknown $fullyQualifiedclassName the fully qualified classname, su chas MyTaxes\Taxes\MyTaxType
|
||||
*
|
||||
*/
|
||||
public function addTaxType($fullyQualifiedclassName)
|
||||
{
|
||||
$this->typeList[] = $fullyQualifiedclassName;
|
||||
}
|
||||
|
||||
public function getTaxTypeList()
|
||||
{
|
||||
if ($this->typeList === null) {
|
||||
$this->typeList = array();
|
||||
|
||||
foreach ($this->taxTypesDirectories as $namespace => $directory) {
|
||||
try {
|
||||
$directoryIterator = new \DirectoryIterator($directory);
|
||||
|
||||
foreach ($directoryIterator as $fileinfo) {
|
||||
if ($fileinfo->isFile()) {
|
||||
$extension = $fileinfo->getExtension();
|
||||
if (strtolower($extension) !== 'php')
|
||||
continue;
|
||||
$className = $fileinfo->getBaseName('.php');
|
||||
|
||||
try {
|
||||
$fullyQualifiedClassName = "$namespace\\$className";
|
||||
|
||||
$instance = new $fullyQualifiedClassName;
|
||||
|
||||
if ($instance instanceof BaseTaxType) {
|
||||
$this->addTaxType(get_class($instance));
|
||||
}
|
||||
} catch (\Exception $ex) {
|
||||
// Nothing special to do
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (\UnexpectedValueException $e) {
|
||||
// Nothing special to do
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->typeList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find Tax Country Id
|
||||
* First look for a picked delivery address country
|
||||
* Then look at the current customer default address country
|
||||
* Else look at the default website country
|
||||
|
||||
* @return null|Country
|
||||
*/
|
||||
public function getDeliveryCountry()
|
||||
{
|
||||
if (null === $this->taxCountry) {
|
||||
/* is there a logged in customer ? */
|
||||
/** @var Customer $customer */
|
||||
if (null !== $customer = $this->getSession()->getCustomerUser()) {
|
||||
if (null !== $this->getSession()->getOrder()
|
||||
&& null !== $this->getSession()->getOrder()->getChoosenDeliveryAddress()
|
||||
&& null !== $currentDeliveryAddress = AddressQuery::create()->findPk($this->getSession()->getOrder()->getChoosenDeliveryAddress())) {
|
||||
$this->taxCountry = $currentDeliveryAddress->getCountry();
|
||||
$this->taxState = $currentDeliveryAddress->getState();
|
||||
} else {
|
||||
$customerDefaultAddress = $customer->getDefaultAddress();
|
||||
$this->taxCountry = $customerDefaultAddress->getCountry();
|
||||
$this->taxState = $customerDefaultAddress->getState();
|
||||
}
|
||||
}
|
||||
|
||||
if (null == $this->taxCountry) {
|
||||
$this->taxCountry = CountryQuery::create()->findOneByByDefault(1);
|
||||
$this->taxState = null;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->taxCountry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find Tax State Id
|
||||
*
|
||||
* First look for a picked delivery address state
|
||||
* Then look at the current customer default address state
|
||||
* Else null
|
||||
|
||||
* @return null|State
|
||||
* @since 2.3.0-alpha1
|
||||
*/
|
||||
public function getDeliveryState()
|
||||
{
|
||||
if (null === $this->taxCountry) {
|
||||
/* is there a logged in customer ? */
|
||||
$this->getDeliveryCountry();
|
||||
}
|
||||
|
||||
return $this->taxState;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Session
|
||||
*/
|
||||
protected function getSession()
|
||||
{
|
||||
return $this->requestStack->getCurrentRequest()->getSession();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\TaxEngine\TaxType;
|
||||
|
||||
use Thelia\Exception\TaxEngineException;
|
||||
use Thelia\Model\FeatureProductQuery;
|
||||
use Thelia\Model\Product;
|
||||
use Thelia\Type\FloatType;
|
||||
use Thelia\Type\ModelValidIdType;
|
||||
use Thelia\Core\Translation\Translator;
|
||||
use Thelia\TaxEngine\BaseTaxType;
|
||||
use Thelia\TaxEngine\TaxTypeRequirementDefinition;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Etienne Roudeix <eroudeix@openstudio.fr>
|
||||
*
|
||||
*/
|
||||
class FeatureFixAmountTaxType extends BaseTaxType
|
||||
{
|
||||
public function setFeature($featureId)
|
||||
{
|
||||
$this->setRequirement('feature', $featureId);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function fixAmountRetriever(Product $product)
|
||||
{
|
||||
$taxAmount = 0;
|
||||
$featureId = $this->getRequirement("feature");
|
||||
|
||||
$query = FeatureProductQuery::create()
|
||||
->filterByProduct($product)
|
||||
->filterByFeatureId($featureId)
|
||||
->findOne();
|
||||
|
||||
if (null !== $query) {
|
||||
$taxAmount = $query->getFreeTextValue();
|
||||
|
||||
$testInt = new FloatType();
|
||||
if (!$testInt->isValid($taxAmount)) {
|
||||
throw new TaxEngineException(
|
||||
Translator::getInstance()->trans('Feature value does not match FLOAT format'),
|
||||
TaxEngineException::FEATURE_BAD_EXPECTED_VALUE
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $taxAmount;
|
||||
}
|
||||
|
||||
public function getRequirementsDefinition()
|
||||
{
|
||||
return array(
|
||||
new TaxTypeRequirementDefinition(
|
||||
'feature',
|
||||
new ModelValidIdType('Feature'),
|
||||
Translator::getInstance()->trans("Feature")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return Translator::getInstance()->trans("Constant amount found in one of the product's feature");
|
||||
}
|
||||
}
|
||||
54
core/lib/Thelia/TaxEngine/TaxType/FixAmountTaxType.php
Normal file
54
core/lib/Thelia/TaxEngine/TaxType/FixAmountTaxType.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\TaxEngine\TaxType;
|
||||
|
||||
use Thelia\Type\FloatType;
|
||||
use Thelia\Core\Translation\Translator;
|
||||
use Thelia\TaxEngine\BaseTaxType;
|
||||
use Thelia\TaxEngine\TaxTypeRequirementDefinition;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Etienne Roudeix <eroudeix@openstudio.fr>
|
||||
*
|
||||
*/
|
||||
class FixAmountTaxType extends BaseTaxType
|
||||
{
|
||||
public function setAmount($amount)
|
||||
{
|
||||
$this->setRequirement('amount', $amount);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function fixAmountRetriever(\Thelia\Model\Product $product)
|
||||
{
|
||||
return $this->getRequirement("amount");
|
||||
}
|
||||
|
||||
public function getRequirementsDefinition()
|
||||
{
|
||||
return array(
|
||||
new TaxTypeRequirementDefinition(
|
||||
'amount',
|
||||
new FloatType(),
|
||||
Translator::getInstance()->trans("Amount")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return Translator::getInstance()->trans("Constant amount");
|
||||
}
|
||||
}
|
||||
54
core/lib/Thelia/TaxEngine/TaxType/PricePercentTaxType.php
Normal file
54
core/lib/Thelia/TaxEngine/TaxType/PricePercentTaxType.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\TaxEngine\TaxType;
|
||||
|
||||
use Thelia\Type\FloatType;
|
||||
use Thelia\Core\Translation\Translator;
|
||||
use Thelia\TaxEngine\TaxTypeRequirementDefinition;
|
||||
use Thelia\TaxEngine\BaseTaxType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Etienne Roudeix <eroudeix@openstudio.fr>
|
||||
*
|
||||
*/
|
||||
class PricePercentTaxType extends BaseTaxType
|
||||
{
|
||||
public function setPercentage($percent)
|
||||
{
|
||||
$this->setRequirement('percent', $percent);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function pricePercentRetriever()
|
||||
{
|
||||
return ($this->getRequirement("percent") * 0.01);
|
||||
}
|
||||
|
||||
public function getRequirementsDefinition()
|
||||
{
|
||||
return array(
|
||||
new TaxTypeRequirementDefinition(
|
||||
'percent',
|
||||
new FloatType(),
|
||||
Translator::getInstance()->trans("Percent")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return Translator::getInstance()->trans("Percentage of the product price");
|
||||
}
|
||||
}
|
||||
71
core/lib/Thelia/TaxEngine/TaxTypeRequirementDefinition.php
Normal file
71
core/lib/Thelia/TaxEngine/TaxTypeRequirementDefinition.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\TaxEngine;
|
||||
|
||||
use Thelia\Type\TypeInterface;
|
||||
|
||||
/**
|
||||
* This class defines a Tax type requirement
|
||||
*
|
||||
* @author Franck Allimant <franck@cqfdev.fr>
|
||||
*/
|
||||
class TaxTypeRequirementDefinition
|
||||
{
|
||||
/**
|
||||
* @var string The requirement name
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* @var TypeInterface The requirement type
|
||||
*/
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* @var string The translated requirement title
|
||||
*/
|
||||
protected $title;
|
||||
|
||||
/**
|
||||
* Create a new Tax type requirement
|
||||
*
|
||||
* @param string $name the name of the requirement
|
||||
* @param TypeInterface $type the type of the data
|
||||
*/
|
||||
public function __construct($name, TypeInterface $type, $title = null)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->type = $type;
|
||||
$this->title = $title ?: $name;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
public function isValueValid($value)
|
||||
{
|
||||
return $this->type->isValid($value);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user