[*] 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
+16 -40
View File
@@ -358,7 +358,7 @@ if (isset($_GET['ajaxStates']) AND isset($_GET['id_country']))
LEFT JOIN '._DB_PREFIX_.'country c ON (s.`id_country` = c.`id_country`)
WHERE s.id_country = '.(int)(Tools::getValue('id_country')).' AND s.active = 1 AND c.`contains_states` = 1
ORDER BY s.`name` ASC');
if (is_array($states) AND !empty($states))
{
$list = '';
@@ -504,30 +504,6 @@ if (Tools::isSubmit('toggleScreencast'))
$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'))
{
$item = Tools::getValue('item');
@@ -562,14 +538,14 @@ if (Tools::isSubmit('getHookableList'))
if ($moduleInstance->isHookableOn($hook_name))
array_push($hookableList[$hook_name], $module);
}
}
die(Tools::jsonEncode($hookableList));
}
if (Tools::isSubmit('getHookableModuleList'))
{
include('../init.php');
$hook_name = Tools::getValue('hook');
$hookableModulesList = array();
@@ -582,9 +558,9 @@ if (Tools::isSubmit('getHookableModuleList'))
$mod = new $module['name']();
if ($mod->isHookableOn($hook_name))
$hookableModulesList[] = array('id' => (int)$mod->id, 'name' => $mod->displayName, 'display' => Module::hookExec($hook_name, array(), (int)$mod->id));
}
}
}
die(Tools::jsonEncode($hookableModulesList));
die(Tools::jsonEncode($hookableModulesList));
}
if (Tools::isSubmit('saveHook'))
@@ -599,7 +575,7 @@ if (Tools::isSubmit('saveHook'))
$hook = trim($hook);
if (!$hook)
continue;
$sql = 'DELETE FROM '._DB_PREFIX_.'hook_module
WHERE id_hook = (SELECT id_hook FROM '._DB_PREFIX_.'hook WHERE `name` = \''.pSQL($hook).'\' LIMIT 1)
AND id_shop = '.$id_shop;
@@ -615,7 +591,7 @@ if (Tools::isSubmit('saveHook'))
}
$value = rtrim($value, ',');
Db::getInstance()->Execute('INSERT INTO '._DB_PREFIX_.'hook_module (id_module, id_shop, id_hook, position) VALUES '.$value);
}
}
die('{"hasError" : false, "errors" : ""}');
@@ -624,18 +600,18 @@ if (Tools::isSubmit('saveHook'))
if (Tools::isSubmit('getAdminHomeElement'))
{
$result = array();
$protocol = Tools::usingSecureMode() ? 'https' : 'http';
$isoUser = Context::getContext()->language->iso_code;
$isoCountry = Context::getContext()->country->iso_code;
$stream_context = stream_context_create(array('http' => array('method'=>"GET", 'timeout' => 5)));
// SCREENCAST
if (@fsockopen('www.prestashop.com', 80, $errno, $errst, 3))
$result['screencast'] = 'OK';
else
$result['screencast'] = 'NOK';
// PREACTIVATION
$content = @file_get_contents($protocol.'://www.prestashop.com/partner/preactivation/preactivation-block.php?version=1.0&shop='.urlencode(Configuration::get('PS_SHOP_NAME')).'&protocol='.$protocol.'&url='.urlencode($_SERVER['HTTP_HOST']).'&iso_country='.$isoCountry.'&iso_lang='.Tools::strtolower($isoUser).'&id_lang='.(int)Context::getContext()->language->id.'&email='.urlencode(Configuration::get('PS_SHOP_EMAIL')).'&date_creation='._PS_CREATION_DATE_.'&v='._PS_VERSION_.'&security='.md5(Configuration::get('PS_SHOP_EMAIL')._COOKIE_IV_), false, $stream_context);
if (!$content)
@@ -661,7 +637,7 @@ if (Tools::isSubmit('getAdminHomeElement'))
else
$result['partner_preactivation'] = 'NOK';
}
// PREACTIVATION PAYPAL WARNING
$content = @file_get_contents('https://www.prestashop.com/partner/preactivation/preactivation-warnings.php?version=1.0&partner=paypal&iso_country='.Tools::strtolower(Context::getContext()->country->iso_code).'&iso_lang='.Tools::strtolower(Context::getContext()->language->iso_code).'&id_lang='.(int)Context::getContext().'&email='.urlencode(Configuration::get('PS_SHOP_EMAIL')).'&security='.md5(Configuration::get('PS_SHOP_EMAIL')._COOKIE_IV_), false, $stream_context);
$content = explode('|', $content);
@@ -681,20 +657,20 @@ if (Tools::isSubmit('getAdminHomeElement'))
$result['discover_prestashop'] = $content[1];
else
$result['discover_prestashop'] = 'NOK';
if (@fsockopen('www.prestashop.com', 80, $errno, $errst, 3))
$result['discover_prestashop'] .= '<iframe frameborder="no" style="margin: 0px; padding: 0px; width: 315px; height: 290px;" src="'.$protocol.'://www.prestashop.com/rss/news2.php?v='._PS_VERSION_.'&lang='.$isoUser.'"></iframe>';
$content = @file_get_contents($protocol.'://www.prestashop.com/partner/paypal/paypal-tips.php?protocol='.$protocol.'&iso_country='.$isoCountry.'&iso_lang='.Tools::strtolower($isoUser).'&id_lang='.(int)Context::getContext()->language->id, false, $stream_context);
$content = explode('|', $content);
if ($content[0] == 'OK')
$result['discover_prestashop'] .= $content[1];
}
}
die(Tools::jsonEncode($result));
}
if (Tools::isSubmit('getChildrenCategories') && Tools::getValue('id_category_parent'))
if (Tools::isSubmit('getChildrenCategories') && Tools::getValue('id_category_parent'))
{
$children_categories = Category::getChildrenWithNbSelectedSubCat(Tools::getValue('id_category_parent'), Tools::getValue('selectedCat', array()), Context::getContext()->language->id);
die(Tools::jsonEncode($children_categories));
+1 -1
View File
@@ -228,7 +228,7 @@ class AdminAttributeGenerator extends AdminTab
i18n_tax_exc = "'.$this->l('Tax Excl.:').'";
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)
{
+22 -22
View File
@@ -131,7 +131,7 @@ class AdminProducts extends AdminTab
$nb = count($this->_list);
if ($this->_list)
{
/* update product final price */
for ($i = 0; $i < $nb; $i++)
@@ -1059,7 +1059,7 @@ class AdminProducts extends AdminTab
else
{
$image = new Image($id_image);
if (!$new_path = $image->getPathForCreation())
$this->_errors[] = Tools::displayError('An error occurred during new folder creation');
if (!$tmpName = tempnam(_PS_TMP_IMG_DIR_, 'PS') OR !move_uploaded_file($_FILES['image_product']['tmp_name'], $tmpName))
@@ -1179,7 +1179,7 @@ class AdminProducts extends AdminTab
$this->updateAccessories($object);
$this->updateDownloadProduct($object);
$this->updateAssoShop((int)$object->id);
if (!$this->updatePackItems($object))
$this->_errors[] = Tools::displayError('An error occurred while adding products to the pack.');
elseif (!$object->updateCategories($_POST['categoryBox'], true))
@@ -1662,7 +1662,7 @@ class AdminProducts extends AdminTab
$specificPrices = SpecificPrice::getByProductId((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();
foreach ($shops as $shop)
@@ -2613,11 +2613,11 @@ class AdminProducts extends AdminTab
</td>
</tr>
<tr><td colspan="2" style="padding-bottom:5px;"><hr style="width:100%;" /></td></tr>';
if ((int)Configuration::get('PS_STOCK_MANAGEMENT'))
{
if (!$has_attribute)
{
if ($obj->id)
@@ -2675,7 +2675,7 @@ class AdminProducts extends AdminTab
echo '<tr>
<td colspan="2">'.$this->l('The stock management is disabled').'</td>
</tr>';
echo '
<tr><td colspan="2" style="padding-bottom:5px;"><hr style="width:100%;" /></td></tr>
<tr>
@@ -2751,23 +2751,23 @@ class AdminProducts extends AdminTab
else
$selectedCat = Product::getProductCategoriesFull($obj->id, $this->_defaultFormLanguage);
}
echo '<select id="id_category_default" name="id_category_default">';
foreach($selectedCat AS $cat)
echo '<option value="'.$cat['id_category'].'" '.($obj->id_category_default == $cat['id_category'] ? 'selected' : '').'>'.$cat['name'].'</option>';
echo '</select>
</td>
</td>
</tr>
<tr id="tr_categories">
<td colspan="2">
';
// Translations are not automatic for the moment ;)
$trads = array(
'Home' => $this->l('Home'),
'selected' => $this->l('selected'),
'Collapse All' => $this->l('Collapse All'),
'Expand All' => $this->l('Expand All'),
'Check All' => $this->l('Check All'),
'Home' => $this->l('Home'),
'selected' => $this->l('selected'),
'Collapse All' => $this->l('Collapse All'),
'Expand All' => $this->l('Expand All'),
'Check All' => $this->l('Check All'),
'Uncheck All' => $this->l('Uncheck All')
);
echo Helper::renderAdminCategorieTree($trads, $selectedCat).'
@@ -2840,7 +2840,7 @@ class AdminProducts extends AdminTab
echo ' <div class="lang_'.$language['id_lang'].'" style="display: '.($language['id_lang'] == $this->_defaultFormLanguage ? 'block' : 'none').';float: left;">
<textarea class="rte" cols="100" rows="10" id="description_short_'.$language['id_lang'].'" name="description_short_'.$language['id_lang'].'">'.htmlentities(stripslashes($this->getFieldValue($obj, 'description_short', $language['id_lang'])), ENT_COMPAT, 'UTF-8').'</textarea>
</div>';
echo '<p class="clear">'.($obj->id ? $this->youEditFieldFor() : '').'</p>
echo '<p class="clear">'.($obj->id ? $this->youEditFieldFor() : '').'</p>
</td>
</tr>
<tr>
@@ -2959,7 +2959,7 @@ class AdminProducts extends AdminTab
unitPriceWithTax(\'unit\');
</script>';
$categoryBox = Tools::getValue('categoryBox', array());
}
function displayFormImages($obj, $token = NULL)
@@ -3070,7 +3070,7 @@ class AdminProducts extends AdminTab
</script>';
foreach ($shops as $shop)
echo '<th>'.$shop['name'].'</th>';
}
}
echo '
<th>'.$this->l('Cover').'</th>
<th>'.$this->l('Action').'</th>
@@ -3111,7 +3111,7 @@ class AdminProducts extends AdminTab
if (Shop::isMultiShopActivated())
foreach ($shops AS $shop)
echo '<td class="center"><input type="checkbox" class="image_shop" name="'.(int)$image['id_image'].'" value="'.(int)$shop['id_shop'].'" '.($imgObj->isAssociatedToShop($shop['id_shop']) ? 'checked="1"' : '').' /></td>';
echo '
echo '
<td class="center"><a href="'.self::$currentIndex.'&id_image='.$image['id_image'].'&coverImage&token='.($token ? $token : $this->token).'"><img src="../img/admin/'.($image['cover'] ? 'enabled.gif' : 'forbbiden.gif').'" alt="" /></a></td>
<td class="center">
<a href="'.self::$currentIndex.'&id_image='.$image['id_image'].'&editImage&tabs=1&token='.($token ? $token : $this->token).'"><img src="../img/admin/edit.gif" alt="'.$this->l('Modify this image').'" title="'.$this->l('Modify this image').'" /></a>
@@ -3172,7 +3172,7 @@ class AdminProducts extends AdminTab
function displayFormAttributes($obj, $languages, $defaultLanguage)
{
$attributeJs = array();
$attributes = Attribute::getAttributes($this->context->language->id, true);
foreach ($attributes AS $k => $attribute)
@@ -3181,7 +3181,7 @@ class AdminProducts extends AdminTab
$attributes_groups = AttributeGroup::getAttributesGroups($this->context->language->id);
$default_country = new Country((int)Configuration::get('PS_COUNTRY_DEFAULT'));
$images = Image::getImages($this->context->language->id, $obj->id);
if ($obj->id)
{
@@ -3726,7 +3726,7 @@ class AdminProducts extends AdminTab
}
else if ($(\'#curPackItemId\').val() == \'\' || $(\'#curPackItemQty\').val() == \'\')
{
alert(\''.$this->l('Thanks to set a quantity to add a product.').'\');
alert(\''.$this->l('Thanks to set a quantity to add a product.').'\');
return false;
}
+398 -479
View File
@@ -25,543 +25,462 @@
* International Registered Trademark & Property of PrestaShop SA
*/
class AdminTaxRulesGroup extends AdminTab
class
AdminTaxRulesGroup extends AdminTab
{
public $tax_rule;
public $_errors_tax_rule;
public function __construct()
{
global $cookie;
$this->table = 'tax_rules_group';
$this->className = 'TaxRulesGroup';
$this->edit = true;
$this->delete = true;
$this->ajax = false;
$this->fieldsDisplay = array(
'id_tax_rules_group' => array('title' => $this->l('ID'), 'align' => 'center', 'width' => 25),
'name' => array('title' => $this->l('Name'), 'width' => 140),
'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;">
'.$this->l('The tax rules allow you to define a product or a carrier with different taxes depending on their location (country, state, etc.).').'
$id_rule = (int)Tools::getValue('id_tax_rule');
<b>'.$this->l('In the majority of cases, the rules created by default by PrestaShop should be enough.').'</b> '.
$this->l('If, however, you need to change them, here is an example that will help you understand how it works:').
'<br /><br />'
.$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:').'
<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 />';
if ($tax_rule = TaxRule::retrieveById($id_rule))
die(Tools::jsonEncode($tax_rule));
else
die('error');
}
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)))
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">
'.($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>
<input type="hidden" name="tabs" id="tabs" value="0" />
';
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.'" />' : '').'
<fieldset><legend><img src="../img/admin/dollar.gif" />'.$this->l('Tax Rules').'</legend>
<input type="hidden" name="tabs" id="tabs" value="0" />
';
echo '<label>'.$this->l('Name').'</label>
<div class="margin-form">
echo '<label>'.$this->l('Name').'</label>
<div class="margin-form">
<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>
<p class="clear"></p>
</div>';
<p class="clear"></p>
</div>';
echo '
<label>'.$this->l('Enable:').' </label>
echo '
<label>'.$this->l('Enable:').' </label>
<div class="margin-form">
<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>
<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>
</div>';
if (Shop::isMultiShopActivated())
{
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;
</div>
<div class="margin-form">
<input type="submit" value="'.$this->l('Save and stay').'" name="submitAdd'.$this->table.'AndStay" class="button" />
</div>';
echo '<br />';
</div>
</form>';
}
echo '<div class="tab-panet-tax" id="tab-pane-1">
<script type="text/javascript">
var pos_select = '.(($tab = Tools::getValue('tabs')) ? $tab : '0').';
function loadTab(id)
{}
/**
* Display the tax rule form
*
* @param int $id_rule_group
*/
protected function displayRuleForm($id_rule_group)
{
global $cookie, $currentIndex;
function applyTax(id_zone)
{
cur_tax = $("#zone_"+id_zone).val();
$(".tax_"+id_zone).val(cur_tax);
return false;
}
if (Validate::isLoadedObject($this->tax_rule))
die(Tools::displayError('Unable to load the tax rule!'));
function disableStateTaxRate(id_country, id_state)
{
if ($("#behavior_state_"+id_state).val() == '.PS_PRODUCT_TAX.')
$("#tax_"+id_country+"_"+id_state).attr("disabled", true);
else
$("#tax_"+id_country+"_"+id_state).attr("disabled", false);
}
$country_select = Helper::selectInput(Country::getCountries((int)$cookie->id_lang),
array('id' => 'country', 'name' => 'country', 'onclick' => 'populateStates($(this).val(), \'\')'),
array('key' => 'id_country', 'value' => 'name'));
function disableCountyTaxRate(id_country, id_state, id_county)
{
if ($("#behavior_county_"+id_county).val() == '.County::USE_STATE_TAX.')
$("#tax_"+id_country+"_"+id_state+"_"+id_county).attr("disabled", true);
else
{
$tax_select = Helper::selectInput(Tax::getTaxes((int)$cookie->id_lang),
array('id' => 'tax', 'name' => 'tax'),
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 (){
$(\'.states\').hide();
$(\'.counties\').hide();
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>
<form action="'.$currentIndex.'&submitAdd'.$this->table.'=1&token='.$this->token.'" method="post">
<div id="rule_form" style="display: none">
<label>'.$this->l('Country').'</label>
<div class="margin-form">
'.$country_select.'
</div>
$(\'.open_state\').click(function (){
if ($(\'.\'+$(this).attr(\'id\')).is(\':hidden\'))
{
$(\'.\'+$(this).attr(\'id\')).show();
$(\'#\'+$(this).attr(\'id\')+\'_button\').attr("src","../img/admin/less.png");
}
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");
}
});
<label id="state-label">'.$this->l('State').'</label>
<div id="state-select" class="margin-form">
<select id="states" name="states">
</select>
</div>
$(\'.open_county\').click(function (){
if ($(\'.\'+$(this).attr(\'id\')).is(\':hidden\'))
{
$(\'.\'+$(this).attr(\'id\')).show();
$(\'#\'+$(this).attr(\'id\')+\'_button\').attr("src","../img/admin/less.png");
}
else
{
$(\'.\'+$(this).attr(\'id\')).hide();
$(\'#\'+$(this).attr(\'id\')+\'_button\').attr("src","../img/admin/more.png");
}
});
});
</script>
<script src="../js/tabpane.js" type="text/javascript"></script>
<script type="text/javascript">
var tabPane1 = new WebFXTabPane( document.getElementById( "tab-pane-1" ) );
</script>
<link type="text/css" rel="stylesheet" href="../css/tabpane.css" />'.$this->renderZones($tax_rules, $this->context->language->id);
echo '
<div class="margin-form" style="margin-top: 10px">
<input type="submit" value="'.$this->l(' Save ').'" name="submitAdd'.$this->table.'" class="button" />&nbsp;&nbsp;
<input type="submit" value="'.$this->l('Save and stay').'" name="submitAdd'.$this->table.'AndStay" class="button" />
<label>'.$this->l('ZipCode range').'</label>
<div class="margin-form">
<input type="hidden" name="action" value="create_rule" />
<input type="hidden" id="id_tax_rules_group" name="id_tax_rules_group" value="'.(int)$id_rule_group.'" />
<input type="hidden" id="id_tax_rule" name="id_tax_rule" />
<input type="text" id="zipcode" name="zipcode" />&nbsp;
<div class="hint" style="display: block">'.$this->l('You can define a range (eg: 75000-75015) or a simple zipcode').'</div>
</div>
<label>'.$this->l('Behavior').'</label>
<div class="margin-form">
'.$behavior_select.'
<div class="hint" style="display: block">
'.$this->l('Define the behavior if an address matches multiple rules:').'<br />
<b>'.$this->l('This Tax Only:').'</b> '.$this->l('Will apply only this tax').'<br />
<b>'.$this->l('Combine:').'</b> '.$this->l('Combine taxes (eg: 10% + 5% => 15%)').'<br />
<b>'.$this->l('One After Another:').'</b> '.$this->l('Apply taxes one after another (eg: 100€ + 10% => 110€ + 5% => 115.5€)').
'</div>
</div>
<label>'.$this->l('Tax').'</label>
<div class="margin-form">
'.$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>
</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)
{
$html = '';
$zones = Zone::getZones(true);
foreach ($zones AS $key => $zone)
{
$html .= '<div class="tab-page" id="tab-page-'.$key.'">
<h4 class="tab">'.$zone['name'].'</h4>
<script type="text/javascript">
tabPane1.addTabPage( document.getElementById( "tab-page-'.$key.'" ) );
</script>
'.$this->renderCountries($tax_rules, $zone['id_zone'], $id_lang).'
</div>';
}
/**
* display the tax rules list table body
*
* @param int $id_rule_group
*/
protected function displayTaxRules($id_rule_group)
{
global $currentIndex, $cookie;
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 = '
<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 />';
$tax = ((float)$tax_rule['rate'] == 0 ? '-' : (float)$tax_rule['rate'].'%');
$html .= '
<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;
$behavior = ($tax_rule['behavior'] == 0 ? $this->l('This tax only') : $this->l('Compute with others'));
foreach ($countries AS $country)
{
$id_tax = 0;
// render fields
$html .= '<tr>
<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']]))
$id_tax = (int)$tax_rules[$country['id_country']][0][0]['id_tax'];
$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);
</td>
</tr>';
}
$i++;
}
$html .= '
</tbody>
</table>
';
}
return $html;
}
}
public function renderStates($tax_rules, $id_zone, $id_country, $id_lang)
{
$states = State::getStatesByIdCountry((int)$id_country);
$countStates = sizeof($states);
$i = 1;
$html = '';
foreach ($states AS $state)
/**
* @param boolean $firstCall
*/
public function displayForm($firstCall = true)
{
if (!($obj = $this->loadObject(true)))
return;
parent::displayForm();
$this->displayRuleGroupForm();
$this->displayJS();
// display tax rules only if the group has already been created
if ($obj->id)
{
$id_tax = 0;
$selected = PS_PRODUCT_TAX;
if (array_key_exists($id_country, $tax_rules)
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++;
echo '<hr />';
$this->displayTaxRulesErrors();
$this->displayRuleForm($obj->id);
$this->displayRulesList($obj->id);
}
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>';
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];
$taxrate = Tax::getProductTaxRate($product->id);
$taxrate = $product->getTaxesRate();
echo '
<tr>
@@ -222,13 +222,15 @@ class AdminTracking extends AdminTab
else
$prod['combination_name'] = $prod['group_name'].' : '.$prod['attribute_name'];
$attributes[$prod['id_product_attribute']] = $prod;
$prevAttributeId = $prod['id_product_attribute'];
}
foreach ($attributes AS $prod)
{
$taxrate = Tax::getProductTaxRate($prod['id_product']);
$product = new Product((int)$prod['id_product'], false);
$tax_rate = $product->getTaxesRate();
echo '
<tr>
+7
View File
@@ -77,6 +77,8 @@ class Autoload
*/
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
if (!isset($this->index[$classname]) || ($this->index[$classname] && !file_exists($this->root_dir.$this->index[$classname])))
$this->generateIndex();
@@ -87,6 +89,7 @@ class Autoload
// If requested class does not exist, load associated core class
if (isset($this->index[$classname]) && !$this->index[$classname])
{
require_once($this->root_dir.$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
if (isset($this->index[$classname.'Core']))
{
require_once($this->root_dir.$this->index[$classname.'Core']);
}
if (isset($this->index[$classname]))
{
require_once($this->root_dir.$this->index[$classname]);
}
}
}
// Call directly ProductCore, ShopCore class
+25 -11
View File
@@ -70,7 +70,7 @@ class CarrierCore extends ObjectModel
/** @var boolean Free carrier */
public $is_free = false;
/** @var int shipping behavior: by weight or by price */
public $shipping_method = 0;
@@ -82,7 +82,7 @@ class CarrierCore extends ObjectModel
/** @var boolean Need Range */
public $need_range = 0;
protected $langMultiShop = true;
protected $fieldsRequired = array('name', 'active');
@@ -488,7 +488,7 @@ class CarrierCore extends ObjectModel
}
}
}
$row['name'] = (strval($row['name']) != '0' ? $row['name'] : Configuration::get('PS_SHOP_NAME'));
$row['price'] = ($shippingMethod == Carrier::SHIPPING_METHOD_FREE ? 0 : $cart->getOrderShippingCost((int)$row['id_carrier']));
$row['price_tax_exc'] = ($shippingMethod == Carrier::SHIPPING_METHOD_FREE ? 0 : $cart->getOrderShippingCost((int)$row['id_carrier'], false));
@@ -590,7 +590,7 @@ class CarrierCore extends ObjectModel
$where .= 'AND id_shop IS NULL AND id_group_shop = '.$shopGroupID;
else
$where .= 'AND id_shop = '.$shopID;
return Db::getInstance()->delete(_DB_PREFIX_.'delivery', $where);
}
@@ -610,7 +610,7 @@ class CarrierCore extends ObjectModel
$keys[] = 'id_shop';
if (!in_array('id_group_shop', $keys))
$keys[] = 'id_group_shop';
if (!$shop)
$shop = Context::getContext()->shop;
$shopID = $shop->getID();
@@ -623,7 +623,7 @@ class CarrierCore extends ObjectModel
$values['id_shop'] = ($shopID) ? $shopID : null;
if (!isset($values['id_group_shop']))
$values['id_group_shop'] = ($shopGroupID) ? $shopGroupID : null;
$sql .= '(';
foreach ($values as $v)
{
@@ -650,7 +650,7 @@ class CarrierCore extends ObjectModel
{
if (!Validate::isUnsignedId($oldId))
die(Tools::displayError());
if (!$this->id)
return false;
@@ -670,7 +670,7 @@ class CarrierCore extends ObjectModel
VALUES ('.$this->id.','.(float)$val['delimiter1'].','.(float)$val['delimiter2'].')';
Db::getInstance()->Execute($sql);
$rangeID = (int)Db::getInstance()->Insert_ID();
$rangePriceID = ($range == 'range_price') ? $rangeID : 'NULL';
$rangeWeightID = ($range == 'range_weight') ? $rangeID : 'NULL';
$sql = 'INSERT INTO '._DB_PREFIX_.$range.' (id_carrier, id_shop, id_group_shop, id_range_price, id_range_weight, id_zone, price)
@@ -769,10 +769,24 @@ class CarrierCore extends ObjectModel
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
*
*
* @since 1.5.0
* @param string $rangeTable
* @param Shop $shop
@@ -791,7 +805,7 @@ class CarrierCore extends ObjectModel
$where = 'AND ((d2.id_group_shop IS NULL OR d2.id_group_shop = '.$shopGroupID.') AND d2.id_shop IS NULL)';
else
$where = 'AND (d2.id_shop = '.$shopID.' OR (d2.id_group_shop = '.$shopGroupID.' AND d2.id_shop IS NULL) OR (d2.id_group_shop IS NULL AND d2.id_shop IS NULL))';
$sql = 'AND '.$alias.'.id_delivery = (
SELECT d2.id_delivery
FROM '._DB_PREFIX_.'delivery d2
+60 -58
View File
@@ -28,11 +28,11 @@
class CartCore extends ObjectModel
{
public $id;
public $id_group_shop;
public $id_shop;
/** @var integer Customer delivery address ID */
public $id_address_delivery;
@@ -75,7 +75,7 @@ class CartCore extends ObjectModel
public $checkedTos = false;
public $pictures;
public $textFields;
protected static $_nbProducts = array();
protected static $_isVirtualCart = array();
@@ -129,7 +129,7 @@ class CartCore extends ObjectModel
$fields['id_group_shop'] = (int)$this->id_group_shop;
$fields['id_shop'] = (int)$this->id_shop;
$fields['id_address_delivery'] = (int)($this->id_address_delivery);
$fields['id_address_invoice'] = (int)($this->id_address_invoice);
$fields['id_currency'] = (int)($this->id_currency);
@@ -187,35 +187,35 @@ class CartCore extends ObjectModel
{
if ($this->OrderExists()) //NOT delete a cart which is associated with an order
return false;
$uploadedFiles = Db::getInstance()->ExecuteS('
SELECT cd.`value`
SELECT cd.`value`
FROM `'._DB_PREFIX_.'customized_data` cd
INNER JOIN `'._DB_PREFIX_.'customization` c ON (cd.`id_customization`= c.`id_customization`)
WHERE cd.`type`= 0 AND c.`id_cart`='.(int)$this->id);
foreach ($uploadedFiles as $mustUnlink)
{
unlink(_PS_UPLOAD_DIR_.$mustUnlink['value'].'_small');
unlink(_PS_UPLOAD_DIR_.$mustUnlink['value']);
}
Db::getInstance()->Execute('
DELETE FROM `'._DB_PREFIX_.'customized_data`
DELETE FROM `'._DB_PREFIX_.'customized_data`
WHERE `id_customization` IN (
SELECT `id_customization`
FROM `'._DB_PREFIX_.'customization`
SELECT `id_customization`
FROM `'._DB_PREFIX_.'customization`
WHERE `id_cart`='.(int)$this->id.'
)');
Db::getInstance()->Execute('
DELETE FROM `'._DB_PREFIX_.'customization`
DELETE FROM `'._DB_PREFIX_.'customization`
WHERE `id_cart` = '.(int)$this->id);
if (!Db::getInstance()->Execute('DELETE FROM `'._DB_PREFIX_.'cart_discount` WHERE `id_cart` = '.(int)($this->id))
if (!Db::getInstance()->Execute('DELETE FROM `'._DB_PREFIX_.'cart_discount` WHERE `id_cart` = '.(int)($this->id))
OR !Db::getInstance()->Execute('DELETE FROM `'._DB_PREFIX_.'cart_product` WHERE `id_cart` = '.(int)($this->id)))
return false;
return parent::delete();
}
@@ -344,7 +344,7 @@ class CartCore extends ObjectModel
if (is_int($id_product))
{
foreach ($this->_products as $product)
if ($product['id_product'] == $id_product)
if ($product['id_product'] == $id_product)
return array($product);
return array();
}
@@ -352,7 +352,7 @@ class CartCore extends ObjectModel
}
if (!$id_country)
$id_country = Context::getContext()->country->id;
$sql = 'SELECT cp.`id_product_attribute`, cp.`id_product`, cu.`id_customization`, cp.`quantity` AS cart_quantity, cp.id_shop, cu.`quantity` AS customization_quantity, pl.`name`,
pl.`description_short`, pl.`available_now`, pl.`available_later`, p.`id_product`, p.`id_category_default`, p.`id_supplier`, p.`id_manufacturer`, p.`on_sale`, p.`ecotax`, p.`additional_shipping_cost`, p.`available_for_order`,
p.`price`, p.`weight`, p.`width`, p.`height`, p.`depth`, p.`out_of_stock`, p.`active`, p.`date_add`, p.`date_upd`, IFNULL(pa.`minimal_quantity`, p.`minimal_quantity`) as minimal_quantity,
@@ -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_.'tax_rule` tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group`
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_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`)
@@ -381,6 +382,7 @@ class CartCore extends ObjectModel
AND p.`id_product` IS NOT NULL
GROUP BY unique_id
ORDER BY cp.date_add ASC';
$result = Db::getInstance()->ExecuteS($sql);
// Reset the cache before the following return, or else an empty cart will add dozens of queries
@@ -414,7 +416,7 @@ class CartCore extends ObjectModel
$row['price'] = Product::getPriceStatic((int)$row['id_product'], false, isset($row['id_product_attribute']) ? (int)($row['id_product_attribute']) : NULL, 2, NULL, false, true, (int)($row['cart_quantity']), false, ((int)($this->id_customer) ? (int)($this->id_customer) : NULL), (int)($this->id), ((int)($this->{Configuration::get('PS_TAX_ADDRESS_TYPE')}) ? (int)($this->{Configuration::get('PS_TAX_ADDRESS_TYPE')}) : NULL), $specificPriceOutput); // Here taxes are computed only once the quantity has been applied to the product price
$row['price_wt'] = Product::getPriceStatic((int)$row['id_product'], true, isset($row['id_product_attribute']) ? (int)($row['id_product_attribute']) : NULL, 2, NULL, false, true, (int)($row['cart_quantity']), false, ((int)($this->id_customer) ? (int)($this->id_customer) : NULL), (int)($this->id), ((int)($this->{Configuration::get('PS_TAX_ADDRESS_TYPE')}) ? (int)($this->{Configuration::get('PS_TAX_ADDRESS_TYPE')}) : NULL));
$tax_rate = Tax::getProductTaxRate((int)$row['id_product'], (int)($this->{Configuration::get('PS_TAX_ADDRESS_TYPE')}));
$row['total_wt'] = Tools::ps_round($row['price'] * (float)$row['cart_quantity'] * (1 + (float)($tax_rate) / 100), 2);
$row['total'] = $row['price'] * (int)($row['cart_quantity']);
}
@@ -428,7 +430,7 @@ class CartCore extends ObjectModel
$row['total_wt'] = $row['price_wt'] * (int)($row['cart_quantity']);
$row['total'] = Tools::ps_round($row['price'] * (int)($row['cart_quantity']), 2);
}
$row2 = Db::getInstance()->getRow('
SELECT i.`id_image`, il.`legend`
FROM `'._DB_PREFIX_.'image` i
@@ -447,7 +449,7 @@ class CartCore extends ObjectModel
if (!$row2)
$row2 = array('id_image' => false, 'legend' => false);
$row = array_merge($row, $row2);
$row['reduction_applies'] = ($specificPriceOutput AND (float)$specificPriceOutput['reduction']);
$row['id_image'] = Product::defineProductImage($row,$this->id_lang);
$row['allow_oosp'] = Product::isAvailableWhenOutOfStock($row['out_of_stock']);
@@ -513,8 +515,8 @@ class CartCore extends ObjectModel
if (isset(self::$_nbProducts[$id]) && self::$_nbProducts[$id] !== NULL)
return self::$_nbProducts[$id];
self::$_nbProducts[$id] = (int)(Db::getInstance()->getValue('
SELECT SUM(`quantity`)
FROM `'._DB_PREFIX_.'cart_product`
SELECT SUM(`quantity`)
FROM `'._DB_PREFIX_.'cart_product`
WHERE `id_cart` = '.(int)($id)));
return self::$_nbProducts[$id];
}
@@ -579,7 +581,7 @@ class CartCore extends ObjectModel
$result = $this->containsProduct($id_product, $id_product_attribute, (int)$id_customization);
/* Update quantity if product already exist */
if ($result)
{
if ($operator == 'up')
@@ -652,7 +654,7 @@ class CartCore extends ObjectModel
// refresh cache of self::_products
$this->_products = $this->getProducts(true);
$this->update(true);
if ($product->customizable)
return $this->_updateCustomizationQuantity((int)$quantity, (int)$id_customization, (int)$id_product, (int)$id_product_attribute, $operator);
else
@@ -673,15 +675,15 @@ class CartCore extends ObjectModel
if ($field['quantity'] == 0)
{
Db::getInstance()->Execute('
UPDATE `'._DB_PREFIX_.'customization`
SET `quantity` = '.(int)($quantity).',
UPDATE `'._DB_PREFIX_.'customization`
SET `quantity` = '.(int)($quantity).',
`id_product_attribute` = '.(int)$id_product_attribute.',
`in_cart` = 1
WHERE `id_customization` = '.(int)$field['id_customization']);
}
}
}
/* Deletion */
if (!empty($id_customization) AND (int)($quantity) < 1)
return $this->_deleteCustomization((int)$id_customization, (int)$id_product, (int)$id_product_attribute);
@@ -694,7 +696,7 @@ class CartCore extends ObjectModel
if ($operator == 'down' AND (int)($result['quantity']) - (int)($quantity) < 1)
return Db::getInstance()->Execute('DELETE FROM `'._DB_PREFIX_.'customization` WHERE `id_customization` = '.(int)$id_customization);
return Db::getInstance()->Execute('
UPDATE `'._DB_PREFIX_.'customization`
UPDATE `'._DB_PREFIX_.'customization`
SET `quantity` = `quantity` '.($operator == 'up' ? '+ ' : '- ').(int)($quantity).'
WHERE `id_customization` = '.(int)($id_customization));
}
@@ -726,15 +728,15 @@ class CartCore extends ObjectModel
AND cu.id_product = '.(int)$id_product.'
AND in_cart = 0');
if ($exising_customization)
if ($exising_customization)
{
// If the customization field is alreay filled, delete it
// If the customization field is alreay filled, delete it
foreach($exising_customization as $customization)
{
if ($customization['type'] == $type && $customization['index'] == $index)
{
Db::getInstance()->Execute('
DELETE FROM `'._DB_PREFIX_.'customized_data`
DELETE FROM `'._DB_PREFIX_.'customized_data`
WHERE id_customization = '.(int)$customization['id_customization'].'
AND type = '.(int)$customization['type'].'
AND `index` = '.(int)$customization['index']);
@@ -750,7 +752,7 @@ class CartCore extends ObjectModel
}else
{
Db::getInstance()->Execute('INSERT INTO `'._DB_PREFIX_.'customization` (`id_cart`, `id_product`, `id_product_attribute`, `quantity`) VALUES ('.(int)($this->id).', '.(int)($id_product).', '.(int)($id_product_attribute).', '.(int)($quantity).')');
$id_customization = Db::getInstance()->Insert_ID();
$id_customization = Db::getInstance()->Insert_ID();
}
$query = 'INSERT INTO `'._DB_PREFIX_.'customized_data` (`id_customization`, `type`, `index`, `value`) VALUES ('.(int)$id_customization.', '.(int)$type.', '.(int)$index.', \''.pSql($field).'\')';
@@ -922,7 +924,7 @@ class CartCore extends ObjectModel
// no shipping cost if is a cart with only virtuals products
$virtual = $this->isVirtualCart();
if ($virtual AND $type == Cart::ONLY_SHIPPING)
if ($virtual AND $type == Cart::ONLY_SHIPPING)
return 0;
if ($virtual AND $type == Cart::BOTH)
$type = Cart::BOTH_WITHOUT_SHIPPING;
@@ -1042,7 +1044,7 @@ class CartCore extends ObjectModel
if (!$default_country)
$default_country = Context::getContext()->country;
// Checking discounts in cart
$products = $this->getProducts();
$discounts = $this->getDiscounts(true);
@@ -1087,7 +1089,7 @@ class CartCore extends ObjectModel
if (!Validate::isLoadedObject($default_country))
$default_country = new Country(Configuration::get('PS_COUNTRY_DEFAULT'), Configuration::get('PS_LANG_DEFAULT'));
$id_zone = (int)$default_country->id_zone;
}
}
// If no carrier, select default one
if (!$id_carrier)
@@ -1173,14 +1175,14 @@ class CartCore extends ObjectModel
die(Tools::displayError('Fatal error: "no default carrier"'));
if (!$carrier->active)
return $shipping_cost;
// Free fees if free carrier
if ($carrier->is_free == 1)
return 0;
return 0;
// Select carrier tax
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'));
// Free fees
@@ -1238,7 +1240,7 @@ class CartCore extends ObjectModel
{
$moduleName = $carrier->external_module_name;
$module = Module::getInstanceByName($moduleName);
if (Validate::isLoadedObject($module))
{
if (array_key_exists('id_carrier', $module))
@@ -1295,13 +1297,13 @@ class CartCore extends ObjectModel
*
* @return mixed Return a string if an error occurred and false otherwise
*/
function checkDiscountValidity($discountObj, $discounts, $order_total, $products, $checkCartDiscount = false,
function checkDiscountValidity($discountObj, $discounts, $order_total, $products, $checkCartDiscount = false,
Customer $customer = null, Shop $shop = null)
{
if (!$shop)
$shop = Context::getContext()->shop;
if (!$customer)
$customer = Context::getContext()->customer;
$customer = Context::getContext()->customer;
if (!$order_total)
return Tools::displayError('Cannot add voucher if order is free.');
if (!$discountObj->active)
@@ -1331,12 +1333,12 @@ class CartCore extends ObjectModel
foreach ($discounts as $discount)
if (!$discount['cumulable'])
return Tools::displayError('Voucher is not valid with other discounts.');
foreach($discounts as $discount)
if($discount['id_discount'] == $discountObj->id)
return Tools::displayError('This voucher is already in your cart');
}
$groups = Customer::getGroupsStatic($this->id_customer);
if (($discountObj->id_customer OR $discountObj->id_group) AND ((($this->id_customer != $discountObj->id_customer) OR ($this->id_customer == 0)) AND !in_array($discountObj->id_group, $groups)))
@@ -1391,7 +1393,7 @@ class CartCore extends ObjectModel
// New layout system with personalization fields
$formattedAddresses['invoice'] = AddressFormat::getFormattedLayoutData($invoice);
$formattedAddresses['delivery'] = AddressFormat::getFormattedLayoutData($delivery);
$total_tax = $this->getOrderTotal() - $this->getOrderTotal(false);
if ($total_tax < 0)
@@ -1513,7 +1515,7 @@ class CartCore extends ObjectModel
$textValue = str_replace(array("\n", "\r"), '', nl2br($textValue));
$textValue = str_replace('\\', '\\\\', $textValue);
$textValue = str_replace('\'', '\\\'', $textValue);
return $this->_addCustomization($id_product, 0, $index, $type, $textValue, 0);
return $this->_addCustomization($id_product, 0, $index, $type, $textValue, 0);
}
/*
@@ -1523,9 +1525,9 @@ class CartCore extends ObjectModel
*/
public function addPictureToProduct($id_product, $index, $type, $file)
{
return $this->_addCustomization($id_product, 0, $index, $type, $file, 0);
return $this->_addCustomization($id_product, 0, $index, $type, $file, 0);
}
/*
* Remove a customer's customization
*
@@ -1534,7 +1536,7 @@ class CartCore extends ObjectModel
public function deleteCustomizationToProduct($id_product, $index)
{
$result = true;
$custData = Db::getInstance()->getRow('
SELECT cu.`id_customization`, cd.`index`, cd.`value`, cd.`type` FROM `'._DB_PREFIX_.'customization` cu
LEFT JOIN `'._DB_PREFIX_.'customized_data` cd
@@ -1544,7 +1546,7 @@ class CartCore extends ObjectModel
AND `index` = '.(int)$index.'
AND `in_cart` = 0'
);
// Delete customization picture if necessary
if ($custData['type'] == 0)
$result &= (@unlink(_PS_UPLOAD_DIR_.$custData['value']) && @unlink(_PS_UPLOAD_DIR_.$custData['value'].'_small'));
@@ -1556,7 +1558,7 @@ class CartCore extends ObjectModel
);
return $result;
}
/**
* Return custom pictures in this cart for a specified product
*
@@ -1603,7 +1605,7 @@ class CartCore extends ObjectModel
$cart->id = NULL;
$cart->id_shop = $this->id_shop;
$cart->id_group_shop = $this->id_group_shop;
$cart->add();
if (!Validate::isLoadedObject($cart))
@@ -1620,7 +1622,7 @@ class CartCore extends ObjectModel
FROM '._DB_PREFIX_.'customization c
LEFT JOIN '._DB_PREFIX_.'customized_data cd ON cd.id_customization = c.id_customization
WHERE c.id_cart = '.(int)$this->id);
// Group line by id_customization
$customsById = array();
foreach ($customs AS $custom)
@@ -1629,7 +1631,7 @@ class CartCore extends ObjectModel
$customsById[$custom['id_customization']] = array();
$customsById[$custom['id_customization']][] = $custom;
}
// Insert new customizations
$custom_ids = array();
foreach($customsById as $customizationId => $val)
@@ -1639,7 +1641,7 @@ class CartCore extends ObjectModel
VALUES(\'\', '.(int)$cart->id.', '.(int)$custom['id_product_attribute'].', '.(int)$custom['id_product'].', '.(int)$custom['quantity'].')');
$custom_ids[$custom['id_customization']] = Db::getInstance(_PS_USE_SQL_SLAVE_)->Insert_ID();
}
// Insert customized_data
if (sizeof($customs))
{
@@ -1655,7 +1657,7 @@ class CartCore extends ObjectModel
}
Db::getInstance(_PS_USE_SQL_SLAVE_)->Execute($sql_custom_data);
}
return array('cart' => $cart, 'success' => $success);
}
+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_.'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_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_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`
+55 -135
View File
@@ -25,6 +25,10 @@
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @deprecated since 1.5
*/
class CountyCore extends ObjectModel
{
public $id;
@@ -63,181 +67,97 @@ class CountyCore extends ObjectModel
public function delete()
{
$id = $this->id;
parent::delete();
// remove associated zip codes & tax rule
return (County::deleteZipCodeByIdCounty($id) AND TaxRule::deleteTaxRuleByIdCounty($id));
return true;
}
/**
* @deprecated since 1.5
*/
public static function getCounties($id_state)
{
if (!isset(self::$_cache_get_counties[$id_state]))
{
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];
Tools::displayAsDeprecated();
return false;
}
// return the list of associated zipcode
/**
* @deprecated since 1.5
*/
public function getZipCodes()
{
return Db::getInstance()->ExecuteS('
SELECT * FROM `'._DB_PREFIX_.'county_zip_code`
WHERE `id_county` = '.(int)$this->id.'
ORDER BY `from_zip_code` ASC'
);
Tools::displayAsDeprecated();
return false;
}
/**
* @deprecated since 1.5
*/
public function addZipCodes($zip_codes)
{
list($from, $to) = $this->breakDownZipCode($zip_codes);
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.')'
);
Tools::displayAsDeprecated();
return true;
}
/**
* @deprecated since 1.5
*/
public function removeZipCodes($zip_codes)
{
list($from, $to) = $this->breakDownZipCode($zip_codes);
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
);
Tools::displayAsDeprecated();
return true;
}
/**
* @deprecated since 1.5
*/
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];
}
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);
Tools::displayAsDeprecated();
return array(0,0);
}
/**
* @deprecated since 1.5
*/
public static function getIdCountyByZipCode($id_state, $zip_code)
{
if (!isset(self::$_cache_county_zipcode[$id_state.'-'.$zip_code]))
{
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];
Tools::displayAsDeprecated();
return false;
}
/**
* @deprecated since 1.5
*/
public function isZipCodeRangePresent($zip_codes)
{
$res = false;
list($from, $to) = $this->breakDownZipCode($zip_codes);
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));
Tools::displayAsDeprecated();
return false;
}
/**
* @deprecated since 1.5
*/
public function isZipCodePresent($zip_code)
{
if ($zip_code == 0)
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.'
)'
);
Tools::displayAsDeprecated();
return false;
}
/**
* @deprecated since 1.5
*/
public static function deleteZipCodeByIdCounty($id_county)
{
return Db::getInstance()->Execute(
'DELETE FROM `'._DB_PREFIX_.'county_zip_code`
WHERE `id_county` = '.(int)$id_county
);
Tools::displayAsDeprecated();
return true;
}
/**
* @deprecated since 1.5
*/
public static function getIdCountyByNameAndIdState($name, $id_state)
{
return Db::getInstance()->getValue('
SELECT `id_county` FROM `'._DB_PREFIX_.'county`
WHERE `name` = \''.pSQL($name).'\'
AND `id_state` = '.(int)$id_state
);
Tools::displayAsDeprecated();
return false;
}
}
+86 -19
View File
@@ -34,7 +34,7 @@ class HelperCore
public static $translationsKeysForAdminCategorieTree = array(
'Home', 'selected', 'selecteds', 'Collapse All', 'Expand All', 'Check All', 'Uncheck All'
);
/**
*
* @param type $trads values of translations keys
@@ -42,22 +42,22 @@ class HelperCore
* @param type $selected_cat array of selected categories
* Format
* Array
(
[0] => 1
[1] => 2
)
* OR
Array
(
[1] => Array
(
[id_category] => 1
[name] => Home page
[link_rewrite] => home
)
)
* (
* [0] => 1
* [1] => 2
* )
* OR
* Array
* (
* [1] => Array
* (
* [id_category] => 1
* [name] => Home page
* [link_rewrite] => home
* )
* )
* @param type $input_name name of input
* @return string
* @return string
*/
public static function renderAdminCategorieTree($trads, $selected_cat = array(), $input_name = 'categoryBox', $use_radio = false)
{
@@ -86,7 +86,7 @@ class HelperCore
</script>
<link type="text/css" rel="stylesheet" href="../css/jquery.treeview.css" />
';
$html .= '
<div style="background-color:#F4E6C9; width:99%;padding:5px 0 5px 5px;">
<a href="#" id="collapse_all" >'.$trads['Collapse All'].'</a>
@@ -97,7 +97,7 @@ class HelperCore
' : '').'
</div>
';
$home_is_selected = false;
foreach($selected_cat AS $cat)
{
@@ -121,10 +121,77 @@ class HelperCore
<li id="1" class="hasChildren">
<span class="folder"> <input type="'.(!$use_radio ? 'checkbox' : 'radio').'" name="'.$input_name.'" value="1" '.($home_is_selected ? 'checked' : '').' onclick="clickOnCategoryBox($(this));" /> '.$trads['Home'].'</span>
<ul>
<li><span class="placeholder">&nbsp;</span></li>
<li><span class="placeholder">&nbsp;</span></li>
</ul>
</li>
</ul>';
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;
}
}
// 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;
}
+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_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`
AND tr.`id_country` = '.(int)$context->country->id.'
AND tr.`id_state` = 0)
AND tr.`id_country` = '.(int)$context->country->id.'
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_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`
+16 -14
View File
@@ -99,9 +99,12 @@ abstract class PaymentModuleCore extends Module
if ($secure_key !== false AND $secure_key != $cart->secure_key)
die(Tools::displayError());
$carrier = new Carrier((int)$cart->id_carrier, (int)$cart->id_lang);
// Copying data from cart
$order = new Order();
$order->id_carrier = (int)($cart->id_carrier);
$order->id_carrier = $carrier->id;
$order->id_customer = (int)($cart->id_customer);
$order->id_address_invoice = (int)($cart->id_address_invoice);
$order->id_address_delivery = (int)($cart->id_address_delivery);
@@ -109,10 +112,10 @@ abstract class PaymentModuleCore extends Module
$order->id_currency = ($currency_special ? (int)($currency_special) : (int)($cart->id_currency));
$order->id_lang = (int)($cart->id_lang);
$order->id_cart = (int)($cart->id);
$order->id_shop = (int)($shop->getID() ? $shop->getID() : $cart->id_shop);
$order->id_group_shop = (int)($shop->getID() ? $shop->getGroupID() : $cart->id_group_shop);
$customer = new Customer((int)($order->id_customer));
$order->secure_key = ($secure_key ? pSQL($secure_key) : pSQL($customer->secure_key));
$order->payment = $paymentMethod;
@@ -128,8 +131,8 @@ abstract class PaymentModuleCore extends Module
$order->total_products = (float)($cart->getOrderTotal(false, 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_shipping = (float)($cart->getOrderShippingCost());
$order->carrier_tax_rate = (float)Tax::getCarrierTaxRate($cart->id_carrier, (int)$cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
$order->total_shipping = (float)$cart->getOrderShippingCost();
$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_paid = (float)(Tools::ps_round((float)($cart->getOrderTotal(true, Cart::BOTH)), 2));
$order->invoice_date = '0000-00-00 00:00:00';
@@ -256,15 +259,15 @@ abstract class PaymentModuleCore extends Module
if (isset($customization['datas'][_CUSTOMIZE_TEXTFIELD_]))
foreach ($customization['datas'][_CUSTOMIZE_TEXTFIELD_] AS $text)
$customizationText .= $text['name'].':'.' '.$text['value'].'<br />';
if (isset($customization['datas'][_CUSTOMIZE_FILE_]))
$customizationText .= sizeof($customization['datas'][_CUSTOMIZE_FILE_]) .' '. Tools::displayError('image(s)').'<br />';
$customizationText .= '---<br />';
$customizationText .= '---<br />';
}
$customizationText = rtrim($customizationText, '---<br />');
$customizationQuantity = (int)($product['customizationQuantityTotal']);
$productsList .=
'<tr style="background-color: '.($key % 2 ? '#DDE2E6' : '#EBECEE').';">
@@ -377,7 +380,6 @@ abstract class PaymentModuleCore extends Module
{
$invoice = new Address((int)($order->id_address_invoice));
$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;
$invoice_state = $invoice->id_state ? new State((int)($invoice->id_state)) : false;
@@ -387,11 +389,11 @@ abstract class PaymentModuleCore extends Module
'{email}' => $customer->email,
'{delivery_block_txt}' => $this->_getFormatedAddress($delivery, "\n"),
'{invoice_block_txt}' => $this->_getFormatedAddress($invoice, "\n"),
'{delivery_block_html}' => $this->_getFormatedAddress($delivery, "<br />",
'{delivery_block_html}' => $this->_getFormatedAddress($delivery, "<br />",
array(
'firstname' => '<span style="color:#DB3484; font-weight:bold;">%s</span>',
'firstname' => '<span style="color:#DB3484; font-weight:bold;">%s</span>',
'lastname' => '<span style="color:#DB3484; font-weight:bold;">%s</span>')),
'{invoice_block_html}' => $this->_getFormatedAddress($invoice, "<br />",
'{invoice_block_html}' => $this->_getFormatedAddress($invoice, "<br />",
array(
'firstname' => '<span style="color:#DB3484; font-weight:bold;">%s</span>',
'lastname' => '<span style="color:#DB3484; font-weight:bold;">%s</span>')),
+85 -54
View File
@@ -186,7 +186,7 @@ class ProductCore extends ObjectModel
public $tags;
public $isFullyLoaded = false;
protected $langMultiShop = true;
public $cache_is_pack;
@@ -202,10 +202,10 @@ class ProductCore extends ObjectModel
protected static $_cacheFeatures = array();
protected static $_frontFeaturesCache = array();
protected static $producPropertiesCache = array();
/** @var array cache stock data in getStock() method */
protected static $cacheStock = array();
/** @var array tables */
protected $tables = array ('product', 'product_lang');
@@ -303,7 +303,7 @@ class ProductCore extends ObjectModel
parent::__construct($id_product, $id_lang, $id_shop);
if (!$context)
$context = Context::getContext();
if ($full AND $this->id)
{
$this->isFullyLoaded = $full;
@@ -311,10 +311,13 @@ class ProductCore extends ObjectModel
$this->manufacturer_name = Manufacturer::getNameById((int)$this->id_manufacturer);
$this->supplier_name = Supplier::getNameById((int)$this->id_supplier);
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)
$this->tax_rate = Tax::getProductTaxRate($this->id, $context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
else
$this->tax_rate = Tax::getProductTaxRate($this->id, NULL);
$address = $context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')};
$this->tax_rate = $this->getTaxesRate(new Address($address));
$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->unit_price = ($this->unit_price_ratio != 0 ? $this->price / $this->unit_price_ratio : 0);
@@ -375,7 +378,7 @@ class ProductCore extends ObjectModel
return $fields;
}
public function add($autodate = true, $nullValues = false)
{
if (!parent::add($autodate, $nullValues))
@@ -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));
}
else if (Validate::isLoadedObject(Context::getContext()->customer))
self::$_taxCalculationMethod = Group::getPriceDisplayMethod(Context::getContext()->customer->id_default_group);
else
self::$_taxCalculationMethod = Group::getDefaultPriceDisplayMethod();
}
public static function getTaxCalculationMethod($customer = NULL)
public static function getTaxCalculationMethod($id_customer = NULL)
{
if ($customer)
self::initPricesComputation((int)($customer));
if ($id_customer)
self::initPricesComputation((int)($id_customer));
return (int)(self::$_taxCalculationMethod);
}
@@ -556,7 +566,7 @@ class ProductCore extends ObjectModel
{
if (!GroupReduction::deleteProductReduction($this->id))
return false;
Hook::deleteProduct($this);
if (!parent::delete() OR
!$this->deleteCategories(true) OR
@@ -669,7 +679,7 @@ class ProductCore extends ObjectModel
if (!$this->setGroupReduction())
return false;
return true;
}
@@ -740,7 +750,7 @@ class ProductCore extends ObjectModel
SELECT `id_image`
FROM `'._DB_PREFIX_.'image`
WHERE `id_product` = '.(int)($this->id));
$status = true;
if ($result)
foreach($result as $row)
@@ -1369,7 +1379,7 @@ class ProductCore extends ObjectModel
AND tr.`id_state` = 0)
LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`)
LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON (m.`id_manufacturer` = p.`id_manufacturer`)
WHERE p.`active` = 1
WHERE p.`active` = 1
AND DATEDIFF(p.`date_add`, DATE_SUB(NOW(), INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY)) > 0
AND p.`id_product` IN (
SELECT cp.`id_product`
@@ -1556,7 +1566,7 @@ class ProductCore extends ObjectModel
$ret[] = $val['id_category'];
return $ret;
}
public static function getProductCategoriesFull($id_product = '', $id_lang)
{
$ret = array();
@@ -1642,7 +1652,7 @@ class ProductCore extends ObjectModel
{
if (!$context)
$context = Context::getContext();
$cur_cart = $context->cart;
if (isset($divisor))
@@ -1680,7 +1690,7 @@ class ProductCore extends ObjectModel
// retrieve address informations
$id_country = (int)$context->country->id;
$id_state = 0;
$id_county = 0;
$zipcode = 0;
if (!$id_address)
$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_state = (int)($address_infos['id_state']);
$postcode = (int)$address_infos['postcode'];
$id_county = (int)County::getIdCountyByZipCode($id_state, $postcode);
$zipcode = $address_infos['postcode'];
}
}
elseif (isset($context->customer->geoloc_id_country))
{
$id_country = (int)$context->customer->geoloc_id_country;
$id_state = (int)$context->customer->id_state;
$postcode = (int)$context->customer->postcode;
$id_county = (int)County::getIdCountyByZipCode($id_state, $postcode);
$zipcode = (int)$context->customer->postcode;
}
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'))
$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);
}
@@ -1733,16 +1739,17 @@ class ProductCore extends ObjectModel
* @param boolean $use_reduc Set if the returned amount will include reduction
* @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
*
* @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
if ($id_product_attribute === NULL)
$product_attribute_label = 'NULL';
else
$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
$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
$price += $attribute_price;
// TaxRate calculation
$tax_rate = Tax::getProductTaxRateViaRules((int)$id_product, (int)$id_country, (int)$id_state, (int)$id_county);
if ($tax_rate === false)
$tax_rate = 0;
// Tax
$address = new Address();
$address->id_country = $id_country;
$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
if ($use_tax)
$price = $price * (1 + ($tax_rate / 100));
$price = $product_tax_calculator->addTaxes($price);
$price = Tools::ps_round($price, $decimals);
// Reduction
@@ -1793,7 +1804,7 @@ class ProductCore extends ObjectModel
if (!$specific_price['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
$reduc = Tools::ps_round($price * $specific_price['reduction'], $decimals);
@@ -1825,8 +1836,13 @@ class ProductCore extends ObjectModel
$ecotax = Tools::convertPrice($ecotax, $id_currency);
if ($use_tax)
{
$taxRate = TaxRulesGroup::getTaxesRate((int)Configuration::get('PS_ECOTAX_TAX_RULES_GROUP_ID'), (int)$id_country, (int)$id_state, (int)$id_county);
$price += $ecotax * (1 + ($taxRate / 100));
// reinit the tax manager for ecotax handling
$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
$price += $ecotax;
@@ -1915,7 +1931,7 @@ class ProductCore extends ObjectModel
$ret .= Tools::displayPrice($params['p']['price'], $smarty->ps_currency);
return $ret;
}
/**
* Display price with right format and currency
*
@@ -1975,10 +1991,10 @@ class ProductCore extends ObjectModel
$product = new Product($id_product);
return $product->getStock($id_product_attribute);
}
/**
* Create JOIN query with 'stock' table
*
*
* @param string $productAlias Alias of product table
* @param string|int $productAttribute If string : alias of PA table ; if int : value of PA ; if null : nothing about PA
* @param bool $innerJoin LEFT JOIN or INNER JOIN
@@ -2002,10 +2018,10 @@ class ProductCore extends ObjectModel
return $sql;
}
/**
* Set the stock quantity of current product
*
*
* @since 1.5.0
* @param int $quantity
* @param int $id_product_attribute
@@ -2060,7 +2076,7 @@ class ProductCore extends ObjectModel
'quantity' => $quantity,
), 'INSERT');
}
// Change stock quantity on product
if ($id_stock = Stock::getStockId($this->id, $id_product_attribute, $shop->getID(true)))
{
@@ -2082,7 +2098,7 @@ class ProductCore extends ObjectModel
/**
* Get the stock quantity of current product
*
*
* @since 1.5.0
* @param int $id_product_attribute
* @param Context $context
@@ -2103,6 +2119,7 @@ class ProductCore extends ObjectModel
WHERE id_product = '.$this->id.'
AND id_product_attribute = '.(int)$id_product_attribute
.$context->shop->sqlRestriction(Shop::SHARE_STOCK);
self::$cacheStock[$this->id][$id_product_attribute] = (int)Db::getInstance()->getValue($sql);
}
return self::$cacheStock[$this->id][$id_product_attribute];
@@ -2692,7 +2709,7 @@ class ProductCore extends ObjectModel
{
if (!$this->isFullyLoaded && is_null($this->tags))
$this->tags = Tag::getProductTags($this->id);
if (!($this->tags AND key_exists($id_lang, $this->tags)))
return '';
@@ -2714,7 +2731,7 @@ class ProductCore extends ObjectModel
if (!$row['id_product'])
return false;
$context = Context::getContext();
// Product::getDefaultAttribute is only called if id_product_attribute is missing from the SQL query at the origin of it: consider adding it in order to avoid unnecessary queries
$row['allow_oosp'] = Product::isAvailableWhenOutOfStock($row['out_of_stock']);
if ((!isset($row['id_product_attribute']) OR !$row['id_product_attribute'])
@@ -3030,10 +3047,10 @@ class ProductCore extends ObjectModel
$fields_present[] = array('id_customization_field' => $field['index'], 'type' => $field['type']);
foreach ($requiredFields AS $required_field)
if (!in_array($required_field, $fields_present))
return false;
return false;
return true;
}
public static function idIsOnCategoryId($id_product, $categories)
{
$sql = 'SELECT id_product FROM `'._DB_PREFIX_.'category_product` WHERE `id_product`='.(int)($id_product).' AND `id_category` IN(';
@@ -3063,7 +3080,7 @@ class ProductCore extends ObjectModel
FROM `'._DB_PREFIX_.'category_product` cp
INNER JOIN `'._DB_PREFIX_.'category_group` ctg ON (ctg.`id_category` = cp.`id_category`)
WHERE cp.`id_product` = '.(int)$this->id.' AND ctg.`id_group` = 1');
else
else
return (bool)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('
SELECT cg.`id_group`
FROM `'._DB_PREFIX_.'category_product` cp
@@ -3075,7 +3092,7 @@ class ProductCore extends ObjectModel
/**
* Add a stock movement for current product
*
*
* @param int $quantity
* @param int $id_reason
* @param int $id_product_attribute
@@ -3155,6 +3172,20 @@ class ProductCore extends ObjectModel
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
*
@@ -3368,7 +3399,7 @@ class ProductCore extends ObjectModel
SET `cover` = 1 WHERE `id_product` = '.(int)($this->id).' AND `id_image` = '.(int)$id_image);
return true;
}
/**
* Webservice getter : get image ids of current product for association
*
@@ -3390,8 +3421,8 @@ class ProductCore extends ObjectModel
FROM `'._DB_PREFIX_.'product_tag`
WHERE `id_product` = '.(int)($this->id));
}
public function getWsManufacturerName()
{
return Manufacturer::getNameById((int)$this->id_manufacturer);
@@ -3404,7 +3435,7 @@ class ProductCore extends ObjectModel
SET ecotax = 0
');
}
/**
* Set Group reduction if needed
*/
+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_.'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_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_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`
+140 -132
View File
@@ -74,138 +74,6 @@ class TaxCore extends ObjectModel
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()
{
if (parent::toggleStatus())
@@ -229,5 +97,145 @@ class TaxCore extends ObjectModel
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_country;
public $id_state;
public $id_county;
public $zipcode_from;
public $zipcode_to;
public $id_tax;
public $state_behavior;
public $county_behavior;
public $behavior;
public $description;
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 $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_country'] = (int)$this->id_country;
$fields['id_state'] = (int)$this->id_state;
$fields['id_county'] = (int)$this->id_county;
$fields['state_behavior'] = (int)$this->state_behavior;
$fields['county_behavior'] = (int)$this->county_behavior;
$fields['id_tax'] = (int)($this->id_tax);
$fields['zipcode_from'] = (int)$this->zipcode_from;
$fields['zipcode_to'] = (int)$this->zipcode_to;
$fields['behavior'] = (int)$this->behavior;
$fields['id_tax'] = (int)($this->id_tax);
$fields['description'] = $this->description;
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)
{
if (empty($id_group))
die(Tools::displayError());
$results = Db::getInstance()->ExecuteS('
return Db::getInstance()->ExecuteS('
SELECT *
FROM `'._DB_PREFIX_.'tax_rule`
WHERE `id_tax_rules_group` = '.(int)$id_group
);
}*/
$res = array();
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']);
public static function getTaxRulesByGroupId($id_lang, $id_group)
{
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)
{
@@ -93,19 +123,57 @@ class TaxRuleCore extends ObjectModel
}
/**
* @deprecated since 1.5
*/
public static function deleteTaxRuleByIdCounty($id_county)
{
return Db::getInstance()->Execute('
DELETE FROM `'._DB_PREFIX_.'tax_rule`
WHERE `id_county` = '.(int)$id_county
);
Tools::displayAsDeprecated();
return true;
}
/**
* @param int $id_tax
* @return boolean
*/
public static function isTaxInUse($id_tax)
{
return Db::getInstance()->getValue('
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()
{
$tax_rules[] = array('id_tax_rules_group' => 0, 'name' => Tools::displayError('No tax'));
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)
{
$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`)
WHERE tr.`id_country` = '.(int)$id_country.'
AND tr.`id_state` = 0
AND tr.`id_county` = 0'
AND 0 between `zipcode_from` AND `zipcode_to`'
);
$res = array();
@@ -146,15 +91,12 @@ class TaxRulesGroupCore extends ObjectModel
return $res;
}
public static function getTaxesRate($id_tax_rules_group, $id_country, $id_state, $id_county)
{
$rate = 0;
foreach (TaxRulesGroup::getTaxes($id_tax_rules_group, $id_country, $id_state, $id_county) AS $tax)
$rate += (float)$tax->rate;
return $rate;
}
/**
* Returns the tax rules group id corresponding to the name
*
* @param string name
* @return int id of the tax rules
*/
public static function getIdByName($name)
{
return Db::getInstance()->getValue(
@@ -163,4 +105,29 @@ class TaxRulesGroupCore extends ObjectModel
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;
}
}
+3 -3
View File
@@ -49,7 +49,7 @@ class ProductControllerCore extends FrontController
$this->addJS(_PS_JS_DIR_.'jquery/jquery.jqzoom.js');
}
}
public function canonicalRedirection()
{
// Automatically redirect to the canonical URL if the current in is the right one
@@ -189,9 +189,9 @@ class ProductControllerCore extends FrontController
$id_country = (int)($id_customer ? Customer::getCurrentCountry($id_customer) : Configuration::get('PS_COUNTRY_DEFAULT'));
// 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);
$productPriceWithTax = Product::getPriceStatic($this->product->id, true, NULL, 6);
if (Product::$_taxCalculationMethod == PS_TAX_INC)
$productPriceWithTax = Tools::ps_round($productPriceWithTax, 2);
+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`
');
}
+11 -28
View File
@@ -178,7 +178,7 @@ CREATE TABLE `PREFIX_cart` (
KEY `id_lang` (`id_lang`),
KEY `id_currency` (`id_currency`),
KEY `id_guest` (`id_guest`),
KEY `id_group_shop` (`id_group_shop`),
KEY `id_group_shop` (`id_group_shop`),
KEY `id_shop` (`id_shop`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
@@ -324,7 +324,7 @@ CREATE TABLE `PREFIX_configuration_lang` (
CREATE TABLE `PREFIX_connections` (
`id_connections` int(10) unsigned NOT NULL auto_increment,
`id_group_shop` INT(11) UNSIGNED NOT NULL DEFAULT '1',
`id_group_shop` INT(11) UNSIGNED NOT NULL DEFAULT '1',
`id_shop` INT(11) UNSIGNED NOT NULL DEFAULT '1',
`id_guest` int(10) unsigned NOT NULL,
`id_page` int(10) unsigned NOT NULL,
@@ -442,7 +442,7 @@ CREATE TABLE `PREFIX_customer` (
KEY `customer_login` (`email`,`passwd`),
KEY `id_customer_passwd` (`id_customer`,`passwd`),
KEY `id_gender` (`id_gender`),
KEY `id_group_shop` (`id_group_shop`),
KEY `id_group_shop` (`id_group_shop`),
KEY `id_shop` (`id_shop`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
@@ -487,7 +487,7 @@ CREATE TABLE `PREFIX_customer_thread` (
KEY `id_contact` (`id_contact`),
KEY `id_customer` (`id_customer`),
KEY `id_order` (`id_order`),
KEY `id_product` (`id_product`)
KEY `id_product` (`id_product`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
@@ -942,7 +942,7 @@ CREATE TABLE `PREFIX_orders` (
KEY `id_currency` (`id_currency`),
KEY `id_address_delivery` (`id_address_delivery`),
KEY `id_address_invoice` (`id_address_invoice`),
KEY `id_group_shop` (`id_group_shop`),
KEY `id_group_shop` (`id_group_shop`),
KEY `id_shop` (`id_shop`),
INDEX `date_add`(`date_add`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
@@ -1119,7 +1119,7 @@ CREATE TABLE `PREFIX_page_type` (
CREATE TABLE `PREFIX_page_viewed` (
`id_page` int(10) unsigned NOT NULL,
`id_group_shop` INT UNSIGNED NOT NULL DEFAULT '1',
`id_group_shop` INT UNSIGNED NOT NULL DEFAULT '1',
`id_shop` INT UNSIGNED NOT NULL DEFAULT '1',
`id_date_range` int(10) unsigned NOT NULL,
`counter` int(10) unsigned NOT NULL,
@@ -1637,14 +1637,14 @@ CREATE TABLE `PREFIX_tax_rule` (
`id_tax_rules_group` int(11) NOT NULL,
`id_country` 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,
`state_behavior` int(11) NOT NULL,
`county_behavior` int(11) NOT NULL,
`behavior` int(11) NOT NULL,
`description` VARCHAR( 100 ) NOT NULL,
PRIMARY KEY (`id_tax_rule`),
KEY `id_tax_rules_group` (`id_tax_rules_group`),
KEY `id_tax` (`id_tax`),
UNIQUE KEY `tax_rule` (`id_tax_rules_group`, `id_country`, `id_state`, `id_county`)
KEY `id_tax` (`id_tax`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
CREATE TABLE `PREFIX_tax_rules_group` (
@@ -1688,23 +1688,6 @@ CREATE TABLE `PREFIX_import_match` (
PRIMARY KEY (`id_import_match`)
) 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` (
`id_country` int(10) unsigned NOT NULL,
`format` varchar(255) NOT NULL DEFAULT '',
+4 -2
View File
@@ -66,7 +66,8 @@ INSERT INTO `PREFIX_hook` (`id_hook`, `name`, `title`, `description`, `position`
(63, 'beforeAuthentication', 'Before Authentication', 'Before authentication', 0, 0),
(64, 'paymentTop', 'Top of payment page', 'Top of payment page', 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
(1, 'PS_LANG_DEFAULT', '1', NOW(), NOW()),
@@ -1180,7 +1181,7 @@ INSERT INTO `PREFIX_address_format` (`id_country`, `format`)
UPDATE `PREFIX_address_format` set `format`='firstname lastname
company
address1 address2
city, State:name postcode
city, State:name postcode
Country:name
phone' where `id_country`=21;
@@ -1199,3 +1200,4 @@ postcode city
State:name
Country:name
phone' where `id_country`=10;
+17 -1
View File
@@ -22,4 +22,20 @@ INSERT INTO `PREFIX_module_access` (`id_profile`, `id_module`, `configure`, `vie
AND a.`view` = 1
);
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`;
+8 -4
View File
@@ -30,7 +30,7 @@ $engineType = 'ENGINE_TYPE';
if (function_exists('date_default_timezone_set'))
date_default_timezone_set('Europe/Paris');
// if _PS_ROOT_DIR_ is defined, use it instead of "guessing" the module dir.
if (defined('_PS_ROOT_DIR_') AND !defined('_PS_MODULE_DIR_'))
define('_PS_MODULE_DIR_', _PS_ROOT_DIR_.'/modules/');
@@ -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_.'update_tax_rules.php');
require_once(_PS_INSTALLER_PHP_UPGRADE_DIR_.'remove_tab.php');
//old version detection
global $oldversion, $logger;
$oldversion = false;
@@ -313,9 +317,9 @@ if ($confFile->error != false)
// Settings updated, compile and cache directories must be emptied
$arrayToClean = array(
INSTALL_PATH.'/../tools/smarty/cache/',
INSTALL_PATH.'/../tools/smarty/compile/',
INSTALL_PATH.'/../tools/smarty_v2/cache/',
INSTALL_PATH.'/../tools/smarty/cache/',
INSTALL_PATH.'/../tools/smarty/compile/',
INSTALL_PATH.'/../tools/smarty_v2/cache/',
INSTALL_PATH.'/../tools/smarty_v2/compile/');
foreach ($arrayToClean as $dir)
if (!file_exists($dir))
+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));
}
}
+16 -16
View File
@@ -1,6 +1,6 @@
<?php
/*
* 2007-2011 PrestaShop
* 2007-2011 PrestaShop
*
* NOTICE OF LICENSE
*
@@ -28,7 +28,7 @@
if (!defined('_PS_VERSION_'))
exit;
class VatNumber extends Module
class VatNumber extends TaxManagerModule
{
public function __construct()
{
@@ -37,35 +37,37 @@ class VatNumber extends Module
$this->version = 1.0;
$this->author = 'PrestaShop';
$this->need_instance = 0;
$this->tax_manager_class = 'VATNumberTaxManager';
parent::__construct();
$this->displayName = $this->l('European VAT number');
$this->description = $this->l('Enable entering of the VAT intra-community number when creating the address (You must fill in the company field to allow keyboarding VAT number)');
}
public function install()
{
return (parent::install() AND Configuration::updateValue('VATNUMBER_MANAGEMENT', 1));
}
public function uninstall()
{
return (parent::uninstall() AND Configuration::updateValue('VATNUMBER_MANAGEMENT', 0));
}
public function enable($forceAll = false)
{
parent::enable();
Configuration::updateValue('VATNUMBER_MANAGEMENT', 1);
}
public function disable($forceAll = false)
{
parent::disable();
Configuration::updateValue('VATNUMBER_MANAGEMENT', 0);
}
public static function getPrefixIntracomVAT()
{
$intracom_array = array(
@@ -95,13 +97,13 @@ class VatNumber extends Module
'SK'=>'SK', //Slovakia
'CZ'=>'CZ', //Czech Republic
'SI'=>'SI', //Slovenia
'RO'=>'RO', //Romania
'BG'=>'BG' //Bulgaria
'RO'=>'RO', //Romania
'BG'=>'BG' //Bulgaria
);
return $intracom_array;
}
public static function isApplicable($id_country)
public static function isApplicable($id_country)
{
return (((int)$id_country AND in_array(Country::getIsoById($id_country), self::getPrefixIntracomVAT())) ? 1 : 0);
}
@@ -144,7 +146,7 @@ class VatNumber extends Module
public function getContent()
{
$echo = '';
if (Tools::isSubmit('submitVatNumber'))
{
if (Configuration::updateValue('VATNUMBER_COUNTRY', (int)(Tools::getValue('vatnumber_country'))))
@@ -178,6 +180,4 @@ class VatNumber extends Module
</fieldset>';
return $echo;
}
}
}