If you set UC Discounts to calculate discounts when a product is added to the cart, only the single product is considered for the discount conditions and actions. Instead, the full cart should be used, so order total discount conditions etc. can also be used as expected.

I've attached a patch which fixes this problem in two steps.
Part 1: (the later part in the patch) this changes uc_discounts_product_discount_price() to use the full cart for the condition checks. It also doesn't change the product quantity for the cart to which the discounts are applied to while applying the discounts. It returns the proper discount (per single item of the product, i.e. as if it was qty 1). An extra parameter is added, in which the cart can be set (necessary for part 2). If it is not set (null), the default cart is used.

Part 2, the first block in the patch: this changes the uc_discounts_cart_item() hook with op == load. Rather than calculating the discount right when the product is loaded, it waits for the final product to be loaded (it first calculates the cart size). Meanwhile it stores references to the cart items on every call. Once the final product is loaded (and our cart copy has the same size as the actual cart), the discounts are applied to all products in one run. It passes the collected cart it got to uc_discounts_product_discount_price().

The result is that discount conditions that check the order total will return a value based on the complete cart rather than a single item (only when discounts are applied when products are added to the cart).

I've tested the code in a single setup, and it works as expected.

This patch should not change sites using the old behavior, except if order conditions instead of product conditions are used. But those conditions would almost always fail unless e.g. a product price is larger than the order total value in the condition (when using the "Order Total" condition). Such setups -- if they exist -- should probably just use the Product discount to discount specific products.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

haffmans’s picture

Slightly updated patch: it broke the "Show discounted product price" before (division by 0 due to no given quantity in the product). If $product->qty is not set, now a qty of 1 is assumed.

psynaptic’s picture

Title: (Patch) Use complete cart for single product discount » Use cart total for single product discount
joachim’s picture

> If you set UC Discounts to calculate discounts when a product is added to the cart, only the single product is considered for the discount conditions and actions. Instead, the full cart should be used, so order total discount conditions etc. can also be used as expected.

But then surely this can cause all sorts of problems!
The user could get different discounts depending on what order products are bought. Eg, we have a discount for "buy 3 shirts get a free tie", and the user adds two shirts, then a tie, then a shirt: they don't get the discount.

I'm actually quite unsure about the whole 'calculate discounts when adding to cart' operation. It's fine for discounts that depend on the general situation (eg role discount) but for discounts depending on the cart it looks like a minefield to me!

psynaptic’s picture

Each time product are added to the cart then the module needs to work out how many products meet the conditions and to apply the actions. The order shouldn't really matter, if they add two shirts and a tie then they shouldn't get a discount, only when they add the third shirt should they get the tie free.

I think most customers would be reassured by seeing the discounts when adding products to their cart.

joachim’s picture

So discounts on all products are recalculated each time a new product is placed in the cart? Ah. I haven't looked at the code. Does that mean discounts that were at the earlier adds are discarded and recalculated?

> I think most customers would be reassured by seeing the discounts when adding products to their cart.
True. Though it could make things more complicated. And big sites don't do it -- eg Tesco only calculates discounts on checkout.

psynaptic’s picture

So discounts on all products are recalculated each time a new product is placed in the cart? Ah. I haven't looked at the code. Does that mean discounts that were at the earlier adds are discarded and recalculated?

If this isn't the way it works then it is certainly the way we should make it work. I don't see the benefit of caching the discounts so this shouldn't be an issue. I added a cart pane to show the discounts below the shopping cart and it's working nicely. I'll post a patch soon.

True. Though it could make things more complicated. And big sites don't do it -- eg Tesco only calculates discounts on checkout.

I think we do need to give the developer the choice to use which ever is most relevant to the site. I can see arguments for and against each and one might suit a particular type of site/product.

mandclu’s picture

I'm currently working on a site where I need to create exactly this scenario. When you put any three towels in your cart (not necessarily all the same style), you get a discount.

Unfortunately, from what I can see currently if you set the discount when the product is added, somehow the quantities for all the products are set to 1. :-(

I think by now it should be obvious that different people need to have their discounts applied at different times. Clearly some of you only want them at checkout, but others want them when shown in the cart. Why not at least give the option?

zmove’s picture

I think this discussion bring a bigger problem : The level the apply option exist.

Currently, it's a whole website option, but I think it should be per discount setting

If you want to apply a discount depending on the order total, you would probably show that discount on the checkout page, not on a product page.
If you want to apply a discount on a product depending on a user role, or a defined product, you probably want to show the discount on the product page.

So, a whole site setting can not fit with all the users needs. That's why it should be a per discount setting IMHO.

rfmartorelli’s picture

To what file did you apply this patch. I am having a similar problem. I'm selling a trial membership that should give you 10% off your entire order, but the discount isn't being applied to the entire order, just the trial product.