taxes management
This commit is contained in:
104
core/lib/Thelia/Action/Tax.php
Normal file
104
core/lib/Thelia/Action/Tax.php
Normal file
@@ -0,0 +1,104 @@
|
||||
<?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\Action;
|
||||
|
||||
use Propel\Runtime\ActiveQuery\Criteria;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Thelia\Core\Event\Tax\TaxEvent;
|
||||
use Thelia\Core\Event\TheliaEvents;
|
||||
use Thelia\Model\Tax as TaxModel;
|
||||
use Thelia\Model\TaxQuery;
|
||||
|
||||
class Tax extends BaseAction implements EventSubscriberInterface
|
||||
{
|
||||
/**
|
||||
* @param TaxEvent $event
|
||||
*/
|
||||
public function create(TaxEvent $event)
|
||||
{
|
||||
$tax = new TaxModel();
|
||||
|
||||
$tax
|
||||
->setDispatcher($this->getDispatcher())
|
||||
->setType($event->getType())
|
||||
->setLocale($event->getLocale())
|
||||
->setTitle($event->getTitle())
|
||||
->setDescription($event->getDescription())
|
||||
;
|
||||
|
||||
$tax->save();
|
||||
|
||||
$event->setTax($tax);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TaxEvent $event
|
||||
*/
|
||||
public function update(TaxEvent $event)
|
||||
{
|
||||
if (null !== $tax = TaxQuery::create()->findPk($event->getId())) {
|
||||
|
||||
$tax
|
||||
->setDispatcher($this->getDispatcher())
|
||||
->setType($event->getType())
|
||||
->setLocale($event->getLocale())
|
||||
->setTitle($event->getTitle())
|
||||
->setDescription($event->getDescription())
|
||||
->save()
|
||||
;
|
||||
|
||||
|
||||
|
||||
$event->setTax($tax);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TaxEvent $event
|
||||
*/
|
||||
public function delete(TaxEvent $event)
|
||||
{
|
||||
if (null !== $tax = TaxQuery::create()->findPk($event->getId())) {
|
||||
|
||||
$tax
|
||||
->delete()
|
||||
;
|
||||
|
||||
$event->setTax($tax);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
TheliaEvents::TAX_CREATE => array("create", 128),
|
||||
TheliaEvents::TAX_UPDATE => array("update", 128),
|
||||
TheliaEvents::TAX_DELETE => array("delete", 128),
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -111,6 +111,11 @@
|
||||
<tag name="kernel.event_subscriber"/>
|
||||
</service>
|
||||
|
||||
<service id="thelia.action.tax" class="Thelia\Action\Tax">
|
||||
<argument type="service" id="service_container"/>
|
||||
<tag name="kernel.event_subscriber"/>
|
||||
</service>
|
||||
|
||||
<service id="thelia.action.content" class="Thelia\Action\Content">
|
||||
<argument type="service" id="service_container"/>
|
||||
<tag name="kernel.event_subscriber"/>
|
||||
|
||||
@@ -117,6 +117,10 @@
|
||||
<form name="thelia.admin.taxrule.taxlistupdate" class="Thelia\Form\TaxRuleTaxListUpdateForm"/>
|
||||
<form name="thelia.admin.taxrule.add" class="Thelia\Form\TaxRuleCreationForm"/>
|
||||
|
||||
<form name="thelia.admin.tax.modification" class="Thelia\Form\TaxModificationForm"/>
|
||||
<form name="thelia.admin.tax.taxlistupdate" class="Thelia\Form\TaxTaxListUpdateForm"/>
|
||||
<form name="thelia.admin.tax.add" class="Thelia\Form\TaxCreationForm"/>
|
||||
|
||||
<form name="thelia.admin.template.creation" class="Thelia\Form\TemplateCreationForm"/>
|
||||
<form name="thelia.admin.template.modification" class="Thelia\Form\TemplateModificationForm"/>
|
||||
|
||||
|
||||
@@ -787,7 +787,28 @@
|
||||
|
||||
<!-- end Modules rule management -->
|
||||
|
||||
<!-- taxe rules management -->
|
||||
<!-- tax management -->
|
||||
|
||||
<route id="admin.configuration.taxes.update" path="/admin/configuration/taxes/update/{tax_id}">
|
||||
<default key="_controller">Thelia\Controller\Admin\TaxController::updateAction</default>
|
||||
<requirement key="tax_id">\d+</requirement>
|
||||
</route>
|
||||
|
||||
<route id="admin.configuration.taxes.add" path="/admin/configuration/taxes/add">
|
||||
<default key="_controller">Thelia\Controller\Admin\TaxController::createAction</default>
|
||||
</route>
|
||||
|
||||
<route id="admin.configuration.taxes.save" path="/admin/configuration/taxes/save">
|
||||
<default key="_controller">Thelia\Controller\Admin\TaxController::processUpdateAction</default>
|
||||
</route>
|
||||
|
||||
<route id="admin.configuration.taxes.delete" path="/admin/configuration/taxes/delete">
|
||||
<default key="_controller">Thelia\Controller\Admin\TaxController::deleteAction</default>
|
||||
</route>
|
||||
|
||||
<!-- end tax management -->
|
||||
|
||||
<!-- tax rules management -->
|
||||
|
||||
<route id="admin.configuration.taxes-rules.list" path="/admin/configuration/taxes_rules">
|
||||
<default key="_controller">Thelia\Controller\Admin\TaxRuleController::defaultAction</default>
|
||||
|
||||
198
core/lib/Thelia/Controller/Admin/TaxController.php
Normal file
198
core/lib/Thelia/Controller/Admin/TaxController.php
Normal file
@@ -0,0 +1,198 @@
|
||||
<?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\Controller\Admin;
|
||||
|
||||
use Thelia\Core\Event\Tax\TaxEvent;
|
||||
use Thelia\Core\Event\TheliaEvents;
|
||||
use Thelia\Form\TaxCreationForm;
|
||||
use Thelia\Form\TaxModificationForm;
|
||||
use Thelia\Form\TaxTaxListUpdateForm;
|
||||
use Thelia\Model\TaxQuery;
|
||||
|
||||
class TaxController extends AbstractCrudController
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(
|
||||
'tax',
|
||||
'manual',
|
||||
'order',
|
||||
|
||||
'admin.configuration.tax.view',
|
||||
'admin.configuration.tax.create',
|
||||
'admin.configuration.tax.update',
|
||||
'admin.configuration.tax.delete',
|
||||
|
||||
TheliaEvents::TAX_CREATE,
|
||||
TheliaEvents::TAX_UPDATE,
|
||||
TheliaEvents::TAX_DELETE
|
||||
);
|
||||
}
|
||||
|
||||
protected function getCreationForm()
|
||||
{
|
||||
return new TaxCreationForm($this->getRequest());
|
||||
}
|
||||
|
||||
protected function getUpdateForm()
|
||||
{
|
||||
return new TaxModificationForm($this->getRequest());
|
||||
}
|
||||
|
||||
protected function getCreationEvent($formData)
|
||||
{
|
||||
$event = new TaxEvent();
|
||||
|
||||
$event->setLocale($formData['locale']);
|
||||
$event->setTitle($formData['title']);
|
||||
$event->setDescription($formData['description']);
|
||||
$event->setType($formData['type']);
|
||||
|
||||
return $event;
|
||||
}
|
||||
|
||||
protected function getUpdateEvent($formData)
|
||||
{
|
||||
$event = new TaxEvent();
|
||||
|
||||
$event->setLocale($formData['locale']);
|
||||
$event->setId($formData['id']);
|
||||
$event->setTitle($formData['title']);
|
||||
$event->setDescription($formData['description']);
|
||||
$event->setType($formData['type']);
|
||||
|
||||
return $event;
|
||||
}
|
||||
|
||||
protected function getDeleteEvent()
|
||||
{
|
||||
$event = new TaxEvent();
|
||||
|
||||
$event->setId(
|
||||
$this->getRequest()->get('tax_id', 0)
|
||||
);
|
||||
|
||||
return $event;
|
||||
}
|
||||
|
||||
protected function eventContainsObject($event)
|
||||
{
|
||||
return $event->hasTax();
|
||||
}
|
||||
|
||||
protected function hydrateObjectForm($object)
|
||||
{
|
||||
$data = array(
|
||||
'id' => $object->getId(),
|
||||
'locale' => $object->getLocale(),
|
||||
'title' => $object->getTitle(),
|
||||
'description' => $object->getDescription(),
|
||||
'type' => $object->getType(),
|
||||
);
|
||||
|
||||
// Setup the object form
|
||||
return new TaxModificationForm($this->getRequest(), "form", $data);
|
||||
}
|
||||
|
||||
protected function getObjectFromEvent($event)
|
||||
{
|
||||
return $event->hasTax() ? $event->getTax() : null;
|
||||
}
|
||||
|
||||
protected function getExistingObject()
|
||||
{
|
||||
return TaxQuery::create()
|
||||
->joinWithI18n($this->getCurrentEditionLocale())
|
||||
->findOneById($this->getRequest()->get('tax_id'));
|
||||
}
|
||||
|
||||
protected function getObjectLabel($object)
|
||||
{
|
||||
return $object->getTitle();
|
||||
}
|
||||
|
||||
protected function getObjectId($object)
|
||||
{
|
||||
return $object->getId();
|
||||
}
|
||||
|
||||
protected function getViewArguments()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
protected function getRouteArguments($tax_id = null)
|
||||
{
|
||||
return array(
|
||||
'tax_id' => $tax_id === null ? $this->getRequest()->get('tax_id') : $tax_id,
|
||||
);
|
||||
}
|
||||
|
||||
protected function renderListTemplate($currentOrder)
|
||||
{
|
||||
// We always return to the feature edition form
|
||||
return $this->render(
|
||||
'taxes-rules',
|
||||
array()
|
||||
);
|
||||
}
|
||||
|
||||
protected function renderEditionTemplate()
|
||||
{
|
||||
// We always return to the feature edition form
|
||||
return $this->render('tax-edit', array_merge($this->getViewArguments(), $this->getRouteArguments()));
|
||||
}
|
||||
|
||||
protected function redirectToEditionTemplate($request = null, $country = null)
|
||||
{
|
||||
// We always return to the feature edition form
|
||||
$this->redirectToRoute(
|
||||
"admin.configuration.taxes.update",
|
||||
$this->getViewArguments($country),
|
||||
$this->getRouteArguments()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Put in this method post object creation processing if required.
|
||||
*
|
||||
* @param TaxEvent $createEvent the create event
|
||||
* @return Response a response, or null to continue normal processing
|
||||
*/
|
||||
protected function performAdditionalCreateAction($createEvent)
|
||||
{
|
||||
$this->redirectToRoute(
|
||||
"admin.configuration.taxes.update",
|
||||
$this->getViewArguments(),
|
||||
$this->getRouteArguments($createEvent->getTax()->getId())
|
||||
);
|
||||
}
|
||||
|
||||
protected function redirectToListTemplate()
|
||||
{
|
||||
$this->redirectToRoute(
|
||||
"admin.configuration.taxes-rules.list"
|
||||
);
|
||||
}
|
||||
}
|
||||
109
core/lib/Thelia/Core/Event/Tax/TaxEvent.php
Normal file
109
core/lib/Thelia/Core/Event/Tax/TaxEvent.php
Normal file
@@ -0,0 +1,109 @@
|
||||
<?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\Core\Event\Tax;
|
||||
use Thelia\Core\Event\ActionEvent;
|
||||
use Thelia\Model\Tax;
|
||||
|
||||
class TaxEvent extends ActionEvent
|
||||
{
|
||||
protected $tax = null;
|
||||
|
||||
protected $locale;
|
||||
protected $id;
|
||||
protected $title;
|
||||
protected $description;
|
||||
protected $type;
|
||||
|
||||
public function __construct(Tax $tax = null)
|
||||
{
|
||||
$this->tax = $tax;
|
||||
}
|
||||
|
||||
public function hasTax()
|
||||
{
|
||||
return ! is_null($this->tax);
|
||||
}
|
||||
|
||||
public function getTax()
|
||||
{
|
||||
return $this->tax;
|
||||
}
|
||||
|
||||
public function setTax(Tax $tax)
|
||||
{
|
||||
$this->tax = $tax;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setDescription($description)
|
||||
{
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
public function setId($id)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setTitle($title)
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
public function setLocale($locale)
|
||||
{
|
||||
$this->locale = $locale;
|
||||
}
|
||||
|
||||
public function getLocale()
|
||||
{
|
||||
return $this->locale;
|
||||
}
|
||||
|
||||
public function setType($type)
|
||||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
}
|
||||
@@ -519,6 +519,12 @@ final class TheliaEvents
|
||||
|
||||
const CHANGE_DEFAULT_CURRENCY = 'action.changeDefaultCurrency';
|
||||
|
||||
// -- Tax management ---------------------------------------------
|
||||
|
||||
const TAX_CREATE = "action.createTax";
|
||||
const TAX_UPDATE = "action.updateTax";
|
||||
const TAX_DELETE = "action.deleteTax";
|
||||
|
||||
// -- Tax Rules management ---------------------------------------------
|
||||
|
||||
const TAX_RULE_CREATE = "action.createTaxRule";
|
||||
|
||||
@@ -152,11 +152,13 @@ class Tax extends BaseI18nLoop
|
||||
$loopResultRow = new LoopResultRow($loopResult, $tax, $this->versionable, $this->timestampable, $this->countable);
|
||||
|
||||
$loopResultRow
|
||||
->set("ID" , $tax->getId())
|
||||
->set("IS_TRANSLATED" , $tax->getVirtualColumn('IS_TRANSLATED'))
|
||||
->set("LOCALE" , $locale)
|
||||
->set("TITLE" , $tax->getVirtualColumn('i18n_TITLE'))
|
||||
->set("DESCRIPTION" , $tax->getVirtualColumn('i18n_DESCRIPTION'))
|
||||
->set("ID" , $tax->getId())
|
||||
->set("TYPE" , $tax->getType())
|
||||
->set("SERIALIZED_REQUIREMENTS" , $tax->getSerializedRequirements())
|
||||
->set("IS_TRANSLATED" , $tax->getVirtualColumn('IS_TRANSLATED'))
|
||||
->set("LOCALE" , $locale)
|
||||
->set("TITLE" , $tax->getVirtualColumn('i18n_TITLE'))
|
||||
->set("DESCRIPTION" , $tax->getVirtualColumn('i18n_DESCRIPTION'))
|
||||
;
|
||||
|
||||
$loopResult->addRow($loopResultRow);
|
||||
|
||||
67
core/lib/Thelia/Form/TaxCreationForm.php
Normal file
67
core/lib/Thelia/Form/TaxCreationForm.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?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\Form;
|
||||
|
||||
use Symfony\Component\Validator\Constraints;
|
||||
use Symfony\Component\Validator\Constraints\NotBlank;
|
||||
use Thelia\Core\Translation\Translator;
|
||||
use Thelia\TaxEngine\TaxEngine;
|
||||
use Thelia\TaxEngine\TaxType;
|
||||
|
||||
class TaxCreationForm extends BaseForm
|
||||
{
|
||||
use StandardDescriptionFieldsTrait;
|
||||
|
||||
protected function buildForm($change_mode = false)
|
||||
{
|
||||
$types = TaxEngine::getInstance()->getTaxTypeList();
|
||||
$typeList = array();
|
||||
foreach($types as $type) {
|
||||
$classPath = "\\Thelia\\TaxEngine\\TaxType\\$type";
|
||||
$instance = new $classPath();
|
||||
$typeList[$type] = $instance->getTitle();
|
||||
}
|
||||
|
||||
$this->formBuilder
|
||||
->add("locale", "text", array(
|
||||
"constraints" => array(new NotBlank())
|
||||
))
|
||||
->add("type", "choice", array(
|
||||
"choices" => $typeList,
|
||||
"required" => true,
|
||||
"constraints" => array(
|
||||
new Constraints\NotBlank(),
|
||||
),
|
||||
"label" => Translator::getInstance()->trans("Type"),
|
||||
"label_attr" => array("for" => "type_field"),
|
||||
))
|
||||
;
|
||||
|
||||
$this->addStandardDescFields(array('postscriptum', 'chapo', 'locale'));
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return "thelia_tax_creation";
|
||||
}
|
||||
}
|
||||
66
core/lib/Thelia/Form/TaxModificationForm.php
Normal file
66
core/lib/Thelia/Form/TaxModificationForm.php
Normal file
@@ -0,0 +1,66 @@
|
||||
<?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\Form;
|
||||
|
||||
use Symfony\Component\Validator\Constraints;
|
||||
use Symfony\Component\Validator\ExecutionContextInterface;
|
||||
use Thelia\Model\TaxQuery;
|
||||
|
||||
class TaxModificationForm extends TaxCreationForm
|
||||
{
|
||||
protected function buildForm()
|
||||
{
|
||||
parent::buildForm(true);
|
||||
|
||||
$this->formBuilder
|
||||
->add("id", "hidden", array(
|
||||
"required" => true,
|
||||
"constraints" => array(
|
||||
new Constraints\NotBlank(),
|
||||
new Constraints\Callback(
|
||||
array(
|
||||
"methods" => array(
|
||||
array($this, "verifyTaxId"),
|
||||
),
|
||||
)
|
||||
),
|
||||
)
|
||||
))
|
||||
;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return "thelia_tax_modification";
|
||||
}
|
||||
|
||||
public function verifyTaxId($value, ExecutionContextInterface $context)
|
||||
{
|
||||
$tax = TaxQuery::create()
|
||||
->findPk($value);
|
||||
|
||||
if (null === $tax) {
|
||||
$context->addViolation("Tax ID not found");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,13 @@ namespace Thelia\Model;
|
||||
|
||||
use Thelia\Exception\TaxEngineException;
|
||||
use Thelia\Model\Base\Tax as BaseTax;
|
||||
use Thelia\Model\Tools\ModelEventDispatcherTrait;
|
||||
use Thelia\TaxEngine\TaxType\BaseTaxType;
|
||||
|
||||
class Tax extends BaseTax
|
||||
{
|
||||
use ModelEventDispatcherTrait;
|
||||
|
||||
public function calculateTax($amount)
|
||||
{
|
||||
if(false === filter_var($amount, FILTER_VALIDATE_FLOAT)) {
|
||||
|
||||
71
core/lib/Thelia/TaxEngine/TaxEngine.php
Executable file
71
core/lib/Thelia/TaxEngine/TaxEngine.php
Executable file
@@ -0,0 +1,71 @@
|
||||
<?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;
|
||||
|
||||
/**
|
||||
* Class TaxEngine
|
||||
* @package Thelia\TaxEngine
|
||||
* @author Etienne Roudeix <eroudeix@openstudio.fr>
|
||||
*/
|
||||
class TaxEngine
|
||||
{
|
||||
static public function getInstance()
|
||||
{
|
||||
return new TaxEngine();
|
||||
}
|
||||
|
||||
private function getTaxTypeDirectory()
|
||||
{
|
||||
return __DIR__ . "/TaxType";
|
||||
}
|
||||
|
||||
public function getTaxTypeList()
|
||||
{
|
||||
$typeList = array();
|
||||
|
||||
try {
|
||||
$directoryBrowser = new \DirectoryIterator($this->getTaxTypeDirectory($this->getTaxTypeDirectory()));
|
||||
} catch (\UnexpectedValueException $e) {
|
||||
return $typeList;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,8 @@ abstract class BaseTaxType
|
||||
|
||||
public abstract function getRequirementsList();
|
||||
|
||||
public abstract function getTitle();
|
||||
|
||||
public function calculate(Product $product, $untaxedPrice)
|
||||
{
|
||||
return $untaxedPrice * $this->pricePercentRetriever() + $this->fixAmountRetriever($product);
|
||||
|
||||
@@ -65,4 +65,9 @@ class FeatureFixAmountTaxType extends BaseTaxType
|
||||
'feature' => new ModelValidIdType('Feature'),
|
||||
);
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return "Fix amount Tax depending on a feature";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,4 +49,9 @@ class featureSlicePercentTaxType extends BaseTaxType
|
||||
'slices' => new FloatToFloatArrayType(),
|
||||
);
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return "% slice Tax depending on a feature";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,4 +47,9 @@ class FixAmountTaxType extends BaseTaxType
|
||||
'amount' => new FloatType(),
|
||||
);
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return "Fix amount Tax";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,9 @@ class PricePercentTaxType extends BaseTaxType
|
||||
'percent' => new FloatType(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//600 / (1 + 0,10 + 0,10) =/= 600 / (1 + 0,10 ) + 600 / (1 + 0,10 )
|
||||
public function getTitle()
|
||||
{
|
||||
return "Price % Tax";
|
||||
}
|
||||
}
|
||||
|
||||
130
templates/admin/default/tax-edit.html
Normal file
130
templates/admin/default/tax-edit.html
Normal file
@@ -0,0 +1,130 @@
|
||||
{extends file="admin-layout.tpl"}
|
||||
|
||||
{block name="page-title"}{intl l='Edit a tax'}{/block}
|
||||
|
||||
{block name="check-permissions"}admin.configuration.taxes.edit{/block}
|
||||
|
||||
{block name="main-content"}
|
||||
|
||||
<div class="taxes-rules edit-taxes-rules">
|
||||
|
||||
<div id="wrapper" class="container">
|
||||
|
||||
<ul class="breadcrumb">
|
||||
<li><a href="{url path='/admin/home'}">{intl l="Home"}</a></li>
|
||||
<li><a href="{url path='/admin/configuration'}">{intl l="Configuration"}</a></li>
|
||||
<li><a href="{url path='/admin/configuration/taxes_rules'}">{intl l="Taxes"}</a></li>
|
||||
<li>{intl l='Editing tax'}</li>
|
||||
</ul>
|
||||
|
||||
{loop type="tax" name="tax" id=$tax_id backend_context="1" lang=$edit_language_id}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12 general-block-decorator clearfix">
|
||||
|
||||
<div class="form-container">
|
||||
|
||||
{form name="thelia.admin.tax.modification"}
|
||||
|
||||
<form method="POST" action="{url path="/admin/configuration/taxes/save"}" {form_enctype form=$form} >
|
||||
|
||||
{include
|
||||
file = "includes/inner-form-toolbar.html"
|
||||
hide_submit_buttons = false
|
||||
|
||||
page_url = {url path="/admin/configuration/taxes/update/$tax_id"}
|
||||
close_url = {url path="/admin/configuration/taxes_rules"}
|
||||
}
|
||||
|
||||
{* Be sure to get the product ID, even if the form could not be validated *}
|
||||
<input type="hidden" name="tax_id" value="{$ID}" />
|
||||
|
||||
{form_hidden_fields form=$form}
|
||||
|
||||
{form_field form=$form field='success_url'}
|
||||
<input type="hidden" name="{$name}" value="{url path="/admin/configuration/taxes_rules"}" />
|
||||
{/form_field}
|
||||
|
||||
{form_field form=$form field='locale'}
|
||||
<input type="hidden" name="{$name}" value="{$edit_language_locale}" />
|
||||
{/form_field}
|
||||
|
||||
{if $form_error}<div class="alert alert-danger">{$form_error_message}</div>{/if}
|
||||
|
||||
{form_field form=$form field='title'}
|
||||
<div class="form-group {if $error}has-error{/if}">
|
||||
<label for="{$label_attr.for}" class="control-label">{intl l=$label} : </label>
|
||||
<input type="text" id="{$label_attr.for}" name="{$name}" required="required" title="{intl l='Title'}" placeholder="{intl l='Title'}" class="form-control" value="{if $error}{$value}{else}{if $IS_TRANSLATED == 1}{$TITLE}{/if}{/if}">
|
||||
</div>
|
||||
{/form_field}
|
||||
|
||||
{form_field form=$form field='description'}
|
||||
<div class="form-group {if $error}has-error{/if}">
|
||||
<label for="{$label_attr.for}" class="control-label">
|
||||
{intl l=$label} :
|
||||
<span class="label-help-block">{intl l="The detailed description."}</span>
|
||||
</label>
|
||||
|
||||
<textarea name="{$name}" id="{$label_attr.for}" rows="10" class="form-control wysiwyg">{if $error}{$value}{else}{if $IS_TRANSLATED == 1}{$DESCRIPTION}{/if}{/if}</textarea>
|
||||
</div>
|
||||
{/form_field}
|
||||
|
||||
{form_field form=$form field='type'}
|
||||
<div class="form-group {if $error}has-error{/if}">
|
||||
<label for="{$label_attr.for}" class="control-label">
|
||||
{intl l=$label} :
|
||||
</label>
|
||||
|
||||
<div class="form-group">
|
||||
<select name="{$name}" data-toggle="selectpicker">
|
||||
{foreach $choices as $choice}
|
||||
<option value="{$choice->value}" {if $choice->value == $TYPE}selected="selected" {/if}>{$choice->label}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
{/form_field}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="control-group">
|
||||
<label> </label>
|
||||
<div class="controls">
|
||||
<p>{intl l='Tax created on %date_create. Last modification: %date_change' date_create={format_date date=$CREATE_DATE} date_change={format_date date=$UPDATE_DATE}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
{/form}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/loop}
|
||||
|
||||
</div>
|
||||
|
||||
{/block}
|
||||
|
||||
{block name="javascript-initialization"}
|
||||
|
||||
{javascripts file='assets/js/bootstrap-select/bootstrap-select.js'}
|
||||
<script src='{$asset_url}'></script>
|
||||
{/javascripts}
|
||||
|
||||
{javascripts file='assets/js/main.js'}
|
||||
<script src='{$asset_url}'></script>
|
||||
{/javascripts}
|
||||
|
||||
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
|
||||
|
||||
<script>
|
||||
$(function() {
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
{/block}
|
||||
@@ -21,6 +21,72 @@
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
|
||||
<div class="alert alert-info">
|
||||
<p>{intl l="In order to manges your shop taxes you can manage"} <strong>{intl l="taxes"}</strong> {intl l="and"} <strong>{intl l="tax rules"}</strong>.</p>
|
||||
<p>{intl l="Taxes define the amount of money which is add to a bought product."}</p>
|
||||
<p>
|
||||
{intl l="Example :"}
|
||||
<ul>
|
||||
<li>{intl l="French 19.6% VAT is a tax which add a 19.6% tax to the product price."}</li>
|
||||
<li>{intl l="Ecotax is a tax wich add a defined amount (throug a product feature) to the product price."}</li>
|
||||
</ul>
|
||||
</p>
|
||||
<p>{intl l="Tax rules are combination of different taxes."}</p>
|
||||
<p>
|
||||
{intl l="Example :"}
|
||||
<ul>
|
||||
<li>{intl l="French 19.6% VAT with ecotax is the applicance of the ecotax (on the product price) then the applicance of the 19.6% tax (on the product price + the ecotax amount)."}</li>
|
||||
</ul>
|
||||
</p>
|
||||
<p>{intl l="you can combine taxes in tax rules and chose if they are applied one after the other or at the same time : it allows to apply taxes on an already taxed price or not."}</p>
|
||||
</div>
|
||||
|
||||
<div class="general-block-decorator">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-condensed table-left-aligned">
|
||||
<caption class="clearfix">
|
||||
{intl l="Taxes"}
|
||||
{loop type="auth" name="can_create" roles="ADMIN" permissions="admin.taxes.create"}
|
||||
<a class="btn btn-default btn-primary pull-right" title="{intl l='Create a new tax'}" href="#tax_create_dialog" data-toggle="modal">
|
||||
<span class="glyphicon glyphicon-plus"></span>
|
||||
</a>
|
||||
{/loop}
|
||||
</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{intl l="Name"}</th>
|
||||
<th>{intl l="Description"}</th>
|
||||
<th>{intl l="Actions"}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
{loop type="tax" name="taxes" backend_context="1"}
|
||||
|
||||
<tr>
|
||||
<td>{$TITLE}</td>
|
||||
<td>{$DESCRIPTION}</td>
|
||||
<td>
|
||||
<div class="btn-group">
|
||||
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.taxes.change"}
|
||||
<a class="btn btn-default btn-xs" title="{intl l='Change this tax'}" href="{url path="/admin/configuration/taxes/update/$ID"}"><span class="glyphicon glyphicon-edit"></span></a>
|
||||
{/loop}
|
||||
|
||||
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.taxes.change"}
|
||||
<a class="btn btn-default btn-xs js-delete-tax" title="{intl l='Delete this tax'}" href="#tax_delete_dialog" data-id="{$ID}" data-toggle="modal"><span class="glyphicon glyphicon-trash"></span></a>
|
||||
{/loop}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{/loop}
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="general-block-decorator">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-condensed table-left-aligned">
|
||||
@@ -41,7 +107,7 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
{loop type="tax-rule" name="taxes-rules"}
|
||||
{loop type="tax-rule" name="taxes-rules" backend_context="1"}
|
||||
|
||||
<tr>
|
||||
<td>{$TITLE}</td>
|
||||
@@ -61,10 +127,10 @@
|
||||
|
||||
{/loop}
|
||||
|
||||
</tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -73,8 +139,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{* -- Add tax rule confirmation dialog ----------------------------------- *}
|
||||
{form name="thelia.admin.taxrule.add"}
|
||||
{* -- Add tax confirmation dialog ----------------------------------- *}
|
||||
{form name="thelia.admin.tax.add"}
|
||||
|
||||
{if $form_error_message}
|
||||
{$taxCreateError = true}
|
||||
@@ -82,6 +148,99 @@
|
||||
{$taxCreateError = false}
|
||||
{/if}
|
||||
|
||||
{* Capture the dialog body, to pass it to the generic dialog *}
|
||||
{capture "tax_create_dialog"}
|
||||
|
||||
{form_hidden_fields form=$form}
|
||||
|
||||
{form_field form=$form field='locale'}
|
||||
<input type="hidden" name="{$name}" value="{$edit_language_locale}" />
|
||||
{/form_field}
|
||||
|
||||
{if $form_error}<div class="alert alert-danger">{$form_error_message}</div>{/if}
|
||||
|
||||
{form_field form=$form field='title'}
|
||||
<div class="form-group {if $error}has-error{/if}">
|
||||
<label for="{$label_attr.for}" class="control-label">{intl l=$label} : </label>
|
||||
<input type="text" id="{$label_attr.for}" name="{$name}" required="required" title="{intl l='Title'}" placeholder="{intl l='Title'}" class="form-control" value="{if $error}{$value}{else}{if $IS_TRANSLATED == 1}{$TITLE}{/if}{/if}">
|
||||
</div>
|
||||
{/form_field}
|
||||
|
||||
{form_field form=$form field='description'}
|
||||
<div class="form-group {if $error}has-error{/if}">
|
||||
<label for="{$label_attr.for}" class="control-label">
|
||||
{intl l=$label} :
|
||||
<span class="label-help-block">{intl l="The detailed description."}</span>
|
||||
</label>
|
||||
|
||||
<textarea name="{$name}" id="{$label_attr.for}" rows="10" class="form-control wysiwyg">{if $error}{$value}{else}{if $IS_TRANSLATED == 1}{$DESCRIPTION}{/if}{/if}</textarea>
|
||||
</div>
|
||||
{/form_field}
|
||||
|
||||
{form_field form=$form field='type'}
|
||||
<div class="form-group {if $error}has-error{/if}">
|
||||
<label for="{$label_attr.for}" class="control-label">
|
||||
{intl l=$label} :
|
||||
</label>
|
||||
|
||||
<div class="form-group">
|
||||
<select name="{$name}" data-toggle="selectpicker">
|
||||
{foreach $choices as $choice}
|
||||
<option value="{$choice->value}" {if $choice->value == $TYPE}selected="selected" {/if}>{$choice->label}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
{/form_field}
|
||||
|
||||
{/capture}
|
||||
|
||||
{include
|
||||
file = "includes/generic-create-dialog.html"
|
||||
|
||||
dialog_id = "tax_create_dialog"
|
||||
dialog_title = {intl l="Create a new tax"}
|
||||
dialog_body = {$smarty.capture.tax_create_dialog nofilter}
|
||||
|
||||
dialog_ok_label = {intl l="Create"}
|
||||
dialog_cancel_label = {intl l="Cancel"}
|
||||
|
||||
form_action = {url path="/admin/configuration/taxes/add"}
|
||||
form_enctype = {form_enctype form=$form}
|
||||
form_error_message = $form_error_message
|
||||
}
|
||||
|
||||
{/form}
|
||||
|
||||
{* -- Delete tax confirmation dialog ----------------------------------- *}
|
||||
|
||||
{capture "tax_delete_dialog"}
|
||||
<input type="hidden" name="tax_id" id="tax_delete_id" value="" />
|
||||
|
||||
{module_include location='tax_delete_form'}
|
||||
|
||||
{/capture}
|
||||
|
||||
{include
|
||||
file = "includes/generic-confirm-dialog.html"
|
||||
|
||||
dialog_id = "tax_delete_dialog"
|
||||
dialog_title = {intl l="Delete tax"}
|
||||
dialog_message = {intl l="Do you really want to delete this tax ?"}
|
||||
|
||||
form_action = {url path='/admin/configuration/taxes/delete'}
|
||||
form_content = {$smarty.capture.tax_delete_dialog nofilter}
|
||||
}
|
||||
|
||||
{* -- Add tax rule confirmation dialog ----------------------------------- *}
|
||||
{form name="thelia.admin.taxrule.add"}
|
||||
|
||||
{if $form_error_message}
|
||||
{$taxRuleCreateError = true}
|
||||
{else}
|
||||
{$taxRuleCreateError = false}
|
||||
{/if}
|
||||
|
||||
{* Capture the dialog body, to pass it to the generic dialog *}
|
||||
{capture "tax_rule_create_dialog"}
|
||||
|
||||
@@ -154,15 +313,31 @@
|
||||
|
||||
{block name="javascript-initialization"}
|
||||
|
||||
{javascripts file='assets/js/bootstrap-select/bootstrap-select.js'}
|
||||
<script src='{$asset_url}'></script>
|
||||
{/javascripts}
|
||||
|
||||
{javascripts file='assets/js/main.js'}
|
||||
<script src='{$asset_url}'></script>
|
||||
{/javascripts}
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
{if $taxCreateError == true}
|
||||
{if $taxRuleCreateError == true}
|
||||
$('#tax_rule_create_dialog').modal();
|
||||
{/if}
|
||||
|
||||
{if $taxCreateError == true}
|
||||
$('#tax_create_dialog').modal();
|
||||
{/if}
|
||||
|
||||
$(".js-delete-tax-rule").click(function(e){
|
||||
$('#tax_rule_delete_id').val($(this).data('id'))
|
||||
});
|
||||
|
||||
$(".js-delete-tax").click(function(e){
|
||||
$('#tax_delete_id').val($(this).data('id'))
|
||||
});
|
||||
</script>
|
||||
|
||||
{/block}
|
||||
Reference in New Issue
Block a user