TaxManager is now a service in the container.
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
</parameters>
|
||||
|
||||
<services>
|
||||
|
||||
<!-- URL maganement -->
|
||||
<service id="thelia.url.manager" class="Thelia\Tools\URL">
|
||||
<argument type="service" id="service_container" />
|
||||
@@ -35,6 +36,13 @@
|
||||
<argument type="service" id="esi" />
|
||||
<argument type="service" id="fragment.renderer.inline" />
|
||||
</service>
|
||||
|
||||
<!-- Tax engine -->
|
||||
|
||||
<service id="thelia.taxEngine" class="Thelia\TaxEngine\TaxEngine" scope="request">
|
||||
<argument type="service" id="request" />
|
||||
</service>
|
||||
|
||||
<!--
|
||||
A ControllerResolver that supports "a:b:c", "service:method" and class::method" notations,
|
||||
thus allowing the definition of controllers as service (see http://symfony.com/fr/doc/current/cookbook/controller/service.html)
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
<tag name="thelia.parser.register_plugin"/>
|
||||
<argument type="service" id="request" />
|
||||
<argument type="service" id="thelia.securityContext" />
|
||||
<argument type="service" id="thelia.taxEngine" />
|
||||
<argument type="service" id="thelia.parser.context"/>
|
||||
<argument type="service" id="event_dispatcher"/>
|
||||
</service>
|
||||
|
||||
@@ -29,6 +29,7 @@ use Thelia\Core\Event\TheliaEvents;
|
||||
use Thelia\Form\TaxCreationForm;
|
||||
use Thelia\Form\TaxModificationForm;
|
||||
use Thelia\Model\TaxQuery;
|
||||
use Thelia\Model\Tax;
|
||||
|
||||
class TaxController extends AbstractCrudController
|
||||
{
|
||||
@@ -49,7 +50,9 @@ class TaxController extends AbstractCrudController
|
||||
|
||||
protected function getCreationForm()
|
||||
{
|
||||
return new TaxCreationForm($this->getRequest());
|
||||
$form = new TaxCreationForm($this->getRequest());
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
protected function getUpdateForm()
|
||||
@@ -64,7 +67,7 @@ class TaxController extends AbstractCrudController
|
||||
$event->setLocale($formData['locale']);
|
||||
$event->setTitle($formData['title']);
|
||||
$event->setDescription($formData['description']);
|
||||
$event->setType($formData['type']);
|
||||
$event->setType(Tax::unescapeTypeName($formData['type']));
|
||||
$event->setRequirements($this->getRequirements($formData['type'], $formData));
|
||||
|
||||
return $event;
|
||||
@@ -78,7 +81,7 @@ class TaxController extends AbstractCrudController
|
||||
$event->setId($formData['id']);
|
||||
$event->setTitle($formData['title']);
|
||||
$event->setDescription($formData['description']);
|
||||
$event->setType($formData['type']);
|
||||
$event->setType(Tax::unescapeTypeName($formData['type']));
|
||||
$event->setRequirements($this->getRequirements($formData['type'], $formData));
|
||||
|
||||
return $event;
|
||||
@@ -107,7 +110,7 @@ class TaxController extends AbstractCrudController
|
||||
'locale' => $object->getLocale(),
|
||||
'title' => $object->getTitle(),
|
||||
'description' => $object->getDescription(),
|
||||
'type' => $object->getType(),
|
||||
'type' => Tax::escapeTypeName($object->getType()),
|
||||
);
|
||||
|
||||
// Setup the object form
|
||||
@@ -200,27 +203,20 @@ class TaxController extends AbstractCrudController
|
||||
);
|
||||
}
|
||||
|
||||
protected function checkRequirements($formData)
|
||||
{
|
||||
$type = $formData['type'];
|
||||
|
||||
}
|
||||
|
||||
protected function getRequirements($type, $formData)
|
||||
{
|
||||
$requirements = array();
|
||||
foreach ($formData as $data => $value) {
|
||||
|
||||
if (!strstr($data, ':')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$couple = explode(':', $data);
|
||||
|
||||
if (count($couple) != 2 || $couple[0] != $type) {
|
||||
continue;
|
||||
if (count($couple) == 2 && $couple[0] == $type) {
|
||||
$requirements[$couple[1]] = $value;
|
||||
}
|
||||
|
||||
$requirements[$couple[1]] = $value;
|
||||
}
|
||||
|
||||
return $requirements;
|
||||
|
||||
@@ -78,7 +78,7 @@ class Cart extends BaseLoop implements ArraySearchLoopInterface
|
||||
|
||||
public function parseResults(LoopResult $loopResult)
|
||||
{
|
||||
$taxCountry = TaxEngine::getInstance($this->request->getSession())->getDeliveryCountry();
|
||||
$taxCountry = $this->container->get('thelia.taxEngine')->getDeliveryCountry();
|
||||
|
||||
foreach ($loopResult->getResultDataCollection() as $cartItem) {
|
||||
$product = $cartItem->getProduct();
|
||||
|
||||
@@ -60,7 +60,7 @@ class Delivery extends BaseSpecificModule
|
||||
throw new \InvalidArgumentException('Cannot found country id: `' . $countryId . '` in delivery loop');
|
||||
}
|
||||
} else {
|
||||
$country = TaxEngine::getInstance($this->request->getSession())->getDeliveryCountry();
|
||||
$country = $this->container->get('thelia.taxEngine')->getDeliveryCountry();
|
||||
}
|
||||
|
||||
foreach ($loopResult->getResultDataCollection() as $deliveryModule) {
|
||||
|
||||
@@ -464,7 +464,7 @@ class Product extends BaseI18nLoop implements PropelSearchLoopInterface, SearchL
|
||||
return $this->parseComplex($loopResult);
|
||||
}
|
||||
|
||||
$taxCountry = TaxEngine::getInstance($this->request->getSession())->getDeliveryCountry();
|
||||
$taxCountry = $this->container->get('thelia.taxEngine')->getDeliveryCountry();
|
||||
|
||||
foreach ($loopResult->getResultDataCollection() as $product) {
|
||||
|
||||
@@ -982,7 +982,7 @@ class Product extends BaseI18nLoop implements PropelSearchLoopInterface, SearchL
|
||||
{
|
||||
$loopResult = new LoopResult($results);
|
||||
|
||||
$taxCountry = TaxEngine::getInstance($this->request->getSession())->getDeliveryCountry();
|
||||
$taxCountry = $this->container->get('thelia.taxEngine')->getDeliveryCountry();
|
||||
|
||||
foreach ($loopResult->getResultDataCollection() as $product) {
|
||||
|
||||
|
||||
@@ -145,7 +145,7 @@ class ProductSaleElements extends BaseLoop implements PropelSearchLoopInterface
|
||||
|
||||
public function parseResults(LoopResult $loopResult)
|
||||
{
|
||||
$taxCountry = TaxEngine::getInstance($this->request->getSession())->getDeliveryCountry();
|
||||
$taxCountry = $this->container->get('thelia.taxEngine')->getDeliveryCountry();
|
||||
|
||||
foreach ($loopResult->getResultDataCollection() as $PSEValue) {
|
||||
$loopResultRow = new LoopResultRow($PSEValue);
|
||||
|
||||
@@ -150,6 +150,7 @@ class Tax extends BaseI18nLoop implements PropelSearchLoopInterface
|
||||
$loopResultRow
|
||||
->set("ID" , $tax->getId())
|
||||
->set("TYPE" , $tax->getType())
|
||||
->set("ESCAPED_TYPE" , \Thelia\Model\Tax::escapeTypeName($tax->getType()))
|
||||
->set("REQUIREMENTS" , $tax->getRequirements())
|
||||
->set("IS_TRANSLATED" , $tax->getVirtualColumn('IS_TRANSLATED'))
|
||||
->set("LOCALE" , $this->locale)
|
||||
|
||||
@@ -58,15 +58,17 @@ class DataAccessFunctions extends AbstractSmartyPlugin
|
||||
protected $parserContext;
|
||||
protected $request;
|
||||
protected $dispatcher;
|
||||
protected $taxEngine;
|
||||
|
||||
private static $dataAccessCache = array();
|
||||
|
||||
public function __construct(Request $request, SecurityContext $securityContext, ParserContext $parserContext, ContainerAwareEventDispatcher $dispatcher)
|
||||
public function __construct(Request $request, SecurityContext $securityContext, TaxEngine $taxEngine, ParserContext $parserContext, ContainerAwareEventDispatcher $dispatcher)
|
||||
{
|
||||
$this->securityContext = $securityContext;
|
||||
$this->parserContext = $parserContext;
|
||||
$this->request = $request;
|
||||
$this->dispatcher = $dispatcher;
|
||||
$this->taxEngine = $taxEngine;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -184,7 +186,7 @@ class DataAccessFunctions extends AbstractSmartyPlugin
|
||||
if (array_key_exists('currentCountry', self::$dataAccessCache)) {
|
||||
$taxCountry = self::$dataAccessCache['currentCountry'];
|
||||
} else {
|
||||
$taxCountry = TaxEngine::getInstance($this->request->getSession())->getDeliveryCountry();
|
||||
$taxCountry = $this->taxEngine->getDeliveryCountry();
|
||||
self::$dataAccessCache['currentCountry'] = $taxCountry;
|
||||
}
|
||||
|
||||
@@ -378,12 +380,17 @@ class DataAccessFunctions extends AbstractSmartyPlugin
|
||||
self::$dataAccessCache['data_' . $objectLabel] = $data;
|
||||
}
|
||||
|
||||
$noGetterData = array();
|
||||
foreach ($columns as $column) {
|
||||
$noGetterData[$column] = $data->getVirtualColumn('i18n_' . $column);
|
||||
if ($data !== null) {
|
||||
$noGetterData = array();
|
||||
|
||||
foreach ($columns as $column) {
|
||||
$noGetterData[$column] = $data->getVirtualColumn('i18n_' . $column);
|
||||
}
|
||||
|
||||
return $this->dataAccess($objectLabel, $params, $data, $noGetterData);
|
||||
}
|
||||
|
||||
return $this->dataAccess($objectLabel, $params, $data, $noGetterData);
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,6 +28,8 @@ use Thelia\Core\Form\Type\TheliaType;
|
||||
use Thelia\Core\Translation\Translator;
|
||||
use Thelia\TaxEngine\TaxEngine;
|
||||
use Thelia\TaxEngine\TaxType;
|
||||
use Thelia\Core\HttpFoundation\Request;
|
||||
use Thelia\Model\Tax;
|
||||
|
||||
/**
|
||||
* Class TaxCreationForm
|
||||
@@ -40,14 +42,21 @@ class TaxCreationForm extends BaseForm
|
||||
|
||||
protected function buildForm($change_mode = false)
|
||||
{
|
||||
$types = TaxEngine::getInstance($this->getRequest()->getSession())->getTaxTypeList();
|
||||
// FIXME : SHOULD be extracted from the container
|
||||
$taxEngine = new TaxEngine($this->getRequest());
|
||||
|
||||
$types = $taxEngine->getTaxTypeList();
|
||||
|
||||
$typeList = array();
|
||||
$requirementList = array();
|
||||
foreach ($types as $type) {
|
||||
$classPath = "\\Thelia\\TaxEngine\\TaxType\\$type";
|
||||
$instance = new $classPath();
|
||||
$typeList[$type] = $instance->getTitle();
|
||||
$requirementList[$type] = $instance->getRequirementsList();
|
||||
|
||||
foreach ($types as $classname) {
|
||||
|
||||
$instance = new $classname();
|
||||
|
||||
$typeList[Tax::escapeTypeName($classname)] = $instance->getTitle();
|
||||
|
||||
$requirementList[$classname] = $instance->getRequirementsDefinition();
|
||||
}
|
||||
|
||||
$this->formBuilder
|
||||
@@ -65,27 +74,29 @@ class TaxCreationForm extends BaseForm
|
||||
))
|
||||
;
|
||||
|
||||
foreach ($requirementList as $type => $requirements) {
|
||||
foreach ($requirements as $name => $requirementType) {
|
||||
foreach ($requirementList as $name => $requirements) {
|
||||
foreach ($requirements as $requirement) {
|
||||
$this->formBuilder
|
||||
->add($type . ':' . $name, new TheliaType(), array(
|
||||
//"instance" => $requirementType,
|
||||
// Replace the '\' in the class name by hyphens
|
||||
// See TaxController::getRequirements if some changes are made about this.
|
||||
->add(Tax::escapeTypeName($name) . ':' . $requirement->getName(), new TheliaType(), array(
|
||||
//"instance" => $requirement->getType(),
|
||||
"constraints" => array(
|
||||
new Constraints\Callback(
|
||||
array(
|
||||
"methods" => array(
|
||||
array($requirementType, "verifyForm"),
|
||||
array($requirement->getType(), "verifyForm"),
|
||||
),
|
||||
)
|
||||
),
|
||||
),
|
||||
"attr" => array(
|
||||
"tag" => "requirements",
|
||||
"tax_type" => $type,
|
||||
"tax_type" => Tax::escapeTypeName($name),
|
||||
),
|
||||
"label" => Translator::getInstance()->trans($name),
|
||||
"type" => $requirementType->getFormType(),
|
||||
"options" => $requirementType->getFormOptions(),
|
||||
"label" => Translator::getInstance()->trans($requirement->getName()),
|
||||
"type" => $requirement->getType()->getFormType(),
|
||||
"options" => $requirement->getType()->getFormOptions(),
|
||||
))
|
||||
;
|
||||
}
|
||||
|
||||
@@ -5,12 +5,23 @@ namespace Thelia\Model;
|
||||
use Thelia\Exception\TaxEngineException;
|
||||
use Thelia\Model\Base\Tax as BaseTax;
|
||||
use Thelia\Model\Tools\ModelEventDispatcherTrait;
|
||||
use Thelia\TaxEngine\TaxType\BaseTaxType;
|
||||
use Thelia\TaxEngine\BaseTaxType;
|
||||
|
||||
class Tax extends BaseTax
|
||||
{
|
||||
use ModelEventDispatcherTrait;
|
||||
|
||||
/**
|
||||
* Provides a form-and-javascript-safe version of the type, which is a fully qualified classname, with \
|
||||
*/
|
||||
public static function escapeTypeName($name) {
|
||||
return str_replace('\\', '-', $name);
|
||||
}
|
||||
|
||||
public static function unescapeTypeName($name) {
|
||||
return str_replace('-', '\\', $name);
|
||||
}
|
||||
|
||||
public function calculateTax($amount)
|
||||
{
|
||||
if(false === filter_var($amount, FILTER_VALIDATE_FLOAT)) {
|
||||
@@ -39,7 +50,7 @@ class Tax extends BaseTax
|
||||
|
||||
public function getTypeInstance()
|
||||
{
|
||||
$class = '\\Thelia\\TaxEngine\\TaxType\\' . $this->getType();
|
||||
$class = $this->getType();
|
||||
|
||||
/* test type */
|
||||
if(!class_exists($class)) {
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* */
|
||||
/*************************************************************************************/
|
||||
namespace Thelia\TaxEngine\TaxType;
|
||||
namespace Thelia\TaxEngine;
|
||||
|
||||
use Thelia\Exception\TaxEngineException;
|
||||
use Thelia\Model\Product;
|
||||
@@ -33,14 +33,54 @@ use Thelia\Type\TypeInterface;
|
||||
*/
|
||||
abstract class BaseTaxType
|
||||
{
|
||||
protected $requirements = null;
|
||||
/**
|
||||
* A var <-> value array which contains TaxtType requirements (e.g. parameters)
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $requirements = array();
|
||||
|
||||
abstract public function pricePercentRetriever();
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
abstract public function fixAmountRetriever(Product $product);
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
abstract public function getRequirementsList();
|
||||
/**
|
||||
* 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)
|
||||
@@ -48,41 +88,50 @@ abstract class BaseTaxType
|
||||
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)
|
||||
{
|
||||
$this->requirements = $this->getRequirementsList();
|
||||
$requirements = $this->getRequirementsDefinition();
|
||||
|
||||
if (!is_array($this->requirements)) {
|
||||
throw new TaxEngineException('getRequirementsList must return an array', TaxEngineException::TAX_TYPE_BAD_ABSTRACT_METHOD);
|
||||
if (!is_array($requirements)) {
|
||||
throw new TaxEngineException('getRequirementsDefinition must return an array', TaxEngineException::TAX_TYPE_BAD_ABSTRACT_METHOD);
|
||||
}
|
||||
|
||||
foreach ($this->requirements as $requirement => $requirementType) {
|
||||
if (!$requirementType instanceof TypeInterface) {
|
||||
throw new TaxEngineException('getRequirementsList must return an array of TypeInterface', 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 (!array_key_exists($requirement, $requirementsValues)) {
|
||||
throw new TaxEngineException('Cannot load requirements : requirement value for `' . $requirement . '` 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);
|
||||
}
|
||||
|
||||
if (!$requirementType->isValid($requirementsValues[$requirement])) {
|
||||
throw new TaxEngineException('Requirement value for `' . $requirement . '` does not match required type', TaxEngineException::TAX_TYPE_BAD_REQUIREMENT_VALUE);
|
||||
}
|
||||
|
||||
$this->requirements[$requirement] = $requirementsValues[$requirement];
|
||||
$this->requirements[$requirementName] = $requirementsValues[$requirementName];
|
||||
}
|
||||
}
|
||||
|
||||
public function setRequirement($key, $value) {
|
||||
$this->requirements[$key] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRequirement($key)
|
||||
{
|
||||
if ($this->requirements === null) {
|
||||
throw new TaxEngineException('Requirements are empty in BaseTaxType::getRequirement', TaxEngineException::UNDEFINED_REQUIREMENTS);
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,74 +25,94 @@ namespace Thelia\TaxEngine;
|
||||
use Symfony\Component\HttpFoundation\Session\Session;
|
||||
use Thelia\Model\AddressQuery;
|
||||
use Thelia\Model\CountryQuery;
|
||||
use Thelia\Core\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Class TaxEngine
|
||||
*
|
||||
* @package Thelia\TaxEngine
|
||||
* @author Etienne Roudeix <eroudeix@openstudio.fr>
|
||||
*/
|
||||
class TaxEngine
|
||||
{
|
||||
protected static $instance = null;
|
||||
protected $taxCountry = null;
|
||||
protected $typeList = null;
|
||||
|
||||
protected static $taxCountry = null;
|
||||
protected $taxTypesDirectories = array();
|
||||
|
||||
/**
|
||||
* @var Session $session
|
||||
*/
|
||||
protected $session = null;
|
||||
|
||||
public static function getInstance(Session $session = null)
|
||||
public function __construct(Request $request)
|
||||
{
|
||||
if (null === self::$instance) {
|
||||
self::$instance = new TaxEngine();
|
||||
}
|
||||
$this->session = $request->getSession();
|
||||
|
||||
if (null !== self::$instance) {
|
||||
self::$instance->setSession($session);
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
// Intialize the defaults Tax Types
|
||||
$this->taxTypesDirectories['Thelia\\TaxEngine\\TaxType'] = __DIR__ . DS . "TaxType";
|
||||
}
|
||||
|
||||
protected function setSession(Session $session)
|
||||
{
|
||||
$this->session = $session;
|
||||
/**
|
||||
* Add a directroy which contains tax types classes. The tax engine
|
||||
* will scan this directory, and add all the tax type classes.
|
||||
*
|
||||
* @param unknown $namespace the namespace of the classes in the directory
|
||||
* @param unknown $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;
|
||||
}
|
||||
|
||||
private function getTaxTypeDirectory()
|
||||
{
|
||||
return __DIR__ . "/TaxType";
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
$typeList = array();
|
||||
if ($this->typeList === null) {
|
||||
|
||||
try {
|
||||
$directoryBrowser = new \DirectoryIterator($this->getTaxTypeDirectory($this->getTaxTypeDirectory()));
|
||||
} catch (\UnexpectedValueException $e) {
|
||||
return $typeList;
|
||||
$this->typeList = array();
|
||||
|
||||
foreach($this->taxTypesDirectories as $namespace => $directory) {
|
||||
|
||||
try {
|
||||
$directoryIterator = new \DirectoryIterator($directory);
|
||||
|
||||
foreach ($directoryIterator as $fileinfo) {
|
||||
|
||||
if ($fileinfo->isFile()) {
|
||||
|
||||
$fileName = $fileinfo->getFilename();
|
||||
$className = substr($fileName, 0, (1+strlen($fileinfo->getExtension())) * -1);
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* browse the directory */
|
||||
foreach ($directoryBrowser as $directoryContent) {
|
||||
/* is it a file ? */
|
||||
if (!$directoryContent->isFile()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$fileName = $directoryContent->getFilename();
|
||||
$className = substr($fileName, 0, (1+strlen($directoryContent->getExtension())) * -1);
|
||||
|
||||
if ($className == "BaseTaxType") {
|
||||
continue;
|
||||
}
|
||||
|
||||
$typeList[] = $className;
|
||||
}
|
||||
|
||||
return $typeList;
|
||||
return $this->typeList;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -100,30 +120,30 @@ class TaxEngine
|
||||
* First look for a picked delivery address country
|
||||
* Then look at the current customer default address country
|
||||
* Else look at the default website country
|
||||
*
|
||||
* @param bool $force result is static cached ; even if a below parameter change between 2 calls, we need to keep coherent results. but you can force it.
|
||||
|
||||
* @return null|TaxEngine
|
||||
*/
|
||||
public function getDeliveryCountry($force = false)
|
||||
public function getDeliveryCountry()
|
||||
{
|
||||
if (false === $force || null === self::$taxCountry) {
|
||||
if (null === $this->taxCountry) {
|
||||
|
||||
/* is there a logged in customer ? */
|
||||
if (null !== $customer = $this->session->getCustomerUser()) {
|
||||
if (null !== $this->session->getOrder()
|
||||
&& null !== $this->session->getOrder()->chosenDeliveryAddress
|
||||
&& null !== $currentDeliveryAddress = AddressQuery::create()->findPk($this->session->getOrder()->chosenDeliveryAddress)) {
|
||||
$taxCountry = $currentDeliveryAddress->getCountry();
|
||||
$this->taxCountry = $currentDeliveryAddress->getCountry();
|
||||
} else {
|
||||
$customerDefaultAddress = $customer->getDefaultAddress();
|
||||
$taxCountry = $customerDefaultAddress->getCountry();
|
||||
$this->taxCountry = $customerDefaultAddress->getCountry();
|
||||
}
|
||||
} else {
|
||||
$taxCountry = CountryQuery::create()->findOneByByDefault(1);
|
||||
}
|
||||
|
||||
self::$taxCountry = $taxCountry;
|
||||
if (null == $this->taxCountry) {
|
||||
$this->taxCountry = CountryQuery::create()->findOneByByDefault(1);
|
||||
}
|
||||
}
|
||||
|
||||
return self::$taxCountry;
|
||||
return $this->taxCountry;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,9 @@ 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;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -35,9 +38,10 @@ use Thelia\Type\ModelValidIdType;
|
||||
*/
|
||||
class FeatureFixAmountTaxType extends BaseTaxType
|
||||
{
|
||||
public function pricePercentRetriever()
|
||||
{
|
||||
return 0;
|
||||
public function setFeature($featureId) {
|
||||
$this->setRequirement('feature', $featureId);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function fixAmountRetriever(Product $product)
|
||||
@@ -53,21 +57,24 @@ class FeatureFixAmountTaxType extends BaseTaxType
|
||||
|
||||
$testInt = new FloatType();
|
||||
if (!$testInt->isValid($taxAmount)) {
|
||||
throw new TaxEngineException('Feature value does not match FLOAT format', TaxEngineException::FEATURE_BAD_EXPECTED_VALUE);
|
||||
throw new TaxEngineException(
|
||||
Translator::getInstance()->trans('Feature value does not match FLOAT format'),
|
||||
TaxEngineException::FEATURE_BAD_EXPECTED_VALUE
|
||||
);
|
||||
}
|
||||
|
||||
return $taxAmount;
|
||||
}
|
||||
|
||||
public function getRequirementsList()
|
||||
public function getRequirementsDefinition()
|
||||
{
|
||||
return array(
|
||||
'feature' => new ModelValidIdType('Feature'),
|
||||
new TaxTypeRequirementDefinition('feature', new ModelValidIdType('Feature'))
|
||||
);
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return "Fix amount Tax depending on a feature";
|
||||
return Translator::getInstance()->trans("Constant amount found in one of the product's feature");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
namespace Thelia\TaxEngine\TaxType;
|
||||
|
||||
use Thelia\Type\FloatType;
|
||||
use Thelia\Core\Translation\Translator;
|
||||
use Thelia\TaxEngine\BaseTaxType;
|
||||
use Thelia\TaxEngine\TaxTypeRequirementDefinition;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -31,9 +34,10 @@ use Thelia\Type\FloatType;
|
||||
*/
|
||||
class FixAmountTaxType extends BaseTaxType
|
||||
{
|
||||
public function pricePercentRetriever()
|
||||
{
|
||||
return 0;
|
||||
public function setAmount($amount) {
|
||||
$this->setRequirement('amount', $amount);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function fixAmountRetriever(\Thelia\Model\Product $product)
|
||||
@@ -41,15 +45,15 @@ class FixAmountTaxType extends BaseTaxType
|
||||
return $this->getRequirement("amount");
|
||||
}
|
||||
|
||||
public function getRequirementsList()
|
||||
public function getRequirementsDefinition()
|
||||
{
|
||||
return array(
|
||||
'amount' => new FloatType(),
|
||||
new TaxTypeRequirementDefinition('amount', new FloatType())
|
||||
);
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return "Fix amount Tax";
|
||||
return Translator::getInstance()->trans("Constant amount");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
namespace Thelia\TaxEngine\TaxType;
|
||||
|
||||
use Thelia\Type\FloatType;
|
||||
use Thelia\Core\Translation\Translator;
|
||||
use Thelia\TaxEngine\TaxTypeRequirementDefinition;
|
||||
use Thelia\TaxEngine\BaseTaxType;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -31,25 +34,26 @@ use Thelia\Type\FloatType;
|
||||
*/
|
||||
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 fixAmountRetriever(\Thelia\Model\Product $product)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getRequirementsList()
|
||||
public function getRequirementsDefinition()
|
||||
{
|
||||
return array(
|
||||
'percent' => new FloatType(),
|
||||
new TaxTypeRequirementDefinition('percent', new FloatType())
|
||||
);
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return "Price % Tax";
|
||||
return Translator::getInstance()->trans("Percentage of the product price");
|
||||
}
|
||||
}
|
||||
|
||||
69
core/lib/Thelia/TaxEngine/TaxTypeRequirementDefinition.php
Normal file
69
core/lib/Thelia/TaxEngine/TaxTypeRequirementDefinition.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* */
|
||||
/* Thelia */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : info@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation; either version 3 of the License */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* GNU General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License */
|
||||
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* */
|
||||
/*************************************************************************************/
|
||||
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;
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function isValueValid($value) {
|
||||
return $this->type->isValid($value);
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,7 @@ use Thelia\Core\Security\SecurityContext;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
|
||||
use Thelia\Core\HttpFoundation\Session\Session;
|
||||
use Thelia\Tools\URL;
|
||||
use Thelia\TaxEngine\TaxEngine;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -108,6 +109,7 @@ abstract class BaseLoopTestor extends \PHPUnit_Framework_TestCase
|
||||
$this->container->set('thelia.securityContext', new SecurityContext($request));
|
||||
$this->container->set('router.admin', $stubRouterAdmin);
|
||||
$this->container->set('thelia.url.manager', new URL($this->container));
|
||||
$this->container->set('thelia.taxEngine', new TaxEngine($request));
|
||||
|
||||
$this->instance = $this->getTestedInstance();
|
||||
$this->instance->initializeArgs($this->getMandatoryArguments());
|
||||
|
||||
@@ -190,25 +190,25 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase
|
||||
$taxRulesCollection->setModel('\Thelia\Model\Tax');
|
||||
|
||||
$tax = new Tax();
|
||||
$tax->setType('PricePercentTaxType')
|
||||
$tax->setType('\Thelia\TaxEngine\TaxType\PricePercentTaxType')
|
||||
->setRequirements(array('percent' => 10))
|
||||
->setVirtualColumn('taxRuleCountryPosition', 1);
|
||||
$taxRulesCollection->append($tax);
|
||||
|
||||
$tax = new Tax();
|
||||
$tax->setType('PricePercentTaxType')
|
||||
$tax->setType('\Thelia\TaxEngine\TaxType\PricePercentTaxType')
|
||||
->setRequirements(array('percent' => 8))
|
||||
->setVirtualColumn('taxRuleCountryPosition', 1);
|
||||
$taxRulesCollection->append($tax);
|
||||
|
||||
$tax = new Tax();
|
||||
$tax->setType('FixAmountTaxType')
|
||||
$tax->setType('\Thelia\TaxEngine\TaxType\FixAmountTaxType')
|
||||
->setRequirements(array('amount' => 5))
|
||||
->setVirtualColumn('taxRuleCountryPosition', 2);
|
||||
$taxRulesCollection->append($tax);
|
||||
|
||||
$tax = new Tax();
|
||||
$tax->setType('PricePercentTaxType')
|
||||
$tax->setType('\Thelia\TaxEngine\TaxType\PricePercentTaxType')
|
||||
->setRequirements(array('percent' => 1))
|
||||
->setVirtualColumn('taxRuleCountryPosition', 3);
|
||||
$taxRulesCollection->append($tax);
|
||||
@@ -246,25 +246,25 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase
|
||||
$taxRulesCollection->setModel('\Thelia\Model\Tax');
|
||||
|
||||
$tax = new Tax();
|
||||
$tax->setType('PricePercentTaxType')
|
||||
$tax->setType('\Thelia\TaxEngine\TaxType\PricePercentTaxType')
|
||||
->setRequirements(array('percent' => 10))
|
||||
->setVirtualColumn('taxRuleCountryPosition', 1);
|
||||
$taxRulesCollection->append($tax);
|
||||
|
||||
$tax = new Tax();
|
||||
$tax->setType('PricePercentTaxType')
|
||||
$tax->setType('\Thelia\TaxEngine\TaxType\PricePercentTaxType')
|
||||
->setRequirements(array('percent' => 8))
|
||||
->setVirtualColumn('taxRuleCountryPosition', 1);
|
||||
$taxRulesCollection->append($tax);
|
||||
|
||||
$tax = new Tax();
|
||||
$tax->setType('FixAmountTaxType')
|
||||
$tax->setType('\Thelia\TaxEngine\TaxType\FixAmountTaxType')
|
||||
->setRequirements(array('amount' => 5))
|
||||
->setVirtualColumn('taxRuleCountryPosition', 2);
|
||||
$taxRulesCollection->append($tax);
|
||||
|
||||
$tax = new Tax();
|
||||
$tax->setType('PricePercentTaxType')
|
||||
$tax->setType('\Thelia\TaxEngine\TaxType\PricePercentTaxType')
|
||||
->setRequirements(array('percent' => 1))
|
||||
->setVirtualColumn('taxRuleCountryPosition', 3);
|
||||
$taxRulesCollection->append($tax);
|
||||
|
||||
61
core/lib/Thelia/Tests/TaxEngine/TaxEngineTest.php
Normal file
61
core/lib/Thelia/Tests/TaxEngine/TaxEngineTest.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
use Thelia\TaxEngine\TaxEngine;
|
||||
/*************************************************************************************/
|
||||
/* */
|
||||
/* Thelia */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : info@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation; either version 3 of the License */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* GNU General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License */
|
||||
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\Tests\TaxEngine;
|
||||
|
||||
use Thelia\Core\HttpFoundation\Request;
|
||||
use Thelia\Core\HttpFoundation\Session\Session;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
|
||||
use Thelia\TaxEngine\TaxEngine;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Franck Allimant <franck@cqfdev.fr>
|
||||
*
|
||||
*/
|
||||
class TaxEngineTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $request;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->request = new Request();
|
||||
|
||||
$this->request->setSession(new Session(new MockArraySessionStorage()));
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function testGetTaxTypeList()
|
||||
{
|
||||
$taxEngine = new TaxEngine($this->request);
|
||||
|
||||
$list = $taxEngine->getTaxTypeList();
|
||||
|
||||
$this->assertEquals($list[0], "Thelia\TaxEngine\TaxType\FeatureFixAmountTaxType");
|
||||
$this->assertEquals($list[1], "Thelia\TaxEngine\TaxType\FixAmountTaxType");
|
||||
$this->assertEquals($list[2], "Thelia\TaxEngine\TaxType\PricePercentTaxType");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user