Jump to content

Make Cart rules incompatible with "specific price"


Recommended Posts

Hi everyone,

 

so that is the problem: I have put my shop on sale by defining a specific price (lower) for a number of products.

Also I have an active Cart Rule to apply a discount of 10% on the whole order if a specific code is given.

 

What I'd like to do is to NOT apply the 10% discount on "on sale" products.

Both of follow option could be acceptable:

1- Discount is not applied if one (or more) "on sale" products are present in the order product list.

2- Discount is applies only on products that are not in the "on sale" mode, within the product order list.

 

I wasn't be able to achieve any of them nor to identify which class is calculating the discount (in order to skip "on sale" products during calculation)

 

Any suggestion?

 

Thanks!

Link to comment
Share on other sites

  • 3 weeks later...

OK partially solved.

 

My CartRule is of the type: % discount on whole cart.

 

Editing the file: classes/CartRule.php line 784

 

after this code:

// Do not give a reduction on free products!
$order_total = $context->cart->getOrderTotal($use_tax, Cart::ONLY_PRODUCTS, $package_products);
  foreach ($context->cart->getCartRules(CartRule::FILTER_ACTION_GIFT) as $cart_rule)
		$order_total -= Tools::ps_round($cart_rule['obj']->getContextualValue($use_tax, $context, CartRule::FILTER_ACTION_G	IFT, $package), 2);

 

I add this lines:

 

foreach ($package_products as $product)
  if($product['on_sale'])
		$order_total -= $use_tax ? $product['total_wt'] : $product['total'];

 

It will then subtract price of product 'on_sale' from the total used to calculate discount.

 

It is a perfect solution but, waiting for an official "not compatible" option...

 

By the way, how can I edit the topic Title to mark as, at least "partially solved" ?

Edited by nandosan (see edit history)
  • Like 2
Link to comment
Share on other sites

  • 2 months later...

Dear Forum,

 

I use 1.5.1 version and I tried to copy/paste the code Nandosan suggested to solve this problem, but it doesn't work for me. The code looks like this now:

 

// Discount (%) on the whole order
if ($this->reduction_percent && $this->reduction_product == 0)
{
// Do not give a reduction on free products!
$order_total = $context->cart->getOrderTotal($use_tax, Cart::ONLY_PRODUCTS, $package_products);


foreach ($context->cart->getCartRules(CartRule::FILTER_ACTION_GIFT) as $cart_rule)
$order_total -= Tools::ps_round($cart_rule['obj']->getContextualValue($use_tax, $context, CartRule::FILTER_ACTION_GIFT, $package), 2);


foreach ($package_products as $product)
  if($product['on_sale'])
$order_total -= $use_tax ? $product['total_wt'] : $product['total'];


$reduction_value += $order_total * $this->reduction_percent / 100;
}

but my site keeps on applying discounts on 'on_sale' products.

 

Can you help please?

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

The "on_sale" status is setted by the associated   checkmark in the product price tab.

It quite independent from the special price applied, meaning you can have a product "on_sale" but with reduction in its price.

 

Have you checked that?

  • Like 1
Link to comment
Share on other sites

Thank you Nandosan, you are very kind  :)

 

I have the italian version of prestashop. I guess layout could be the same in every language so here's a screenshot of my price tag. As you can see the only checkbox is ticked. The translation to english of the checkbox could be: "Show 'On sale' icon in product page and the text in product list".

 

Is this one to be checked?

 

 

prodotto_sconto.jpg

 

If this is the only checkbox I have to tick, then I did it, but still calculate 15% discount when reaching 100 euros spent...

 

Here's my discount settings screenshot:

 

info.jpg

 

 

condizioni.jpg

 

azioni.jpg

Thanks so much!

 

Luca

Link to comment
Share on other sites

It didn't work for me on 1.5.5

I solved in this other way:

 

In classes/Cart.php I copied the "public function getOrderTotal" and I called it "getOrderTotalWithoutOnSaleProducts". In this new method I changed those lines adding a control to skip on_sale ones:

foreach ($products as $product) // products refer to the cart details
{
			
if (!$product['on_sale']) {
				
etc. etc.

Then in classes/CartRule.php I used it instead of the old one:

// Discount (%) on the whole order
	if ($this->reduction_percent && $this->reduction_product == 0)
	{
	// Do not give a reduction on free products!
	$order_total = $context->cart->getOrderTotalWithoutOnSaleProducts($use_tax, Cart::ONLY_PRODUCTS, $package_products);
				

I made this change only for percentage discount on the whole order. 

 

Hope that helps!

nimloth

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

  • 3 months later...

Here both the methods: 

public function getOrderTotal($with_taxes = true, $type = Cart::BOTH, $products = null, $id_carrier = null, $use_cache = true)
	{
		if (!$this->id)
			return 0;

		$type = (int)$type;
		$array_type = array(
			Cart::ONLY_PRODUCTS,
			Cart::ONLY_DISCOUNTS,
			Cart::BOTH,
			Cart::BOTH_WITHOUT_SHIPPING,
			Cart::ONLY_SHIPPING,
			Cart::ONLY_WRAPPING,
			Cart::ONLY_PRODUCTS_WITHOUT_SHIPPING,
			Cart::ONLY_PHYSICAL_PRODUCTS_WITHOUT_SHIPPING,
		);
		
		// Define virtual context to prevent case where the cart is not the in the global context
		$virtual_context = Context::getContext()->cloneContext();
		$virtual_context->cart = $this;

		if (!in_array($type, $array_type))
			die(Tools::displayError());

		$with_shipping = in_array($type, array(Cart::BOTH, Cart::ONLY_SHIPPING));
		
		// if cart rules are not used
		if ($type == Cart::ONLY_DISCOUNTS && !CartRule::isFeatureActive())
			return 0;

		// no shipping cost if is a cart with only virtuals products
		$virtual = $this->isVirtualCart();
		if ($virtual && $type == Cart::ONLY_SHIPPING)
			return 0;

		if ($virtual && $type == Cart::BOTH)
			$type = Cart::BOTH_WITHOUT_SHIPPING;

		if ($with_shipping)
		{
			if (is_null($products) && is_null($id_carrier))
				$shipping_fees = $this->getTotalShippingCost(null, (boolean)$with_taxes);
			else
				$shipping_fees = $this->getPackageShippingCost($id_carrier, (int)$with_taxes, null, $products);
		}
		else
			$shipping_fees = 0;

		if ($type == Cart::ONLY_SHIPPING)
			return $shipping_fees;

		if ($type == Cart::ONLY_PRODUCTS_WITHOUT_SHIPPING)
			$type = Cart::ONLY_PRODUCTS;

		$param_product = true;
		if (is_null($products))
		{
			$param_product = false;
			$products = $this->getProducts();
		}
	
		if ($type == Cart::ONLY_PHYSICAL_PRODUCTS_WITHOUT_SHIPPING)
		{
			foreach ($products as $key => $product)
				if ($product['is_virtual'])
					unset($products[$key]);
			$type = Cart::ONLY_PRODUCTS;
		}

		$order_total = 0;
		if (Tax::excludeTaxeOption())
			$with_taxes = false;

		foreach ($products as $product) // products refer to the cart details
		{
		
			if ($virtual_context->shop->id != $product['id_shop'])
				$virtual_context->shop = new Shop((int)$product['id_shop']);

			if (Configuration::get('PS_TAX_ADDRESS_TYPE') == 'id_address_invoice')
				$address_id = (int)$this->id_address_invoice;
			else
				$address_id = (int)$product['id_address_delivery']; // Get delivery address of the product from the cart
			if (!Address::addressExists($address_id))
				$address_id = null;
			
			if ($this->_taxCalculationMethod == PS_TAX_EXC)
			{
				// Here taxes are computed only once the quantity has been applied to the product price
				$price = Product::getPriceStatic(
					(int)$product['id_product'],
					false,
					(int)$product['id_product_attribute'],
					2,
					null,
					false,
					true,
					$product['cart_quantity'],
					false,
					(int)$this->id_customer ? (int)$this->id_customer : null,
					(int)$this->id,
					$address_id,
					$null,
					true,
					true,
					$virtual_context
				);

				$total_ecotax = $product['ecotax'] * (int)$product['cart_quantity'];
				$total_price = $price * (int)$product['cart_quantity'];

				if ($with_taxes)
				{
					$product_tax_rate = (float)Tax::getProductTaxRate((int)$product['id_product'], (int)$address_id, $virtual_context);
					$product_eco_tax_rate = Tax::getProductEcotaxRate((int)$address_id);

					$total_price = ($total_price - $total_ecotax) * (1 + $product_tax_rate / 100);
					$total_ecotax = $total_ecotax * (1 + $product_eco_tax_rate / 100);
					$total_price = Tools::ps_round($total_price + $total_ecotax, 2);
				}
			}
			else
			{
				if ($with_taxes)
					$price = Product::getPriceStatic(
						(int)$product['id_product'],
						true,
						(int)$product['id_product_attribute'],
						2,
						null,
						false,
						true,
						$product['cart_quantity'],
						false,
						((int)$this->id_customer ? (int)$this->id_customer : null),
						(int)$this->id,
						((int)$address_id ? (int)$address_id : null),
						$null,
						true,
						true,
						$virtual_context
					);
				else
					$price = Product::getPriceStatic(
						(int)$product['id_product'],
						false,
						(int)$product['id_product_attribute'],
						2,
						null,
						false,
						true,
						$product['cart_quantity'],
						false,
						((int)$this->id_customer ? (int)$this->id_customer : null),
						(int)$this->id,
						((int)$address_id ? (int)$address_id : null),
						$null,
						true,
						true,
						$virtual_context
					);

				$total_price = Tools::ps_round($price * (int)$product['cart_quantity'], 2);
			}
			$order_total += $total_price;
		}
		
		$order_total_products = $order_total;

		if ($type == Cart::ONLY_DISCOUNTS)
			$order_total = 0;

		// Wrapping Fees
		$wrapping_fees = 0;
		if ($this->gift)
			$wrapping_fees = Tools::convertPrice(Tools::ps_round($this->getGiftWrappingPrice($with_taxes), 2), Currency::getCurrencyInstance((int)$this->id_currency));
		if ($type == Cart::ONLY_WRAPPING)
			return $wrapping_fees;

		$order_total_discount = 0;
		if (!in_array($type, array(Cart::ONLY_SHIPPING, Cart::ONLY_PRODUCTS)) && CartRule::isFeatureActive())
		{
			// First, retrieve the cart rules associated to this "getOrderTotal"
			if ($with_shipping || $type == Cart::ONLY_DISCOUNTS)
				$cart_rules = $this->getCartRules(CartRule::FILTER_ACTION_ALL);
			else
			{
				$cart_rules = $this->getCartRules(CartRule::FILTER_ACTION_REDUCTION);
				// Cart Rules array are merged manually in order to avoid doubles
				foreach ($this->getCartRules(CartRule::FILTER_ACTION_GIFT) as $tmp_cart_rule)
				{
					$flag = false;
					foreach ($cart_rules as $cart_rule)
						if ($tmp_cart_rule['id_cart_rule'] == $cart_rule['id_cart_rule'])
							$flag = true;
					if (!$flag)
						$cart_rules[] = $tmp_cart_rule;
				}
			}
			
			$id_address_delivery = 0;
			if (isset($products[0]))
				$id_address_delivery = (is_null($products) ? $this->id_address_delivery : $products[0]['id_address_delivery']);
			$package = array('id_carrier' => $id_carrier, 'id_address' => $id_address_delivery, 'products' => $products);
			
			// Then, calculate the contextual value for each one
			foreach ($cart_rules as $cart_rule)
			{
				// If the cart rule offers free shipping, add the shipping cost
				if (($with_shipping || $type == Cart::ONLY_DISCOUNTS) && $cart_rule['obj']->free_shipping)
					$order_total_discount += Tools::ps_round($cart_rule['obj']->getContextualValue($with_taxes, $virtual_context, CartRule::FILTER_ACTION_SHIPPING, ($param_product ? $package : null), $use_cache), 2);

				// If the cart rule is a free gift, then add the free gift value only if the gift is in this package
				if ((int)$cart_rule['obj']->gift_product)
				{
					$in_order = false;
					if (is_null($products))
						$in_order = true;
					else
						foreach ($products as $product)
							if ($cart_rule['obj']->gift_product == $product['id_product'] && $cart_rule['obj']->gift_product_attribute == $product['id_product_attribute'])
								$in_order = true;

					if ($in_order)
						$order_total_discount += $cart_rule['obj']->getContextualValue($with_taxes, $virtual_context, CartRule::FILTER_ACTION_GIFT, $package, $use_cache);
				}

				// If the cart rule offers a reduction, the amount is prorated (with the products in the package)
				if ($cart_rule['obj']->reduction_percent > 0 || $cart_rule['obj']->reduction_amount > 0)
					$order_total_discount += Tools::ps_round($cart_rule['obj']->getContextualValue($with_taxes, $virtual_context, CartRule::FILTER_ACTION_REDUCTION, $package, $use_cache), 2);
			}
			$order_total_discount = min(Tools::ps_round($order_total_discount, 2), $wrapping_fees + $order_total_products + $shipping_fees);
			$order_total -= $order_total_discount;
		}

		if ($type == Cart::BOTH)
			$order_total += $shipping_fees + $wrapping_fees;

		if ($order_total < 0 && $type != Cart::ONLY_DISCOUNTS)
			return 0;

		if ($type == Cart::ONLY_DISCOUNTS)
			return $order_total_discount;

		return Tools::ps_round((float)$order_total, 2);
	}

/** AGGIUNTA CUSTOM PER ESCLUDERE DAI VOUCHER I PRODOTTI GIA SCONTATI
	* This function returns the total cart amount with exception of on sale products
	*
	* Possible values for $type:
	* Cart::ONLY_PRODUCTS
	* Cart::ONLY_DISCOUNTS
	* Cart::BOTH
	* Cart::BOTH_WITHOUT_SHIPPING
	* Cart::ONLY_SHIPPING
	* Cart::ONLY_WRAPPING
	* Cart::ONLY_PRODUCTS_WITHOUT_SHIPPING
	* Cart::ONLY_PHYSICAL_PRODUCTS_WITHOUT_SHIPPING
	*
	* @param boolean $withTaxes With or without taxes
	* @param integer $type Total type
	* @param boolean $use_cache Allow using cache of the method CartRule::getContextualValue
	* @return float Order total
	*/
	public function getOrderTotalWithoutOnSaleProducts($with_taxes = true, $type = Cart::BOTH, $products = null, $id_carrier = null, $use_cache = true)
	{
		if (!$this->id)
			return 0;

		$type = (int)$type;
		$array_type = array(
			Cart::ONLY_PRODUCTS,
			Cart::ONLY_DISCOUNTS,
			Cart::BOTH,
			Cart::BOTH_WITHOUT_SHIPPING,
			Cart::ONLY_SHIPPING,
			Cart::ONLY_WRAPPING,
			Cart::ONLY_PRODUCTS_WITHOUT_SHIPPING,
			Cart::ONLY_PHYSICAL_PRODUCTS_WITHOUT_SHIPPING,
		);
		
		// Define virtual context to prevent case where the cart is not the in the global context
		$virtual_context = Context::getContext()->cloneContext();
		$virtual_context->cart = $this;

		if (!in_array($type, $array_type))
			die(Tools::displayError());

		$with_shipping = in_array($type, array(Cart::BOTH, Cart::ONLY_SHIPPING));
		
		// if cart rules are not used
		if ($type == Cart::ONLY_DISCOUNTS && !CartRule::isFeatureActive())
			return 0;

		// no shipping cost if is a cart with only virtuals products
		$virtual = $this->isVirtualCart();
		if ($virtual && $type == Cart::ONLY_SHIPPING)
			return 0;

		if ($virtual && $type == Cart::BOTH)
			$type = Cart::BOTH_WITHOUT_SHIPPING;

		if ($with_shipping)
		{
			if (is_null($products) && is_null($id_carrier))
				$shipping_fees = $this->getTotalShippingCost(null, (boolean)$with_taxes);
			else
				$shipping_fees = $this->getPackageShippingCost($id_carrier, (int)$with_taxes, null, $products);
		}
		else
			$shipping_fees = 0;

		if ($type == Cart::ONLY_SHIPPING)
			return $shipping_fees;

		if ($type == Cart::ONLY_PRODUCTS_WITHOUT_SHIPPING)
			$type = Cart::ONLY_PRODUCTS;

		$param_product = true;
		if (is_null($products))
		{
			$param_product = false;
			$products = $this->getProducts();
		}
	
		if ($type == Cart::ONLY_PHYSICAL_PRODUCTS_WITHOUT_SHIPPING)
		{
			foreach ($products as $key => $product)
				if ($product['is_virtual'])
					unset($products[$key]);
			$type = Cart::ONLY_PRODUCTS;
		}

		$order_total = 0;
		if (Tax::excludeTaxeOption())
			$with_taxes = false;

		foreach ($products as $product) // products refer to the cart details
		{
			if (!$product['on_sale']) {
				if ($virtual_context->shop->id != $product['id_shop'])
					$virtual_context->shop = new Shop((int)$product['id_shop']);

				if (Configuration::get('PS_TAX_ADDRESS_TYPE') == 'id_address_invoice')
					$address_id = (int)$this->id_address_invoice;
				else
					$address_id = (int)$product['id_address_delivery']; // Get delivery address of the product from the cart
				if (!Address::addressExists($address_id))
					$address_id = null;
			
				if ($this->_taxCalculationMethod == PS_TAX_EXC)
				{
					// Here taxes are computed only once the quantity has been applied to the product price
					$price = Product::getPriceStatic(
						(int)$product['id_product'],
						false,
						(int)$product['id_product_attribute'],
						2,
						null,
						false,
						true,
						$product['cart_quantity'],
						false,
						(int)$this->id_customer ? (int)$this->id_customer : null,
						(int)$this->id,
						$address_id,
						$null,
						true,
						true,
						$virtual_context
					);

					$total_ecotax = $product['ecotax'] * (int)$product['cart_quantity'];
					$total_price = $price * (int)$product['cart_quantity'];

					if ($with_taxes)
					{
						$product_tax_rate = (float)Tax::getProductTaxRate((int)$product['id_product'], (int)$address_id, $virtual_context);
						$product_eco_tax_rate = Tax::getProductEcotaxRate((int)$address_id);

						$total_price = ($total_price - $total_ecotax) * (1 + $product_tax_rate / 100);
						$total_ecotax = $total_ecotax * (1 + $product_eco_tax_rate / 100);
						$total_price = Tools::ps_round($total_price + $total_ecotax, 2);
					}
				}
				else
				{
					if ($with_taxes)
						$price = Product::getPriceStatic(
							(int)$product['id_product'],
							true,
							(int)$product['id_product_attribute'],
							2,
							null,
							false,
							true,
							$product['cart_quantity'],
							false,
							((int)$this->id_customer ? (int)$this->id_customer : null),
							(int)$this->id,
							((int)$address_id ? (int)$address_id : null),
							$null,
							true,
							true,
							$virtual_context
						);
					else
						$price = Product::getPriceStatic(
							(int)$product['id_product'],
							false,
							(int)$product['id_product_attribute'],
							2,
							null,
							false,
							true,
							$product['cart_quantity'],
							false,
							((int)$this->id_customer ? (int)$this->id_customer : null),
							(int)$this->id,
							((int)$address_id ? (int)$address_id : null),
							$null,
							true,
							true,
							$virtual_context
						);

					$total_price = Tools::ps_round($price * (int)$product['cart_quantity'], 2);
				}
				$order_total += $total_price;
			}
		}
		
		$order_total_products = $order_total;

		if ($type == Cart::ONLY_DISCOUNTS)
			$order_total = 0;

		// Wrapping Fees
		$wrapping_fees = 0;
		if ($this->gift)
			$wrapping_fees = Tools::convertPrice(Tools::ps_round($this->getGiftWrappingPrice($with_taxes), 2), Currency::getCurrencyInstance((int)$this->id_currency));
		if ($type == Cart::ONLY_WRAPPING)
			return $wrapping_fees;

		$order_total_discount = 0;
		if (!in_array($type, array(Cart::ONLY_SHIPPING, Cart::ONLY_PRODUCTS)) && CartRule::isFeatureActive())
		{
			// First, retrieve the cart rules associated to this "getOrderTotal"
			if ($with_shipping || $type == Cart::ONLY_DISCOUNTS)
				$cart_rules = $this->getCartRules(CartRule::FILTER_ACTION_ALL);
			else
			{
				$cart_rules = $this->getCartRules(CartRule::FILTER_ACTION_REDUCTION);
				// Cart Rules array are merged manually in order to avoid doubles
				foreach ($this->getCartRules(CartRule::FILTER_ACTION_GIFT) as $tmp_cart_rule)
				{
					$flag = false;
					foreach ($cart_rules as $cart_rule)
						if ($tmp_cart_rule['id_cart_rule'] == $cart_rule['id_cart_rule'])
							$flag = true;
					if (!$flag)
						$cart_rules[] = $tmp_cart_rule;
				}
			}
			
			$id_address_delivery = 0;
			if (isset($products[0]))
				$id_address_delivery = (is_null($products) ? $this->id_address_delivery : $products[0]['id_address_delivery']);
			$package = array('id_carrier' => $id_carrier, 'id_address' => $id_address_delivery, 'products' => $products);
			
			// Then, calculate the contextual value for each one
			foreach ($cart_rules as $cart_rule)
			{
				// If the cart rule offers free shipping, add the shipping cost
				if (($with_shipping || $type == Cart::ONLY_DISCOUNTS) && $cart_rule['obj']->free_shipping)
					$order_total_discount += Tools::ps_round($cart_rule['obj']->getContextualValue($with_taxes, $virtual_context, CartRule::FILTER_ACTION_SHIPPING, ($param_product ? $package : null), $use_cache), 2);

				// If the cart rule is a free gift, then add the free gift value only if the gift is in this package
				if ((int)$cart_rule['obj']->gift_product)
				{
					$in_order = false;
					if (is_null($products))
						$in_order = true;
					else
						foreach ($products as $product)
							if ($cart_rule['obj']->gift_product == $product['id_product'] && $cart_rule['obj']->gift_product_attribute == $product['id_product_attribute'])
								$in_order = true;

					if ($in_order)
						$order_total_discount += $cart_rule['obj']->getContextualValue($with_taxes, $virtual_context, CartRule::FILTER_ACTION_GIFT, $package, $use_cache);
				}

				// If the cart rule offers a reduction, the amount is prorated (with the products in the package)
				if ($cart_rule['obj']->reduction_percent > 0 || $cart_rule['obj']->reduction_amount > 0)
					$order_total_discount += Tools::ps_round($cart_rule['obj']->getContextualValue($with_taxes, $virtual_context, CartRule::FILTER_ACTION_REDUCTION, $package, $use_cache), 2);
			}
			$order_total_discount = min(Tools::ps_round($order_total_discount, 2), $wrapping_fees + $order_total_products + $shipping_fees);
			$order_total -= $order_total_discount;
		}

		if ($type == Cart::BOTH)
			$order_total += $shipping_fees + $wrapping_fees;

		if ($order_total < 0 && $type != Cart::ONLY_DISCOUNTS)
			return 0;

		if ($type == Cart::ONLY_DISCOUNTS)
			return $order_total_discount;

		return Tools::ps_round((float)$order_total, 2);
	}

Original method in lines 1-246, new one after. 

The line of code I added is in line 341.

Edited by nimloth (see edit history)
  • Like 1
Link to comment
Share on other sites

  • 2 weeks later...

I discovered today that the solution I posted only solves the case when the "Show on sale" checkbox is marked. 

I fixed it and now it work in both cases: on sale and specific price.

 

In the new method mentioned above (getOrderTotalWithoutOnSaleProducts) I added this check. The method  "isDiscounted" is already written into Product.php class.

foreach ($products as $product) // products refer to the cart details
		{
			if (!$product['on_sale'] && !(Product::isDiscounted((int)$product['id_product']))) { 
				
				

Hope that helps!

Edited by nimloth (see edit history)
  • Like 1
Link to comment
Share on other sites

  • 1 month later...

Hi,

 

First of all, thank you nimloth for taking the time to share!

Nimloth's code works perfectly for my 1.5.4.1, just a small issue: only if cart rule is set to Order (without shipping) in the Actions tab. If you set to Selected product(s), the problem remains the same.

If anyone has any hint please give us a hand.

 

Thank you all!

 

Link to comment
Share on other sites

  • 2 months later...

OK partially solved.

 

My CartRule is of the type: % discount on whole cart.

 

Editing the file: classes/CartRule.php line 784

 

after this code:

// Do not give a reduction on free products!
$order_total = $context->cart->getOrderTotal($use_tax, Cart::ONLY_PRODUCTS, $package_products);
	  foreach ($context->cart->getCartRules(CartRule::FILTER_ACTION_GIFT) as $cart_rule)
			$order_total -= Tools::ps_round($cart_rule['obj']->getContextualValue($use_tax, $context, CartRule::FILTER_ACTION_G	IFT, $package), 2);
I add this lines:

 

foreach ($package_products as $product)
	  if($product['on_sale'])
			$order_total -= $use_tax ? $product['total_wt'] : $product['total'];
It will then subtract price of product 'on_sale' from the total used to calculate discount.

 

It is a perfect solution but, waiting for an official "not compatible" option...

 

By the way, how can I edit the topic Title to mark as, at least "partially solved" ?

 

 

 

I discovered today that the solution I posted only solves the case when the "Show on sale" checkbox is marked. 

I fixed it and now it work in both cases: on sale and specific price.

 

In the new method mentioned above (getOrderTotalWithoutOnSaleProducts) I added this check. The method  "isDiscounted" is already written into Product.php class.

foreach ($products as $product) // products refer to the cart details
		{
			if (!$product['on_sale'] && !(Product::isDiscounted((int)$product['id_product']))) { 
				
				

Hope that helps!

 

Thank you guys for the solution! In general treasury would like to add the following to help avoid the discount basket which is based on products (applied to the amount of certain goods) th code to insert in places allocated: /*[bv*/ ... /*bv]*/   :)

// Discount (%) on the selection of products
            if ($this->reduction_percent && $this->reduction_product == -2)
            {
                $selected_products_reduction = 0;
                $selected_products = $this->checkProductRestrictions($context, true);
                if (is_array($selected_products))
                    foreach ($package_products as $product)
                        if /*[bv*/(/*bv]*/(in_array($product['id_product'].'-'.$product['id_product_attribute'], $selected_products)
                            || in_array($product['id_product'].'-0', $selected_products))/*[bv*/&& (!$product['on_sale'] && !Product::isDiscounted((int)$product['id_product'])))/*bv]*/
                        {
                            $price = ($use_tax ? $product['price_wt'] : $product['price']);
                            $selected_products_reduction += $price * $product['cart_quantity'];
                        }
                $reduction_value += $selected_products_reduction * $this->reduction_percent / 100;
            }
Link to comment
Share on other sites

  • 11 months later...

Hi guys, i know this is old topic but somehow i am getting closer to solving my problem and maybe someone could help me 

 

what i am trying to achieve is to have Cart::ONLY_PRODUCTS_WITH_SHIPPING, in prestashop 1.6 in order to give a discount on the total including shipping

 

Thank you 

Link to comment
Share on other sites

×
×
  • Create New...