diff --git a/admin-dev/themes/default/template/controllers/cart_rules/actions.tpl b/admin-dev/themes/default/template/controllers/cart_rules/actions.tpl
index 2621310ec..bc0264172 100644
--- a/admin-dev/themes/default/template/controllers/cart_rules/actions.tpl
+++ b/admin-dev/themes/default/template/controllers/cart_rules/actions.tpl
@@ -28,7 +28,7 @@
-
+
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+ {$gift_product_attribute_select}
+
+
+
+
+
+
diff --git a/admin-dev/themes/default/template/controllers/cart_rules/form.js b/admin-dev/themes/default/template/controllers/cart_rules/form.js
index 8ab9d0170..15db30784 100644
--- a/admin-dev/themes/default/template/controllers/cart_rules/form.js
+++ b/admin-dev/themes/default/template/controllers/cart_rules/form.js
@@ -228,36 +228,6 @@ $('#cart_rule_form').submit(function() {
$(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(
@@ -347,4 +317,75 @@ $('.datepicker').datepicker({
prevText: '',
nextText: '',
dateFormat: 'yy-mm-dd ' + hours + ':' + mins + ':' + secs
-});
\ No newline at end of file
+});
+
+$('#giftProductFilter').typeWatch({
+ captureLength: 2,
+ highlight: false,
+ wait: 100,
+ callback: function(){ searchProducts(); }
+});
+
+var gift_product_search = $('#giftProductFilter').val();
+function searchProducts()
+{
+ if ($('#giftProductFilter').val() == gift_product_search)
+ return;
+ gift_product_search = $('#giftProductFilter').val();
+
+ $.ajax({
+ type: 'POST',
+ url: 'ajax-tab.php',
+ async: true,
+ dataType: 'json',
+ data: {
+ controller: 'AdminCartRules',
+ token: currentToken,
+ action: 'searchProducts',
+ product_search: $('#giftProductFilter').val()
+ },
+ success : function(res)
+ {
+ var products_found = '';
+ var attributes_html = '';
+ stock = {};
+
+ if (res.found)
+ {
+ $('#gift_products_err').hide();
+ $('#gift_products_found').show();
+ $.each(res.products, function() {
+ products_found += '';
+
+ attributes_html += '';
+ });
+
+ $('#gift_product_list #gift_product').html(products_found);
+ $('#gift_attributes_list #gift_attributes_list_select').html(attributes_html);
+ displayProductAttributes();
+ }
+ else
+ {
+ $('#products_found').hide();
+ $('#products_err').html(res.notfound);
+ $('#products_err').show();
+ }
+ }
+ });
+}
+
+function displayProductAttributes()
+{
+ if ($('#ipa_' + $('#gift_product option:selected').val() + ' option').length === 0)
+ $('#gift_attributes_list').hide();
+ else
+ {
+ $('#gift_attributes_list').show();
+ $('.id_product_attribute').hide();
+ $('#ipa_' + $('#gift_product option:selected').val()).show();
+ }
+}
\ No newline at end of file
diff --git a/classes/Cart.php b/classes/Cart.php
index c43efbd2f..1957292fc 100644
--- a/classes/Cart.php
+++ b/classes/Cart.php
@@ -705,7 +705,7 @@ class CartCore extends ObjectModel
Cache::clean('Cart::getCartRules'.$this->id);
if ((int)$cartRule->gift_product)
- return $this->updateQty(1, $cartRule->gift_product);
+ $this->updateQty(1, $cartRule->gift_product, $cartRule->gift_product_attribute);
return true;
}
@@ -751,8 +751,8 @@ class CartCore extends ObjectModel
{
if ($id_address_delivery == 0) // The $id_address_delivery is null, get the default customer address
$id_address_delivery = (int)Address::getFirstCustomerAddressId((int)Context::getContext()->customer->id);
- else if (!Customer::customerHasAddress(Context::getContext()->customer->id, $id_address_delivery)) // The $id_address_delivery must be linked with customer
- $id_address_delivery = 0;
+ elseif (!Customer::customerHasAddress(Context::getContext()->customer->id, $id_address_delivery)) // The $id_address_delivery must be linked with customer
+ $id_address_delivery = 0;
}
$quantity = (int)$quantity;
@@ -1019,11 +1019,18 @@ class CartCore extends ObjectModel
public function removeCartRule($id_cart_rule)
{
Cache::clean('Cart::getCartRules'.$this->id);
- 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'
- );
+
+ $result = 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');
+
+ $cart_rule = new CartRule($id_cart_rule, Configuration::get('PS_LANG_DEFAULT'));
+ if ((int)$cart_rule->gift_product)
+ $this->updateQty(1, $cart_rule->gift_product, $cart_rule->gift_product_attribute, null, null, 'down');
+
+ return $result;
}
/**
@@ -1051,14 +1058,13 @@ class CartCore extends ObjectModel
AND `id_product_attribute` = '.(int)$id_product_attribute
);
- $customization_quantity = (int)Db::getInstance()->getValue(
- 'SELECT `quantity`
- FROM `'._DB_PREFIX_.'customization`
- WHERE `id_cart` = '.(int)$this->id.'
- AND `id_product` = '.(int)$id_product.'
- AND `id_product_attribute` = '.(int)$id_product_attribute.'
- AND `id_address_delivery` = '.(int)$id_address_delivery
- );
+ $customization_quantity = (int)Db::getInstance()->getValue('
+ SELECT `quantity`
+ FROM `'._DB_PREFIX_.'customization`
+ WHERE `id_cart` = '.(int)$this->id.'
+ AND `id_product` = '.(int)$id_product.'
+ AND `id_product_attribute` = '.(int)$id_product_attribute.'
+ '.((int)$id_address_delivery ? 'AND `id_address_delivery` = '.(int)$id_address_delivery : ''));
if (!$this->_deleteCustomization((int)$id_customization, (int)$id_product, (int)$id_product_attribute))
return false;
@@ -1091,13 +1097,12 @@ class CartCore extends ObjectModel
);
/* Product deletion */
- $result = Db::getInstance()->execute(
- 'DELETE FROM `'._DB_PREFIX_.'cart_product`
- WHERE `id_product` = '.(int)$id_product.
- (!is_null($id_product_attribute) ? ' AND `id_product_attribute` = '.(int)$id_product_attribute : '').'
- AND `id_cart` = '.(int)$this->id.'
- AND `id_address_delivery` = '.(int)$id_address_delivery
- );
+ $result = Db::getInstance()->execute('
+ DELETE FROM `'._DB_PREFIX_.'cart_product`
+ WHERE `id_product` = '.(int)$id_product.'
+ '.(!is_null($id_product_attribute) ? ' AND `id_product_attribute` = '.(int)$id_product_attribute : '').'
+ AND `id_cart` = '.(int)$this->id.'
+ '.((int)$id_address_delivery ? 'AND `id_address_delivery` = '.(int)$id_address_delivery : ''));
if ($result)
{
diff --git a/classes/CartRule.php b/classes/CartRule.php
index 6118deda4..4fcf5ff9e 100644
--- a/classes/CartRule.php
+++ b/classes/CartRule.php
@@ -55,6 +55,7 @@ class CartRuleCore extends ObjectModel
public $reduction_currency;
public $reduction_product;
public $gift_product;
+ public $gift_product_attribute;
public $active = 1;
public $date_add;
public $date_upd;
@@ -93,6 +94,7 @@ class CartRuleCore extends ObjectModel
'reduction_currency' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
'reduction_product' => array('type' => self::TYPE_INT, 'validate' => 'isInt'),
'gift_product' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
+ 'gift_product_attribute' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
'active' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
'date_add' => array('type' => self::TYPE_DATE, 'validate' => 'isDate'),
'date_upd' => array('type' => self::TYPE_DATE, 'validate' => 'isDate'),
@@ -463,24 +465,31 @@ class CartRuleCore extends ObjectModel
// If a product is given for free in this rule and already in the cart, the price is subtracted
if ($this->gift_product)
{
- $in_cart = (bool)Db::getInstance()->getValue('SELECT id_product FROM '._DB_PREFIX_.'cart_product WHERE id_product = '.(int)$this->gift_product.' AND id_cart = '.(int)$context->cart->id);
+ $in_cart = (bool)Db::getInstance()->getValue('
+ SELECT id_product
+ FROM '._DB_PREFIX_.'cart_product
+ WHERE id_product = '.(int)$this->gift_product.'
+ AND id_product_attribute = '.(int)$this->gift_product_attribute.'
+ AND id_cart = '.(int)$context->cart->id);
if ($in_cart)
{
$ref = false;
$product_price = Product::getPriceStatic(
$this->gift_product,
$this->minimum_amount_tax,
- null, null, null, null, null, null, null,
+ $this->gift_product_attribute,
+ null, null, null, null, null, null,
$context->cart->id_customer ? $context->cart->id_customer : null,
$context->cart->id,
(int)$context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')} ? (int)$context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')} : null,
$ref, null, null,
$context, null
);
+
$cartTotal -= $product_price;
}
}
-
+
if ($cartTotal < $minimum_amount)
return Tools::displayError('You do not reach the minimum amount required to use this voucher');
}
@@ -762,10 +771,10 @@ class CartRuleCore extends ObjectModel
}
// Free gift
- if ($this->gift_product)
+ if ((int)$this->gift_product)
{
foreach ($context->cart->getProducts() as $product)
- if ($product['id_product'] == $this->gift_product)
+ if ($product['id_product'] == $this->gift_product && $product['id_product_attribute'] == $this->gift_product_attribute)
$reduction_value += ($useTax ? $product['price_wt'] : $product['price']);
}
diff --git a/controllers/admin/AdminCartRulesController.php b/controllers/admin/AdminCartRulesController.php
index 58ccb1d08..17108e45e 100644
--- a/controllers/admin/AdminCartRulesController.php
+++ b/controllers/admin/AdminCartRulesController.php
@@ -57,6 +57,10 @@ class AdminCartRulesControllerCore extends AdminController
foreach (array('country', 'carrier', 'group', 'cart_rule', 'product', 'shop') as $type)
if (!Tools::getValue($type.'_restriction'))
$_POST[$type.'_restriction'] = 0;
+
+ // Retrieve the product attribute id of the gift (if available)
+ if ($id_product = (int)Tools::getValue('gift_product'))
+ $_POST['gift_product_attribute'] = (int)Tools::getValue('ipa_'.$id_product);
// Idiot-proof control
if (strtotime(Tools::getValue('date_from')) > strtotime(Tools::getValue('date_to')))
@@ -330,6 +334,51 @@ class AdminCartRulesControllerCore extends AdminController
die(Tools::jsonEncode($products));
}
}
+
+ protected function searchProducts($search)
+ {
+ if ($products = Product::searchByName((int)$this->context->language->id, $search))
+ {
+ foreach ($products as &$product)
+ {
+ // Formatted price
+ $combinations = array();
+ $productObj = new Product((int)$product['id_product'], false, (int)$this->context->language->id);
+ $attributes = $productObj->getAttributesGroups((int)$this->context->language->id);
+ $product['formatted_price'] = Tools::displayPrice(Tools::convertPrice($product['price_tax_incl'], $this->context->currency), $this->context->currency);
+
+ foreach ($attributes as $attribute)
+ {
+ if (!isset($combinations[$attribute['id_product_attribute']]['attributes']))
+ $combinations[$attribute['id_product_attribute']]['attributes'] = '';
+ $combinations[$attribute['id_product_attribute']]['attributes'] .= $attribute['attribute_name'].' - ';
+ $combinations[$attribute['id_product_attribute']]['id_product_attribute'] = $attribute['id_product_attribute'];
+ $combinations[$attribute['id_product_attribute']]['default_on'] = $attribute['default_on'];
+ if (!isset($combinations[$attribute['id_product_attribute']]['price']))
+ {
+ $price_tax_incl = Product::getPriceStatic((int)$product['id_product'], true, $attribute['id_product_attribute']);
+ $combinations[$attribute['id_product_attribute']]['formatted_price'] = Tools::displayPrice(Tools::convertPrice($price_tax_incl, $this->context->currency), $this->context->currency);
+ }
+ }
+
+ foreach ($combinations as &$combination)
+ $combination['attributes'] = rtrim($combination['attributes'], ' - ');
+ $product['combinations'] = $combinations;
+ }
+ return array(
+ 'products' => $products,
+ 'found' => true
+ );
+ }
+ else
+ return array('found' => false, 'notfound' => Tools::displayError('No product found'));
+ }
+
+ public function ajaxProcessSearchProducts()
+ {
+ $array = $this->searchProducts(Tools::getValue('product_search'));
+ $this->content = trim(Tools::jsonEncode($array));
+ }
public function renderForm()
{
@@ -343,6 +392,7 @@ class AdminCartRulesControllerCore extends AdminController
);
// Todo: change for "Media" version
+ $this->addJs(_PS_JS_DIR_.'jquery/plugins/jquery.typewatch.js');
$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');
@@ -359,19 +409,19 @@ class AdminCartRulesControllerCore extends AdminController
$gift_product_filter = '';
if (Validate::isUnsignedId($current_object->gift_product) &&
- ($product = new Product($current_object->gift_product, false, Context::getContext()->language->id)) &&
+ ($product = new Product($current_object->gift_product, false, $this->context->language->id)) &&
Validate::isLoadedObject($product))
$gift_product_filter = trim($product->reference.' '.$product->name);
$reduction_product_filter = '';
if (Validate::isUnsignedId($current_object->reduction_product) &&
- ($product = new Product($current_object->reduction_product, false, Context::getContext()->language->id)) &&
+ ($product = new Product($current_object->reduction_product, false, $this->context->language->id)) &&
Validate::isLoadedObject($product))
$reduction_product_filter = trim($product->reference.' '.$product->name);
$product_rule_groups = $this->getProductRuleGroupsDisplay($current_object);
- $attribute_groups = AttributeGroup::getAttributesGroups(Context::getContext()->language->id);
+ $attribute_groups = AttributeGroup::getAttributesGroups($this->context->language->id);
$currencies = Currency::getCurrencies();
$languages = Language::getLanguages();
$countries = $current_object->getAssociatedRestrictions('country', true, true);
@@ -384,8 +434,35 @@ class AdminCartRulesControllerCore extends AdminController
foreach ($carrier as $field => &$value)
if ($field == 'name' && $value == '0')
$value = Configuration::get('PS_SHOP_NAME');
+
+ $gift_product_select = '';
+ $gift_product_attribute_select = '';
+ if ((int)$current_object->gift_product)
+ {
+ $search_products = $this->searchProducts($gift_product_filter);
+ foreach ($search_products['products'] as $product)
+ {
+ $gift_product_select .= '
+ ';
+
+ if (count($product['combinations']))
+ {
+ $gift_product_attribute_select .= '';
+ }
+ }
+ }
- Context::getContext()->smarty->assign(
+ $this->context->smarty->assign(
array(
'show_toolbar' => true,
'toolbar_btn' => $this->toolbar_btn,
@@ -395,6 +472,8 @@ class AdminCartRulesControllerCore extends AdminController
'defaultDateTo' => date('Y-m-d H:00:00', strtotime('+1 month')),
'customerFilter' => $customer_filter,
'giftProductFilter' => $gift_product_filter,
+ 'gift_product_select' => $gift_product_select,
+ 'gift_product_attribute_select' => $gift_product_attribute_select,
'reductionProductFilter' => $reduction_product_filter,
'defaultCurrency' => Configuration::get('PS_CURRENCY_DEFAULT'),
'defaultLanguage' => Configuration::get('PS_LANG_DEFAULT'),
@@ -424,7 +503,7 @@ class AdminCartRulesControllerCore extends AdminController
public function displayAjaxSearchCartRuleVouchers()
{
$found = false;
- if ($vouchers = CartRule::getCartsRuleByCode(Tools::getValue('q'), (int)Context::getContext()->cookie->id_lang))
+ if ($vouchers = CartRule::getCartsRuleByCode(Tools::getValue('q'), (int)$this->context->language->id))
$found = true;
echo Tools::jsonEncode(array('found' => $found, 'vouchers' => $vouchers));
}
diff --git a/install-dev/data/db_structure.sql b/install-dev/data/db_structure.sql
index ce4226bd1..b769977bd 100644
--- a/install-dev/data/db_structure.sql
+++ b/install-dev/data/db_structure.sql
@@ -224,6 +224,7 @@ CREATE TABLE `PREFIX_cart_rule` (
`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,
+ `gift_product_attribute` 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,
diff --git a/install-dev/upgrade/sql/1.5.0.6.sql b/install-dev/upgrade/sql/1.5.0.6.sql
index 2b7bbc3ff..8a019a79b 100644
--- a/install-dev/upgrade/sql/1.5.0.6.sql
+++ b/install-dev/upgrade/sql/1.5.0.6.sql
@@ -9,4 +9,6 @@ SET o.`current_state` = (
LIMIT 1
);
+ALTER TABLE `PREFIX_cart_rule` ADD `gift_product_attribute` int(10) unsigned NOT NULL default 0 AFTER `gift_product`;
+
UPDATE `PREFIX_product` set is_virtual = 1 WHERE id_product IN (SELECT id_product FROM `PREFIX_product_download` WHERE active = 1);
diff --git a/translations/fr/admin.php b/translations/fr/admin.php
index 17e9bb1be..8d293aafb 100644
--- a/translations/fr/admin.php
+++ b/translations/fr/admin.php
@@ -3032,7 +3032,9 @@ $_LANGADM['AdminCartRules00d23a76e43b46dae9ec7aa9dcbebb32'] = 'Activé';
$_LANGADM['AdminCartRulesb9f5c797ebbf55adccdd8539a65a0241'] = 'Désactivé';
$_LANGADM['AdminCartRulesfc6341fa76fe93b837d748563e0a60c1'] = 'Appliquer une réduction';
$_LANGADM['AdminCartRulesda73ea07f51049046d527dabd85170e1'] = 'En pourcent (%)';
+$_LANGADM['AdminCartRulesb2f40690858b404ed10e62bdf422c704'] = 'Montant';
$_LANGADM['AdminCartRules6adf97f83acf6453d4a6a4b1070f3754'] = 'Aucune';
+$_LANGADM['AdminCartRules689202409e48743b914713f96d93947c'] = 'Valeur';
$_LANGADM['AdminCartRulesde11e2e4296bb20487b6430508866e06'] = 'Ne s\'applique pas aux frais de ports';
$_LANGADM['AdminCartRulesbefcac0f9644a7abee43e69f49252ac4'] = 'HT';
$_LANGADM['AdminCartRulesf4a0d7cb0cd45214c8ca5912c970de13'] = 'TTC';
@@ -3043,6 +3045,9 @@ $_LANGADM['AdminCartRules8bab8ac32605948e59399033c7606222'] = 'Le produit le moi
$_LANGADM['AdminCartRules8cfdac16c15c9b130f26ca1d275035a0'] = 'Le(s) produit(s) sélectionné(s)';
$_LANGADM['AdminCartRulesdeb10517653c255364175796ace3553f'] = 'Produit';
$_LANGADM['AdminCartRules2f73d13f0a878086ce1f9933aed3ac80'] = 'Offrir un cadeau';
+$_LANGADM['AdminCartRulesc5f17f7ca53d9225478fdbfd0a5583ac'] = 'Rechercher un produit';
+$_LANGADM['AdminCartRules635c8dcb5a9c7f405ebf10ee3351a158'] = 'Produits';
+$_LANGADM['AdminCartRules34b9126c1ba9f3b131875a8da7b426c4'] = 'Déclinaisons';
$_LANGADM['AdminCartRules8f36b08eb9ebba13ef930c9dd719ff7c'] = 'Limiter à un seul client';
$_LANGADM['AdminCartRules5e60b472b57279a00a961e1e93fa0802'] = 'Facultatif : la règle panier sera disponible pour tout le monde si vous laissez ce champ vide.';
$_LANGADM['AdminCartRulesb07cc2801693b2e722906a3db3d9c447'] = 'Validité';
diff --git a/translations/fr/errors.php b/translations/fr/errors.php
index 3ddadd1f6..ce161484e 100644
--- a/translations/fr/errors.php
+++ b/translations/fr/errors.php
@@ -267,6 +267,7 @@ $_ERRORS['eedef2c356c6598d1c1c35c30459ba3c'] = 'Le bon de réduction ne peut ter
$_ERRORS['9eafdd415e82973f24b7af6580ff15de'] = 'Le montant minimum ne peut être inférieur à 0';
$_ERRORS['ed6f33d6a5ac4b1e0f37e9ccd6e6a96e'] = 'Le pourcentage de réduction doit être entre 0% et 100%';
$_ERRORS['8c9b12ce6c7cf8bc520d01e89b358c60'] = 'Le montant de la réduction ne peut être inférieur à 0';
+$_ERRORS['44fb451a35a1c382da79166dc8c78e43'] = 'Aucun produit trouvé';
$_ERRORS['c1a4c1b929c4f5c81f80ece2d7b196aa'] = 'Produit non valable';
$_ERRORS['e5b55dc69d10c8673f9d5db587591526'] = 'Combinaison invalide';
$_ERRORS['b59e4337db2c711a88aa5756f86c682e'] = 'Une commande a déjà été passée avec ce panier';