taxes management

This commit is contained in:
Etienne Roudeix
2013-10-14 17:28:31 +02:00
parent 0ae9c562e4
commit 085c2fa75c
19 changed files with 995 additions and 14 deletions

View 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),
);
}
}

View File

@@ -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"/>

View File

@@ -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"/>

View File

@@ -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>

View 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"
);
}
}

View 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;
}
}

View File

@@ -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";

View File

@@ -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);

View 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";
}
}

View 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");
}
}
}

View File

@@ -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)) {

View 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;
}
}

View File

@@ -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);

View File

@@ -65,4 +65,9 @@ class FeatureFixAmountTaxType extends BaseTaxType
'feature' => new ModelValidIdType('Feature'),
);
}
public function getTitle()
{
return "Fix amount Tax depending on a feature";
}
}

View File

@@ -49,4 +49,9 @@ class featureSlicePercentTaxType extends BaseTaxType
'slices' => new FloatToFloatArrayType(),
);
}
public function getTitle()
{
return "% slice Tax depending on a feature";
}
}

View File

@@ -47,4 +47,9 @@ class FixAmountTaxType extends BaseTaxType
'amount' => new FloatType(),
);
}
public function getTitle()
{
return "Fix amount Tax";
}
}

View File

@@ -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";
}
}

View 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>&nbsp;</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}

View File

@@ -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}