[*] 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`) 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 WHERE s.id_country = '.(int)(Tools::getValue('id_country')).' AND s.active = 1 AND c.`contains_states` = 1
ORDER BY s.`name` ASC'); ORDER BY s.`name` ASC');
if (is_array($states) AND !empty($states)) if (is_array($states) AND !empty($states))
{ {
$list = ''; $list = '';
@@ -504,30 +504,6 @@ if (Tools::isSubmit('toggleScreencast'))
$context->employee->save(); $context->employee->save();
} }
if (Tools::isSubmit('ajaxAddZipCode') OR Tools::isSubmit('ajaxRemoveZipCode'))
{
require_once(PS_ADMIN_DIR.'/tabs/AdminCounty.php');
$zipcodes = Tools::getValue('zipcodes');
$id_county = (int)Tools::getValue('id_county');
$county = new County($id_county);
if (!Validate::isLoadedObject($county))
die('error');
if (Tools::isSubmit('ajaxAddZipCode'))
{
if ($county->isZipCodeRangePresent($zipcodes))
die('error:'.Tools::displayError('This Zip Code is already in use.'));
if ($county->addZipCodes($zipcodes))
die(AdminCounty::renderZipCodeList($county->getZipCodes()));
}
else if (Tools::isSubmit('ajaxRemoveZipCode') AND $county->removeZipCodes($zipcodes))
die(AdminCounty::renderZipCodeList($county->getZipCodes()));
die('error');
}
if (Tools::isSubmit('helpAccess')) if (Tools::isSubmit('helpAccess'))
{ {
$item = Tools::getValue('item'); $item = Tools::getValue('item');
@@ -562,14 +538,14 @@ if (Tools::isSubmit('getHookableList'))
if ($moduleInstance->isHookableOn($hook_name)) if ($moduleInstance->isHookableOn($hook_name))
array_push($hookableList[$hook_name], $module); array_push($hookableList[$hook_name], $module);
} }
} }
die(Tools::jsonEncode($hookableList)); die(Tools::jsonEncode($hookableList));
} }
if (Tools::isSubmit('getHookableModuleList')) if (Tools::isSubmit('getHookableModuleList'))
{ {
include('../init.php'); include('../init.php');
$hook_name = Tools::getValue('hook'); $hook_name = Tools::getValue('hook');
$hookableModulesList = array(); $hookableModulesList = array();
@@ -582,9 +558,9 @@ if (Tools::isSubmit('getHookableModuleList'))
$mod = new $module['name'](); $mod = new $module['name']();
if ($mod->isHookableOn($hook_name)) if ($mod->isHookableOn($hook_name))
$hookableModulesList[] = array('id' => (int)$mod->id, 'name' => $mod->displayName, 'display' => Module::hookExec($hook_name, array(), (int)$mod->id)); $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')) if (Tools::isSubmit('saveHook'))
@@ -599,7 +575,7 @@ if (Tools::isSubmit('saveHook'))
$hook = trim($hook); $hook = trim($hook);
if (!$hook) if (!$hook)
continue; continue;
$sql = 'DELETE FROM '._DB_PREFIX_.'hook_module $sql = 'DELETE FROM '._DB_PREFIX_.'hook_module
WHERE id_hook = (SELECT id_hook FROM '._DB_PREFIX_.'hook WHERE `name` = \''.pSQL($hook).'\' LIMIT 1) WHERE id_hook = (SELECT id_hook FROM '._DB_PREFIX_.'hook WHERE `name` = \''.pSQL($hook).'\' LIMIT 1)
AND id_shop = '.$id_shop; AND id_shop = '.$id_shop;
@@ -615,7 +591,7 @@ if (Tools::isSubmit('saveHook'))
} }
$value = rtrim($value, ','); $value = rtrim($value, ',');
Db::getInstance()->Execute('INSERT INTO '._DB_PREFIX_.'hook_module (id_module, id_shop, id_hook, position) VALUES '.$value); Db::getInstance()->Execute('INSERT INTO '._DB_PREFIX_.'hook_module (id_module, id_shop, id_hook, position) VALUES '.$value);
} }
} }
die('{"hasError" : false, "errors" : ""}'); die('{"hasError" : false, "errors" : ""}');
@@ -624,18 +600,18 @@ if (Tools::isSubmit('saveHook'))
if (Tools::isSubmit('getAdminHomeElement')) if (Tools::isSubmit('getAdminHomeElement'))
{ {
$result = array(); $result = array();
$protocol = Tools::usingSecureMode() ? 'https' : 'http'; $protocol = Tools::usingSecureMode() ? 'https' : 'http';
$isoUser = Context::getContext()->language->iso_code; $isoUser = Context::getContext()->language->iso_code;
$isoCountry = Context::getContext()->country->iso_code; $isoCountry = Context::getContext()->country->iso_code;
$stream_context = stream_context_create(array('http' => array('method'=>"GET", 'timeout' => 5))); $stream_context = stream_context_create(array('http' => array('method'=>"GET", 'timeout' => 5)));
// SCREENCAST // SCREENCAST
if (@fsockopen('www.prestashop.com', 80, $errno, $errst, 3)) if (@fsockopen('www.prestashop.com', 80, $errno, $errst, 3))
$result['screencast'] = 'OK'; $result['screencast'] = 'OK';
else else
$result['screencast'] = 'NOK'; $result['screencast'] = 'NOK';
// PREACTIVATION // 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); $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) if (!$content)
@@ -661,7 +637,7 @@ if (Tools::isSubmit('getAdminHomeElement'))
else else
$result['partner_preactivation'] = 'NOK'; $result['partner_preactivation'] = 'NOK';
} }
// PREACTIVATION PAYPAL WARNING // 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 = @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); $content = explode('|', $content);
@@ -681,20 +657,20 @@ if (Tools::isSubmit('getAdminHomeElement'))
$result['discover_prestashop'] = $content[1]; $result['discover_prestashop'] = $content[1];
else else
$result['discover_prestashop'] = 'NOK'; $result['discover_prestashop'] = 'NOK';
if (@fsockopen('www.prestashop.com', 80, $errno, $errst, 3)) 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>'; $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 = @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); $content = explode('|', $content);
if ($content[0] == 'OK') if ($content[0] == 'OK')
$result['discover_prestashop'] .= $content[1]; $result['discover_prestashop'] .= $content[1];
} }
die(Tools::jsonEncode($result)); 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); $children_categories = Category::getChildrenWithNbSelectedSubCat(Tools::getValue('id_category_parent'), Tools::getValue('selectedCat', array()), Context::getContext()->language->id);
die(Tools::jsonEncode($children_categories)); 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_exc = "'.$this->l('Tax Excl.:').'";
i18n_tax_inc = "'.$this->l('Tax Incl.:').'"; i18n_tax_inc = "'.$this->l('Tax Incl.:').'";
var product_tax = "'.Tax::getProductTaxRate($this->product->id, NULL).'"; var product_tax = "'.$this->product->getTaxesRate().'";
function calcPrice(element, element_has_tax) function calcPrice(element, element_has_tax)
{ {
+22 -22
View File
@@ -131,7 +131,7 @@ class AdminProducts extends AdminTab
$nb = count($this->_list); $nb = count($this->_list);
if ($this->_list) if ($this->_list)
{ {
/* update product final price */ /* update product final price */
for ($i = 0; $i < $nb; $i++) for ($i = 0; $i < $nb; $i++)
@@ -1059,7 +1059,7 @@ class AdminProducts extends AdminTab
else else
{ {
$image = new Image($id_image); $image = new Image($id_image);
if (!$new_path = $image->getPathForCreation()) if (!$new_path = $image->getPathForCreation())
$this->_errors[] = Tools::displayError('An error occurred during new folder creation'); $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)) 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->updateAccessories($object);
$this->updateDownloadProduct($object); $this->updateDownloadProduct($object);
$this->updateAssoShop((int)$object->id); $this->updateAssoShop((int)$object->id);
if (!$this->updatePackItems($object)) if (!$this->updatePackItems($object))
$this->_errors[] = Tools::displayError('An error occurred while adding products to the pack.'); $this->_errors[] = Tools::displayError('An error occurred while adding products to the pack.');
elseif (!$object->updateCategories($_POST['categoryBox'], true)) elseif (!$object->updateCategories($_POST['categoryBox'], true))
@@ -1662,7 +1662,7 @@ class AdminProducts extends AdminTab
$specificPrices = SpecificPrice::getByProductId((int)($obj->id)); $specificPrices = SpecificPrice::getByProductId((int)($obj->id));
$specificPricePriorities = SpecificPrice::getPriority((int)($obj->id)); $specificPricePriorities = SpecificPrice::getPriority((int)($obj->id));
$taxRate = TaxRulesGroup::getTaxesRate($obj->id_tax_rules_group, $this->context->country->id, 0, 0); $taxRate = $obj->getTaxesRate(Tax::initializeAddress());
$tmp = array(); $tmp = array();
foreach ($shops as $shop) foreach ($shops as $shop)
@@ -2613,11 +2613,11 @@ class AdminProducts extends AdminTab
</td> </td>
</tr> </tr>
<tr><td colspan="2" style="padding-bottom:5px;"><hr style="width:100%;" /></td></tr>'; <tr><td colspan="2" style="padding-bottom:5px;"><hr style="width:100%;" /></td></tr>';
if ((int)Configuration::get('PS_STOCK_MANAGEMENT')) if ((int)Configuration::get('PS_STOCK_MANAGEMENT'))
{ {
if (!$has_attribute) if (!$has_attribute)
{ {
if ($obj->id) if ($obj->id)
@@ -2675,7 +2675,7 @@ class AdminProducts extends AdminTab
echo '<tr> echo '<tr>
<td colspan="2">'.$this->l('The stock management is disabled').'</td> <td colspan="2">'.$this->l('The stock management is disabled').'</td>
</tr>'; </tr>';
echo ' echo '
<tr><td colspan="2" style="padding-bottom:5px;"><hr style="width:100%;" /></td></tr> <tr><td colspan="2" style="padding-bottom:5px;"><hr style="width:100%;" /></td></tr>
<tr> <tr>
@@ -2751,23 +2751,23 @@ class AdminProducts extends AdminTab
else else
$selectedCat = Product::getProductCategoriesFull($obj->id, $this->_defaultFormLanguage); $selectedCat = Product::getProductCategoriesFull($obj->id, $this->_defaultFormLanguage);
} }
echo '<select id="id_category_default" name="id_category_default">'; echo '<select id="id_category_default" name="id_category_default">';
foreach($selectedCat AS $cat) foreach($selectedCat AS $cat)
echo '<option value="'.$cat['id_category'].'" '.($obj->id_category_default == $cat['id_category'] ? 'selected' : '').'>'.$cat['name'].'</option>'; echo '<option value="'.$cat['id_category'].'" '.($obj->id_category_default == $cat['id_category'] ? 'selected' : '').'>'.$cat['name'].'</option>';
echo '</select> echo '</select>
</td> </td>
</tr> </tr>
<tr id="tr_categories"> <tr id="tr_categories">
<td colspan="2"> <td colspan="2">
'; ';
// Translations are not automatic for the moment ;) // Translations are not automatic for the moment ;)
$trads = array( $trads = array(
'Home' => $this->l('Home'), 'Home' => $this->l('Home'),
'selected' => $this->l('selected'), 'selected' => $this->l('selected'),
'Collapse All' => $this->l('Collapse All'), 'Collapse All' => $this->l('Collapse All'),
'Expand All' => $this->l('Expand All'), 'Expand All' => $this->l('Expand All'),
'Check All' => $this->l('Check All'), 'Check All' => $this->l('Check All'),
'Uncheck All' => $this->l('Uncheck All') 'Uncheck All' => $this->l('Uncheck All')
); );
echo Helper::renderAdminCategorieTree($trads, $selectedCat).' 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;"> 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> <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>'; </div>';
echo '<p class="clear">'.($obj->id ? $this->youEditFieldFor() : '').'</p> echo '<p class="clear">'.($obj->id ? $this->youEditFieldFor() : '').'</p>
</td> </td>
</tr> </tr>
<tr> <tr>
@@ -2959,7 +2959,7 @@ class AdminProducts extends AdminTab
unitPriceWithTax(\'unit\'); unitPriceWithTax(\'unit\');
</script>'; </script>';
$categoryBox = Tools::getValue('categoryBox', array()); $categoryBox = Tools::getValue('categoryBox', array());
} }
function displayFormImages($obj, $token = NULL) function displayFormImages($obj, $token = NULL)
@@ -3070,7 +3070,7 @@ class AdminProducts extends AdminTab
</script>'; </script>';
foreach ($shops as $shop) foreach ($shops as $shop)
echo '<th>'.$shop['name'].'</th>'; echo '<th>'.$shop['name'].'</th>';
} }
echo ' echo '
<th>'.$this->l('Cover').'</th> <th>'.$this->l('Cover').'</th>
<th>'.$this->l('Action').'</th> <th>'.$this->l('Action').'</th>
@@ -3111,7 +3111,7 @@ class AdminProducts extends AdminTab
if (Shop::isMultiShopActivated()) if (Shop::isMultiShopActivated())
foreach ($shops AS $shop) 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 '<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'].'&coverImage&token='.($token ? $token : $this->token).'"><img src="../img/admin/'.($image['cover'] ? 'enabled.gif' : 'forbbiden.gif').'" alt="" /></a></td>
<td class="center"> <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> <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) function displayFormAttributes($obj, $languages, $defaultLanguage)
{ {
$attributeJs = array(); $attributeJs = array();
$attributes = Attribute::getAttributes($this->context->language->id, true); $attributes = Attribute::getAttributes($this->context->language->id, true);
foreach ($attributes AS $k => $attribute) foreach ($attributes AS $k => $attribute)
@@ -3181,7 +3181,7 @@ class AdminProducts extends AdminTab
$attributes_groups = AttributeGroup::getAttributesGroups($this->context->language->id); $attributes_groups = AttributeGroup::getAttributesGroups($this->context->language->id);
$default_country = new Country((int)Configuration::get('PS_COUNTRY_DEFAULT')); $default_country = new Country((int)Configuration::get('PS_COUNTRY_DEFAULT'));
$images = Image::getImages($this->context->language->id, $obj->id); $images = Image::getImages($this->context->language->id, $obj->id);
if ($obj->id) if ($obj->id)
{ {
@@ -3726,7 +3726,7 @@ class AdminProducts extends AdminTab
} }
else if ($(\'#curPackItemId\').val() == \'\' || $(\'#curPackItemQty\').val() == \'\') 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; return false;
} }
+398 -479
View File
@@ -25,543 +25,462 @@
* International Registered Trademark & Property of PrestaShop SA * International Registered Trademark & Property of PrestaShop SA
*/ */
class
class AdminTaxRulesGroup extends AdminTab AdminTaxRulesGroup extends AdminTab
{ {
public $tax_rule;
public $_errors_tax_rule;
public function __construct() public function __construct()
{ {
global $cookie;
$this->table = 'tax_rules_group'; $this->table = 'tax_rules_group';
$this->className = 'TaxRulesGroup'; $this->className = 'TaxRulesGroup';
$this->edit = true; $this->edit = true;
$this->delete = true; $this->delete = true;
$this->ajax = false;
$this->fieldsDisplay = array( $this->fieldsDisplay = array(
'id_tax_rules_group' => array('title' => $this->l('ID'), 'align' => 'center', 'width' => 25), 'id_tax_rules_group' => array('title' => $this->l('ID'), 'align' => 'center', 'width' => 25),
'name' => array('title' => $this->l('Name'), 'width' => 140), 'name' => array('title' => $this->l('Name'), 'width' => 140),
'active' => array('title' => $this->l('Enabled'), 'width' => 25, 'align' => 'center', 'active' => 'status', 'type' => 'bool', 'orderby' => false)); 'active' => array('title' => $this->l('Enabled'), 'width' => 25, 'align' => 'center', 'active' => 'status', 'type' => 'bool', 'orderby' => false));
parent::__construct(); parent::__construct();
} }
public function displayTop() /**
* retrieve a tax rule via ajax
* @return tax rule in json format
*/
public function ajaxProcessGetTaxRule()
{ {
echo '<div class="hint clear" style="display:block;"> $id_rule = (int)Tools::getValue('id_tax_rule');
'.$this->l('The tax rules allow you to define a product or a carrier with different taxes depending on their location (country, state, etc.).').'
<b>'.$this->l('In the majority of cases, the rules created by default by PrestaShop should be enough.').'</b> '. if ($tax_rule = TaxRule::retrieveById($id_rule))
$this->l('If, however, you need to change them, here is an example that will help you understand how it works:'). die(Tools::jsonEncode($tax_rule));
'<br /><br />' else
.$this->l('You want to apply a tax of 19.6% to a product in France and Europe, but not apply this tax to other countries. Follow these steps:').' die('error');
<ul>
<li>'.$this->l('Click "Add New".').'</li>
<li>'.$this->l('Give a name to your tax rule (ex: "19.6% tax rule).').'</li>
<li>'.$this->l('Set the \'active\' field to true.').'</li>
<li>'.$this->l('Edit its configuration by country by associating a 19.6% tax with France and with European countries, and a tax of 0% to other countries.').'</li>
<li>'.$this->l('Click on Save.').'</li>
<li>'.$this->l('Go to your product page (Catalog tab) and associate the "19.6% tax rule" to your product.').'</li>
</ul>
<br />
'.$this->l('Later, if you need to apply a different tax to Spain, you can simply edit the rule "19.6% tax rule" and change the tax associated with Spain.').'<br />
'.$this->l('Note: The default rate applied to your product will be based on your store\'s default country.').'
</div><br />';
} }
public function displayForm($isMainTab = true)
public function ajaxPreProcess() {}
public function postProcess()
{
$action = Tools::getValue('action');
if ($action == 'delete_rule')
{
$id_rule = (int)Tools::getValue('id_tax_rule');
$tax_rule = new TaxRule($id_rule);
if (Validate::isLoadedObject($tax_rule))
{
$tax_rule->delete();
Tools::redirectAdmin(self::$currentIndex.'&'.$this->identifier.'='.$tax_rule->id_tax_rules_group.'&conf=4&update'.$this->table.'&token='.$this->token);
}
}
else if ($action == 'create_rule')
{
$zipcode = Tools::getValue('zipcode');
$id_rule = (int)Tools::getValue('id_tax_rule');
$tr = new TaxRule();
// update or creation?
if (isset($id_rule))
$tr->id = $id_rule;
$tr->id_tax = (int)Tools::getValue('tax');
$tr->id_tax_rules_group = (int)Tools::getValue('id_tax_rules_group');
$tr->id_country = (int)Tools::getValue('country');
$tr->id_state = (int)Tools::getValue('states');
list($tr->zipcode_from, $tr->zipcode_to) = $tr->breakDownZipCode($zipcode);
$tr->behavior = (int)Tools::getValue('behavior');
$tr->description = Tools::getValue('description');
$this->_errors_tax_rule = $this->validateTaxRule($tr);
if (sizeof($this->_errors_tax_rule) == 0)
{
if (!$tr->save())
die('error');
}
$this->tax_rule = $tr;
Tools::redirectAdmin(self::$currentIndex.'&'.$this->identifier.'='.$tr->id_tax_rules_group.'&conf=4&update'.$this->table.'&token='.$this->token);
} else
parent::postProcess();
}
/**
* check if the tax rule could be added in the database
* @param TaxRule $tr
*/
protected function validateTaxRule(TaxRule $tr)
{ {
parent::displayForm(); // TODO: check if the rule already exists
return $tr->validateController();
}
protected function displayJS()
{
global $cookie;
$javascript = <<<EOT
<script type="text/javascript">
function populateStates(id_country, id_state)
{
$.ajax({
url: "ajax.php",
cache: false,
data: "ajaxStates=1&id_country="+id_country+"&id_state="+id_state,
success: function(html){
if (html == "false")
{
$("#state-label").hide();
$("#state-select").hide();
}
else
{
$("#state-label").show();
$("#state-select").show();
$("#states").html(html);
}
}
});
}
function loadTaxRule(id_tax_rule)
{
$.ajax({
url: "ajax-tab.php",
cache: false,
dataType: "json",
data: "action=get_tax_rule&id_tax_rule="+id_tax_rule+"&tab=AdminTaxRulesGroup&token=$this->token",
success: function(data){
$('#rule_form').show();
$('#id_tax_rule').val(data.id_tax_rule);
$('#country').val(data.id_country);
$('#state').val(data.id_state);
zipcode = 0;
if (data.zipcode_from != 0)
{
zipcode = data.zipcode_from;
if (data.zipcode_to != 0)
zipcode = zipcode +"-"+data.zipcode_to
}
$('#zipcode').val(zipcode);
$('#behavior').val(data.behavior);
$('#tax').val(data.id_tax);
$('#description').val(data.description);
populateStates(data.id_country, data.id_state);
},
error: function(data)
{
}
});
}
function initForm()
{
$('#id_tax_rule').val('');
$('#country').val(0);
$('#state').val(0);
$('#zipcode').val(0);
$('#behavior').val(0);
$('#tax').val(0);
$('#description').val('');
populateStates(0,0);
}
</script>
EOT;
echo $javascript;
}
public function displayTaxRulesErrors()
{
if ($nbErrors = count($this->_errors_tax_rule) AND $this->_includeContainer)
{
echo '<script type="text/javascript">
$(document).ready(function() {
$(\'#hideErrorTaxRules\').unbind(\'click\').click(function(){
$(\'.error\').hide(\'slow\', function (){
$(\'.error\').remove();
});
return false;
});
});
$(document).ready(function() {
$(\'#rule_form\').show();
populateStates("'.(int)$this->tax_rule->id_country.'", "'.(int)$this->tax_rule->id_state.'")
});
</script>
<div class="error"><span style="float:right"><a id="hideErrorTaxRules" href=""><img alt="X" src="../img/admin/close.png" /></a></span><img src="../img/admin/error2.png" />';
if (count($this->_errors_tax_rule) == 1)
echo $this->_errors_tax_rule[0];
else
{
echo $nbErrors.' '.$this->l('errors').'<br /><ol>';
foreach ($this->_errors_tax_rule AS $error)
echo '<li>'.$error.'</li>';
echo '</ol>';
}
echo '</div>';
}
}
public function display()
{
if ((Tools::getValue('submitAdd'.$this->table) AND sizeof($this->_errors_tax_rule)) OR isset($_GET['add'.$this->table]))
{
if ($this->tabAccess['add'] === '1')
$this->displayForm();
else
echo $this->l('You do not have permission to add here');
}
else parent::display();
}
/**
* displays the tax rules group form
*/
protected function displayRuleGroupForm()
{
global $cookie, $currentIndex;
parent::displayForm();
if (!($obj = $this->loadObject(true))) if (!($obj = $this->loadObject(true)))
return; return;
$tax_rules = isset($obj->id) ? $tax_rules = TaxRule::getTaxRulesByGroupId($obj->id) : array();
$param_product = Tools::getValue('id_product') ? '&id_product='.Tools::getValue('id_product') : ''; // if the user come from the product page
$param_product = Tools::getValue('id_product') ? '&id_product='.Tools::getValue('id_product') : '';
echo '<form action="'.self::$currentIndex.'&submitAdd'.$this->table.'=1&token='.$this->token.$param_product.'" method="post"> echo '<form action="'.$currentIndex.'&submitAdd'.$this->table.'=1&token='.$this->token.$param_product.'" method="post">
'.($obj->id ? '<input type="hidden" name="id_'.$this->table.'" value="'.$obj->id.'" />' : '').' '.($obj->id ? '<input type="hidden" name="id_'.$this->table.'" value="'.$obj->id.'" />' : '').'
<fieldset><legend><img src="../img/admin/dollar.gif" />'.$this->l('Tax Rules').'</legend> <fieldset><legend><img src="../img/admin/dollar.gif" />'.$this->l('Tax Rules').'</legend>
<input type="hidden" name="tabs" id="tabs" value="0" /> <input type="hidden" name="tabs" id="tabs" value="0" />
'; ';
echo '<label>'.$this->l('Name').'</label> echo '<label>'.$this->l('Name').'</label>
<div class="margin-form"> <div class="margin-form">
<input size="33" type="text" name="name" value="'.Tools::htmlentitiesUTF8($this->getFieldValue($obj, 'name')).'" /><sup> *</sup> <input size="33" type="text" name="name" value="'.Tools::htmlentitiesUTF8($this->getFieldValue($obj, 'name')).'" /><sup> *</sup>
<span class="hint" name="help_box">'.$this->l('Invalid characters:').' <>;=#{}<span class="hint-pointer">&nbsp;</span></span> <span class="hint" name="help_box">'.$this->l('Invalid characters:').' <>;=#{}<span class="hint-pointer">&nbsp;</span></span>
<p class="clear"></p> <p class="clear"></p>
</div>'; </div>';
echo ' echo '
<label>'.$this->l('Enable:').' </label> <label>'.$this->l('Enable:').' </label>
<div class="margin-form"> <div class="margin-form">
<input type="radio" name="active" id="active_on" value="1" '.($this->getFieldValue($obj, 'active') ? 'checked="checked" ' : '').'/> <input type="radio" name="active" id="active_on" value="1" '.($this->getFieldValue($obj, 'active') ? 'checked="checked" ' : '').'/>
<label class="t" for="active_on"> <img src="../img/admin/enabled.gif" alt="'.$this->l('Enabled').'" title="'.$this->l('Enabled').'" /></label> <label class="t" for="active_on"> <img src="../img/admin/enabled.gif" alt="'.$this->l('Enabled').'" title="'.$this->l('Enabled').'" /></label>
<input type="radio" name="active" id="active_off" value="0" '.(!$this->getFieldValue($obj, 'active') ? 'checked="checked" ' : '').'/> <input type="radio" name="active" id="active_off" value="0" '.(!$this->getFieldValue($obj, 'active') ? 'checked="checked" ' : '').'/>
<label class="t" for="active_off"> <img src="../img/admin/disabled.gif" alt="'.$this->l('Disabled').'" title="'.$this->l('Disabled').'" /></label> <label class="t" for="active_off"> <img src="../img/admin/disabled.gif" alt="'.$this->l('Disabled').'" title="'.$this->l('Disabled').'" /></label>
</div>'; </div>
if (Shop::isMultiShopActivated()) <div class="margin-form">
{
echo '<label>'.$this->l('Shop association:').'</label><div class="margin-form">';
$this->displayAssoShop('group_shop');
echo '</div>';
}
echo '
<div class="margin-form">
<input type="submit" value="'.$this->l(' Save ').'" name="submitAdd'.$this->table.'" class="button" />&nbsp;
<input type="submit" value="'.$this->l('Save and stay').'" name="submitAdd'.$this->table.'AndStay" class="button" /> <input type="submit" value="'.$this->l('Save and stay').'" name="submitAdd'.$this->table.'AndStay" class="button" />
</div>'; </div>
echo '<br />'; </form>';
}
echo '<div class="tab-panet-tax" id="tab-pane-1"> /**
<script type="text/javascript"> * Display the tax rule form
var pos_select = '.(($tab = Tools::getValue('tabs')) ? $tab : '0').'; *
function loadTab(id) * @param int $id_rule_group
{} */
protected function displayRuleForm($id_rule_group)
{
global $cookie, $currentIndex;
function applyTax(id_zone) if (Validate::isLoadedObject($this->tax_rule))
{ die(Tools::displayError('Unable to load the tax rule!'));
cur_tax = $("#zone_"+id_zone).val();
$(".tax_"+id_zone).val(cur_tax);
return false;
}
function disableStateTaxRate(id_country, id_state) $country_select = Helper::selectInput(Country::getCountries((int)$cookie->id_lang),
{ array('id' => 'country', 'name' => 'country', 'onclick' => 'populateStates($(this).val(), \'\')'),
if ($("#behavior_state_"+id_state).val() == '.PS_PRODUCT_TAX.') array('key' => 'id_country', 'value' => 'name'));
$("#tax_"+id_country+"_"+id_state).attr("disabled", true);
else
$("#tax_"+id_country+"_"+id_state).attr("disabled", false);
}
function disableCountyTaxRate(id_country, id_state, id_county)
{
if ($("#behavior_county_"+id_county).val() == '.County::USE_STATE_TAX.') $tax_select = Helper::selectInput(Tax::getTaxes((int)$cookie->id_lang),
$("#tax_"+id_country+"_"+id_state+"_"+id_county).attr("disabled", true); array('id' => 'tax', 'name' => 'tax'),
else array('key' => 'id_tax',
{ 'value' => 'name',
'empty' => $this->l('No Tax')));
$("#tax_"+id_country+"_"+id_state+"_"+id_county).attr("disabled", false); $behavior_select = Helper::selectInput(array(0 => $this->l('This tax only'),
} 1 => $this->l('Combine'),
} 2 => $this->l('One After Another')
),
array('id' => 'behavior', 'name' => 'behavior'));
$(\'document\').ready(function (){ echo '<a href="#" onclick="initForm();$(\'#rule_form\').slideToggle();return false;"><img src="../img/admin/add.gif" alt="" /> '.$this->l('Add a new tax rule').'</a>
$(\'.states\').hide(); <form action="'.$currentIndex.'&submitAdd'.$this->table.'=1&token='.$this->token.'" method="post">
$(\'.counties\').hide(); <div id="rule_form" style="display: none">
<label>'.$this->l('Country').'</label>
<div class="margin-form">
'.$country_select.'
</div>
$(\'.open_state\').click(function (){ <label id="state-label">'.$this->l('State').'</label>
if ($(\'.\'+$(this).attr(\'id\')).is(\':hidden\')) <div id="state-select" class="margin-form">
{ <select id="states" name="states">
$(\'.\'+$(this).attr(\'id\')).show(); </select>
$(\'#\'+$(this).attr(\'id\')+\'_button\').attr("src","../img/admin/less.png"); </div>
}
else
{
$(\'.\'+$(this).attr(\'id\')).hide();
$(\'.county_\'+$(this).attr(\'id\')).hide();
$(\'.county_\'+$(this).attr(\'id\')+\'_button\').attr("src","../img/admin/more.png");
$(\'#\'+$(this).attr(\'id\')+\'_button\').attr("src","../img/admin/more.png");
}
});
$(\'.open_county\').click(function (){ <label>'.$this->l('ZipCode range').'</label>
if ($(\'.\'+$(this).attr(\'id\')).is(\':hidden\')) <div class="margin-form">
{ <input type="hidden" name="action" value="create_rule" />
$(\'.\'+$(this).attr(\'id\')).show(); <input type="hidden" id="id_tax_rules_group" name="id_tax_rules_group" value="'.(int)$id_rule_group.'" />
$(\'#\'+$(this).attr(\'id\')+\'_button\').attr("src","../img/admin/less.png"); <input type="hidden" id="id_tax_rule" name="id_tax_rule" />
} <input type="text" id="zipcode" name="zipcode" />&nbsp;
else <div class="hint" style="display: block">'.$this->l('You can define a range (eg: 75000-75015) or a simple zipcode').'</div>
{ </div>
$(\'.\'+$(this).attr(\'id\')).hide();
$(\'#\'+$(this).attr(\'id\')+\'_button\').attr("src","../img/admin/more.png"); <label>'.$this->l('Behavior').'</label>
} <div class="margin-form">
}); '.$behavior_select.'
}); <div class="hint" style="display: block">
</script> '.$this->l('Define the behavior if an address matches multiple rules:').'<br />
<script src="../js/tabpane.js" type="text/javascript"></script> <b>'.$this->l('This Tax Only:').'</b> '.$this->l('Will apply only this tax').'<br />
<script type="text/javascript"> <b>'.$this->l('Combine:').'</b> '.$this->l('Combine taxes (eg: 10% + 5% => 15%)').'<br />
var tabPane1 = new WebFXTabPane( document.getElementById( "tab-pane-1" ) ); <b>'.$this->l('One After Another:').'</b> '.$this->l('Apply taxes one after another (eg: 100€ + 10% => 110€ + 5% => 115.5€)').
</script> '</div>
<link type="text/css" rel="stylesheet" href="../css/tabpane.css" />'.$this->renderZones($tax_rules, $this->context->language->id); </div>
echo '
<div class="margin-form" style="margin-top: 10px"> <label>'.$this->l('Tax').'</label>
<input type="submit" value="'.$this->l(' Save ').'" name="submitAdd'.$this->table.'" class="button" />&nbsp;&nbsp; <div class="margin-form">
<input type="submit" value="'.$this->l('Save and stay').'" name="submitAdd'.$this->table.'AndStay" class="button" /> '.$tax_select.' '.$this->l('(Total tax:').'9%'.')
</div>
<label>'.$this->l('Description').'</label>
<div class="margin-form">
<input type="text" id="description" name="description" />&nbsp;
</div>
<div class="margin-form">
<input type="submit" value="'.$this->l(' Save ').'" name="create_rule" class="button" />
</div>
</div> </div>
</fieldset> </form>
</form>'; <br /><br />
} ';
}
/**
* display the list of rules
*
* @param int $id_rule_group
*/
protected function displayRulesList($id_rule_group)
{
echo '<table class="table" cellspacing="0" cellpadding="0" style="text-align: center; width: 100%;">
<thead>
<tr>
<th>'.$this->l('Country').'</th>
<th>'.$this->l('State').'</th>
<th>'.$this->l('ZipCodes').'</th>
<th>'.$this->l('Behavior').'</th>
<th>'.$this->l('Tax').'</th>
<th>'.$this->l('Description').'</th>
<th>'.$this->l('Actions').'</th>
</tr>
</thead>
<tbody>
'.$this->displayTaxRules((int)$id_rule_group).'
</tbody>
</table>';
}
public function renderZones($tax_rules, $id_lang) /**
{ * display the tax rules list table body
$html = ''; *
$zones = Zone::getZones(true); * @param int $id_rule_group
foreach ($zones AS $key => $zone) */
{ protected function displayTaxRules($id_rule_group)
$html .= '<div class="tab-page" id="tab-page-'.$key.'"> {
<h4 class="tab">'.$zone['name'].'</h4> global $currentIndex, $cookie;
<script type="text/javascript">
tabPane1.addTabPage( document.getElementById( "tab-page-'.$key.'" ) );
</script>
'.$this->renderCountries($tax_rules, $zone['id_zone'], $id_lang).'
</div>';
}
return $html; $html = '';
} $tax_rules = TaxRule::getTaxRulesByGroupId((int)$cookie->id_lang, (int)$id_rule_group);
if (sizeof($tax_rules) == 0)
{
$html .= '<tr>
<td colspan="7">'.$this->l('No rules defined').'</td>
</tr>';
} else {
foreach ($tax_rules as $tax_rule)
{
// format fields for display
$state_name = ($tax_rule['state_name'] == '' ? '*' : $tax_rule['state_name']);
public function renderCountries($tax_rules, $id_zone, $id_lang) $zipcodes = '*';
{ if (isset($tax_rule['zipcode_from']) && $tax_rule['zipcode_from'] != 0)
{
$zipcodes = $tax_rule['zipcode_from'];
if (isset($tax_rule['zipcode_to']) && $tax_rule['zipcode_to'] != 0 && $tax_rule['zipcode_to'] != $tax_rule['zipcode_from'])
{
$zipcodes .= '-'.$tax_rule['zipcode_to'];
}
}
$html = ' $tax = ((float)$tax_rule['rate'] == 0 ? '-' : (float)$tax_rule['rate'].'%');
<table>
<tr>
<td width="260px" style="font-weight:bold">'.$this->l('All').'</td>
<td>'.$this->renderTaxesSelect($id_lang, '', array('id' => 'zone_'.(int)$id_zone)).' <input type="submit" onclick="return applyTax(\''.(int)$id_zone.'\')" class="button" value="'.$this->l('Apply').'"/></td>
</tr>
</table><hr />';
$html .= ' $behavior = ($tax_rule['behavior'] == 0 ? $this->l('This tax only') : $this->l('Compute with others'));
<table class="table" cellpadding="0" cellspacing="0" style="width: 100%;">
<thead>
<tr>
<th style="width: 3%;"></th>
<th style="width: 40%;">'.$this->l('Country / State / County').'</th>
<th style="width: 57%;">'.$this->l('Tax to apply').'</th>
</tr>
</thead>
<tbody>
';
$countries = Country::getCountriesByZoneId((int)$id_zone, (int)$id_lang);
$countCountries = sizeof($countries);
$i = 1;
foreach ($countries AS $country) // render fields
{ $html .= '<tr>
$id_tax = 0; <td>'.Tools::htmlentitiesUTF8($tax_rule['country_name']).'</td>
<td>'.Tools::htmlentitiesUTF8($state_name).'</td>
<td>'.Tools::htmlentitiesUTF8($zipcodes).'</td>
<td>'.Tools::htmlentitiesUTF8($behavior).'</td>
<td>'.Tools::htmlentitiesUTF8($tax).'</td>
<td>'.Tools::htmlentitiesUTF8($tax_rule['description']).'</td>
<td>
<a href="#" onclick="loadTaxRule(\''.$tax_rule['id_tax_rule'].'\'); return false;">
<img src="../img/admin/edit.gif" border="0" alt="'.$this->l('Edit').'" title="'.$this->l('Edit').'" />
</a>
<a href="'.$currentIndex.'&id_tax_rule='.$tax_rule['id_tax_rule'].'&action=delete_rule&token='.$this->token.'" onclick="return confirm(\''.addslashes($this->l('Delete item ?')).'\');">
<img src="../img/admin/delete.gif" border="0" alt="'.$this->l('Delete').'" title="'.$this->l('Delete').'" />
</a>
if (array_key_exists($country['id_country'], $tax_rules) AND array_key_exists(0, $tax_rules[$country['id_country']])) </td>
$id_tax = (int)$tax_rules[$country['id_country']][0][0]['id_tax']; </tr>';
$html .= '
<tr>
<td>'.($country['contains_states'] ? '<a class="open_state" id="state_'.(int)$country['id_country'].'"><img id="state_'.(int)$country['id_country'].'_button" src="../img/admin/more.png" alt="" style="vertical-align:middle;padding:0;" /></a>' : '').'</td>
<td>
<img src="../img/admin/lv2_'.($i == $countCountries ? 'f' : 'b').'.png" alt="" style="vertical-align:middle;" /> <label class="t">'.Tools::htmlentitiesUTF8($country['name']).'</label>
</td>
<td>'.$this->renderTaxesSelect($id_lang, $id_tax, array('class' => 'tax_'.$id_zone, 'id' => 'tax_'.$country['id_country'].'_0', 'name' => 'tax_'.$country['id_country'].'_0' )).'</td>
</tr>
';
if ($country['contains_states']) {
$html .= $this->renderStates($tax_rules, (int)$id_zone, (int)$country['id_country'], (int)$id_lang);
} }
}
$i++;
}
$html .= '
</tbody>
</table>
';
return $html; return $html;
} }
public function renderStates($tax_rules, $id_zone, $id_country, $id_lang) /**
{ * @param boolean $firstCall
$states = State::getStatesByIdCountry((int)$id_country); */
$countStates = sizeof($states); public function displayForm($firstCall = true)
$i = 1; {
$html = ''; if (!($obj = $this->loadObject(true)))
foreach ($states AS $state) return;
parent::displayForm();
$this->displayRuleGroupForm();
$this->displayJS();
// display tax rules only if the group has already been created
if ($obj->id)
{ {
$id_tax = 0; echo '<hr />';
$selected = PS_PRODUCT_TAX; $this->displayTaxRulesErrors();
$this->displayRuleForm($obj->id);
if (array_key_exists($id_country, $tax_rules) $this->displayRulesList($obj->id);
AND array_key_exists($state['id_state'], $tax_rules[$id_country])
AND array_key_exists(0, $tax_rules[$id_country][$state['id_state']]))
{
$id_tax = (int)$tax_rules[$id_country][$state['id_state']][0]['id_tax'];
$selected = (int)$tax_rules[$id_country][$state['id_state']][0]['state_behavior'];
}
$disable = (PS_PRODUCT_TAX == $selected ? 'disabled' : '');
$html .= '
<tr class="states state_'.(int)$id_country.' alt_row">
<td>'.(State::hasCounties($state['id_state']) ? '<a class="open_county" id="county_'.(int)$state['id_state'].'"><img id="county_'.(int)$state['id_state'].'_button" class="county_state_'.(int)$id_country.'_button" src="../img/admin/more.png" alt="" /></a>' : '').'</td>
<td><img src="../img/admin/lv3_'.($i == $countStates ? 'f' : 'b').'.png" alt="" style="vertical-align:middle;" /> <label class="t">'.Tools::htmlentitiesUTF8($state['name']).'</label></td>
<td>
'.$this->renderTaxesSelect($id_lang, $id_tax, array('class' => 'tax_'.$id_zone,
'id' => 'tax_'.$id_country.'_'.$state['id_state'],
'name' => 'tax_'.$id_country.'_'.$state['id_state'],
'disabled' => $disable )).'&nbsp;-&nbsp;
<select id="behavior_state_'.$state['id_state'].'" name="behavior_state_'.$state['id_state'].'" onchange="disableStateTaxRate(\''.$id_country.'\',\''.$state['id_state'].'\')">
<option value="'.(int)PS_PRODUCT_TAX.'" '.($selected == PS_PRODUCT_TAX ? 'selected="selected"' : '').'>'.$this->l('Apply country tax only').'</option>
<option value="'.(int)PS_STATE_TAX.'" '.($selected == PS_STATE_TAX ? 'selected="selected"' : '').'>'.$this->l('Apply state tax only').'</option>
<option value="'.(int)PS_BOTH_TAX.'" '.($selected == PS_BOTH_TAX ? 'selected="selected"' : '').'>'.$this->l('Apply both taxes').'</option>
</select>
</td>
</tr>
';
if (State::hasCounties($state['id_state']))
$html .= $this->renderCounties($tax_rules, $id_zone, $id_country, $state['id_state'], $id_lang);
$i++;
} }
}
return $html;
}
public function renderCounties($tax_rules, $id_zone, $id_country, $id_state, $id_lang)
{
$counties = County::getCounties((int)$id_state);
$countCounties = sizeof($counties);
$i = 1;
$html = '';
foreach ($counties AS $county)
{
$id_tax = 0;
$selected = County::USE_STATE_TAX;
if (array_key_exists($id_country, $tax_rules)
AND array_key_exists($id_state, $tax_rules[$id_country])
AND array_key_exists($county['id_county'], $tax_rules[$id_country][$id_state]))
{
$id_tax = (int)$tax_rules[$id_country][$id_state][$county['id_county']]['id_tax'];
$selected = (int)$tax_rules[$id_country][$id_state][$county['id_county']]['county_behavior'];
}
$disable = (County::USE_STATE_TAX == $selected ? 'disabled' : '');
$html .= '
<tr class="counties county_state_'.(int)$id_country.' county_'.(int)$id_state.'">
<td></td>
<td><img src="../img/admin/lv4_'.($i == $countCounties ? 'f' : 'b').'.png" alt="" style="vertical-align:middle;" /> <label class="t">'.Tools::htmlentitiesUTF8($county['name']).'</label></td>
<td>
'.$this->renderTaxesSelect($id_lang, $id_tax, array('class' => 'tax_'.$id_zone,
'id' => 'tax_'.$id_country.'_'.$id_state.'_'.$county['id_county'],
'name' => 'tax_'.$id_country.'_'.$id_state.'_'.$county['id_county'],
'disabled' => $disable )).'&nbsp;-&nbsp;
<select id="behavior_county_'.$county['id_county'].'" name="behavior_county_'.$county['id_county'].'" onchange="disableCountyTaxRate(\''.$id_country.'\',\''.$id_state.'\',\''.$county['id_county'].'\')">
<option value="'.(int)County::USE_STATE_TAX.'" '.($selected == County::USE_STATE_TAX ? 'selected="selected"' : '').'>'.$this->l('Apply state tax only').'</option>
<option value="'.(int)County::USE_COUNTY_TAX.'" '.($selected == County::USE_COUNTY_TAX ? 'selected="selected"' : '').'>'.$this->l('Apply county tax only').'</option>
<option value="'.(int)County::USE_BOTH_TAX.'" '.($selected == County::USE_BOTH_TAX ? 'selected="selected"' : '').'>'.$this->l('Apply both taxes').'</option>
</select>
</td>
</tr>
';
}
return $html;
}
public function renderTaxesSelect($id_lang, $default_value, $html_options)
{
$opt = '';
foreach( array('id', 'class', 'name', 'disabled') AS $prop)
if (array_key_exists($prop, $html_options) && !empty($html_options[$prop]))
$opt .= $prop.'="'.$html_options[$prop].'"';
$html = '<select '.$opt.'>
<option value="0">'.$this->l('No Tax').'</option>';
$taxes = Tax::getTaxes((int)$id_lang, true);
foreach ($taxes AS $tax)
{
$selected = ($default_value == $tax['id_tax']) ? 'selected="selected"' : '';
$html .= '<option value="'.(int)$tax['id_tax'].'" '.$selected.'>'.Tools::htmlentitiesUTF8($tax['name']).'</option>';
}
$html .= '</select>';
return $html;
}
protected function afterAdd($object)
{
$this->afterUpdate($object);
}
protected function afterUpdate($object)
{
TaxRule::deleteByGroupId($object->id);
foreach(Country::getCountries($this->context->language->id, true) AS $country)
{
$id_tax = (int)Tools::getValue('tax_'.$country['id_country'].'_0');
// default country rule
if (!empty($id_tax))
{
$tr = new TaxRule();
$tr->id_tax_rules_group = $object->id;
$tr->id_country = (int)$country['id_country'];
$tr->id_state = 0;
$tr->id_county = 0;
$tr->id_tax = $id_tax;
$tr->state_behavior = 0;
$tr->county_behavior = 0;
$tr->save();
}
// state specific rule
if (!empty($country['contains_states']))
{
foreach ($country['states'] AS $state)
{
$state_behavior = (int)Tools::getValue('behavior_state_'.$state['id_state']);
if ($state_behavior != PS_PRODUCT_TAX)
{
$tr = new TaxRule();
$tr->id_tax_rules_group = $object->id;
$tr->id_country = (int)$country['id_country'];
$tr->id_state = (int)$state['id_state'];
$tr->id_county = 0;
$tr->id_tax = (int)Tools::getValue('tax_'.$country['id_country'].'_'.$state['id_state']);
$tr->state_behavior = $state_behavior;
$tr->county_behavior = 0;
$tr->save();
}
// county specific rule
if (State::hasCounties($state['id_state']))
{
$counties = County::getCounties($state['id_state']);
foreach ($counties AS $county)
{
$county_behavior = (int)Tools::getValue('behavior_county_'.$county['id_county']);
if ($county_behavior != County::USE_STATE_TAX)
{
$tr = new TaxRule();
$tr->id_tax_rules_group = $object->id;
$tr->id_country = (int)$country['id_country'];
$tr->id_state = (int)$state['id_state'];
$tr->id_county = (int)$county['id_county'];
$tr->id_tax = (int)Tools::getValue('tax_'.$country['id_country'].'_'.$state['id_state'].'_'.$county['id_county']);
$tr->state_behavior = 0;
$tr->county_behavior = $county_behavior;
$tr->save();
}
}
}
}
}
}
}
public function postProcess()
{
if (!isset($this->table))
return false;
// set token
$token = Tools::getValue('token') ? Tools::getValue('token') : $this->token;
if (Tools::getValue('submitAdd'.$this->table))
{
$id_product = Tools::getValue('id_product');
/* Checking fields validity */
$this->validateRules();
if (!sizeof($this->_errors))
{
$id = (int)(Tools::getValue($this->identifier));
/* Object update */
if (isset($id) AND !empty($id))
{
if ($this->tabAccess['edit'] === '1')
{
$object = new $this->className($id);
if (Validate::isLoadedObject($object))
{
/* Specific to objects which must not be deleted */
if ($this->deleted AND $this->beforeDelete($object))
{
// Create new one with old objet values
$objectNew = new $this->className($object->id);
$objectNew->id = NULL;
$objectNew->date_add = '';
$objectNew->date_upd = '';
// Update old object to deleted
$object->deleted = 1;
$object->update();
// Update new object with post values
$this->copyFromPost($objectNew, $this->table);
$result = $objectNew->add();
if (Validate::isLoadedObject($objectNew))
$this->afterDelete($objectNew, $object->id);
}
else
{
$this->copyFromPost($object, $this->table);
$result = $object->update();
$this->afterUpdate($object);
}
if (!$result)
$this->_errors[] = Tools::displayError('An error occurred while updating object.').' <b>'.$this->table.'</b> ('.Db::getInstance()->getMsgError().')';
elseif ($this->postImage($object->id) AND !sizeof($this->_errors))
{
$parent_id = (int)(Tools::getValue('id_parent', 1));
// Save and stay on same form
if (Tools::isSubmit('submitAdd'.$this->table.'AndStay'))
Tools::redirectAdmin(self::$currentIndex.'&'.$this->identifier.'='.$object->id.'&conf=4&update'.$this->table.'&token='.$token);
// Default behavior (save and back)
$id_product = (int)Tools::getValue('id_product');
if ($id_product)
Tools::redirectAdmin('?tab=AdminCatalog&id_product='.$id_product.'&updateproduct&token='.Tools::getAdminToken('AdminCatalog'.(int)(Tab::getIdFromClassName('AdminCatalog')).(int)$this->context->employee->id));
Tools::redirectAdmin(self::$currentIndex.($parent_id ? '&'.$this->identifier.'='.$object->id : '').'&conf=3&token='.$token);
}
}
else
$this->_errors[] = Tools::displayError('An error occurred while updating object.').' <b>'.$this->table.'</b> '.Tools::displayError('(cannot load object)');
}
else
$this->_errors[] = Tools::displayError('You do not have permission to edit here.');
}
/* Object creation */
else
{
if ($this->tabAccess['add'] === '1')
{
$object = new $this->className();
$this->copyFromPost($object, $this->table);
if (!$object->add())
$this->_errors[] = Tools::displayError('An error occurred while creating object.').' <b>'.$this->table.' ('.Db::getInstance()->getMsgError().')</b>';
elseif (($_POST[$this->identifier] = $object->id /* voluntary */) AND $this->postImage($object->id) AND !sizeof($this->_errors) AND $this->_redirect)
{
$parent_id = (int)(Tools::getValue('id_parent', 1));
$this->afterAdd($object);
// Save and stay on same form
if (Tools::isSubmit('submitAdd'.$this->table.'AndStay'))
Tools::redirectAdmin(self::$currentIndex.'&'.$this->identifier.'='.$object->id.'&conf=3&update'.$this->table.'&token='.$token);
$id_product = (int)Tools::getValue('id_product');
if ($id_product)
Tools::redirectAdmin('?tab=AdminCatalog&id_product='.$id_product.'&updateproduct&token='.Tools::getAdminToken('AdminCatalog'.(int)(Tab::getIdFromClassName('AdminCatalog')).(int)$this->context->employee->id));
Tools::redirectAdmin(self::$currentIndex.($parent_id ? '&'.$this->identifier.'='.$object->id : '').'&conf=3&token='.$token);
// Default behavior (save and back)
Tools::redirectAdmin(self::$currentIndex.($parent_id ? '&'.$this->identifier.'='.$object->id : '').'&conf=3&token='.$token);
}
}
else
$this->_errors[] = Tools::displayError('You do not have permission to add here.');
}
}
$this->_errors = array_unique($this->_errors);
}
parent::postProcess();
}
} }
+5 -3
View File
@@ -156,9 +156,9 @@ class AdminTracking extends AdminTab
</tr>'; </tr>';
foreach ($this->_list['obj'] AS $k => $prod) foreach ($this->_list['obj'] AS $k => $prod)
{ {
$product = new Product((int)($prod['id_product'])); $product = new Product((int)$prod['id_product'], false);
$product->name = $product->name[(int)$this->context->language->id]; $product->name = $product->name[(int)$this->context->language->id];
$taxrate = Tax::getProductTaxRate($product->id); $taxrate = $product->getTaxesRate();
echo ' echo '
<tr> <tr>
@@ -222,13 +222,15 @@ class AdminTracking extends AdminTab
else else
$prod['combination_name'] = $prod['group_name'].' : '.$prod['attribute_name']; $prod['combination_name'] = $prod['group_name'].' : '.$prod['attribute_name'];
$attributes[$prod['id_product_attribute']] = $prod; $attributes[$prod['id_product_attribute']] = $prod;
$prevAttributeId = $prod['id_product_attribute']; $prevAttributeId = $prod['id_product_attribute'];
} }
foreach ($attributes AS $prod) foreach ($attributes AS $prod)
{ {
$taxrate = Tax::getProductTaxRate($prod['id_product']); $product = new Product((int)$prod['id_product'], false);
$tax_rate = $product->getTaxesRate();
echo ' echo '
<tr> <tr>
+7
View File
@@ -77,6 +77,8 @@ class Autoload
*/ */
public function load($classname) public function load($classname)
{ {
// echo("Please load $classname.<br />");
// regenerate the class index if the requested class is not found in the index or if the requested file doesn't exists // regenerate the class index if the requested class is not found in the index or if the requested file doesn't exists
if (!isset($this->index[$classname]) || ($this->index[$classname] && !file_exists($this->root_dir.$this->index[$classname]))) if (!isset($this->index[$classname]) || ($this->index[$classname] && !file_exists($this->root_dir.$this->index[$classname])))
$this->generateIndex(); $this->generateIndex();
@@ -87,6 +89,7 @@ class Autoload
// If requested class does not exist, load associated core class // If requested class does not exist, load associated core class
if (isset($this->index[$classname]) && !$this->index[$classname]) if (isset($this->index[$classname]) && !$this->index[$classname])
{ {
require_once($this->root_dir.$this->index[$classname.'Core']); require_once($this->root_dir.$this->index[$classname.'Core']);
if (file_exists($this->root_dir.'override/'.$this->index[$classname.'Core'])) if (file_exists($this->root_dir.'override/'.$this->index[$classname.'Core']))
{ {
@@ -104,10 +107,14 @@ class Autoload
{ {
// request a non Core Class load the associated Core class if exists // request a non Core Class load the associated Core class if exists
if (isset($this->index[$classname.'Core'])) if (isset($this->index[$classname.'Core']))
{
require_once($this->root_dir.$this->index[$classname.'Core']); require_once($this->root_dir.$this->index[$classname.'Core']);
}
if (isset($this->index[$classname])) if (isset($this->index[$classname]))
{
require_once($this->root_dir.$this->index[$classname]); require_once($this->root_dir.$this->index[$classname]);
}
} }
} }
// Call directly ProductCore, ShopCore class // Call directly ProductCore, ShopCore class
+25 -11
View File
@@ -70,7 +70,7 @@ class CarrierCore extends ObjectModel
/** @var boolean Free carrier */ /** @var boolean Free carrier */
public $is_free = false; public $is_free = false;
/** @var int shipping behavior: by weight or by price */ /** @var int shipping behavior: by weight or by price */
public $shipping_method = 0; public $shipping_method = 0;
@@ -82,7 +82,7 @@ class CarrierCore extends ObjectModel
/** @var boolean Need Range */ /** @var boolean Need Range */
public $need_range = 0; public $need_range = 0;
protected $langMultiShop = true; protected $langMultiShop = true;
protected $fieldsRequired = array('name', 'active'); 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['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'] = ($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)); $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; $where .= 'AND id_shop IS NULL AND id_group_shop = '.$shopGroupID;
else else
$where .= 'AND id_shop = '.$shopID; $where .= 'AND id_shop = '.$shopID;
return Db::getInstance()->delete(_DB_PREFIX_.'delivery', $where); return Db::getInstance()->delete(_DB_PREFIX_.'delivery', $where);
} }
@@ -610,7 +610,7 @@ class CarrierCore extends ObjectModel
$keys[] = 'id_shop'; $keys[] = 'id_shop';
if (!in_array('id_group_shop', $keys)) if (!in_array('id_group_shop', $keys))
$keys[] = 'id_group_shop'; $keys[] = 'id_group_shop';
if (!$shop) if (!$shop)
$shop = Context::getContext()->shop; $shop = Context::getContext()->shop;
$shopID = $shop->getID(); $shopID = $shop->getID();
@@ -623,7 +623,7 @@ class CarrierCore extends ObjectModel
$values['id_shop'] = ($shopID) ? $shopID : null; $values['id_shop'] = ($shopID) ? $shopID : null;
if (!isset($values['id_group_shop'])) if (!isset($values['id_group_shop']))
$values['id_group_shop'] = ($shopGroupID) ? $shopGroupID : null; $values['id_group_shop'] = ($shopGroupID) ? $shopGroupID : null;
$sql .= '('; $sql .= '(';
foreach ($values as $v) foreach ($values as $v)
{ {
@@ -650,7 +650,7 @@ class CarrierCore extends ObjectModel
{ {
if (!Validate::isUnsignedId($oldId)) if (!Validate::isUnsignedId($oldId))
die(Tools::displayError()); die(Tools::displayError());
if (!$this->id) if (!$this->id)
return false; return false;
@@ -670,7 +670,7 @@ class CarrierCore extends ObjectModel
VALUES ('.$this->id.','.(float)$val['delimiter1'].','.(float)$val['delimiter2'].')'; VALUES ('.$this->id.','.(float)$val['delimiter1'].','.(float)$val['delimiter2'].')';
Db::getInstance()->Execute($sql); Db::getInstance()->Execute($sql);
$rangeID = (int)Db::getInstance()->Insert_ID(); $rangeID = (int)Db::getInstance()->Insert_ID();
$rangePriceID = ($range == 'range_price') ? $rangeID : 'NULL'; $rangePriceID = ($range == 'range_price') ? $rangeID : 'NULL';
$rangeWeightID = ($range == 'range_weight') ? $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) $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 self::$_cache_tax_rule[$id_carrier];
} }
/**
* Return the taxes rate associated to the carrier
*
* @since 1.5
* @param Address $address
*/
public function getTaxesRate(Address $address)
{
$tax_manager = TaxManagerFactory::getManager($address, $this->id_tax_rules_group);
$tax_calculator = $tax_manager->getTaxCalculator();
return $tax_calculator->getTaxesRate();
}
/** /**
* This tricky method generate a sql clause to check if ranged data are overloaded by multishop * This tricky method generate a sql clause to check if ranged data are overloaded by multishop
* *
* @since 1.5.0 * @since 1.5.0
* @param string $rangeTable * @param string $rangeTable
* @param Shop $shop * @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)'; $where = 'AND ((d2.id_group_shop IS NULL OR d2.id_group_shop = '.$shopGroupID.') AND d2.id_shop IS NULL)';
else 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))'; $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 = ( $sql = 'AND '.$alias.'.id_delivery = (
SELECT d2.id_delivery SELECT d2.id_delivery
FROM '._DB_PREFIX_.'delivery d2 FROM '._DB_PREFIX_.'delivery d2
+60 -58
View File
@@ -28,11 +28,11 @@
class CartCore extends ObjectModel class CartCore extends ObjectModel
{ {
public $id; public $id;
public $id_group_shop; public $id_group_shop;
public $id_shop; public $id_shop;
/** @var integer Customer delivery address ID */ /** @var integer Customer delivery address ID */
public $id_address_delivery; public $id_address_delivery;
@@ -75,7 +75,7 @@ class CartCore extends ObjectModel
public $checkedTos = false; public $checkedTos = false;
public $pictures; public $pictures;
public $textFields; public $textFields;
protected static $_nbProducts = array(); protected static $_nbProducts = array();
protected static $_isVirtualCart = array(); protected static $_isVirtualCart = array();
@@ -129,7 +129,7 @@ class CartCore extends ObjectModel
$fields['id_group_shop'] = (int)$this->id_group_shop; $fields['id_group_shop'] = (int)$this->id_group_shop;
$fields['id_shop'] = (int)$this->id_shop; $fields['id_shop'] = (int)$this->id_shop;
$fields['id_address_delivery'] = (int)($this->id_address_delivery); $fields['id_address_delivery'] = (int)($this->id_address_delivery);
$fields['id_address_invoice'] = (int)($this->id_address_invoice); $fields['id_address_invoice'] = (int)($this->id_address_invoice);
$fields['id_currency'] = (int)($this->id_currency); $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 if ($this->OrderExists()) //NOT delete a cart which is associated with an order
return false; return false;
$uploadedFiles = Db::getInstance()->ExecuteS(' $uploadedFiles = Db::getInstance()->ExecuteS('
SELECT cd.`value` SELECT cd.`value`
FROM `'._DB_PREFIX_.'customized_data` cd FROM `'._DB_PREFIX_.'customized_data` cd
INNER JOIN `'._DB_PREFIX_.'customization` c ON (cd.`id_customization`= c.`id_customization`) INNER JOIN `'._DB_PREFIX_.'customization` c ON (cd.`id_customization`= c.`id_customization`)
WHERE cd.`type`= 0 AND c.`id_cart`='.(int)$this->id); WHERE cd.`type`= 0 AND c.`id_cart`='.(int)$this->id);
foreach ($uploadedFiles as $mustUnlink) foreach ($uploadedFiles as $mustUnlink)
{ {
unlink(_PS_UPLOAD_DIR_.$mustUnlink['value'].'_small'); unlink(_PS_UPLOAD_DIR_.$mustUnlink['value'].'_small');
unlink(_PS_UPLOAD_DIR_.$mustUnlink['value']); unlink(_PS_UPLOAD_DIR_.$mustUnlink['value']);
} }
Db::getInstance()->Execute(' Db::getInstance()->Execute('
DELETE FROM `'._DB_PREFIX_.'customized_data` DELETE FROM `'._DB_PREFIX_.'customized_data`
WHERE `id_customization` IN ( WHERE `id_customization` IN (
SELECT `id_customization` SELECT `id_customization`
FROM `'._DB_PREFIX_.'customization` FROM `'._DB_PREFIX_.'customization`
WHERE `id_cart`='.(int)$this->id.' WHERE `id_cart`='.(int)$this->id.'
)'); )');
Db::getInstance()->Execute(' Db::getInstance()->Execute('
DELETE FROM `'._DB_PREFIX_.'customization` DELETE FROM `'._DB_PREFIX_.'customization`
WHERE `id_cart` = '.(int)$this->id); 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))) OR !Db::getInstance()->Execute('DELETE FROM `'._DB_PREFIX_.'cart_product` WHERE `id_cart` = '.(int)($this->id)))
return false; return false;
return parent::delete(); return parent::delete();
} }
@@ -344,7 +344,7 @@ class CartCore extends ObjectModel
if (is_int($id_product)) if (is_int($id_product))
{ {
foreach ($this->_products as $product) foreach ($this->_products as $product)
if ($product['id_product'] == $id_product) if ($product['id_product'] == $id_product)
return array($product); return array($product);
return array(); return array();
} }
@@ -352,7 +352,7 @@ class CartCore extends ObjectModel
} }
if (!$id_country) if (!$id_country)
$id_country = Context::getContext()->country->id; $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`, $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`, 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, 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_.'product_attribute` pa ON (pa.`id_product_attribute` = cp.`id_product_attribute`)
LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group` LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group`
AND tr.`id_country` = '.(int)$id_country.' AND tr.`id_country` = '.(int)$id_country.'
AND tr.`id_state` = 0) AND tr.`id_state` = 0
AND tr.`zipcode_from` = 0)
LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`) LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`)
LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)$this->id_lang.') LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)$this->id_lang.')
LEFT JOIN `'._DB_PREFIX_.'customization` cu ON (p.`id_product` = cu.`id_product`) LEFT JOIN `'._DB_PREFIX_.'customization` cu ON (p.`id_product` = cu.`id_product`)
@@ -381,6 +382,7 @@ class CartCore extends ObjectModel
AND p.`id_product` IS NOT NULL AND p.`id_product` IS NOT NULL
GROUP BY unique_id GROUP BY unique_id
ORDER BY cp.date_add ASC'; ORDER BY cp.date_add ASC';
$result = Db::getInstance()->ExecuteS($sql); $result = Db::getInstance()->ExecuteS($sql);
// Reset the cache before the following return, or else an empty cart will add dozens of queries // Reset the cache before the following return, or else an empty cart will add dozens of queries
@@ -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'] = 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)); $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')})); $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_wt'] = Tools::ps_round($row['price'] * (float)$row['cart_quantity'] * (1 + (float)($tax_rate) / 100), 2);
$row['total'] = $row['price'] * (int)($row['cart_quantity']); $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_wt'] = $row['price_wt'] * (int)($row['cart_quantity']);
$row['total'] = Tools::ps_round($row['price'] * (int)($row['cart_quantity']), 2); $row['total'] = Tools::ps_round($row['price'] * (int)($row['cart_quantity']), 2);
} }
$row2 = Db::getInstance()->getRow(' $row2 = Db::getInstance()->getRow('
SELECT i.`id_image`, il.`legend` SELECT i.`id_image`, il.`legend`
FROM `'._DB_PREFIX_.'image` i FROM `'._DB_PREFIX_.'image` i
@@ -447,7 +449,7 @@ class CartCore extends ObjectModel
if (!$row2) if (!$row2)
$row2 = array('id_image' => false, 'legend' => false); $row2 = array('id_image' => false, 'legend' => false);
$row = array_merge($row, $row2); $row = array_merge($row, $row2);
$row['reduction_applies'] = ($specificPriceOutput AND (float)$specificPriceOutput['reduction']); $row['reduction_applies'] = ($specificPriceOutput AND (float)$specificPriceOutput['reduction']);
$row['id_image'] = Product::defineProductImage($row,$this->id_lang); $row['id_image'] = Product::defineProductImage($row,$this->id_lang);
$row['allow_oosp'] = Product::isAvailableWhenOutOfStock($row['out_of_stock']); $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) if (isset(self::$_nbProducts[$id]) && self::$_nbProducts[$id] !== NULL)
return self::$_nbProducts[$id]; return self::$_nbProducts[$id];
self::$_nbProducts[$id] = (int)(Db::getInstance()->getValue(' self::$_nbProducts[$id] = (int)(Db::getInstance()->getValue('
SELECT SUM(`quantity`) SELECT SUM(`quantity`)
FROM `'._DB_PREFIX_.'cart_product` FROM `'._DB_PREFIX_.'cart_product`
WHERE `id_cart` = '.(int)($id))); WHERE `id_cart` = '.(int)($id)));
return self::$_nbProducts[$id]; return self::$_nbProducts[$id];
} }
@@ -579,7 +581,7 @@ class CartCore extends ObjectModel
$result = $this->containsProduct($id_product, $id_product_attribute, (int)$id_customization); $result = $this->containsProduct($id_product, $id_product_attribute, (int)$id_customization);
/* Update quantity if product already exist */ /* Update quantity if product already exist */
if ($result) if ($result)
{ {
if ($operator == 'up') if ($operator == 'up')
@@ -652,7 +654,7 @@ class CartCore extends ObjectModel
// refresh cache of self::_products // refresh cache of self::_products
$this->_products = $this->getProducts(true); $this->_products = $this->getProducts(true);
$this->update(true); $this->update(true);
if ($product->customizable) if ($product->customizable)
return $this->_updateCustomizationQuantity((int)$quantity, (int)$id_customization, (int)$id_product, (int)$id_product_attribute, $operator); return $this->_updateCustomizationQuantity((int)$quantity, (int)$id_customization, (int)$id_product, (int)$id_product_attribute, $operator);
else else
@@ -673,15 +675,15 @@ class CartCore extends ObjectModel
if ($field['quantity'] == 0) if ($field['quantity'] == 0)
{ {
Db::getInstance()->Execute(' Db::getInstance()->Execute('
UPDATE `'._DB_PREFIX_.'customization` UPDATE `'._DB_PREFIX_.'customization`
SET `quantity` = '.(int)($quantity).', SET `quantity` = '.(int)($quantity).',
`id_product_attribute` = '.(int)$id_product_attribute.', `id_product_attribute` = '.(int)$id_product_attribute.',
`in_cart` = 1 `in_cart` = 1
WHERE `id_customization` = '.(int)$field['id_customization']); WHERE `id_customization` = '.(int)$field['id_customization']);
} }
} }
} }
/* Deletion */ /* Deletion */
if (!empty($id_customization) AND (int)($quantity) < 1) if (!empty($id_customization) AND (int)($quantity) < 1)
return $this->_deleteCustomization((int)$id_customization, (int)$id_product, (int)$id_product_attribute); 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) 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('DELETE FROM `'._DB_PREFIX_.'customization` WHERE `id_customization` = '.(int)$id_customization);
return Db::getInstance()->Execute(' return Db::getInstance()->Execute('
UPDATE `'._DB_PREFIX_.'customization` UPDATE `'._DB_PREFIX_.'customization`
SET `quantity` = `quantity` '.($operator == 'up' ? '+ ' : '- ').(int)($quantity).' SET `quantity` = `quantity` '.($operator == 'up' ? '+ ' : '- ').(int)($quantity).'
WHERE `id_customization` = '.(int)($id_customization)); WHERE `id_customization` = '.(int)($id_customization));
} }
@@ -726,15 +728,15 @@ class CartCore extends ObjectModel
AND cu.id_product = '.(int)$id_product.' AND cu.id_product = '.(int)$id_product.'
AND in_cart = 0'); 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) foreach($exising_customization as $customization)
{ {
if ($customization['type'] == $type && $customization['index'] == $index) if ($customization['type'] == $type && $customization['index'] == $index)
{ {
Db::getInstance()->Execute(' Db::getInstance()->Execute('
DELETE FROM `'._DB_PREFIX_.'customized_data` DELETE FROM `'._DB_PREFIX_.'customized_data`
WHERE id_customization = '.(int)$customization['id_customization'].' WHERE id_customization = '.(int)$customization['id_customization'].'
AND type = '.(int)$customization['type'].' AND type = '.(int)$customization['type'].'
AND `index` = '.(int)$customization['index']); AND `index` = '.(int)$customization['index']);
@@ -750,7 +752,7 @@ class CartCore extends ObjectModel
}else }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).')'); 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).'\')'; $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 // no shipping cost if is a cart with only virtuals products
$virtual = $this->isVirtualCart(); $virtual = $this->isVirtualCart();
if ($virtual AND $type == Cart::ONLY_SHIPPING) if ($virtual AND $type == Cart::ONLY_SHIPPING)
return 0; return 0;
if ($virtual AND $type == Cart::BOTH) if ($virtual AND $type == Cart::BOTH)
$type = Cart::BOTH_WITHOUT_SHIPPING; $type = Cart::BOTH_WITHOUT_SHIPPING;
@@ -1042,7 +1044,7 @@ class CartCore extends ObjectModel
if (!$default_country) if (!$default_country)
$default_country = Context::getContext()->country; $default_country = Context::getContext()->country;
// Checking discounts in cart // Checking discounts in cart
$products = $this->getProducts(); $products = $this->getProducts();
$discounts = $this->getDiscounts(true); $discounts = $this->getDiscounts(true);
@@ -1087,7 +1089,7 @@ class CartCore extends ObjectModel
if (!Validate::isLoadedObject($default_country)) if (!Validate::isLoadedObject($default_country))
$default_country = new Country(Configuration::get('PS_COUNTRY_DEFAULT'), Configuration::get('PS_LANG_DEFAULT')); $default_country = new Country(Configuration::get('PS_COUNTRY_DEFAULT'), Configuration::get('PS_LANG_DEFAULT'));
$id_zone = (int)$default_country->id_zone; $id_zone = (int)$default_country->id_zone;
} }
// If no carrier, select default one // If no carrier, select default one
if (!$id_carrier) if (!$id_carrier)
@@ -1173,14 +1175,14 @@ class CartCore extends ObjectModel
die(Tools::displayError('Fatal error: "no default carrier"')); die(Tools::displayError('Fatal error: "no default carrier"'));
if (!$carrier->active) if (!$carrier->active)
return $shipping_cost; return $shipping_cost;
// Free fees if free carrier // Free fees if free carrier
if ($carrier->is_free == 1) if ($carrier->is_free == 1)
return 0; return 0;
// Select carrier tax // Select carrier tax
if ($useTax AND !Tax::excludeTaxeOption()) if ($useTax AND !Tax::excludeTaxeOption())
$carrierTax = Tax::getCarrierTaxRate((int)$carrier->id, (int)$this->{Configuration::get('PS_TAX_ADDRESS_TYPE')}); $carrierTax = $carrier->getTaxesRate(new Address((int)$this->{Configuration::get('PS_TAX_ADDRESS_TYPE')}));
$configuration = Configuration::getMultiple(array('PS_SHIPPING_FREE_PRICE', 'PS_SHIPPING_HANDLING', 'PS_SHIPPING_METHOD', 'PS_SHIPPING_FREE_WEIGHT')); $configuration = Configuration::getMultiple(array('PS_SHIPPING_FREE_PRICE', 'PS_SHIPPING_HANDLING', 'PS_SHIPPING_METHOD', 'PS_SHIPPING_FREE_WEIGHT'));
// Free fees // Free fees
@@ -1238,7 +1240,7 @@ class CartCore extends ObjectModel
{ {
$moduleName = $carrier->external_module_name; $moduleName = $carrier->external_module_name;
$module = Module::getInstanceByName($moduleName); $module = Module::getInstanceByName($moduleName);
if (Validate::isLoadedObject($module)) if (Validate::isLoadedObject($module))
{ {
if (array_key_exists('id_carrier', $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 * @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) Customer $customer = null, Shop $shop = null)
{ {
if (!$shop) if (!$shop)
$shop = Context::getContext()->shop; $shop = Context::getContext()->shop;
if (!$customer) if (!$customer)
$customer = Context::getContext()->customer; $customer = Context::getContext()->customer;
if (!$order_total) if (!$order_total)
return Tools::displayError('Cannot add voucher if order is free.'); return Tools::displayError('Cannot add voucher if order is free.');
if (!$discountObj->active) if (!$discountObj->active)
@@ -1331,12 +1333,12 @@ class CartCore extends ObjectModel
foreach ($discounts as $discount) foreach ($discounts as $discount)
if (!$discount['cumulable']) if (!$discount['cumulable'])
return Tools::displayError('Voucher is not valid with other discounts.'); return Tools::displayError('Voucher is not valid with other discounts.');
foreach($discounts as $discount) foreach($discounts as $discount)
if($discount['id_discount'] == $discountObj->id) if($discount['id_discount'] == $discountObj->id)
return Tools::displayError('This voucher is already in your cart'); return Tools::displayError('This voucher is already in your cart');
} }
$groups = Customer::getGroupsStatic($this->id_customer); $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))) 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 // New layout system with personalization fields
$formattedAddresses['invoice'] = AddressFormat::getFormattedLayoutData($invoice); $formattedAddresses['invoice'] = AddressFormat::getFormattedLayoutData($invoice);
$formattedAddresses['delivery'] = AddressFormat::getFormattedLayoutData($delivery); $formattedAddresses['delivery'] = AddressFormat::getFormattedLayoutData($delivery);
$total_tax = $this->getOrderTotal() - $this->getOrderTotal(false); $total_tax = $this->getOrderTotal() - $this->getOrderTotal(false);
if ($total_tax < 0) if ($total_tax < 0)
@@ -1513,7 +1515,7 @@ class CartCore extends ObjectModel
$textValue = str_replace(array("\n", "\r"), '', nl2br($textValue)); $textValue = str_replace(array("\n", "\r"), '', nl2br($textValue));
$textValue = str_replace('\\', '\\\\', $textValue); $textValue = str_replace('\\', '\\\\', $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) 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 * Remove a customer's customization
* *
@@ -1534,7 +1536,7 @@ class CartCore extends ObjectModel
public function deleteCustomizationToProduct($id_product, $index) public function deleteCustomizationToProduct($id_product, $index)
{ {
$result = true; $result = true;
$custData = Db::getInstance()->getRow(' $custData = Db::getInstance()->getRow('
SELECT cu.`id_customization`, cd.`index`, cd.`value`, cd.`type` FROM `'._DB_PREFIX_.'customization` cu SELECT cu.`id_customization`, cd.`index`, cd.`value`, cd.`type` FROM `'._DB_PREFIX_.'customization` cu
LEFT JOIN `'._DB_PREFIX_.'customized_data` cd LEFT JOIN `'._DB_PREFIX_.'customized_data` cd
@@ -1544,7 +1546,7 @@ class CartCore extends ObjectModel
AND `index` = '.(int)$index.' AND `index` = '.(int)$index.'
AND `in_cart` = 0' AND `in_cart` = 0'
); );
// Delete customization picture if necessary // Delete customization picture if necessary
if ($custData['type'] == 0) if ($custData['type'] == 0)
$result &= (@unlink(_PS_UPLOAD_DIR_.$custData['value']) && @unlink(_PS_UPLOAD_DIR_.$custData['value'].'_small')); $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 $result;
} }
/** /**
* Return custom pictures in this cart for a specified product * Return custom pictures in this cart for a specified product
* *
@@ -1603,7 +1605,7 @@ class CartCore extends ObjectModel
$cart->id = NULL; $cart->id = NULL;
$cart->id_shop = $this->id_shop; $cart->id_shop = $this->id_shop;
$cart->id_group_shop = $this->id_group_shop; $cart->id_group_shop = $this->id_group_shop;
$cart->add(); $cart->add();
if (!Validate::isLoadedObject($cart)) if (!Validate::isLoadedObject($cart))
@@ -1620,7 +1622,7 @@ class CartCore extends ObjectModel
FROM '._DB_PREFIX_.'customization c FROM '._DB_PREFIX_.'customization c
LEFT JOIN '._DB_PREFIX_.'customized_data cd ON cd.id_customization = c.id_customization LEFT JOIN '._DB_PREFIX_.'customized_data cd ON cd.id_customization = c.id_customization
WHERE c.id_cart = '.(int)$this->id); WHERE c.id_cart = '.(int)$this->id);
// Group line by id_customization // Group line by id_customization
$customsById = array(); $customsById = array();
foreach ($customs AS $custom) foreach ($customs AS $custom)
@@ -1629,7 +1631,7 @@ class CartCore extends ObjectModel
$customsById[$custom['id_customization']] = array(); $customsById[$custom['id_customization']] = array();
$customsById[$custom['id_customization']][] = $custom; $customsById[$custom['id_customization']][] = $custom;
} }
// Insert new customizations // Insert new customizations
$custom_ids = array(); $custom_ids = array();
foreach($customsById as $customizationId => $val) 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'].')'); 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(); $custom_ids[$custom['id_customization']] = Db::getInstance(_PS_USE_SQL_SLAVE_)->Insert_ID();
} }
// Insert customized_data // Insert customized_data
if (sizeof($customs)) if (sizeof($customs))
{ {
@@ -1655,7 +1657,7 @@ class CartCore extends ObjectModel
} }
Db::getInstance(_PS_USE_SQL_SLAVE_)->Execute($sql_custom_data); Db::getInstance(_PS_USE_SQL_SLAVE_)->Execute($sql_custom_data);
} }
return array('cart' => $cart, 'success' => $success); 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_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.')
LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group` LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group`
AND tr.`id_country` = '.(int)$context->country->id.' AND tr.`id_country` = '.(int)$context->country->id.'
AND tr.`id_state` = 0) AND tr.`id_state` = 0
AND tr.`zipcode_from` = 0)
LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`) LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`)
LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)$id_lang.') LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)$id_lang.')
LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON m.`id_manufacturer` = p.`id_manufacturer` LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON m.`id_manufacturer` = p.`id_manufacturer`
+55 -135
View File
@@ -25,6 +25,10 @@
* International Registered Trademark & Property of PrestaShop SA * International Registered Trademark & Property of PrestaShop SA
*/ */
/**
* @deprecated since 1.5
*/
class CountyCore extends ObjectModel class CountyCore extends ObjectModel
{ {
public $id; public $id;
@@ -63,181 +67,97 @@ class CountyCore extends ObjectModel
public function delete() public function delete()
{ {
$id = $this->id; return true;
parent::delete();
// remove associated zip codes & tax rule
return (County::deleteZipCodeByIdCounty($id) AND TaxRule::deleteTaxRuleByIdCounty($id));
} }
/**
* @deprecated since 1.5
*/
public static function getCounties($id_state) public static function getCounties($id_state)
{ {
if (!isset(self::$_cache_get_counties[$id_state])) Tools::displayAsDeprecated();
{ return false;
self::$_cache_get_counties[$id_state] = Db::getInstance()->ExecuteS('
SELECT * FROM `'._DB_PREFIX_.'county`
WHERE `id_state` = '.(int)$id_state
);
}
return self::$_cache_get_counties[$id_state];
} }
// return the list of associated zipcode /**
* @deprecated since 1.5
*/
public function getZipCodes() public function getZipCodes()
{ {
return Db::getInstance()->ExecuteS(' Tools::displayAsDeprecated();
SELECT * FROM `'._DB_PREFIX_.'county_zip_code` return false;
WHERE `id_county` = '.(int)$this->id.'
ORDER BY `from_zip_code` ASC'
);
} }
/**
* @deprecated since 1.5
*/
public function addZipCodes($zip_codes) public function addZipCodes($zip_codes)
{ {
list($from, $to) = $this->breakDownZipCode($zip_codes); Tools::displayAsDeprecated();
return true;
if ($from == 0)
return false;
return Db::getInstance()->Execute(
'INSERT INTO `'._DB_PREFIX_.'county_zip_code` (`id_county`, `from_zip_code`, `to_zip_code`)
VALUES ('.(int)$this->id.','.(int)$from.','.(int)$to.')'
);
} }
/**
* @deprecated since 1.5
*/
public function removeZipCodes($zip_codes) public function removeZipCodes($zip_codes)
{ {
list($from, $to) = $this->breakDownZipCode($zip_codes); Tools::displayAsDeprecated();
return true;
if ($from == 0)
return false;
return Db::getInstance()->Execute('
DELETE FROM `'._DB_PREFIX_.'county_zip_code`
WHERE `id_county` = '.(int)$this->id.'
AND `from_zip_code` = '.(int)$from.'
AND `to_zip_code` = '.(int)$to
);
} }
/**
* @deprecated since 1.5
*/
public function breakDownZipCode($zip_codes) public function breakDownZipCode($zip_codes)
{ {
$zip_codes = preg_split('/-/', $zip_codes); Tools::displayAsDeprecated();
return array(0,0);
if (sizeof($zip_codes) == 2)
{
$from = $zip_codes[0];
$to = $zip_codes[1];
if ($zip_codes[0] > $zip_codes[1])
{
$from = $zip_codes[1];
$to = $zip_codes[0];
}
else if ($zip_codes[0] == $zip_codes[1])
{
$from = $zip_codes[0];
$to = 0;
}
}
else if (sizeof($zip_codes) == 1)
{
$from = $zip_codes[0];
$to = 0;
}
if (!Validate::isInt($from) OR !Validate::isInt($to))
{
$from = 0;
$to = 0;
}
return array($from, $to);
} }
/**
* @deprecated since 1.5
*/
public static function getIdCountyByZipCode($id_state, $zip_code) public static function getIdCountyByZipCode($id_state, $zip_code)
{ {
if (!isset(self::$_cache_county_zipcode[$id_state.'-'.$zip_code])) Tools::displayAsDeprecated();
{ return false;
self::$_cache_county_zipcode[$id_state.'-'.$zip_code] = Db::getInstance()->getValue('
SELECT DISTINCT c.`id_county` FROM `'._DB_PREFIX_.'county` c
LEFT JOIN `'._DB_PREFIX_.'county_zip_code` cz ON (c.`id_county` = cz.`id_county`)
WHERE `id_state` = '.(int)$id_state.'
AND cz.`from_zip_code` >= '.(int)$zip_code.'
AND cz.`to_zip_code` <= '.(int)$zip_code
);
}
return self::$_cache_county_zipcode[$id_state.'-'.$zip_code];
} }
/**
* @deprecated since 1.5
*/
public function isZipCodeRangePresent($zip_codes) public function isZipCodeRangePresent($zip_codes)
{ {
$res = false; Tools::displayAsDeprecated();
list($from, $to) = $this->breakDownZipCode($zip_codes); return false;
if ($from == 0)
return false;
if ($to != 0)
{
$res = Db::getInstance()->getValue('
SELECT COUNT(*) FROM `'._DB_PREFIX_.'county_zip_code` cz
LEFT JOIN `'._DB_PREFIX_.'county` c ON (c.`id_county` = cz.`id_county`)
LEFT JOIN `'._DB_PREFIX_.'state` s ON (s.`id_state` = c.`id_state`)
WHERE `from_zip_code` >= '.(int)$from.'
AND `to_zip_code` <= '.(int)$to.'
AND s.`id_country` = (SELECT `id_country`
FROM `'._DB_PREFIX_.'state` s
LEFT JOIN `'._DB_PREFIX_.'county` c ON (c.`id_state` = s.`id_state`)
WHERE `id_county` = '.(int)$this->id.'
)'
);
}
return ($res OR County::isZipCodePresent($from) OR County::isZipCodePresent($to));
} }
/**
* @deprecated since 1.5
*/
public function isZipCodePresent($zip_code) public function isZipCodePresent($zip_code)
{ {
Tools::displayAsDeprecated();
if ($zip_code == 0) return false;
return false;
return (bool) Db::getInstance()->getValue('
SELECT COUNT(*) FROM `'._DB_PREFIX_.'county_zip_code` cz
LEFT JOIN `'._DB_PREFIX_.'county` c ON (c.`id_county` = cz.`id_county`)
LEFT JOIN `'._DB_PREFIX_.'state` s ON (s.`id_state` = c.`id_state`)
WHERE
(`from_zip_code` <= '.(int)$zip_code.' AND `to_zip_code` >= '.(int)$zip_code.')
OR
(`from_zip_code` = '.(int)$zip_code.')
AND s.`id_country` = (SELECT `id_country`
FROM `'._DB_PREFIX_.'state` s
LEFT JOIN `'._DB_PREFIX_.'county` c ON (c.`id_state` = s.`id_state`)
WHERE `id_county` = '.(int)$this->id.'
)'
);
} }
/**
* @deprecated since 1.5
*/
public static function deleteZipCodeByIdCounty($id_county) public static function deleteZipCodeByIdCounty($id_county)
{ {
return Db::getInstance()->Execute( Tools::displayAsDeprecated();
'DELETE FROM `'._DB_PREFIX_.'county_zip_code` return true;
WHERE `id_county` = '.(int)$id_county
);
} }
/**
* @deprecated since 1.5
*/
public static function getIdCountyByNameAndIdState($name, $id_state) public static function getIdCountyByNameAndIdState($name, $id_state)
{ {
return Db::getInstance()->getValue(' Tools::displayAsDeprecated();
SELECT `id_county` FROM `'._DB_PREFIX_.'county` return false;
WHERE `name` = \''.pSQL($name).'\'
AND `id_state` = '.(int)$id_state
);
} }
} }
+86 -19
View File
@@ -34,7 +34,7 @@ class HelperCore
public static $translationsKeysForAdminCategorieTree = array( public static $translationsKeysForAdminCategorieTree = array(
'Home', 'selected', 'selecteds', 'Collapse All', 'Expand All', 'Check All', 'Uncheck All' 'Home', 'selected', 'selecteds', 'Collapse All', 'Expand All', 'Check All', 'Uncheck All'
); );
/** /**
* *
* @param type $trads values of translations keys * @param type $trads values of translations keys
@@ -42,22 +42,22 @@ class HelperCore
* @param type $selected_cat array of selected categories * @param type $selected_cat array of selected categories
* Format * Format
* Array * Array
( * (
[0] => 1 * [0] => 1
[1] => 2 * [1] => 2
) * )
* OR * OR
Array * Array
( * (
[1] => Array * [1] => Array
( * (
[id_category] => 1 * [id_category] => 1
[name] => Home page * [name] => Home page
[link_rewrite] => home * [link_rewrite] => home
) * )
) * )
* @param type $input_name name of input * @param type $input_name name of input
* @return string * @return string
*/ */
public static function renderAdminCategorieTree($trads, $selected_cat = array(), $input_name = 'categoryBox', $use_radio = false) public static function renderAdminCategorieTree($trads, $selected_cat = array(), $input_name = 'categoryBox', $use_radio = false)
{ {
@@ -86,7 +86,7 @@ class HelperCore
</script> </script>
<link type="text/css" rel="stylesheet" href="../css/jquery.treeview.css" /> <link type="text/css" rel="stylesheet" href="../css/jquery.treeview.css" />
'; ';
$html .= ' $html .= '
<div style="background-color:#F4E6C9; width:99%;padding:5px 0 5px 5px;"> <div style="background-color:#F4E6C9; width:99%;padding:5px 0 5px 5px;">
<a href="#" id="collapse_all" >'.$trads['Collapse All'].'</a> <a href="#" id="collapse_all" >'.$trads['Collapse All'].'</a>
@@ -97,7 +97,7 @@ class HelperCore
' : '').' ' : '').'
</div> </div>
'; ';
$home_is_selected = false; $home_is_selected = false;
foreach($selected_cat AS $cat) foreach($selected_cat AS $cat)
{ {
@@ -121,10 +121,77 @@ class HelperCore
<li id="1" class="hasChildren"> <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> <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> <ul>
<li><span class="placeholder">&nbsp;</span></li> <li><span class="placeholder">&nbsp;</span></li>
</ul> </ul>
</li> </li>
</ul>'; </ul>';
return $html; return $html;
} }
/**
* Create a select input field
*
* @param array $values
* @param array $html_options any key => value options
* @param array $select_options
* - key: the array value that will be used as a key in my select (optional)
* - value: the array value that will be used as a label in my select (optional)
* - empty: the label displayed as an empty value (optional)
* - selected: the key corresponding to the selected value (optional)
*
* @return string html content
*/
public static function selectInput(array $values, array $html_options = array(), array $select_options = array())
{
// options management
$options = self::buildHtmlOptions($html_options);
$select_html = '<select '.$options.'>';
if (isset($select_options['key']))
$use_key = $select_options['key'];
if (isset($select_options['value']))
$use_value = $select_options['value'];
if (isset($select_options['empty']))
$select_html .= '<option value="">'.$select_options['empty'].'</option>';
// render options fields
foreach ($values as $key => $value)
{
$current_key = isset($use_key) ? $value[$use_key] : $key;
$current_value = isset($use_value) ? $value[$use_value] : $value;
if (isset($select_options['selected']) && $select_options['selected'] == $current_key)
$selected = 'selected="selected"';
else
$selected = '';
$select_html .= '<option value="'.Tools::htmlentitiesUTF8($current_key).'" '.$selected.'>'.Tools::htmlentitiesUTF8($current_value).'</option>';
}
$select_html .= '</select>';
return $select_html;
}
/**
* Create html a string containing html options
* eg: buildHtmlOptions(array('name' => 'myInputName', 'id' => 'myInputId'));
* return => 'name="myInputName" id="myInputId"'
*
* @param array $html_options
*
* @return string
*/
protected static function buildHtmlOptions(array $html_options)
{
$html = '';
foreach ($html_options as $html_option => $value)
$html .= Tools::htmlentitiesUTF8($html_option).'="'.Tools::htmlentitiesUTF8($value).'" ';
return rtrim($html, ' ');
}
} }
-52
View File
@@ -117,60 +117,8 @@ class LocalizationPackCore
return false; return false;
} }
} }
// Add counties
foreach ($data->county AS $xml_county)
{
$county_attributes = $xml_county->attributes();
if (!$id_county = County::getIdCountyByNameAndIdState($county_attributes['name'], $state->id))
{
$county = new County();
$county->name = $county_attributes['name'];
$county->id_state = (int)$state->id;
$county->active = 1;
if (!$county->validateFields())
{
$this->_errors[] = Tools::displayError('Invalid County properties');
return false;
}
if (!$county->save())
{
$this->_errors[] = Tools::displayError('An error has occurred while adding the county');
return false;
}
} else {
$county = new County((int)$id_county);
if (!Validate::isLoadedObject($county))
{
$this->_errors[] = Tools::displayError('An error occurred while fetching the county.');
return false;
}
}
// add zip codes
foreach ($xml_county->zipcode AS $xml_zipcode)
{
$zipcode_attributes = $xml_zipcode->attributes();
$zipcodes = $zipcode_attributes['from'];
if (isset($zipcode_attributes['to']))
$zipcodes .= '-'.$zipcode_attributes['to'];
if ($county->isZipCodeRangePresent($zipcodes))
continue;
if (!$county->addZipCodes($zipcodes))
{
$this->_errors[] = Tools::displayError('An error has occurred while adding zipcodes');
return false;
}
}
}
} }
return true; return true;
} }
+3 -2
View File
@@ -286,8 +286,9 @@ class ManufacturerCore extends ObjectModel
LEFT JOIN `'._DB_PREFIX_.'image` i ON (i.`id_product` = p.`id_product` AND i.`cover` = 1) LEFT JOIN `'._DB_PREFIX_.'image` i ON (i.`id_product` = p.`id_product` AND i.`cover` = 1)
LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.') LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.')
LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group` LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group`
AND tr.`id_country` = '.(int)$context->country->id.' AND tr.`id_country` = '.(int)$context->country->id.'
AND tr.`id_state` = 0) AND tr.`id_state` = 0
AND tr.`zipcode_from` = 0)
LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`) LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`)
LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)$id_lang.') LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)$id_lang.')
LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON m.`id_manufacturer` = p.`id_manufacturer` LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON m.`id_manufacturer` = p.`id_manufacturer`
+16 -14
View File
@@ -99,9 +99,12 @@ abstract class PaymentModuleCore extends Module
if ($secure_key !== false AND $secure_key != $cart->secure_key) if ($secure_key !== false AND $secure_key != $cart->secure_key)
die(Tools::displayError()); die(Tools::displayError());
$carrier = new Carrier((int)$cart->id_carrier, (int)$cart->id_lang);
// Copying data from cart // Copying data from cart
$order = new Order(); $order = new Order();
$order->id_carrier = (int)($cart->id_carrier); $order->id_carrier = $carrier->id;
$order->id_customer = (int)($cart->id_customer); $order->id_customer = (int)($cart->id_customer);
$order->id_address_invoice = (int)($cart->id_address_invoice); $order->id_address_invoice = (int)($cart->id_address_invoice);
$order->id_address_delivery = (int)($cart->id_address_delivery); $order->id_address_delivery = (int)($cart->id_address_delivery);
@@ -109,10 +112,10 @@ abstract class PaymentModuleCore extends Module
$order->id_currency = ($currency_special ? (int)($currency_special) : (int)($cart->id_currency)); $order->id_currency = ($currency_special ? (int)($currency_special) : (int)($cart->id_currency));
$order->id_lang = (int)($cart->id_lang); $order->id_lang = (int)($cart->id_lang);
$order->id_cart = (int)($cart->id); $order->id_cart = (int)($cart->id);
$order->id_shop = (int)($shop->getID() ? $shop->getID() : $cart->id_shop); $order->id_shop = (int)($shop->getID() ? $shop->getID() : $cart->id_shop);
$order->id_group_shop = (int)($shop->getID() ? $shop->getGroupID() : $cart->id_group_shop); $order->id_group_shop = (int)($shop->getID() ? $shop->getGroupID() : $cart->id_group_shop);
$customer = new Customer((int)($order->id_customer)); $customer = new Customer((int)($order->id_customer));
$order->secure_key = ($secure_key ? pSQL($secure_key) : pSQL($customer->secure_key)); $order->secure_key = ($secure_key ? pSQL($secure_key) : pSQL($customer->secure_key));
$order->payment = $paymentMethod; $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 = (float)($cart->getOrderTotal(false, Cart::ONLY_PRODUCTS));
$order->total_products_wt = (float)($cart->getOrderTotal(true, Cart::ONLY_PRODUCTS)); $order->total_products_wt = (float)($cart->getOrderTotal(true, Cart::ONLY_PRODUCTS));
$order->total_discounts = (float)(abs($cart->getOrderTotal(true, Cart::ONLY_DISCOUNTS))); $order->total_discounts = (float)(abs($cart->getOrderTotal(true, Cart::ONLY_DISCOUNTS)));
$order->total_shipping = (float)($cart->getOrderShippingCost()); $order->total_shipping = (float)$cart->getOrderShippingCost();
$order->carrier_tax_rate = (float)Tax::getCarrierTaxRate($cart->id_carrier, (int)$cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}); $order->carrier_tax_rate = (float)$carrier->getTaxesRate(new Address((int)$cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}));
$order->total_wrapping = (float)(abs($cart->getOrderTotal(true, Cart::ONLY_WRAPPING))); $order->total_wrapping = (float)(abs($cart->getOrderTotal(true, Cart::ONLY_WRAPPING)));
$order->total_paid = (float)(Tools::ps_round((float)($cart->getOrderTotal(true, Cart::BOTH)), 2)); $order->total_paid = (float)(Tools::ps_round((float)($cart->getOrderTotal(true, Cart::BOTH)), 2));
$order->invoice_date = '0000-00-00 00:00:00'; $order->invoice_date = '0000-00-00 00:00:00';
@@ -256,15 +259,15 @@ abstract class PaymentModuleCore extends Module
if (isset($customization['datas'][_CUSTOMIZE_TEXTFIELD_])) if (isset($customization['datas'][_CUSTOMIZE_TEXTFIELD_]))
foreach ($customization['datas'][_CUSTOMIZE_TEXTFIELD_] AS $text) foreach ($customization['datas'][_CUSTOMIZE_TEXTFIELD_] AS $text)
$customizationText .= $text['name'].':'.' '.$text['value'].'<br />'; $customizationText .= $text['name'].':'.' '.$text['value'].'<br />';
if (isset($customization['datas'][_CUSTOMIZE_FILE_])) if (isset($customization['datas'][_CUSTOMIZE_FILE_]))
$customizationText .= sizeof($customization['datas'][_CUSTOMIZE_FILE_]) .' '. Tools::displayError('image(s)').'<br />'; $customizationText .= sizeof($customization['datas'][_CUSTOMIZE_FILE_]) .' '. Tools::displayError('image(s)').'<br />';
$customizationText .= '---<br />'; $customizationText .= '---<br />';
} }
$customizationText = rtrim($customizationText, '---<br />'); $customizationText = rtrim($customizationText, '---<br />');
$customizationQuantity = (int)($product['customizationQuantityTotal']); $customizationQuantity = (int)($product['customizationQuantityTotal']);
$productsList .= $productsList .=
'<tr style="background-color: '.($key % 2 ? '#DDE2E6' : '#EBECEE').';"> '<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)); $invoice = new Address((int)($order->id_address_invoice));
$delivery = new Address((int)($order->id_address_delivery)); $delivery = new Address((int)($order->id_address_delivery));
$carrier = new Carrier((int)($order->id_carrier), $order->id_lang);
$delivery_state = $delivery->id_state ? new State((int)($delivery->id_state)) : false; $delivery_state = $delivery->id_state ? new State((int)($delivery->id_state)) : false;
$invoice_state = $invoice->id_state ? new State((int)($invoice->id_state)) : false; $invoice_state = $invoice->id_state ? new State((int)($invoice->id_state)) : false;
@@ -387,11 +389,11 @@ abstract class PaymentModuleCore extends Module
'{email}' => $customer->email, '{email}' => $customer->email,
'{delivery_block_txt}' => $this->_getFormatedAddress($delivery, "\n"), '{delivery_block_txt}' => $this->_getFormatedAddress($delivery, "\n"),
'{invoice_block_txt}' => $this->_getFormatedAddress($invoice, "\n"), '{invoice_block_txt}' => $this->_getFormatedAddress($invoice, "\n"),
'{delivery_block_html}' => $this->_getFormatedAddress($delivery, "<br />", '{delivery_block_html}' => $this->_getFormatedAddress($delivery, "<br />",
array( 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>')), '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( 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>')), '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 $tags;
public $isFullyLoaded = false; public $isFullyLoaded = false;
protected $langMultiShop = true; protected $langMultiShop = true;
public $cache_is_pack; public $cache_is_pack;
@@ -202,10 +202,10 @@ class ProductCore extends ObjectModel
protected static $_cacheFeatures = array(); protected static $_cacheFeatures = array();
protected static $_frontFeaturesCache = array(); protected static $_frontFeaturesCache = array();
protected static $producPropertiesCache = array(); protected static $producPropertiesCache = array();
/** @var array cache stock data in getStock() method */ /** @var array cache stock data in getStock() method */
protected static $cacheStock = array(); protected static $cacheStock = array();
/** @var array tables */ /** @var array tables */
protected $tables = array ('product', 'product_lang'); protected $tables = array ('product', 'product_lang');
@@ -303,7 +303,7 @@ class ProductCore extends ObjectModel
parent::__construct($id_product, $id_lang, $id_shop); parent::__construct($id_product, $id_lang, $id_shop);
if (!$context) if (!$context)
$context = Context::getContext(); $context = Context::getContext();
if ($full AND $this->id) if ($full AND $this->id)
{ {
$this->isFullyLoaded = $full; $this->isFullyLoaded = $full;
@@ -311,10 +311,13 @@ class ProductCore extends ObjectModel
$this->manufacturer_name = Manufacturer::getNameById((int)$this->id_manufacturer); $this->manufacturer_name = Manufacturer::getNameById((int)$this->id_manufacturer);
$this->supplier_name = Supplier::getNameById((int)$this->id_supplier); $this->supplier_name = Supplier::getNameById((int)$this->id_supplier);
self::$_tax_rules_group[$this->id] = $this->id_tax_rules_group; self::$_tax_rules_group[$this->id] = $this->id_tax_rules_group;
$address = NULL;
if (is_object($context->cart) AND $context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')} != NULL) if (is_object($context->cart) AND $context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')} != NULL)
$this->tax_rate = Tax::getProductTaxRate($this->id, $context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}); $address = $context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')};
else
$this->tax_rate = Tax::getProductTaxRate($this->id, NULL); $this->tax_rate = $this->getTaxesRate(new Address($address));
$this->new = $this->isNew(); $this->new = $this->isNew();
$this->price = Product::getPriceStatic((int)($this->id), false, NULL, 6, NULL, false, true, 1, false, NULL, NULL, NULL, $this->specificPrice); $this->price = Product::getPriceStatic((int)($this->id), false, NULL, 6, NULL, false, true, 1, false, NULL, NULL, NULL, $this->specificPrice);
$this->unit_price = ($this->unit_price_ratio != 0 ? $this->price / $this->unit_price_ratio : 0); $this->unit_price = ($this->unit_price_ratio != 0 ? $this->price / $this->unit_price_ratio : 0);
@@ -375,7 +378,7 @@ class ProductCore extends ObjectModel
return $fields; return $fields;
} }
public function add($autodate = true, $nullValues = false) public function add($autodate = true, $nullValues = false)
{ {
if (!parent::add($autodate, $nullValues)) 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)); self::$_taxCalculationMethod = Group::getPriceDisplayMethod((int)($customer->id_default_group));
}
else if (Validate::isLoadedObject(Context::getContext()->customer))
self::$_taxCalculationMethod = Group::getPriceDisplayMethod(Context::getContext()->customer->id_default_group);
else else
self::$_taxCalculationMethod = Group::getDefaultPriceDisplayMethod(); self::$_taxCalculationMethod = Group::getDefaultPriceDisplayMethod();
} }
public static function getTaxCalculationMethod($customer = NULL) public static function getTaxCalculationMethod($id_customer = NULL)
{ {
if ($customer) if ($id_customer)
self::initPricesComputation((int)($customer)); self::initPricesComputation((int)($id_customer));
return (int)(self::$_taxCalculationMethod); return (int)(self::$_taxCalculationMethod);
} }
@@ -556,7 +566,7 @@ class ProductCore extends ObjectModel
{ {
if (!GroupReduction::deleteProductReduction($this->id)) if (!GroupReduction::deleteProductReduction($this->id))
return false; return false;
Hook::deleteProduct($this); Hook::deleteProduct($this);
if (!parent::delete() OR if (!parent::delete() OR
!$this->deleteCategories(true) OR !$this->deleteCategories(true) OR
@@ -669,7 +679,7 @@ class ProductCore extends ObjectModel
if (!$this->setGroupReduction()) if (!$this->setGroupReduction())
return false; return false;
return true; return true;
} }
@@ -740,7 +750,7 @@ class ProductCore extends ObjectModel
SELECT `id_image` SELECT `id_image`
FROM `'._DB_PREFIX_.'image` FROM `'._DB_PREFIX_.'image`
WHERE `id_product` = '.(int)($this->id)); WHERE `id_product` = '.(int)($this->id));
$status = true; $status = true;
if ($result) if ($result)
foreach($result as $row) foreach($result as $row)
@@ -1369,7 +1379,7 @@ class ProductCore extends ObjectModel
AND tr.`id_state` = 0) AND tr.`id_state` = 0)
LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`) LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`)
LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON (m.`id_manufacturer` = p.`id_manufacturer`) 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 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 ( AND p.`id_product` IN (
SELECT cp.`id_product` SELECT cp.`id_product`
@@ -1556,7 +1566,7 @@ class ProductCore extends ObjectModel
$ret[] = $val['id_category']; $ret[] = $val['id_category'];
return $ret; return $ret;
} }
public static function getProductCategoriesFull($id_product = '', $id_lang) public static function getProductCategoriesFull($id_product = '', $id_lang)
{ {
$ret = array(); $ret = array();
@@ -1642,7 +1652,7 @@ class ProductCore extends ObjectModel
{ {
if (!$context) if (!$context)
$context = Context::getContext(); $context = Context::getContext();
$cur_cart = $context->cart; $cur_cart = $context->cart;
if (isset($divisor)) if (isset($divisor))
@@ -1680,7 +1690,7 @@ class ProductCore extends ObjectModel
// retrieve address informations // retrieve address informations
$id_country = (int)$context->country->id; $id_country = (int)$context->country->id;
$id_state = 0; $id_state = 0;
$id_county = 0; $zipcode = 0;
if (!$id_address) if (!$id_address)
$id_address = $cur_cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}; $id_address = $cur_cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')};
@@ -1692,18 +1702,14 @@ class ProductCore extends ObjectModel
{ {
$id_country = (int)($address_infos['id_country']); $id_country = (int)($address_infos['id_country']);
$id_state = (int)($address_infos['id_state']); $id_state = (int)($address_infos['id_state']);
$postcode = (int)$address_infos['postcode']; $zipcode = $address_infos['postcode'];
$id_county = (int)County::getIdCountyByZipCode($id_state, $postcode);
} }
} }
elseif (isset($context->customer->geoloc_id_country)) elseif (isset($context->customer->geoloc_id_country))
{ {
$id_country = (int)$context->customer->geoloc_id_country; $id_country = (int)$context->customer->geoloc_id_country;
$id_state = (int)$context->customer->id_state; $id_state = (int)$context->customer->id_state;
$postcode = (int)$context->customer->postcode; $zipcode = (int)$context->customer->postcode;
$id_county = (int)County::getIdCountyByZipCode($id_state, $postcode);
} }
if (Tax::excludeTaxeOption()) if (Tax::excludeTaxeOption())
@@ -1712,7 +1718,7 @@ class ProductCore extends ObjectModel
if ($usetax != false AND !empty($address_infos['vat_number']) AND $address_infos['id_country'] != Configuration::get('VATNUMBER_COUNTRY') AND Configuration::get('VATNUMBER_MANAGEMENT')) if ($usetax != false AND !empty($address_infos['vat_number']) AND $address_infos['id_country'] != Configuration::get('VATNUMBER_COUNTRY') AND Configuration::get('VATNUMBER_MANAGEMENT'))
$usetax = false; $usetax = false;
return Product::priceCalculation($context->shop->getID(), $id_product, $id_product_attribute, $id_country, $id_state, $id_county, $id_currency, $id_group, $quantity, $usetax, $decimals, $only_reduc, return Product::priceCalculation($context->shop->getID(), $id_product, $id_product_attribute, $id_country, $id_state, $zipcode, $id_currency, $id_group, $quantity, $usetax, $decimals, $only_reduc,
$usereduc, $with_ecotax, $specificPriceOutput, $use_groupReduction); $usereduc, $with_ecotax, $specificPriceOutput, $use_groupReduction);
} }
@@ -1733,16 +1739,17 @@ class ProductCore extends ObjectModel
* @param boolean $use_reduc Set if the returned amount will include reduction * @param boolean $use_reduc Set if the returned amount will include reduction
* @param boolean $with_ecotax insert ecotax in price output. * @param boolean $with_ecotax insert ecotax in price output.
* @param variable_reference $specific_price_output If a specific price applies regarding the previous parameters, this variable is filled with the corresponding SpecificPrice object * @param variable_reference $specific_price_output If a specific price applies regarding the previous parameters, this variable is filled with the corresponding SpecificPrice object
*
* @return float Product price * @return float Product price
**/ **/
public static function priceCalculation($id_shop, $id_product, $id_product_attribute, $id_country, $id_state, $id_county, $id_currency, $id_group, $quantity, $use_tax, $decimals, $only_reduc, $use_reduc, $with_ecotax, &$specific_price, $use_groupReduction) public static function priceCalculation($id_shop, $id_product, $id_product_attribute, $id_country, $id_state, $zipcode, $id_currency, $id_group, $quantity, $use_tax, $decimals, $only_reduc, $use_reduc, $with_ecotax, &$specific_price, $use_groupReduction)
{ {
// Caching // Caching
if ($id_product_attribute === NULL) if ($id_product_attribute === NULL)
$product_attribute_label = 'NULL'; $product_attribute_label = 'NULL';
else else
$product_attribute_label = ($id_product_attribute === false ? 'false' : $id_product_attribute); $product_attribute_label = ($id_product_attribute === false ? 'false' : $id_product_attribute);
$cacheId = $id_product.'-'.$id_shop.'-'.$id_currency.'-'.$id_country.'-'.$id_state.'-'.$id_county.'-'.$id_group.'-'.$quantity.'-'.$product_attribute_label.'-'.($use_tax?'1':'0').'-'.$decimals.'-'.($only_reduc?'1':'0').'-'.($use_reduc?'1':'0').'-'.$with_ecotax; $cacheId = $id_product.'-'.$id_shop.'-'.$id_currency.'-'.$id_country.'-'.$id_state.'-'.$zipcode.'-'.$id_group.'-'.$quantity.'-'.$product_attribute_label.'-'.($use_tax?'1':'0').'-'.$decimals.'-'.($only_reduc?'1':'0').'-'.($use_reduc?'1':'0').'-'.$with_ecotax;
// reference parameter is filled before any returns // reference parameter is filled before any returns
$specific_price = SpecificPrice::getSpecificPrice((int)($id_product), $id_shop, $id_currency, $id_country, $id_group, $quantity); $specific_price = SpecificPrice::getSpecificPrice((int)($id_product), $id_shop, $id_currency, $id_country, $id_group, $quantity);
@@ -1773,14 +1780,18 @@ class ProductCore extends ObjectModel
if ($id_product_attribute !== false) // If you want the default combination, please use NULL value instead if ($id_product_attribute !== false) // If you want the default combination, please use NULL value instead
$price += $attribute_price; $price += $attribute_price;
// TaxRate calculation // Tax
$tax_rate = Tax::getProductTaxRateViaRules((int)$id_product, (int)$id_country, (int)$id_state, (int)$id_county); $address = new Address();
if ($tax_rate === false) $address->id_country = $id_country;
$tax_rate = 0; $address->id_state = $id_state;
$address->postcode = $zipcode;
$tax_manager = TaxManagerFactory::getManager($address, Product::getIdTaxRulesGroupByIdProduct((int)$id_product));
$product_tax_calculator = $tax_manager->getTaxCalculator();
// Add Tax // Add Tax
if ($use_tax) if ($use_tax)
$price = $price * (1 + ($tax_rate / 100)); $price = $product_tax_calculator->addTaxes($price);
$price = Tools::ps_round($price, $decimals); $price = Tools::ps_round($price, $decimals);
// Reduction // Reduction
@@ -1793,7 +1804,7 @@ class ProductCore extends ObjectModel
if (!$specific_price['id_currency']) if (!$specific_price['id_currency'])
$reduction_amount = Tools::convertPrice($reduction_amount, $id_currency); $reduction_amount = Tools::convertPrice($reduction_amount, $id_currency);
$reduc = Tools::ps_round(!$use_tax ? $reduction_amount / (1 + $tax_rate / 100) : $reduction_amount, $decimals); $reduc = Tools::ps_round(!$use_tax ? $product_tax_calculator->removeTax($reduction_amount) : $reduction_amount, $decimals);
} }
else else
$reduc = Tools::ps_round($price * $specific_price['reduction'], $decimals); $reduc = Tools::ps_round($price * $specific_price['reduction'], $decimals);
@@ -1825,8 +1836,13 @@ class ProductCore extends ObjectModel
$ecotax = Tools::convertPrice($ecotax, $id_currency); $ecotax = Tools::convertPrice($ecotax, $id_currency);
if ($use_tax) if ($use_tax)
{ {
$taxRate = TaxRulesGroup::getTaxesRate((int)Configuration::get('PS_ECOTAX_TAX_RULES_GROUP_ID'), (int)$id_country, (int)$id_state, (int)$id_county); // reinit the tax manager for ecotax handling
$price += $ecotax * (1 + ($taxRate / 100)); $tax_manager = TaxManagerFactory::getManager(
$address,
(int)Configuration::get('PS_ECOTAX_TAX_RULES_GROUP_ID')
);
$ecotax_tax_calculator = $tax_manager->getTaxCalculator();
$price += $ecotax_tax_calculator->addTaxes($ecotax);
} }
else else
$price += $ecotax; $price += $ecotax;
@@ -1915,7 +1931,7 @@ class ProductCore extends ObjectModel
$ret .= Tools::displayPrice($params['p']['price'], $smarty->ps_currency); $ret .= Tools::displayPrice($params['p']['price'], $smarty->ps_currency);
return $ret; return $ret;
} }
/** /**
* Display price with right format and currency * Display price with right format and currency
* *
@@ -1975,10 +1991,10 @@ class ProductCore extends ObjectModel
$product = new Product($id_product); $product = new Product($id_product);
return $product->getStock($id_product_attribute); return $product->getStock($id_product_attribute);
} }
/** /**
* Create JOIN query with 'stock' table * Create JOIN query with 'stock' table
* *
* @param string $productAlias Alias of product 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 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 * @param bool $innerJoin LEFT JOIN or INNER JOIN
@@ -2002,10 +2018,10 @@ class ProductCore extends ObjectModel
return $sql; return $sql;
} }
/** /**
* Set the stock quantity of current product * Set the stock quantity of current product
* *
* @since 1.5.0 * @since 1.5.0
* @param int $quantity * @param int $quantity
* @param int $id_product_attribute * @param int $id_product_attribute
@@ -2060,7 +2076,7 @@ class ProductCore extends ObjectModel
'quantity' => $quantity, 'quantity' => $quantity,
), 'INSERT'); ), 'INSERT');
} }
// Change stock quantity on product // Change stock quantity on product
if ($id_stock = Stock::getStockId($this->id, $id_product_attribute, $shop->getID(true))) 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 * Get the stock quantity of current product
* *
* @since 1.5.0 * @since 1.5.0
* @param int $id_product_attribute * @param int $id_product_attribute
* @param Context $context * @param Context $context
@@ -2103,6 +2119,7 @@ class ProductCore extends ObjectModel
WHERE id_product = '.$this->id.' WHERE id_product = '.$this->id.'
AND id_product_attribute = '.(int)$id_product_attribute AND id_product_attribute = '.(int)$id_product_attribute
.$context->shop->sqlRestriction(Shop::SHARE_STOCK); .$context->shop->sqlRestriction(Shop::SHARE_STOCK);
self::$cacheStock[$this->id][$id_product_attribute] = (int)Db::getInstance()->getValue($sql); self::$cacheStock[$this->id][$id_product_attribute] = (int)Db::getInstance()->getValue($sql);
} }
return self::$cacheStock[$this->id][$id_product_attribute]; return self::$cacheStock[$this->id][$id_product_attribute];
@@ -2692,7 +2709,7 @@ class ProductCore extends ObjectModel
{ {
if (!$this->isFullyLoaded && is_null($this->tags)) if (!$this->isFullyLoaded && is_null($this->tags))
$this->tags = Tag::getProductTags($this->id); $this->tags = Tag::getProductTags($this->id);
if (!($this->tags AND key_exists($id_lang, $this->tags))) if (!($this->tags AND key_exists($id_lang, $this->tags)))
return ''; return '';
@@ -2714,7 +2731,7 @@ class ProductCore extends ObjectModel
if (!$row['id_product']) if (!$row['id_product'])
return false; return false;
$context = Context::getContext(); $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 // 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']); $row['allow_oosp'] = Product::isAvailableWhenOutOfStock($row['out_of_stock']);
if ((!isset($row['id_product_attribute']) OR !$row['id_product_attribute']) 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']); $fields_present[] = array('id_customization_field' => $field['index'], 'type' => $field['type']);
foreach ($requiredFields AS $required_field) foreach ($requiredFields AS $required_field)
if (!in_array($required_field, $fields_present)) if (!in_array($required_field, $fields_present))
return false; return false;
return true; return true;
} }
public static function idIsOnCategoryId($id_product, $categories) 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('; $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 FROM `'._DB_PREFIX_.'category_product` cp
INNER JOIN `'._DB_PREFIX_.'category_group` ctg ON (ctg.`id_category` = cp.`id_category`) 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'); WHERE cp.`id_product` = '.(int)$this->id.' AND ctg.`id_group` = 1');
else else
return (bool)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue(' return (bool)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('
SELECT cg.`id_group` SELECT cg.`id_group`
FROM `'._DB_PREFIX_.'category_product` cp FROM `'._DB_PREFIX_.'category_product` cp
@@ -3075,7 +3092,7 @@ class ProductCore extends ObjectModel
/** /**
* Add a stock movement for current product * Add a stock movement for current product
* *
* @param int $quantity * @param int $quantity
* @param int $id_reason * @param int $id_reason
* @param int $id_product_attribute * @param int $id_product_attribute
@@ -3155,6 +3172,20 @@ class ProductCore extends ObjectModel
return self::$_tax_rules_group[$id_product]; return self::$_tax_rules_group[$id_product];
} }
/**
* @return the total taxes rate applied to the product
*/
public function getTaxesRate(Address $address = NULL)
{
if (!$address OR !$address->id_country)
$address = Tax::initializeAddress();
$tax_manager = TaxManagerFactory::getManager($address, $this->id_tax_rules_group);
$tax_calculator = $tax_manager->getTaxCalculator();
return $tax_calculator->getTaxesRate();
}
/** /**
* Webservice getter : get product features association * Webservice getter : get product features association
* *
@@ -3368,7 +3399,7 @@ class ProductCore extends ObjectModel
SET `cover` = 1 WHERE `id_product` = '.(int)($this->id).' AND `id_image` = '.(int)$id_image); SET `cover` = 1 WHERE `id_product` = '.(int)($this->id).' AND `id_image` = '.(int)$id_image);
return true; return true;
} }
/** /**
* Webservice getter : get image ids of current product for association * Webservice getter : get image ids of current product for association
* *
@@ -3390,8 +3421,8 @@ class ProductCore extends ObjectModel
FROM `'._DB_PREFIX_.'product_tag` FROM `'._DB_PREFIX_.'product_tag`
WHERE `id_product` = '.(int)($this->id)); WHERE `id_product` = '.(int)($this->id));
} }
public function getWsManufacturerName() public function getWsManufacturerName()
{ {
return Manufacturer::getNameById((int)$this->id_manufacturer); return Manufacturer::getNameById((int)$this->id_manufacturer);
@@ -3404,7 +3435,7 @@ class ProductCore extends ObjectModel
SET ecotax = 0 SET ecotax = 0
'); ');
} }
/** /**
* Set Group reduction if needed * 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_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)($id_lang).')
LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group` LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group`
AND tr.`id_country` = '.(int)Context::getContext()->country->id.' AND tr.`id_country` = '.(int)Context::getContext()->country->id.'
AND tr.`id_state` = 0) AND tr.`id_state` = 0
AND tr.`zipcode_from` = 0)
LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`) LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`)
LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)($id_lang).') LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)($id_lang).')
LEFT JOIN `'._DB_PREFIX_.'supplier` s ON s.`id_supplier` = p.`id_supplier` LEFT JOIN `'._DB_PREFIX_.'supplier` s ON s.`id_supplier` = p.`id_supplier`
+140 -132
View File
@@ -74,138 +74,6 @@ class TaxCore extends ObjectModel
return parent::delete(); return parent::delete();
} }
/**
* Get all available taxes
*
* @return array Taxes
*/
public static function getTaxes($id_lang = false, $active = 1)
{
return Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS('
SELECT t.id_tax, t.rate'.((int)($id_lang) ? ', tl.name, tl.id_lang ' : '').'
FROM `'._DB_PREFIX_.'tax` t
'.((int)($id_lang) ? 'LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)($id_lang).')'
.($active == 1 ? 'WHERE t.`active` = 1' : '').'
ORDER BY `name` ASC' : ''));
}
public static function excludeTaxeOption()
{
return !Configuration::get('PS_TAX');
}
public static function getTaxIdByName($tax_name, $active = 1)
{
$tax = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow('
SELECT t.`id_tax`
FROM `'._DB_PREFIX_.'tax` t
LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (tl.id_tax = t.id_tax)
WHERE tl.`name` = \''.pSQL($tax_name).'\' '.
($active == 1 ? ' AND t.`active` = 1' : ''));
return $tax ? (int)($tax['id_tax']) : false;
}
/**
* Return the product tax
*
* @param integer $id_product
* @param integer $id_country
* @return Tax
*/
public static function getProductTaxRate($id_product, $id_address = NULL)
{
$id_country = (int)Context::getContext()->country->id;
$id_state = 0;
$id_county = 0;
$rate = 0;
if (!empty($id_address))
{
$address_infos = Address::getCountryAndState($id_address);
if ($address_infos['id_country'])
{
$id_country = (int)($address_infos['id_country']);
$id_state = (int)$address_infos['id_state'];
$id_county = (int)County::getIdCountyByZipCode($address_infos['id_state'], $address_infos['postcode']);
}
if (!empty($address_infos['vat_number']) AND $address_infos['id_country'] != Configuration::get('VATNUMBER_COUNTRY') AND Configuration::get('VATNUMBER_MANAGEMENT'))
return 0;
}
if ($rate = Tax::getProductTaxRateViaRules((int)$id_product, (int)$id_country, (int)$id_state, (int)$id_county))
return $rate;
return $rate;
}
public static function getProductEcotaxRate($id_address = NULL)
{
$id_country = (int)Context::getContext()->country->id;
$id_state = 0;
$id_county = 0;
$rate = 0;
if (!empty($id_address))
{
$address_infos = Address::getCountryAndState($id_address);
if ($address_infos['id_country'])
{
$id_country = (int)($address_infos['id_country']);
$id_state = (int)$address_infos['id_state'];
$id_county = (int)County::getIdCountyByZipCode($address_infos['id_state'], $address_infos['postcode']);
}
if (!empty($address_infos['vat_number']) AND $address_infos['id_country'] != Configuration::get('VATNUMBER_COUNTRY') AND Configuration::get('VATNUMBER_MANAGEMENT'))
return 0;
}
if ($rate = TaxRulesGroup::getTaxesRate((int)Configuration::get('PS_ECOTAX_TAX_RULES_GROUP_ID'), (int)$id_country, (int)$id_state, (int)$id_county))
return $rate;
return $rate;
}
/**
* Return the product tax rate using the tax rules system
*
* @param integer $id_product
* @param integer $id_country
* @return Tax
*/
public static function getProductTaxRateViaRules($id_product, $id_country, $id_state, $id_county)
{
if (!isset(self::$_product_tax_via_rules[$id_product.'-'.$id_country.'-'.$id_state.'-'.$id_county]))
{
$tax_rate = TaxRulesGroup::getTaxesRate((int)Product::getIdTaxRulesGroupByIdProduct((int)$id_product), (int)$id_country, (int)$id_state, (int)$id_county);
self::$_product_tax_via_rules[$id_product.'-'.$id_country.'-'.$id_county] = $tax_rate;
}
return self::$_product_tax_via_rules[$id_product.'-'.$id_country.'-'.$id_county];
}
public static function getCarrierTaxRate($id_carrier, $id_address = NULL)
{
$id_country = (int)Context::getContext()->country->id;
$id_state = 0;
$id_county = 0;
if (!empty($id_address))
{
$address_infos = Address::getCountryAndState($id_address);
if ($address_infos['id_country'])
{
$id_country = (int)($address_infos['id_country']);
$id_state = (int)$address_infos['id_state'];
$id_county = (int)County::getIdCountyByZipCode($address_infos['id_state'], $address_infos['postcode']);
}
if (!empty($address_infos['vat_number']) AND $address_infos['id_country'] != Configuration::get('VATNUMBER_COUNTRY') AND Configuration::get('VATNUMBER_MANAGEMENT'))
return 0;
}
return TaxRulesGroup::getTaxesRate((int)Carrier::getIdTaxRulesGroupByIdCarrier((int)$id_carrier), (int)$id_country, (int)$id_state, (int)$id_county);
}
public function toggleStatus() public function toggleStatus()
{ {
if (parent::toggleStatus()) if (parent::toggleStatus())
@@ -229,5 +97,145 @@ class TaxCore extends ObjectModel
return true; return true;
} }
/**
* Get all available taxes
*
* @return array Taxes
*/
public static function getTaxes($id_lang = false, $active = 1)
{
return Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS('
SELECT t.id_tax, t.rate'.((int)($id_lang) ? ', tl.name, tl.id_lang ' : '').'
FROM `'._DB_PREFIX_.'tax` t
'.((int)($id_lang) ? 'LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)($id_lang).')'
.($active == 1 ? 'WHERE t.`active` = 1' : '').'
ORDER BY `name` ASC' : ''));
}
public static function excludeTaxeOption()
{
return !Configuration::get('PS_TAX');
}
/**
* Return the tax id associated to the specified name
*
* @param string $tax_name
* @param boolean $active (true by default)
*/
public static function getTaxIdByName($tax_name, $active = 1)
{
$tax = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow('
SELECT t.`id_tax`
FROM `'._DB_PREFIX_.'tax` t
LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (tl.id_tax = t.id_tax)
WHERE tl.`name` = \''.pSQL($tax_name).'\' '.
($active == 1 ? ' AND t.`active` = 1' : ''));
return $tax ? (int)($tax['id_tax']) : false;
}
/**
* Returns the product tax
*
* @param integer $id_product
* @param integer $id_country
* @return Tax
*
* @deprecated use $product->getTaxesRate() instead
*/
public static function getProductTaxRate($id_product, $id_address = NULL)
{
$address = Tax::initializeAddress($id_address);
$id_tax_rules = (int)Product::getIdTaxRulesGroupByIdProduct($id_product);
$tax_manager = TaxManagerFactory::getManager($address, $id_tax_rules);
$tax_calculator = $tax_manager->getTaxCalculator();
return $tax_calculator->getTaxesRate();
}
/**
* Returns the ecotax tax rate
*
* @param id_address
* @return float $tax_rate
*/
public static function getProductEcotaxRate($id_address = NULL)
{
$address = Tax::initializeAddress($id_address);
$tax_manager = TaxManagerFactory::getManager($address, (int)Configuration::get('PS_ECOTAX_TAX_RULES_GROUP_ID'));
$tax_calculator = $tax_manager->getTaxCalculator();
return $tax_calculator->getTaxesRate();
}
/**
* Returns the carrier tax rate
*
* @param id_address
* @return float $tax_rate
*/
public static function getCarrierTaxRate($id_carrier, $id_address = NULL)
{
$address = Tax::initializeAddress($id_address);
$id_tax_rules = (int)Carrier::getIdTaxRulesGroupByIdCarrier((int)$id_carrier);
$tax_manager = TaxManagerFactory::getManager($address, $id_tax_rules);
$tax_calculator = $tax_manager->getTaxCalculator();
return $tax_calculator->getTaxesRate();
}
/**
* Initiliaze an address corresponding to the id address if any or to the
* default shop configuration
*
* @param int $id_address
* @return Address address
*/
public static function initializeAddress($id_address = NULL)
{
// set the default address
$address = new Address();
$address->id_country = (int)Context::getContext()->country->id;
$address->id_state = 0;
$address->postcode = 0;
// if an id_address has been specified retrieve the address
if ($id_address)
{
$address = new Address((int)$id_address);
if (!Validate::isLoadedObject())
throw new Exception('Invalid address');
}
return $address;
}
/**
* Return the product tax rate using the tax rules system
*
* @param integer $id_product
* @param integer $id_country
* @return Tax
*
* @deprecated since 1.5
*/
public static function getProductTaxRateViaRules($id_product, $id_country, $id_state, $zipcode)
{
Tools::displayAsDeprecated();
if (!isset(self::$_product_tax_via_rules[$id_product.'-'.$id_country.'-'.$id_state.'-'.$zipcode]))
{
$tax_rate = TaxRulesGroup::getTaxesRate((int)Product::getIdTaxRulesGroupByIdProduct((int)$id_product), (int)$id_country, (int)$id_state, $zipcode);
self::$_product_tax_via_rules[$id_product.'-'.$id_country.'-'.$zipcode] = $tax_rate;
}
return self::$_product_tax_via_rules[$id_product.'-'.$id_country.'-'.$zipcode];
}
} }
+144
View File
@@ -0,0 +1,144 @@
<?php
/*
* 2007-2011 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2011 PrestaShop SA
* @version Release: $Revision$
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @since 1.5.0
*
* TaxCaculator is responsible of the tax computation
*/
class TaxCalculatorCore
{
/**
* COMBINE_METHOD sum taxes
* eg: 100€ * (10% + 15%)
*/
const COMBINE_METHOD = 1;
/**
* ONE_AFTER_ANOTHER_METHOD apply taxes one after another
* eg: (100€ * 10%) * 15%
*/
const ONE_AFTER_ANOTHER_METHOD = 2;
/**
* @var array $taxes_rate
*/
public $taxes_rate;
/**
* @var int $computation_method (COMBINE_METHOD | ONE_AFTER_ANOTHER_METHOD)
*/
public $computation_method;
/**
* @param array $taxes_rate
* @param int $computation_method (COMBINE_METHOD | ONE_AFTER_ANOTHER_METHOD)
*/
public function __construct(array $taxes_rate, $computation_method = TaxCalculator::COMBINE_METHOD)
{
$this->taxes_rate = $taxes_rate;
$this->computation_method = (int)$computation_method;
}
/**
* Compute and add the taxes to the specified price
*
* @param price
* @return price with taxes
*/
public function addTaxes($price)
{
$total_price = $price;
if ($this->computation_method == TaxCalculator::ONE_AFTER_ANOTHER_METHOD)
{
foreach ($this->taxes_rate as $tax_rate)
$total_price = $total_price * (1 + abs($tax_rate) / 100);
}
else
{
foreach ($this->taxes_rate as $tax_rate)
{
if ($tax_rate != 0)
$total_price = $total_price + ($price * (abs($tax_rate) / 100));
}
}
return $total_price;
}
/**
* Compute and remove the taxes to the specified price
*
* @param price
* @return price without taxes
*/
public function removeTaxes($price)
{
$total_price = $price;
if ($this->computation_method == TaxCalculator::ONE_AFTER_ANOTHER_METHOD)
{
foreach ($this->taxes_rate as $tax_rate)
$total_price = $total_price / (1 + abs($tax_rate) / 100);
}
else
{
$taxes_rate = 0;
foreach ($this->taxes_rate as $tax_rate)
$taxes_rate += abs($tax_rate);
$total_price = $total_price / (1 + (abs($taxes_rate) / 100));
}
return $total_price;
}
/**
* @return total taxes rate
*/
public function getTaxesRate()
{
$taxes_rate = 0;
if ($this->computation_method == TaxCalculator::ONE_AFTER_ANOTHER_METHOD)
{
$taxes_rate = 1;
foreach ($this->taxes_rate as $rate)
$taxes_rate *= (1 + (abs($rate) / 100));
$taxes_rate = $taxes_rate - 1;
$taxes_rate = $taxes_rate * 100;
}
else
{
foreach ($this->taxes_rate as $rate)
$taxes_rate += abs($rate);
}
return $taxes_rate;
}
}
+103
View File
@@ -0,0 +1,103 @@
<?php
/*
* 2007-2011 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2011 PrestaShop SA
* @version Release: $Revision$
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @since 1.5
*/
class TaxManagerFactoryCore
{
protected static $cache_tax_manager;
/**
* Returns a tax manager able to handle this address
*
* @param Address $address
* @param string $type
*
* @return TaxManager
*/
public static function getManager(Address $address, $type)
{
$cache_id = TaxManagerFactory::getCacheKey($address).'-'.$type;
if (!isset(TaxManagerFactory::$cache_tax_manager[$cache_id]))
{
$tax_manager = TaxManagerFactory::execHookTaxManagerFactory($address, $type);
if (!($tax_manager instanceof TaxManagerInterface))
$tax_manager = new TaxRulesTaxManager($address, $type);
TaxManagerFactory::$cache_tax_manager[$cache_id] = $tax_manager;
}
return TaxManagerFactory::$cache_tax_manager[$cache_id];
}
/**
* Check for a tax manager able to handle this type of address in the module list
*
* @param Address $address
* @param string $type
*
* @return TaxManager
*/
public static function execHookTaxManagerFactory(Address $address, $type)
{
$modules_infos = Hook::getModulesFromHook(Hook::getIdByName('taxManager'));
$tax_manager = false;
foreach ($modules_infos as $module_infos)
{
$module_instance = Module::getInstanceByName($module_infos['name']);
if (is_callable(array($module_instance, 'hookTaxManager')))
{
$tax_manager = $module_instance->hookTaxManager(array(
'address' => $address,
'params' => $type
));
}
if ($tax_manager)
break;
}
return $tax_manager;
}
/**
* Create a unique identifier for the address
* @param Address
*/
protected static function getCacheKey(Address $address)
{
return $address->id_country.'-'
.(int)$address->id_state.'-'
.$address->postcode.'-'
.$address->vat_number.'-'
.$address->dni;
}
}
+51
View File
@@ -0,0 +1,51 @@
<?php
/*
* 2007-2011 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2011 PrestaShop SA
* @version Release: $Revision$
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* A TaxManager define a way to retrieve tax.
*/
interface TaxManagerInterface
{
/**
* This method determine if the tax manager is available for the specified address.
*
* @param Address $address
* @param string $type
*
* @return TaxManager
*/
public static function isAvailableForThisAddress(Address $address);
/**
* Return the tax calculator associated to this address
*
* @return TaxCalculator
*/
public function getTaxCalculator();
}
+57
View File
@@ -0,0 +1,57 @@
<?php
/*
* 2007-2011 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2011 PrestaShop SA
* @version Release: $Revision$
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
abstract class TaxManagerModuleCore extends Module
{
public $tax_manager_class;
public function install()
{
return (parent::install() && $this->registerHook('taxManager') );
}
public function hookTaxManager($args)
{
$class_file =_PS_MODULE_DIR_.'/'.$this->name.'/'.$this->tax_manager_class.'.php';
if (!isset($this->tax_manager_class) || !file_exists($class_file))
die(Tools::displayError('Incorrect Tax Manager class ['.$this->tax_manager_class.']'));
require_once($class_file);
if (!class_exists($this->tax_manager_class))
die(Tools::displayError('Tax Manager class not found ['.$this->tax_manager_class.']'));
$class = $this->tax_manager_class;
if ($class::isAvailableForThisAddress($args['address']))
return new $class();
return false;
}
}
+86 -18
View File
@@ -30,13 +30,21 @@ class TaxRuleCore extends ObjectModel
public $id_tax_rules_group; public $id_tax_rules_group;
public $id_country; public $id_country;
public $id_state; public $id_state;
public $id_county; public $zipcode_from;
public $zipcode_to;
public $id_tax; public $id_tax;
public $state_behavior; public $behavior;
public $county_behavior; public $description;
protected $fieldsRequired = array('id_tax_rules_group', 'id_country', 'id_tax'); protected $fieldsRequired = array('id_tax_rules_group', 'id_country', 'id_tax');
protected $fieldsValidate = array('id_tax_rules_group' => 'isUnsignedId', 'id_country' => 'isUnsignedId', 'id_state' => 'isUnsignedId', 'id_county' => 'isUnsignedId', 'id_tax' => 'isUnsignedId', 'state_behavior' => 'isUnsignedInt', 'county_behavior' => 'isUnsignedInt'); protected $fieldsValidate = array('id_tax_rules_group' => 'isUnsignedId',
'id_country' => 'isUnsignedId',
'id_state' => 'isUnsignedId',
'zipcode_from' => 'isUnsignedId', // TODO: char
'zipcode_to' => 'isUnsignedId', // TODO: char
'id_tax' => 'isUnsignedId',
'behavior' => 'isUnsignedInt',
'description' => 'isUnsignedInt'); // TODO:char
protected $table = 'tax_rule'; protected $table = 'tax_rule';
protected $identifier = 'id_tax_rule'; protected $identifier = 'id_tax_rule';
@@ -47,10 +55,11 @@ class TaxRuleCore extends ObjectModel
$fields['id_tax_rules_group'] = (int)($this->id_tax_rules_group); $fields['id_tax_rules_group'] = (int)($this->id_tax_rules_group);
$fields['id_country'] = (int)$this->id_country; $fields['id_country'] = (int)$this->id_country;
$fields['id_state'] = (int)$this->id_state; $fields['id_state'] = (int)$this->id_state;
$fields['id_county'] = (int)$this->id_county; $fields['zipcode_from'] = (int)$this->zipcode_from;
$fields['state_behavior'] = (int)$this->state_behavior; $fields['zipcode_to'] = (int)$this->zipcode_to;
$fields['county_behavior'] = (int)$this->county_behavior; $fields['behavior'] = (int)$this->behavior;
$fields['id_tax'] = (int)($this->id_tax); $fields['id_tax'] = (int)($this->id_tax);
$fields['description'] = $this->description;
return $fields; return $fields;
} }
@@ -66,23 +75,44 @@ class TaxRuleCore extends ObjectModel
); );
} }
public static function retrieveById($id_tax_rule)
{
return Db::getInstance()->getRow('
SELECT * FROM `'._DB_PREFIX_.'tax_rule`
WHERE `id_tax_rule` = '.(int)$id_tax_rule);
}
/*
public static function getTaxRulesByGroupId($id_group) public static function getTaxRulesByGroupId($id_group)
{ {
if (empty($id_group)) if (empty($id_group))
die(Tools::displayError()); die(Tools::displayError());
$results = Db::getInstance()->ExecuteS(' return Db::getInstance()->ExecuteS('
SELECT * SELECT *
FROM `'._DB_PREFIX_.'tax_rule` FROM `'._DB_PREFIX_.'tax_rule`
WHERE `id_tax_rules_group` = '.(int)$id_group WHERE `id_tax_rules_group` = '.(int)$id_group
); );
}*/
$res = array(); public static function getTaxRulesByGroupId($id_lang, $id_group)
foreach ($results AS $row) {
$res[$row['id_country']][$row['id_state']][$row['id_county']] = array('id_tax' => $row['id_tax'], 'state_behavior' => $row['state_behavior'], 'county_behavior' => $row['county_behavior']);
return $res;
} return Db::getInstance()->ExecuteS('
SELECT g.`id_tax_rule`,
c.`name` AS country_name,
s.`name` AS state_name,
t.rate,
g.`zipcode_from`, g.`zipcode_to`,
g.`description`,
g.`behavior`
FROM `'._DB_PREFIX_.'tax_rule` g
LEFT JOIN `'._DB_PREFIX_.'country_lang` c ON (g.`id_country` = c.`id_country` AND id_lang = '.(int)$id_lang.')
LEFT JOIN `'._DB_PREFIX_.'state` s ON (g.`id_state` = s.`id_state`)
LEFT JOIN `'._DB_PREFIX_.'tax` t ON (g.`id_tax` = t.`id_tax`)
WHERE `id_tax_rules_group` = '.(int)$id_group
);
}
public static function deleteTaxRuleByIdTax($id_tax) public static function deleteTaxRuleByIdTax($id_tax)
{ {
@@ -93,19 +123,57 @@ class TaxRuleCore extends ObjectModel
} }
/**
* @deprecated since 1.5
*/
public static function deleteTaxRuleByIdCounty($id_county) public static function deleteTaxRuleByIdCounty($id_county)
{ {
return Db::getInstance()->Execute(' Tools::displayAsDeprecated();
DELETE FROM `'._DB_PREFIX_.'tax_rule` return true;
WHERE `id_county` = '.(int)$id_county
);
} }
/**
* @param int $id_tax
* @return boolean
*/
public static function isTaxInUse($id_tax) public static function isTaxInUse($id_tax)
{ {
return Db::getInstance()->getValue(' return Db::getInstance()->getValue('
SELECT COUNT(*) FROM `'._DB_PREFIX_.'tax_rule` WHERE `id_tax` = '.(int)$id_tax SELECT COUNT(*) FROM `'._DB_PREFIX_.'tax_rule` WHERE `id_tax` = '.(int)$id_tax
); );
} }
/**
* @param string $zipcode a range of zipcode (eg: 75000 / 75000-75015)
* @return array an array containing two zipcode ordered by zipcode
*/
public function breakDownZipCode($zip_codes)
{
$zip_codes = preg_split('/-/', $zip_codes);
if (sizeof($zip_codes) == 2)
{
$from = $zip_codes[0];
$to = $zip_codes[1];
if ($zip_codes[0] > $zip_codes[1])
{
$from = $zip_codes[1];
$to = $zip_codes[0];
}
elseif ($zip_codes[0] == $zip_codes[1])
{
$from = $zip_codes[0];
$to = 0;
}
}
elseif (sizeof($zip_codes) == 1)
{
$from = $zip_codes[0];
$to = 0;
}
return array($from, $to);
}
} }
@@ -59,74 +59,19 @@ class TaxRulesGroupCore extends ObjectModel
); );
} }
/**
* @return array an array of tax rules group formatted as $id => $name
*/
public static function getTaxRulesGroupsForOptions() public static function getTaxRulesGroupsForOptions()
{ {
$tax_rules[] = array('id_tax_rules_group' => 0, 'name' => Tools::displayError('No tax')); $tax_rules[] = array('id_tax_rules_group' => 0, 'name' => Tools::displayError('No tax'));
return array_merge($tax_rules, TaxRulesGroup::getTaxRulesGroups()); return array_merge($tax_rules, TaxRulesGroup::getTaxRulesGroups());
} }
public static function getTaxes($id_tax_rules_group, $id_country, $id_state, $id_county)
{
if (empty($id_tax_rules_group) OR empty($id_country))
return array(new Tax()); // No Tax
if (isset(self::$_taxes[$id_tax_rules_group.'-'.$id_country.'-'.$id_state.'-'.$id_county]))
return self::$_taxes[$id_tax_rules_group.'-'.$id_country.'-'.$id_state.'-'.$id_county];
$rows = Db::getInstance()->ExecuteS('
SELECT *
FROM `'._DB_PREFIX_.'tax_rule`
WHERE `id_country` = '.(int)$id_country.'
AND `id_tax_rules_group` = '.(int)$id_tax_rules_group.'
AND `id_state` IN (0, '.(int)$id_state.')
AND `id_county` IN (0, '.(int)$id_county.')
ORDER BY `id_county` DESC, `id_state` DESC'
);
$taxes = array();
foreach ($rows AS $row)
{
if ($row['id_county'] != 0)
{
switch($row['county_behavior'])
{
case County::USE_BOTH_TAX:
$taxes[] = new Tax($row['id_tax']);
break;
case County::USE_COUNTY_TAX:
$taxes = array(new Tax($row['id_tax']));
break 2;
case County::USE_STATE_TAX: // do nothing
break;
}
}
else if ($row['id_state'] != 0)
{
switch($row['state_behavior'])
{
case PS_STATE_TAX: // use only product tax
$taxes[] = new Tax($row['id_tax']);
break 2; // switch + foreach
case PS_BOTH_TAX:
$taxes[] = new Tax($row['id_tax']);
break;
case PS_PRODUCT_TAX: // do nothing use country tax
break;
}
}
else
$taxes[] = new Tax((int)$row['id_tax']);
}
self::$_taxes[$id_tax_rules_group.'-'.$id_country.'-'.$id_state.'-'.$id_county] = $taxes;
return $taxes;
}
/**
* @return array
*/
public static function getAssociatedTaxRatesByIdCountry($id_country) public static function getAssociatedTaxRatesByIdCountry($id_country)
{ {
$rows = Db::getInstance()->ExecuteS(' $rows = Db::getInstance()->ExecuteS('
@@ -136,7 +81,7 @@ class TaxRulesGroupCore extends ObjectModel
LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`) LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`)
WHERE tr.`id_country` = '.(int)$id_country.' WHERE tr.`id_country` = '.(int)$id_country.'
AND tr.`id_state` = 0 AND tr.`id_state` = 0
AND tr.`id_county` = 0' AND 0 between `zipcode_from` AND `zipcode_to`'
); );
$res = array(); $res = array();
@@ -146,15 +91,12 @@ class TaxRulesGroupCore extends ObjectModel
return $res; return $res;
} }
public static function getTaxesRate($id_tax_rules_group, $id_country, $id_state, $id_county) /**
{ * Returns the tax rules group id corresponding to the name
$rate = 0; *
foreach (TaxRulesGroup::getTaxes($id_tax_rules_group, $id_country, $id_state, $id_county) AS $tax) * @param string name
$rate += (float)$tax->rate; * @return int id of the tax rules
*/
return $rate;
}
public static function getIdByName($name) public static function getIdByName($name)
{ {
return Db::getInstance()->getValue( return Db::getInstance()->getValue(
@@ -163,4 +105,29 @@ class TaxRulesGroupCore extends ObjectModel
WHERE `name` = \''.pSQL($name).'\'' WHERE `name` = \''.pSQL($name).'\''
); );
} }
}
/**
* @deprecated since 1.5
*/
public static function getTaxesRate($id_tax_rules_group, $id_country, $id_state, $zipcode)
{
Tools::displayAsDeprecated();
$rate = 0;
foreach (TaxRulesGroup::getTaxes($id_tax_rules_group, $id_country, $id_state, $zipcode) AS $tax)
$rate += (float)$tax->rate;
return $rate;
}
/**
* Return taxes associated to this para
* @deprecated since 1.5
*/
public static function getTaxes($id_tax_rules_group, $id_country, $id_state, $id_county)
{
Tools::displayAsDeprecated();
return array();
}
}
+101
View File
@@ -0,0 +1,101 @@
<?php
/*
* 2007-2011 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2011 PrestaShop SA
* @version Release: $Revision$
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
class TaxRulesTaxManagerCore implements TaxManagerInterface
{
public $address;
public $type;
public $tax_calculator;
public function __construct(Address $address, $type)
{
$this->address = $address;
$this->type = $type;
}
/**
* Returns true if this tax manager is available for this address
*
* @return boolean
*/
public static function isAvailableForThisAddress(Address $address)
{
return true; // default manager, available for all addresses
}
/**
* Return the tax calculator associated to this address
*
* @return TaxCalculator
*/
public function getTaxCalculator()
{
if (isset($this->tax_calculator))
return $this->tax_calculator;
$postcode = 0;
if (!empty($this->address->postcode))
$postcode = $this->address->postcode;
$rows = Db::getInstance()->ExecuteS('
SELECT *
FROM `'._DB_PREFIX_.'tax_rule`
WHERE `id_country` = '.(int)$this->address->id_country.'
AND `id_tax_rules_group` = '.(int)$this->type.'
AND `id_state` IN (0, '.(int)$this->address->id_state.')
AND ('.pSQL($postcode).' BETWEEN `zipcode_from` AND `zipcode_to` OR `zipcode_from` = 0 OR `zipcode_from` = '.pSQL($postcode).')
ORDER BY `zipcode_from` DESC, `zipcode_to` DESC, `id_state` DESC, `id_country` DESC');
$behavior = 0;
$first_row = true;
$taxes_rates = array();
foreach ($rows as $row)
{
$tax = new Tax((int)$row['id_tax']);
$taxes_rates[] = $tax->rate;
// the applied behavior correspond to the most specific rules
if ($first_row)
{
$behavior = $row['behavior'];
$first_row = false;
}
if ($row['behavior'] == 0)
break;
}
$this->tax_calculator = new TaxCalculator($taxes_rates, $behavior);
return $this->tax_calculator;
}
}
+3 -3
View File
@@ -49,7 +49,7 @@ class ProductControllerCore extends FrontController
$this->addJS(_PS_JS_DIR_.'jquery/jquery.jqzoom.js'); $this->addJS(_PS_JS_DIR_.'jquery/jquery.jqzoom.js');
} }
} }
public function canonicalRedirection() public function canonicalRedirection()
{ {
// Automatically redirect to the canonical URL if the current in is the right one // 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')); $id_country = (int)($id_customer ? Customer::getCurrentCountry($id_customer) : Configuration::get('PS_COUNTRY_DEFAULT'));
// Tax // Tax
$tax = (float)(Tax::getProductTaxRate((int)$this->product->id, $this->context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')})); $tax = (float)$this->product->getTaxesRate(new Address((int)$this->context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}));
$this->context->smarty->assign('tax_rate', $tax); $this->context->smarty->assign('tax_rate', $tax);
$productPriceWithTax = Product::getPriceStatic($this->product->id, true, NULL, 6); $productPriceWithTax = Product::getPriceStatic($this->product->id, true, NULL, 6);
if (Product::$_taxCalculationMethod == PS_TAX_INC) if (Product::$_taxCalculationMethod == PS_TAX_INC)
$productPriceWithTax = Tools::ps_round($productPriceWithTax, 2); $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_lang` (`id_lang`),
KEY `id_currency` (`id_currency`), KEY `id_currency` (`id_currency`),
KEY `id_guest` (`id_guest`), KEY `id_guest` (`id_guest`),
KEY `id_group_shop` (`id_group_shop`), KEY `id_group_shop` (`id_group_shop`),
KEY `id_shop` (`id_shop`) KEY `id_shop` (`id_shop`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8; ) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
@@ -324,7 +324,7 @@ CREATE TABLE `PREFIX_configuration_lang` (
CREATE TABLE `PREFIX_connections` ( CREATE TABLE `PREFIX_connections` (
`id_connections` int(10) unsigned NOT NULL auto_increment, `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_shop` INT(11) UNSIGNED NOT NULL DEFAULT '1',
`id_guest` int(10) unsigned NOT NULL, `id_guest` int(10) unsigned NOT NULL,
`id_page` 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 `customer_login` (`email`,`passwd`),
KEY `id_customer_passwd` (`id_customer`,`passwd`), KEY `id_customer_passwd` (`id_customer`,`passwd`),
KEY `id_gender` (`id_gender`), KEY `id_gender` (`id_gender`),
KEY `id_group_shop` (`id_group_shop`), KEY `id_group_shop` (`id_group_shop`),
KEY `id_shop` (`id_shop`) KEY `id_shop` (`id_shop`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8; ) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
@@ -487,7 +487,7 @@ CREATE TABLE `PREFIX_customer_thread` (
KEY `id_contact` (`id_contact`), KEY `id_contact` (`id_contact`),
KEY `id_customer` (`id_customer`), KEY `id_customer` (`id_customer`),
KEY `id_order` (`id_order`), KEY `id_order` (`id_order`),
KEY `id_product` (`id_product`) KEY `id_product` (`id_product`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8; ) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
@@ -942,7 +942,7 @@ CREATE TABLE `PREFIX_orders` (
KEY `id_currency` (`id_currency`), KEY `id_currency` (`id_currency`),
KEY `id_address_delivery` (`id_address_delivery`), KEY `id_address_delivery` (`id_address_delivery`),
KEY `id_address_invoice` (`id_address_invoice`), 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`), KEY `id_shop` (`id_shop`),
INDEX `date_add`(`date_add`) INDEX `date_add`(`date_add`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8; ) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
@@ -1119,7 +1119,7 @@ CREATE TABLE `PREFIX_page_type` (
CREATE TABLE `PREFIX_page_viewed` ( CREATE TABLE `PREFIX_page_viewed` (
`id_page` int(10) unsigned NOT NULL, `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_shop` INT UNSIGNED NOT NULL DEFAULT '1',
`id_date_range` int(10) unsigned NOT NULL, `id_date_range` int(10) unsigned NOT NULL,
`counter` 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_tax_rules_group` int(11) NOT NULL,
`id_country` int(11) NOT NULL, `id_country` int(11) NOT NULL,
`id_state` int(11) NOT NULL, `id_state` int(11) NOT NULL,
`id_county` int(11) NOT NULL, `zipcode_from` INT NOT NULL,
`zipcode_to` INT NOT NULL,
`id_tax` int(11) NOT NULL, `id_tax` int(11) NOT NULL,
`state_behavior` int(11) NOT NULL, `behavior` int(11) NOT NULL,
`county_behavior` int(11) NOT NULL, `description` VARCHAR( 100 ) NOT NULL,
PRIMARY KEY (`id_tax_rule`), PRIMARY KEY (`id_tax_rule`),
KEY `id_tax_rules_group` (`id_tax_rules_group`), KEY `id_tax_rules_group` (`id_tax_rules_group`),
KEY `id_tax` (`id_tax`), KEY `id_tax` (`id_tax`)
UNIQUE KEY `tax_rule` (`id_tax_rules_group`, `id_country`, `id_state`, `id_county`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8; ) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
CREATE TABLE `PREFIX_tax_rules_group` ( CREATE TABLE `PREFIX_tax_rules_group` (
@@ -1688,23 +1688,6 @@ CREATE TABLE `PREFIX_import_match` (
PRIMARY KEY (`id_import_match`) PRIMARY KEY (`id_import_match`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8; ) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
CREATE TABLE `PREFIX_county` (
`id_county` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(64) NOT NULL,
`id_state` int(11) NOT NULL,
`active` tinyint(1) NOT NULL,
PRIMARY KEY (`id_county`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8 ;
CREATE TABLE `PREFIX_county_zip_code` (
`id_county` INT NOT NULL ,
`from_zip_code` INT NOT NULL ,
`to_zip_code` INT NOT NULL ,
PRIMARY KEY ( `id_county` , `from_zip_code` , `to_zip_code` )
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
CREATE TABLE `PREFIX_address_format` ( CREATE TABLE `PREFIX_address_format` (
`id_country` int(10) unsigned NOT NULL, `id_country` int(10) unsigned NOT NULL,
`format` varchar(255) NOT NULL DEFAULT '', `format` varchar(255) NOT NULL DEFAULT '',
+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), (63, 'beforeAuthentication', 'Before Authentication', 'Before authentication', 0, 0),
(64, 'paymentTop', 'Top of payment page', 'Top of payment page', 0, 0), (64, 'paymentTop', 'Top of payment page', 'Top of payment page', 0, 0),
(65, 'afterCreateHtaccess', 'After htaccess creation', 'After htaccess creation', 0, 0), (65, 'afterCreateHtaccess', 'After htaccess creation', 'After htaccess creation', 0, 0),
(66, 'afterSaveAdminMeta', 'After save configuration in AdminMeta', 'After save configuration in AdminMeta', 0, 0); (66, 'afterSaveAdminMeta', 'After save configuration in AdminMeta', 'After save configuration in AdminMeta', 0, 0),
(67, 'taxManager', 'Tax Manager Factory', '' , 0, 0);
INSERT INTO `PREFIX_configuration` (`id_configuration`, `name`, `value`, `date_add`, `date_upd`) VALUES INSERT INTO `PREFIX_configuration` (`id_configuration`, `name`, `value`, `date_add`, `date_upd`) VALUES
(1, 'PS_LANG_DEFAULT', '1', NOW(), NOW()), (1, 'PS_LANG_DEFAULT', '1', NOW(), NOW()),
@@ -1180,7 +1181,7 @@ INSERT INTO `PREFIX_address_format` (`id_country`, `format`)
UPDATE `PREFIX_address_format` set `format`='firstname lastname UPDATE `PREFIX_address_format` set `format`='firstname lastname
company company
address1 address2 address1 address2
city, State:name postcode city, State:name postcode
Country:name Country:name
phone' where `id_country`=21; phone' where `id_country`=21;
@@ -1199,3 +1200,4 @@ postcode city
State:name State:name
Country:name Country:name
phone' where `id_country`=10; 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 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')) if (function_exists('date_default_timezone_set'))
date_default_timezone_set('Europe/Paris'); date_default_timezone_set('Europe/Paris');
// if _PS_ROOT_DIR_ is defined, use it instead of "guessing" the module dir. // if _PS_ROOT_DIR_ is defined, use it instead of "guessing" the module dir.
if (defined('_PS_ROOT_DIR_') AND !defined('_PS_MODULE_DIR_')) if (defined('_PS_ROOT_DIR_') AND !defined('_PS_MODULE_DIR_'))
define('_PS_MODULE_DIR_', _PS_ROOT_DIR_.'/modules/'); 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_.'add_order_state.php');
require_once(_PS_INSTALLER_PHP_UPGRADE_DIR_.'update_tax_rules.php');
require_once(_PS_INSTALLER_PHP_UPGRADE_DIR_.'remove_tab.php');
//old version detection //old version detection
global $oldversion, $logger; global $oldversion, $logger;
$oldversion = false; $oldversion = false;
@@ -313,9 +317,9 @@ if ($confFile->error != false)
// Settings updated, compile and cache directories must be emptied // Settings updated, compile and cache directories must be emptied
$arrayToClean = array( $arrayToClean = array(
INSTALL_PATH.'/../tools/smarty/cache/', INSTALL_PATH.'/../tools/smarty/cache/',
INSTALL_PATH.'/../tools/smarty/compile/', INSTALL_PATH.'/../tools/smarty/compile/',
INSTALL_PATH.'/../tools/smarty_v2/cache/', INSTALL_PATH.'/../tools/smarty_v2/cache/',
INSTALL_PATH.'/../tools/smarty_v2/compile/'); INSTALL_PATH.'/../tools/smarty_v2/compile/');
foreach ($arrayToClean as $dir) foreach ($arrayToClean as $dir)
if (!file_exists($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 <?php
/* /*
* 2007-2011 PrestaShop * 2007-2011 PrestaShop
* *
* NOTICE OF LICENSE * NOTICE OF LICENSE
* *
@@ -28,7 +28,7 @@
if (!defined('_PS_VERSION_')) if (!defined('_PS_VERSION_'))
exit; exit;
class VatNumber extends Module class VatNumber extends TaxManagerModule
{ {
public function __construct() public function __construct()
{ {
@@ -37,35 +37,37 @@ class VatNumber extends Module
$this->version = 1.0; $this->version = 1.0;
$this->author = 'PrestaShop'; $this->author = 'PrestaShop';
$this->need_instance = 0; $this->need_instance = 0;
$this->tax_manager_class = 'VATNumberTaxManager';
parent::__construct(); parent::__construct();
$this->displayName = $this->l('European VAT number'); $this->displayName = $this->l('European VAT number');
$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)'); $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() public function install()
{ {
return (parent::install() AND Configuration::updateValue('VATNUMBER_MANAGEMENT', 1)); return (parent::install() AND Configuration::updateValue('VATNUMBER_MANAGEMENT', 1));
} }
public function uninstall() public function uninstall()
{ {
return (parent::uninstall() AND Configuration::updateValue('VATNUMBER_MANAGEMENT', 0)); return (parent::uninstall() AND Configuration::updateValue('VATNUMBER_MANAGEMENT', 0));
} }
public function enable($forceAll = false) public function enable($forceAll = false)
{ {
parent::enable(); parent::enable();
Configuration::updateValue('VATNUMBER_MANAGEMENT', 1); Configuration::updateValue('VATNUMBER_MANAGEMENT', 1);
} }
public function disable($forceAll = false) public function disable($forceAll = false)
{ {
parent::disable(); parent::disable();
Configuration::updateValue('VATNUMBER_MANAGEMENT', 0); Configuration::updateValue('VATNUMBER_MANAGEMENT', 0);
} }
public static function getPrefixIntracomVAT() public static function getPrefixIntracomVAT()
{ {
$intracom_array = array( $intracom_array = array(
@@ -95,13 +97,13 @@ class VatNumber extends Module
'SK'=>'SK', //Slovakia 'SK'=>'SK', //Slovakia
'CZ'=>'CZ', //Czech Republic 'CZ'=>'CZ', //Czech Republic
'SI'=>'SI', //Slovenia 'SI'=>'SI', //Slovenia
'RO'=>'RO', //Romania 'RO'=>'RO', //Romania
'BG'=>'BG' //Bulgaria 'BG'=>'BG' //Bulgaria
); );
return $intracom_array; 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); 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() public function getContent()
{ {
$echo = ''; $echo = '';
if (Tools::isSubmit('submitVatNumber')) if (Tools::isSubmit('submitVatNumber'))
{ {
if (Configuration::updateValue('VATNUMBER_COUNTRY', (int)(Tools::getValue('vatnumber_country')))) if (Configuration::updateValue('VATNUMBER_COUNTRY', (int)(Tools::getValue('vatnumber_country'))))
@@ -178,6 +180,4 @@ class VatNumber extends Module
</fieldset>'; </fieldset>';
return $echo; return $echo;
} }
} }