[+] Project : Vouchers are now replaced by cart rules

git-svn-id: http://dev.prestashop.com/svn/v1/branches/1.5.x@9771 b9a71923-0436-4b27-9f14-aed3839534dd
This commit is contained in:
dMetzger
2011-11-01 18:50:42 +00:00
parent 1cfd76a66f
commit 486622522c
46 changed files with 2183 additions and 994 deletions
+3 -1
View File
@@ -36,6 +36,8 @@ if (!isset($_POST['controller']) && isset($_POST['tab']))
$_POST['controller'] = strtolower($_POST['tab']);
if (!isset($_REQUEST['controller']) && isset($_REQUEST['tab']))
$_REQUEST['controller'] = strtolower($_REQUEST['tab']);
// Retrocompatibility with 1.4
$_REQUEST['ajaxMode'] = $_POST['ajaxMode'] = $_GET['ajaxMode'] = $_REQUEST['ajax'] = $_POST['ajax'] = $_GET['ajax'] = 1;
Dispatcher::getInstance()->setControllerDirectories(array(_PS_ADMIN_DIR_.'/tabs/', _PS_ADMIN_CONTROLLER_DIR_));
Dispatcher::getInstance()->dispatch();
-1
View File
@@ -120,7 +120,6 @@ class AdminCustomerThreads extends AdminTab
}
if (isset($_POST['id_employee_forward']))
{
// Todo: need to avoid doubles
$messages = Db::getInstance()->executeS('
SELECT ct.*, cm.*, cl.name subject, CONCAT(e.firstname, \' \', e.lastname) employee_name, CONCAT(c.firstname, \' \', c.lastname) customer_name, c.firstname
FROM '._DB_PREFIX_.'customer_thread ct
-532
View File
@@ -1,532 +0,0 @@
<?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: 7060 $
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
class AdminDiscounts extends AdminTab
{
public function __construct()
{
$this->context = Context::getContext();
$this->table = 'discount';
$this->className = 'Discount';
$this->lang = true;
$this->edit = true;
$this->delete = true;
$this->_select = 'dtl.`name` AS discount_type,
IF(a.id_discount_type = '.(int)Discount::PERCENT.', CONCAT(a.value, " %"),
IF(a.id_discount_type = '.(int)Discount::AMOUNT.', CONCAT(a.value, " ", c.sign),
"--")) as strvalue';
$this->_join = 'LEFT JOIN `'._DB_PREFIX_.'currency` c ON (c.`id_currency` = a.`id_currency`)
LEFT JOIN `'._DB_PREFIX_.'discount_type` dt ON (dt.`id_discount_type` = a.`id_discount_type`)
LEFT JOIN `'._DB_PREFIX_.'discount_type_lang` dtl ON (dt.`id_discount_type` = dtl.`id_discount_type` AND dtl.`id_lang` = '.(int)$this->context->language->id.')';
$typesArray = array();
$types = Discount::getDiscountTypes($this->context->language->id);
foreach ($types AS $type)
$typesArray[$type['id_discount_type']] = $type['name'];
$this->fieldsDisplay = array(
'id_discount' => array('title' => $this->l('ID'), 'align' => 'center', 'width' => 25),
'name' => array('title' => $this->l('Code'), 'width' => 85, 'prefix' => '<span class="discount_name">', 'suffix' => '</span>', 'filter_key' => 'a!name'),
'shop_name' => array('title' => $this->l('Shop'), 'width' => 85, 'filter_key' => 's!name'),
'description' => array('title' => $this->l('Description'), 'width' => 100, 'filter_key' => 'b!description'),
'discount_type' => array('title' => $this->l('Type'), 'type' => 'select', 'select' => $typesArray, 'filter_key' => 'dt!id_discount_type'),
'strvalue' => array('title' => $this->l('Value'), 'width' => 50, 'align' => 'right', 'filter_key' => 'a!value'),
'quantity' => array('title' => $this->l('Qty'), 'width' => 40, 'align' => 'right'),
'date_to' => array('title' => $this->l('To'), 'width' => 60, 'type' => 'date', 'align' => 'right'),
'active' => array('title' => $this->l('Status'), 'align' => 'center', 'active' => 'status', 'type' => 'bool', 'orderby' => false),
);
$this->optionsList = array(
'general' => array(
'title' => $this->l('Discounts options'),
'fields' => array(
'PS_VOUCHERS' => array('title' => $this->l('Enable vouchers:'), 'desc' => $this->l('Allow the use of vouchers in shop'), 'cast' => 'intval', 'type' => 'bool'),
),
),
);
parent::__construct();
}
protected function copyFromPost(&$object, $table)
{
parent::copyFromPost($object, $table);
$object->cumulable = (!isset($_POST['cumulable']) ? false : true);
$object->cumulable_reduction = (!isset($_POST['cumulable_reduction']) ? false : true);
}
public function postProcess()
{
$token = Tools::getValue('token') ? Tools::getValue('token') : $this->token;
if ($discountName = Tools::getValue('name') AND Validate::isDiscountName($discountName) AND Discount::discountExists($discountName, Tools::getValue('id_discount')))
$this->_errors[] = Tools::displayError('A voucher of this name already exists. Please choose another name.');
if (Tools::getValue('submitAdd'.$this->table))
{
if (Tools::getValue('id_discount_type') == 0)
$this->_errors[] = Tools::displayError('Please set a type for this voucher.');
if (Tools::getValue('id_discount_type') == Discount::AMOUNT AND Tools::getValue('id_currency') == 0)
$this->_errors[] = Tools::displayError('Please set a currency for this voucher.');
if ((Tools::getValue('id_discount_type') == Discount::PERCENT || Tools::getValue('id_discount_type') == 2) && !Tools::getValue('value'))
$this->_errors[] = Tools::displayError('Please set a amount for this voucher.');
if (!Validate::isBool_Id(Tools::getValue('id_target')))
$this->_errors[] = Tools::displayError('Invalid customer or group ID field');
else
{
$rules = explode('_', Tools::getValue('id_target'));
/* In form, there is one field for two differents fields in object*/
$_POST[($rules[0] ? 'id_group' : 'id_customer')] = $rules[1];
}
/* 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))
{
$object->deleted = 1;
$object->update();
$objectNew = new $this->className();
$this->copyFromPost($objectNew, $this->table);
$result = $objectNew->add();
if (Validate::isLoadedObject($objectNew))
$this->afterDelete($objectNew, $object->id);
}
else
{
if (($categories = Tools::getValue('categoryBox')) === false OR (!empty($categories) AND !is_array($categories)))
$this->_errors[] = Tools::displayError('Please set a category for this voucher.');
$this->copyFromPost($object, $this->table);
$result = $object->update(true, false, $categories);
}
if (!$result)
$this->_errors[] = Tools::displayError('An error occurred while updating object.').' <b>'.$this->table.'</b>';
elseif ($this->postImage($object->id))
{
if ($back = Tools::getValue('back'))
Tools::redirectAdmin(urldecode($back).'&conf=4');
if (Tools::getValue('stay_here') == 'on' || Tools::getValue('stay_here') == 'true' || Tools::getValue('stay_here') == '1')
Tools::redirectAdmin(self::$currentIndex.'&'.$this->identifier.'='.$object->id.'&conf=4&updatescene&token='.$token);
Tools::redirectAdmin(self::$currentIndex.'&'.$this->identifier.'='.$object->id.'&conf=4&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);
$categories = Tools::getValue('categoryBox', null);
if (!$object->add(true, false, $categories))
$this->_errors[] = Tools::displayError('An error occurred while creating object.').' <b>'.$this->table.'</b>';
elseif (($_POST[$this->identifier] = $object->id /* voluntary */) AND $this->postImage($object->id) AND $this->_redirect)
{
if ($customer = new Customer($object->id_customer) AND Validate::isLoadedObject($customer))
{
if (Validate::isEmail($customer->email))
{
$data = array(
'{firstname}' => $customer->firstname,
'{lastname}' => $customer->lastname,
'{email}' => $customer->email,
'{voucher_num}' => $object->name);
@Mail::Send((int)Configuration::get('PS_LANG_DEFAULT'), 'voucher_new', Mail::l('New voucher'), $data, $customer->email, $customer->firstname.' '.$customer->lastname);
}
}
elseif ($group = new Group($object->id_group) AND Validate::isLoadedObject($group))
{
$customer = null;
$customers = $group->getCustomers();
if ($customers)
foreach ($customers as $customer)
{
$data = array(
'{firstname}' => $customer['firstname'],
'{lastname}' => $customer['lastname'],
'{email}' => $customer['email'],
'{voucher_num}' => $object->name);
@Mail::Send((int)Configuration::get('PS_LANG_DEFAULT'), 'voucher_new', Mail::l('New voucher'), $data, $customer['email'], $customer['firstname'].' '.$customer['lastname']);
}
}
Tools::redirectAdmin(self::$currentIndex.'&'.$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);
}
else
return parent::postProcess();
}
public function displayForm($isMainTab = true)
{
parent::displayForm();
if (!($obj = $this->loadObject(true)))
return;
echo '
<script type="text/javascript">
function discountType()
{
if ($("#id_discount_type").val() == 0)
$("#value-div").css("display", "none");
else if ($("#id_discount_type").val() == '.Discount::PERCENT.')
{
$("#value-div").css("display", "block");
$("#percent-span").css("display", "block");
$("#id_currency").css("display", "none");
}
else if ($("#id_discount_type").val() == '.Discount::AMOUNT.')
{
$("#value-div").css("display", "block");
$("#percent-span").css("display", "none");
$("#id_currency").css("display", "block");
$(\'#behavior_not_exhausted\').show();
}
else if ($("#id_discount_type").val() == '.Discount::FREE_SHIPPING.')
$("#value-div").css("display", "none");
if ($(\'#id_discount_type\').val() != '.Discount::AMOUNT.')
$(\'#behavior_not_exhausted\').hide();
}
$(document).ready(function(){
$("#id_discount_type").change(function(){discountType();});
discountType();
});
</script>
<form action="'.self::$currentIndex.'&submitAdd'.$this->table.'=1&token='.$this->token.'" id="discount" name="discount" method="post" enctype="multipart/form-data">
'.($obj->id ? '<input type="hidden" name="id_'.$this->table.'" value="'.$obj->id.'" />' : '').'
<fieldset><legend><img src="../img/admin/coupon.gif" />'.$this->l('Vouchers').'</legend>
<label>'.$this->l('Code:').' </label>
<div class="margin-form">
<input type="text" size="30" maxlength="32" name="name" value="'.htmlentities($this->getFieldValue($obj, 'name'), ENT_COMPAT, 'UTF-8').'" id="code" />
<sup>*</sup>
<img src="../img/admin/news-new.gif" onclick="gencode(8);" style="cursor: pointer" />
<span class="hint" name="help_box">'.$this->l('Invalid characters: numbers and').' !<>,;?=+()@#"{}_$%:<span class="hint-pointer">&nbsp;</span></span>
<p class="clear">'.$this->l('The voucher\'s code, at least 3 characters long, which the customer types in during check-out').'</p>
</div>
<label>'.$this->l('Type:').' </label>
<div class="margin-form">
<select name="id_discount_type" id="id_discount_type" onchange="free_shipping()">
<option value="0">'.$this->l('-- Choose --').'</option>';
$discountTypes = Discount::getDiscountTypes($this->context->language->id);
foreach ($discountTypes AS $discountType)
echo '<option value="'.(int)($discountType['id_discount_type']).'"'.
(($this->getFieldValue($obj, 'id_discount_type') == $discountType['id_discount_type']) ? ' selected="selected"' : '').'>'.$discountType['name'].'</option>';
echo ' </select> <sup>*</sup>
</div>
<div id="value-div" style="display:none">
<label>'.$this->l('Value').'</label>
<div class="margin-form">
<input style="float:left;width:80px" type="text" name="value" id="discount_value" value="'.(float)($this->getFieldValue($obj, 'value')).'" onKeyUp="javascript:this.value = this.value.replace(/,/g, \'.\'); " />
<select id="id_currency" name="id_currency" style="float:left;margin-left:10px;width:50px;display:none">
<option value="0">--</option>';
foreach (Currency::getCurrencies() as $row)
echo ' <option value="'.(int)$row['id_currency'].'" '.(($this->getFieldValue($obj, 'id_currency') == $row['id_currency']) ? 'selected="selected"' : '').'>'.$row['sign'].'</option>';
echo ' </select>
<span id="percent-span" style="margin-left:10px;display:none;float:left;font-size:12px;font-weight:bold;color:black"> %</span>
<sup style="float:left;margin-left:5px">*</sup>
<p class="clear">'.$this->l('Either the monetary amount or the %, depending on Type selected above').'</p>
</div>
<div id="behavior_not_exhausted" style="display:none;">
<label>'.$this->l('Behavior not exhausted:').'</label>
<div class="margin-form">
<select name="behavior_not_exhausted">
<option value="1" '.($obj->behavior_not_exhausted === 1 ? 'selected="selected"' : '').'>'.$this->l('Reduce the voucher to the total order amount').'</option>
<option value="2" '.($obj->behavior_not_exhausted == 2 ? 'selected="selected"' : '').'>'.$this->l('Create a new voucher with remaining amount').'</option>
<option value="3" '.($obj->behavior_not_exhausted == 3 ? 'selected="selected"' : '').'>'.$this->l('Create negative invoice').'</option>
</select>
</div>
</div>
</div>
<label>'.$this->l('Description:').' </label>
<div class="margin-form">';
foreach ($this->_languages as $language)
echo ' <div id="description_'.$language['id_lang'].'" style="display: '.($language['id_lang'] == $this->_defaultFormLanguage ? 'block' : 'none').'; float: left;">
<input size="33" type="text" name="description_'.$language['id_lang'].'" value="'.htmlentities($this->getFieldValue($obj, 'description', (int)($language['id_lang'])), ENT_COMPAT, 'UTF-8').'" /><sup> *</sup>
<span class="hint" name="help_box">'.$this->l('Invalid characters:').' <>;=#{}<span class="hint-pointer">&nbsp;</span></span>
<p class="clear">'.$this->l('Will appear in cart next to voucher code').'</p>
</div>';
$this->displayFlags($this->_languages, $this->_defaultFormLanguage, 'description', 'description');
echo ' </div>
<div class="clear" / >
<label>'.$this->l('Categories:').' </label>
<div class="margin-form">
<table cellspacing="0" cellpadding="0" class="table" style="width: 600px;">
<tr>
<th><input type="checkbox" name="checkme" class="noborder" onclick="checkDelBoxes(this.form, \'categoryBox[]\', this.checked)" /></th>
<th>'.$this->l('ID').'</th>
<th>'.$this->l('Name').'</th>
</tr>';
$done = array();
$index = array();
$indexedCategories = isset($_POST['categoryBox']) ? $_POST['categoryBox'] : ($obj->id ? Discount::getCategories($obj->id) : array());
$categories = Category::getCategories($this->context->language->id, false);
foreach ($indexedCategories AS $k => $row)
$index[] = $row['id_category'];
$this->recurseCategoryForInclude((int)(Tools::getValue($this->identifier)), $index, $categories, $categories[0][1], 1, $obj->id);
echo '
</table>
<p style="padding:0px; margin:0px 0px 10px 0px;">'.$this->l('Mark all checkbox(es) of categories to which the discount is to be applied').'<sup> *</sup></p>
</div>
<div class="clear" / >
<label>'.$this->l('Total quantity:').' </label>
<div class="margin-form">
<input type="text" size="15" name="quantity" value="'.(int)($this->getFieldValue($obj, 'quantity')).'" /> <sup>*</sup>
<p class="clear">'.$this->l('Total quantity available (mainly for vouchers open to everyone)').'</p>
</div>
<label>'.$this->l('Qty per each user:').' </label>
<div class="margin-form">
<input type="text" size="15" name="quantity_per_user" value="'.(int)($this->getFieldValue($obj, 'quantity_per_user')).'" /> <sup>*</sup>
<p class="clear">'.$this->l('Number of times a single customer can use this voucher').'</p>
</div>
<label>'.$this->l('Minimum amount').'</label>
<div class="margin-form">
<input type="text" size="15" name="minimal" value="'.($this->getFieldValue($obj, 'minimal') ? (float)($this->getFieldValue($obj, 'minimal')) : '0').'" onkeyup="javascript:this.value = this.value.replace(/,/g, \'.\'); " /> <sup>*</sup>&nbsp;
<select name="include_tax" id="include_tax" style="vertical-align: middle;">
<option value="0" '.($obj->include_tax == 0 ? 'selected="selected"' : '').'>'.$this->l('tax excl.').'</option>
<option value="1" '.($obj->include_tax == 1 ? 'selected="selected"' : '').'>'.$this->l('tax incl.').'</option>
</select>
<p class="clear">'.$this->l('0 if not applicable').'</p>
</div>
<div class="margin-form">
<p>
<input type="checkbox" name="cumulable"'.(($this->getFieldValue($obj, 'cumulable') == 1) ? ' checked="checked"' : '').' id="cumulable_on" value="1" />
<label class="t" for="cumulable_on"> '.$this->l('Cumulative with other vouchers').'</label>
</p>
</div>
<div class="margin-form">
<p>
<input type="checkbox" name="cumulable_reduction"'.(($this->getFieldValue($obj, 'cumulable_reduction') == 1) ? ' checked="checked"' : '').' id="cumulable_reduction_on" value="1" />
<label class="t" for="cumulable_reduction_on"> '.$this->l('Cumulative with price reductions').'</label>
</p>
</div>
<label>'.$this->l('To be used by:').' </label>
<div class="margin-form">
<input type="hidden" name="id_customer" value="0">
<input type="hidden" name="id_group" value="0">
<select name="id_target" id="id_target">
<option value="0_0">-- '.$this->l('All customers').' --</option>
<optgroup label="'.$this->l('Groups').'" id="id_target_group">
</optgroup>
<optgroup label="'.$this->l('Customers').'" id="id_target_customers">
</optgroup>
</select><br />'.$this->l('Filter:').' <input type="text" size="25" name="filter" id="filter" onkeyup="fillCustomersAjax();" class="space" value="" />
<script type="text/javascript">
var formDiscount = document.layers ? document.forms.discount : document.discount;
function fillCustomersAjax()
{
var filterValue = \''.(($value = (int)($this->getFieldValue($obj, 'id_customer'))) ? '0_'.$value : (($value = (int)($this->getFieldValue($obj, 'id_group'))) ? '1_'.$value : '')).'\';
if ($(\'#filter\').val())
filterValue = $(\'#filter\').val();
$.getJSON("'.dirname(self::$currentIndex).'/ajax.php",{ajaxDiscountCustomers:1,filter:filterValue},
function(obj) {
var groups_length = obj.groups.length;
if (obj.groups.length == 0)
groups_length = 1;
var customers_length = obj.customers.length;
if (obj.customers.length == 0)
customers_length = 1;
formDiscount.id_target.length = 1 + customers_length + groups_length;
if (obj.groups.length == 0)
{
formDiscount.id_target.options[1].value = -1;
formDiscount.id_target.options[1].text = \''.$this->l('No match found').'\';
formDiscount.id_target.options[1].className = "groups_filtered";
}
else
{
for (i = 0; i < obj.groups.length && i < 50; i++)
{
formDiscount.id_target.options[i+1].value = obj.groups[i]["value"];
formDiscount.id_target.options[i+1].text = obj.groups[i]["text"];
formDiscount.id_target.options[i+1].className = "groups_filtered";
}
if (obj.groups.length >= 50)
{
formDiscount.id_target.options[50].text = "'.$this->l('Too many results...',__CLASS__ , true, false).'";
formDiscount.id_target.options[50].value = "_";
formDiscount.id_target.options[50].className = "groups_filtered";
}
}
if (obj.customers.length == 0)
{
formDiscount.id_target.options[groups_length+1].value = -1;
formDiscount.id_target.options[groups_length+1].text = \''.$this->l('No match found').'\';
formDiscount.id_target.options[groups_length+1].className = "customers_filtered";
}
else
{
for (i = 0; i < obj.customers.length && i < 50; i++)
{
formDiscount.id_target.options[groups_length+1+i].value = obj.customers[i]["value"];
formDiscount.id_target.options[groups_length+1+i].text = obj.customers[i]["text"];
formDiscount.id_target.options[groups_length+1+i].className = "customers_filtered";
}
if (obj.customers.length >= 50)
{
formDiscount.id_target.options[groups_length+50+i].text = "'.$this->l('Too many results...',__CLASS__ , true, false).'";
formDiscount.id_target.options[groups_length+50+i].value = "_";
formDiscount.id_target.options[groups_length+50+i].className = "customers_filtered";
}
}
$(".groups_filtered").appendTo($("#id_target_group"));
$(".customers_filtered").appendTo($("#id_target_customers"));
if ($(\'#filter\').val())
{
if (formDiscount.id_target.options[1].value != -1)
formDiscount.id_target.options.selectedIndex = 1;
else
formDiscount.id_target.options.selectedIndex = 2;
}
else if(filterValue)
for (i = 0; i < (customers_length + groups_length); i++)
if (formDiscount.id_target.options[i+1].value == filterValue)
formDiscount.id_target.options.selectedIndex = i + 1;
}
);
}
fillCustomersAjax();
</script>
</div><br />';
includeDatepicker(array('date_from', 'date_to'), true);
echo '
<label>'.$this->l('From:').' </label>
<div class="margin-form">
<input type="text" size="20" id="date_from" name="date_from" value="'.($this->getFieldValue($obj, 'date_from') ? htmlentities($this->getFieldValue($obj, 'date_from'), ENT_COMPAT, 'UTF-8') : date('Y-m-d H:i:s')).'" /> <sup>*</sup>
<p class="clear">'.$this->l('Start date/time from which voucher can be used').'<br />'.$this->l('Format: YYYY-MM-DD HH:MM:SS').'</p>
</div>
<label>'.$this->l('To:').' </label>
<div class="margin-form">
<input type="text" size="20" id="date_to" name="date_to" value="'.($this->getFieldValue($obj, 'date_to') ? htmlentities($this->getFieldValue($obj, 'date_to'), ENT_COMPAT, 'UTF-8') : (date('Y') + 1).date('-m-d H:i:s')).'" /> <sup>*</sup>
<p class="clear">'.$this->l('End date/time at which voucher is no longer valid').'<br />'.$this->l('Format: YYYY-MM-DD HH:MM:SS').'</p>
</div>
<label>'.$this->l('Display the voucher in the cart summary:').' </label>
<div class="margin-form">
<input type="radio" name="cart_display" id="cart_active_on" value="1" '.($this->getFieldValue($obj, 'cart_display') ? 'checked="checked" ' : '').'/>
<label class="t" for="cart_display_on"> <img src="../img/admin/enabled.gif" alt="'.$this->l('Enabled').'" title="'.$this->l('Enabled').'" /></label>
<input type="radio" name="cart_display" id="cart_active_off" value="0" '.(!$this->getFieldValue($obj, 'cart_display') ? 'checked="checked" ' : '').'/>
<label class="t" for="cart_display_off"> <img src="../img/admin/disabled.gif" alt="'.$this->l('Disabled').'" title="'.$this->l('Disabled').'" /></label>
</div>
<div class="clear" / >
<label>'.$this->l('Status:').' </label>
<div class="margin-form">
<input type="radio" name="active" id="active_on" value="1" '.($this->getFieldValue($obj, 'active') ? 'checked="checked" ' : '').'/>
<label class="t" for="active_on"> <img src="../img/admin/enabled.gif" alt="'.$this->l('Enabled').'" title="'.$this->l('Enabled').'" /></label>
<input type="radio" name="active" id="active_off" value="0" '.(!$this->getFieldValue($obj, 'active') ? 'checked="checked" ' : '').'/>
<label class="t" for="active_off"> <img src="../img/admin/disabled.gif" alt="'.$this->l('Disabled').'" title="'.$this->l('Disabled').'" /></label>
<p>'.$this->l('Enable or disable voucher').'</p>
</div>';
if (Shop::isFeatureActive())
{
echo '<label>'.$this->l('Shop association:').'</label><div class="margin-form">';
$this->displayAssoShop();
echo '</div>';
}
echo ' <div class="margin-form">
<input type="submit" value="'.$this->l(' Save ').'" name="submitAdd'.$this->table.'" class="button" />
</div>
<div class="small"><sup>*</sup> '.$this->l('Required field').'</div>
</fieldset>
</form>';
}
/**
* Build a categories tree
*
* @param array $indexedCategories Array with categories where product is indexed (in order to check checkbox)
* @param array $categories Categories to list
* @param array $current Current category
* @param integer $id_category Current category id
*/
public static function recurseCategoryForInclude($id_obj, $indexedCategories, $categories, $current, $id_category = 1, $id_category_default = NULL, $has_suite = array())
{
global $done;
static $irow;
if (!isset($done[$current['infos']['id_parent']]))
$done[$current['infos']['id_parent']] = 0;
$done[$current['infos']['id_parent']] += 1;
$todo = sizeof($categories[$current['infos']['id_parent']]);
$doneC = $done[$current['infos']['id_parent']];
$level = $current['infos']['level_depth'] + 1;
echo '
<tr class="'.($irow++ % 2 ? 'alt_row' : '').'">
<td>
<input type="checkbox" name="categoryBox[]" class="categoryBox'.($id_category_default == $id_category ? ' id_category_default' : '').'" id="categoryBox_'.$id_category.'" value="'.$id_category.'"'.((in_array($id_category, $indexedCategories) OR ((int)(Tools::getValue('id_category')) == $id_category AND !(int)($id_obj)) OR Tools::getIsset('adddiscount')) ? ' checked="checked"' : '').' />
</td>
<td>
'.$id_category.'
</td>
<td>';
for ($i = 2; $i < $level; $i++)
echo '<img src="../img/admin/lvl_'.$has_suite[$i - 2].'.gif" alt="" style="vertical-align: middle;"/>';
echo '<img src="../img/admin/'.($level == 1 ? 'lv1.gif' : 'lv2_'.($todo == $doneC ? 'f' : 'b').'.gif').'" alt="" style="vertical-align: middle;"/> &nbsp;
<label for="categoryBox_'.$id_category.'" class="t">'.stripslashes($current['infos']['name']).'</label></td>
</tr>';
if ($level > 1)
$has_suite[] = ($todo == $doneC ? 0 : 1);
if (isset($categories[$id_category]))
foreach ($categories[$id_category] AS $key => $row)
if ($key != 'infos')
self::recurseCategoryForInclude($id_obj, $indexedCategories, $categories, $categories[$id_category][$key], $key, $id_category_default, $has_suite);
}
}
+1 -1
View File
@@ -229,7 +229,7 @@ class AdminPerformance extends AdminTab
if (!extension_loaded('xcache'))
$warnings[] = $this->l('To use Xcache, you must install the Xcache extension on your server.').' <a href="http://xcache.lighttpd.net">http://xcache.lighttpd.net</a>';
if (!is_writable(_PS_CACHEFS_DIRECTORY_))
if(!is_writable(_PS_CACHEFS_DIRECTORY_))
$warnings[] = $this->l('To use CacheFS the directory').' '.realpath(_PS_CACHEFS_DIRECTORY_).' '.$this->l('must be writable');
if ($warnings)
@@ -0,0 +1,85 @@
<label>{l s='Free shipping'}</label>
<div class="margin-form">
&nbsp;&nbsp;
<input type="radio" name="free_shipping" id="free_shipping_on" value="1" {if $currentTab->getFieldValue($currentObject, 'free_shipping')|intval}checked="checked"{/if} />
<label class="t" for="free_shipping_on"> <img src="../img/admin/enabled.gif" alt="{l s='Enabled'}" title="{l s='Enabled'}" style="cursor:pointer" /></label>
&nbsp;&nbsp;
<input type="radio" name="free_shipping" id="free_shipping_off" value="0" {if !$currentTab->getFieldValue($currentObject, 'free_shipping')|intval}checked="checked"{/if} />
<label class="t" for="free_shipping_off"> <img src="../img/admin/disabled.gif" alt="{l s='Disabled'}" title="{l s='Disabled'}" style="cursor:pointer" /></label>
</div>
<hr />
<label>{l s='Apply a discount'}</label>
<div class="margin-form">
&nbsp;&nbsp;
<input type="radio" name="apply_discount" id="apply_discount_percent" value="percent" {if $currentTab->getFieldValue($currentObject, 'reduction_percent')|intval}checked="checked"{/if} />
<label class="t" for="apply_discount_percent"> <img src="../img/admin/enabled.gif" alt="{l s='Enabled'}" title="{l s='Enabled'}" style="cursor:pointer" /> {l s='Percent (%)'}</label>
&nbsp;&nbsp;
<input type="radio" name="apply_discount" id="apply_discount_amount" value="amount" {if $currentTab->getFieldValue($currentObject, 'reduction_amount')|intval}checked="checked"{/if} />
<label class="t" for="apply_discount_amount"> <img src="../img/admin/enabled.gif" alt="{l s='Enabled'}" title="{l s='Enabled'}" style="cursor:pointer" /> {l s='Amount (¤)'}</label>
&nbsp;&nbsp;
<input type="radio" name="apply_discount" id="apply_discount_off" value="off" {if !$currentTab->getFieldValue($currentObject, 'reduction_amount')|intval && !$currentTab->getFieldValue($currentObject, 'reduction_percent')|intval}checked="checked"{/if} />
<label class="t" for="apply_discount_off"> <img src="../img/admin/disabled.gif" alt="{l s='Disabled'}" title="{l s='Disabled'}" style="cursor:pointer" /> {l s='None'}</label>
</div>
<div id="apply_discount_percent_div">
<label>{l s='Value (%)'}</label>
<div class="margin-form">
<input type="text" id="reduction_percent" name="reduction_percent" value="{$currentTab->getFieldValue($currentObject, 'reduction_percent')|floatval}" />
<p>{l s='Does not apply to the shipping costs'}</p>
</div>
</div>
<div id="apply_discount_amount_div">
<label>{l s='Value (¤)'}</label>
<div class="margin-form">
<input type="text" id="reduction_amount" name="reduction_amount" value="{$currentTab->getFieldValue($currentObject, 'reduction_amount')|floatval}" />
<select name="reduction_currency">
{foreach from=$currencies item='currency'}
<option value="{$currency.id_currency|intval}" {if $currentTab->getFieldValue($currentObject, 'reduction_currency') == $currency.id_currency || (!$currentTab->getFieldValue($currentObject, 'reduction_currency') && $currency.id_currency == $defaultCurrency)}selected="selected"{/if}>{$currency.iso_code}</option>
{/foreach}
</select>
<select name="reduction_tax">
<option value="0" {if $currentTab->getFieldValue($currentObject, 'reduction_tax') == 0}selected="selected"{/if}>{l s='Tax excluded'}</option>
<option value="1" {if $currentTab->getFieldValue($currentObject, 'reduction_tax') == 1}selected="selected"{/if}>{l s='Tax included'}</option>
</select>
</div>
</div>
<div id="apply_discount_to_div">
<label>{l s='Apply discount to'}</label>
<div class="margin-form">
&nbsp;&nbsp;
<input type="radio" name="apply_discount_to" id="apply_discount_to_order" value="order" {if $currentTab->getFieldValue($currentObject, 'reduction_product')|intval == 0}checked="checked"{/if} />
<label class="t" for="apply_discount_to_order"> {l s='Order (without shipping)'}</label>
&nbsp;&nbsp;
<input type="radio" name="apply_discount_to" id="apply_discount_to_product" value="specific" {if $currentTab->getFieldValue($currentObject, 'reduction_product')|intval > 0}checked="checked"{/if} />
<label class="t" for="apply_discount_to_product"> {l s='Specific product'}</label>
&nbsp;&nbsp;
<input type="radio" name="apply_discount_to" id="apply_discount_to_cheapest" value="cheapest" {if $currentTab->getFieldValue($currentObject, 'reduction_product')|intval == -1}checked="checked"{/if} />
<label class="t" for="apply_discount_to_cheapest"> {l s='Cheapest product'}</label>
&nbsp;&nbsp;
<input type="radio" name="apply_discount_to" id="apply_discount_to_selection" value="selection" {if $currentTab->getFieldValue($currentObject, 'reduction_product')|intval == -2}checked="checked"{/if} />
<label class="t" for="apply_discount_to_selection"> {l s='Selected product(s)'}</label>
</div>
<div id="apply_discount_to_product_div">
<label>{l s='Product'}</label>
<div class="margin-form">
<input type="hidden" id="reduction_product" name="reduction_product" value="{$currentTab->getFieldValue($currentObject, 'reduction_product')|intval}" />
<input type="text" id="reductionProductFilter" name="reductionProductFilter" value="{$reductionProductFilter}" style="width:400px" />
</div>
</div>
</div>
<hr />
<label>{l s='Send a free gift'}</label>
<div class="margin-form">
&nbsp;&nbsp;
<input type="radio" name="free_gift" id="free_gift_on" value="1" {if $currentTab->getFieldValue($currentObject, 'gift_product')|intval}checked="checked"{/if} />
<label class="t" for="free_gift_on"> <img src="../img/admin/enabled.gif" alt="{l s='Enabled'}" title="{l s='Enabled'}" style="cursor:pointer" /></label>
&nbsp;&nbsp;
<input type="radio" name="free_gift" id="free_gift_off" value="0" {if !$currentTab->getFieldValue($currentObject, 'gift_product')|intval}checked="checked"{/if} />
<label class="t" for="free_gift_off"> <img src="../img/admin/disabled.gif" alt="{l s='Disabled'}" title="{l s='Disabled'}" style="cursor:pointer" /></label>
</div>
<div id="free_gift_div">
<label>{l s='Product'}</label>
<div class="margin-form">
<input type="hidden" id="gift_product" name="gift_product" value="{$currentTab->getFieldValue($currentObject, 'gift_product')|intval}" />
<input type="text" id="giftProductFilter" name="giftProductFilter" value="{$giftProductFilter}" style="width:400px" />
</div>
</div>
@@ -0,0 +1,188 @@
<label>{l s='Limit to a single customer'}</label>
<div class="margin-form">
<input type="hidden" id="id_customer" name="id_customer" value="{$currentTab->getFieldValue($currentObject, 'id_customer')|intval}" />
<input type="text" id="customerFilter" name="customerFilter" value="{$customerFilter}" style="width:400px" />
<p>{l s='Optional, the cart rule will be available for everyone if you leave this field blank.'}</p>
</div>
<label>{l s='Validity'}</label>
<div class="margin-form">
<strong>{l s='from'}</strong>
<input type="text" name="date_from" value="{if $currentTab->getFieldValue($currentObject, 'date_from')}{$currentTab->getFieldValue($currentObject, 'date_from')}{else}{$defaultDateFrom}{/if}" />
<strong>{l s='to'}</strong>
<input type="text" name="date_to" value="{if $currentTab->getFieldValue($currentObject, 'date_to')}{$currentTab->getFieldValue($currentObject, 'date_to')}{else}{$defaultDateTo}{/if}" />
<p>{l s='Default period is one year.'}</p>
</div>
<label>{l s='Minimum amount'}</label>
<div class="margin-form">
<input type="text" name="minimum_amount" value="{$currentTab->getFieldValue($currentObject, 'minimum_amount')|floatval}" />
<select name="minimum_amount_currency">
{foreach from=$currencies item='currency'}
<option value="{$currency.id_currency|intval}" {if $currentTab->getFieldValue($currentObject, 'minimum_amount_currency') == $currency.id_currency || (!$currentTab->getFieldValue($currentObject, 'minimum_amount_currency') && $currency.id_currency == $defaultCurrency)}selected="selected"{/if}>{$currency.iso_code}</option>
{/foreach}
</select>
<select name="minimum_amount_tax">
<option value="0" {if $currentTab->getFieldValue($currentObject, 'minimum_amount_tax') == 0}selected="selected"{/if}>{l s='Tax excluded'}</option>
<option value="1" {if $currentTab->getFieldValue($currentObject, 'minimum_amount_tax') == 1}selected="selected"{/if}>{l s='Tax included'}</option>
</select>
<select name="minimum_amount_shipping">
<option value="0" {if $currentTab->getFieldValue($currentObject, 'minimum_amount_shipping') == 0}selected="selected"{/if}>{l s='Shipping excluded'}</option>
<option value="1" {if $currentTab->getFieldValue($currentObject, 'minimum_amount_shipping') == 1}selected="selected"{/if}>{l s='Shipping included'}</option>
</select>
<p>{l s='You can choose a minimum amount for the cart either with or without the taxes, with or without shipping.'}</p>
</div>
<label>{l s='Total available'}</label>
<div class="margin-form">
<input type="text" name="quantity" value="{$currentTab->getFieldValue($currentObject, 'quantity')|intval}" />
</div>
<label>{l s='Total available for each user'}</label>
<div class="margin-form">
<input type="text" name="quantity_per_user" value="{$currentTab->getFieldValue($currentObject, 'quantity_per_user')|intval}" />
</div>
{if $countries.unselected|@count + $countries.selected|@count > 1}
<br />
<input type="checkbox" id="country_restriction" name="country_restriction" value="1" {if $countries.unselected|@count}checked="checked"{/if} /> <strong>{l s='Country selection'}</strong>
<div id="country_restriction_div" style="border:1px solid #AAAAAA;margin-top:10px;padding:0 10px 10px 10px;background-color:#FFF5D3">
<table>
<tr>
<td>
<p><strong>{l s='Selected countries'}</strong></p>
<select name="country_select[]" id="country_select_2" style="border:1px solid #AAAAAA;width:400px;height:160px" multiple>
{foreach from=$countries.selected item='country'}
<option value="{$country.id_country|intval}">&nbsp;{$country.name}</option>
{/foreach}
</select><br /><br />
<a style="cursor:pointer;text-align:center;display:block;border:1px solid #aaa;text-decoration:none;background-color:#fafafa;color:#123456;margin:2px;padding:2px" id="country_select_remove">
{l s='Remove'} &gt;&gt;
</a>
</td>
<td style="padding-left:20px;">
<p><strong>{l s='Unselected countries'}</strong></p>
<select id="country_select_1" style="border:1px solid #AAAAAA;width:400px;height:160px" multiple>
{foreach from=$countries.unselected item='country'}
<option value="{$country.id_country|intval}">&nbsp;{$country.name}</option>
{/foreach}
</select><br /><br />
<a style="cursor:pointer;text-align:center;display:block;border:1px solid #aaa;text-decoration:none;background-color:#fafafa;color:#123456;margin:2px;padding:2px" id="country_select_add">
&lt;&lt; {l s='Add'}
</a>
</td>
</tr>
</table>
</div>
{/if}
{if $carriers.unselected|@count + $carriers.selected|@count > 1}
<br />
<input type="checkbox" id="carrier_restriction" name="carrier_restriction" value="1" {if $carriers.unselected|@count}checked="checked"{/if} /> <strong>{l s='Carrier selection'}</strong>
<div id="carrier_restriction_div" style="border:1px solid #AAAAAA;margin-top:10px;padding:0 10px 10px 10px;background-color:#FFF5D3">
<table>
<tr>
<td>
<p><strong>{l s='Selected carriers'}</strong></p>
<select name="carrier_select[]" id="carrier_select_2" style="border:1px solid #AAAAAA;width:400px;height:160px" multiple>
{foreach from=$carriers.selected item='carrier'}
<option value="{$carrier.id_carrier|intval}">&nbsp;{$carrier.name}</option>
{/foreach}
</select><br /><br />
<a style="cursor:pointer;text-align:center;display:block;border:1px solid #aaa;text-decoration:none;background-color:#fafafa;color:#123456;margin:2px;padding:2px" id="carrier_select_remove">
{l s='Remove'} &gt;&gt;
</a>
</td>
<td style="padding-left:20px;">
<p><strong>{l s='Unselected carriers'}</strong></p>
<select id="carrier_select_1" style="border:1px solid #AAAAAA;width:400px;height:160px" multiple>
{foreach from=$carriers.unselected item='carrier'}
<option value="{$carrier.id_carrier|intval}">&nbsp;{$carrier.name}</option>
{/foreach}
</select><br /><br />
<a style="cursor:pointer;text-align:center;display:block;border:1px solid #aaa;text-decoration:none;background-color:#fafafa;color:#123456;margin:2px;padding:2px" id="carrier_select_add">
&lt;&lt; {l s='Add'}
</a>
</td>
</tr>
</table>
</div>
{/if}
{if $groups.unselected|@count + $groups.selected|@count > 1}
<br />
<input type="checkbox" id="group_restriction" name="group_restriction" value="1" {if $groups.unselected|@count}checked="checked"{/if} /> <strong>{l s='Customer group selection'}</strong>
<div id="group_restriction_div" style="border:1px solid #AAAAAA;margin-top:10px;padding:0 10px 10px 10px;background-color:#FFF5D3">
<table>
<tr>
<td>
<p><strong>{l s='Selected groups'}</strong></p>
<select name="group_select[]" id="group_select_2" style="border:1px solid #AAAAAA;width:400px;height:160px" multiple>
{foreach from=$groups.selected item='group'}
<option value="{$group.id_group|intval}">&nbsp;{$group.name}</option>
{/foreach}
</select><br /><br />
<a style="text-align:center;display:block;border:1px solid #aaa;text-decoration:none;background-color:#fafafa;color:#123456;margin:2px;padding:2px" id="group_select_remove">
{l s='Remove'} &gt;&gt;
</a>
</td>
<td style="padding-left:20px;">
<p><strong>{l s='Unselected groups'}</strong></p>
<select id="group_select_1" style="border:1px solid #AAAAAA;width:400px;height:160px" multiple>
{foreach from=$groups.unselected item='group'}
<option value="{$group.id_group|intval}">&nbsp;{$group.name}</option>
{/foreach}
</select><br /><br />
<a style="text-align:center;display:block;border:1px solid #aaa;text-decoration:none;background-color:#fafafa;color:#123456;margin:2px;padding:2px" id="group_select_add">
&lt;&lt; {l s='Add'}
</a>
</td>
</tr>
</table>
</div>
{/if}
{if $cart_rules.unselected|@count + $cart_rules.selected|@count > 1}
<br />
<input type="checkbox" id="cart_rule_restriction" name="cart_rule_restriction" value="1" {if $cart_rules.unselected|@count}checked="checked"{/if} /> <strong>{l s='Other cart rules compatibility'}</strong>
<div id="cart_rule_restriction_div" style="border:1px solid #AAAAAA;margin-top:10px;padding:0 10px 10px 10px;background-color:#FFF5D3">
<table>
<tr>
<td>
<p><strong>{l s='Combinable cart rules'}</strong></p>
<select name="cart_rule_select[]" id="cart_rule_select_2" style="border:1px solid #AAAAAA;width:400px;height:160px" multiple>
{foreach from=$cart_rules.selected item='cart_rule'}
<option value="{$cart_rule.id_cart_rule|intval}">&nbsp;{$cart_rule.name}</option>
{/foreach}
</select><br /><br />
<a style="text-align:center;display:block;border:1px solid #aaa;text-decoration:none;background-color:#fafafa;color:#123456;margin:2px;padding:2px" id="cart_rule_select_remove">
{l s='Remove'} &gt;&gt;
</a>
</td>
<td style="padding-left:20px;">
<p><strong>{l s='Uncombinable cart rules'}</strong></p>
<select id="cart_rule_select_1" style="border:1px solid #AAAAAA;width:400px;height:160px" multiple="">
{foreach from=$cart_rules.unselected item='cart_rule'}
<option value="{$cart_rule.id_cart_rule|intval}">&nbsp;{$cart_rule.name}</option>
{/foreach}
</select><br /><br />
<a style="text-align:center;display:block;border:1px solid #aaa;text-decoration:none;background-color:#fafafa;color:#123456;margin:2px;padding:2px" id="cart_rule_select_add">
&lt;&lt; {l s='Add'}
</a>
</td>
</tr>
</table>
</div>
{/if}
<br />
<input type="checkbox" id="product_restriction" name="product_restriction" value="1" {if $product_rules|@count}checked="checked"{/if} /> <strong>{l s='Product selection'}</strong>
<div id="product_restriction_div" style="border:1px solid #AAAAAA;margin-top:10px;padding:10px 10px 10px 10px;background-color:#FFF5D3">
{l s='Add a filter on'}
<select id="product_rule_type">
<option value="">{l s='-- Choose --'}</option>
<option value="products">{l s='Products'}</option>
<option value="attributes">{l s='Attributes'}</option>
<option value="categories">{l s='Categories'}</option>
</select>
<a href="javascript:addProductRule();">
<img src="../img/admin/add.gif" alt="{l s='Add'}" title="{l s='Add'}" /> {l s='Add'}
</a>
<hr />
<table id="product_rule_table" class="table" cellpadding="0" cellspacing="0">
{foreach from=$product_rules item='product_rule'}
{$product_rule}
{/foreach}
</table>
</div>
@@ -0,0 +1,300 @@
/*
* 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: 6844 $
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
function addProductRule()
{
product_rules_counter += 1;
if ($('#product_rule_type').val() != 0)
$.get(
'ajax-tab.php',
{controller:'AdminCartRules',token:currentToken,newProductRule:1,product_rule_type:$('#product_rule_type').val(),product_rule_id:product_rules_counter},
function(content) {
if (content != "")
$('#product_rule_table').append(content);
}
);
}
function removeProductRule(id)
{
$('#product_rule_' + id + '_tr').remove();
}
function toggleCartRuleFilter(id)
{
if ($(id).attr('checked'))
$('#' + $(id).attr('id') + '_div').show(400);
else
$('#' + $(id).attr('id') + '_div').hide(200);
}
function removeCartRuleOption(item)
{
var id = $(item).attr('id').replace('_remove', '');
$('#' + id + '_2 option:selected').remove().appendTo('#' + id + '_1');
}
function addCartRuleOption(item)
{
var id = $(item).attr('id').replace('_add', '');
$('#' + id + '_1 option:selected').remove().appendTo('#' + id + '_2');
}
function updateProductRuleShortDescription(item)
{
var id1 = $(item).attr('id').replace('_add', '').replace('_remove', '');
var id2 = id1.replace('_select', '');
var length = $('#' + id1 + '_2 option').length;
if (length == 1)
$('#' + id2 + '_match').val($('#' + id1 + '_2 option').first().text().trim());
else
$('#' + id2 + '_match').val(length);
}
var restrictions = new Array('country', 'carrier', 'group', 'cart_rule');
for (i in restrictions)
{
toggleCartRuleFilter($('#' + restrictions[i] + '_restriction'));
$('#' + restrictions[i] + '_restriction').click(function() {toggleCartRuleFilter(this);});
$('#' + restrictions[i] + '_select_remove').click(function() {removeCartRuleOption(this);});
$('#' + restrictions[i] + '_select_add').click(function() {addCartRuleOption(this);});
}
toggleCartRuleFilter($('#product_restriction'));
$('#product_restriction').click(function() {toggleCartRuleFilter(this);});
function toggleApplyDiscount(percent, amount, apply_to)
{
if (percent)
{
$('#apply_discount_percent_div').show(400);
if ($('#apply_discount_to_product').attr('checked'))
toggleApplyDiscountTo();
$('#apply_discount_to_cheapest').removeAttr('disabled');
$('#apply_discount_to_cheapest').removeAttr('checked');
}
else
{
$('#apply_discount_percent_div').hide(200);
$('#reduction_percent').val('0');
$('#apply_discount_to_cheapest').attr('disabled', 'disabled');
}
if (amount)
{
$('#apply_discount_amount_div').show(400);
if ($('#apply_discount_to_product').attr('checked'))
toggleApplyDiscountTo();
$('#apply_discount_to_cheapest').attr('disabled', 'disabled');
$('#apply_discount_to_cheapest').removeAttr('checked');
}
else
{
$('#apply_discount_amount_div').hide(200);
$('#reduction_amount').val('0');
$('#apply_discount_to_cheapest').removeAttr('disabled');
}
if (apply_to)
$('#apply_discount_to_div').show(400);
else
{
toggleApplyDiscountTo();
$('#apply_discount_to_div').hide(200);
}
}
function toggleApplyDiscountTo()
{
if ($('#apply_discount_to_product').attr('checked'))
$('#apply_discount_to_product_div').show(400);
else
{
$('#apply_discount_to_product_div').hide(200);
$('#reductionProductFilter').val('');
if ($('#apply_discount_to_order').attr('checked'))
$('#reduction_product').val('0');
if ($('#apply_discount_to_cheapest').attr('checked'))
$('#reduction_product').val('-1');
if ($('#apply_discount_to_selection').attr('checked'))
$('#reduction_product').val('-2');
}
}
function toggleGiftProduct()
{
if ($('#free_gift_on').attr('checked'))
$('#free_gift_div').show(400);
else
{
$('#gift_product').val('0');
$('#giftProductFilter').val('');
$('#free_gift_div').hide(200);
}
}
$('#apply_discount_percent').click(function() {toggleApplyDiscount(true, false, true);});
if ($('#apply_discount_percent').attr('checked'))
toggleApplyDiscount(true, false, true);
$('#apply_discount_amount').click(function() {toggleApplyDiscount(false, true, true);});
if ($('#apply_discount_amount').attr('checked'))
toggleApplyDiscount(false, true, true);
$('#apply_discount_off').click(function() {toggleApplyDiscount(false, false, false);});
if ($('#apply_discount_off').attr('checked'))
toggleApplyDiscount(false, false, false);
$('#apply_discount_to_order').click(function() {toggleApplyDiscountTo();});
if ($('#apply_discount_to_order').attr('checked'))
toggleApplyDiscountTo();
$('#apply_discount_to_product').click(function() {toggleApplyDiscountTo();});
if ($('#apply_discount_to_product').attr('checked'))
toggleApplyDiscountTo();
$('#apply_discount_to_cheapest').click(function() {toggleApplyDiscountTo();});
if ($('#apply_discount_to_cheapest').attr('checked'))
toggleApplyDiscountTo();
$('#apply_discount_to_selection').click(function() {toggleApplyDiscountTo();});
if ($('#apply_discount_to_selection').attr('checked'))
toggleApplyDiscountTo();
$('#free_gift_on').click(function() {toggleGiftProduct();});
$('#free_gift_off').click(function() {toggleGiftProduct();});
toggleGiftProduct();
// Main form submit
$('#cart_rule_form').submit(function() {
if ($('#customerFilter').val() == '')
$('#id_customer').val('0');
for (i in restrictions)
{
if ($('#' + restrictions[i] + '_select_1 option').length == 0)
$('#' + restrictions[i] + '_restriction').removeAttr('checked');
else
{
$('#' + restrictions[i] + '_select_2 option').each(function(i) {
$(this).attr('selected', 'selected');
});
}
}
$('.product_rule_toselect option').each(function(i) {
$(this).attr('selected', 'selected');
});
});
$('#giftProductFilter')
.autocomplete(
'ajax-tab.php', {
minChars: 2,
max: 50,
width: 500,
selectFirst: false,
scroll: false,
dataType: 'json',
formatItem: function(data, i, max, value, term) {
return value;
},
parse: function(data) {
var mytab = new Array();
for (var i = 0; i < data.length; i++)
mytab[mytab.length] = { data: data[i], value: (data[i].reference + ' ' + data[i].name).trim() };
return mytab;
},
extraParams: {
controller: 'AdminCartRules',
token: currentToken,
giftProductFilter: 1
}
}
)
.result(function(event, data, formatted) {
$('#gift_product').val(data.id_product);
$('#giftProductFilter').val((data.reference + ' ' + data.name).trim());
});
$('#reductionProductFilter')
.autocomplete(
'ajax-tab.php', {
minChars: 2,
max: 50,
width: 500,
selectFirst: false,
scroll: false,
dataType: 'json',
formatItem: function(data, i, max, value, term) {
return value;
},
parse: function(data) {
var mytab = new Array();
for (var i = 0; i < data.length; i++)
mytab[mytab.length] = { data: data[i], value: (data[i].reference + ' ' + data[i].name).trim() };
return mytab;
},
extraParams: {
controller: 'AdminCartRules',
token: currentToken,
reductionProductFilter: 1
}
}
)
.result(function(event, data, formatted) {
$('#reduction_product').val(data.id_product);
$('#reductionProductFilter').val((data.reference + ' ' + data.name).trim());
});
$('#customerFilter')
.autocomplete(
'ajax-tab.php', {
minChars: 2,
max: 50,
width: 500,
selectFirst: false,
scroll: false,
dataType: 'json',
formatItem: function(data, i, max, value, term) {
return value;
},
parse: function(data) {
var mytab = new Array();
for (var i = 0; i < data.length; i++)
mytab[mytab.length] = { data: data[i], value: data[i].cname + ' (' + data[i].email + ')' };
return mytab;
},
extraParams: {
controller: 'AdminCartRules',
token: currentToken,
customerFilter: 1
}
}
)
.result(function(event, data, formatted) {
$('#id_customer').val(data.id_customer);
$('#customerFilter').val(data.cname + ' (' + data.email + ')');
});
@@ -0,0 +1,59 @@
<form action="{$currentIndex}&token={$currentToken}&addcart_rule" id="cart_rule_form" method="post">
<fieldset>
<legend><img src="../img/t/AdminCartRules.gif" /> {l s='Cart Rule'}</legend>
{if $currentObject->id}<input type="hidden" name="id_cart_rule" value="{$currentObject->id|intval}" />{/if}
<label>{l s='Name'}</label>
<div class="margin-form">
{foreach from=$languages item=language}
<input type="text" name="name_{$language.id_lang}" value="{$currentTab->getFieldValue($currentObject, 'name', $language.id_lang)}" style="width:300px" />
<br />
{/foreach}
<p>{l s='Will be displayed in the cart summary as well as on the invoice.'}</p>
</div>
<label>{l s='Description'}</label>
<div class="margin-form">
<textarea name="description" style="width:90%;height:100px">{$currentTab->getFieldValue($currentObject, 'description')}</textarea>
<p>{l s='For you only, never displayed to the customer.'}</p>
</div>
<label>{l s='Code'}</label>
<div class="margin-form">
<input type="text" id="code" name="code" value="{$currentTab->getFieldValue($currentObject, 'code')}" />
<img src="../img/admin/news-new.gif" onclick="gencode(8);" style="cursor:pointer" />
<p>{l s='Optional, the rule will automatically be applied if you leave this field blank.'}</p>
</div>
<label>{l s='Partial use'}</label>
<div class="margin-form">
<select name="partial_use">
<option value="0" {if $currentTab->getFieldValue($currentObject, 'partial_use') == 0}selected="selected"{/if}>{l s='No - Lower the voucher value to the total order amount'}</option>
<option value="1" {if $currentTab->getFieldValue($currentObject, 'partial_use') == 1}selected="selected"{/if}>{l s='Yes - Create a new voucher with the remainder'}</option>
</select>
</div>
<label>{l s='Priority'}</label>
<div class="margin-form">
<input type="text" name="priority" value="{$currentTab->getFieldValue($currentObject, 'priority')|intval}" />
</div>
<label>{l s='Status'}</label>
<div class="margin-form">
&nbsp;&nbsp;
<input type="radio" name="active" id="active_on" value="1" {if $currentTab->getFieldValue($currentObject, 'active')|intval}checked="checked"{/if} />
<label class="t" for="active_on"> <img src="../img/admin/enabled.gif" alt="{l s='Enabled'}" title="{l s='Enabled'}" style="cursor:pointer" /></label>
&nbsp;&nbsp;
<input type="radio" name="active" id="active_off" value="0" {if !$currentTab->getFieldValue($currentObject, 'active')|intval}checked="checked"{/if} />
<label class="t" for="active_off"> <img src="../img/admin/disabled.gif" alt="{l s='Disabled'}" title="{l s='Disabled'}" style="cursor:pointer" /></label>
</div>
<hr />
<legend style="margin:-22px 0 10px 0"><img src="../img/admin/access.png" /> {l s='Conditions'}</legend>
{include file='cart_rules/conditions.tpl'}
<div class="clear">&nbsp;</div><hr />
<legend style="margin:-22px 0 10px 0"><img src="../img/admin/asterisk.gif" /> {l s='Actions'}</legend>
{include file='cart_rules/actions.tpl'}
<hr />
<input type="submit" value="{l s='Save'}" class="button" name="submitAddcart_rule" />
</fieldset>
</form>
<script type="text/javascript">
var product_rules_counter = {if isset($product_rules_counter)}{$product_rules_counter}{else}0{/if};
var currentToken = '{$currentToken}';
</script>
<script type="text/javascript" src="themes/template/cart_rules/form.js"></script>
@@ -0,0 +1,36 @@
<tr id="product_rule_{$product_rule_id}_tr">
<td>
<a href="javascript:removeProductRule({$product_rule_id});">
<img src="../img/admin/disabled.gif" alt="{l s='Remove'}" title="{l s='Remove'}" />
</a>
</td>
<td>
<input type="hidden" name="product_rule[]" value="{$product_rule_id}" />
<input type="hidden" name="product_rule_{$product_rule_id}_type" value="{$product_rule_type}" />
[{$product_rule_type}] {l s='The cart must contain at least'}
</td>
<td style="padding:5px">
<input type="text" name="product_rule_{$product_rule_id}_quantity" value="{$product_rule_quantity|intval}" style="width:30px" />
</td>
<td>
{l s='product(s) matching'}
</td>
<td>
<input type="text" id="product_rule_{$product_rule_id}_match" value="" disabled="disabled" />
</td>
<td>
<a id="product_rule_{$product_rule_id}_choose_link" href="#product_rule_{$product_rule_id}_choose_content">
<img src="../img/admin/choose.gif" alt="{l s='Choose'}" title="{l s='Choose'}" /> {l s='Choose'}
</a>
<div>
<div id="product_rule_{$product_rule_id}_choose_content">
{$product_rule_choose_content}
</div>
</div>
</td>
</tr>
<script type="text/javascript">
$('#product_rule_{$product_rule_id}_choose_content').parent().hide();
$("#product_rule_{$product_rule_id}_choose_link").fancybox();
</script>
@@ -0,0 +1,32 @@
<table>
<tr>
<td>
<p><strong>{l s='Selected'}</strong></p>
<select name="product_rule_select_{$product_rule_id}[]" class="product_rule_toselect" id="product_rule_select_{$product_rule_id}_2" style="border:1px solid #AAAAAA;width:400px;height:160px" multiple>
{foreach from=$product_rule_itemlist.selected item='item'}
<option value="{$item.id|intval}">&nbsp;{$item.name}</option>
{/foreach}
</select><br /><br />
<a style="cursor:pointer;text-align:center;display:block;border:1px solid #aaa;text-decoration:none;background-color:#fafafa;color:#123456;margin:2px;padding:2px" id="product_rule_select_{$product_rule_id}_remove">
{l s='Remove'} &gt;&gt;
</a>
</td>
<td style="padding-left:20px;">
<p><strong>{l s='Unselected'}</strong></p>
<select id="product_rule_select_{$product_rule_id}_1" style="border:1px solid #AAAAAA;width:400px;height:160px" multiple>
{foreach from=$product_rule_itemlist.unselected item='item'}
<option value="{$item.id|intval}">&nbsp;{$item.name}</option>
{/foreach}
</select><br /><br />
<a style="cursor:pointer;text-align:center;display:block;border:1px solid #aaa;text-decoration:none;background-color:#fafafa;color:#123456;margin:2px;padding:2px" id="product_rule_select_{$product_rule_id}_add">
&lt;&lt; {l s='Add'}
</a>
</td>
</tr>
</table>
<script type="text/javascript">
$('#product_rule_select_{$product_rule_id}_remove').click(function() { removeCartRuleOption(this); updateProductRuleShortDescription(this); });
$('#product_rule_select_{$product_rule_id}_add').click(function() { addCartRuleOption(this); updateProductRuleShortDescription(this); });
$(document).ready(function() { updateProductRuleShortDescription($('#product_rule_select_{$product_rule_id}_add')); });
</script>
@@ -82,7 +82,7 @@
{foreach from=$toolbar_btn item=btn key=k}
<li>
<a class="toolbar_btn" href="{$btn.href}" title="{$btn.desc}">
<span class="process-icon-{$btn.imgclass|default:$k} {$btn.class|default:'' }" ></span>{$btn.desc}
<span class="process-icon-{$btn.imgclass|default:$k} {$btn.class|default:''}" ></span>{$btn.desc}
</a>
</li>
{/foreach}
+1 -1
View File
@@ -59,7 +59,7 @@
{foreach from=$toolbar_btn item=btn key=k}
<li>
<a class="toolbar_btn" href="{$btn.href}" title="{$btn.desc}">
<span class="process-icon-{$btn.imgclass|default:$k} {$btn.class|default:'' }" ></span>{$btn.desc}
<span class="process-icon-{$btn.imgclass|default:$k} {$btn.class|default:''}" ></span>{$btn.desc}
</a>
</li>
{/foreach}
@@ -67,7 +67,7 @@
{foreach from=$toolbar_btn item=btn key=k}
<li>
<a class="toolbar_btn" href="{$btn.href}" title="{$btn.desc}">
<span class="process-icon-{$btn.imgclass|default:$k} {$btn.class|default:'' }" ></span>{$btn.desc}
<span class="process-icon-{$btn.imgclass|default:$k} {$btn.class|default:''}" ></span>{$btn.desc}
</a>
</li>
{/foreach}
@@ -61,7 +61,7 @@
{foreach from=$toolbar_btn item=btn key=k}
<li>
<a class="toolbar_btn" href="{$btn.href}" title="{$btn.desc}">
<span class="process-icon-{$btn.imgclass|default:$k} {$btn.class|default:'' }" ></span>{$btn.desc}
<span class="process-icon-{$btn.imgclass|default:$k} {$btn.class|default:''}" ></span>{$btn.desc}
</a>
</li>
{/foreach}
@@ -136,13 +136,13 @@
<input type="text" size="{if isset($field['size'])}{$field['size']|intval}{else}5{/if}" name="{$key}_{$id_lang}" value="{$value}" />
</div>
{/foreach}
{elseif $field['type'] == 'textareaLang' }
{elseif $field['type'] == 'textareaLang'}
{foreach $field['languages'] AS $id_lang => $value}
<div id="{$key}_{$id_lang}" style="display: {if $id_lang == $current_id_lang}block{else}none{/if}; float: left;">
<textarea rows="{$field['rows']}" cols="{$field['cols']|intval}" name="{$key}_{$id_lang}">{$value|replace:'\r\n':"\n"}</textarea>
</div>
{/foreach}
{elseif $field['type'] == 'selectLang' }
{elseif $field['type'] == 'selectLang'}
{foreach $languages as $language}
<div id="{$key}_{$language.id_lang}" style="margin-bottom:8px; display: {if $language.id_lang == $current_id_lang}block{else}none{/if}; float: left; vertical-align: top;">
<select name="{$key}_{$language.iso_code|upper}">
+2 -2
View File
@@ -111,7 +111,7 @@ $(document).ready(function() {
if({$refresh_check_version})
{
$('#blockNewVersionCheck').hide();
$.ajax({
$.ajax({
type : 'POST',
data : {
ajax : '1',
@@ -179,7 +179,7 @@ $(document).ready(function() {
{
// don't show/hide screencast if it's deactivated
{if $employee->bo_show_screencast}
$('#adminpresentation').fadeOut('slow');
$('#adminpresentation').fadeOut('slow');
{/if}
$('#partner_preactivation').fadeOut('slow');
$('#discover_prestashop').fadeOut('slow');
@@ -61,7 +61,7 @@
{foreach from=$toolbar_btn item=btn key=k}
<li>
<a class="toolbar_btn" href="{$btn.href}" title="{$btn.desc}">
<span class="process-icon-{$btn.imgclass|default:$k} {$btn.class|default:'' }" ></span>{$btn.desc}
<span class="process-icon-{$btn.imgclass|default:$k} {$btn.class|default:''}" ></span>{$btn.desc}
</a>
</li>
{/foreach}
@@ -29,7 +29,7 @@
{if $field['type'] == 'price'}
<div class="margin-form">
{$field['currency_left']}
<input type="text"{if isset($field['id']) } id="{$field['id']}"{/if} size="{if isset($field['size'])}{$field['size']|intval}{else} 5{/if}" name="{$key}" value="{$field['value']|escape:'htmlall':'UTF-8'}" />
<input type="text"{if isset($field['id'])} id="{$field['id']}"{/if} size="{if isset($field['size'])}{$field['size']|intval}{else} 5{/if}" name="{$key}" value="{$field['value']|escape:'htmlall':'UTF-8'}" />
{if isset($field['next'])} &nbsp; {$field['next']|strval}{/if}
{$field['currency_right']}
{elseif $field['type'] == 'disabled'}
@@ -38,7 +38,7 @@
{elseif $field['type'] == 'maintenance_ip'}
<div class="margin-form">
{$field['script_ip']}
<input type="text"{if isset($field['id']) } id="{$field['id']}"{/if} size="{if isset($field['size'])}{$field['size']|intval}{else} 5{/if}" name="{$key}" value="{$field['value']|escape:'htmlall':'UTF-8'}" />
<input type="text"{if isset($field['id'])} id="{$field['id']}"{/if} size="{if isset($field['size'])}{$field['size']|intval}{else} 5{/if}" name="{$key}" value="{$field['value']|escape:'htmlall':'UTF-8'}" />
{$field['link_remove_ip']}
{else}
<div class="margin-form">
@@ -167,7 +167,7 @@
<td style="padding-bottom:5px;">
{if $currency->format % 2 != 0}{$currency->sign}{/if}
<input type="text" size="6" name="attribute_wholesale_price" id="attribute_wholesale_price" value="0.00" onKeyUp="if (isArrowKey(event)) return ;this.value = this.value.replace(/,/g, '.');" />
{if $currency->format % 2 == 0 } {$currency->sign} {/if}({l s='overrides Wholesale price on Information tab'})</td>
{if $currency->format % 2 == 0} {$currency->sign} {/if}({l s='overrides Wholesale price on Information tab'})</td>
</tr>
<tr>
<td style="width:150px;vertical-align:top;text-align:right;padding-right:10px;font-weight:bold;">{l s='Impact on price:'}</td>
@@ -178,7 +178,7 @@
<option value="-1">{l s='Reduction'}</option>
</select>
<span id="span_impact">&nbsp;&nbsp;{l s='of'}&nbsp;&nbsp;{if $currency->format % 2 != 0}{$currency->sign} {/if}
<input type="text" size="6" name="attribute_price" id="attribute_price" value="0.00" onKeyUp="if (isArrowKey(event)) return ;this.value = this.value.replace(/,/g, '.'); calcImpactPriceTI();"/>{if $currency->format % 2 == 0 } {$currency->sign}{/if}
<input type="text" size="6" name="attribute_price" id="attribute_price" value="0.00" onKeyUp="if (isArrowKey(event)) return ;this.value = this.value.replace(/,/g, '.'); calcImpactPriceTI();"/>{if $currency->format % 2 == 0} {$currency->sign}{/if}
{if $country_display_tax_label}
{l s='(tax excl.)'}
<span {if $tax_exclude_option}style="display:none"{/if}> {l s='or'} {if $currency->format % 2 != 0}{$currency->sign} {/if}
@@ -218,9 +218,9 @@
{if $ps_use_ecotax}
<tr>
<td style="width:150px;vertical-align:top;text-align:right;padding-right:10px;font-weight:bold;">
{l s='Eco-tax:' }
{l s='Eco-tax:'}
</td>
<td style="padding-bottom:5px;">{if $currency->format % 2 != 0 }{$currency->sign}{/if}
<td style="padding-bottom:5px;">{if $currency->format % 2 != 0}{$currency->sign}{/if}
<input type="text" size="3" name="attribute_ecotax" id="attribute_ecotax" value="0.00"
onKeyUp="if (isArrowKey(event)) return ;this.value = this.value.replace(/,/g, '.');" />
{if $currency->format % 2 == 0} {$currency->sign}{/if}
@@ -229,7 +229,7 @@
</tr>
{/if}
<tr>
<td style="width:150px;vertical-align:top;text-align:right;padding-right:10px;font-weight:bold;" class="col-left"><label>{l s='Minimum quantity:' }</label>
<td style="width:150px;vertical-align:top;text-align:right;padding-right:10px;font-weight:bold;" class="col-left"><label>{l s='Minimum quantity:'}</label>
</td>
<td style="padding-bottom:5px;">
<input size="3" maxlength="6" name="minimal_quantity" id="minimal_quantity" type="text" value="{$minimal_quantity}" />
@@ -252,7 +252,7 @@
</tr>
<tr><td colspan="2"><div class="separation"></div></td></tr>
<tr>
<td style="width:150px">{l s='Image:' }</td>
<td style="width:150px">{l s='Image:'}</td>
<td style="padding-bottom:5px;">
<ul id="id_image_attr">
{foreach from=$images key=k item=image}
@@ -12,7 +12,7 @@
{foreach from=$toolbar_btn item=btn key=k}
<li>
<a class="toolbar_btn action-{$k}" href="{$btn.href}" title="{$btn.desc}">
<span class="process-icon-{$k} {$btn.class|default:'' }" ></span>{$btn.desc}
<span class="process-icon-{$k} {$btn.class|default:''}" ></span>{$btn.desc}
</a>
</li>
{/foreach}
@@ -56,7 +56,7 @@
{foreach $ranges AS $range}
<td class="center">
{$currency->getSign('left')}
<input type="text" id="fees_all_{$range[$rangeIdentifier]}" onchange="this.value = this.value.replace(/,/g, \'.\');" onkeyup="if ((event.keyCode||event.which) != 9){ spreadFees('.$range[$rangeIdentifier].') }" style="width: 45px;" />
<input type="text" id="fees_all_{$range[$rangeIdentifier]}" onchange="this.value = this.value.replace(/,/g, \'.\');" onkeyup="if ((event.keyCode||event.which) != 9){ spreadFees('.$range[$rangeIdentifier].')}" style="width: 45px;" />
{$currency->getSign('right')}
</td>
{/foreach}
+4 -4
View File
@@ -296,7 +296,7 @@ class AdminControllerCore extends Controller
if (!empty($action) && method_exists($this, 'ajaxProcess'.Tools::toCamelCase($action)))
$this->{'ajaxProcess'.Tools::toCamelCase($action)}();
else if (method_exists($this, 'ajaxProcess'))
$this->ajaxProcess();
$this->ajaxProcess();
// @TODO We should use a displayAjaxError
/*$this->displayErrors();
@@ -1104,7 +1104,7 @@ class AdminControllerCore extends Controller
'content' => $this->content,
'url_post' => self::$currentIndex.'&token='.$this->token,
));
}
}
/**
* initialize the invalid doom page of death
@@ -1703,7 +1703,7 @@ class AdminControllerCore extends Controller
* @param integer $id_lang Language id (optional)
* @return string
*/
protected function getFieldValue($obj, $key, $id_lang = null)
public function getFieldValue($obj, $key, $id_lang = null)
{
if ($id_lang)
$default_value = ($obj->id && isset($obj->{$key}[$id_lang])) ? $obj->{$key}[$id_lang] : '';
@@ -2334,5 +2334,5 @@ EOF;
return $output;
return $output;
}
}
}
+1 -1
View File
@@ -2167,7 +2167,7 @@ abstract class AdminTabCore
* @param integer $id_lang Language id (optional)
* @return string
*/
protected function getFieldValue($obj, $key, $id_lang = NULL, $id_shop = null)
public function getFieldValue($obj, $key, $id_lang = NULL, $id_shop = null)
{
if (!$id_shop && $obj->isLangMultishop())
$id_shop = Context::getContext()->shop->getID();
+7
View File
@@ -174,6 +174,13 @@ class CarrierCore extends ObjectModel
return true;
}
public function delete()
{
if (!parent::delete())
return false;
return Db::getInstance()->Execute('DELETE FROM '._DB_PREFIX_.'cart_rule_carrier WHERE id_carrier = '.(int)$this->id);
}
/**
* Change carrier id in delivery prices when updating a carrier
*
+96 -242
View File
@@ -212,7 +212,7 @@ class CartCore extends ObjectModel
DELETE FROM `'._DB_PREFIX_.'customization`
WHERE `id_cart` = '.(int)$this->id);
if (!Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'cart_discount` WHERE `id_cart` = '.(int)($this->id))
if (!Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'cart_cart_rule` WHERE `id_cart` = '.(int)($this->id))
OR !Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'cart_product` WHERE `id_cart` = '.(int)($this->id)))
return false;
@@ -247,6 +247,15 @@ class CartCore extends ObjectModel
return 0;
}
/**
* @deprecated 1.5.0.1
*/
public function getDiscounts($lite = false, $refresh = false)
{
Tools::displayAsDeprecated();
return $this->getCartRules();
}
/**
* Return cart discounts
*
@@ -254,78 +263,49 @@ class CartCore extends ObjectModel
* @param bool true will erase the cache
* @result array Discounts
*/
public function getDiscounts($lite = false, $refresh = false)
public function getCartRules()
{
// if discounts are never used
if (!Discount::isFeatureActive())
// TODO : add cache
// If the cart has not been saved, then there can't be any cart rule applied
if (!CartRule::isFeatureActive() || !$this->id)
return array();
if (!$this->id)
return array();
if (!$refresh)
{
if (!$lite AND isset(self::$_discounts[$this->id]))
return self::$_discounts[$this->id];
if ($lite AND isset(self::$_discountsLite[$this->id]))
return self::$_discountsLite[$this->id];
}
$total_products_ti = $this->getOrderTotal(true, Cart::ONLY_PRODUCTS);
$total_products_te = $this->getOrderTotal(false, Cart::ONLY_PRODUCTS);
$shipping_ti = $this->getOrderShippingCost();
$shipping_te = $this->getOrderShippingCost(NULL, false);
$result = Db::getInstance()->executeS('
SELECT d.*, `id_cart`
FROM `'._DB_PREFIX_.'cart_discount` c
LEFT JOIN `'._DB_PREFIX_.'discount` d ON c.`id_discount` = d.`id_discount`
WHERE `id_cart` = '.(int)($this->id));
SELECT *
FROM `'._DB_PREFIX_.'cart_cart_rule` cd
LEFT JOIN `'._DB_PREFIX_.'cart_rule` cr ON cd.`id_cart_rule` = cr.`id_cart_rule`
LEFT JOIN `'._DB_PREFIX_.'cart_rule_lang` crl ON (cd.`id_cart_rule` = cr.`id_cart_rule` AND crl.id_lang = '.(int)$this->id_lang.')
WHERE `id_cart` = '.(int)$this->id);
$products = $this->getProducts();
foreach ($result AS $k => $discount)
foreach ($result as &$row)
{
$categories = Discount::getCategories((int)($discount['id_discount']));
$in_category = false;
foreach ($products AS $product)
if (Product::idIsOnCategoryId((int)($product['id_product']), $categories))
{
$in_category = true;
break;
}
if (!$in_category)
unset($result[$k]);
$cartRule = new CartRule($row['id_cart_rule'], (int)$this->id_lang);
$row['value_real'] = $cartRule->getValue(true);
$row['value_tax_exc'] = $cartRule->getValue(false);
// Retro compatibility < 1.5.0.2
$row['id_discount'] = $row['id_cart_rule'];
$row['description'] = $row['name'];
}
if ($lite)
{
self::$_discountsLite[$this->id] = $result;
return $result;
}
$total_products_wt = $this->getOrderTotal(true, Cart::ONLY_PRODUCTS);
$total_products = $this->getOrderTotal(false, Cart::ONLY_PRODUCTS);
$shipping_wt = $this->getOrderShippingCost();
$shipping = $this->getOrderShippingCost(NULL, false);
self::$_discounts[$this->id] = array();
foreach ($result as $row)
{
$discount = new Discount($row['id_discount'], (int)($this->id_lang));
$row['description'] = $discount->description ? $discount->description : $discount->name;
$row['value_real'] = $discount->getValue(sizeof($result), $total_products_wt, $shipping_wt, $this->id);
$row['value_tax_exc'] = $discount->getValue(sizeof($result), $total_products, $shipping, $this->id, false);
if ($row['value_real'] !== 0)
self::$_discounts[$this->id][] = $row;
else
$this->deleteDiscount($row['id_discount']);
}
return isset(self::$_discounts[$this->id]) ? self::$_discounts[$this->id] : NULL;
return $result;
}
// Todo: see uses and change name
public function getDiscountsCustomer($id_discount)
{
if (!Discount::isFeatureActive())
if (!CartRule::isFeatureActive())
return 0;
return Db::getInstance()->getValue('
SELECT COUNT(*)
FROM `'._DB_PREFIX_.'cart_discount`
FROM `'._DB_PREFIX_.'cart_cart_rule`
WHERE `id_discount` = '.(int)($id_discount).' AND `id_cart` = '.(int)($this->id));
}
@@ -570,14 +550,17 @@ class CartCore extends ObjectModel
}
/**
* Add a discount to the cart (NO controls except doubles)
*
* @param integer $id_discount The discount to add to the cart
* @result boolean Update result
* @deprecated 1.5.0.1
*/
public function addDiscount($id_discount)
public function addDiscount($id_discount)
{
return Db::getInstance()->AutoExecute(_DB_PREFIX_.'cart_discount', array('id_discount' => (int)($id_discount), 'id_cart' => (int)($this->id)), 'INSERT');
Tools::displayAsDeprecated();
return $this->addCartRule($id_discount);
}
public function addCartRule($id_cart_rule)
{
return Db::getInstance()->AutoExecute(_DB_PREFIX_.'cart_cart_rule', array('id_cart_rule' => (int)$id_cart_rule, 'id_cart' => (int)$this->id), 'INSERT');
}
public function containsProduct($id_product, $id_product_attribute = 0, $id_customization = false)
@@ -701,6 +684,9 @@ class CartCore extends ObjectModel
// refresh cache of self::_products
$this->_products = $this->getProducts(true);
$this->update(true);
$context = Context::getContext()->cloneContext();
$context->cart = $this;
CartRule::autoAddToCart($context);
if ($product->customizable)
return $this->_updateCustomizationQuantity((int)$quantity, (int)$id_customization, (int)$id_product, (int)$id_product_attribute, $operator);
@@ -820,19 +806,18 @@ class CartCore extends ObjectModel
return (bool)Db::getInstance()->getValue('SELECT `id_cart` FROM `'._DB_PREFIX_.'orders` WHERE `id_cart` = '.(int)$this->id);
}
/*
** Deletion
*/
/**
* Delete a discount from the cart
*
* @param integer $id_discount Discount ID
* @return boolean result
* @deprecated 1.5.0.1
*/
public function deleteDiscount($id_discount)
public function deleteDiscount($id_discount)
{
return Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'cart_discount` WHERE `id_discount` = '.(int)$id_discount.' AND `id_cart` = '.(int)$this->id.' LIMIT 1');
Tools::displayAsDeprecated();
return $this->removeCartRule($id_discount);
}
public function removeCartRule($id_cart_rule)
{
return Db::getInstance()->Execute('DELETE FROM `'._DB_PREFIX_.'cart_cart_rule` WHERE `id_cart_rule` = '.(int)$id_cart_rule.' AND `id_cart` = '.(int)$this->id.' LIMIT 1');
}
/**
@@ -982,7 +967,8 @@ class CartCore extends ObjectModel
die(Tools::displayError());
// if discounts are never used
if ($type == Cart::ONLY_DISCOUNTS && !Discount::isFeatureActive())
// Todo: remove and replace by cart rules
if ($type == Cart::ONLY_DISCOUNTS && !CartRule::isFeatureActive())
return 0;
// no shipping cost if is a cart with only virtuals products
$virtual = $this->isVirtualCart();
@@ -1025,6 +1011,7 @@ class CartCore extends ObjectModel
$order_total += $total_price;
}
$order_total_products = $order_total;
// Todo: consider optimizations
if ($type == Cart::ONLY_DISCOUNTS)
$order_total = 0;
// Wrapping Fees
@@ -1039,61 +1026,28 @@ class CartCore extends ObjectModel
}
$wrapping_fees = Tools::convertPrice(Tools::ps_round($wrapping_fees, 2), Currency::getCurrencyInstance((int)($this->id_currency)));
}
if ($type != Cart::ONLY_PRODUCTS)
$order_total_discount = 0;
if ($type != Cart::ONLY_PRODUCTS && CartRule::isFeatureActive())
{
$discounts = array();
if (Discount::isFeatureActive())
{
/* Firstly get all discounts, looking for a free shipping one (in order to substract shipping fees to the total amount) */
if ($discountIds = $this->getDiscounts(true))
{
foreach ($discountIds AS $id_discount)
{
$discount = new Discount((int)($id_discount['id_discount']));
if (Validate::isLoadedObject($discount))
{
$discounts[] = $discount;
if ($discount->id_discount_type == Discount::FREE_SHIPPING)
foreach($products AS $product)
{
$categories = Discount::getCategories($discount->id);
if (count($categories) AND Product::idIsOnCategoryId($product['id_product'], $categories))
{
if($type == Cart::ONLY_DISCOUNTS)
$order_total -= $shipping_fees;
$shipping_fees = 0;
break;
}
}
}
}
/* Secondly applying all vouchers to the correct amount */
$shrunk = false;
foreach ($discounts AS $discount)
if ($discount->id_discount_type != Discount::FREE_SHIPPING)
{
$order_total -= Tools::ps_round((float)($discount->getValue(sizeof($discounts), $order_total_products, $shipping_fees, $this->id, (int)($withTaxes))), 2);
if ($discount->id_discount_type == Discount::AMOUNT)
if (in_array($discount->behavior_not_exhausted, array(1,2)))
$shrunk = true;
}
$order_total_discount = 0;
if ($shrunk AND $order_total < (-$wrapping_fees - $order_total_products - $shipping_fees))
$order_total_discount = -$wrapping_fees - $order_total_products - $shipping_fees;
else
$order_total_discount = $order_total;
}
}
$result = $this->getCartRules();
foreach (ObjectModel::hydrateCollection('CartRule', $result, Configuration::get('PS_LANG_DEFAULT')) AS $cartRule)
$order_total_discount += Tools::ps_round($cartRule->getValue($withTaxes));
$order_total_discount = min(Tools::ps_round($order_total_discount), $wrapping_fees + $order_total_products + $shipping_fees);
$order_total -= $order_total_discount;
}
if ($type == Cart::ONLY_SHIPPING) return $shipping_fees;
if ($type == Cart::ONLY_WRAPPING) return $wrapping_fees;
if ($type == Cart::BOTH) $order_total += $shipping_fees + $wrapping_fees;
if ($order_total < 0 AND $type != Cart::ONLY_DISCOUNTS) return 0;
if ($type == Cart::ONLY_DISCOUNTS AND isset($order_total_discount))
return Tools::ps_round((float)($order_total_discount), 2);
return Tools::ps_round((float)($order_total), 2);
if ($type == Cart::ONLY_SHIPPING)
return $shipping_fees;
if ($type == Cart::ONLY_WRAPPING)
return $wrapping_fees;
if ($type == Cart::BOTH)
$order_total += $shipping_fees + $wrapping_fees;
if ($order_total < 0 AND $type != Cart::ONLY_DISCOUNTS)
return 0;
if ($type == Cart::ONLY_DISCOUNTS)
return $order_total_discount;
return Tools::ps_round((float)$order_total, 2);
}
/**
@@ -1110,33 +1064,6 @@ class CartCore extends ObjectModel
if (!$default_country)
$default_country = Context::getContext()->country;
// Checking discounts in cart
$products = $this->getProducts();
if (Discount::isFeatureActive())
$discounts = $this->getDiscounts(true);
else
$discounts = null;
if ($discounts)
foreach ($discounts AS $id_discount)
if ($id_discount['id_discount_type'] == Discount::FREE_SHIPPING)
{
if ($id_discount['minimal'] > 0)
{
$total_cart = 0;
$categories = Discount::getCategories((int)($id_discount['id_discount']));
if (sizeof($categories))
foreach($products AS $product)
if (Product::idIsOnCategoryId((int)($product['id_product']), $categories))
$total_cart += $product['total_wt'];
if ($total_cart >= $id_discount['minimal'])
return 0;
}
else
return 0;
}
// Order total in default currency without fees
$order_total = $this->getOrderTotal(true, Cart::ONLY_PRODUCTS_WITHOUT_SHIPPING);
@@ -1250,9 +1177,9 @@ class CartCore extends ObjectModel
$free_fees_price = 0;
if (isset($configuration['PS_SHIPPING_FREE_PRICE']))
$free_fees_price = Tools::convertPrice((float)($configuration['PS_SHIPPING_FREE_PRICE']), Currency::getCurrencyInstance((int)($this->id_currency)));
$orderTotalwithDiscounts = $this->getOrderTotal(true, Cart::BOTH_WITHOUT_SHIPPING);
if ($orderTotalwithDiscounts >= (float)($free_fees_price) AND (float)($free_fees_price) > 0)
return $shipping_cost;
// $orderTotalwithDiscounts = $this->getOrderTotal(true, Cart::BOTH_WITHOUT_SHIPPING);
// if ($orderTotalwithDiscounts >= (float)($free_fees_price) AND (float)($free_fees_price) > 0)
// return $shipping_cost;
if (isset($configuration['PS_SHIPPING_FREE_WEIGHT']) AND $this->getTotalWeight() >= (float)($configuration['PS_SHIPPING_FREE_WEIGHT']) AND (float)($configuration['PS_SHIPPING_FREE_WEIGHT']) > 0)
return $shipping_cost;
@@ -1290,9 +1217,10 @@ class CartCore extends ObjectModel
if (isset($configuration['PS_SHIPPING_HANDLING']) AND $carrier->shipping_handling)
$shipping_cost += (float)($configuration['PS_SHIPPING_HANDLING']);
// TODO : $products does not exists
// Additional Shipping Cost per product
foreach($products AS $product)
$shipping_cost += $product['additional_shipping_cost'] * $product['cart_quantity'];
// foreach($products AS $product)
// $shipping_cost += $product['additional_shipping_cost'] * $product['cart_quantity'];
$shipping_cost = Tools::convertPrice($shipping_cost, Currency::getCurrencyInstance((int)($this->id_currency)));
@@ -1357,90 +1285,16 @@ class CartCore extends ObjectModel
}
return self::$_totalWeight[$this->id];
}
/**
* Check discount validity
*
* @return mixed Return a string if an error occurred and false otherwise
*/
function checkDiscountValidity($discountObj, $discounts, $order_total, $products, $checkCartDiscount = false,
Customer $customer = null, Shop $shop = null)
* @deprecated 1.5.0.1
*/
public function checkDiscountValidity($discountObj, $discounts, $order_total, $products, $checkCartDiscount = false)
{
if (!$shop)
$shop = Context::getContext()->shop;
if (!$customer)
$customer = Context::getContext()->customer;
if (!$order_total)
return Tools::displayError('Cannot add voucher if order is free.');
if (!$discountObj->active)
return Tools::displayError('This voucher has already been used or is disabled.');
if (!$discountObj->quantity)
return Tools::displayError('This voucher has expired (usage limit attained).');
if ($discountObj->id_discount_type == Discount::AMOUNT AND $this->id_currency != $discountObj->id_currency)
return Tools::displayError('This voucher can only be used in the following currency:').'
'.Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('SELECT `name` FROM `'._DB_PREFIX_.'currency` WHERE id_currency = '.(int)$discountObj->id_currency);
if ($checkCartDiscount
AND (
$this->getDiscountsCustomer($discountObj->id) >= $discountObj->quantity_per_user
OR (Order::getDiscountsCustomer($customer->id, $discountObj->id) + $this->getDiscountsCustomer($discountObj->id) >= $discountObj->quantity_per_user) >= $discountObj->quantity_per_user
)
)
return Tools::displayError('You cannot use this voucher anymore (usage limit attained).');
if (strtotime($discountObj->date_from) > time())
return Tools::displayError('This voucher is not yet valid');
if (strtotime($discountObj->date_to) < time())
return Tools::displayError('This voucher has expired.');
if (!$discountObj->isAssociatedToShop((int)$shop->id))
return Tools::displayError('This voucher is not available with this shop.');
if (sizeof($discounts) >= 1 AND $checkCartDiscount)
{
if (!$discountObj->cumulable)
return Tools::displayError('This voucher is not valid with other current discounts.');
foreach ($discounts as $discount)
if (!$discount['cumulable'])
return Tools::displayError('Voucher is not valid with other discounts.');
foreach($discounts as $discount)
if($discount['id_discount'] == $discountObj->id)
return Tools::displayError('This voucher is already in your cart');
}
$groups = Customer::getGroupsStatic($this->id_customer);
if (($discountObj->id_customer OR $discountObj->id_group) AND ((($this->id_customer != $discountObj->id_customer) OR ($this->id_customer == 0)) AND !in_array($discountObj->id_group, $groups)))
{
if (!$customer->isLogged())
return Tools::displayError('You cannot use this voucher.').' - '.Tools::displayError('Please log in.');
return Tools::displayError('You cannot use this voucher.');
}
$onlyProductWithDiscount = true;
if (!$discountObj->cumulable_reduction)
{
foreach ($products as $product)
if (!$product['reduction_applies'] AND !$product['on_sale'])
$onlyProductWithDiscount = false;
}
if (!$discountObj->cumulable_reduction AND $onlyProductWithDiscount)
return Tools::displayError('This voucher is not valid for marked or reduced products.');
$total_cart = 0;
$categories = Discount::getCategories($discountObj->id);
$returnErrorNoProductCategory = true;
foreach($products AS $product)
{
if(count($categories))
if (Product::idIsOnCategoryId($product['id_product'], $categories))
{
if ((!$discountObj->cumulable_reduction AND !$product['reduction_applies'] AND !$product['on_sale']) OR $discountObj->cumulable_reduction)
$total_cart += $discountObj->include_tax ? $product['total_wt'] : $product['total'];
$returnErrorNoProductCategory = false;
}
}
if ($returnErrorNoProductCategory)
return Tools::displayError('This discount does not apply to that product category.');
if ($total_cart < $discountObj->minimal)
return Tools::displayError('The order total is not high enough or this voucher cannot be used with those products.');
return false;
Tools::displayAsDeprecated();
$context = Context::getContext()->cloneContext();
$context->cart = $this;
return $discountObj->checkValidity($context);
}
/**
@@ -1468,7 +1322,7 @@ class CartCore extends ObjectModel
$total_free_ship = 0;
if ($free_ship = Tools::convertPrice((float)(Configuration::get('PS_SHIPPING_FREE_PRICE')), new Currency((int)($this->id_currency))))
{
$discounts = $this->getDiscounts();
$discounts = $this->getCartRules();
$total_free_ship = $free_ship - ($this->getOrderTotal(true, Cart::ONLY_PRODUCTS) + $this->getOrderTotal(true, Cart::ONLY_DISCOUNTS));
foreach ($discounts as $discount)
if ($discount['id_discount_type'] == Discount::FREE_SHIPPING)
@@ -1485,7 +1339,7 @@ class CartCore extends ObjectModel
'formattedAddresses' => $formattedAddresses,
'carrier' => new Carrier($this->id_carrier, $id_lang),
'products' => $this->getProducts(false),
'discounts' => $this->getDiscounts(false, true),
'discounts' => $this->getCartRules(),
'is_virtual_cart' => (int)$this->isVirtualCart(),
'total_discounts' => $this->getOrderTotal(true, Cart::ONLY_DISCOUNTS),
'total_discounts_tax_exc' => $this->getOrderTotal(false, Cart::ONLY_DISCOUNTS),
+624
View File
@@ -0,0 +1,624 @@
<?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: 7040 $
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
class CartRuleCore extends ObjectModel
{
public $id;
public $name;
public $id_customer;
public $date_from;
public $date_to;
public $description;
public $quantity = 1;
public $quantity_per_user = 1;
public $priority = 1;
public $code;
public $minimum_amount;
public $minimum_amount_tax;
public $minimum_amount_currency;
public $minimum_amount_shipping;
public $country_restriction;
public $carrier_restriction;
public $group_restriction;
public $cart_rule_restriction;
public $product_restriction;
public $free_shipping;
public $reduction_percent;
public $reduction_amount;
public $reduction_tax;
public $reduction_currency;
public $reduction_product;
public $gift_product;
public $active = 1;
public $date_add;
public $date_upd;
protected $table = 'cart_rule';
protected $identifier = 'id_cart_rule';
protected $fieldsRequired = array('date_from', 'date_to');
protected $fieldsSize = array('code' => 254, 'description' => 65534);
protected $fieldsValidate = array(
'id_customer' => 'isUnsignedId',
'date_from' => 'isDate',
'date_to' => 'isDate',
'description' => 'isCleanHtml',
'quantity' => 'isUnsignedInt',
'quantity_per_user' => 'isUnsignedInt',
'priority' => 'isUnsignedInt',
'code' => 'isCleanHtml',
'minimum_amount' => 'isFloat',
'minimum_amount_tax' => 'isBool',
'minimum_amount_currency' => 'isInt',
'minimum_amount_shipping' => 'isBool',
'country_restriction' => 'isBool',
'carrier_restriction' => 'isBool',
'group_restriction' => 'isBool',
'cart_rule_restriction' => 'isBool',
'product_restriction' => 'isBool',
'free_shipping' => 'isBool',
'reduction_percent' => 'isFloat',
'reduction_amount' => 'isFloat',
'reduction_tax' => 'isBool',
'reduction_currency' => 'isUnsignedId',
'reduction_product' => 'isInt',
'gift_product' => 'isUnsignedId',
'active' => 'isBool',
'date_add' => 'isDate',
'date_upd' => 'isDate'
);
protected $fieldsRequiredLang = array('name');
protected $fieldsSizeLang = array('name' => 254);
protected $fieldsValidateLang = array('name' => 'isCleanHtml');
public function getFields()
{
$this->validateFields();
$fields['id_customer'] = (int)$this->id_customer;
$fields['priority'] = (int)$this->priority;
$fields['code'] = pSQL($this->code);
$fields['quantity'] = (int)$this->quantity;
$fields['quantity_per_user'] = (int)$this->quantity_per_user;
$fields['date_from'] = pSQL($this->date_from);
$fields['date_to'] = pSQL($this->date_to);
$fields['description'] = pSQL($this->description);
$fields['minimum_amount'] = (float)$this->minimum_amount;
$fields['minimum_amount_tax'] = (int)$this->minimum_amount_tax;
$fields['minimum_amount_currency'] = (int)$this->minimum_amount_currency;
$fields['minimum_amount_shipping'] = (int)$this->minimum_amount_shipping;
$fields['country_restriction'] = (int)$this->country_restriction;
$fields['carrier_restriction'] = (int)$this->carrier_restriction;
$fields['group_restriction'] = (int)$this->group_restriction;
$fields['cart_rule_restriction'] = (int)$this->cart_rule_restriction;
$fields['product_restriction'] = (int)$this->product_restriction;
$fields['free_shipping'] = (int)$this->free_shipping;
$fields['reduction_percent'] = (float)$this->reduction_percent;
$fields['reduction_amount'] = (float)$this->reduction_amount;
$fields['reduction_tax'] = (int)$this->reduction_tax;
$fields['reduction_currency'] = (int)$this->reduction_currency;
$fields['reduction_product'] = (int)$this->reduction_product;
$fields['gift_product'] = (int)$this->gift_product;
$fields['active'] = (int)$this->active;
$fields['date_add'] = pSQL($this->date_add);
$fields['date_upd'] = pSQL($this->date_upd);
return $fields;
}
public function getTranslationsFieldsChild()
{
if (!$this->validateFieldsLang())
return false;
return $this->getTranslationsFields(array('name'));
}
public function add($autodate = true, $nullValues = false)
{
if (!parent::add($autodate, $nullValues))
return false;
Configuration::updateGlobalValue('PS_CART_RULE_FEATURE_ACTIVE', '1');
return true;
}
public function delete()
{
if (!parent::delete())
return false;
Configuration::updateGlobalValue('PS_CART_RULE_FEATURE_ACTIVE', CartRule::isCurrentlyUsed($this->table, true));
Db::getInstance()->Execute('DELETE FROM `'._DB_PREFIX_.'cart_cart_rule` WHERE `id_cart_rule` = '.(int)$this->id);
Db::getInstance()->Execute('DELETE FROM `'._DB_PREFIX_.'cart_rule_carrier` WHERE `id_cart_rule` = '.(int)$this->id);
Db::getInstance()->Execute('DELETE FROM `'._DB_PREFIX_.'cart_rule_group` WHERE `id_cart_rule` = '.(int)$this->id);
Db::getInstance()->Execute('DELETE FROM `'._DB_PREFIX_.'cart_rule_country` WHERE `id_cart_rule` = '.(int)$this->id);
Db::getInstance()->Execute('DELETE FROM `'._DB_PREFIX_.'cart_rule_cart_rule` WHERE `id_cart_rule_1` = '.(int)$this->id.' OR `id_cart_rule_2` = '.(int)$this->id);
Db::getInstance()->Execute('DELETE FROM `'._DB_PREFIX_.'cart_rule_product_rule` WHERE `id_cart_rule` = '.(int)$this->id);
Db::getInstance()->Execute('DELETE FROM `'._DB_PREFIX_.'cart_rule_product_rule_value` WHERE `id_product_rule` NOT IN (SELECT `id_product_rule` FROM `'._DB_PREFIX_.'cart_rule_product_rule`)');
}
public static function getIdByCode($code)
{
if (!Validate::isDiscountName($code))
return false;
return Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('SELECT `id_cart_rule` FROM `'._DB_PREFIX_.'cart_rule` WHERE `code` = \''.pSQL($code).'\'');
}
public function getProductRules()
{
if (!Validate::isLoadedObject($this) OR $this->product_restriction == 0)
return array();
$productRules = array();
$result = Db::getInstance()->ExecuteS('
SELECT *
FROM '._DB_PREFIX_.'cart_rule_product_rule pr
LEFT JOIN '._DB_PREFIX_.'cart_rule_product_rule_value prv ON pr.id_product_rule = prv.id_product_rule
WHERE pr.id_cart_rule = '.(int)$this->id, false);
while ($row = Db::getInstance()->nextRow($result))
{
if (!isset($productRules[$row['id_product_rule']]))
$productRules[$row['id_product_rule']] = array('quantity' => $row['quantity'], 'type' => $row['type'], 'values' => array());
$productRules[$row['id_product_rule']]['values'][] = $row['id_item'];
}
return $productRules;
}
// Todo : Add shop management
public function checkValidity(Context $context, $alreadyInCart = false)
{
if (!CartRule::isFeatureActive())
return false;
if (!$this->active)
return Tools::displayError('This voucher is disabled');
if (!$this->quantity)
return Tools::displayError('This voucher has already been used ');
if (strtotime($this->date_from) > time())
return Tools::displayError('This voucher is not valid yet');
if (strtotime($this->date_to) < time())
return Tools::displayError('This voucher has expired');
if ($context->cart->id_customer)
{
$quantityUsed = Db::getInstance()->getValue('
SELECT count(*)
FROM '._DB_PREFIX_.'orders o
LEFT JOIN '._DB_PREFIX_.'order_discount od ON o.id_order = od.id_order
WHERE o.id_customer = '.$context->cart->id_customer.'
AND od.id_cart_rule = '.(int)$this->id.'
AND '.(int)Configuration::get('PS_OS_ERROR').' != (
SELECT oh.id_order_state
FROM '._DB_PREFIX_.'order_history oh
WHERE oh.id_order = o.id_order
ORDER BY oh.date_add DESC
LIMIT 1
)');
if ($quantityUsed + 1 > $this->quantity_per_user)
return Tools::displayError('You cannot use this voucher anymore (usage limit reached)');
}
$otherCartRules = $context->cart->getCartRules();
if (count($otherCartRules))
foreach ($otherCartRules as $otherCartRule)
{
if ($otherCartRule['id_cart_rule'] == $this->id && !$alreadyInCart)
return Tools::displayError('This voucher is already in your cart');
if ($this->carrier_restriction AND $otherCartRule['cart_rule_restriction'])
{
$combinable = Db::getInstance()->getValue('
SELECT id_cart_rule_1
FROM '._DB_PREFIX_.'cart_rule_combination
WHERE (id_cart_rule_1 = '.(int)$this->id.' AND id_cart_rule_2 = '.(int)$otherCartRule['id_cart_rule'].')
OR (id_cart_rule_2 = '.(int)$this->id.' AND id_cart_rule_1 = '.(int)$otherCartRule['id_cart_rule'].')');
if (!$combinable)
{
$cartRule = new CartRule($otherCartRule['cart_rule_restriction'], $context->cart->id_lang);
return Tools::displayError('This voucher is not combinable with an other voucher already in your cart:').' '.$this->name;
}
}
}
// Get an intersection of the customer groups and the cart rule groups (if the customer is not logged in, the default group is 1)
if ($this->group_restriction)
{
$id_cart_rule = (int)Db::getInstance()->getValue('
SELECT crg.id_cart_rule
FROM '._DB_PREFIX_.'cart_rule_group crg
WHERE crg.id_cart_rule = '.(int)$this->id.'
AND crg.id_group '.($context->cart->id_customer ? 'IN (SELECT cg.id_group FROM '._DB_PREFIX_.'customer_group cg WHERE cg.id_customer = '.(int)$context->cart->id_customer.')' : '= 1'));
if (!$id_cart_rule)
return Tools::displayError('You cannot use this voucher');
}
// Check if the customer delivery address is usable with the cart rule
if ($this->country_restriction AND $context->cart->id_address_delivery)
{
$id_cart_rule = (int)Db::getInstance()->getValue('
SELECT crc.id_cart_rule
FROM '._DB_PREFIX_.'cart_rule_country crc
WHERE crc.id_cart_rule = '.(int)$this->id.'
AND crc.id_country = (SELECT a.id_country FROM '._DB_PREFIX_.'address a WHERE a.id_address = '.(int)$context->cart->id_address_delivery.' LIMIT 1)');
if (!$id_cart_rule)
return Tools::displayError('You cannot use this voucher in your country of delivery');
}
// Check if the carrier chosen by the customer is usable with the cart rule
if ($this->carrier_restriction AND $context->cart->id_carrier)
{
$id_cart_rule = (int)Db::getInstance()->getValue('
SELECT crc.id_cart_rule
FROM '._DB_PREFIX_.'cart_rule_carrier crc
WHERE crc.id_cart_rule = '.(int)$this->id.'
AND crc.id_carrier = '.(int)$context->cart->id_carrier);
if (!$id_cart_rule)
return Tools::displayError('You cannot use this voucher with this carrier');
}
// Check if the products chosen by the customer are usable with the cart rule
if ($this->product_restriction)
{
$productRules = $this->getProductRules();
foreach ($productRules as $productRule)
{
switch ($productRule['type'])
{
case 'attributes':
$cartAttributes = Db::getInstance()->ExecuteS('
SELECT cp.quantity, pac.`id_attribute`
FROM `'._DB_PREFIX_.'cart_product` cp
LEFT JOIN `'._DB_PREFIX_.'product_attribute_combination` pac ON cp.id_product_attribute = pac.id_product_attribute
WHERE cp.`id_cart` = '.(int)$context->cart->id.'
AND cp.id_product_attribute > 0');
$matchingProducts = 0;
foreach ($cartAttributes as $cartAttribute)
if (in_array($cartAttribute['id_attribute'], $productRule['values']))
$matchingProducts += $cartAttribute['quantity'];
if ($matchingProducts < $productRule['quantity'])
return Tools::displayError('You cannot use this voucher with these products');
break;
case 'products':
$cartProducts = Db::getInstance()->ExecuteS('
SELECT cp.quantity, cp.`id_product`
FROM `'._DB_PREFIX_.'cart_product` cp
WHERE cp.`id_cart` = '.(int)$context->cart->id);
$matchingProducts = 0;
foreach ($cartProducts as $cartProduct)
if (in_array($cartProduct['id_product'], $productRule['values']))
$matchingProducts += $cartProduct['quantity'];
if ($matchingProducts < $productRule['quantity'])
return Tools::displayError('You cannot use this voucher with these products');
break;
case 'categories':
$cartCategories = Db::getInstance()->ExecuteS('
SELECT cp.quantity, catp.`id_category`
FROM `'._DB_PREFIX_.'cart_product` cp
LEFT JOIN `'._DB_PREFIX_.'category_product` catp ON cp.id_product = catp.id_product
WHERE cp.`id_cart` = '.(int)$context->cart->id);
$matchingProducts = 0;
foreach ($cartCategories as $cartCategory)
if (in_array($cartCategory['id_category'], $productRule['values']))
$matchingProducts += $cartCategory['quantity'];
if ($matchingProducts < $productRule['quantity'])
return Tools::displayError('You cannot use this voucher with these products');
break;
}
}
}
// Check if the cart rule is only usable by a specific customer, and if the current customer is the right one
if ($this->id_customer && $context->cart->id_customer != $this->id_customer)
{
if (!Context::getContext()->customer->isLogged())
return Tools::displayError('You cannot use this voucher').' - '.Tools::displayError('Please log in');
return Tools::displayError('You cannot use this voucher');
}
if ($this->minimum_amount)
{
$minimum_amount = $this->minimum_amount;
if ($this->minimum_amount_currency != Configuration::get('PS_CURRENCY_DEFAULT'))
{
$minimumAmountCurrency = new Currency($this->minimum_amount);
$minimum_amount = $this->minimum_amount / $minimumAmountCurrency->convertion_rate;
}
$cartTotal = $context->cart->getOrderTotal($this->minimum_amount_tax, Cart::ONLY_PRODUCTS);
if ($this->minimum_amount_shipping)
$cartTotal += $context->cart->getOrderTotal($this->minimum_amount_tax, Cart::ONLY_SHIPPING);
if ($cartTotal < $minimum_amount)
return Tools::displayError('You do not reach the minimum amount required to use this voucher');
}
}
// The reduction value is POSITIVE
public function getValue($useTax, Context $context = NULL)
{
if (!CartRule::isFeatureActive())
return 0;
if (!$context)
$context = Context::getContext();
$reductionValue = 0;
// Free shipping on selected carriers
if ($this->free_shipping)
{
if (!$this->carrier_restriction)
$reductionValue += $context->cart->getOrderShippingCost($context->cart->id_carrier, $useTax = true, $context->country);
elseif ($context->cart->id_carrier)
{
$id_cart_rule = (int)Db::getInstance()->getValue('
SELECT crc.id_cart_rule
FROM '._DB_PREFIX_.'cart_rule_carrier crc
WHERE crc.id_cart_rule = '.(int)$this->id.'
AND crc.id_carrier = '.(int)$context->cart->id_carrier);
if ($id_cart_rule)
$reductionValue += $context->cart->getOrderShippingCost($context->cart->id_carrier, $useTax, $context->country);
}
}
// Discount (%) on the whole order
if ($this->reduction_percent AND $this->reduction_product == 0)
{
$reductionValue += $context->cart->getOrderTotal($useTax, Cart::ONLY_PRODUCTS) * $this->reduction_percent / 100;
}
// Discount (%) on a specific product
if ($this->reduction_percent AND $this->reduction_product > 0)
{
foreach ($context->cart->getProducts() as $product)
if ($product['id_product'] == $this->reduction_product)
$reductionValue += ($useTax ? $product['total_wt'] : $product['total']) * $this->reduction_percent / 100;
}
// Discount (%) on the cheapest product
if ($this->reduction_percent AND $this->reduction_product == -1)
{
$minPrice = false;
foreach ($context->cart->getProducts() as $product)
{
$price = ($useTax ? $product['price_wt'] : $product['price']);
if ($price > 0 && ($minPrice === false || $minPrice > $price))
$minPrice = $price;
$reductionValue += $minPrice * $this->reduction_percent / 100;
}
}
// Discount (¤)
if ($this->reduction_amount)
{
$reduction_amount = $this->reduction_amount;
// If we need to convert the voucher value to the cart currency
if ($this->reduction_currency != $context->currency->id)
{
$voucherCurrency = new Currency($this->reduction_currency);
// First we convert the voucher value to the default currency
$reduction_amount /= $voucherCurrency->conversion_rate;
// Then we convert the voucher value in the default currency into the cart currency
$reduction_amount *= $context->currency->conversion_rate;
$reduction_amount = Tools::ps_round($reduction_amount);
}
// If it has the same tax application that you need, then it's the right value, whatever the product!
if ($this->reduction_tax == $useTax)
$reductionValue += $reduction_amount;
else
{
if ($this->reduction_product > 0)
{
// Todo: optimize with an array_search (and do the same in the other foreach of this function)
foreach ($context->cart->getProducts() as $product)
if ($product['id_product'] == $this->reduction_product)
{
$product_price_ti = $product['price_wt'];
$product_price_te = $product['price'];
$product_vat_amount = $product_price_ti - $product_price_te;
$product_vat_rate = $product_vat_amount / $product_price_te;
if ($this->reduction_tax && !$useTax)
$reductionValue += $reduction_amount / (1 + $product_vat_rate);
elseif (!$this->reduction_tax && $useTax)
$reductionValue += $reduction_amount * (1 + $product_vat_rate);
}
}
// Discount (¤) on the whole order
elseif ($this->reduction_product == 0)
{
$cart_amount_ti = $context->cart->getOrderTotal(true, Cart::ONLY_PRODUCTS);
$cart_amount_te = $context->cart->getOrderTotal(false, Cart::ONLY_PRODUCTS);
$cart_vat_amount = $cart_amount_ti - $cart_amount_te;
$cart_average_vat_rate = $cart_vat_amount / $cart_amount_te;
if ($this->reduction_tax && !$useTax)
$reductionValue += $reduction_amount / (1 + $cart_average_vat_rate);
elseif (!$this->reduction_tax && $useTax)
$reductionValue += $reduction_amount * (1 + $cart_average_vat_rate);
}
// Todo: discount on the cheapest (but this is not meaningful)
}
}
// Free gift
if ($this->gift_product)
{
foreach ($context->cart->getProducts() as $product)
if ($product['id_product'] == $this->gift_product)
$reductionValue += ($useTax ? $product['price_wt'] : $product['price']);
}
return $reductionValue;
}
protected function getCartRuleCombinations()
{
$array = array();
$array['selected'] = Db::getInstance()->ExecuteS('
SELECT cr.*, crl.*, 1 as selected
FROM '._DB_PREFIX_.'cart_rule cr
LEFT JOIN '._DB_PREFIX_.'cart_rule_lang crl ON (cr.id_cart_rule = crl.id_cart_rule AND crl.id_lang = '.(int)Context::getContext()->language->id.')
WHERE cr.id_cart_rule != '.(int)$this->id.'
AND (
cr.cart_rule_restriction = 0
OR cr.id_cart_rule IN (
SELECT IF(id_cart_rule_1 = '.(int)$this->id.', id_cart_rule_2, id_cart_rule_1)
FROM '._DB_PREFIX_.'cart_rule_combination
WHERE '.(int)$this->id.' = id_cart_rule_1
OR '.(int)$this->id.' = id_cart_rule_2
)
)');
$array['unselected'] = Db::getInstance()->ExecuteS('
SELECT cr.*, crl.*, 1 as selected
FROM '._DB_PREFIX_.'cart_rule cr
LEFT JOIN '._DB_PREFIX_.'cart_rule_lang crl ON (cr.id_cart_rule = crl.id_cart_rule AND crl.id_lang = '.(int)Context::getContext()->language->id.')
WHERE cr.cart_rule_restriction = 1
AND cr.id_cart_rule != '.(int)$this->id.'
AND cr.id_cart_rule NOT IN (
SELECT IF(id_cart_rule_1 = '.(int)$this->id.', id_cart_rule_2, id_cart_rule_1)
FROM '._DB_PREFIX_.'cart_rule_combination
WHERE '.(int)$this->id.' = id_cart_rule_1
OR '.(int)$this->id.' = id_cart_rule_2
)');
return $array;
}
public function getAssociatedRestrictions($type, $active = 1)
{
$array = array('selected' => array(), 'unselected' => array());
if (!in_array($type, array('country', 'carrier', 'group', 'cart_rule')))
return false;
if (!Validate::isLoadedObject($this) OR $this->{$type.'_restriction'} == 0)
{
$array['selected'] = Db::getInstance()->ExecuteS('
SELECT t.*, tl.*, 1 as selected
FROM '._DB_PREFIX_.''.$type.' t
LEFT JOIN '._DB_PREFIX_.''.$type.'_lang tl ON t.id_'.$type.' = tl.id_'.$type.' AND tl.id_lang = '.(int)Context::getContext()->language->id.'
WHERE 1
'.($active ? 'AND t.active = 1' : '').'
'.($type == 'cart_rule' ? 'AND t.id_cart_rule != '.(int)$this->id : '').'
ORDER BY name ASC');
}
else
{
if ($type == 'cart_rule')
$array = $this->getCartRuleCombinations();
else
{
$result = Db::getInstance()->ExecuteS('
SELECT t.*, tl.*, IF(crt.id_'.$type.' IS NULL, 0, 1) as selected
FROM '._DB_PREFIX_.''.$type.' t
LEFT JOIN '._DB_PREFIX_.''.$type.'_lang tl ON t.id_'.$type.' = tl.id_'.$type.' AND tl.id_lang = '.(int)Context::getContext()->language->id.'
LEFT JOIN (SELECT id_'.$type.' FROM '._DB_PREFIX_.'cart_rule_'.$type.' WHERE id_cart_rule = '.(int)$this->id.') crt ON t.id_'.$type.' = crt.id_'.$type.'
'.($active ? 'WHERE t.active = 1' : '').'
ORDER BY name ASC',
false);
while ($row = Db::getInstance()->nextRow())
$array[($row['selected'] || $this->{$type.'_restriction'} == 0) ? 'selected' : 'unselected'][] = $row;
}
}
return $array;
}
public static function autoRemoveFromCart($context = NULL)
{
if (!CartRule::isFeatureActive())
return;
$errors = array();
if (!$context)
$context = Context::getContext();
$result = $context->cart->getCartRules();
$cartRules = ObjectModel::hydrateCollection('CartRule', $result);
foreach ($cartRules as $cartRule)
{
if ($error = $cartRule->checkValidity($context, true))
{
$context->cart->removeCartRule($cartRule->id);
$context->cart->update();
$errors[] = $error;
}
}
return $errors;
}
public static function autoAddToCart($context = NULL)
{
if ($context === NULL)
$context = Context::getContext();
if (!CartRule::isFeatureActive() || !Validate::isLoadedObject($context->cart))
return;
$result = Db::getInstance()->ExecuteS('
SELECT cr.*
FROM '._DB_PREFIX_.'cart_rule cr
LEFT JOIN '._DB_PREFIX_.'cart_rule_carrier crca ON cr.id_cart_rule = crca.id_cart_rule
LEFT JOIN '._DB_PREFIX_.'cart_rule_country crco ON cr.id_cart_rule = crco.id_cart_rule
WHERE cr.active = 1
AND cr.code = ""
AND cr.quantity > 0
AND cr.date_from < "'.date('Y-m-d H:i:s').'"
AND cr.date_to > "'.date('Y-m-d H:i:s').'"
AND cr.id_cart_rule NOT IN (SELECT id_cart_rule FROM '._DB_PREFIX_.'cart_cart_rule WHERE id_cart = '.(int)$context->cart->id.')
AND (
cr.id_customer = 0
'.($context->customer->id ? 'OR cr.id_customer = '.(int)$context->cart->id_customer : '').'
)
AND (
cr.carrier_restriction = 0
'.($context->cart->id_carrier ? 'OR crca.id_carrier = '.(int)$context->cart->id_carrier : '').'
)
AND (
cr.group_restriction = 0
'.($context->customer->id ? 'OR 0 < (
SELECT cg.id_group
FROM '._DB_PREFIX_.'customer_group cg
LEFT JOIN '._DB_PREFIX_.'cart_rule_group crg ON cg.id_group = crg.id_group
WHERE cr.id_cart_rule = crg.id_cart_rule
AND cg.id_customer = '.(int)$context->customer->id.'
)' : '').'
)
AND (
cr.reduction_product = 0
OR cr.reduction_product IN (
SELECT id_product
FROM '._DB_PREFIX_.'cart_product
WHERE id_cart = '.(int)$context->cart->id.'
)
)
ORDER BY priority');
$cartRules = ObjectModel::hydrateCollection('CartRule', $result);
// Todo: consider optimization (we can avoid many queries in checkValidity)
foreach ($cartRules as $cartRule)
if (!$cartRule->checkValidity($context))
$context->cart->addCartRule($cartRule->id);
}
public static function isFeatureActive()
{
return (bool)Configuration::get('PS_CART_RULE_FEATURE_ACTIVE');
}
}
+7
View File
@@ -122,6 +122,13 @@ class CountryCore extends ObjectModel
$this->validateFieldsLang();
return $this->getTranslationsFields(array('name'));
}
public function delete()
{
if (!parent::delete())
return false;
return Db::getInstance()->Execute('DELETE FROM '._DB_PREFIX_.'cart_rule_country WHERE id_country = '.(int)$this->id);
}
/**
* Return available countries
+10 -9
View File
@@ -25,7 +25,7 @@
* International Registered Trademark & Property of PrestaShop SA
*/
class DiscountCore extends ObjectModel
class DiscountCore extends CartRule
{
public $id;
@@ -310,14 +310,14 @@ class DiscountCore extends ObjectModel
}
/**
* Return discount value
*
* @param integer $nb_discounts Number of discount currently in cart
* @param boolean $order_total_products Total cart products amount
* @return mixed Return a float value or '!' if reduction is 'Shipping free'
* @deprecated 1.5.0.1
*/
public function getValue($nb_discounts = 0, $order_total_products = 0, $shipping_fees = 0, $idCart = false, $useTax = true, Currency $currency = null, Shop $shop = null)
public function getValue($nb_discounts = 0, $order_total_products = 0, $shipping_fees = 0, $id_cart = false, $useTax = true, Currency $currency = null, Shop $shop = null)
{
Tools::displayAsDeprecated();
$context = Context::getContext();
$context->cart = new Cart($id_cart);
return parent::getValue($useTax, $context);
if (!self::isFeatureActive())
return 0;
@@ -509,7 +509,7 @@ class DiscountCore extends ObjectModel
*/
public static function getVouchersToCartDisplay($id_lang, $id_customer = 0)
{
if (!self::isFeatureActive())
if (!CartRule::isFeatureActive())
return array();
$sql = '
@@ -584,6 +584,7 @@ class DiscountCore extends ObjectModel
*/
public static function isFeatureActive()
{
return Configuration::get('PS_DISCOUNT_FEATURE_ACTIVE');
Tools::displayAsDeprecated();
return CartRule::isFeatureActive();
}
}
+4 -1
View File
@@ -134,6 +134,10 @@ class FrontControllerCore extends Controller
if (isset($_GET['logout']) OR ($this->context->customer->logged AND Customer::isBanned($this->context->customer->id)))
{
$this->context->customer->logout();
// Login information have changed, so we check if the cart rules still apply
CartRule::autoRemoveFromCart();
Tools::redirect(isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : NULL);
}
elseif (isset($_GET['mylogout']))
@@ -285,7 +289,6 @@ class FrontControllerCore extends Controller
'customerName' => ($this->context->customer->logged ? $this->context->cookie->customer_firstname.' '.$this->context->cookie->customer_lastname : false)
));
// TODO for better performances (cache usage), remove these assign and use a smarty function to get the right media server in relation to the full ressource name
$assignArray = array(
'img_ps_dir' => _PS_IMG_,
'img_cat_dir' => _THEME_CAT_DIR_,
+1
View File
@@ -166,6 +166,7 @@ class GroupCore extends ObjectModel
return false;
if (parent::delete())
{
Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'cart_rule_group` WHERE `id_group` = '.(int)$this->id);
Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'customer_group` WHERE `id_group` = '.(int)$this->id);
Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'category_group` WHERE `id_group` = '.(int)$this->id);
Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'group_reduction` WHERE `id_group` = '.(int)$this->id);
+7 -1
View File
@@ -897,7 +897,13 @@ class OrderCore extends ObjectModel
*/
public function addDiscount($id_discount, $name, $value)
{
return Db::getInstance()->AutoExecute(_DB_PREFIX_.'order_discount', array('id_order' => (int)($this->id), 'id_discount' => (int)($id_discount), 'name' => pSQL($name), 'value' => (float)($value)), 'INSERT');
Tools::displayAsDeprecated();
return Order::addCartRule($id_discount, $name, $value);
}
public function addCartRule($id_cart_rule, $name, $value)
{
return Db::getInstance()->AutoExecute(_DB_PREFIX_.'order_cart_rule', array('id_order' => (int)$this->id, 'id_cart_rule' => (int)$id_cart_rule, 'name' => pSQL($name), 'value' => (float)$value), 'INSERT');
}
public function getNumberOfDays()
+71
View File
@@ -0,0 +1,71 @@
<?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: 6844 $
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
class OrderDiscountCore extends ObjectModel
{
/** @var integer */
public $id_order_cart_rule;
/** @var integer */
public $id_order;
/** @var integer */
public $id_cart_rule;
/** @var string */
public $name;
/** @var integer */
public $value;
protected $tables = array ('order_cart_rule');
protected $fieldsRequired = array ('id_order', 'name', 'value');
protected $fieldsValidate = array ('id_order' => 'isUnsignedId', 'name' => 'isGenericName', 'value' => 'isInt');
/* MySQL does not allow 'order detail' for a table name */
protected $table = 'order_cart_rule';
protected $identifier = 'id_order_cart_rule';
protected $webserviceParameters = array(
'fields' => array(
'id_order' => array('xlink_resource' => 'orders'),
),
);
public function getFields()
{
$this->validateFields();
$fields['id_order'] = (int)($this->id_order);
$fields['name'] = pSQL($this->name);
$fields['value'] = (int)($this->value);
return $fields;
}
}
+17 -41
View File
@@ -25,47 +25,23 @@
* International Registered Trademark & Property of PrestaShop SA
*/
class OrderDiscountCore extends ObjectModel
class OrderDiscountCore extends OrderCartRule
{
/** @var integer */
public $id_order_discount;
/** @var integer */
public $id_order;
/** @var integer */
public $id_discount;
/** @var string */
public $name;
/** @var integer */
public $value;
protected $tables = array ('order_discount');
protected $fieldsRequired = array ('id_order', 'name', 'value');
protected $fieldsValidate = array ('id_order' => 'isUnsignedId', 'name' => 'isGenericName', 'value' => 'isInt');
/* MySQL does not allow 'order detail' for a table name */
protected $table = 'order_discount';
protected $identifier = 'id_order_discount';
protected $webserviceParameters = array(
'fields' => array(
'id_order' => array('xlink_resource' => 'orders'),
),
);
public function getFields()
public function __get($key)
{
$this->validateFields();
$fields['id_order'] = (int)($this->id_order);
$fields['name'] = pSQL($this->name);
$fields['value'] = (int)($this->value);
return $fields;
}
if ($key == 'id_order_discount')
return $this->id_order_cart_rule;
if ($key == 'id_discount')
return $this->id_cart_rule;
return $this->{$key};
}
public function __set($key, $value)
{
if ($key == 'id_order_discount')
$this->id_order_cart_rule = $value;
if ($key == 'id_discount')
$this->id_cart_rule = $value;
$this->{$key} = $value;
}
}
+1 -1
View File
@@ -89,7 +89,7 @@ class OrderHistoryCore extends ObjectModel
if ($newOS->logable AND (!$oldOrderStatus OR !$oldOrderStatus->logable))
ProductSale::addProductSale($product['id_product'], $product['cart_quantity']);
/* If becoming unlogable => removing sale */
else if (!$newOS->logable AND ($oldOrderStatus AND $oldOrderStatus->logable))
elseif (!$newOS->logable AND ($oldOrderStatus AND $oldOrderStatus->logable))
ProductSale::removeProductSale($product['id_product'], $product['cart_quantity']);
if (!Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') && !$isValidated AND $newOS->logable AND isset($oldOrderStatus) AND $oldOrderStatus AND $oldOrderStatus->id == Configuration::get('PS_OS_ERROR'))
+33 -44
View File
@@ -245,53 +245,42 @@ abstract class PaymentModuleCore extends Module
</tr>';
} // end foreach ($products)
// Insert discounts from cart into order_discount table
$discounts = $cart->getDiscounts();
$discountsList = '';
$total_discount_value = 0;
$shrunk = false;
foreach ($discounts AS $discount)
$cartRulesList = '';
$result = $cart->getCartRules();
$cartRules = ObjectModel::hydrateCollection('CartRule', $result, (int)$order->id_lang);
foreach ($cartRules AS $cartRule)
{
$objDiscount = new Discount((int)$discount['id_discount']);
$value = $objDiscount->getValue(sizeof($discounts), $cart->getOrderTotal(true, Cart::ONLY_PRODUCTS), $order->total_shipping, $cart->id);
if ($objDiscount->id_discount_type == Discount::AMOUNT AND in_array($objDiscount->behavior_not_exhausted, array(1,2)))
$shrunk = true;
$value = $cartRule->getValue(true);
// Todo: repair shrunk
// if ($shrunk AND ($total_discount_value + $value) > ($order->total_products_wt + $order->total_shipping + $order->total_wrapping))
// {
// $amount_to_add = ($order->total_products_wt + $order->total_shipping + $order->total_wrapping) - $total_discount_value;
// if ($cartRule->id_discount_type == Discount::AMOUNT AND $cartRule->behavior_not_exhausted == 2)
// {
// $voucher = new Discount();
// foreach ($cartRule AS $key => $discountValue)
// $voucher->$key = $discountValue;
// $voucher->name = 'VSRK'.(int)$order->id_customer.'O'.(int)$order->id;
// $voucher->value = (float)$value - $amount_to_add;
// $voucher->add();
// $params['{voucher_amount}'] = Tools::displayPrice($voucher->value, $currency, false);
// $params['{voucher_num}'] = $voucher->name;
// $params['{firstname}'] = $customer->firstname;
// $params['{lastname}'] = $customer->lastname;
// $params['{id_order}'] = $order->id;
// @Mail::Send((int)$order->id_lang, 'voucher', Mail::l('New voucher regarding your order #').$order->id, $params, $customer->email, $customer->firstname.' '.$customer->lastname);
// }
// }
if ($shrunk AND ($total_discount_value + $value) > ($order->total_products_wt + $order->total_shipping + $order->total_wrapping))
{
$amount_to_add = ($order->total_products_wt + $order->total_shipping + $order->total_wrapping) - $total_discount_value;
if ($objDiscount->id_discount_type == Discount::AMOUNT AND $objDiscount->behavior_not_exhausted == 2)
{
$voucher = new Discount();
foreach ($objDiscount AS $key => $discountValue)
$voucher->$key = $discountValue;
$voucher->name = 'VSRK'.(int)$order->id_customer.'O'.(int)$order->id;
$voucher->value = (float)$value - $amount_to_add;
$voucher->add();
$params['{voucher_amount}'] = Tools::displayPrice($voucher->value, $currency, false);
$params['{voucher_num}'] = $voucher->name;
$params['{firstname}'] = $customer->firstname;
$params['{lastname}'] = $customer->lastname;
$params['{id_order}'] = $order->id;
@Mail::Send((int)$order->id_lang, 'voucher', Mail::l('New voucher regarding your order #').$order->id, $params, $customer->email, $customer->firstname.' '.$customer->lastname);
}
}
else
$amount_to_add = $value;
$order->addDiscount($objDiscount->id, $objDiscount->name, $amount_to_add);
$total_discount_value += $amount_to_add;
$order->addCartRule($cartRule->id, $cartRule->name, $value);
if ($id_order_state != Configuration::get('PS_OS_ERROR') AND $id_order_state != Configuration::get('PS_OS_CANCELED'))
$objDiscount->quantity = $objDiscount->quantity - 1;
$objDiscount->update();
$cartRule->quantity = $cartRule->quantity - 1;
$cartRule->update();
$discountsList .=
'<tr style="background-color:#EBECEE;">
<td colspan="4" style="padding: 0.6em 0.4em; text-align: right;">'.
$this->l('Voucher code:').' '.$objDiscount->name.
'</td>
<td style="padding: 0.6em 0.4em; text-align: right;">'.
($value != 0.00 ? '-' : '').Tools::displayPrice($value, $currency, false).
'</td>
$cartRulesList .= '
<tr style="background-color:#EBECEE;">
<td colspan="4" style="padding:0.6em 0.4em;text-align:right">'.$this->l('Voucher name:').' '.$cartRule->name.'</td>
<td style="padding:0.6em 0.4em;text-align:right">'.($value != 0.00 ? '-' : '').Tools::displayPrice($value, $currency, false).'</td>
</tr>';
}
@@ -384,7 +373,7 @@ abstract class PaymentModuleCore extends Module
'{carrier}' => $carrier->name,
'{payment}' => Tools::substr($order->payment, 0, 32),
'{products}' => $productsList,
'{discounts}' => $discountsList,
'{discounts}' => $cartRulesList,
'{total_paid}' => Tools::displayPrice($order->total_paid, $currency, false),
'{total_products}' => Tools::displayPrice($order->total_paid - $order->total_shipping - $order->total_wrapping + $order->total_discounts, $currency, false),
'{total_discounts}' => Tools::displayPrice($order->total_discounts, $currency, false),
@@ -0,0 +1,326 @@
<?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: 7060 $
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
class AdminCartRulesControllerCore extends AdminController
{
public function __construct()
{
$this->table = 'cart_rule';
$this->className = 'CartRule';
$this->lang = true;
$this->addRowAction('delete');
$this->addRowAction('edit');
$this->bulk_actions = array('delete' => array('text' => $this->l('Delete selected'), 'confirm' => $this->l('Delete selected items?')));
$this->fieldsDisplay = array(
'id_cart_rule' => array('title' => $this->l('ID'), 'align' => 'center', 'width' => 25),
'name' => array('title' => $this->l('Code')),
'priority' => array('title' => $this->l('Priority')),
'code' => array('title' => $this->l('Code')),
'quantity' => array('title' => $this->l('Quantity')),
'date_to' => array('title' => $this->l('Until')),
'active' => array('title' => $this->l('Status'), 'align' => 'center', 'active' => 'status', 'type' => 'bool', 'orderby' => false),
);
parent::__construct();
}
public function postProcess()
{
if (Tools::isSubmit('submitAddcart_rule'))
{
// These are checkboxes (which aren't sent through POST when they are not check), so they are forced to 0
foreach (array('country', 'carrier', 'group', 'cart_rule', 'product') as $type)
if (!Tools::getValue($type.'_restriction'))
$_POST[$type.'_restriction'] = 0;
// Idiot-proof control
if (strtotime(Tools::getValue('date_from')) > strtotime(Tools::getValue('date_to')))
$this->_errors[] = Tools::displayError('The voucher cannot end before it begins');
if ((int)Tools::getValue('minimum_amount') < 0)
$this->_errors[] = Tools::displayError('Minimum amount cannot be lower than 0');
if ((float)Tools::getValue('reduction_percent') < 0 || (float)Tools::getValue('reduction_percent') > 100)
$this->_errors[] = Tools::displayError('Reduction percent must range from 0% to 100%');
if ((int)Tools::getValue('reduction_amount') < 0)
$this->_errors[] = Tools::displayError('Reduction amount cannot be lower than 0');
}
return parent::postProcess();
}
public function afterUpdate($currentObject)
{
// All the associations are deleted for an update, then recreated when we call the "afterAdd" method
$id_cart_rule = Tools::getValue('id_cart_rule');
foreach (array('country', 'carrier', 'group', 'product_rule') as $type)
Db::getInstance()->Execute('DELETE FROM `'._DB_PREFIX_.'cart_rule_'.$type.'` WHERE `id_cart_rule` = '.(int)$id_cart_rule);
Db::getInstance()->Execute('DELETE FROM `'._DB_PREFIX_.'cart_rule_product_rule_value` WHERE `id_product_rule` NOT IN (SELECT `id_product_rule` FROM `'._DB_PREFIX_.'cart_rule_product_rule`)');
Db::getInstance()->Execute('DELETE FROM `'._DB_PREFIX_.'cart_rule_combination` WHERE `id_cart_rule_1` = '.(int)$id_cart_rule.' OR `id_cart_rule_2` = '.(int)$id_cart_rule);
$this->afterAdd($currentObject);
}
// TODO Move this function into CartRule
public function afterAdd($currentObject)
{
// Add restrictions for generic entities like country, carrier and group
foreach (array('country', 'carrier', 'group') as $type)
if (Tools::getValue($type.'_restriction') && is_array($array = Tools::getValue($type.'_select')) && count($array))
{
$values = array();
foreach ($array as $id)
$values[] = '('.(int)$currentObject->id.','.(int)$id.')';
Db::getInstance()->Execute('INSERT INTO `'._DB_PREFIX_.'cart_rule_'.$type.'` (`id_cart_rule`, `id_'.$type.'`) VALUES '.implode(',', $values));
}
// Add cart rule restrictions
if (Tools::getValue('cart_rule_restriction') && is_array($array = Tools::getValue('cart_rule_select')) && count($array))
{
$values = array();
foreach ($array as $id)
$values[] = '('.(int)$currentObject->id.','.(int)$id.')';
Db::getInstance()->Execute('INSERT INTO `'._DB_PREFIX_.'cart_rule_combination` (`id_cart_rule_1`, `id_cart_rule_2`) VALUES '.implode(',', $values));
}
// Add product rule restrictions
if (Tools::getValue('product_restriction') && is_array($array = Tools::getValue('product_rule')) && count($array))
{
foreach ($array as $id)
{
Db::getInstance()->Execute('INSERT INTO `'._DB_PREFIX_.'cart_rule_product_rule` (`id_cart_rule`, `quantity`, `type`)
VALUES ('.(int)$currentObject->id.', '.(int)Tools::getValue('product_rule_'.$id.'_quantity').', "'.pSQL(Tools::getValue('product_rule_'.$id.'_type')).'")');
$id_product_rule = Db::getInstance()->Insert_ID();
$values = array();
foreach (Tools::getValue('product_rule_select_'.$id) as $id)
$values[] = '('.(int)$id_product_rule.','.(int)$id.')';
Db::getInstance()->Execute('INSERT INTO `'._DB_PREFIX_.'cart_rule_product_rule_value` (`id_product_rule`, `id_item`) VALUES '.implode(',', $values));
}
}
// If the new rule has no cart rule restriction, then it must be added to the white list of the other cart rules that have restrictions
if ($currentObject->cart_rule_restriction == 0)
{
Db::getInstance()->Execute('
INSERT INTO `'._DB_PREFIX_.'cart_rule_combination` (`id_cart_rule_1`, `id_cart_rule_2`) (
SELECT id_cart_rule, '.(int)$currentObject->id.' FROM `'._DB_PREFIX_.'cart_rule` WHERE cart_rule_restriction = 1
)');
}
// And if the new cart rule has restrictions, previously unrestricted cart rules may now be restricted (a mug of coffee is strongly advised to understand this sentence)
else
{
$ruleCombinations = Db::getInstance()->ExecuteS('
SELECT cr.id_cart_rule
FROM '._DB_PREFIX_.'cart_rule cr
WHERE cr.id_cart_rule != '.(int)$currentObject->id.'
AND cr.id_cart_rule NOT IN (
SELECT IF(id_cart_rule_1 = '.(int)$currentObject->id.', id_cart_rule_2, id_cart_rule_1)
FROM '._DB_PREFIX_.'cart_rule_combination
WHERE '.(int)$currentObject->id.' = id_cart_rule_1
OR '.(int)$currentObject->id.' = id_cart_rule_2
)');
foreach ($ruleCombinations as $incompatibleRule)
{
Db::getInstance()->Execute('UPDATE `'._DB_PREFIX_.'cart_rule` SET cart_rule_restriction = 1 WHERE id_cart_rule = '.(int)$incompatibleRule['id_cart_rule'].' LIMIT 1');
Db::getInstance()->Execute('
INSERT INTO `'._DB_PREFIX_.'cart_rule_combination` (`id_cart_rule_1`, `id_cart_rule_2`) (
SELECT id_cart_rule, '.(int)$incompatibleRule['id_cart_rule'].' FROM `'._DB_PREFIX_.'cart_rule` WHERE active = 1 AND id_cart_rule != '.(int)$currentObject->id.'
)');
}
}
}
public function getProductRuleDisplay($product_rule_id, $product_rule_type, $product_rule_quantity = 1, $selected = array())
{
Context::getContext()->smarty->assign(
array(
'product_rule_id' => (int)$product_rule_id,
'product_rule_type' => $product_rule_type,
'product_rule_quantity' => (int)$product_rule_quantity
)
);
switch ($product_rule_type)
{
case 'attributes':
$attributes = array('selected' => array(), 'unselected' => array());
$result = Db::getInstance()->ExecuteS('
SELECT CONCAT(agl.name, " - ", al.name) as name, a.id_attribute as id
FROM '._DB_PREFIX_.'attribute_group_lang agl
LEFT JOIN '._DB_PREFIX_.'attribute a ON a.id_attribute_group = agl.id_attribute_group
LEFT JOIN '._DB_PREFIX_.'attribute_lang al ON (a.id_attribute = al.id_attribute AND al.id_lang = '.(int)Context::getContext()->language->id.')
WHERE agl.id_lang = '.(int)Context::getContext()->language->id.'
ORDER BY agl.name, al.name', false);
while ($row = Db::getInstance()->nextRow($result))
$attributes[in_array($row['id'], $selected) ? 'selected' : 'unselected'][] = $row;
Context::getContext()->smarty->assign('product_rule_itemlist', $attributes);
$choose_content = Context::getContext()->smarty->fetch('cart_rules/product_rule_itemlist.tpl');
Context::getContext()->smarty->assign('product_rule_choose_content', $choose_content);
break;
case 'products':
// Todo: Consider optimization
$products = array('selected' => array(), 'unselected' => array());
$result = Db::getInstance()->ExecuteS('
SELECT name, id_product as id
FROM '._DB_PREFIX_.'product_lang pl
WHERE id_lang = '.(int)Context::getContext()->language->id.'
ORDER BY name', false);
while ($row = Db::getInstance()->nextRow($result))
$products[in_array($row['id'], $selected) ? 'selected' : 'unselected'][] = $row;
Context::getContext()->smarty->assign('product_rule_itemlist', $products);
$choose_content = Context::getContext()->smarty->fetch('cart_rules/product_rule_itemlist.tpl');
Context::getContext()->smarty->assign('product_rule_choose_content', $choose_content);
break;
case 'categories':
// Todo: Consider optimization (with code below)
$categories = array('selected' => array(), 'unselected' => array());
$result = Db::getInstance()->ExecuteS('
SELECT name, id_category as id
FROM '._DB_PREFIX_.'category_lang pl
WHERE id_lang = '.(int)Context::getContext()->language->id.'
ORDER BY name', false);
while ($row = Db::getInstance()->nextRow($result))
$categories[in_array($row['id'], $selected) ? 'selected' : 'unselected'][] = $row;
Context::getContext()->smarty->assign('product_rule_itemlist', $categories);
$choose_content = Context::getContext()->smarty->fetch('cart_rules/product_rule_itemlist.tpl');
Context::getContext()->smarty->assign('product_rule_choose_content', $choose_content);
// $translations = array(
// 'Home' => $this->l('Home'),
// 'selected' => $this->l('selected'),
// 'Collapse All' => $this->l('Collapse All'),
// 'Expand All' => $this->l('Expand All'),
// 'Check All' => $this->l('Check All'),
// 'Uncheck All' => $this->l('Uncheck All'),
// 'search' => $this->l('Search a category')
// );
// Context::getContext()->smarty->assign('product_rule_choose_content', Helper::renderAdminCategorieTree($translations, $selected, 'categoryBox', false, true));
break;
default:
die;
}
return Context::getContext()->smarty->fetch('cart_rules/product_rule.tpl');
}
public function ajaxProcess()
{
if (Tools::isSubmit('newProductRule'))
die ($this->getProductRuleDisplay(Tools::getValue('product_rule_id'), Tools::getValue('product_rule_type')));
if (Tools::isSubmit('customerFilter'))
{
$q = trim(Tools::getValue('q'));
$customers = Db::getInstance()->ExecuteS('
SELECT `id_customer`, `email`, CONCAT(`firstname`, \' \', `lastname`) as cname
FROM `'._DB_PREFIX_.'customer`
WHERE `deleted` = 0 AND is_guest = 0 AND active = 1
AND (
`id_customer` = '.(int)$q.'
OR `email` LIKE "%'.pSQL($q).'%"
OR `firstname` LIKE "%'.pSQL($q).'%"
OR `lastname` LIKE "%'.pSQL($q).'%"
)
ORDER BY `firstname`, `lastname` ASC
LIMIT 50');
die(Tools::jsonEncode($customers));
}
// Both product filter (free product and product discount) search for products
if (Tools::isSubmit('giftProductFilter') || Tools::isSubmit('reductionProductFilter'))
{
$products = Product::searchByName(Context::getContext()->language->id, trim(Tools::getValue('q')));
die(Tools::jsonEncode($products));
}
}
public function getProductRulesDisplay($cartRule)
{
$i = 1;
$productRulesArray = array();
$productRules = $cartRule->getProductRules();
foreach ($productRules as $productRule)
$productRulesArray[] = $this->getProductRuleDisplay($i++, $productRule['type'], $productRule['quantity'], $productRule['values']);
return $productRulesArray;
}
public function initForm()
{
// Todo: change for "Media" version
$this->addJs(_PS_JS_DIR_.'jquery/plugins/fancybox/jquery.fancybox.js');
$this->addJs(_PS_JS_DIR_.'jquery/plugins/autocomplete/jquery.autocomplete.js');
$this->addCss(_PS_JS_DIR_.'jquery/plugins/fancybox/jquery.fancybox.css');
$this->addCss(_PS_JS_DIR_.'jquery/plugins/autocomplete/jquery.autocomplete.css');
$currentObject = $this->loadObject(true);
// All the filter are prefilled with the correct information
$customerFilter = '';
if (Validate::isUnsignedId($currentObject->id_customer) AND $customer = new Customer($currentObject->id_customer) AND Validate::isLoadedObject($customer))
$customerFilter = $customer->firstname.' '.$customer->lastname.' ('.$customer->email.')';
$giftProductFilter = '';
if (Validate::isUnsignedId($currentObject->gift_product) AND $product = new Product($currentObject->gift_product, false, Context::getContext()->language->id) AND Validate::isLoadedObject($product))
$giftProductFilter = trim($product->reference.' '.$product->name);
$reductionProductFilter = '';
if (Validate::isUnsignedId($currentObject->reduction_product) AND $product = new Product($currentObject->reduction_product, false, Context::getContext()->language->id) AND Validate::isLoadedObject($product))
$reductionProductFilter = trim($product->reference.' '.$product->name);
$product_rules = $this->getProductRulesDisplay($currentObject);
Context::getContext()->smarty->assign(
array(
'languages' => Language::getLanguages(),
'defaultDateFrom' => date('Y-m-d H:00:00'),
'defaultDateTo' => date('Y-m-d H:00:00', strtotime('+1 year')),
'customerFilter' => $customerFilter,
'giftProductFilter' => $giftProductFilter,
'reductionProductFilter' => $reductionProductFilter,
'defaultCurrency' => Configuration::get('PS_CURRENCY_DEFAULT'),
'currencies' => Currency::getCurrencies(),
'countries' => $currentObject->getAssociatedRestrictions('country', 1),
'carriers' => $currentObject->getAssociatedRestrictions('carrier', 1),
'groups' => $currentObject->getAssociatedRestrictions('group', 0),
'cart_rules' => $currentObject->getAssociatedRestrictions('cart_rule', 1),
'product_rules' => $product_rules,
'product_rules_counter' => count($product_rules),
'attribute_groups' => AttributeGroup::getAttributesGroups(Context::getContext()->language->id),
'currentIndex' => self::$currentIndex,
'currentToken' => $this->token,
'currentObject' => $currentObject,
'currentTab' => $this
)
);
$this->content .= Context::getContext()->smarty->fetch('cart_rules/form.tpl');
// Todo: replace by the new "includeDatepicker" version
$ob_content = ob_get_contents();
ob_clean();
includeDatepicker(array('date_from', 'date_to'), true);
$this->content .= ob_get_contents();
ob_clean();
echo $ob_content;
return parent::initForm();
}
}
+11 -7
View File
@@ -276,6 +276,10 @@ class AuthControllerCore extends FrontController
$this->context->cart->id_address_invoice = Address::getFirstCustomerAddressId((int)($customer->id));
$this->context->cart->update();
Module::hookExec('authentication');
// Login information have changed, so we check if the cart rules still apply
CartRule::autoRemoveFromCart();
if (!$this->ajax)
{
if ($back = Tools::getValue('back'))
@@ -565,15 +569,15 @@ class AuthControllerCore extends FrontController
protected function sendConfirmationMail(Customer $customer)
{
return Mail::Send(
$this->context->language->id,
'account',
$this->context->language->id,
'account',
Mail::l('Welcome!'),
array(
'{firstname}' => $customer->firstname,
'{lastname}' => $customer->lastname,
'{email}' => $customer->email,
'{passwd}' => Tools::getValue('passwd')),
$customer->email,
'{firstname}' => $customer->firstname,
'{lastname}' => $customer->lastname,
'{email}' => $customer->email,
'{passwd}' => Tools::getValue('passwd')),
$customer->email,
$customer->firstname.' '.$customer->lastname
);
}
+4 -40
View File
@@ -58,9 +58,6 @@ class CartControllerCore extends FrontController
public function postProcess()
{
// Check cart discounts
$this->processRemoveDiscounts();
if ($this->isTokenValid())
$this->errors[] = Tools::displayError('Invalid token');
@@ -72,8 +69,6 @@ class CartControllerCore extends FrontController
else if (Tools::getIsset('delete'))
$this->processDeleteProductInCart();
$this->processRemoveDiscounts();
// Make redirection
if (!$this->errors && !$this->ajax)
{
@@ -107,6 +102,7 @@ class CartControllerCore extends FrontController
$this->context->cart->gift_message = '';
$this->context->cart->update();
}
CartRule::autoRemoveFromCart();
}
/**
@@ -147,29 +143,6 @@ class CartControllerCore extends FrontController
else if (!$product->checkQty($this->qty))
$this->errors[] = Tools::displayError('There is not enough product in stock.');
// Check vouchers compatibility
if ($mode == 'add' && (($product->specificPrice && (float)$product->specificPrice['reduction']) || $product->on_sale))
{
$discounts = $this->context->cart->getDiscounts();
$hasUndiscountedProduct = null;
foreach ($discounts as $discount)
{
if (is_null($hasUndiscountedProduct))
{
$hasUndiscountedProduct = false;
foreach ($this->context->cart->getProducts() as $product)
if ($product['reduction_applies'] === false)
{
$hasUndiscountedProduct = true;
break;
}
}
if (!$discount['cumulable_reduction'] && ($discount['id_discount_type'] != Discount::PERCENT || !$hasUndiscountedProduct))
$this->errors[] = Tools::displayError('Cannot add this product because current voucher does not allow additional discounts.');
}
}
// If no errors, process product addition
if (!$this->errors && $mode == 'add')
{
@@ -198,6 +171,7 @@ class CartControllerCore extends FrontController
$this->errors[] = Tools::displayError('You already have the maximum quantity available for this product.');
}
}
CartRule::autoRemoveFromCart();
}
/**
@@ -205,18 +179,8 @@ class CartControllerCore extends FrontController
*/
protected function processRemoveDiscounts()
{
$orderTotal = $this->context->cart->getOrderTotal(true, Cart::ONLY_PRODUCTS);
$cartProducts = $this->context->cart->getProducts();
foreach ($this->context->cart->getDiscounts() as $discount)
{
$discountObj = new Discount($discount['id_discount'], $this->context->language->id);
if ($error = $this->context->cart->checkDiscountValidity($discountObj, $discounts, $orderTotal, $cartProducts, false))
{
$this->context->cart->deleteDiscount($discount['id_discount']);
$this->context->cart->update();
$this->errors[] = $error;
}
}
Tools::displayAsDeprecated();
$this->errors = array_merge($this->errors, CartRule::autoRemoveFromCart());
}
/**
+38 -27
View File
@@ -88,38 +88,40 @@ class ParentOrderControllerCore extends FrontController
if ($this->nbProducts)
{
if (Tools::isSubmit('submitAddDiscount') && Tools::getValue('discount_name') && Discount::isFeatureActive())
if (CartRule::isFeatureActive())
{
$discountName = Tools::getValue('discount_name');
if (!Validate::isDiscountName($discountName))
$this->errors[] = Tools::displayError('Voucher name invalid.');
else
if (Tools::isSubmit('submitAddDiscount'))
{
$discount = new Discount((int)(Discount::getIdByName($discountName)));
if (Validate::isLoadedObject($discount))
{
if ($tmpError = $this->context->cart->checkDiscountValidity($discount, $this->context->cart->getDiscounts(), $this->context->cart->getOrderTotal(), $this->context->cart->getProducts(), true))
$this->errors[] = $tmpError;
}
if (!($code = Tools::getValue('discount_name')))
$this->errors[] = Tools::displayError('You must enter a voucher code');
elseif (!Validate::isDiscountName($code))
$this->errors[] = Tools::displayError('Voucher code invalid');
else
$this->errors[] = Tools::displayError('Voucher name invalid.');
if (!count($this->errors))
{
$this->context->cart->addDiscount((int)($discount->id));
Tools::redirect('index.php?controller=order-opc');
if ($cartRule = new CartRule(CartRule::getIdByCode($code)) AND Validate::isLoadedObject($cartRule))
{
if ($error = $cartRule->checkValidity($this->context))
$this->errors[] = $error;
else
{
$this->context->cart->addCartRule($cartRule->id);
Tools::redirect('index.php?controller=order-opc');
}
}
else
$this->errors[] = Tools::displayError('Voucher name invalid.');
}
$this->context->smarty->assign(array(
'errors' => $this->errors,
'discount_name' => Tools::safeOutput($code)
));
}
elseif ($id_cart_rule = (int)Tools::getValue('deleteDiscount') AND Validate::isUnsignedId($id_cart_rule))
{
$this->context->cart->removeCartRule($id_cart_rule);
Tools::redirect('index.php?controller=order-opc');
}
$this->context->smarty->assign(array(
'errors' => $this->errors,
'discount_name' => Tools::safeOutput($discountName)
));
}
else if (isset($_GET['deleteDiscount']) && Validate::isUnsignedId($_GET['deleteDiscount']) && Discount::isFeatureActive())
{
$this->context->cart->deleteDiscount((int)($_GET['deleteDiscount']));
Tools::redirect('index.php?controller=order-opc');
}
/* Is there only virtual product in cart */
if ($isVirtualCart = $this->context->cart->isVirtualCart())
$this->setNoCarrier();
@@ -222,7 +224,11 @@ class ParentOrderControllerCore extends FrontController
Module::hookExec('processCarrier', array('cart' => $this->context->cart));
return $this->context->cart->update();
if (!$this->context->cart->update())
return false;
// Carrier has changed, so we check if the cart rules still apply
CartRule::autoRemoveFromCart();
}
protected function _assignSummaryInformations()
@@ -249,7 +255,7 @@ class ParentOrderControllerCore extends FrontController
if ($free_ship = Tools::convertPrice((float)(Configuration::get('PS_SHIPPING_FREE_PRICE')), new Currency($this->context->cart->id_currency)))
{
$discounts = $this->context->cart->getDiscounts();
$discounts = $this->context->cart->getCartRules();
$total_free_ship = $free_ship - ($summary['total_products_wt'] + $summary['total_discounts']);
foreach ($discounts as $discount)
if ($discount['id_discount_type'] == Discount::FREE_SHIPPING)
@@ -338,7 +344,12 @@ class ParentOrderControllerCore extends FrontController
}
/* Update cart addresses only if needed */
if (isset($update) && $update)
{
$this->context->cart->update();
// Address has changed, so we check if the cart rules still apply
CartRule::autoRemoveFromCart();
}
/* If delivery address is valid in cart, assign it to Smarty */
if (isset($this->context->cart->id_address_delivery))
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1019 B

+87 -10
View File
@@ -187,11 +187,88 @@ CREATE TABLE `PREFIX_cart` (
KEY `id_shop` (`id_shop`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
CREATE TABLE `PREFIX_cart_discount` (
CREATE TABLE `PREFIX_cart_rule` (
`id_cart_rule` int(10) unsigned NOT NULL auto_increment,
`id_customer` int unsigned NOT NULL default 0,
`date_from` datetime NOT NULL,
`date_to` datetime NOT NULL,
`description` text,
`quantity` int(10) unsigned NOT NULL default 0,
`quantity_per_user` int(10) unsigned NOT NULL default 0,
`priority` int(10) unsigned NOT NULL default 1,
`code` varchar(254) NOT NULL,
`minimum_amount` decimal(17,2) NOT NULL default 0,
`minimum_amount_tax` tinyint(1) NOT NULL default 0,
`minimum_amount_currency` int unsigned NOT NULL default 0,
`minimum_amount_shipping` tinyint(1) NOT NULL default 0,
`country_restriction` tinyint(1) unsigned NOT NULL default 0,
`carrier_restriction` tinyint(1) unsigned NOT NULL default 0,
`group_restriction` tinyint(1) unsigned NOT NULL default 0,
`cart_rule_restriction` tinyint(1) unsigned NOT NULL default 0,
`product_restriction` tinyint(1) unsigned NOT NULL default 0,
`free_shipping` tinyint(1) NOT NULL default 0,
`reduction_percent` decimal(4,2) NOT NULL default 0,
`reduction_amount` decimal(17,2) NOT NULL default 0,
`reduction_tax` tinyint(1) unsigned NOT NULL default 0,
`reduction_currency` int(10) unsigned NOT NULL default 0,
`reduction_product` int(10) NOT NULL default 0,
`gift_product` int(10) unsigned NOT NULL default 0,
`active` tinyint(1) unsigned NOT NULL default 0,
`date_add` datetime NOT NULL,
`date_upd` datetime NOT NULL,
PRIMARY KEY (`id_cart_rule`)
);
CREATE TABLE `PREFIX_cart_rule_lang` (
`id_cart_rule` int(10) unsigned NOT NULL,
`id_lang` int(10) unsigned NOT NULL,
`name` varchar(254) NOT NULL,
PRIMARY KEY (`id_cart_rule`, `id_lang`)
);
CREATE TABLE `PREFIX_cart_rule_country` (
`id_cart_rule` int(10) unsigned NOT NULL,
`id_country` int(10) unsigned NOT NULL,
PRIMARY KEY (`id_cart_rule`, `id_country`)
);
CREATE TABLE `PREFIX_cart_rule_group` (
`id_cart_rule` int(10) unsigned NOT NULL,
`id_group` int(10) unsigned NOT NULL,
PRIMARY KEY (`id_cart_rule`, `id_group`)
);
CREATE TABLE `PREFIX_cart_rule_carrier` (
`id_cart_rule` int(10) unsigned NOT NULL,
`id_carrier` int(10) unsigned NOT NULL,
PRIMARY KEY (`id_cart_rule`, `id_carrier`)
);
CREATE TABLE `PREFIX_cart_rule_combination` (
`id_cart_rule_1` int(10) unsigned NOT NULL,
`id_cart_rule_2` int(10) unsigned NOT NULL,
PRIMARY KEY (`id_cart_rule_1`, `id_cart_rule_2`)
);
CREATE TABLE `PREFIX_cart_rule_product_rule` (
`id_product_rule` int(10) unsigned NOT NULL auto_increment,
`id_cart_rule` int(10) unsigned NOT NULL,
`quantity` int(10) unsigned NOT NULL default 1,
`type` ENUM('products', 'categories', 'attributes') NOT NULL,
PRIMARY KEY (`id_product_rule`)
);
CREATE TABLE `PREFIX_cart_rule_product_rule_value` (
`id_product_rule` int(10) unsigned NOT NULL,
`id_item` int(10) unsigned NOT NULL,
PRIMARY KEY (`id_product_rule`, `id_item`)
);
CREATE TABLE `PREFIX_cart_cart_rule` (
`id_cart` int(10) unsigned NOT NULL,
`id_discount` int(10) unsigned NOT NULL,
KEY `cart_discount_index` (`id_cart`,`id_discount`),
KEY `id_discount` (`id_discount`)
`id_cart_rule` int(10) unsigned NOT NULL,
PRIMARY KEY (`id_cart`,`id_cart_rule`),
KEY (`id_cart_rule`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
CREATE TABLE `PREFIX_cart_product` (
@@ -1027,15 +1104,15 @@ CREATE TABLE `PREFIX_order_detail` (
KEY `id_order_id_order_detail` (`id_order`, `id_order_detail`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
CREATE TABLE `PREFIX_order_discount` (
`id_order_discount` int(10) unsigned NOT NULL auto_increment,
CREATE TABLE `PREFIX_order_cart_rule` (
`id_order_cart_rule` int(10) unsigned NOT NULL auto_increment,
`id_order` int(10) unsigned NOT NULL,
`id_discount` int(10) unsigned NOT NULL,
`id_cart_rule` int(10) unsigned NOT NULL,
`name` varchar(32) NOT NULL,
`value` decimal(17,2) NOT NULL default '0.00',
PRIMARY KEY (`id_order_discount`),
KEY `order_discount_order` (`id_order`),
KEY `id_discount` (`id_discount`)
PRIMARY KEY (`id_order_cart_rule`),
KEY `id_order` (`id_order`),
KEY `id_cart_rule` (`id_cart_rule`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
CREATE TABLE `PREFIX_order_history` (
+5 -5
View File
@@ -230,7 +230,7 @@ INSERT INTO `PREFIX_configuration` (`id_configuration`, `name`, `value`, `date_a
(142, 'PS_SCENE_FEATURE_ACTIVE', '1', NOW(), NOW()),
(143, 'PS_VIRTUAL_PROD_FEATURE_ACTIVE', '0', NOW(), NOW()),
(144, 'PS_CUSTOMIZATION_FEATURE_ACTIVE', '0', NOW(), NOW()),
(145, 'PS_DISCOUNT_FEATURE_ACTIVE', '0', NOW(), NOW()),
(145, 'PS_CART_RULE_FEATURE_ACTIVE', '0', NOW(), NOW()),
(146, 'PS_GROUP_FEATURE_ACTIVE', '0', NOW(), NOW()),
(147, 'PS_PACK_FEATURE_ACTIVE', '0', NOW(), NOW()),
(148, 'PS_ALIAS_FEATURE_ACTIVE', '1', NOW(), NOW()),
@@ -848,7 +848,7 @@ INSERT INTO `PREFIX_tab` (`id_tab`, `class_name`, `id_parent`, `position`) VALUE
(9, 'AdminTools', 0, 10),(82, 'AdminStores', 9, 11),(60, 'AdminTracking', 1, 3),(10, 'AdminManufacturers', 1, 4),(34, 'AdminSuppliers', 1, 5),(11, 'AdminAttributesGroups', 1, 6),
(36, 'AdminFeatures', 1, 7),(58, 'AdminScenes', 1, 8),(66, 'AdminTags', 1, 9),(68, 'AdminAttachments', 1, 10),(12, 'AdminAddresses', 2, 1),(63, 'AdminGroups', 2, 2),
(65, 'AdminCarts', 2, 3),(42, 'AdminInvoices', 3, 1),(55, 'AdminDeliverySlip', 3, 2),(47, 'AdminReturn', 3, 3),(49, 'AdminSlip', 3, 4),(59, 'AdminMessages', 3, 5),
(13, 'AdminStatuses', 3, 6),(54, 'AdminOrderMessage', 3, 7),(14, 'AdminDiscounts', 4, 4),(15, 'AdminCurrencies', 4, 1),(16, 'AdminTaxes', 4, 2),
(13, 'AdminStatuses', 3, 6),(54, 'AdminOrderMessage', 3, 7),(14, 'AdminCartRules', 4, 4),(15, 'AdminCurrencies', 4, 1),(16, 'AdminTaxes', 4, 2),
(17, 'AdminCarriers', 5, 1),(46, 'AdminStates', 5, 2),(18, 'AdminCountries', 5, 3),(19, 'AdminZones', 5, 5),(20, 'AdminRangePrice', 5, 6),
(21, 'AdminRangeWeight', 5, 7),(51, 'AdminStatsConf', 6, 1),(61, 'AdminSearchEngines', 6, 2),(62, 'AdminReferrers', 6, 3),
(22, 'AdminModulesPositions', 7, 4),(30, 'AdminProfiles', 29, 1),(31, 'AdminAccess', 29, 2),(28, 'AdminContacts', 29, 3),(39, 'AdminContact', 8, 1),
@@ -874,7 +874,7 @@ INSERT INTO `PREFIX_access` (`id_profile`, `id_tab`, `view`, `add`, `edit`, `del
INSERT INTO `PREFIX_tab_lang` (`id_lang`, `id_tab`, `name`) VALUES
(1, 1, 'Catalog'),(1, 2, 'Customers'),(1, 3, 'Orders'),(1, 4, 'Payment'),
(1, 5, 'Shipping'),(1, 6, 'Stats'),(1, 7, 'Modules'),(1, 8, 'Preferences'),(1, 9, 'Tools'),(1, 10, 'Manufacturers'),(1, 11, 'Attributes and Groups'),
(1, 12, 'Addresses'),(1, 13, 'Statuses'),(1, 14, 'Vouchers'),(1, 15, 'Currencies'),(1, 16, 'Taxes'),(1, 17, 'Carriers'),(1, 18, 'Countries'),
(1, 12, 'Addresses'),(1, 13, 'Statuses'),(1, 14, 'Cart Rules'),(1, 15, 'Currencies'),(1, 16, 'Taxes'),(1, 17, 'Carriers'),(1, 18, 'Countries'),
(1, 19, 'Zones'),(1, 20, 'Price Ranges'),(1, 21, 'Weight Ranges'),(1, 22, 'Positions'),(1, 23, 'Database'),(1, 24, 'E-mail'),(1, 26, 'Images'),
(1, 27, 'Products'),(1, 28, 'Contacts'),(1, 29, 'Employees'),(1, 30, 'Profiles'),(1, 31, 'Permissions'),(1, 32, 'Languages'),(1, 33, 'Translations'),
(1, 34, 'Suppliers'),(1, 35, 'Tabs'),(1, 36, 'Features'),(1, 37, 'Quick Access'),(1, 38, 'Themes'),(1, 39, 'Contact Information'),(1, 40, 'Keyword Typos'),
@@ -897,7 +897,7 @@ INSERT INTO `PREFIX_tab_lang` (`id_lang`, `id_tab`, `name`) VALUES
INSERT INTO `PREFIX_tab_lang` (`id_lang`, `id_tab`, `name`) VALUES
(2, 1, 'Catalogue'),(2, 2, 'Clients'),(2, 3, 'Commandes'),(2, 4, 'Paiement'),(2, 5, 'Transport'),
(2, 6, 'Stats'),(2, 7, 'Modules'),(2, 8, 'Préférences'),(2, 9, 'Outils'),(2, 10, 'Marques'),(2, 11, 'Attributs et groupes'),(2, 12, 'Adresses'),(2, 13, 'Statuts'),
(2, 14, 'Bons de réduction'),(2, 15, 'Devises'),(2, 16, 'Taxes'),(2, 17, 'Transporteurs'),(2, 18, 'Pays'),(2, 19, 'Zones'),(2, 20, 'Tranches de prix'),
(2, 14, 'Règles paniers'),(2, 15, 'Devises'),(2, 16, 'Taxes'),(2, 17, 'Transporteurs'),(2, 18, 'Pays'),(2, 19, 'Zones'),(2, 20, 'Tranches de prix'),
(2, 21, 'Tranches de poids'),(2, 22, 'Positions'),(2, 23, 'Base de données'),(2, 24, 'Emails'),(2, 26, 'Images'),(2, 27, 'Produits'),(2, 28, 'Contacts'),
(2, 29, 'Employés'),(2, 30, 'Profils'),(2, 31, 'Permissions'),(2, 32, 'Langues'),(2, 33, 'Traductions'),(2, 34, 'Fournisseurs'),(2, 35, 'Onglets'),
(2, 36, 'Caractéristiques'),(2, 37, 'Accès rapide'),(2, 38, 'Thèmes'),(2, 39, 'Coordonnées'),(2, 40, 'Alias'),(2, 41, 'Import'),(2, 42, 'Factures'),
@@ -994,7 +994,7 @@ INSERT IGNORE INTO `PREFIX_tab_lang` (`id_tab`, `id_lang`, `name`)
FROM `PREFIX_lang` CROSS JOIN `PREFIX_tab`);
INSERT INTO `PREFIX_quick_access` (`id_quick_access`, `link`, `new_window`) VALUES
(1, 'index.php', 0),(2, '../', 1),(3, 'index.php?controller=AdminCatalog&addcategory', 0),(4, 'index.php?controller=AdminCatalog&addproduct', 0),(5, 'index.php?controller=AdminDiscounts&adddiscount', 0);
(1, 'index.php', 0),(2, '../', 1),(3, 'index.php?controller=AdminCatalog&addcategory', 0),(4, 'index.php?controller=AdminCatalog&addproduct', 0),(5, 'index.php?controller=AdminCartRules&addcart_rule', 0);
INSERT INTO `PREFIX_quick_access_lang` (`id_quick_access`, `id_lang`, `name`) VALUES
(1, 1, 'Home'),(1, 2, 'Accueil'),(1, 3, 'Inicio'),(1, 4, 'Start'),(1, 5, 'Home page'),
+94
View File
@@ -222,3 +222,97 @@ ALTER TABLE `PREFIX_carrier` ADD `position` INT( 10 ) UNSIGNED NOT NULL DEFAULT
ALTER TABLE `PREFIX_order_state` ADD COLUMN `shipped` TINYINT(1) UNSIGNED NOT NULL DEFAULT 0 AFTER `delivery`;
UPDATE `PREFIX_order_state` SET `shipped` = 1 WHERE id_order_states IN (4, 5);
CREATE TABLE `PREFIX_cart_rule` (
`id_cart_rule` int(10) unsigned NOT NULL auto_increment,
`id_customer` int unsigned NOT NULL default 0,
`date_from` datetime NOT NULL,
`date_to` datetime NOT NULL,
`description` text,
`quantity` int(10) unsigned NOT NULL default 0,
`quantity_per_user` int(10) unsigned NOT NULL default 0,
`priority` int(10) unsigned NOT NULL default 1,
`code` varchar(254) NOT NULL,
`minimum_amount` decimal(17,2) NOT NULL default 0,
`minimum_amount_tax` tinyint(1) NOT NULL default 0,
`minimum_amount_currency` int unsigned NOT NULL default 0,
`minimum_amount_shipping` tinyint(1) NOT NULL default 0,
`country_restriction` tinyint(1) unsigned NOT NULL default 0,
`carrier_restriction` tinyint(1) unsigned NOT NULL default 0,
`group_restriction` tinyint(1) unsigned NOT NULL default 0,
`cart_rule_restriction` tinyint(1) unsigned NOT NULL default 0,
`product_restriction` tinyint(1) unsigned NOT NULL default 0,
`free_shipping` tinyint(1) NOT NULL default 0,
`reduction_percent` decimal(4,2) NOT NULL default 0,
`reduction_amount` decimal(17,2) NOT NULL default 0,
`reduction_tax` tinyint(1) unsigned NOT NULL default 0,
`reduction_currency` int(10) unsigned NOT NULL default 0,
`reduction_product` int(10) NOT NULL default 0,
`gift_product` int(10) unsigned NOT NULL default 0,
`active` tinyint(1) unsigned NOT NULL default 0,
`date_add` datetime NOT NULL,
`date_upd` datetime NOT NULL,
PRIMARY KEY (`id_cart_rule`)
);
CREATE TABLE `PREFIX_cart_rule_lang` (
`id_cart_rule` int(10) unsigned NOT NULL,
`id_lang` int(10) unsigned NOT NULL,
`name` varchar(254) NOT NULL,
PRIMARY KEY (`id_cart_rule`, `id_lang`)
);
CREATE TABLE `PREFIX_cart_rule_country` (
`id_cart_rule` int(10) unsigned NOT NULL,
`id_country` int(10) unsigned NOT NULL,
PRIMARY KEY (`id_cart_rule`, `id_country`)
);
CREATE TABLE `PREFIX_cart_rule_group` (
`id_cart_rule` int(10) unsigned NOT NULL,
`id_group` int(10) unsigned NOT NULL,
PRIMARY KEY (`id_cart_rule`, `id_group`)
);
CREATE TABLE `PREFIX_cart_rule_carrier` (
`id_cart_rule` int(10) unsigned NOT NULL,
`id_carrier` int(10) unsigned NOT NULL,
PRIMARY KEY (`id_cart_rule`, `id_carrier`)
);
CREATE TABLE `PREFIX_cart_rule_combination` (
`id_cart_rule_1` int(10) unsigned NOT NULL,
`id_cart_rule_2` int(10) unsigned NOT NULL,
PRIMARY KEY (`id_cart_rule_1`, `id_cart_rule_2`)
);
CREATE TABLE `PREFIX_cart_rule_product_rule` (
`id_product_rule` int(10) unsigned NOT NULL auto_increment,
`id_cart_rule` int(10) unsigned NOT NULL,
`quantity` int(10) unsigned NOT NULL default 1,
`type` ENUM('products', 'categories', 'attributes') NOT NULL,
PRIMARY KEY (`id_product_rule`)
);
CREATE TABLE `PREFIX_cart_rule_product_rule_value` (
`id_product_rule` int(10) unsigned NOT NULL,
`id_item` int(10) unsigned NOT NULL,
PRIMARY KEY (`id_product_rule`, `id_item`)
);
ALTER TABLE `PREFIX_cart_discount` CHANGE `id_discount` `id_cart_rule` int(10) unsigned NOT NULL;
ALTER TABLE `PREFIX_order_discount` CHANGE `id_discount` `id_cart_rule` int(10) unsigned NOT NULL;
ALTER TABLE `PREFIX_order_discount` CHANGE `id_order_discount` `id_order_cart_rule` int(10) unsigned NOT NULL;
RENAME TABLE `PREFIX_order_discount` TO `PREFIX_order_cart_rule`;
RENAME TABLE `PREFIX_cart_discount` TO `PREFIX_cart_cart_rule`;
CREATE VIEW `PREFIX_order_discount` AS SELECT *, id_cart_rule as id_discount FROM `PREFIX_order_cart_rule`;
CREATE VIEW `PREFIX_cart_discount` AS SELECT *, id_cart_rule as id_discount FROM `PREFIX_cart_cart_rule`;
INSERT INTO `PREFIX_configuration` (`name`, `value`, `date_add`, `date_upd`) (
SELECT 'PS_CART_RULE_FEATURE_ACTIVE', `value`, NOW(), NOW() FROM `PREFIX_configuration` WHERE `name` = 'PS_DISCOUNT_FEATURE_ACTIVE' LIMIT 1
);
UPDATE `PREFIX_tab` SET class_name = 'AdminCartRules' WHERE class_name = 'AdminDiscounts';
+1 -1
View File
@@ -85,7 +85,7 @@ class BlockCart extends Module
'customizedDatas' => Product::getAllCustomizedDatas((int)($params['cart']->id)),
'CUSTOMIZE_FILE' => _CUSTOMIZE_FILE_,
'CUSTOMIZE_TEXTFIELD' => _CUSTOMIZE_TEXTFIELD_,
'discounts' => $params['cart']->getDiscounts(false, Tools::isSubmit('id_product')),
'discounts' => $params['cart']->getCartRules(false, Tools::isSubmit('id_product')),
'nb_total_products' => (int)($nbTotalProducts),
'shipping_cost' => Tools::displayPrice($params['cart']->getOrderTotal($useTax, Cart::ONLY_SHIPPING), $currency),
'show_wrapping' => $wrappingCost > 0 ? true : false,
+11 -6
View File
@@ -270,13 +270,18 @@
<tbody>
{foreach from=$discounts item=discount name=discountLoop}
<tr class="cart_discount {if $smarty.foreach.discountLoop.last}last_item{elseif $smarty.foreach.discountLoop.first}first_item{else}item{/if}" id="cart_discount_{$discount.id_discount}">
<td class="cart_discount_name" colspan="2">{$discount.name}</td>
<td class="cart_discount_description" colspan="3">{$discount.description}</td>
<td class="cart_discount_delete"><a href="{if $opc}{$link->getPageLink('order-opc', true)}{else}{$link->getPageLink('order', true)}{/if}?deleteDiscount={$discount.id_discount}" title="{l s='Delete'}"><img src="{$img_dir}icon/delete.gif" alt="{l s='Delete'}" class="icon" width="11" height="13" /></a></td>
<td class="cart_discount_name" colspan="4">{$discount.name}</td>
<td class="cart_discount_price"><span class="price-discount">
{if $discount.value_real > 0}
{if !$priceDisplay}{displayPrice price=$discount.value_real*-1}{else}{displayPrice price=$discount.value_tax_exc*-1}{/if}
{/if}
{if !$priceDisplay}{displayPrice price=$discount.value_real*-1}{else}{displayPrice price=$discount.value_tax_exc*-1}{/if}
</span></td>
<td class="cart_discount_delete">
<a href="{if $opc}{$link->getPageLink('order-opc', true)}{else}{$link->getPageLink('order', true)}{/if}?deleteDiscount={$discount.id_discount}" title="{l s='Delete'}">
<img src="{$img_dir}icon/delete.gif" alt="{l s='Delete'}" class="icon" width="11" height="13" />
</a>
1
</td>
<td class="cart_discount_price"><span class="price-discount">
{if !$priceDisplay}{displayPrice price=$discount.value_real*-1}{else}{displayPrice price=$discount.value_tax_exc*-1}{/if}
</span></td>
</tr>
{/foreach}