In my testing I created a coupon that is only valid if a certain product is in the cart.

So, I created an order with the required product, started the checkout process and validated my coupon. This worked fine, recognising the product and taking a fixed amount off the order.

Now I cancel the order, go back and remove the required product, or change it's quantity or otherwise change my order. When I go back to checkout, the coupon is still applied.

My solution to this would be to create a rule which fires when something is added, deleted or changed in the order, and simply delete the line items added by the coupon.

The problem is, I can't see how to remove the effects of commerce_coupon_action_set_granted_amount

Setting it to zero makes it display zero rather than removing it. There's also the issue of finding and removing the coupon line item. I guess what we need here are additional action items for the rules system.

Any idea how this can be achieved?

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

darksnow’s picture

FileSize
1.2 KB

I think I solved this one.

I created a rule which fires on:
"commerce_line_item_update",
"commerce_cart_product_add",
"commerce_cart_product_remove"

I think these three cover anything that can happen after an order has been created. The action is custom code to look through the current order, find any coupon line items, get the coupon, delete the entry in the coupon log referenced by coupon and order ID, then remove the coupon line item from the order.

The effect of this is that a customer can start the checkout process and add a coupon, then cancel the checkout. The cart still has the coupon in it until this rule fires. This rule should ensure that any applied coupons are removed if the contents of the cart changes.

I cobbled this together reading the source for commerce, coupon, entity and a few other things so I think I've got both the things that need to be changed to clean up the coupon. If I've missed anything, or there's a better way to do this, I'd really appreciate the feedback.

Cheers and I hope this little snippet can help somebody else.

Martin...

z_khn06’s picture

I have created the rule as above but the coupon does not get removed.

darksnow’s picture

Have you turned on Rules debug to make sure that the rule fires at all?

It won't tell you if the code is working, but will tell you if the rules system is triggering the rule and getting to the code.

If it is, stick some debugging in the code using drupal_set_message("message") to see what's going on in there.

I user set message a lot to write the code, and it will tell you that the code is at least being run.

I hope that helps.

thehong’s picture

Component: Miscellaneous » Code
Category: feature » task
Status: Active » Needs work

I think we need a patch to update module default rule.

esdrubal’s picture

I've tried this rule but get the error Fatal error: __clone method called on non-object in /sites/all/modules/commerce/modules/cart/commerce_cart.module on line 736.

The removal of coupons once a user changes the cart would be something really helpful. Ideally we could have a rule's action under Rules Coupon (much like "Create Coupon Line Item" or "Set Coupon Granted Ammount") the would Delete Coupon Line Items from an order.

dags’s picture

Status: Needs work » Needs review
FileSize
2.38 KB

Here's a first attempt at a patch that provides a 'Remove coupon line item' action. This action will remove all coupons when the event and conditions are met.

dags’s picture

Oops, rolled it wrong. Here's an update.

anibal’s picture

Using only the rules, works, and the coupon is removed from the cart, but there is a error in the page of the site:

Error
The website encountered an unexpected error. Please try again later.
Status message
Coupon removed from order.
Error message
EntityMetadataWrapperException: Unable to get the data property commerce_total as the parent data structure is not set. in EntityStructureWrapper->getPropertyValue() (line 442 of /var/www/sites/dtc/cd-ai.com/subdomains/clientes/html/lusomundo2/profiles/commerce_kickstart/modules/entity/includes/entity.wrapper.inc).

dags’s picture

anibal,

I was also encountering this error, but had thought it was unique to my project. Guess not.

What's happening is our 'commerce_coupon_action_remove_coupon_line_item' action is running after the 'Remove product line item' event provided by commerce_cart.module. This event executes commerce_cart_order_product_line_item_delete() which invokes rules_invoke_all('commerce_cart_product_remove', ...) and that calls our action which uses coupon_log_remove() and that runs commerce_line_item_delete(). So I suppose it's a problem of recursion: it's trying to delete a line item that has already been deleted.

The solution was to hack up commerce/modules/cart/commerce_cart.module around line 1154 to load up the cached version of the order before executing commerce_order_save(). Sorry I don't have the exact code at the moment, I'll have to track it down. But it's not very pretty and there should be a better solution. I'll try to post an update soon.

Edit commerce/modules/cart/commerce_cart.module @ line #1153 to look like this:

if (!$skip_save) {
    $orders = commerce_order_load_multiple(array($order->order_id), array(), TRUE);
    $updated_order = reset($orders);

    commerce_order_save($updated_order);
   }

return $updated_order;
anibal’s picture

Thanks, i'll try it, but i think that the best will be to provide this as a patch so it can be included in the release.

dags’s picture

I opened an issue and uploaded the patch: http://drupal.org/node/1408464.

muschpusch’s picture

I think the action should look like this?

  $actions['commerce_coupon_action_remove_coupon_line_item'] = array(
    'label' => t('Remove coupon line item'),
    'group' => t('Commerce Coupon'),
    'parameter' => array(
      'commerce_order' => array(
        'type' => 'commerce_order',
        'label' => t('commerce order'),
      ),
      'commerce_line_item' => array(
        'type' => 'commerce_line_item',
        'label' => t('commerce line item'),
      ),
    ),
  );
muschpusch’s picture

Status: Needs review » Needs work

And i get an undefined function error for coupon_log_remove().

this isn't returning a value either:

$coupon_id = $line_item_wrapper->commerce_coupon_reference->value();

muschpusch’s picture

FileSize
2.54 KB

ok fixed it!

muschpusch’s picture

Status: Needs work » Needs review

and changing status sorry for the spam!

deggertsen’s picture

I patched with #14, but it didn't seem to fix the problem for me.

dags’s picture

Quick update: After moving to the latest stable Commerce release (7.x-1.2), the patch for Coupon is no longer necessary (see http://drupal.org/node/1408464).

jbloomfield’s picture

Category: task » bug

This does not seem to be fixed for me on 7.x-1.2

I have a coupon applied to the cart which I have a real hard time removing. I have cleared my browser history and cookies and if I log in I still have my items in the cart with the applied coupon. Makes it very hard to test rules etc.

Not sure why there isn't a "cancel coupon" button next to each applied coupon?

lukus’s picture

I agree; a remove coupon option on checkout would be very useful.

ahimsauzi’s picture

darksnow's rule in #1 did it.

pcambra’s picture

Title: Remove Coupon when order changes » Remove Coupons from the checkout
Category: bug » feature
Status: Needs review » Needs work

We totally need a solution for removing coupons, but we need some work there, I really don't think we should remove stuff from the coupon log but set it to disabled or unactive.

pcambra’s picture

Status: Needs work » Fixed

Most of the discussion of this issue has been pushed to the -dev version through #1443570: When removing a coupon from an order, remove it also from log and reset it so we have now an API and rules to remove coupons from the order.

Thanks to everyone participating in this issue!

Status: Fixed » Closed (fixed)

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