The symptom

* place an order, in my case with payment method commerce_cheque (but any should give this error)
* mark the cheque as paid
expected
* hook_commerce_payment_order_paid_in_full() should fire and (in my case) change order status
experienced
* hook does not fire

The cause

(wow, this was a nasty bug to track down...)
* payment changes $transactio->status from pending to success
* DrupalCommerceEntityController::save fires hook_commerce_payment_transaction_update() before it clears entity cache.
* So commerce_payment_order_balance($order) loads the old $transaction which is still pending
* order balance is calculated wrong
* and hook not fired

The cure

see attached patch:
hook invocation should come after cache update.
i think it should also come after releaseLock() - but a DrupalCommerceEntityController guru might consider this.

Comments

geek-merlin’s picture

Status: Active » Needs review
StatusFileSize
new1.21 KB

here's the patch.

rszrama’s picture

Just to clarify here: the bug is with updating pending transactions to successful. Inserting a successful payment transaction directly will trigger this rule properly. That said, I'm interested in other solutions that don't involve changing the nature of the base controller unless absolutely necessary. For example, perhaps we just need to ensure that we've cleared the cache of payment transactions before we perform our save. : ?

geek-merlin’s picture

ryan,

think i get your point about being conservative about the controller.

i thought about that for a while and i'm sure the controller need be fixed:
look at the current controller::save

it does
* write
* invoke aftersave hook
* clear cache
* release lock

but
* write
* clear cache
* release lock
should be an atomic operation

so
* invoke aftersave hook

has to come after that.

so the controller is buggy and has to be fixed.
which my patch does, and fixes this issue and surely others to come.

to the point: we don's wanna invoke a hook while our cache is inconsistent.

rszrama’s picture

Ok, I'll give it a close look ASAP and ost likely roll this into a quick 1.3 (i.e. it's important enough not to postpone for weeks). I talked it over with Damien at dinner, and I think he would agree with you.

damien tournoud’s picture

I'm fine with the change in the controller (EntityAPIController clears the cache before invoking the hooks too); but we need a test for the initial bug report.

mossy2100’s picture

I hope this will be fixed soon! Thanks for working on it :)

rszrama’s picture

Issue tags: +1.3 blocker

Tagging this one as a must-fix for 1.3.

helior’s picture

Assigned: Unassigned » helior

Boom.

helior’s picture

Here's a patch for the just the test requested. (Does not contain the fix from #1)
Although this issue is revolved around the commerce_payment_transaction entity, it affects all commerce entities. I used the Commerce Product entity as my testing grounds as it is the simplest setup.

Status: Needs review » Needs work

The last submitted patch, entity-controller-save-test-1427780-9.patch, failed testing.

helior’s picture

Status: Needs work » Needs review
StatusFileSize
new4.54 KB

Alrighties.. So now that we see that #9 fails without the patch, let's apply the patch from #1.

helior’s picture

Assigned: helior » rszrama

Can you review this when you get a chance? I'm actually not sure if this is the "right" way to test this sort of thing, but hey, it's there :)

rszrama’s picture

Assigned: rszrama » Unassigned
Status: Needs review » Fixed

Finally walked through this patch and the tests tonight with helior. Kudos to Axel for finding and fixing such a tricky issue, and thanks to Helior for figuring out a simple way to test for the behavior. I actually hadn't seen the technique of testing the test in a patch on its own before testing it alongside the fix, but it makes perfect sense now that I've seen it demonstrated. : )

Automatically closed -- issue fixed for 2 weeks with no activity.

gladiatorhl2’s picture

Issue summary: View changes

I suppose that this issue is again the same one and I am not sure that it is related to commerce 1.9 or to commerce cheque. When the payment method commerce_cheque is used, hook_commerce_payment_order_paid_in_full() is not triggered.

gladiatorhl2’s picture

I have found a problem. Sorry for the false alarm, it was not clear at all. I've spent a lot of time to fix this issue and test all the modules.