[-] Project : #PSFV-820 - Cartrules are now reapplied each time we add/remove a product on/from the cart

This commit is contained in:
mDeflotte
2012-04-19 09:39:14 +00:00
parent 264cce99c2
commit 0cb73f9e13
6 changed files with 80 additions and 50 deletions
+6 -5
View File
@@ -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;
}
+46 -35
View File
@@ -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;
}
}
@@ -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(),
)
);
+3 -3
View File
@@ -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');
+16 -3
View File
@@ -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;
}
}
}
}
}
@@ -71,7 +71,7 @@
{/if}
</div>
<input type="hidden" value="{if $quantityDisplayed == 0 AND isset($customizedDatas.$productId.$productAttributeId)}{$customizedDatas.$productId.$productAttributeId|@count}{else}{$product.cart_quantity-$quantityDisplayed}{/if}" name="quantity_{$product.id_product}_{$product.id_product_attribute}_0_{$product.id_address_delivery|intval}_hidden" />
<input size="2" type="text" class="cart_quantity_input" value="{if $quantityDisplayed == 0 AND isset($customizedDatas.$productId.$productAttributeId)}{$customizedDatas.$productId.$productAttributeId|@count}{else}{$product.cart_quantity-$quantityDisplayed}{/if}" name="quantity_{$product.id_product}_{$product.id_product_attribute}_0_{$product.id_address_delivery|intval}" />
<input size="2" type="text" autocomplete="off" class="cart_quantity_input" value="{if $quantityDisplayed == 0 AND isset($customizedDatas.$productId.$productAttributeId)}{$customizedDatas.$productId.$productAttributeId|@count}{else}{$product.cart_quantity-$quantityDisplayed}{/if}" name="quantity_{$product.id_product}_{$product.id_product_attribute}_0_{$product.id_address_delivery|intval}" />
{/if}
{/if}