Jump to content

Cart rules problem with multishop


Recommended Posts

I'm configuring a multishop (3 shops) using PS 1.5.6.2

 

I have problem with cart rules:

I created three cart rules to give a free item depending on items in the cart, one for each shop.

 

To be more precise:

 

rule 1 is for shop 1

rule 2 is for shop 2

rule 3 is for shop 3

 

rule 1 and 2 are both visible in shop 1, 2 and 3

rule 3 is not visible anywhere.

 

I'm sure the rules are created correctly. I think the problem is in the shop selection routine, because if I change the shop associated to the rule, nothing changes. In the database the rules look correctly associated to the correct shop (ps_cart_rule_shop)

 

Any help?

 

 

Link to comment
Share on other sites

Hello, i had the same issue and i fixed it.

I'm on   PrestaShop™ 1.5.6.1   with a multi-shop configuration (2 shops)

 

You are right, the shop selection routine is a mess.

 

create  the  file    www\override\classes\CartRule.php

<?php

class CartRule extends CartRuleCore
{

	/**
	 * @static
	 * @param $id_lang
	 * @param $id_customer
	 * @param bool $active
	 * @param bool $includeGeneric
	 * @param bool $inStock
	 * @param Cart|null $cart
	 * @return array
	 */
	public static function getCustomerCartRules($id_lang, $id_customer, $active = false, $includeGeneric = true, $inStock = false, Cart $cart = null)
	{

		if (!CartRule::isFeatureActive())
			return array();

		// $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
		// SELECT *
		// 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)$id_lang.')
		// WHERE (
		// 	cr.`id_customer` = '.(int)$id_customer.' OR cr.group_restriction = 1
		// 	'.($includeGeneric ? 'OR cr.`id_customer` = 0' : '').'
		// )
		// AND cr.date_from < "'.date('Y-m-d H:i:s').'"
		// AND cr.date_to > "'.date('Y-m-d H:i:s').'"
		// '.($active ? 'AND cr.`active` = 1' : '').'
		// '.($inStock ? 'AND cr.`quantity` > 0' : ''));

		$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
		SELECT *
		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)$id_lang.')
		LEFT JOIN `'._DB_PREFIX_.'cart_rule_shop` crs ON (cr.`id_cart_rule` = crs.`id_cart_rule`)
		WHERE (
			cr.`id_customer` = '.(int)$id_customer.' OR cr.group_restriction = 1
			'.($includeGeneric ? 'OR cr.`id_customer` = 0' : '').'
		)
		AND  crs.`id_shop` = '.Context::getContext()->shop->id.'
		AND cr.date_from < "'.date('Y-m-d H:i:s').'"
		AND cr.date_to > "'.date('Y-m-d H:i:s').'"
		'.($active ? 'AND cr.`active` = 1' : '').'
		'.($inStock ? 'AND cr.`quantity` > 0' : ''));

		// Remove cart rule that does not match the customer groups
		$customerGroups = Customer::getGroupsStatic($id_customer);
		foreach ($result as $key => $cart_rule)
			if ($cart_rule['group_restriction'])
			{
				$cartRuleGroups = Db::getInstance()->executeS('SELECT id_group FROM '._DB_PREFIX_.'cart_rule_group WHERE id_cart_rule = '.(int)$cart_rule['id_cart_rule']);
				foreach ($cartRuleGroups as $cartRuleGroup)
					if (in_array($cartRuleGroup['id_group'], $customerGroups))
						continue 2;

				unset($result[$key]);
			}

		foreach ($result as &$cart_rule)
			if ($cart_rule['quantity_per_user'])
			{
				$quantity_used = Order::getDiscountsCustomer((int)$id_customer, (int)$cart_rule['id_cart_rule']);
				if (isset($cart) && isset($cart->id))
					$quantity_used += $cart->getDiscountsCustomer((int)$cart_rule['id_cart_rule']);
				$cart_rule['quantity_for_user'] = $cart_rule['quantity_per_user'] - $quantity_used;
			}
			else
				$cart_rule['quantity_for_user'] = 0;
		unset($cart_rule);


		
		foreach ($result as $cart_rule)
			if ($cart_rule['shop_restriction'])
			{
				$cartRuleShops = Db::getInstance()->executeS('SELECT id_shop FROM '._DB_PREFIX_.'cart_rule_shop WHERE id_cart_rule = '.(int)$cart_rule['id_cart_rule']);

				foreach ($cartRuleShops as $cartRuleShop){
					if (Shop::isFeatureActive() && ($cartRuleShop['id_shop'] == Context::getContext()->shop->id)){
						continue 2;
					}
				}
				unset($result[$key]);
			}


		// Retrocompatibility with 1.4 discounts
		foreach ($result as &$cart_rule)
		{
			$cart_rule['value'] = 0;
			$cart_rule['minimal'] = $cart_rule['minimum_amount'];
			$cart_rule['cumulable'] = !$cart_rule['cart_rule_restriction'];
			$cart_rule['id_discount_type'] = false;
			if ($cart_rule['free_shipping'])
				$cart_rule['id_discount_type'] = Discount::FREE_SHIPPING;
			elseif ($cart_rule['reduction_percent'] > 0)
			{
				$cart_rule['id_discount_type'] = Discount::PERCENT;
				$cart_rule['value'] = $cart_rule['reduction_percent'];
			}
			elseif ($cart_rule['reduction_amount'] > 0)
			{
				$cart_rule['id_discount_type'] = Discount::AMOUNT;
				$cart_rule['value'] = $cart_rule['reduction_amount'];
			}
		}

		return $result;
	}

}

I have only modified the sql Query to get the cart rules with the shop id as a parameter.

It work fine for me now.

ps : don't forget to erase the file www/cache/class_index.php

 

All the best

Ben

  • Like 1
Link to comment
Share on other sites

  • 2 weeks later...

Hello, I don't think this fix is the best because if you look a the code in this function, the program works like :

1 - retrieve all the active and available cart rules.

2 - do a loop to remove  all the cart rules that does not match the customer groups.

3 - do a loop to remove  a cart rule if the customer has exedeed the allowed quantity per customer.

4 - do a final loop to remove all the cart rules that does not match with the shop id (this part doesn't work)

 

My solution is applied to the first step of the function (the SQL query).

It's makes the 4th step useless.

 

Instead of changing the SQL query, the cleanest way to fix this problem is to rewrite the loop in the 4th step.

 

Someday I will try to debug this loop and commit a solid fix to gitHub.

 

edit : you should see this commit :

https://github.com/PrestaShop/PrestaShop/commit/79cba4b655aef64d7dac144db767e58939ad08d8

 

All the best

Ben

Edited by benamou2014 (see edit history)
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...