Closed (duplicate)
Project:
Commerce Discount
Version:
7.x-1.x-dev
Component:
Code
Priority:
Major
Category:
Bug report
Assigned:
Unassigned
Issue tags:
Reporter:
Created:
27 Aug 2014 at 07:34 UTC
Updated:
19 Sep 2017 at 23:21 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #1
essbee commentedFurther to this, things function fine if I make the discount a product discount (i.e. operating at line item level), But for order level discounts the stored total is not being altered.
Comment #2
sansui commentedI'm having a similar issue with this version, but the order total is not adjusted with either the product or order level discounts. Have you been able to resolve this?
Edit: It works with flat dollar off coupons, but percent off does not discount the total
Comment #3
bc commentedJust noticed that I'm having this issue after deploying discounts + coupons on a live site.
Things work perfectly on a staging site, even with real payment processing... this is super weird.
I am also using a one-page checkout system with no review step... but the staging site is set up identically and it works there.
Comment #4
proloy03 commentedThis happens to me as well. Works locally but not in live. Did any one find any possible reason for this? I created one fixed coupon only.
Thanks.
Comment #5
sansui commentedUnder admin/commerce/store/discounts/settings did you set the line item types?
Comment #6
proloy03 commentedYes, I did that. It was not the issue.
The shipping module was somehow conflicting with the coupon module which was causing the issue. Disabling it fixed the issue. I totally uninstalled the shipping module and then enabled it again but the problem did not occur again. This probably was due to shipping rule "Delete shipping line items on shopping cart updates", but I could not test it further since the issue was fixed.
Comment #7
deadcow commented+1 for the shipping module.
Shipping module disabled => what is sent to the payment gateway is the correct price, with discount
Shipping module enabled => price without discount. Problem.
Seems not to be about "Delete shipping line items on shopping cart updates" rule though. I disabled it and same result.
Another thing I saw while messing with the database is that a lot of commerce_discount line items are created. Currently I have 21 commerce_discount line items and 1 product line item. On every submission a new one is created, not sure if this is intended. And on the way to the payment gateway, the commerce_discount is lost (looking at the order wrapper while debugging).
I'd say it's more a problem with the discount module though. Not sure if I have to open an issue there.
Also FYI I have no shipping configured, my shop is like free shipping for everyone. I have the module enabled to get the address though.
Comment #8
dpolant commentedI can reproduce this without turning coupon module on, so I'm going to put it in the discount queue. Just to clarify, this bug happens when:
- There is an order discount (fixed and pct offers I know will trigger it not sure about the others)
- Shipping module is on
- Checkout is single page
Comment #9
mxwitkowski commentedHi - I am seeing the same issue with my setup [discount properly applies and shows with the Ajax update, but is removed after proceeding to the next pane]. I am using the Discount 7.x-1.0-alpha4+7-dev version and using a multi-page checkout. I have disabled all shipping rules but still encounter this issue.
I can see in the database in the field_data_commerce_order_total table that the price is properly updated when the coupon is applied. However, in my case when I click the 'continue to next step' button and move onto the shipping pane, I can see that the price is recalculated and the discount is removed from the order record field_data_commerce_order_total table.
Comment #10
mxwitkowski commentedHave done some further troubleshooting to try and narrow down the root cause of this.
Some interesting observations:
First: Since I am using a multi-pane checkout process, I moved the coupon code field into the same pane as the order review. Interesting, it looks as though the coupon does get accepted and in the order record in the field_data_commerce_order_total table I see the discount has been applied -- however the shopping cart contents are not displaying the discount.
Second: As stated earlier in #9, if I leave the coupon code field in the 'Checkout' pane, the coupon does apply and properly shows in the cart summary and I can see in the database in the field_data_commerce_order_total table that the price is properly updated when the coupon is applied. However, in my case when I click the 'continue to next step' button and move onto the shipping pane, I can see that the price is recalculated and the discount is removed from the order record in the field_data_commerce_order_total table.
Comment #11
mxwitkowski commentedI have done a boatload more research and found that this issue is most likely due to Rules v2.8. Discussion about this issue on the Rules issue queue for Rules 2.8
https://www.drupal.org/node/2403851
Comment #12
taote commentedI have the same problem here. And I need to fix it ASAP. Please help!!
I don't know where to look. And I need to hand in a project with this feature working today. Please, can anyone help ?
Comment #13
taote commentedI have done some tests and the type of discounts that are not working are the order discounts, products discounts don't have the problem described in my previous post. Maybe this can help to solve it.
Comment #14
trevorbradley commentedI just hit this today as well. Discounts are working on products, and on order discounts, free items are showing up. But $ off and % off the order are broken. The $order object appears to be calculated correctly (?) but when commerce_cart_form is called, the discount disappears.
I've downgraded to Rules 2.7, as suggested following these threads down the rabbit hole. It looks like this is broken. I also have a deadline to try to get this to work, and I may have to discard the module and roll my own to make an order discount work.
Comment #15
trevorbradley commentedDING DING DING! I think I may have it. I don't like unsolved problems, so I kept going down the rabbit hole.
The "Shopping Cart Form" view has a filter on it: "Line item is of a product line item type". Except our discount line items aren't of the "product" type, they're the "commerce_discount" type, as seen in the "commerce_line_item" DB table.
If you remove the views filter entirely, the discount appears on the view, and if the order goes through, the discount persists all the way to the end. (This after I downgraded to Rules 2.7, not sure if that's an effect.)
Comment #16
taote commented@TrevorBradley I tried what you said, but order discount is still not being sent to the payment gateway.
Order summary shows the discount correctly but the order total amount received by the payment module doesn't include the discount.
Is this not happening to everybody?
Comment #17
Ravenight commentedI too am having this issue...
-rules 2.8
I found some additional info that might be useful.
Following the advice in #15, I went to views and looked at the admin/structure/views/view/commerce_cart_summary view that is being called on the review checkout page. I noticed, before removing the "Line item is of a product line item type" filter but after putting in the conditional filter (order # of an order with an item on sale) that the discounted amount was being correctly calculated and shown in the views footer.
What is strange to me, is the review page calling this view is returning something different in that one place. My shopping cart summary can be used anywhere else on the site, and it returns accurate discount information, just not on the review checkout pane.
Comment #18
Ravenight commentedLooks like this has been addressed in rules here: https://www.drupal.org/node/2324587
I applied the Rule 7.x-2.x-dev (latest as of today) and the problem went away. All discounts are being applied on review checkout correctly now.
Comment #19
trevorbradley commentedOnly order discounts ($ off/% off) were broken for me at the cart level. Product discounts worked fine, at least in the cart. EDIT2: To clarify, I was seeing a different problem at the cart level, seperate from the missing discount at the checkout level which is resolved by changing Rules to 2.7 or 2.8-dev.
I don't know why my discounts were being eaten even after I applied either Rules 2.7 or 2.x-dev, but I know that altering the cart view to not filter on products fixed my problem. I'm guessing it was filtered from the cart view, and when carts were being submitted to go to checkout, it was removed.
I verified that my discounts also broke with Rules 2.8, but this break occurred later in the process (in checkout, not the cart).
EDIT: I'm not using a payment gateway yet, so I can't confirm if this is an issue there.
Comment #20
taote commented@Ravenight Are the discounts being applied on the payment gateway too?
Can I update Rules to the dev version and revert it back to 2.7 in case in doesn't work?
Comment #21
jiisuominen commentedJust to confirm that I had this issue with Rules 2.8, but updating to 7.x-2.8+2-dev fixed this.
In my situation up until the checkout page prices were calculated properly. I have 1 page checkout and on that page I had original prices. Only thing I did was the Rules update.
Comment #22
taote commentedNo luck :'-( Installed the the Rules dev version, but when the order is sent to the payment gateway doesn't include the discount.
Comment #23
dpolant commentedI can verify that Rules is the culprit here. As 5to1 said, getting the latest rules dev version fixed it. I believe the commit you need is http://cgit.drupalcode.org/rules/commit/?id=db14bda
@taote I really think upgrading rules should fix it. Did you remember to run update.php? At the very least ou need to clear the cache since you picked up commits that added a hook.
Comment #24
dpolant commentedComment #25
rahu231086 commentedHello there,
I have this issue too. i am totally agree with @taote order discount seems work on review page but on payment gateway page it goes away. i am using commerce kickstart 2.21. One thing i know it was not the problem in commerce kickstart 2.16 but when i upgraded it to 2.20 this problem appeared and also after upgraded to commerce kickstart 2.21 the problem still remain.
Comment #26
rahu231086 commentedOk guys,
I have got the problem. This is by commerce entity cache module. So just disable this module until this fixed.
thanks
Comment #27
rahu231086 commentedSolved !
I finally solved this weird issue as i know this happens when we enable commerce entitycache module. Easiest way is to disable this but i need this because of performance. So i just track down the problem and found during commerce checkout form submission order is not saved with Commerce Discount line item as it should be. This is because before saving the order it should be refreshed again by calling commerce_cart_order_refresh function. I don't how to fix this as i don't know how commerce discount module and commerce entity cache works. So for the mean time until this bug is fixed what i do make a custom module to resolve this here is the method:
So i believe we should not blame on entity cache or commerce entity cache module this is something commerce discount module need to do to make it compatible with them.
thanks
Gaurav Sharma
Comment #28
rahu231086 commentedHello guys,
I went further deep down to this problem and found out during commerce shipping calculation commerce shipping module call this function commerce_order_calculate_total($order); after adding shipping line item to the order. After calling this function our order discount line items are removed. So i think we need to fix commerce discount module so that it will work well when this function is going to call. Since this function
is in core and a lot contributed modules will call this. And whenever it calls order discount line items are removed.
thanks
Comment #29
rahu231086 commentedOk now Guys,
Continue to comment #28
Now i found out why calling this
by contributed module like commerce shipping becomes the cause of removing line items because commerce discount line items are not longer in the database they have been removed and recreated by the commerce discount and thus newly commerce line items have different line item ids than in the commerce order referring line item ids. So it's all about timing because every contributed module which add or remove line items in the order are not sync with each other or may be they are missing a better hook to alter orders line items rather than directly are they are doing. So at the end i will only say to fix this just save the order on every stage if you have changed something rather waiting core modules do this as i have done in my comment number #27
thanks
Comment #30
rahu231086 commentedSOLVED!
So here is the final one. Since you know from comment #27 i proposed a solution as quick fix to this issues. Also i told you this problem happens only when commerce entity cache is enabled if it is not the there is no problem at all. So what i have done not just clear order cache bin when checkout form is loaded so that during payment payment gateway always pick the fresh one. So here we can do in custom module no need to patch anything.
thanks
Gaurav Sharma
Comment #31
trevorbradley commentedRules 2.9 came out today, which incorporates the latest dev fixes.
Comment #32
torgospizzaJust FYI we have been using Rules dev for a while, and this morning a customer used a Percent off coupon (Product discount) that did not stay attached to the order when he checked out with PayPal. He tried twice more and it worked once, then did not work the second time. After that, all subsequent tries DID work with the coupon code maintaining its association with the order.
So I think Rules was a major player, but I don't believe it's resolved quite yet.
Also if it helps, I have found that a Product Discount without a Coupon works without issue; but as soon as you add a Coupon, we have failures - though they are still intermittent and hard to find a correlation.
1. We did a Coupon-less discount on 3/14 (for "Pi day") where the prices were discounted automatically, and from what I can surmise there were no issues (at least, no reports from users.)
2. On March 17 we did a Coupon code product discount for St. Patrick's Day, and we've had multiple failures.
I'd love it if someone else still having this issue can try with and without coupons to see if the problem persists.
I don't believe Shipping module is related because for us this occurs on both digital and physical goods. It happens across PayPal EC and Stripe (credit card) payments, new users and old users alike. We did have one user who went back and forth several times and finally got the discount to stick. My guess is that there is a race condition and caching is possibly involved, but I'm still unable to narrow down exactly a root cause.
Our checkout is multi-page.
Comment #33
torgospizzaI spent some more time digging around and I can definitely reproduce it when checkout is a single page. Every time, in fact. And I think I've figured out why but I'm having trouble nailing down the moment this happens.
Note: shipping module can be disabled. I think the issue is exacerbated by single page checkout, because the visitor doesn't have another chance to save the order with a coupon in it.
Basically when you click the "Apply coupon" button it calls hook_commerce_cart_order_refresh(). When it does this it adds a "commerce_ properties to the $order object: commerce_discounts and commerce_coupons.
When you first add the coupon, all of these properties are there and good to go. But then at the next refresh, something appears to be removing price components, resulting in the coupons array being removed.
I'm not sure at this point if it's just that we're lacking a save() function somewhere on either a line item or an order wrapper, but hopefully this sheds some light on things. I'll continue to dig to see if I can't find an exact moment that is the problem.
EDIT: Annnnd now I can't replicate it. I got it to replicate 2 or 3 times but wasn't inspecting as much as I could in the debugger. I'll continue to try and narrow this down.
Comment #34
bgilhome commentedApproach in #27 seems to work for me, except I changed it to a commerce_cart_order_refresh() call.
Comment #35
torgospizza@bgilhome, can you elaborate?
What was your scenario and were you seeing the same types of issues? Were you using any caching modules? (@dpolant, the maintainer for Discount and Coupons, has mentioned that he does not recommend using Commerce Entitycache as that seems to have a lot of unintended consequences elsewhere in Drupal.)
Would love to know more about your setup, config, symptoms, etc. Thanks!
Comment #36
torgospizzaEDIT: When using an Order discount, what seems to be happening is:
1. Add a coupon code; component gets saved to the product prices, as well as a line_item is saved in the $order entity that references this discount.
2. Immediately following that, commerce_cart_order_refresh is triggered;
3. For some reason the newly created $line_item for the discount gets removed immediately, then added in the next refresh pass (as part of $line_item_wrapper->save() when commerce_discount_set_existing_line_item_price() is called.
This causes a race condition because the line_item in the order and the ones in the database, because their IDs no longer match. Therefore, multiple entries in the database are created.
I'm going to switch back to product discounts next to see if there is a common thread.
Comment #37
torgospizzaComment #38
torgospizzaComment #39
torgospizzaComment #40
SurajHo commentedHi, I was wondering if anyone made some progress with this issue. In my case, the discount only disappears when the customer is an anonymous user. When a customer is logged in, everything just works. I'm currently busy debugging to see what goes differently, but this can take a while since there's a lot to go through.
Comment #41
tribsel commentedit appears this problem is not solved yet. and unfortunately im not able to trace nor solve it.
I am on rules 2.9. I not using entity cache and checkout is on single page.
Product discount works without any problem, but order discount fails - its lost on submit.
Comment #42
joelpittetNot a solution yet but one thing I noticed is if I saved the discount line items early before rules in like an cart refresh this seemed to happen quite frequently.
I set my cart refresh to 0. And check your code for early commerce_line_item_save calls.
This may help us all find this problem.
Comment #43
dpolant commentedOk, I was able to reproduce this quite reliably under these circumstances:
- One page checkout
- Shipping module on
- Profile copy for billing > shipping on
I wrote a patch to the commerce profile-copy code that seems to fix it. See https://www.drupal.org/node/2487550#comment-9915426
Profile copy was saving a stale version of the order. This is a really pervasive problem because so many modules both alter line items and save orders, and there is no framework to make sure this gets done in a sensible order.
So people, try the patch that I referenced. If it works, please test the default profile copy stuff thoroughly too, otherwise I cannot get it committed to commerce core.
My guess is this will fix it for most of you, especially those reporting an issue with shipping. @Torgos, your problem sounds like its related to coupons somehow. I would suggest running the debugger and sticking a breakpoint on the order save method, and looking at the line items each time it saves, and note what's in the callstack when you think the order is getting saved with a stale set of line items.
Comment #44
torgospizza@dpolant, I think you're right. We basically had both of these issues simultaneously, and so I think there were a lot of red herrings we were following to no resolution.
Our issue ended up being that the order was being refreshed by external services pinging the checkout URLs - for example if a user is using Chrome and they hit a checkout/ORDER-ID link, moments afterward a social sharing widget would ping that URL to see if it was valid/shareable. Due to our permissions settings, we had it setup so that Anon users could access checkout (for Checkout Redirect, where they are required to login) but Anon users could not redeem coupons.
I did more digging and found that even if Anonymous users CAN'T access checkout, because of the way Drupal's menu object autoloading classes (such as checkout/%commerce_order) works, the full order is loaded and refreshed before returning Access Denied. Thus, due to our combination of settings, the order was refreshed and the coupon was removed by the anonymous user.
Our solution there was to just allow Anony users to "redeem coupons". Since then we haven't seen this issue pop up at all, after several subsequent coupon promotions.
I'll test your patch and your conditions as expressed above, and hopefully we'll be error free with Discounts.
Thanks for continuing on down this road as this issue was obviously not an easy one to solve.
Comment #45
SurajHo commented@dpolant
I just applied the patch and I can confirm that in my situation (latest discount and coupon dev + stable version of commerce), anonymous customers can now successfully use discounts. It is not removed anymore when the customer reaches the payment gate.
Thanks!
Comment #46
joelpittetThere is no patch in this issue, so changing it to active.
Comment #47
torgospizzaI'm guessing maybe we should mark this a duplicate of #2487550: Customer profile copy calls order save on stale object then?
Comment #48
joelpittet@torgosPizza let's see what happens to that issue first. It is likely a good candidate but with such a tricky issue there may be others.
Comment #49
geek-merlinI had the very same symptom. After applying my patch from #2418033-14: Allow tax/vat on order discount (commerce_discount) line items (which also fixes an underlying issue, see there) it went away. Might be worth a try.
Comment #50
capfive commentedHere is my use case and here is the solution that helped me.
Drupal Commerce 7.x-1.11
Commerce Shipping 7.x-2.x-dev
Commerce Flat Rate 7.x-1.0-beta2
Commerce Discount 7.x-1.0-alpha4
We were having the issue some others were showing:
1. Apply fixed discount to an order
2. Add product to cart and the discount shows up in the cart
3. Checkout and the Discount shows in the checkout (NOTE** we are using a 1 page checkout with no review)
4. Order doesn't have the discount on the final invoice/order after payment for any role other than anonymous.
NOTES:
With Commerce Shipping disabled the discount stays on the order (no good because we need to charge postage)
I did apply the view fix to show the discounted line item types, but even with a fresh install it still doesnt attached with the modules mentioned
Tried Dev's of all the above mentioned and none of them worked
Tried the rules patches and fixes and none of these helped
SOLUTION:
I applied the patch from #47 but i am only using commerce 7.x-1.11 so I manually added the code and made a note for updates and will be posting in that thread to ask for a commit to dev version or a patch for the dev version.
This solved the issue and now the discount and the postage both attach :)
Thanks for the awesome module and the great find torgosPizza!
Comment #51
ahmad abbad commentedTry this patch is working for me
Comment #52
joelpittet@ahmad abbad although interesting if that helped you, that patch belongs on the commerce_coupon issue queue. Also, just a note as you may have forgot but you should use
--relativeflag when making the patch from the module root folder instead of the site root. That patch will fail to apply, as is.Comment #53
ahmad abbad commented@joelpittet I'm sorry by mistake
Comment #54
dan_lennox commentedThe patch from https://www.drupal.org/node/2487550#comment-9915426 mentioned in #43 and #47 definitely fixed this issue for me.
Comment #55
damienmckennaDon't forget to change the issue status to "needs review" when you upload a patch.
Comment #57
torgospizza@DamienMcKenna: Per #52 should we change this to the Commerce Coupon issue queue? Also as @joelpittet mentioned it will need to be rerolled with --relative.
Comment #58
agoradesign commentedFor me, none of the discussed solutions worked. I was debugging and trying for hours, until I finally found a solution that worked for me.
It seems to me, that the commerce_discount_commerce_cart_order_refresh() function is causing the problems. On every cart refresh, which can be twice on jumping to the next checkout step, first all discount line items and components are removed, and at the end the rules event is fired to re-add them again. It's clear to me, why this is/must be done. However for some unknown reasons it leads to orphaned records in commerce_discount, although it should be deleted by the commerce_line_item_delete_multiple() call within the commerce_discount_commerce_cart_order_refresh(). And as it seems, the line item reference in the order is pointing to an already deleted line item, not to the newest one. It's likely that the interaction of different modules, that modify and save the order may have their impact on this too, like discussed in #2533396: Convention for updating the order during checkout or #2026321: Avoid overwriting an already updated order.
At the end, the following workaround is my current solution for the problem. During checkout completion, I manually call the commerce_discount_commerce_cart_order_refresh() a last time, so I can ensure, that the discount will be re-added during the checkout completion:
Comment #59
torgospizza#58: That is an interesting workaround. I know that the "refresh" hook has been the hardest thing to work with, especially when attempting to track down bugs such as this. What I'd like to figure out is what exactly is the root cause of this - because essentially the order refresh should be happening quite frequently (basically, whenever an order is saved, which would happen at each stage of the checkout process)... so what is it that's causing line items to become out of sync? That's the real question. Were you able to glean anything to that end during your testing?
Comment #60
agoradesign commentedIn general, I'd like to figure this out too, but for now I'm satisfied with this workaround, which is imho really a bad solution.
I saw this bug today, when I saw a new order having a coupon reference but no discount line item and full total amount. When trying to reproduce this bug, I first thought that I couldn't - because including the review chekout step, the discount was applied correctly. However, on completing the order, the discount gets removed and not replaced with a fresh one again.
I was spending several hours with debugging, inserting watchdog() and dpm() calls in several places. I can confirm, that the refreshing of the order is really done very frequently - in my case at least two times on proceeding to the next step. I also saw, that on other places, during the validation and submission of the checkout panes, the order is most of time correct (== including the discount), but sometimes not. This sounds quite vague - and it really is. Because I haven't found any explanation, why at some given points during the debugging session the values suddenly changed. I have analyzed other involved modules and their checkout panes. I didn't find any problem here too.
However, at the very end of every step until the completion, the order refreshment seems to find always the right way. But unfortunately it seems, that it doesn't get called during payment/completion anymore. That's why I've tried the described workaround, which really helped.
But the next problem arised with the next tests I've done. My first test was fully successful: the saved order was complete, the totals were correct and the payment also had the right amount set (I was using a self-defined "pay upon pickup" payment). In my next test, I've tried credit card payment, which is implemented with commerce_ogone module - an offsite payment. Drupal sent the full amount without discount to the payment provider. So I had to implement a data alteration hook of commerce_ogone module, where I again had to manually call the order refreshment function + I had to reload the order object in order to get the correct total amount!!! This is so strange!!!
Another strange thing, I've already mentioned in my first post in #58: I get lots of orphaned line items, which do not get deleted actually. My theory is, that something like this must happen: the order is referencing line item with ID 1. commerce_discount_commerce_cart_order_refresh() gets called and wants to delete ID 1 and then call Rules to add a new one. Stale data exists anywhere and another save() call leads to re-adding the deleted line item (or prevent deletion). And also there must be set somewhere somehow an old and wrong value in the line items reference field of the order - an reference to a line item, which actually does get/got deleted by commerce_discount_commerce_cart_order_refresh(). And then Commerce deletes the orphaned line item reference of the order to the no longer existing one.
I'm not sure, if my thoughts are explained understandable enough - but the problem is, that I'm still too much confused by this issue and especially now in the evening my brain feels quite "squashy" :D
Comment #61
torgospizzaThis sounds like a lot of the issues I was experiencing earlier, but oddly enough I fixed it by Reverting some of the Rules that had been created by Discounts. Some updates to the -dev branch introduced new features, and unbeknownst to me, this requires some cache-clearing as well as possibly reversion of some Rules that may have been overridden (for example to add a configuration option). Give reverting that a try.
In these problem orders, is your coupon referencing a product discount or an order discount? I, too, was confused by the discount disappearing, but in the case of a product discount I don't think it's 100% necessary, because the discount is essentially referenced through the coupon, and the discount is applied as a price component to the line item itself (as opposed to the entire order). So in essence a discount reference may not be needed in the order if the only discounts around are product level discounts... but I could be mistaken. It seems counterintuitive, but I have had plenty of orders work just fine without a discount reference when the only discount is product level.
In my testing I actually used Drush:
drush ev "print_r(commerce_order_load(ORDER_ID))"
Doing this allowed me to watch the commerce_coupons and commerce_discounts on the object go away one at a time. That is, until I reverted my custom Rules, at which point that stopped happening. (For coupons, anyway.)
I agree that the refresh hook is weird and janky and seems unstable but I'm not sure where else to go from there, since for me at least, it now seems to work without issue.
Comment #62
torgospizzaAlso give the patch in #2444703: EntityMetadataWrapperException: Unknown data property commerce_coupons. a try.
Comment #63
agoradesign commentedThe problem was caused by a fixed amount order discount, which needs to have its line item in the order.
The associated rule on the "Apply a discount to a given order" event is not customized at all. The discount, hence its associated rule, was created about two weeks ago, long after the last module update of commerce_discount took place. So the rule is fresh and unchanged.
Well, I can try the patch, but I've never experienced this exception. I just can't promise you, when I'll find time to do so. Like it's always, when you're extremely busy and don't have any time, then such problems like this begin to arise additionally...
Comment #64
torgospizzaTurns out we're still having this issue apparently, but for the life of me I can't find a common denominator other than an offsite payment (PayPal) and using a Coupon. At some point during the order refresh the coupon is removed from the order. In our logs I can see this take place - suddenly, commerce_coupon_discount_coupon_codes_exist_on_order() returns FALSE when it should return TRUE.
Comment #65
torgospizzaWould love some sprint help on this. It's a corner case but seems to happen incredibly often.
Comment #66
joelpittetThis really needs the steps well defined. @torgosPizza can you write up some steps in the issue summary for the minimum nessasary to get this bug to happen. (I haven't seen this in a while but did at one point).
Comment #67
torgospizzaSo here's the thing: we ran a big coupon deal yesterday (for Star Wars' "Wookiee Life Day") and for the most part it worked. That's why this is such a hairy issue to solve.
But I managed to find one prime candidate: an order that has a coupon attached but whose discount price components were either never added or were removed and not-re-added.
I'm digging in now to see what if anything is causing this. I even updated Coupons to the latest Dev (pretty sure Discounts still is) but the problem showed up for me even on our staging server. I added a coupon to a NEW order (that seems to be a #1 step - subsequent coupon redemptions work fine), viewed another product page, then my cart, and at that time noticed the coupon had been removed.
Going to try digging in and seeing if I can actually find some "steps to reproduce" because at the moment there literally are none - it just happens on occasion, and all I can do is try to log as much data as possible and look at the evidence afterward. Hoping that will change soon!
Comment #68
torgospizzaAfter talking with @joelpittet for a while on G+ I did some more digging, and I think the actual issue boils down to a race condition in Rules. I'd love to have others who've experienced this problem check this using the latest versions of Commerce Discount and Commerce Coupon, mainly because Discounts now has a sort order field in the discount attributes tabs.
For me, setting the sort order (weight) of this discount to 21 fixed the problem that I had been able to reproduce:
1. Add a product discount that works on only specific products.
2. Set its sort order to '1' (its generated rule should show as -1)
3. Make sure the Coupon field is on the first Checkout page.
4. Add a product, then go to Checkout and apply the coupon.
5. In another tab, refresh that Product's page. You'll notice the price will NOT be the discounted price.
6. Refresh Checkout tab and the coupon will probably be gone if the race condition is being hit.
Now if you go back and set the Discount's weight to 21 (in Rules it will be "10"), and follow the other steps 2-6, the discount will remain on the order!
EDIT: This may have been another false alarm. It looks like the problem still persists, it just might take more than one refresh.For us this only affected a small number of users because most people checked out right away. What leads me to the conclusion of a weight/race issue is after inspecting the Coupons logic that checks for discount components at the product line item level:
- Coupons has a hook_module_implements_alter() that sets their implementation of hook_commerce_cart_order_refresh() to run last.
- Discounts (of the type 'product_discount') relies on the Rules event "Calculating the sell price of a product"
- Coupons' refresh function basically removes all of the discount price components from every line item, relying on Rules to re-add them.
- To do so, during commerce_coupon_commerce_cart_order_refresh() a call is made to commerce_coupon_order_coupon_code_discounts().
- That function calls commerce_coupon_order_discount_ids($order), which loops through price components looking for key "discount_name"
- BUT due to the race condition, no price components would be found on the product line items yet:
- So the coupon is removed from the order.
At the moment I can reliably reproduce this every time, simply by adjusting the Discount weight. Therefore, I think we may want to find a way to force an order here, given that pricing and product-level discount calculations all react on the "Calculating the sell price of a product" event.
Comment #69
torgospizzaSome additional notes and an interesting turn of events:
1. I was showing the Product Price in a View, using fields
2. The price was the formatted amoun
3. The option "Show the calculated price for the current user" was selected
The product page uses Views to show prices on the various products associated with a display rather than the default add to cart form. (We're using Panelizer and Views to create the node pages.)
When I change the Price field settings to display the original price, the coupon stays on the order when the product page is refreshed. (Kind of expected but still interesting.)
Following this line of thought I watched the steps in the debugger and noticed that it seemed to be doing a lot of looping (and also commerce_cart_order_refresh() seems to call itself once). Finally I realized I had applied the patch at #1268472: Recursion in price calculation causes cart to skip calculation rules, which seemed like it should be helpful.. however, reverting that patch actually made this problem go away(!).I'm going to tentatively mark that patch as Needs work, because this is a very interesting side effect.False alarm, that patch didn't really have an effect one way or another; the problem appears to be with how Coupons is doing a cart refresh.
I verified this by removing the Coupon. After multiple refreshes the Discount seems to stick around in that case. (Confirmed, removing the coupon from the discount makes this issue resolved.... not good news for coupons though!)
Moving my work to #2464525: Coupon is removed during Checkout
Comment #70
joelpittetTotally reproducible with #1268472: Recursion in price calculation causes cart to skip calculation rules + coupon.
While it's in
commerce_coupon_order_discount_ids()on a Product Display, the pricing rules fire but don't refresh the cart because that patch removes the extracommerce_order_load()(which fires all the refresh rules).I've not tracked down why the pricing rules causes the discounts to be lost, or really where they are lost on the component. But it's reproducible! That's half the battle. the other half is red and blue lasers obvs.
Comment #71
joelpittetUnless someone can reproduce this without commerce coupon + that patch I'm going to close this as a duplicate and move the discussion over there.
#2464525: Coupon is removed during Checkout
Comment #72
fotograafinge commentedI can reproduce it without Commerce Coupon. And with the patch.
In short:
Rules 7.x-2.9
No coupon, just discount (product discount % for products with a certain taxonomy term)
Multipage checkout
Same problem as described in #9, #10, #12
#15 is not the solution, problem still exists
Commerce EntityCache is disabled
#58 does not fix things for me
I guess my issue is a duplicate: #2673870: Discount is shown, after browser refresh / cart update / during checkout not shown anymore ?
Comment #73
prjcarr commentedI can confirm this is still happening. Only happens to me with Product Discounts. Order discounts seem to be fine.
Comment #74
torgospizzaAre there any other steps involved? For instance are you selecting addresses from a dropdown, etc. - any type of interacting with the Checkout pages/panes? Some more explicit steps to reproduce will be helpful, in case there is any variance there (as opposed to "just clicking Continue all the way to checkout").
EDIT: One thing I found helpful in my troubleshooting of this was to put a watchdog() within the functions that remove discounts from orders. I also would include a call to debug_backtrace() that gives you the caller responsible. That way you can easily see in the logs which function and request are triggering the removal, and we can more easily narrow it down. But having been down this route before the most likely culprit is the cart order refresh hook.
Comment #75
fotograafinge commentedNo other steps involved. It even happens before going to checkout. On every refresh of a page that shows prices, it happens. So in every view where I render my products (like product overview page, shopping cart, and more) ... but ONLY when there is a product in the shopping cart !! If the shopping cart is empty, the discount does not disappear on the product overview pages. When I add a product to the cart, the discount disappears. When I refresh, it's back and so on.
So I also think the cart order refresh hook causes the problem. Haven't found anything else that can cause it.
(fyi, It only happens with Product Discount, not with Order Discount.)
Comment #76
deanduke commentedSolution #58 worked for me for any payment method but Paypal...
EDIT: by applying the same solution at commerce_paypal_wps.module in
function commerce_paypal_wps_order_form($form, &$form_state, $order, $settings) {it works
Comment #77
torgospizzaI might not recommend the solution in #58 which seems more like a band-aid than a way of fixing the root issue. I still can't reproduce this on my local site but will be setting up a default Drupal Commerce site to try and help troubleshoot this. As soon as I can reproduce the bug I can attempt to provide some insight,
Comment #78
fotograafinge commented@torgosPizza: If you want, I can give you access to a copy of my Drupal Commerce site? Or sent you the database and files so you can install it locally?
Comment #79
prjcarr commentedI was just having another play with this and I noticed that product discounts are working if I leave the setting "Compatibility with other discounts" as "Any discount". The moment I change this setting is when the discount stops working during checkout. Can someone else advise if this is the case for them also? We may be able to narrow this down.
Comment #80
torgospizzaYeah, you should NOT be using the compatibility settings at this time. There are some other issues around that:
#2621526: Compatibility settings other than "all" causes Discount+Coupon to be removed
#2618072: Compatibility settings not honored with multiple coupons, allowing multiple discounts on order
#2632072: Move compatibility feature to optional experimental feature
For now I would leave this feature disabled or set to "Any" until we can figure out a better solution for product-level discounts.
Comment #81
fotograafinge commented#79 is the answer !
@torgosPizza: Better do disable this in the dev version, if it can't be used. If the shop owner does not know this causes problems, he will use this. But if it isn't shown, he can't use it.
I checked it and had a discount that was on "Compatibility with other discounts: Not with any other discounts" because dat product discount can never be combined with other discounts. But I guess I can make a workaround by adding this as a and condition + negate to my other discounts. Although that is only acceptable as a temp solution.
When all my discounts have the setting "Compatibility with other discounts" as "Any discount", the discount does not go away anymore. Finally !
Comment #82
zeroduh commentedFor me after updating the rules from 2.7 to 2.9 the discount keeps going away. After back tracing a little I notice the rules event invocation are not called on the commerce_load, because the load order are called before the get_menu_item(), at this point the flag rules_event_invocation_enabled() are false, making this rules event (on commerce_discount_commerce_cart_order_refresh) never run :
For me setting the flag ON on commerce_order load make the trick and all my discounts and even the coupon ones are attached on the order. I just add in a custom module with the hook_entity_load:
Comment #83
attiks commentedI ran into the same problem, tried a lot, but only #58 works for me
Comment #84
roam2345 commentedTurns out the issue is the following.
in commerce_discount_compatibility_check the commerce_discount_compatibility_check does not check if it is looking at its self.
foreach ($applied_discounts as $applied_discount_id => $applied_discount_name) {
//missing if statement causes discounts to disappear in some cases
if ($applied_discount_name == $discount_name) {
return TRUE;
}
Comment #85
roam2345 commentedHere is a patch enjoy :)
Comment #86
roam2345 commentedHere is a better one.
Comment #87
roam2345 commentedmissed file sorry for so many comments.
Comment #89
torgospizza@lathan: If this is the case, then I think we are duplicating effort that is taking place over in #2621526: Compatibility settings other than "all" causes Discount+Coupon to be removed. There is a line in those patches that is supposed to remove the "current" discount in the logic chain so as to not attempt to check compatibility with itself:
I'm not 100% sure that this is a duplicate issue but I really think we should focus our energy on fixing the compatibility logic in one place :)
Comment #90
roam2345 commented@torgosPizza Great I did not see that that issue your patch seem much better thought out that what I have fumbled together above. Thanks for the pointer to the correct issue.
Comment #91
3cwebdev commented#58 fixed the issue for me! The discounts now persist through the complete checkout process. Thanks @agoradesign
Comment #92
ashutoshjha commented#58 solves the issue for discount and for order view page, but in order payment page(admin/commerce/orders//payment) its not working properly. Its showing Order balance with discounted amount.
Comment #93
stevendeleus commentedI have a similar issue when I go to the payment page. The discount disappears, because the line items are removed. As I understand it, they can be re-added by calling commerce_discount_commerce_cart_order_refresh but I don't know where to put this call (which hook?).
Comment #94
stevendeleus commentedI used hook_commerce_checkout_pane_info_alter to calculate the correct total on the payment page. When I redirect to the offsite payment terminal, the discount disappears again... It seems the line items are only added in memory and not in the database, or else they're removed immediately after. Where is the logic that does this? I think I can just remove it for my use case.
Comment #95
mrchristophy commentedSame issue here - can use hook_commerce_checkout_complete to fix that side, but the checkout panes between the cart and 'checkout complete' show the order with the line items removed. Is there any actual fix for this? I'd be happy with a hack at this point!
Comment #96
petermeng72 commentedI had the same problem, I created a new discount. in my case a percentage off discount. Once it was created it works fine when you go to the check out. The discount applied, for me it then runs past shipping before it comes to the final review page. Here the discount disappeared and subsequently at the payment page (paypal for me). When I looked at my discount rules I noticed that the new discounts are created with an event trigger of "Calculating the sell price of a product". If I change the event to "Apply a discount to a given order" and update the conditions and actions to say "Order: [commerce-order]" it all works as intended. Maybe it helps anyone.
I am now using
rules Version: 7.x-2.10
commerce discount: Version: 7.x-1.0-alpha8
commerce coupon: Version: 7.x-2.0-rc2
commerce: Version: 7.x-1.13
Which I believe are all the latest versions (didn't double check)
Peter
Comment #97
ahmad abbad commentedComment #98
nayanalok commented#37 solved issue for me.
@torgospizza u were life saver for me :)
Comment #99
arunkumarkHi All,
I am also facing the same problem on single page checkout. Am using Commerce Shipping and Commerce gift wrapper along with the latest version of Rules(7.x-2.10). Am tries above patch that won't helps me.
After some deep analysis, i will find that The discount is added initially to the order. But before
commerce_checkout_form_validate()it will removes from the order object. This is because of discount is calculated fromcommerce_discount_commerce_cart_order_refresh()function. So we need to update the order total from bothcommerce_checkout_form_validate()andcommerce_checkout_form_submit()by calling the functioncommerce_cart_order_refresh($order);so it will update from latest object from database.[Am not sure am correct]Comment #100
torgospizza#98 Glad to hear it! Sorry I had linked to this issue at first :)
#99 @arunkumark: Can you give the patch at #1804592: During AJAX form submission in checkout, the $order argument passed by the Form API is incorrect. a try? I think it might solve your issue.
Comment #101
czigor commentedThere's a good chance this is a duplicate of #2621526: Compatibility settings other than "all" causes Discount+Coupon to be removed. Test the last patch over there. If it does not work, please provide steps to reproduce.
Comment #102
mistergroove commentedI don't know if this is related. But the discount wasn't being applied to the review page. I added the patch and then I get the error :
The totals of the cart item amounts do not match order amounts.
In log from the commerce_paypal_ec. Is this a result of the patch?
The review page works fine tho. :)