[SOLVED] Removing line items from an order if they're prohibited
I trying to use Rules to restrict the purchase of certain products from customers in certain states(slingshots in New Mexico). I tried this several different ways, but cannot quite get all the pieces in place. With my last attempt, the rules setup was as follows.
Calculating the sell price of a product
Has Address Component(State/NM)
Redirect to cart page
The problem I am now having is that this creates an infinite redirect loop. I assume this is do to the caching of the mailing zip. How do I prevent this loop and allow users to remove the slingshot from the cart? Another setup I tried used the Select available payment methods for an order event, but with this event I was not able to access all of the information I needed with the data selector. Any help would be unbelievably appreciated.
Unfortunately, you don't yet
Unfortunately, you don't yet know when calculating the sale price whether they are from New Mexico. "Calculating the sale price" is used all over the place.
I think you have to do this after you've collected the shipping/billing address, and create a checkout pane that explains why they can't purchase. And empties their order?
Cannot find Appropriate Event
With other events, I cannot seem to be able to call the tags into scope with the method I have seen referenced in so many places here. I have tried selecting a number of events, but every event I try besides the "calculating the sale price" event products a list of line items(0,1,2,3) to select for in the data selector. I can select one (say 0) and use it to pull product into scope and look for the tag, but this method seems to break if the slingshot is the second item in the cart (say line item 1). Is there a way to look at all line items for a product and then each of those products for a specific tag?
Adding Or's Breaks Function
Additionally, I have tried adding or statements for each of the line items listed in my data selector. When this is done, the actions do not take place. I have attached several screen shots to give you some more insight into the configuration I am trying. The first is the multiple line items in the data selector, which is where I am having the tag "scoping" issue. The second is the configuration that has gotten me closest to the function i require, but it only works on the first line item in the cart. The third is the configuration I tried with or statements, trying to check each line item for product and tag.
This doesn't seem like it should be this complex, and yet here I am offering screenshots to the commerce gods. I feel like there is something I am missing with the rules configuration, but I have no clue what it is. I appreciate any and all insight into how to add this function to my site.
How to remove a line items from an order using rules
A member on DrupalCommerce.org was asking how to create a rule that would prevent users in New Mexico from purchasing slingshots. I thought about it for awhile and decided this technique would work.
1. Add a field to the product that marks it as prohibited.
2. Create a rule that loops through all the line items when the order is about to be saved. Have it call a component (rules subroutine) for each line item to see if that line item should be removed.
3. Create the component that does the work. It needs to take two arguments (line item and the order-about-to-be-saved)
This turns out to do the trick, but there's a lesson in rules debugging in there too :-) The rule and component used are attached as textfiles.
[Sorry for the bad audio here... you might want to turn down the volume control. First time on a new machine.]
Removing Items From the Cart Using Rules from Randy Fay on Vimeo.
2 comments on your implementation
First, thank you Randy for the screencast. As a Drupal newbie I was looking for tips on how to loop through line items and your video was perfect. It helped me a lot implementing custom affiliation rules in order to use together Commerce Coupon, Affiliate-NG and Commerce Affiliate modules.
My 2 comments on your implementation:
1. Could moving the adress check to the main rule instead of the component save some processing time for all the times the customer does not live in NM? That way we would not loop through the line items if the customer does not live in NM.
2. I noticed at the end of your screencast that the prohibited line item was removed but the order total was still incorporating the $10 amount :( I did not work on this implementation so I don't know the solution out of my head. I don't think there is a DC action to update the order.
Doesn't Quite Work
HI rfay, I am a big fan of the work that you do and have found all of your videocasts extremely helpful. I tried following this video cast and it doesn't quite work properly and is confusing from a user perspective. One reason being the event that triggers the rule. By using "when saving an order" that happens during multiple times during the site experience. For example (and this is seen at the end of your cast) if a user already has address information entered that meets your conditions, the action fires upon adding to cart. Also, it's just plain weird to have an item removed from a cart. Many users might have alternate addresses (ie live in NJ and work in NY) and can easily change their shipping address to meet the criteria. Removing the items can be extremely frustrating, especially if there are multiple items in the cart.
It seems like the best experience would be to fire the rule on the event "Collecting shipping rates for an order." Then if the cart meets the criteria, restrict the user from being able to advance any further in checkout. However I have not found a way to prevent users from continuing the checkout process if certain conditions are met. The only checkout rules are for "completing the checkout process." It would be helpful if there were rules that could fire on events as the checkout process advances. For example in my case, I have the shipping calculated before the customer goes to the review order page. I would prefer for them to get the error message when they click on the "continue to next step" button. Another nice feature would be to fire a rule upon the event "begin checkout." When that event happens, check cart items and show a site message that says item A can't be shipped to a specific states and remove the state from the dropdown.
If anyone has any other tips on how to restrict sales to specific addresses, that would be great. Rules kinda gets me there, but it's not 100% working properly.
Removed line items still displayed in PDF invoice
I have created a specific rule based on Drupal roles. If you don't have the right role, you can not add a specific product to the cart. Then, the product is added and, after testing the user's roles, the product can be removed from the cart. At this point, we can imagine that the user would order other products available and checkout. In my case, a PDF invoice is created (Commerce PDF invoice) and unfortunately, the product previously removed is still in the cache (I presume) and appears in the PDF invoice, even if the user was not able to order it. Any idea why? Do you know any action we could add to the rule after removing the product to flush the PDF invoice cache or update the cart?
I hope I am clear enough about this specific procedure.
Thanks for any help or maybe any people I can contact about it.