diff --git a/classes/Cart.php b/classes/Cart.php
index b1cfae764..ef572c2fd 100644
--- a/classes/Cart.php
+++ b/classes/Cart.php
@@ -724,7 +724,7 @@ class CartCore extends ObjectModel
Cache::clean('Cart::getCartRules'.$this->id);
if ((int)$cartRule->gift_product)
- $this->updateQty(1, $cartRule->gift_product, $cartRule->gift_product_attribute);
+ $this->updateQty(1, $cartRule->gift_product, $cartRule->gift_product_attribute, false, 0, 'up', null, false);
return true;
}
@@ -761,7 +761,7 @@ class CartCore extends ObjectModel
* @param string $operator Indicate if quantity must be increased or decreased
*/
public function updateQty($quantity, $id_product, $id_product_attribute = null, $id_customization = false,
- $id_address_delivery = 0, $operator = 'up', Shop $shop = null)
+ $id_address_delivery = 0, $operator = 'up', Shop $shop = null, $auto_add_cart_rule = true)
{
if (!$shop)
$shop = Context::getContext()->shop;
@@ -853,7 +853,7 @@ class CartCore extends ObjectModel
);
}
/* Add product to the cart */
- else
+ elseif ($operator == 'up')
{
$sql = 'SELECT stock.out_of_stock, IFNULL(stock.quantity, 0) as quantity
FROM '._DB_PREFIX_.'product p
@@ -893,7 +893,8 @@ class CartCore extends ObjectModel
$this->update(true);
$context = Context::getContext()->cloneContext();
$context->cart = $this;
- CartRule::autoAddToCart($context);
+ if ($auto_add_cart_rule)
+ CartRule::autoAddToCart($context);
if ($product->customizable)
return $this->_updateCustomizationQuantity((int)$quantity, (int)$id_customization, (int)$id_product, (int)$id_product_attribute, (int)$id_address_delivery, $operator);
@@ -1049,7 +1050,7 @@ class CartCore extends ObjectModel
$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');
+ $this->updateQty(1, $cart_rule->gift_product, $cart_rule->gift_product_attribute, null, null, 'down', null, false);
return $result;
}
diff --git a/classes/CartRule.php b/classes/CartRule.php
index 16594ecfd..c45b1fff8 100644
--- a/classes/CartRule.php
+++ b/classes/CartRule.php
@@ -361,22 +361,23 @@ class CartRuleCore extends ObjectModel
* Check if this cart rule can be applied
*
* @param Context $context
- * @param bool $alreadyInCart
+ * @param bool $alreadyInCart Check if the voucher is already on the cart
+ * @param bool $display_error Display error
* @return bool|mixed|string
*/
- public function checkValidity(Context $context, $alreadyInCart = false)
+ public function checkValidity(Context $context, $alreadyInCart = false, $display_error = true)
{
if (!CartRule::isFeatureActive())
return false;
if (!$this->active)
- return Tools::displayError('This voucher is disabled');
+ return (!$display_error) ? false : Tools::displayError('This voucher is disabled');
if (!$this->quantity)
- return Tools::displayError('This voucher has already been used');
+ return (!$display_error) ? false : Tools::displayError('This voucher has already been used');
if (strtotime($this->date_from) > time())
- return Tools::displayError('This voucher is not valid yet');
+ return (!$display_error) ? false : Tools::displayError('This voucher is not valid yet');
if (strtotime($this->date_to) < time())
- return Tools::displayError('This voucher has expired');
+ return (!$display_error) ? false : Tools::displayError('This voucher has expired');
if ($context->cart->id_customer)
{
@@ -394,7 +395,7 @@ class CartRuleCore extends ObjectModel
LIMIT 1
)');
if ($quantityUsed + 1 > $this->quantity_per_user)
- return Tools::displayError('You cannot use this voucher anymore (usage limit reached)');
+ return (!$display_error) ? false : Tools::displayError('You cannot use this voucher anymore (usage limit reached)');
}
$otherCartRules = $context->cart->getCartRules();
@@ -402,8 +403,8 @@ class CartRuleCore extends ObjectModel
foreach ($otherCartRules as $otherCartRule)
{
if ($otherCartRule['id_cart_rule'] == $this->id && !$alreadyInCart)
- return Tools::displayError('This voucher is already in your cart');
- if ($this->cart_rule_restriction && $otherCartRule['cart_rule_restriction'])
+ return (!$display_error) ? false : Tools::displayError('This voucher is already in your cart');
+ if ($this->cart_rule_restriction && $otherCartRule['cart_rule_restriction'] && $otherCartRule['id_cart_rule'] != $this->id)
{
$combinable = Db::getInstance()->getValue('
SELECT id_cart_rule_1
@@ -413,7 +414,7 @@ class CartRuleCore extends ObjectModel
if (!$combinable)
{
$cart_rule = 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:').' '.$cart_rule->name;
+ return (!$display_error) ? false : Tools::displayError('This voucher is not combinable with an other voucher already in your cart:').' '.$cart_rule->name;
}
}
}
@@ -427,7 +428,7 @@ class CartRuleCore extends ObjectModel
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');
+ return (!$display_error) ? false : Tools::displayError('You cannot use this voucher');
}
// Check if the customer delivery address is usable with the cart rule
@@ -439,7 +440,7 @@ class CartRuleCore extends ObjectModel
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');
+ return (!$display_error) ? false : 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
@@ -451,7 +452,7 @@ class CartRuleCore extends ObjectModel
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');
+ return (!$display_error) ? false : Tools::displayError('You cannot use this voucher with this carrier');
}
// Check if the cart rules appliy to the shop browsed by the customer
@@ -463,23 +464,25 @@ class CartRuleCore extends ObjectModel
WHERE crs.id_cart_rule = '.(int)$this->id.'
AND crs.id_shop = '.(int)$context->shop->id);
if (!$id_cart_rule)
- return Tools::displayError('You cannot use this voucher');
+ return (!$display_error) ? false : Tools::displayError('You cannot use this voucher');
}
// Check if the products chosen by the customer are usable with the cart rule
if ($this->product_restriction)
{
- $r = $this->checkProductRestrictions($context, false);
- if ($r !== false)
+ $r = $this->checkProductRestrictions($context, false, $display_error);
+ if ($r !== false && $display_error)
return $r;
+ elseif (!$r && !$display_error)
+ return false;
}
// 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');
+ return (!$display_error) ? false : (Tools::displayError('You cannot use this voucher').' - '.Tools::displayError('Please log in'));
+ return (!$display_error) ? false : Tools::displayError('You cannot use this voucher');
}
if ($this->minimum_amount)
@@ -528,11 +531,13 @@ class CartRuleCore extends ObjectModel
}
if ($cartTotal < $minimum_amount)
- return Tools::displayError('You have not reached the minimum amount required to use this voucher');
+ return (!$display_error) ? false : Tools::displayError('You have not reached the minimum amount required to use this voucher');
}
+ if (!$display_error)
+ return true;
}
- protected function checkProductRestrictions(Context $context, $return_products = false)
+ protected function checkProductRestrictions(Context $context, $return_products = false, $display_error = true)
{
$selectedProducts = array();
@@ -568,7 +573,7 @@ class CartRuleCore extends ObjectModel
$matchingProductsList[] = $cartAttribute['id_product'].'-'.$cartAttribute['id_product_attribute'];
}
if ($countMatchingProducts < $productRuleGroup['quantity'])
- return Tools::displayError('You cannot use this voucher with these products');
+ return (!$display_error) ? false : Tools::displayError('You cannot use this voucher with these products');
$eligibleProductsList = array_uintersect($eligibleProductsList, $matchingProductsList, 'cartrule_products_intersect');
break;
case 'products':
@@ -586,7 +591,7 @@ class CartRuleCore extends ObjectModel
$matchingProductsList[] = $cartProduct['id_product'].'-0';
}
if ($countMatchingProducts < $productRuleGroup['quantity'])
- return Tools::displayError('You cannot use this voucher with these products');
+ return (!$display_error) ? false : Tools::displayError('You cannot use this voucher with these products');
$eligibleProductsList = array_uintersect($eligibleProductsList, $matchingProductsList, 'cartrule_products_intersect');
break;
case 'categories':
@@ -605,7 +610,7 @@ class CartRuleCore extends ObjectModel
$matchingProductsList[] = $cartCategory['id_product'].'-0';
}
if ($countMatchingProducts < $productRuleGroup['quantity'])
- return Tools::displayError('You cannot use this voucher with these products');
+ return (!$display_error) ? false : Tools::displayError('You cannot use this voucher with these products');
$eligibleProductsList = array_uintersect($eligibleProductsList, $matchingProductsList, 'cartrule_products_intersect');
break;
case 'manufacturers':
@@ -624,7 +629,7 @@ class CartRuleCore extends ObjectModel
$matchingProductsList[] = $cartManufacturer['id_product'].'-0';
}
if ($countMatchingProducts < $productRuleGroup['quantity'])
- return Tools::displayError('You cannot use this voucher with these products');
+ return (!$display_error) ? false : Tools::displayError('You cannot use this voucher with these products');
$eligibleProductsList = array_uintersect($eligibleProductsList, $matchingProductsList, 'cartrule_products_intersect');
break;
case 'suppliers':
@@ -643,13 +648,13 @@ class CartRuleCore extends ObjectModel
$matchingProductsList[] = $cartSupplier['id_product'].'-0';
}
if ($countMatchingProducts < $productRuleGroup['quantity'])
- return Tools::displayError('You cannot use this voucher with these products');
+ return (!$display_error) ? false : Tools::displayError('You cannot use this voucher with these products');
$eligibleProductsList = array_uintersect($eligibleProductsList, $matchingProductsList, 'cartrule_products_intersect');
break;
}
if (!count($eligibleProductsList))
- return Tools::displayError('You cannot use this voucher with these products');
+ return (!$display_error) ? false : Tools::displayError('You cannot use this voucher with these products');
}
$selectedProducts = array_merge($selectedProducts, $eligibleProductsList);
}
@@ -657,7 +662,7 @@ class CartRuleCore extends ObjectModel
if ($return_products)
return $selectedProducts;
- return false;
+ return ($display_error) ? true : false;
}
/**
@@ -938,7 +943,6 @@ class CartRuleCore extends ObjectModel
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 : '').'
@@ -975,8 +979,15 @@ class CartRuleCore extends ObjectModel
// Todo: consider optimization (we can avoid many queries in checkValidity)
foreach ($cartRules as $cartRule)
- if (!$cartRule->checkValidity($context))
- $context->cart->addCartRule($cartRule->id);
+ if (Db::getInstance()->getValue('SELECT count(*)
+ FROM '._DB_PREFIX_.'cart_cart_rule
+ WHERE id_cart = '.(int)$context->cart->id.'
+ AND id_cart_rule = '.(int)$cartRule->id))
+ $context->cart->removeCartRule($cartRule->id);
+
+ foreach ($cartRules as $cartRule)
+ if ($cartRule->checkValidity($context, true, false))
+ $context->cart->addCartRule($cartRule->id);
}
/**
@@ -1007,13 +1018,13 @@ class CartRuleCore extends ObjectModel
function cartrule_products_intersect($a, $b)
{
- if ($a == $b)
- return 0;
+ if ($a == $b)
+ return 0;
$asplit = explode('-', $a);
$bsplit = explode('-', $b);
- if ($asplit[0] == $bsplit[0] && (!(int)$asplit[1] || !(int)$bsplit[1]))
- return 0;
+ if ($asplit[0] == $bsplit[0] && (!(int)$asplit[1] || !(int)$bsplit[1]))
+ return 0;
return 1;
-}
\ No newline at end of file
+}
diff --git a/controllers/admin/AdminCartRulesController.php b/controllers/admin/AdminCartRulesController.php
index 7611a3c51..3ea7bd11a 100644
--- a/controllers/admin/AdminCartRulesController.php
+++ b/controllers/admin/AdminCartRulesController.php
@@ -168,8 +168,11 @@ class AdminCartRulesControllerCore extends AdminController
{
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.'
+ INSERT IGNORE 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.'
+ AND id_cart_rule != '.(int)$incompatibleRule['id_cart_rule'].'
)');
}
}
@@ -474,6 +477,7 @@ class AdminCartRulesControllerCore extends AdminController
}
}
+ $product = new Product($current_object->gift_product);
$this->context->smarty->assign(
array(
'show_toolbar' => true,
@@ -502,7 +506,8 @@ class AdminCartRulesControllerCore extends AdminController
'currentIndex' => self::$currentIndex,
'currentToken' => $this->token,
'currentObject' => $current_object,
- 'currentTab' => $this
+ 'currentTab' => $this,
+ 'hasAttribute' => $product->hasAttributes(),
)
);
diff --git a/controllers/admin/AdminCartsController.php b/controllers/admin/AdminCartsController.php
index abdf5a8d3..dd32d550b 100755
--- a/controllers/admin/AdminCartsController.php
+++ b/controllers/admin/AdminCartsController.php
@@ -29,7 +29,7 @@ class AdminCartsControllerCore extends AdminController
{
public function __construct()
{
- $this->table = 'cart';
+ $this->table = 'cart';
$this->className = 'Cart';
$this->lang = false;
$this->requiredDatabase = true;
@@ -44,7 +44,7 @@ class AdminCartsControllerCore extends AdminController
LEFT JOIN '._DB_PREFIX_.'orders o ON (o.id_cart = a.id_cart)
LEFT JOIN `'._DB_PREFIX_.'connections` co ON (a.id_guest = co.id_guest AND TIME_TO_SEC(TIMEDIFF(NOW(), co.`date_add`)) < 1800)';
- $this->fields_list = array(
+ $this->fields_list = array(
'id_cart' => array(
'title' => $this->l('ID'),
'align' => 'center',
@@ -149,7 +149,7 @@ class AdminCartsControllerCore extends AdminController
$image = Db::getInstance()->getRow('SELECT id_image
FROM '._DB_PREFIX_.'product_attribute_image
WHERE id_product_attribute = '.(int)$product['id_product_attribute']);
- if (!isset($image['id_image']))
+ if (!isset($image['id_image']))
$image = Db::getInstance()->getRow('SELECT id_image
FROM '._DB_PREFIX_.'image
WHERE id_product = '.(int)$product['id_product'].' AND cover = 1');
diff --git a/controllers/front/CartController.php b/controllers/front/CartController.php
index bf243909c..02901010c 100644
--- a/controllers/front/CartController.php
+++ b/controllers/front/CartController.php
@@ -227,13 +227,26 @@ class CartControllerCore extends FrontController
$minimal_quantity = ($this->id_product_attribute) ? Attribute::getAttributeMinimalQty($this->id_product_attribute) : $product->minimal_quantity;
$this->errors[] = Tools::displayError('You must add', false).' '.$minimal_quantity.' '.Tools::displayError('Minimum quantity', false);
}
- else if (!$updateQuantity)
+ elseif (!$updateQuantity)
$this->errors[] = Tools::displayError('You already have the maximum quantity available for this product.', false);
- else
+ elseif ((int)Tools::getValue('allow_refresh'))
{
+ // If the cart rules has changed, we need to refresh the whole cart
$cart_rules2 = $this->context->cart->getCartRules();
- if (count($cart_rules2) != count($cart_rules) && (int)Tools::getValue('allow_refresh'))
+ if (count($cart_rules2) != count($cart_rules))
$this->ajax_refresh = true;
+ else
+ {
+ $rule_list = array();
+ foreach ($cart_rules2 as $rule)
+ $rule_list[] = $rule['id_cart_rule'];
+ foreach ($cart_rules as $rule)
+ if (!in_array($rule['id_cart_rule'], $rule_list))
+ {
+ $this->ajax_refresh = true;
+ break;
+ }
+ }
}
}
}
diff --git a/themes/default/shopping-cart-product-line.tpl b/themes/default/shopping-cart-product-line.tpl
index 2dab8400d..e4ca798ee 100644
--- a/themes/default/shopping-cart-product-line.tpl
+++ b/themes/default/shopping-cart-product-line.tpl
@@ -71,7 +71,7 @@
{/if}
-
+
{/if}
{/if}