[*] Project : US + CA TaxSystem

This commit is contained in:
fBrignoli
2011-08-18 10:10:50 +00:00
parent 50e9f03719
commit 8f8ac0670d
33 changed files with 1665 additions and 1168 deletions
-24
View File
@@ -504,30 +504,6 @@ if (Tools::isSubmit('toggleScreencast'))
$context->employee->save(); $context->employee->save();
} }
if (Tools::isSubmit('ajaxAddZipCode') OR Tools::isSubmit('ajaxRemoveZipCode'))
{
require_once(PS_ADMIN_DIR.'/tabs/AdminCounty.php');
$zipcodes = Tools::getValue('zipcodes');
$id_county = (int)Tools::getValue('id_county');
$county = new County($id_county);
if (!Validate::isLoadedObject($county))
die('error');
if (Tools::isSubmit('ajaxAddZipCode'))
{
if ($county->isZipCodeRangePresent($zipcodes))
die('error:'.Tools::displayError('This Zip Code is already in use.'));
if ($county->addZipCodes($zipcodes))
die(AdminCounty::renderZipCodeList($county->getZipCodes()));
}
else if (Tools::isSubmit('ajaxRemoveZipCode') AND $county->removeZipCodes($zipcodes))
die(AdminCounty::renderZipCodeList($county->getZipCodes()));
die('error');
}
if (Tools::isSubmit('helpAccess')) if (Tools::isSubmit('helpAccess'))
{ {
$item = Tools::getValue('item'); $item = Tools::getValue('item');
+1 -1
View File
@@ -228,7 +228,7 @@ class AdminAttributeGenerator extends AdminTab
i18n_tax_exc = "'.$this->l('Tax Excl.:').'"; i18n_tax_exc = "'.$this->l('Tax Excl.:').'";
i18n_tax_inc = "'.$this->l('Tax Incl.:').'"; i18n_tax_inc = "'.$this->l('Tax Incl.:').'";
var product_tax = "'.Tax::getProductTaxRate($this->product->id, NULL).'"; var product_tax = "'.$this->product->getTaxesRate().'";
function calcPrice(element, element_has_tax) function calcPrice(element, element_has_tax)
{ {
+1 -1
View File
@@ -1662,7 +1662,7 @@ class AdminProducts extends AdminTab
$specificPrices = SpecificPrice::getByProductId((int)($obj->id)); $specificPrices = SpecificPrice::getByProductId((int)($obj->id));
$specificPricePriorities = SpecificPrice::getPriority((int)($obj->id)); $specificPricePriorities = SpecificPrice::getPriority((int)($obj->id));
$taxRate = TaxRulesGroup::getTaxesRate($obj->id_tax_rules_group, $this->context->country->id, 0, 0); $taxRate = $obj->getTaxesRate(Tax::initializeAddress());
$tmp = array(); $tmp = array();
foreach ($shops as $shop) foreach ($shops as $shop)
+398 -479
View File
@@ -25,543 +25,462 @@
* International Registered Trademark & Property of PrestaShop SA * International Registered Trademark & Property of PrestaShop SA
*/ */
class
class AdminTaxRulesGroup extends AdminTab AdminTaxRulesGroup extends AdminTab
{ {
public $tax_rule;
public $_errors_tax_rule;
public function __construct() public function __construct()
{ {
global $cookie;
$this->table = 'tax_rules_group'; $this->table = 'tax_rules_group';
$this->className = 'TaxRulesGroup'; $this->className = 'TaxRulesGroup';
$this->edit = true; $this->edit = true;
$this->delete = true; $this->delete = true;
$this->ajax = false;
$this->fieldsDisplay = array( $this->fieldsDisplay = array(
'id_tax_rules_group' => array('title' => $this->l('ID'), 'align' => 'center', 'width' => 25), 'id_tax_rules_group' => array('title' => $this->l('ID'), 'align' => 'center', 'width' => 25),
'name' => array('title' => $this->l('Name'), 'width' => 140), 'name' => array('title' => $this->l('Name'), 'width' => 140),
'active' => array('title' => $this->l('Enabled'), 'width' => 25, 'align' => 'center', 'active' => 'status', 'type' => 'bool', 'orderby' => false)); 'active' => array('title' => $this->l('Enabled'), 'width' => 25, 'align' => 'center', 'active' => 'status', 'type' => 'bool', 'orderby' => false));
parent::__construct(); parent::__construct();
} }
public function displayTop() /**
* retrieve a tax rule via ajax
* @return tax rule in json format
*/
public function ajaxProcessGetTaxRule()
{ {
echo '<div class="hint clear" style="display:block;"> $id_rule = (int)Tools::getValue('id_tax_rule');
'.$this->l('The tax rules allow you to define a product or a carrier with different taxes depending on their location (country, state, etc.).').'
<b>'.$this->l('In the majority of cases, the rules created by default by PrestaShop should be enough.').'</b> '. if ($tax_rule = TaxRule::retrieveById($id_rule))
$this->l('If, however, you need to change them, here is an example that will help you understand how it works:'). die(Tools::jsonEncode($tax_rule));
'<br /><br />' else
.$this->l('You want to apply a tax of 19.6% to a product in France and Europe, but not apply this tax to other countries. Follow these steps:').' die('error');
<ul>
<li>'.$this->l('Click "Add New".').'</li>
<li>'.$this->l('Give a name to your tax rule (ex: "19.6% tax rule).').'</li>
<li>'.$this->l('Set the \'active\' field to true.').'</li>
<li>'.$this->l('Edit its configuration by country by associating a 19.6% tax with France and with European countries, and a tax of 0% to other countries.').'</li>
<li>'.$this->l('Click on Save.').'</li>
<li>'.$this->l('Go to your product page (Catalog tab) and associate the "19.6% tax rule" to your product.').'</li>
</ul>
<br />
'.$this->l('Later, if you need to apply a different tax to Spain, you can simply edit the rule "19.6% tax rule" and change the tax associated with Spain.').'<br />
'.$this->l('Note: The default rate applied to your product will be based on your store\'s default country.').'
</div><br />';
} }
public function displayForm($isMainTab = true)
public function ajaxPreProcess() {}
public function postProcess()
{
$action = Tools::getValue('action');
if ($action == 'delete_rule')
{
$id_rule = (int)Tools::getValue('id_tax_rule');
$tax_rule = new TaxRule($id_rule);
if (Validate::isLoadedObject($tax_rule))
{
$tax_rule->delete();
Tools::redirectAdmin(self::$currentIndex.'&'.$this->identifier.'='.$tax_rule->id_tax_rules_group.'&conf=4&update'.$this->table.'&token='.$this->token);
}
}
else if ($action == 'create_rule')
{
$zipcode = Tools::getValue('zipcode');
$id_rule = (int)Tools::getValue('id_tax_rule');
$tr = new TaxRule();
// update or creation?
if (isset($id_rule))
$tr->id = $id_rule;
$tr->id_tax = (int)Tools::getValue('tax');
$tr->id_tax_rules_group = (int)Tools::getValue('id_tax_rules_group');
$tr->id_country = (int)Tools::getValue('country');
$tr->id_state = (int)Tools::getValue('states');
list($tr->zipcode_from, $tr->zipcode_to) = $tr->breakDownZipCode($zipcode);
$tr->behavior = (int)Tools::getValue('behavior');
$tr->description = Tools::getValue('description');
$this->_errors_tax_rule = $this->validateTaxRule($tr);
if (sizeof($this->_errors_tax_rule) == 0)
{
if (!$tr->save())
die('error');
}
$this->tax_rule = $tr;
Tools::redirectAdmin(self::$currentIndex.'&'.$this->identifier.'='.$tr->id_tax_rules_group.'&conf=4&update'.$this->table.'&token='.$this->token);
} else
parent::postProcess();
}
/**
* check if the tax rule could be added in the database
* @param TaxRule $tr
*/
protected function validateTaxRule(TaxRule $tr)
{ {
parent::displayForm(); // TODO: check if the rule already exists
return $tr->validateController();
}
protected function displayJS()
{
global $cookie;
$javascript = <<<EOT
<script type="text/javascript">
function populateStates(id_country, id_state)
{
$.ajax({
url: "ajax.php",
cache: false,
data: "ajaxStates=1&id_country="+id_country+"&id_state="+id_state,
success: function(html){
if (html == "false")
{
$("#state-label").hide();
$("#state-select").hide();
}
else
{
$("#state-label").show();
$("#state-select").show();
$("#states").html(html);
}
}
});
}
function loadTaxRule(id_tax_rule)
{
$.ajax({
url: "ajax-tab.php",
cache: false,
dataType: "json",
data: "action=get_tax_rule&id_tax_rule="+id_tax_rule+"&tab=AdminTaxRulesGroup&token=$this->token",
success: function(data){
$('#rule_form').show();
$('#id_tax_rule').val(data.id_tax_rule);
$('#country').val(data.id_country);
$('#state').val(data.id_state);
zipcode = 0;
if (data.zipcode_from != 0)
{
zipcode = data.zipcode_from;
if (data.zipcode_to != 0)
zipcode = zipcode +"-"+data.zipcode_to
}
$('#zipcode').val(zipcode);
$('#behavior').val(data.behavior);
$('#tax').val(data.id_tax);
$('#description').val(data.description);
populateStates(data.id_country, data.id_state);
},
error: function(data)
{
}
});
}
function initForm()
{
$('#id_tax_rule').val('');
$('#country').val(0);
$('#state').val(0);
$('#zipcode').val(0);
$('#behavior').val(0);
$('#tax').val(0);
$('#description').val('');
populateStates(0,0);
}
</script>
EOT;
echo $javascript;
}
public function displayTaxRulesErrors()
{
if ($nbErrors = count($this->_errors_tax_rule) AND $this->_includeContainer)
{
echo '<script type="text/javascript">
$(document).ready(function() {
$(\'#hideErrorTaxRules\').unbind(\'click\').click(function(){
$(\'.error\').hide(\'slow\', function (){
$(\'.error\').remove();
});
return false;
});
});
$(document).ready(function() {
$(\'#rule_form\').show();
populateStates("'.(int)$this->tax_rule->id_country.'", "'.(int)$this->tax_rule->id_state.'")
});
</script>
<div class="error"><span style="float:right"><a id="hideErrorTaxRules" href=""><img alt="X" src="../img/admin/close.png" /></a></span><img src="../img/admin/error2.png" />';
if (count($this->_errors_tax_rule) == 1)
echo $this->_errors_tax_rule[0];
else
{
echo $nbErrors.' '.$this->l('errors').'<br /><ol>';
foreach ($this->_errors_tax_rule AS $error)
echo '<li>'.$error.'</li>';
echo '</ol>';
}
echo '</div>';
}
}
public function display()
{
if ((Tools::getValue('submitAdd'.$this->table) AND sizeof($this->_errors_tax_rule)) OR isset($_GET['add'.$this->table]))
{
if ($this->tabAccess['add'] === '1')
$this->displayForm();
else
echo $this->l('You do not have permission to add here');
}
else parent::display();
}
/**
* displays the tax rules group form
*/
protected function displayRuleGroupForm()
{
global $cookie, $currentIndex;
parent::displayForm();
if (!($obj = $this->loadObject(true))) if (!($obj = $this->loadObject(true)))
return; return;
$tax_rules = isset($obj->id) ? $tax_rules = TaxRule::getTaxRulesByGroupId($obj->id) : array();
$param_product = Tools::getValue('id_product') ? '&id_product='.Tools::getValue('id_product') : ''; // if the user come from the product page
$param_product = Tools::getValue('id_product') ? '&id_product='.Tools::getValue('id_product') : '';
echo '<form action="'.self::$currentIndex.'&submitAdd'.$this->table.'=1&token='.$this->token.$param_product.'" method="post"> echo '<form action="'.$currentIndex.'&submitAdd'.$this->table.'=1&token='.$this->token.$param_product.'" method="post">
'.($obj->id ? '<input type="hidden" name="id_'.$this->table.'" value="'.$obj->id.'" />' : '').' '.($obj->id ? '<input type="hidden" name="id_'.$this->table.'" value="'.$obj->id.'" />' : '').'
<fieldset><legend><img src="../img/admin/dollar.gif" />'.$this->l('Tax Rules').'</legend> <fieldset><legend><img src="../img/admin/dollar.gif" />'.$this->l('Tax Rules').'</legend>
<input type="hidden" name="tabs" id="tabs" value="0" /> <input type="hidden" name="tabs" id="tabs" value="0" />
'; ';
echo '<label>'.$this->l('Name').'</label> echo '<label>'.$this->l('Name').'</label>
<div class="margin-form"> <div class="margin-form">
<input size="33" type="text" name="name" value="'.Tools::htmlentitiesUTF8($this->getFieldValue($obj, 'name')).'" /><sup> *</sup> <input size="33" type="text" name="name" value="'.Tools::htmlentitiesUTF8($this->getFieldValue($obj, 'name')).'" /><sup> *</sup>
<span class="hint" name="help_box">'.$this->l('Invalid characters:').' <>;=#{}<span class="hint-pointer">&nbsp;</span></span> <span class="hint" name="help_box">'.$this->l('Invalid characters:').' <>;=#{}<span class="hint-pointer">&nbsp;</span></span>
<p class="clear"></p> <p class="clear"></p>
</div>'; </div>';
echo ' echo '
<label>'.$this->l('Enable:').' </label> <label>'.$this->l('Enable:').' </label>
<div class="margin-form"> <div class="margin-form">
<input type="radio" name="active" id="active_on" value="1" '.($this->getFieldValue($obj, 'active') ? 'checked="checked" ' : '').'/> <input type="radio" name="active" id="active_on" value="1" '.($this->getFieldValue($obj, 'active') ? 'checked="checked" ' : '').'/>
<label class="t" for="active_on"> <img src="../img/admin/enabled.gif" alt="'.$this->l('Enabled').'" title="'.$this->l('Enabled').'" /></label> <label class="t" for="active_on"> <img src="../img/admin/enabled.gif" alt="'.$this->l('Enabled').'" title="'.$this->l('Enabled').'" /></label>
<input type="radio" name="active" id="active_off" value="0" '.(!$this->getFieldValue($obj, 'active') ? 'checked="checked" ' : '').'/> <input type="radio" name="active" id="active_off" value="0" '.(!$this->getFieldValue($obj, 'active') ? 'checked="checked" ' : '').'/>
<label class="t" for="active_off"> <img src="../img/admin/disabled.gif" alt="'.$this->l('Disabled').'" title="'.$this->l('Disabled').'" /></label> <label class="t" for="active_off"> <img src="../img/admin/disabled.gif" alt="'.$this->l('Disabled').'" title="'.$this->l('Disabled').'" /></label>
</div>'; </div>
if (Shop::isMultiShopActivated()) <div class="margin-form">
{
echo '<label>'.$this->l('Shop association:').'</label><div class="margin-form">';
$this->displayAssoShop('group_shop');
echo '</div>';
}
echo '
<div class="margin-form">
<input type="submit" value="'.$this->l(' Save ').'" name="submitAdd'.$this->table.'" class="button" />&nbsp;
<input type="submit" value="'.$this->l('Save and stay').'" name="submitAdd'.$this->table.'AndStay" class="button" /> <input type="submit" value="'.$this->l('Save and stay').'" name="submitAdd'.$this->table.'AndStay" class="button" />
</div>'; </div>
echo '<br />'; </form>';
}
echo '<div class="tab-panet-tax" id="tab-pane-1"> /**
<script type="text/javascript"> * Display the tax rule form
var pos_select = '.(($tab = Tools::getValue('tabs')) ? $tab : '0').'; *
function loadTab(id) * @param int $id_rule_group
{} */
protected function displayRuleForm($id_rule_group)
{
global $cookie, $currentIndex;
function applyTax(id_zone) if (Validate::isLoadedObject($this->tax_rule))
{ die(Tools::displayError('Unable to load the tax rule!'));
cur_tax = $("#zone_"+id_zone).val();
$(".tax_"+id_zone).val(cur_tax);
return false;
}
function disableStateTaxRate(id_country, id_state) $country_select = Helper::selectInput(Country::getCountries((int)$cookie->id_lang),
{ array('id' => 'country', 'name' => 'country', 'onclick' => 'populateStates($(this).val(), \'\')'),
if ($("#behavior_state_"+id_state).val() == '.PS_PRODUCT_TAX.') array('key' => 'id_country', 'value' => 'name'));
$("#tax_"+id_country+"_"+id_state).attr("disabled", true);
else
$("#tax_"+id_country+"_"+id_state).attr("disabled", false);
}
function disableCountyTaxRate(id_country, id_state, id_county)
{
if ($("#behavior_county_"+id_county).val() == '.County::USE_STATE_TAX.') $tax_select = Helper::selectInput(Tax::getTaxes((int)$cookie->id_lang),
$("#tax_"+id_country+"_"+id_state+"_"+id_county).attr("disabled", true); array('id' => 'tax', 'name' => 'tax'),
else array('key' => 'id_tax',
{ 'value' => 'name',
'empty' => $this->l('No Tax')));
$("#tax_"+id_country+"_"+id_state+"_"+id_county).attr("disabled", false); $behavior_select = Helper::selectInput(array(0 => $this->l('This tax only'),
} 1 => $this->l('Combine'),
} 2 => $this->l('One After Another')
),
array('id' => 'behavior', 'name' => 'behavior'));
$(\'document\').ready(function (){ echo '<a href="#" onclick="initForm();$(\'#rule_form\').slideToggle();return false;"><img src="../img/admin/add.gif" alt="" /> '.$this->l('Add a new tax rule').'</a>
$(\'.states\').hide(); <form action="'.$currentIndex.'&submitAdd'.$this->table.'=1&token='.$this->token.'" method="post">
$(\'.counties\').hide(); <div id="rule_form" style="display: none">
<label>'.$this->l('Country').'</label>
<div class="margin-form">
'.$country_select.'
</div>
$(\'.open_state\').click(function (){ <label id="state-label">'.$this->l('State').'</label>
if ($(\'.\'+$(this).attr(\'id\')).is(\':hidden\')) <div id="state-select" class="margin-form">
{ <select id="states" name="states">
$(\'.\'+$(this).attr(\'id\')).show(); </select>
$(\'#\'+$(this).attr(\'id\')+\'_button\').attr("src","../img/admin/less.png"); </div>
}
else
{
$(\'.\'+$(this).attr(\'id\')).hide();
$(\'.county_\'+$(this).attr(\'id\')).hide();
$(\'.county_\'+$(this).attr(\'id\')+\'_button\').attr("src","../img/admin/more.png");
$(\'#\'+$(this).attr(\'id\')+\'_button\').attr("src","../img/admin/more.png");
}
});
$(\'.open_county\').click(function (){ <label>'.$this->l('ZipCode range').'</label>
if ($(\'.\'+$(this).attr(\'id\')).is(\':hidden\')) <div class="margin-form">
{ <input type="hidden" name="action" value="create_rule" />
$(\'.\'+$(this).attr(\'id\')).show(); <input type="hidden" id="id_tax_rules_group" name="id_tax_rules_group" value="'.(int)$id_rule_group.'" />
$(\'#\'+$(this).attr(\'id\')+\'_button\').attr("src","../img/admin/less.png"); <input type="hidden" id="id_tax_rule" name="id_tax_rule" />
} <input type="text" id="zipcode" name="zipcode" />&nbsp;
else <div class="hint" style="display: block">'.$this->l('You can define a range (eg: 75000-75015) or a simple zipcode').'</div>
{ </div>
$(\'.\'+$(this).attr(\'id\')).hide();
$(\'#\'+$(this).attr(\'id\')+\'_button\').attr("src","../img/admin/more.png"); <label>'.$this->l('Behavior').'</label>
} <div class="margin-form">
}); '.$behavior_select.'
}); <div class="hint" style="display: block">
</script> '.$this->l('Define the behavior if an address matches multiple rules:').'<br />
<script src="../js/tabpane.js" type="text/javascript"></script> <b>'.$this->l('This Tax Only:').'</b> '.$this->l('Will apply only this tax').'<br />
<script type="text/javascript"> <b>'.$this->l('Combine:').'</b> '.$this->l('Combine taxes (eg: 10% + 5% => 15%)').'<br />
var tabPane1 = new WebFXTabPane( document.getElementById( "tab-pane-1" ) ); <b>'.$this->l('One After Another:').'</b> '.$this->l('Apply taxes one after another (eg: 100€ + 10% => 110€ + 5% => 115.5€)').
</script> '</div>
<link type="text/css" rel="stylesheet" href="../css/tabpane.css" />'.$this->renderZones($tax_rules, $this->context->language->id); </div>
echo '
<div class="margin-form" style="margin-top: 10px"> <label>'.$this->l('Tax').'</label>
<input type="submit" value="'.$this->l(' Save ').'" name="submitAdd'.$this->table.'" class="button" />&nbsp;&nbsp; <div class="margin-form">
<input type="submit" value="'.$this->l('Save and stay').'" name="submitAdd'.$this->table.'AndStay" class="button" /> '.$tax_select.' '.$this->l('(Total tax:').'9%'.')
</div>
<label>'.$this->l('Description').'</label>
<div class="margin-form">
<input type="text" id="description" name="description" />&nbsp;
</div>
<div class="margin-form">
<input type="submit" value="'.$this->l(' Save ').'" name="create_rule" class="button" />
</div>
</div> </div>
</fieldset> </form>
</form>'; <br /><br />
} ';
}
/**
* display the list of rules
*
* @param int $id_rule_group
*/
protected function displayRulesList($id_rule_group)
{
echo '<table class="table" cellspacing="0" cellpadding="0" style="text-align: center; width: 100%;">
<thead>
<tr>
<th>'.$this->l('Country').'</th>
<th>'.$this->l('State').'</th>
<th>'.$this->l('ZipCodes').'</th>
<th>'.$this->l('Behavior').'</th>
<th>'.$this->l('Tax').'</th>
<th>'.$this->l('Description').'</th>
<th>'.$this->l('Actions').'</th>
</tr>
</thead>
<tbody>
'.$this->displayTaxRules((int)$id_rule_group).'
</tbody>
</table>';
}
public function renderZones($tax_rules, $id_lang) /**
{ * display the tax rules list table body
$html = ''; *
$zones = Zone::getZones(true); * @param int $id_rule_group
foreach ($zones AS $key => $zone) */
{ protected function displayTaxRules($id_rule_group)
$html .= '<div class="tab-page" id="tab-page-'.$key.'"> {
<h4 class="tab">'.$zone['name'].'</h4> global $currentIndex, $cookie;
<script type="text/javascript">
tabPane1.addTabPage( document.getElementById( "tab-page-'.$key.'" ) );
</script>
'.$this->renderCountries($tax_rules, $zone['id_zone'], $id_lang).'
</div>';
}
return $html; $html = '';
} $tax_rules = TaxRule::getTaxRulesByGroupId((int)$cookie->id_lang, (int)$id_rule_group);
if (sizeof($tax_rules) == 0)
{
$html .= '<tr>
<td colspan="7">'.$this->l('No rules defined').'</td>
</tr>';
} else {
foreach ($tax_rules as $tax_rule)
{
// format fields for display
$state_name = ($tax_rule['state_name'] == '' ? '*' : $tax_rule['state_name']);
public function renderCountries($tax_rules, $id_zone, $id_lang) $zipcodes = '*';
{ if (isset($tax_rule['zipcode_from']) && $tax_rule['zipcode_from'] != 0)
{
$zipcodes = $tax_rule['zipcode_from'];
if (isset($tax_rule['zipcode_to']) && $tax_rule['zipcode_to'] != 0 && $tax_rule['zipcode_to'] != $tax_rule['zipcode_from'])
{
$zipcodes .= '-'.$tax_rule['zipcode_to'];
}
}
$html = ' $tax = ((float)$tax_rule['rate'] == 0 ? '-' : (float)$tax_rule['rate'].'%');
<table>
<tr>
<td width="260px" style="font-weight:bold">'.$this->l('All').'</td>
<td>'.$this->renderTaxesSelect($id_lang, '', array('id' => 'zone_'.(int)$id_zone)).' <input type="submit" onclick="return applyTax(\''.(int)$id_zone.'\')" class="button" value="'.$this->l('Apply').'"/></td>
</tr>
</table><hr />';
$html .= ' $behavior = ($tax_rule['behavior'] == 0 ? $this->l('This tax only') : $this->l('Compute with others'));
<table class="table" cellpadding="0" cellspacing="0" style="width: 100%;">
<thead>
<tr>
<th style="width: 3%;"></th>
<th style="width: 40%;">'.$this->l('Country / State / County').'</th>
<th style="width: 57%;">'.$this->l('Tax to apply').'</th>
</tr>
</thead>
<tbody>
';
$countries = Country::getCountriesByZoneId((int)$id_zone, (int)$id_lang);
$countCountries = sizeof($countries);
$i = 1;
foreach ($countries AS $country) // render fields
{ $html .= '<tr>
$id_tax = 0; <td>'.Tools::htmlentitiesUTF8($tax_rule['country_name']).'</td>
<td>'.Tools::htmlentitiesUTF8($state_name).'</td>
<td>'.Tools::htmlentitiesUTF8($zipcodes).'</td>
<td>'.Tools::htmlentitiesUTF8($behavior).'</td>
<td>'.Tools::htmlentitiesUTF8($tax).'</td>
<td>'.Tools::htmlentitiesUTF8($tax_rule['description']).'</td>
<td>
<a href="#" onclick="loadTaxRule(\''.$tax_rule['id_tax_rule'].'\'); return false;">
<img src="../img/admin/edit.gif" border="0" alt="'.$this->l('Edit').'" title="'.$this->l('Edit').'" />
</a>
<a href="'.$currentIndex.'&id_tax_rule='.$tax_rule['id_tax_rule'].'&action=delete_rule&token='.$this->token.'" onclick="return confirm(\''.addslashes($this->l('Delete item ?')).'\');">
<img src="../img/admin/delete.gif" border="0" alt="'.$this->l('Delete').'" title="'.$this->l('Delete').'" />
</a>
if (array_key_exists($country['id_country'], $tax_rules) AND array_key_exists(0, $tax_rules[$country['id_country']])) </td>
$id_tax = (int)$tax_rules[$country['id_country']][0][0]['id_tax']; </tr>';
$html .= '
<tr>
<td>'.($country['contains_states'] ? '<a class="open_state" id="state_'.(int)$country['id_country'].'"><img id="state_'.(int)$country['id_country'].'_button" src="../img/admin/more.png" alt="" style="vertical-align:middle;padding:0;" /></a>' : '').'</td>
<td>
<img src="../img/admin/lv2_'.($i == $countCountries ? 'f' : 'b').'.png" alt="" style="vertical-align:middle;" /> <label class="t">'.Tools::htmlentitiesUTF8($country['name']).'</label>
</td>
<td>'.$this->renderTaxesSelect($id_lang, $id_tax, array('class' => 'tax_'.$id_zone, 'id' => 'tax_'.$country['id_country'].'_0', 'name' => 'tax_'.$country['id_country'].'_0' )).'</td>
</tr>
';
if ($country['contains_states']) {
$html .= $this->renderStates($tax_rules, (int)$id_zone, (int)$country['id_country'], (int)$id_lang);
} }
}
$i++;
}
$html .= '
</tbody>
</table>
';
return $html; return $html;
} }
public function renderStates($tax_rules, $id_zone, $id_country, $id_lang) /**
{ * @param boolean $firstCall
$states = State::getStatesByIdCountry((int)$id_country); */
$countStates = sizeof($states); public function displayForm($firstCall = true)
$i = 1; {
$html = ''; if (!($obj = $this->loadObject(true)))
foreach ($states AS $state) return;
parent::displayForm();
$this->displayRuleGroupForm();
$this->displayJS();
// display tax rules only if the group has already been created
if ($obj->id)
{ {
$id_tax = 0; echo '<hr />';
$selected = PS_PRODUCT_TAX; $this->displayTaxRulesErrors();
$this->displayRuleForm($obj->id);
if (array_key_exists($id_country, $tax_rules) $this->displayRulesList($obj->id);
AND array_key_exists($state['id_state'], $tax_rules[$id_country])
AND array_key_exists(0, $tax_rules[$id_country][$state['id_state']]))
{
$id_tax = (int)$tax_rules[$id_country][$state['id_state']][0]['id_tax'];
$selected = (int)$tax_rules[$id_country][$state['id_state']][0]['state_behavior'];
}
$disable = (PS_PRODUCT_TAX == $selected ? 'disabled' : '');
$html .= '
<tr class="states state_'.(int)$id_country.' alt_row">
<td>'.(State::hasCounties($state['id_state']) ? '<a class="open_county" id="county_'.(int)$state['id_state'].'"><img id="county_'.(int)$state['id_state'].'_button" class="county_state_'.(int)$id_country.'_button" src="../img/admin/more.png" alt="" /></a>' : '').'</td>
<td><img src="../img/admin/lv3_'.($i == $countStates ? 'f' : 'b').'.png" alt="" style="vertical-align:middle;" /> <label class="t">'.Tools::htmlentitiesUTF8($state['name']).'</label></td>
<td>
'.$this->renderTaxesSelect($id_lang, $id_tax, array('class' => 'tax_'.$id_zone,
'id' => 'tax_'.$id_country.'_'.$state['id_state'],
'name' => 'tax_'.$id_country.'_'.$state['id_state'],
'disabled' => $disable )).'&nbsp;-&nbsp;
<select id="behavior_state_'.$state['id_state'].'" name="behavior_state_'.$state['id_state'].'" onchange="disableStateTaxRate(\''.$id_country.'\',\''.$state['id_state'].'\')">
<option value="'.(int)PS_PRODUCT_TAX.'" '.($selected == PS_PRODUCT_TAX ? 'selected="selected"' : '').'>'.$this->l('Apply country tax only').'</option>
<option value="'.(int)PS_STATE_TAX.'" '.($selected == PS_STATE_TAX ? 'selected="selected"' : '').'>'.$this->l('Apply state tax only').'</option>
<option value="'.(int)PS_BOTH_TAX.'" '.($selected == PS_BOTH_TAX ? 'selected="selected"' : '').'>'.$this->l('Apply both taxes').'</option>
</select>
</td>
</tr>
';
if (State::hasCounties($state['id_state']))
$html .= $this->renderCounties($tax_rules, $id_zone, $id_country, $state['id_state'], $id_lang);
$i++;
} }
}
return $html;
}
public function renderCounties($tax_rules, $id_zone, $id_country, $id_state, $id_lang)
{
$counties = County::getCounties((int)$id_state);
$countCounties = sizeof($counties);
$i = 1;
$html = '';
foreach ($counties AS $county)
{
$id_tax = 0;
$selected = County::USE_STATE_TAX;
if (array_key_exists($id_country, $tax_rules)
AND array_key_exists($id_state, $tax_rules[$id_country])
AND array_key_exists($county['id_county'], $tax_rules[$id_country][$id_state]))
{
$id_tax = (int)$tax_rules[$id_country][$id_state][$county['id_county']]['id_tax'];
$selected = (int)$tax_rules[$id_country][$id_state][$county['id_county']]['county_behavior'];
}
$disable = (County::USE_STATE_TAX == $selected ? 'disabled' : '');
$html .= '
<tr class="counties county_state_'.(int)$id_country.' county_'.(int)$id_state.'">
<td></td>
<td><img src="../img/admin/lv4_'.($i == $countCounties ? 'f' : 'b').'.png" alt="" style="vertical-align:middle;" /> <label class="t">'.Tools::htmlentitiesUTF8($county['name']).'</label></td>
<td>
'.$this->renderTaxesSelect($id_lang, $id_tax, array('class' => 'tax_'.$id_zone,
'id' => 'tax_'.$id_country.'_'.$id_state.'_'.$county['id_county'],
'name' => 'tax_'.$id_country.'_'.$id_state.'_'.$county['id_county'],
'disabled' => $disable )).'&nbsp;-&nbsp;
<select id="behavior_county_'.$county['id_county'].'" name="behavior_county_'.$county['id_county'].'" onchange="disableCountyTaxRate(\''.$id_country.'\',\''.$id_state.'\',\''.$county['id_county'].'\')">
<option value="'.(int)County::USE_STATE_TAX.'" '.($selected == County::USE_STATE_TAX ? 'selected="selected"' : '').'>'.$this->l('Apply state tax only').'</option>
<option value="'.(int)County::USE_COUNTY_TAX.'" '.($selected == County::USE_COUNTY_TAX ? 'selected="selected"' : '').'>'.$this->l('Apply county tax only').'</option>
<option value="'.(int)County::USE_BOTH_TAX.'" '.($selected == County::USE_BOTH_TAX ? 'selected="selected"' : '').'>'.$this->l('Apply both taxes').'</option>
</select>
</td>
</tr>
';
}
return $html;
}
public function renderTaxesSelect($id_lang, $default_value, $html_options)
{
$opt = '';
foreach( array('id', 'class', 'name', 'disabled') AS $prop)
if (array_key_exists($prop, $html_options) && !empty($html_options[$prop]))
$opt .= $prop.'="'.$html_options[$prop].'"';
$html = '<select '.$opt.'>
<option value="0">'.$this->l('No Tax').'</option>';
$taxes = Tax::getTaxes((int)$id_lang, true);
foreach ($taxes AS $tax)
{
$selected = ($default_value == $tax['id_tax']) ? 'selected="selected"' : '';
$html .= '<option value="'.(int)$tax['id_tax'].'" '.$selected.'>'.Tools::htmlentitiesUTF8($tax['name']).'</option>';
}
$html .= '</select>';
return $html;
}
protected function afterAdd($object)
{
$this->afterUpdate($object);
}
protected function afterUpdate($object)
{
TaxRule::deleteByGroupId($object->id);
foreach(Country::getCountries($this->context->language->id, true) AS $country)
{
$id_tax = (int)Tools::getValue('tax_'.$country['id_country'].'_0');
// default country rule
if (!empty($id_tax))
{
$tr = new TaxRule();
$tr->id_tax_rules_group = $object->id;
$tr->id_country = (int)$country['id_country'];
$tr->id_state = 0;
$tr->id_county = 0;
$tr->id_tax = $id_tax;
$tr->state_behavior = 0;
$tr->county_behavior = 0;
$tr->save();
}
// state specific rule
if (!empty($country['contains_states']))
{
foreach ($country['states'] AS $state)
{
$state_behavior = (int)Tools::getValue('behavior_state_'.$state['id_state']);
if ($state_behavior != PS_PRODUCT_TAX)
{
$tr = new TaxRule();
$tr->id_tax_rules_group = $object->id;
$tr->id_country = (int)$country['id_country'];
$tr->id_state = (int)$state['id_state'];
$tr->id_county = 0;
$tr->id_tax = (int)Tools::getValue('tax_'.$country['id_country'].'_'.$state['id_state']);
$tr->state_behavior = $state_behavior;
$tr->county_behavior = 0;
$tr->save();
}
// county specific rule
if (State::hasCounties($state['id_state']))
{
$counties = County::getCounties($state['id_state']);
foreach ($counties AS $county)
{
$county_behavior = (int)Tools::getValue('behavior_county_'.$county['id_county']);
if ($county_behavior != County::USE_STATE_TAX)
{
$tr = new TaxRule();
$tr->id_tax_rules_group = $object->id;
$tr->id_country = (int)$country['id_country'];
$tr->id_state = (int)$state['id_state'];
$tr->id_county = (int)$county['id_county'];
$tr->id_tax = (int)Tools::getValue('tax_'.$country['id_country'].'_'.$state['id_state'].'_'.$county['id_county']);
$tr->state_behavior = 0;
$tr->county_behavior = $county_behavior;
$tr->save();
}
}
}
}
}
}
}
public function postProcess()
{
if (!isset($this->table))
return false;
// set token
$token = Tools::getValue('token') ? Tools::getValue('token') : $this->token;
if (Tools::getValue('submitAdd'.$this->table))
{
$id_product = Tools::getValue('id_product');
/* Checking fields validity */
$this->validateRules();
if (!sizeof($this->_errors))
{
$id = (int)(Tools::getValue($this->identifier));
/* Object update */
if (isset($id) AND !empty($id))
{
if ($this->tabAccess['edit'] === '1')
{
$object = new $this->className($id);
if (Validate::isLoadedObject($object))
{
/* Specific to objects which must not be deleted */
if ($this->deleted AND $this->beforeDelete($object))
{
// Create new one with old objet values
$objectNew = new $this->className($object->id);
$objectNew->id = NULL;
$objectNew->date_add = '';
$objectNew->date_upd = '';
// Update old object to deleted
$object->deleted = 1;
$object->update();
// Update new object with post values
$this->copyFromPost($objectNew, $this->table);
$result = $objectNew->add();
if (Validate::isLoadedObject($objectNew))
$this->afterDelete($objectNew, $object->id);
}
else
{
$this->copyFromPost($object, $this->table);
$result = $object->update();
$this->afterUpdate($object);
}
if (!$result)
$this->_errors[] = Tools::displayError('An error occurred while updating object.').' <b>'.$this->table.'</b> ('.Db::getInstance()->getMsgError().')';
elseif ($this->postImage($object->id) AND !sizeof($this->_errors))
{
$parent_id = (int)(Tools::getValue('id_parent', 1));
// Save and stay on same form
if (Tools::isSubmit('submitAdd'.$this->table.'AndStay'))
Tools::redirectAdmin(self::$currentIndex.'&'.$this->identifier.'='.$object->id.'&conf=4&update'.$this->table.'&token='.$token);
// Default behavior (save and back)
$id_product = (int)Tools::getValue('id_product');
if ($id_product)
Tools::redirectAdmin('?tab=AdminCatalog&id_product='.$id_product.'&updateproduct&token='.Tools::getAdminToken('AdminCatalog'.(int)(Tab::getIdFromClassName('AdminCatalog')).(int)$this->context->employee->id));
Tools::redirectAdmin(self::$currentIndex.($parent_id ? '&'.$this->identifier.'='.$object->id : '').'&conf=3&token='.$token);
}
}
else
$this->_errors[] = Tools::displayError('An error occurred while updating object.').' <b>'.$this->table.'</b> '.Tools::displayError('(cannot load object)');
}
else
$this->_errors[] = Tools::displayError('You do not have permission to edit here.');
}
/* Object creation */
else
{
if ($this->tabAccess['add'] === '1')
{
$object = new $this->className();
$this->copyFromPost($object, $this->table);
if (!$object->add())
$this->_errors[] = Tools::displayError('An error occurred while creating object.').' <b>'.$this->table.' ('.Db::getInstance()->getMsgError().')</b>';
elseif (($_POST[$this->identifier] = $object->id /* voluntary */) AND $this->postImage($object->id) AND !sizeof($this->_errors) AND $this->_redirect)
{
$parent_id = (int)(Tools::getValue('id_parent', 1));
$this->afterAdd($object);
// Save and stay on same form
if (Tools::isSubmit('submitAdd'.$this->table.'AndStay'))
Tools::redirectAdmin(self::$currentIndex.'&'.$this->identifier.'='.$object->id.'&conf=3&update'.$this->table.'&token='.$token);
$id_product = (int)Tools::getValue('id_product');
if ($id_product)
Tools::redirectAdmin('?tab=AdminCatalog&id_product='.$id_product.'&updateproduct&token='.Tools::getAdminToken('AdminCatalog'.(int)(Tab::getIdFromClassName('AdminCatalog')).(int)$this->context->employee->id));
Tools::redirectAdmin(self::$currentIndex.($parent_id ? '&'.$this->identifier.'='.$object->id : '').'&conf=3&token='.$token);
// Default behavior (save and back)
Tools::redirectAdmin(self::$currentIndex.($parent_id ? '&'.$this->identifier.'='.$object->id : '').'&conf=3&token='.$token);
}
}
else
$this->_errors[] = Tools::displayError('You do not have permission to add here.');
}
}
$this->_errors = array_unique($this->_errors);
}
parent::postProcess();
}
} }
+5 -3
View File
@@ -156,9 +156,9 @@ class AdminTracking extends AdminTab
</tr>'; </tr>';
foreach ($this->_list['obj'] AS $k => $prod) foreach ($this->_list['obj'] AS $k => $prod)
{ {
$product = new Product((int)($prod['id_product'])); $product = new Product((int)$prod['id_product'], false);
$product->name = $product->name[(int)$this->context->language->id]; $product->name = $product->name[(int)$this->context->language->id];
$taxrate = Tax::getProductTaxRate($product->id); $taxrate = $product->getTaxesRate();
echo ' echo '
<tr> <tr>
@@ -222,13 +222,15 @@ class AdminTracking extends AdminTab
else else
$prod['combination_name'] = $prod['group_name'].' : '.$prod['attribute_name']; $prod['combination_name'] = $prod['group_name'].' : '.$prod['attribute_name'];
$attributes[$prod['id_product_attribute']] = $prod; $attributes[$prod['id_product_attribute']] = $prod;
$prevAttributeId = $prod['id_product_attribute']; $prevAttributeId = $prod['id_product_attribute'];
} }
foreach ($attributes AS $prod) foreach ($attributes AS $prod)
{ {
$taxrate = Tax::getProductTaxRate($prod['id_product']); $product = new Product((int)$prod['id_product'], false);
$tax_rate = $product->getTaxesRate();
echo ' echo '
<tr> <tr>
+7
View File
@@ -77,6 +77,8 @@ class Autoload
*/ */
public function load($classname) public function load($classname)
{ {
// echo("Please load $classname.<br />");
// regenerate the class index if the requested class is not found in the index or if the requested file doesn't exists // regenerate the class index if the requested class is not found in the index or if the requested file doesn't exists
if (!isset($this->index[$classname]) || ($this->index[$classname] && !file_exists($this->root_dir.$this->index[$classname]))) if (!isset($this->index[$classname]) || ($this->index[$classname] && !file_exists($this->root_dir.$this->index[$classname])))
$this->generateIndex(); $this->generateIndex();
@@ -87,6 +89,7 @@ class Autoload
// If requested class does not exist, load associated core class // If requested class does not exist, load associated core class
if (isset($this->index[$classname]) && !$this->index[$classname]) if (isset($this->index[$classname]) && !$this->index[$classname])
{ {
require_once($this->root_dir.$this->index[$classname.'Core']); require_once($this->root_dir.$this->index[$classname.'Core']);
if (file_exists($this->root_dir.'override/'.$this->index[$classname.'Core'])) if (file_exists($this->root_dir.'override/'.$this->index[$classname.'Core']))
{ {
@@ -104,10 +107,14 @@ class Autoload
{ {
// request a non Core Class load the associated Core class if exists // request a non Core Class load the associated Core class if exists
if (isset($this->index[$classname.'Core'])) if (isset($this->index[$classname.'Core']))
{
require_once($this->root_dir.$this->index[$classname.'Core']); require_once($this->root_dir.$this->index[$classname.'Core']);
}
if (isset($this->index[$classname])) if (isset($this->index[$classname]))
{
require_once($this->root_dir.$this->index[$classname]); require_once($this->root_dir.$this->index[$classname]);
}
} }
} }
// Call directly ProductCore, ShopCore class // Call directly ProductCore, ShopCore class
+14
View File
@@ -770,6 +770,20 @@ class CarrierCore extends ObjectModel
return self::$_cache_tax_rule[$id_carrier]; return self::$_cache_tax_rule[$id_carrier];
} }
/**
* Return the taxes rate associated to the carrier
*
* @since 1.5
* @param Address $address
*/
public function getTaxesRate(Address $address)
{
$tax_manager = TaxManagerFactory::getManager($address, $this->id_tax_rules_group);
$tax_calculator = $tax_manager->getTaxCalculator();
return $tax_calculator->getTaxesRate();
}
/** /**
* This tricky method generate a sql clause to check if ranged data are overloaded by multishop * This tricky method generate a sql clause to check if ranged data are overloaded by multishop
* *
+5 -3
View File
@@ -369,7 +369,8 @@ class CartCore extends ObjectModel
LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa ON (pa.`id_product_attribute` = cp.`id_product_attribute`) LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa ON (pa.`id_product_attribute` = cp.`id_product_attribute`)
LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group` LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group`
AND tr.`id_country` = '.(int)$id_country.' AND tr.`id_country` = '.(int)$id_country.'
AND tr.`id_state` = 0) AND tr.`id_state` = 0
AND tr.`zipcode_from` = 0)
LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`) LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`)
LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)$this->id_lang.') LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)$this->id_lang.')
LEFT JOIN `'._DB_PREFIX_.'customization` cu ON (p.`id_product` = cu.`id_product`) LEFT JOIN `'._DB_PREFIX_.'customization` cu ON (p.`id_product` = cu.`id_product`)
@@ -381,6 +382,7 @@ class CartCore extends ObjectModel
AND p.`id_product` IS NOT NULL AND p.`id_product` IS NOT NULL
GROUP BY unique_id GROUP BY unique_id
ORDER BY cp.date_add ASC'; ORDER BY cp.date_add ASC';
$result = Db::getInstance()->ExecuteS($sql); $result = Db::getInstance()->ExecuteS($sql);
// Reset the cache before the following return, or else an empty cart will add dozens of queries // Reset the cache before the following return, or else an empty cart will add dozens of queries
@@ -922,7 +924,7 @@ class CartCore extends ObjectModel
// no shipping cost if is a cart with only virtuals products // no shipping cost if is a cart with only virtuals products
$virtual = $this->isVirtualCart(); $virtual = $this->isVirtualCart();
if ($virtual AND $type == Cart::ONLY_SHIPPING) if ($virtual AND $type == Cart::ONLY_SHIPPING)
return 0; return 0;
if ($virtual AND $type == Cart::BOTH) if ($virtual AND $type == Cart::BOTH)
$type = Cart::BOTH_WITHOUT_SHIPPING; $type = Cart::BOTH_WITHOUT_SHIPPING;
@@ -1180,7 +1182,7 @@ class CartCore extends ObjectModel
// Select carrier tax // Select carrier tax
if ($useTax AND !Tax::excludeTaxeOption()) if ($useTax AND !Tax::excludeTaxeOption())
$carrierTax = Tax::getCarrierTaxRate((int)$carrier->id, (int)$this->{Configuration::get('PS_TAX_ADDRESS_TYPE')}); $carrierTax = $carrier->getTaxesRate(new Address((int)$this->{Configuration::get('PS_TAX_ADDRESS_TYPE')}));
$configuration = Configuration::getMultiple(array('PS_SHIPPING_FREE_PRICE', 'PS_SHIPPING_HANDLING', 'PS_SHIPPING_METHOD', 'PS_SHIPPING_FREE_WEIGHT')); $configuration = Configuration::getMultiple(array('PS_SHIPPING_FREE_PRICE', 'PS_SHIPPING_HANDLING', 'PS_SHIPPING_METHOD', 'PS_SHIPPING_FREE_WEIGHT'));
// Free fees // Free fees
+2 -1
View File
@@ -548,7 +548,8 @@ class CategoryCore extends ObjectModel
LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.') LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.')
LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group` LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group`
AND tr.`id_country` = '.(int)$context->country->id.' AND tr.`id_country` = '.(int)$context->country->id.'
AND tr.`id_state` = 0) AND tr.`id_state` = 0
AND tr.`zipcode_from` = 0)
LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`) LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`)
LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)$id_lang.') LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)$id_lang.')
LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON m.`id_manufacturer` = p.`id_manufacturer` LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON m.`id_manufacturer` = p.`id_manufacturer`
+55 -135
View File
@@ -25,6 +25,10 @@
* International Registered Trademark & Property of PrestaShop SA * International Registered Trademark & Property of PrestaShop SA
*/ */
/**
* @deprecated since 1.5
*/
class CountyCore extends ObjectModel class CountyCore extends ObjectModel
{ {
public $id; public $id;
@@ -63,181 +67,97 @@ class CountyCore extends ObjectModel
public function delete() public function delete()
{ {
$id = $this->id; return true;
parent::delete();
// remove associated zip codes & tax rule
return (County::deleteZipCodeByIdCounty($id) AND TaxRule::deleteTaxRuleByIdCounty($id));
} }
/**
* @deprecated since 1.5
*/
public static function getCounties($id_state) public static function getCounties($id_state)
{ {
if (!isset(self::$_cache_get_counties[$id_state])) Tools::displayAsDeprecated();
{ return false;
self::$_cache_get_counties[$id_state] = Db::getInstance()->ExecuteS('
SELECT * FROM `'._DB_PREFIX_.'county`
WHERE `id_state` = '.(int)$id_state
);
}
return self::$_cache_get_counties[$id_state];
} }
// return the list of associated zipcode /**
* @deprecated since 1.5
*/
public function getZipCodes() public function getZipCodes()
{ {
return Db::getInstance()->ExecuteS(' Tools::displayAsDeprecated();
SELECT * FROM `'._DB_PREFIX_.'county_zip_code` return false;
WHERE `id_county` = '.(int)$this->id.'
ORDER BY `from_zip_code` ASC'
);
} }
/**
* @deprecated since 1.5
*/
public function addZipCodes($zip_codes) public function addZipCodes($zip_codes)
{ {
list($from, $to) = $this->breakDownZipCode($zip_codes); Tools::displayAsDeprecated();
return true;
if ($from == 0)
return false;
return Db::getInstance()->Execute(
'INSERT INTO `'._DB_PREFIX_.'county_zip_code` (`id_county`, `from_zip_code`, `to_zip_code`)
VALUES ('.(int)$this->id.','.(int)$from.','.(int)$to.')'
);
} }
/**
* @deprecated since 1.5
*/
public function removeZipCodes($zip_codes) public function removeZipCodes($zip_codes)
{ {
list($from, $to) = $this->breakDownZipCode($zip_codes); Tools::displayAsDeprecated();
return true;
if ($from == 0)
return false;
return Db::getInstance()->Execute('
DELETE FROM `'._DB_PREFIX_.'county_zip_code`
WHERE `id_county` = '.(int)$this->id.'
AND `from_zip_code` = '.(int)$from.'
AND `to_zip_code` = '.(int)$to
);
} }
/**
* @deprecated since 1.5
*/
public function breakDownZipCode($zip_codes) public function breakDownZipCode($zip_codes)
{ {
$zip_codes = preg_split('/-/', $zip_codes); Tools::displayAsDeprecated();
return array(0,0);
if (sizeof($zip_codes) == 2)
{
$from = $zip_codes[0];
$to = $zip_codes[1];
if ($zip_codes[0] > $zip_codes[1])
{
$from = $zip_codes[1];
$to = $zip_codes[0];
}
else if ($zip_codes[0] == $zip_codes[1])
{
$from = $zip_codes[0];
$to = 0;
}
}
else if (sizeof($zip_codes) == 1)
{
$from = $zip_codes[0];
$to = 0;
}
if (!Validate::isInt($from) OR !Validate::isInt($to))
{
$from = 0;
$to = 0;
}
return array($from, $to);
} }
/**
* @deprecated since 1.5
*/
public static function getIdCountyByZipCode($id_state, $zip_code) public static function getIdCountyByZipCode($id_state, $zip_code)
{ {
if (!isset(self::$_cache_county_zipcode[$id_state.'-'.$zip_code])) Tools::displayAsDeprecated();
{ return false;
self::$_cache_county_zipcode[$id_state.'-'.$zip_code] = Db::getInstance()->getValue('
SELECT DISTINCT c.`id_county` FROM `'._DB_PREFIX_.'county` c
LEFT JOIN `'._DB_PREFIX_.'county_zip_code` cz ON (c.`id_county` = cz.`id_county`)
WHERE `id_state` = '.(int)$id_state.'
AND cz.`from_zip_code` >= '.(int)$zip_code.'
AND cz.`to_zip_code` <= '.(int)$zip_code
);
}
return self::$_cache_county_zipcode[$id_state.'-'.$zip_code];
} }
/**
* @deprecated since 1.5
*/
public function isZipCodeRangePresent($zip_codes) public function isZipCodeRangePresent($zip_codes)
{ {
$res = false; Tools::displayAsDeprecated();
list($from, $to) = $this->breakDownZipCode($zip_codes); return false;
if ($from == 0)
return false;
if ($to != 0)
{
$res = Db::getInstance()->getValue('
SELECT COUNT(*) FROM `'._DB_PREFIX_.'county_zip_code` cz
LEFT JOIN `'._DB_PREFIX_.'county` c ON (c.`id_county` = cz.`id_county`)
LEFT JOIN `'._DB_PREFIX_.'state` s ON (s.`id_state` = c.`id_state`)
WHERE `from_zip_code` >= '.(int)$from.'
AND `to_zip_code` <= '.(int)$to.'
AND s.`id_country` = (SELECT `id_country`
FROM `'._DB_PREFIX_.'state` s
LEFT JOIN `'._DB_PREFIX_.'county` c ON (c.`id_state` = s.`id_state`)
WHERE `id_county` = '.(int)$this->id.'
)'
);
}
return ($res OR County::isZipCodePresent($from) OR County::isZipCodePresent($to));
} }
/**
* @deprecated since 1.5
*/
public function isZipCodePresent($zip_code) public function isZipCodePresent($zip_code)
{ {
Tools::displayAsDeprecated();
if ($zip_code == 0) return false;
return false;
return (bool) Db::getInstance()->getValue('
SELECT COUNT(*) FROM `'._DB_PREFIX_.'county_zip_code` cz
LEFT JOIN `'._DB_PREFIX_.'county` c ON (c.`id_county` = cz.`id_county`)
LEFT JOIN `'._DB_PREFIX_.'state` s ON (s.`id_state` = c.`id_state`)
WHERE
(`from_zip_code` <= '.(int)$zip_code.' AND `to_zip_code` >= '.(int)$zip_code.')
OR
(`from_zip_code` = '.(int)$zip_code.')
AND s.`id_country` = (SELECT `id_country`
FROM `'._DB_PREFIX_.'state` s
LEFT JOIN `'._DB_PREFIX_.'county` c ON (c.`id_state` = s.`id_state`)
WHERE `id_county` = '.(int)$this->id.'
)'
);
} }
/**
* @deprecated since 1.5
*/
public static function deleteZipCodeByIdCounty($id_county) public static function deleteZipCodeByIdCounty($id_county)
{ {
return Db::getInstance()->Execute( Tools::displayAsDeprecated();
'DELETE FROM `'._DB_PREFIX_.'county_zip_code` return true;
WHERE `id_county` = '.(int)$id_county
);
} }
/**
* @deprecated since 1.5
*/
public static function getIdCountyByNameAndIdState($name, $id_state) public static function getIdCountyByNameAndIdState($name, $id_state)
{ {
return Db::getInstance()->getValue(' Tools::displayAsDeprecated();
SELECT `id_county` FROM `'._DB_PREFIX_.'county` return false;
WHERE `name` = \''.pSQL($name).'\'
AND `id_state` = '.(int)$id_state
);
} }
} }
+81 -14
View File
@@ -42,20 +42,20 @@ class HelperCore
* @param type $selected_cat array of selected categories * @param type $selected_cat array of selected categories
* Format * Format
* Array * Array
( * (
[0] => 1 * [0] => 1
[1] => 2 * [1] => 2
) * )
* OR * OR
Array * Array
( * (
[1] => Array * [1] => Array
( * (
[id_category] => 1 * [id_category] => 1
[name] => Home page * [name] => Home page
[link_rewrite] => home * [link_rewrite] => home
) * )
) * )
* @param type $input_name name of input * @param type $input_name name of input
* @return string * @return string
*/ */
@@ -127,4 +127,71 @@ class HelperCore
</ul>'; </ul>';
return $html; return $html;
} }
/**
* Create a select input field
*
* @param array $values
* @param array $html_options any key => value options
* @param array $select_options
* - key: the array value that will be used as a key in my select (optional)
* - value: the array value that will be used as a label in my select (optional)
* - empty: the label displayed as an empty value (optional)
* - selected: the key corresponding to the selected value (optional)
*
* @return string html content
*/
public static function selectInput(array $values, array $html_options = array(), array $select_options = array())
{
// options management
$options = self::buildHtmlOptions($html_options);
$select_html = '<select '.$options.'>';
if (isset($select_options['key']))
$use_key = $select_options['key'];
if (isset($select_options['value']))
$use_value = $select_options['value'];
if (isset($select_options['empty']))
$select_html .= '<option value="">'.$select_options['empty'].'</option>';
// render options fields
foreach ($values as $key => $value)
{
$current_key = isset($use_key) ? $value[$use_key] : $key;
$current_value = isset($use_value) ? $value[$use_value] : $value;
if (isset($select_options['selected']) && $select_options['selected'] == $current_key)
$selected = 'selected="selected"';
else
$selected = '';
$select_html .= '<option value="'.Tools::htmlentitiesUTF8($current_key).'" '.$selected.'>'.Tools::htmlentitiesUTF8($current_value).'</option>';
}
$select_html .= '</select>';
return $select_html;
}
/**
* Create html a string containing html options
* eg: buildHtmlOptions(array('name' => 'myInputName', 'id' => 'myInputId'));
* return => 'name="myInputName" id="myInputId"'
*
* @param array $html_options
*
* @return string
*/
protected static function buildHtmlOptions(array $html_options)
{
$html = '';
foreach ($html_options as $html_option => $value)
$html .= Tools::htmlentitiesUTF8($html_option).'="'.Tools::htmlentitiesUTF8($value).'" ';
return rtrim($html, ' ');
}
} }
-52
View File
@@ -117,60 +117,8 @@ class LocalizationPackCore
return false; return false;
} }
} }
// Add counties
foreach ($data->county AS $xml_county)
{
$county_attributes = $xml_county->attributes();
if (!$id_county = County::getIdCountyByNameAndIdState($county_attributes['name'], $state->id))
{
$county = new County();
$county->name = $county_attributes['name'];
$county->id_state = (int)$state->id;
$county->active = 1;
if (!$county->validateFields())
{
$this->_errors[] = Tools::displayError('Invalid County properties');
return false;
}
if (!$county->save())
{
$this->_errors[] = Tools::displayError('An error has occurred while adding the county');
return false;
}
} else {
$county = new County((int)$id_county);
if (!Validate::isLoadedObject($county))
{
$this->_errors[] = Tools::displayError('An error occurred while fetching the county.');
return false;
}
}
// add zip codes
foreach ($xml_county->zipcode AS $xml_zipcode)
{
$zipcode_attributes = $xml_zipcode->attributes();
$zipcodes = $zipcode_attributes['from'];
if (isset($zipcode_attributes['to']))
$zipcodes .= '-'.$zipcode_attributes['to'];
if ($county->isZipCodeRangePresent($zipcodes))
continue;
if (!$county->addZipCodes($zipcodes))
{
$this->_errors[] = Tools::displayError('An error has occurred while adding zipcodes');
return false;
}
}
}
} }
return true; return true;
} }
+3 -2
View File
@@ -286,8 +286,9 @@ class ManufacturerCore extends ObjectModel
LEFT JOIN `'._DB_PREFIX_.'image` i ON (i.`id_product` = p.`id_product` AND i.`cover` = 1) LEFT JOIN `'._DB_PREFIX_.'image` i ON (i.`id_product` = p.`id_product` AND i.`cover` = 1)
LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.') LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.')
LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group` LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group`
AND tr.`id_country` = '.(int)$context->country->id.' AND tr.`id_country` = '.(int)$context->country->id.'
AND tr.`id_state` = 0) AND tr.`id_state` = 0
AND tr.`zipcode_from` = 0)
LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`) LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`)
LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)$id_lang.') LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)$id_lang.')
LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON m.`id_manufacturer` = p.`id_manufacturer` LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON m.`id_manufacturer` = p.`id_manufacturer`
+6 -4
View File
@@ -99,9 +99,12 @@ abstract class PaymentModuleCore extends Module
if ($secure_key !== false AND $secure_key != $cart->secure_key) if ($secure_key !== false AND $secure_key != $cart->secure_key)
die(Tools::displayError()); die(Tools::displayError());
$carrier = new Carrier((int)$cart->id_carrier, (int)$cart->id_lang);
// Copying data from cart // Copying data from cart
$order = new Order(); $order = new Order();
$order->id_carrier = (int)($cart->id_carrier); $order->id_carrier = $carrier->id;
$order->id_customer = (int)($cart->id_customer); $order->id_customer = (int)($cart->id_customer);
$order->id_address_invoice = (int)($cart->id_address_invoice); $order->id_address_invoice = (int)($cart->id_address_invoice);
$order->id_address_delivery = (int)($cart->id_address_delivery); $order->id_address_delivery = (int)($cart->id_address_delivery);
@@ -128,8 +131,8 @@ abstract class PaymentModuleCore extends Module
$order->total_products = (float)($cart->getOrderTotal(false, Cart::ONLY_PRODUCTS)); $order->total_products = (float)($cart->getOrderTotal(false, Cart::ONLY_PRODUCTS));
$order->total_products_wt = (float)($cart->getOrderTotal(true, Cart::ONLY_PRODUCTS)); $order->total_products_wt = (float)($cart->getOrderTotal(true, Cart::ONLY_PRODUCTS));
$order->total_discounts = (float)(abs($cart->getOrderTotal(true, Cart::ONLY_DISCOUNTS))); $order->total_discounts = (float)(abs($cart->getOrderTotal(true, Cart::ONLY_DISCOUNTS)));
$order->total_shipping = (float)($cart->getOrderShippingCost()); $order->total_shipping = (float)$cart->getOrderShippingCost();
$order->carrier_tax_rate = (float)Tax::getCarrierTaxRate($cart->id_carrier, (int)$cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}); $order->carrier_tax_rate = (float)$carrier->getTaxesRate(new Address((int)$cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}));
$order->total_wrapping = (float)(abs($cart->getOrderTotal(true, Cart::ONLY_WRAPPING))); $order->total_wrapping = (float)(abs($cart->getOrderTotal(true, Cart::ONLY_WRAPPING)));
$order->total_paid = (float)(Tools::ps_round((float)($cart->getOrderTotal(true, Cart::BOTH)), 2)); $order->total_paid = (float)(Tools::ps_round((float)($cart->getOrderTotal(true, Cart::BOTH)), 2));
$order->invoice_date = '0000-00-00 00:00:00'; $order->invoice_date = '0000-00-00 00:00:00';
@@ -377,7 +380,6 @@ abstract class PaymentModuleCore extends Module
{ {
$invoice = new Address((int)($order->id_address_invoice)); $invoice = new Address((int)($order->id_address_invoice));
$delivery = new Address((int)($order->id_address_delivery)); $delivery = new Address((int)($order->id_address_delivery));
$carrier = new Carrier((int)($order->id_carrier), $order->id_lang);
$delivery_state = $delivery->id_state ? new State((int)($delivery->id_state)) : false; $delivery_state = $delivery->id_state ? new State((int)($delivery->id_state)) : false;
$invoice_state = $invoice->id_state ? new State((int)($invoice->id_state)) : false; $invoice_state = $invoice->id_state ? new State((int)($invoice->id_state)) : false;
+57 -26
View File
@@ -311,10 +311,13 @@ class ProductCore extends ObjectModel
$this->manufacturer_name = Manufacturer::getNameById((int)$this->id_manufacturer); $this->manufacturer_name = Manufacturer::getNameById((int)$this->id_manufacturer);
$this->supplier_name = Supplier::getNameById((int)$this->id_supplier); $this->supplier_name = Supplier::getNameById((int)$this->id_supplier);
self::$_tax_rules_group[$this->id] = $this->id_tax_rules_group; self::$_tax_rules_group[$this->id] = $this->id_tax_rules_group;
$address = NULL;
if (is_object($context->cart) AND $context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')} != NULL) if (is_object($context->cart) AND $context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')} != NULL)
$this->tax_rate = Tax::getProductTaxRate($this->id, $context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}); $address = $context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')};
else
$this->tax_rate = Tax::getProductTaxRate($this->id, NULL); $this->tax_rate = $this->getTaxesRate(new Address($address));
$this->new = $this->isNew(); $this->new = $this->isNew();
$this->price = Product::getPriceStatic((int)($this->id), false, NULL, 6, NULL, false, true, 1, false, NULL, NULL, NULL, $this->specificPrice); $this->price = Product::getPriceStatic((int)($this->id), false, NULL, 6, NULL, false, true, 1, false, NULL, NULL, NULL, $this->specificPrice);
$this->unit_price = ($this->unit_price_ratio != 0 ? $this->price / $this->unit_price_ratio : 0); $this->unit_price = ($this->unit_price_ratio != 0 ? $this->price / $this->unit_price_ratio : 0);
@@ -405,18 +408,25 @@ class ProductCore extends ObjectModel
)); ));
} }
public static function initPricesComputation($customer = NULL) public static function initPricesComputation($id_customer = NULL)
{ {
if ($customer) if ($id_customer)
{
$customer = new Customer((int)($id_customer));
if (!Validate::isLoadedObject($customer))
die(Tools::displayError());
self::$_taxCalculationMethod = Group::getPriceDisplayMethod((int)($customer->id_default_group)); self::$_taxCalculationMethod = Group::getPriceDisplayMethod((int)($customer->id_default_group));
}
else if (Validate::isLoadedObject(Context::getContext()->customer))
self::$_taxCalculationMethod = Group::getPriceDisplayMethod(Context::getContext()->customer->id_default_group);
else else
self::$_taxCalculationMethod = Group::getDefaultPriceDisplayMethod(); self::$_taxCalculationMethod = Group::getDefaultPriceDisplayMethod();
} }
public static function getTaxCalculationMethod($customer = NULL) public static function getTaxCalculationMethod($id_customer = NULL)
{ {
if ($customer) if ($id_customer)
self::initPricesComputation((int)($customer)); self::initPricesComputation((int)($id_customer));
return (int)(self::$_taxCalculationMethod); return (int)(self::$_taxCalculationMethod);
} }
@@ -1680,7 +1690,7 @@ class ProductCore extends ObjectModel
// retrieve address informations // retrieve address informations
$id_country = (int)$context->country->id; $id_country = (int)$context->country->id;
$id_state = 0; $id_state = 0;
$id_county = 0; $zipcode = 0;
if (!$id_address) if (!$id_address)
$id_address = $cur_cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}; $id_address = $cur_cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')};
@@ -1692,18 +1702,14 @@ class ProductCore extends ObjectModel
{ {
$id_country = (int)($address_infos['id_country']); $id_country = (int)($address_infos['id_country']);
$id_state = (int)($address_infos['id_state']); $id_state = (int)($address_infos['id_state']);
$postcode = (int)$address_infos['postcode']; $zipcode = $address_infos['postcode'];
$id_county = (int)County::getIdCountyByZipCode($id_state, $postcode);
} }
} }
elseif (isset($context->customer->geoloc_id_country)) elseif (isset($context->customer->geoloc_id_country))
{ {
$id_country = (int)$context->customer->geoloc_id_country; $id_country = (int)$context->customer->geoloc_id_country;
$id_state = (int)$context->customer->id_state; $id_state = (int)$context->customer->id_state;
$postcode = (int)$context->customer->postcode; $zipcode = (int)$context->customer->postcode;
$id_county = (int)County::getIdCountyByZipCode($id_state, $postcode);
} }
if (Tax::excludeTaxeOption()) if (Tax::excludeTaxeOption())
@@ -1712,7 +1718,7 @@ class ProductCore extends ObjectModel
if ($usetax != false AND !empty($address_infos['vat_number']) AND $address_infos['id_country'] != Configuration::get('VATNUMBER_COUNTRY') AND Configuration::get('VATNUMBER_MANAGEMENT')) if ($usetax != false AND !empty($address_infos['vat_number']) AND $address_infos['id_country'] != Configuration::get('VATNUMBER_COUNTRY') AND Configuration::get('VATNUMBER_MANAGEMENT'))
$usetax = false; $usetax = false;
return Product::priceCalculation($context->shop->getID(), $id_product, $id_product_attribute, $id_country, $id_state, $id_county, $id_currency, $id_group, $quantity, $usetax, $decimals, $only_reduc, return Product::priceCalculation($context->shop->getID(), $id_product, $id_product_attribute, $id_country, $id_state, $zipcode, $id_currency, $id_group, $quantity, $usetax, $decimals, $only_reduc,
$usereduc, $with_ecotax, $specificPriceOutput, $use_groupReduction); $usereduc, $with_ecotax, $specificPriceOutput, $use_groupReduction);
} }
@@ -1733,16 +1739,17 @@ class ProductCore extends ObjectModel
* @param boolean $use_reduc Set if the returned amount will include reduction * @param boolean $use_reduc Set if the returned amount will include reduction
* @param boolean $with_ecotax insert ecotax in price output. * @param boolean $with_ecotax insert ecotax in price output.
* @param variable_reference $specific_price_output If a specific price applies regarding the previous parameters, this variable is filled with the corresponding SpecificPrice object * @param variable_reference $specific_price_output If a specific price applies regarding the previous parameters, this variable is filled with the corresponding SpecificPrice object
*
* @return float Product price * @return float Product price
**/ **/
public static function priceCalculation($id_shop, $id_product, $id_product_attribute, $id_country, $id_state, $id_county, $id_currency, $id_group, $quantity, $use_tax, $decimals, $only_reduc, $use_reduc, $with_ecotax, &$specific_price, $use_groupReduction) public static function priceCalculation($id_shop, $id_product, $id_product_attribute, $id_country, $id_state, $zipcode, $id_currency, $id_group, $quantity, $use_tax, $decimals, $only_reduc, $use_reduc, $with_ecotax, &$specific_price, $use_groupReduction)
{ {
// Caching // Caching
if ($id_product_attribute === NULL) if ($id_product_attribute === NULL)
$product_attribute_label = 'NULL'; $product_attribute_label = 'NULL';
else else
$product_attribute_label = ($id_product_attribute === false ? 'false' : $id_product_attribute); $product_attribute_label = ($id_product_attribute === false ? 'false' : $id_product_attribute);
$cacheId = $id_product.'-'.$id_shop.'-'.$id_currency.'-'.$id_country.'-'.$id_state.'-'.$id_county.'-'.$id_group.'-'.$quantity.'-'.$product_attribute_label.'-'.($use_tax?'1':'0').'-'.$decimals.'-'.($only_reduc?'1':'0').'-'.($use_reduc?'1':'0').'-'.$with_ecotax; $cacheId = $id_product.'-'.$id_shop.'-'.$id_currency.'-'.$id_country.'-'.$id_state.'-'.$zipcode.'-'.$id_group.'-'.$quantity.'-'.$product_attribute_label.'-'.($use_tax?'1':'0').'-'.$decimals.'-'.($only_reduc?'1':'0').'-'.($use_reduc?'1':'0').'-'.$with_ecotax;
// reference parameter is filled before any returns // reference parameter is filled before any returns
$specific_price = SpecificPrice::getSpecificPrice((int)($id_product), $id_shop, $id_currency, $id_country, $id_group, $quantity); $specific_price = SpecificPrice::getSpecificPrice((int)($id_product), $id_shop, $id_currency, $id_country, $id_group, $quantity);
@@ -1773,14 +1780,18 @@ class ProductCore extends ObjectModel
if ($id_product_attribute !== false) // If you want the default combination, please use NULL value instead if ($id_product_attribute !== false) // If you want the default combination, please use NULL value instead
$price += $attribute_price; $price += $attribute_price;
// TaxRate calculation // Tax
$tax_rate = Tax::getProductTaxRateViaRules((int)$id_product, (int)$id_country, (int)$id_state, (int)$id_county); $address = new Address();
if ($tax_rate === false) $address->id_country = $id_country;
$tax_rate = 0; $address->id_state = $id_state;
$address->postcode = $zipcode;
$tax_manager = TaxManagerFactory::getManager($address, Product::getIdTaxRulesGroupByIdProduct((int)$id_product));
$product_tax_calculator = $tax_manager->getTaxCalculator();
// Add Tax // Add Tax
if ($use_tax) if ($use_tax)
$price = $price * (1 + ($tax_rate / 100)); $price = $product_tax_calculator->addTaxes($price);
$price = Tools::ps_round($price, $decimals); $price = Tools::ps_round($price, $decimals);
// Reduction // Reduction
@@ -1793,7 +1804,7 @@ class ProductCore extends ObjectModel
if (!$specific_price['id_currency']) if (!$specific_price['id_currency'])
$reduction_amount = Tools::convertPrice($reduction_amount, $id_currency); $reduction_amount = Tools::convertPrice($reduction_amount, $id_currency);
$reduc = Tools::ps_round(!$use_tax ? $reduction_amount / (1 + $tax_rate / 100) : $reduction_amount, $decimals); $reduc = Tools::ps_round(!$use_tax ? $product_tax_calculator->removeTax($reduction_amount) : $reduction_amount, $decimals);
} }
else else
$reduc = Tools::ps_round($price * $specific_price['reduction'], $decimals); $reduc = Tools::ps_round($price * $specific_price['reduction'], $decimals);
@@ -1825,8 +1836,13 @@ class ProductCore extends ObjectModel
$ecotax = Tools::convertPrice($ecotax, $id_currency); $ecotax = Tools::convertPrice($ecotax, $id_currency);
if ($use_tax) if ($use_tax)
{ {
$taxRate = TaxRulesGroup::getTaxesRate((int)Configuration::get('PS_ECOTAX_TAX_RULES_GROUP_ID'), (int)$id_country, (int)$id_state, (int)$id_county); // reinit the tax manager for ecotax handling
$price += $ecotax * (1 + ($taxRate / 100)); $tax_manager = TaxManagerFactory::getManager(
$address,
(int)Configuration::get('PS_ECOTAX_TAX_RULES_GROUP_ID')
);
$ecotax_tax_calculator = $tax_manager->getTaxCalculator();
$price += $ecotax_tax_calculator->addTaxes($ecotax);
} }
else else
$price += $ecotax; $price += $ecotax;
@@ -2103,6 +2119,7 @@ class ProductCore extends ObjectModel
WHERE id_product = '.$this->id.' WHERE id_product = '.$this->id.'
AND id_product_attribute = '.(int)$id_product_attribute AND id_product_attribute = '.(int)$id_product_attribute
.$context->shop->sqlRestriction(Shop::SHARE_STOCK); .$context->shop->sqlRestriction(Shop::SHARE_STOCK);
self::$cacheStock[$this->id][$id_product_attribute] = (int)Db::getInstance()->getValue($sql); self::$cacheStock[$this->id][$id_product_attribute] = (int)Db::getInstance()->getValue($sql);
} }
return self::$cacheStock[$this->id][$id_product_attribute]; return self::$cacheStock[$this->id][$id_product_attribute];
@@ -3155,6 +3172,20 @@ class ProductCore extends ObjectModel
return self::$_tax_rules_group[$id_product]; return self::$_tax_rules_group[$id_product];
} }
/**
* @return the total taxes rate applied to the product
*/
public function getTaxesRate(Address $address = NULL)
{
if (!$address OR !$address->id_country)
$address = Tax::initializeAddress();
$tax_manager = TaxManagerFactory::getManager($address, $this->id_tax_rules_group);
$tax_calculator = $tax_manager->getTaxCalculator();
return $tax_calculator->getTaxesRate();
}
/** /**
* Webservice getter : get product features association * Webservice getter : get product features association
* *
+2 -1
View File
@@ -223,7 +223,8 @@ class SupplierCore extends ObjectModel
LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)($id_lang).') LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)($id_lang).')
LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group` LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group`
AND tr.`id_country` = '.(int)Context::getContext()->country->id.' AND tr.`id_country` = '.(int)Context::getContext()->country->id.'
AND tr.`id_state` = 0) AND tr.`id_state` = 0
AND tr.`zipcode_from` = 0)
LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`) LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`)
LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)($id_lang).') LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)($id_lang).')
LEFT JOIN `'._DB_PREFIX_.'supplier` s ON s.`id_supplier` = p.`id_supplier` LEFT JOIN `'._DB_PREFIX_.'supplier` s ON s.`id_supplier` = p.`id_supplier`
+140 -132
View File
@@ -74,138 +74,6 @@ class TaxCore extends ObjectModel
return parent::delete(); return parent::delete();
} }
/**
* Get all available taxes
*
* @return array Taxes
*/
public static function getTaxes($id_lang = false, $active = 1)
{
return Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS('
SELECT t.id_tax, t.rate'.((int)($id_lang) ? ', tl.name, tl.id_lang ' : '').'
FROM `'._DB_PREFIX_.'tax` t
'.((int)($id_lang) ? 'LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)($id_lang).')'
.($active == 1 ? 'WHERE t.`active` = 1' : '').'
ORDER BY `name` ASC' : ''));
}
public static function excludeTaxeOption()
{
return !Configuration::get('PS_TAX');
}
public static function getTaxIdByName($tax_name, $active = 1)
{
$tax = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow('
SELECT t.`id_tax`
FROM `'._DB_PREFIX_.'tax` t
LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (tl.id_tax = t.id_tax)
WHERE tl.`name` = \''.pSQL($tax_name).'\' '.
($active == 1 ? ' AND t.`active` = 1' : ''));
return $tax ? (int)($tax['id_tax']) : false;
}
/**
* Return the product tax
*
* @param integer $id_product
* @param integer $id_country
* @return Tax
*/
public static function getProductTaxRate($id_product, $id_address = NULL)
{
$id_country = (int)Context::getContext()->country->id;
$id_state = 0;
$id_county = 0;
$rate = 0;
if (!empty($id_address))
{
$address_infos = Address::getCountryAndState($id_address);
if ($address_infos['id_country'])
{
$id_country = (int)($address_infos['id_country']);
$id_state = (int)$address_infos['id_state'];
$id_county = (int)County::getIdCountyByZipCode($address_infos['id_state'], $address_infos['postcode']);
}
if (!empty($address_infos['vat_number']) AND $address_infos['id_country'] != Configuration::get('VATNUMBER_COUNTRY') AND Configuration::get('VATNUMBER_MANAGEMENT'))
return 0;
}
if ($rate = Tax::getProductTaxRateViaRules((int)$id_product, (int)$id_country, (int)$id_state, (int)$id_county))
return $rate;
return $rate;
}
public static function getProductEcotaxRate($id_address = NULL)
{
$id_country = (int)Context::getContext()->country->id;
$id_state = 0;
$id_county = 0;
$rate = 0;
if (!empty($id_address))
{
$address_infos = Address::getCountryAndState($id_address);
if ($address_infos['id_country'])
{
$id_country = (int)($address_infos['id_country']);
$id_state = (int)$address_infos['id_state'];
$id_county = (int)County::getIdCountyByZipCode($address_infos['id_state'], $address_infos['postcode']);
}
if (!empty($address_infos['vat_number']) AND $address_infos['id_country'] != Configuration::get('VATNUMBER_COUNTRY') AND Configuration::get('VATNUMBER_MANAGEMENT'))
return 0;
}
if ($rate = TaxRulesGroup::getTaxesRate((int)Configuration::get('PS_ECOTAX_TAX_RULES_GROUP_ID'), (int)$id_country, (int)$id_state, (int)$id_county))
return $rate;
return $rate;
}
/**
* Return the product tax rate using the tax rules system
*
* @param integer $id_product
* @param integer $id_country
* @return Tax
*/
public static function getProductTaxRateViaRules($id_product, $id_country, $id_state, $id_county)
{
if (!isset(self::$_product_tax_via_rules[$id_product.'-'.$id_country.'-'.$id_state.'-'.$id_county]))
{
$tax_rate = TaxRulesGroup::getTaxesRate((int)Product::getIdTaxRulesGroupByIdProduct((int)$id_product), (int)$id_country, (int)$id_state, (int)$id_county);
self::$_product_tax_via_rules[$id_product.'-'.$id_country.'-'.$id_county] = $tax_rate;
}
return self::$_product_tax_via_rules[$id_product.'-'.$id_country.'-'.$id_county];
}
public static function getCarrierTaxRate($id_carrier, $id_address = NULL)
{
$id_country = (int)Context::getContext()->country->id;
$id_state = 0;
$id_county = 0;
if (!empty($id_address))
{
$address_infos = Address::getCountryAndState($id_address);
if ($address_infos['id_country'])
{
$id_country = (int)($address_infos['id_country']);
$id_state = (int)$address_infos['id_state'];
$id_county = (int)County::getIdCountyByZipCode($address_infos['id_state'], $address_infos['postcode']);
}
if (!empty($address_infos['vat_number']) AND $address_infos['id_country'] != Configuration::get('VATNUMBER_COUNTRY') AND Configuration::get('VATNUMBER_MANAGEMENT'))
return 0;
}
return TaxRulesGroup::getTaxesRate((int)Carrier::getIdTaxRulesGroupByIdCarrier((int)$id_carrier), (int)$id_country, (int)$id_state, (int)$id_county);
}
public function toggleStatus() public function toggleStatus()
{ {
if (parent::toggleStatus()) if (parent::toggleStatus())
@@ -229,5 +97,145 @@ class TaxCore extends ObjectModel
return true; return true;
} }
/**
* Get all available taxes
*
* @return array Taxes
*/
public static function getTaxes($id_lang = false, $active = 1)
{
return Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS('
SELECT t.id_tax, t.rate'.((int)($id_lang) ? ', tl.name, tl.id_lang ' : '').'
FROM `'._DB_PREFIX_.'tax` t
'.((int)($id_lang) ? 'LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)($id_lang).')'
.($active == 1 ? 'WHERE t.`active` = 1' : '').'
ORDER BY `name` ASC' : ''));
}
public static function excludeTaxeOption()
{
return !Configuration::get('PS_TAX');
}
/**
* Return the tax id associated to the specified name
*
* @param string $tax_name
* @param boolean $active (true by default)
*/
public static function getTaxIdByName($tax_name, $active = 1)
{
$tax = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow('
SELECT t.`id_tax`
FROM `'._DB_PREFIX_.'tax` t
LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (tl.id_tax = t.id_tax)
WHERE tl.`name` = \''.pSQL($tax_name).'\' '.
($active == 1 ? ' AND t.`active` = 1' : ''));
return $tax ? (int)($tax['id_tax']) : false;
}
/**
* Returns the product tax
*
* @param integer $id_product
* @param integer $id_country
* @return Tax
*
* @deprecated use $product->getTaxesRate() instead
*/
public static function getProductTaxRate($id_product, $id_address = NULL)
{
$address = Tax::initializeAddress($id_address);
$id_tax_rules = (int)Product::getIdTaxRulesGroupByIdProduct($id_product);
$tax_manager = TaxManagerFactory::getManager($address, $id_tax_rules);
$tax_calculator = $tax_manager->getTaxCalculator();
return $tax_calculator->getTaxesRate();
}
/**
* Returns the ecotax tax rate
*
* @param id_address
* @return float $tax_rate
*/
public static function getProductEcotaxRate($id_address = NULL)
{
$address = Tax::initializeAddress($id_address);
$tax_manager = TaxManagerFactory::getManager($address, (int)Configuration::get('PS_ECOTAX_TAX_RULES_GROUP_ID'));
$tax_calculator = $tax_manager->getTaxCalculator();
return $tax_calculator->getTaxesRate();
}
/**
* Returns the carrier tax rate
*
* @param id_address
* @return float $tax_rate
*/
public static function getCarrierTaxRate($id_carrier, $id_address = NULL)
{
$address = Tax::initializeAddress($id_address);
$id_tax_rules = (int)Carrier::getIdTaxRulesGroupByIdCarrier((int)$id_carrier);
$tax_manager = TaxManagerFactory::getManager($address, $id_tax_rules);
$tax_calculator = $tax_manager->getTaxCalculator();
return $tax_calculator->getTaxesRate();
}
/**
* Initiliaze an address corresponding to the id address if any or to the
* default shop configuration
*
* @param int $id_address
* @return Address address
*/
public static function initializeAddress($id_address = NULL)
{
// set the default address
$address = new Address();
$address->id_country = (int)Context::getContext()->country->id;
$address->id_state = 0;
$address->postcode = 0;
// if an id_address has been specified retrieve the address
if ($id_address)
{
$address = new Address((int)$id_address);
if (!Validate::isLoadedObject())
throw new Exception('Invalid address');
}
return $address;
}
/**
* Return the product tax rate using the tax rules system
*
* @param integer $id_product
* @param integer $id_country
* @return Tax
*
* @deprecated since 1.5
*/
public static function getProductTaxRateViaRules($id_product, $id_country, $id_state, $zipcode)
{
Tools::displayAsDeprecated();
if (!isset(self::$_product_tax_via_rules[$id_product.'-'.$id_country.'-'.$id_state.'-'.$zipcode]))
{
$tax_rate = TaxRulesGroup::getTaxesRate((int)Product::getIdTaxRulesGroupByIdProduct((int)$id_product), (int)$id_country, (int)$id_state, $zipcode);
self::$_product_tax_via_rules[$id_product.'-'.$id_country.'-'.$zipcode] = $tax_rate;
}
return self::$_product_tax_via_rules[$id_product.'-'.$id_country.'-'.$zipcode];
}
} }
+144
View File
@@ -0,0 +1,144 @@
<?php
/*
* 2007-2011 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2011 PrestaShop SA
* @version Release: $Revision$
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @since 1.5.0
*
* TaxCaculator is responsible of the tax computation
*/
class TaxCalculatorCore
{
/**
* COMBINE_METHOD sum taxes
* eg: 100€ * (10% + 15%)
*/
const COMBINE_METHOD = 1;
/**
* ONE_AFTER_ANOTHER_METHOD apply taxes one after another
* eg: (100€ * 10%) * 15%
*/
const ONE_AFTER_ANOTHER_METHOD = 2;
/**
* @var array $taxes_rate
*/
public $taxes_rate;
/**
* @var int $computation_method (COMBINE_METHOD | ONE_AFTER_ANOTHER_METHOD)
*/
public $computation_method;
/**
* @param array $taxes_rate
* @param int $computation_method (COMBINE_METHOD | ONE_AFTER_ANOTHER_METHOD)
*/
public function __construct(array $taxes_rate, $computation_method = TaxCalculator::COMBINE_METHOD)
{
$this->taxes_rate = $taxes_rate;
$this->computation_method = (int)$computation_method;
}
/**
* Compute and add the taxes to the specified price
*
* @param price
* @return price with taxes
*/
public function addTaxes($price)
{
$total_price = $price;
if ($this->computation_method == TaxCalculator::ONE_AFTER_ANOTHER_METHOD)
{
foreach ($this->taxes_rate as $tax_rate)
$total_price = $total_price * (1 + abs($tax_rate) / 100);
}
else
{
foreach ($this->taxes_rate as $tax_rate)
{
if ($tax_rate != 0)
$total_price = $total_price + ($price * (abs($tax_rate) / 100));
}
}
return $total_price;
}
/**
* Compute and remove the taxes to the specified price
*
* @param price
* @return price without taxes
*/
public function removeTaxes($price)
{
$total_price = $price;
if ($this->computation_method == TaxCalculator::ONE_AFTER_ANOTHER_METHOD)
{
foreach ($this->taxes_rate as $tax_rate)
$total_price = $total_price / (1 + abs($tax_rate) / 100);
}
else
{
$taxes_rate = 0;
foreach ($this->taxes_rate as $tax_rate)
$taxes_rate += abs($tax_rate);
$total_price = $total_price / (1 + (abs($taxes_rate) / 100));
}
return $total_price;
}
/**
* @return total taxes rate
*/
public function getTaxesRate()
{
$taxes_rate = 0;
if ($this->computation_method == TaxCalculator::ONE_AFTER_ANOTHER_METHOD)
{
$taxes_rate = 1;
foreach ($this->taxes_rate as $rate)
$taxes_rate *= (1 + (abs($rate) / 100));
$taxes_rate = $taxes_rate - 1;
$taxes_rate = $taxes_rate * 100;
}
else
{
foreach ($this->taxes_rate as $rate)
$taxes_rate += abs($rate);
}
return $taxes_rate;
}
}
+103
View File
@@ -0,0 +1,103 @@
<?php
/*
* 2007-2011 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2011 PrestaShop SA
* @version Release: $Revision$
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @since 1.5
*/
class TaxManagerFactoryCore
{
protected static $cache_tax_manager;
/**
* Returns a tax manager able to handle this address
*
* @param Address $address
* @param string $type
*
* @return TaxManager
*/
public static function getManager(Address $address, $type)
{
$cache_id = TaxManagerFactory::getCacheKey($address).'-'.$type;
if (!isset(TaxManagerFactory::$cache_tax_manager[$cache_id]))
{
$tax_manager = TaxManagerFactory::execHookTaxManagerFactory($address, $type);
if (!($tax_manager instanceof TaxManagerInterface))
$tax_manager = new TaxRulesTaxManager($address, $type);
TaxManagerFactory::$cache_tax_manager[$cache_id] = $tax_manager;
}
return TaxManagerFactory::$cache_tax_manager[$cache_id];
}
/**
* Check for a tax manager able to handle this type of address in the module list
*
* @param Address $address
* @param string $type
*
* @return TaxManager
*/
public static function execHookTaxManagerFactory(Address $address, $type)
{
$modules_infos = Hook::getModulesFromHook(Hook::getIdByName('taxManager'));
$tax_manager = false;
foreach ($modules_infos as $module_infos)
{
$module_instance = Module::getInstanceByName($module_infos['name']);
if (is_callable(array($module_instance, 'hookTaxManager')))
{
$tax_manager = $module_instance->hookTaxManager(array(
'address' => $address,
'params' => $type
));
}
if ($tax_manager)
break;
}
return $tax_manager;
}
/**
* Create a unique identifier for the address
* @param Address
*/
protected static function getCacheKey(Address $address)
{
return $address->id_country.'-'
.(int)$address->id_state.'-'
.$address->postcode.'-'
.$address->vat_number.'-'
.$address->dni;
}
}
+51
View File
@@ -0,0 +1,51 @@
<?php
/*
* 2007-2011 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2011 PrestaShop SA
* @version Release: $Revision$
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* A TaxManager define a way to retrieve tax.
*/
interface TaxManagerInterface
{
/**
* This method determine if the tax manager is available for the specified address.
*
* @param Address $address
* @param string $type
*
* @return TaxManager
*/
public static function isAvailableForThisAddress(Address $address);
/**
* Return the tax calculator associated to this address
*
* @return TaxCalculator
*/
public function getTaxCalculator();
}
+57
View File
@@ -0,0 +1,57 @@
<?php
/*
* 2007-2011 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2011 PrestaShop SA
* @version Release: $Revision$
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
abstract class TaxManagerModuleCore extends Module
{
public $tax_manager_class;
public function install()
{
return (parent::install() && $this->registerHook('taxManager') );
}
public function hookTaxManager($args)
{
$class_file =_PS_MODULE_DIR_.'/'.$this->name.'/'.$this->tax_manager_class.'.php';
if (!isset($this->tax_manager_class) || !file_exists($class_file))
die(Tools::displayError('Incorrect Tax Manager class ['.$this->tax_manager_class.']'));
require_once($class_file);
if (!class_exists($this->tax_manager_class))
die(Tools::displayError('Tax Manager class not found ['.$this->tax_manager_class.']'));
$class = $this->tax_manager_class;
if ($class::isAvailableForThisAddress($args['address']))
return new $class();
return false;
}
}
+86 -18
View File
@@ -30,13 +30,21 @@ class TaxRuleCore extends ObjectModel
public $id_tax_rules_group; public $id_tax_rules_group;
public $id_country; public $id_country;
public $id_state; public $id_state;
public $id_county; public $zipcode_from;
public $zipcode_to;
public $id_tax; public $id_tax;
public $state_behavior; public $behavior;
public $county_behavior; public $description;
protected $fieldsRequired = array('id_tax_rules_group', 'id_country', 'id_tax'); protected $fieldsRequired = array('id_tax_rules_group', 'id_country', 'id_tax');
protected $fieldsValidate = array('id_tax_rules_group' => 'isUnsignedId', 'id_country' => 'isUnsignedId', 'id_state' => 'isUnsignedId', 'id_county' => 'isUnsignedId', 'id_tax' => 'isUnsignedId', 'state_behavior' => 'isUnsignedInt', 'county_behavior' => 'isUnsignedInt'); protected $fieldsValidate = array('id_tax_rules_group' => 'isUnsignedId',
'id_country' => 'isUnsignedId',
'id_state' => 'isUnsignedId',
'zipcode_from' => 'isUnsignedId', // TODO: char
'zipcode_to' => 'isUnsignedId', // TODO: char
'id_tax' => 'isUnsignedId',
'behavior' => 'isUnsignedInt',
'description' => 'isUnsignedInt'); // TODO:char
protected $table = 'tax_rule'; protected $table = 'tax_rule';
protected $identifier = 'id_tax_rule'; protected $identifier = 'id_tax_rule';
@@ -47,10 +55,11 @@ class TaxRuleCore extends ObjectModel
$fields['id_tax_rules_group'] = (int)($this->id_tax_rules_group); $fields['id_tax_rules_group'] = (int)($this->id_tax_rules_group);
$fields['id_country'] = (int)$this->id_country; $fields['id_country'] = (int)$this->id_country;
$fields['id_state'] = (int)$this->id_state; $fields['id_state'] = (int)$this->id_state;
$fields['id_county'] = (int)$this->id_county; $fields['zipcode_from'] = (int)$this->zipcode_from;
$fields['state_behavior'] = (int)$this->state_behavior; $fields['zipcode_to'] = (int)$this->zipcode_to;
$fields['county_behavior'] = (int)$this->county_behavior; $fields['behavior'] = (int)$this->behavior;
$fields['id_tax'] = (int)($this->id_tax); $fields['id_tax'] = (int)($this->id_tax);
$fields['description'] = $this->description;
return $fields; return $fields;
} }
@@ -66,23 +75,44 @@ class TaxRuleCore extends ObjectModel
); );
} }
public static function retrieveById($id_tax_rule)
{
return Db::getInstance()->getRow('
SELECT * FROM `'._DB_PREFIX_.'tax_rule`
WHERE `id_tax_rule` = '.(int)$id_tax_rule);
}
/*
public static function getTaxRulesByGroupId($id_group) public static function getTaxRulesByGroupId($id_group)
{ {
if (empty($id_group)) if (empty($id_group))
die(Tools::displayError()); die(Tools::displayError());
$results = Db::getInstance()->ExecuteS(' return Db::getInstance()->ExecuteS('
SELECT * SELECT *
FROM `'._DB_PREFIX_.'tax_rule` FROM `'._DB_PREFIX_.'tax_rule`
WHERE `id_tax_rules_group` = '.(int)$id_group WHERE `id_tax_rules_group` = '.(int)$id_group
); );
}*/
$res = array(); public static function getTaxRulesByGroupId($id_lang, $id_group)
foreach ($results AS $row) {
$res[$row['id_country']][$row['id_state']][$row['id_county']] = array('id_tax' => $row['id_tax'], 'state_behavior' => $row['state_behavior'], 'county_behavior' => $row['county_behavior']);
return $res;
} return Db::getInstance()->ExecuteS('
SELECT g.`id_tax_rule`,
c.`name` AS country_name,
s.`name` AS state_name,
t.rate,
g.`zipcode_from`, g.`zipcode_to`,
g.`description`,
g.`behavior`
FROM `'._DB_PREFIX_.'tax_rule` g
LEFT JOIN `'._DB_PREFIX_.'country_lang` c ON (g.`id_country` = c.`id_country` AND id_lang = '.(int)$id_lang.')
LEFT JOIN `'._DB_PREFIX_.'state` s ON (g.`id_state` = s.`id_state`)
LEFT JOIN `'._DB_PREFIX_.'tax` t ON (g.`id_tax` = t.`id_tax`)
WHERE `id_tax_rules_group` = '.(int)$id_group
);
}
public static function deleteTaxRuleByIdTax($id_tax) public static function deleteTaxRuleByIdTax($id_tax)
{ {
@@ -93,19 +123,57 @@ class TaxRuleCore extends ObjectModel
} }
/**
* @deprecated since 1.5
*/
public static function deleteTaxRuleByIdCounty($id_county) public static function deleteTaxRuleByIdCounty($id_county)
{ {
return Db::getInstance()->Execute(' Tools::displayAsDeprecated();
DELETE FROM `'._DB_PREFIX_.'tax_rule` return true;
WHERE `id_county` = '.(int)$id_county
);
} }
/**
* @param int $id_tax
* @return boolean
*/
public static function isTaxInUse($id_tax) public static function isTaxInUse($id_tax)
{ {
return Db::getInstance()->getValue(' return Db::getInstance()->getValue('
SELECT COUNT(*) FROM `'._DB_PREFIX_.'tax_rule` WHERE `id_tax` = '.(int)$id_tax SELECT COUNT(*) FROM `'._DB_PREFIX_.'tax_rule` WHERE `id_tax` = '.(int)$id_tax
); );
} }
/**
* @param string $zipcode a range of zipcode (eg: 75000 / 75000-75015)
* @return array an array containing two zipcode ordered by zipcode
*/
public function breakDownZipCode($zip_codes)
{
$zip_codes = preg_split('/-/', $zip_codes);
if (sizeof($zip_codes) == 2)
{
$from = $zip_codes[0];
$to = $zip_codes[1];
if ($zip_codes[0] > $zip_codes[1])
{
$from = $zip_codes[1];
$to = $zip_codes[0];
}
elseif ($zip_codes[0] == $zip_codes[1])
{
$from = $zip_codes[0];
$to = 0;
}
}
elseif (sizeof($zip_codes) == 1)
{
$from = $zip_codes[0];
$to = 0;
}
return array($from, $to);
}
} }
@@ -59,74 +59,19 @@ class TaxRulesGroupCore extends ObjectModel
); );
} }
/**
* @return array an array of tax rules group formatted as $id => $name
*/
public static function getTaxRulesGroupsForOptions() public static function getTaxRulesGroupsForOptions()
{ {
$tax_rules[] = array('id_tax_rules_group' => 0, 'name' => Tools::displayError('No tax')); $tax_rules[] = array('id_tax_rules_group' => 0, 'name' => Tools::displayError('No tax'));
return array_merge($tax_rules, TaxRulesGroup::getTaxRulesGroups()); return array_merge($tax_rules, TaxRulesGroup::getTaxRulesGroups());
} }
public static function getTaxes($id_tax_rules_group, $id_country, $id_state, $id_county)
{
if (empty($id_tax_rules_group) OR empty($id_country))
return array(new Tax()); // No Tax
if (isset(self::$_taxes[$id_tax_rules_group.'-'.$id_country.'-'.$id_state.'-'.$id_county]))
return self::$_taxes[$id_tax_rules_group.'-'.$id_country.'-'.$id_state.'-'.$id_county];
$rows = Db::getInstance()->ExecuteS('
SELECT *
FROM `'._DB_PREFIX_.'tax_rule`
WHERE `id_country` = '.(int)$id_country.'
AND `id_tax_rules_group` = '.(int)$id_tax_rules_group.'
AND `id_state` IN (0, '.(int)$id_state.')
AND `id_county` IN (0, '.(int)$id_county.')
ORDER BY `id_county` DESC, `id_state` DESC'
);
$taxes = array();
foreach ($rows AS $row)
{
if ($row['id_county'] != 0)
{
switch($row['county_behavior'])
{
case County::USE_BOTH_TAX:
$taxes[] = new Tax($row['id_tax']);
break;
case County::USE_COUNTY_TAX:
$taxes = array(new Tax($row['id_tax']));
break 2;
case County::USE_STATE_TAX: // do nothing
break;
}
}
else if ($row['id_state'] != 0)
{
switch($row['state_behavior'])
{
case PS_STATE_TAX: // use only product tax
$taxes[] = new Tax($row['id_tax']);
break 2; // switch + foreach
case PS_BOTH_TAX:
$taxes[] = new Tax($row['id_tax']);
break;
case PS_PRODUCT_TAX: // do nothing use country tax
break;
}
}
else
$taxes[] = new Tax((int)$row['id_tax']);
}
self::$_taxes[$id_tax_rules_group.'-'.$id_country.'-'.$id_state.'-'.$id_county] = $taxes;
return $taxes;
}
/**
* @return array
*/
public static function getAssociatedTaxRatesByIdCountry($id_country) public static function getAssociatedTaxRatesByIdCountry($id_country)
{ {
$rows = Db::getInstance()->ExecuteS(' $rows = Db::getInstance()->ExecuteS('
@@ -136,7 +81,7 @@ class TaxRulesGroupCore extends ObjectModel
LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`) LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`)
WHERE tr.`id_country` = '.(int)$id_country.' WHERE tr.`id_country` = '.(int)$id_country.'
AND tr.`id_state` = 0 AND tr.`id_state` = 0
AND tr.`id_county` = 0' AND 0 between `zipcode_from` AND `zipcode_to`'
); );
$res = array(); $res = array();
@@ -146,15 +91,12 @@ class TaxRulesGroupCore extends ObjectModel
return $res; return $res;
} }
public static function getTaxesRate($id_tax_rules_group, $id_country, $id_state, $id_county) /**
{ * Returns the tax rules group id corresponding to the name
$rate = 0; *
foreach (TaxRulesGroup::getTaxes($id_tax_rules_group, $id_country, $id_state, $id_county) AS $tax) * @param string name
$rate += (float)$tax->rate; * @return int id of the tax rules
*/
return $rate;
}
public static function getIdByName($name) public static function getIdByName($name)
{ {
return Db::getInstance()->getValue( return Db::getInstance()->getValue(
@@ -163,4 +105,29 @@ class TaxRulesGroupCore extends ObjectModel
WHERE `name` = \''.pSQL($name).'\'' WHERE `name` = \''.pSQL($name).'\''
); );
} }
/**
* @deprecated since 1.5
*/
public static function getTaxesRate($id_tax_rules_group, $id_country, $id_state, $zipcode)
{
Tools::displayAsDeprecated();
$rate = 0;
foreach (TaxRulesGroup::getTaxes($id_tax_rules_group, $id_country, $id_state, $zipcode) AS $tax)
$rate += (float)$tax->rate;
return $rate;
}
/**
* Return taxes associated to this para
* @deprecated since 1.5
*/
public static function getTaxes($id_tax_rules_group, $id_country, $id_state, $id_county)
{
Tools::displayAsDeprecated();
return array();
}
} }
+101
View File
@@ -0,0 +1,101 @@
<?php
/*
* 2007-2011 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2011 PrestaShop SA
* @version Release: $Revision$
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
class TaxRulesTaxManagerCore implements TaxManagerInterface
{
public $address;
public $type;
public $tax_calculator;
public function __construct(Address $address, $type)
{
$this->address = $address;
$this->type = $type;
}
/**
* Returns true if this tax manager is available for this address
*
* @return boolean
*/
public static function isAvailableForThisAddress(Address $address)
{
return true; // default manager, available for all addresses
}
/**
* Return the tax calculator associated to this address
*
* @return TaxCalculator
*/
public function getTaxCalculator()
{
if (isset($this->tax_calculator))
return $this->tax_calculator;
$postcode = 0;
if (!empty($this->address->postcode))
$postcode = $this->address->postcode;
$rows = Db::getInstance()->ExecuteS('
SELECT *
FROM `'._DB_PREFIX_.'tax_rule`
WHERE `id_country` = '.(int)$this->address->id_country.'
AND `id_tax_rules_group` = '.(int)$this->type.'
AND `id_state` IN (0, '.(int)$this->address->id_state.')
AND ('.pSQL($postcode).' BETWEEN `zipcode_from` AND `zipcode_to` OR `zipcode_from` = 0 OR `zipcode_from` = '.pSQL($postcode).')
ORDER BY `zipcode_from` DESC, `zipcode_to` DESC, `id_state` DESC, `id_country` DESC');
$behavior = 0;
$first_row = true;
$taxes_rates = array();
foreach ($rows as $row)
{
$tax = new Tax((int)$row['id_tax']);
$taxes_rates[] = $tax->rate;
// the applied behavior correspond to the most specific rules
if ($first_row)
{
$behavior = $row['behavior'];
$first_row = false;
}
if ($row['behavior'] == 0)
break;
}
$this->tax_calculator = new TaxCalculator($taxes_rates, $behavior);
return $this->tax_calculator;
}
}
+1 -1
View File
@@ -189,7 +189,7 @@ class ProductControllerCore extends FrontController
$id_country = (int)($id_customer ? Customer::getCurrentCountry($id_customer) : Configuration::get('PS_COUNTRY_DEFAULT')); $id_country = (int)($id_customer ? Customer::getCurrentCountry($id_customer) : Configuration::get('PS_COUNTRY_DEFAULT'));
// Tax // Tax
$tax = (float)(Tax::getProductTaxRate((int)$this->product->id, $this->context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')})); $tax = (float)$this->product->getTaxesRate(new Address((int)$this->context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}));
$this->context->smarty->assign('tax_rate', $tax); $this->context->smarty->assign('tax_rate', $tax);
$productPriceWithTax = Product::getPriceStatic($this->product->id, true, NULL, 6); $productPriceWithTax = Product::getPriceStatic($this->product->id, true, NULL, 6);
+11
View File
@@ -0,0 +1,11 @@
<?php
function remove_tab($tabname)
{
Db::getInstance()->Execute('
DELETE t, l
FROM `ps_tab` t LEFT JOIN `PREFIX_tab_lang` l ON (t.id_tab = l.id_tab)
WHERE t.`class_name` = '.pSQL($tabname));
}
+48
View File
@@ -0,0 +1,48 @@
<?php
function update_tax_rules()
{
// Add new columns
Db::getInstance()->Execute('
ALTER TABLE `'._DB_PREFIX_.'tax_rule`
ADD `zipcode_from` INT NOT NULL AFTER `id_state` ,
ADD `zipcode_to` INT NOT NULL AFTER `zipcode_from` ,
ADD `behavior` INT NOT NULL AFTER `zipcode_to`,
ADD `description` VARCHAR( 100 ) NOT NULL AFTER `id_tax`;
');
// Drop integrity constraint
Db::getInstance()->Execute('
ALTER TABLE `'._DB_PREFIX_.'tax_rule` DROP INDEX tax_rule
');
// Create new format rules
Db::getInstance()->Execute('
INSERT INTO `'._DB_PREFIX_.'tax_rule` (`id_tax_rules_group`, `id_country`, `id_state`, `id_tax`, `behavior`, `zipcode_from`, `zipcode_to`)
SELECT r.`id_tax_rules_group`, r.`id_country`, r.`id_state`, r.`id_tax`, 0, z.`from_zip_code`, z.`to_zip_code`
FROM `'._DB_PREFIX_.'tax_rule` r INNER JOIN `'._DB_PREFIX_.'county_zip_code` z ON (z.`id_county` = r.`id_county`)
');
// update behavior
Db::getInstance()->Execute('
UPDATE `'._DB_PREFIX_.'tax_rule` SET `behavior` = GREATEST(`state_behavior`, `county_behavior`);
');
// Clean old entries
Db::getInstance()->Execute('
DELETE FROM `'._DB_PREFIX_.'tax_rule`
WHERE `id_county` != 0
AND `zipcode_from` = 0
');
// Remove old columns
Db::getInstance()->Execute('
ALTER TABLE `'._DB_PREFIX_.'tax_rule`
DROP `id_county`,
DROP `state_behavior`,
DROP `county_behavior`
');
}
+5 -22
View File
@@ -1637,14 +1637,14 @@ CREATE TABLE `PREFIX_tax_rule` (
`id_tax_rules_group` int(11) NOT NULL, `id_tax_rules_group` int(11) NOT NULL,
`id_country` int(11) NOT NULL, `id_country` int(11) NOT NULL,
`id_state` int(11) NOT NULL, `id_state` int(11) NOT NULL,
`id_county` int(11) NOT NULL, `zipcode_from` INT NOT NULL,
`zipcode_to` INT NOT NULL,
`id_tax` int(11) NOT NULL, `id_tax` int(11) NOT NULL,
`state_behavior` int(11) NOT NULL, `behavior` int(11) NOT NULL,
`county_behavior` int(11) NOT NULL, `description` VARCHAR( 100 ) NOT NULL,
PRIMARY KEY (`id_tax_rule`), PRIMARY KEY (`id_tax_rule`),
KEY `id_tax_rules_group` (`id_tax_rules_group`), KEY `id_tax_rules_group` (`id_tax_rules_group`),
KEY `id_tax` (`id_tax`), KEY `id_tax` (`id_tax`)
UNIQUE KEY `tax_rule` (`id_tax_rules_group`, `id_country`, `id_state`, `id_county`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8; ) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
CREATE TABLE `PREFIX_tax_rules_group` ( CREATE TABLE `PREFIX_tax_rules_group` (
@@ -1688,23 +1688,6 @@ CREATE TABLE `PREFIX_import_match` (
PRIMARY KEY (`id_import_match`) PRIMARY KEY (`id_import_match`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8; ) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
CREATE TABLE `PREFIX_county` (
`id_county` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(64) NOT NULL,
`id_state` int(11) NOT NULL,
`active` tinyint(1) NOT NULL,
PRIMARY KEY (`id_county`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8 ;
CREATE TABLE `PREFIX_county_zip_code` (
`id_county` INT NOT NULL ,
`from_zip_code` INT NOT NULL ,
`to_zip_code` INT NOT NULL ,
PRIMARY KEY ( `id_county` , `from_zip_code` , `to_zip_code` )
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
CREATE TABLE `PREFIX_address_format` ( CREATE TABLE `PREFIX_address_format` (
`id_country` int(10) unsigned NOT NULL, `id_country` int(10) unsigned NOT NULL,
`format` varchar(255) NOT NULL DEFAULT '', `format` varchar(255) NOT NULL DEFAULT '',
+3 -1
View File
@@ -66,7 +66,8 @@ INSERT INTO `PREFIX_hook` (`id_hook`, `name`, `title`, `description`, `position`
(63, 'beforeAuthentication', 'Before Authentication', 'Before authentication', 0, 0), (63, 'beforeAuthentication', 'Before Authentication', 'Before authentication', 0, 0),
(64, 'paymentTop', 'Top of payment page', 'Top of payment page', 0, 0), (64, 'paymentTop', 'Top of payment page', 'Top of payment page', 0, 0),
(65, 'afterCreateHtaccess', 'After htaccess creation', 'After htaccess creation', 0, 0), (65, 'afterCreateHtaccess', 'After htaccess creation', 'After htaccess creation', 0, 0),
(66, 'afterSaveAdminMeta', 'After save configuration in AdminMeta', 'After save configuration in AdminMeta', 0, 0); (66, 'afterSaveAdminMeta', 'After save configuration in AdminMeta', 'After save configuration in AdminMeta', 0, 0),
(67, 'taxManager', 'Tax Manager Factory', '' , 0, 0);
INSERT INTO `PREFIX_configuration` (`id_configuration`, `name`, `value`, `date_add`, `date_upd`) VALUES INSERT INTO `PREFIX_configuration` (`id_configuration`, `name`, `value`, `date_add`, `date_upd`) VALUES
(1, 'PS_LANG_DEFAULT', '1', NOW(), NOW()), (1, 'PS_LANG_DEFAULT', '1', NOW(), NOW()),
@@ -1199,3 +1200,4 @@ postcode city
State:name State:name
Country:name Country:name
phone' where `id_country`=10; phone' where `id_country`=10;
+16
View File
@@ -23,3 +23,19 @@ INSERT INTO `PREFIX_module_access` (`id_profile`, `id_module`, `configure`, `vie
); );
UPDATE `PREFIX_tab` SET `class_name` = 'AdminThemes' WHERE `class_name` = 'AdminAppearance'; UPDATE `PREFIX_tab` SET `class_name` = 'AdminThemes' WHERE `class_name` = 'AdminAppearance';
INSERT INTO `PREFIX_hook` (
`name` ,
`title` ,
`description` ,
`position` ,
`live_edit`
)
VALUES ('taxmanager', 'taxmanager', NULL , '1', '0');
/* PHP:update_tax_rules(); */;
/* PHP:remove_tab(AdminCounty); */;
DROP TABLE `PREFIX_county_zip_code`;
DROP TABLE `PREFIX_county`;
+4
View File
@@ -133,6 +133,10 @@ require_once(_PS_INSTALLER_PHP_UPGRADE_DIR_.'create_multistore.php');
require_once(_PS_INSTALLER_PHP_UPGRADE_DIR_.'add_order_state.php'); require_once(_PS_INSTALLER_PHP_UPGRADE_DIR_.'add_order_state.php');
require_once(_PS_INSTALLER_PHP_UPGRADE_DIR_.'update_tax_rules.php');
require_once(_PS_INSTALLER_PHP_UPGRADE_DIR_.'remove_tab.php');
//old version detection //old version detection
global $oldversion, $logger; global $oldversion, $logger;
$oldversion = false; $oldversion = false;
+43
View File
@@ -0,0 +1,43 @@
<?php
/*
* 2007-2011 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2011 PrestaShop SA
* @version Release: $Revision$
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
class VATNumberTaxManager implements TaxManagerInterface
{
public static function isAvailableForThisAddress(Address $address)
{
return (!empty($address->vat_number)
AND $address->id_country != Configuration::get('VATNUMBER_COUNTRY')
AND Configuration::get('VATNUMBER_MANAGEMENT'));
}
public function getTaxCalculator()
{
// No tax
return new TaxCalculator(array(0));
}
}
+3 -3
View File
@@ -28,7 +28,7 @@
if (!defined('_PS_VERSION_')) if (!defined('_PS_VERSION_'))
exit; exit;
class VatNumber extends Module class VatNumber extends TaxManagerModule
{ {
public function __construct() public function __construct()
{ {
@@ -38,6 +38,8 @@ class VatNumber extends Module
$this->author = 'PrestaShop'; $this->author = 'PrestaShop';
$this->need_instance = 0; $this->need_instance = 0;
$this->tax_manager_class = 'VATNumberTaxManager';
parent::__construct(); parent::__construct();
$this->displayName = $this->l('European VAT number'); $this->displayName = $this->l('European VAT number');
@@ -179,5 +181,3 @@ class VatNumber extends Module
return $echo; return $echo;
} }
} }