Restrict Qty
I'm trying to accomplish something similar to the functionality of Ryan's UC Restrict Qty module.
We have a site that will be selling digital downloads, and we don't want customers accidentally ordering more than one of any product (it would be a waste of their money, and we'd probably have to find a way to offer refunds etc).
I'm guessing there's probably a way to accomplish this with rules, but so far I've been unsuccessful. Any ideas?
Comments
It seems like it will suffice
It seems like it will suffice to set a rule with event "After adding item to cart" and action "Set a data value" to set "commerce-line-item:quantity" to 1.
Brilliant! Works like a
Brilliant! Works like a charm.
Thank you!
Limit Quantity or Disable edit to quantity in cart
I need to keep all quantities at "1" as well.
The tip above worked great when using the add to cart button. Is there a way to not allow user to edit the quantity in the cart located at mysite/cart ?
Got it to work...
I hope this helps someone. This allows users to "0" quantity and remove the item, as well as disallow any number higher than quantity of "1"
Create a new rule: Name it
Event: After updating an existing commerce line item
Add Action: Set a data value
-- Data Selector: commerce-line-item:quantity
-- Value: 1
Not working
I have set up both of these rules as I only want customers to be able to buy one ticket but neither seem to work.
As a test I set the add to cart event to remove all other items from the cart and that works for anon users but not the admin.
Any ideas why not?
I am also trying to figure out a rule that if the cart already has a product of type ticket in it, the user cannot add another ticket. I think I am going to need a loop?
David
I tried to add an action that
I tried to add an action that send a message to the user, when he tries to add a more than 1 quantity ... but the action *After updating an existing commerce line item event seems to be triggered on every page load/refresh ...
A same issue is being discussed here: http://drupal.stackexchange.com/questions/12113/how-do-i-copy-a-purchase...
ah sorry. Everything works as
ah sorry. Everything works as expetcted, as I forgot to add the proper conditions appointed in the adviced post ...
Creating the rule..
I am real new to Drupal, but have set rules and events for relating to a specific model (commerce flat rate). I really need to restrict this quantity also. Where Do I get access to this event? I am running Drupal 7 commerce kick start. Thanks!
Figured it out, duh !
Figured it out, duh !
Just what I need but..
I am new to Drupal. I am running on Drupal 7 with commerce kickstart as a base. If you could point me to documentation on how to do this I would appreciate it. I understand the solution but don't know how to find the event "After adding item to cart".
Geez I hadn't noticed rules
Geez I hadn't noticed rules section under config... me bad. Works great
Restrict to single product in cart
In accordance with the business rules, I used the following Drupal rule to restrict the cart to the single latest product a user has added only:
"Before adding a product to the cart" > IF "Total product quantity comparison" >=1 > "Remove all products from an order"
This rule basically removes the old product and adds the new one, if a product is added twice.
Export code:
{ "rules_restrict_to_single_product" : {
"LABEL" : "Restrict to single product",
"PLUGIN" : "reaction rule",
"REQUIRES" : [ "commerce_order", "commerce_cart", "rules" ],
"ON" : [ "commerce_cart_product_prepare" ],
"IF" : [
{ "commerce_order_compare_total_product_quantity" : {
"commerce_order" : [ "commerce_order" ],
"operator" : "\u003e=",
"value" : "1"
}
}
],
"DO" : [
{ "commerce_cart_empty" : { "commerce_order" : [ "commerce_order" ] } }
]
}
}
I hope that helps someone else.
its perfect, thank you a lot!
its perfect, thank you a lot!
Almost perfect... Just
Almost perfect... Just missing to check if the order is completed:
{ "rules_restrict_to_single_product" : {
"LABEL" : "Restrict to single product",
"PLUGIN" : "reaction rule",
"REQUIRES" : [ "commerce_order", "rules", "commerce_cart" ],
"ON" : [ "commerce_cart_product_prepare" ],
"IF" : [
{ "commerce_order_compare_total_product_quantity" : {
"commerce_order" : [ "commerce_order" ],
"operator" : "\u003E=",
"value" : "1"
}
},
{ "NOT data_is" : { "data" : [ "commerce-order:state" ], "value" : "completed" } }
],
"DO" : [
{ "commerce_cart_empty" : { "commerce_order" : [ "commerce_order" ] } }
]
}
}
Disable "Add to Cart" button for items that are already in cart
Here's how I've made sure users can only click the "add to cart" button on items that aren't already in their cart. On this site, we also only want to allow a quantity of 1 on all "program" items. Please let me know if I'm doing something wrong here... but it seems to be working great.
The input filter's markdown support is seriously breaking my comment syntax... I wish I knew how to fix this problem.
For now, a cleaner version of this code is here: http://drupalbin.com/21095
<?php
/**
* Implements hook_form_FORMID_alter().
*/
function mymodule_form_commerce_cart_add_to_cart_form_alter(&$form, &$form_state) {
$product_ids = mymodule_get_products_in_cart();
$line_item = $form_state['line_item'];
$product = commerce_product_load($line_item->commerce_product[LANGUAGE_NONE][0]['product_id']);
if ($product->type == 'program') {
if (in_array($product->product_id, $product_ids)) {
// Product is already in cart! We only want to allow a quantity of 1,
// so disable the submit button and change its text accordingly
$form['submit']['#disabled'] = TRUE;
$form['submit']['#value'] = t('Already in cart');
}
}
}
/**
* Return the product_id values for all products in the cart
*
* @return
* An array of product ids
*/
function mymodule_get_products_in_cart() {
$product_ids = &drupal_static(__FUNCTION__);
if (!isset($product_ids)) {
global $user;
$product_ids = array();
$order = commerce_cart_order_load($user->uid);
if ($order) {
$order_wrapper = entity_metadata_wrapper('commerce_order', $order);
foreach ($order_wrapper->commerce_line_items as $delta => $line_item_wrapper) {
$product_wrapper = $line_item_wrapper->commerce_product;
$product_ids[] = $product_wrapper->product_id->value();
}
}
}
return array_unique($product_ids);
}
?>
Thank you very much. This
Thank you very much.
This works perfect and is exactly what I have been looking for a long time.
Kirk
UPDATE! I've made some
UPDATE! I've made some changes to the code. Please read my blog post, where I explain some things in detail and provide a better code example. http://agileadam.com/add-to-cart-tweaks
you made my day
Thank you so much this works perfect.
Possible with just rules
Instead of writing a custom module this is possible within rules out of the box. Plus rules is a better solution when you only want to restrict the quantity of a SINGLE product. Below is an example:
{ "rules_force_index_quantity_to_1" : {
"LABEL" : "Force Index Quantity to 1",
"PLUGIN" : "reaction rule",
"REQUIRES" : [ "commerce_order", "rules", "entity" ],
"ON" : [ "commerce_line_item_presave" ],
"IF" : [
{ "commerce_order_contains_product" : {
"commerce_order" : [ "commerce-line-item:order" ],
"product_id" : "your_product_sku",
"operator" : "\u003E=",
"value" : "1"
}
},
{ "data_is" : { "data" : [ "commerce-line-item:type" ], "value" : "product" } },
{ "data_is" : {
"data" : [ "commerce-line-item:commerce-product:sku" ],
"value" : "your_product_sku"
}
}
],
"DO" : [
{ "data_set" : { "data" : [ "commerce-line-item:quantity" ], "value" : "1" } },
{ "drupal_message" : {
"message" : "This product has already been added to your cart and is limited to one per purchase",
"type" : "warning",
"repeat" : 0
}
}
]
}
}
thank you for sharing,
thank you for sharing, @JMOmandown.
Works for me.
This Rule does not update line item total!
Hi there,
This Rule works perfectly for forcing the line item quantity to 1 but it doesn't address the line item price.
So each time the user tries to change the quantity, the quantity is reset to 1 but the line item total is set to what it would be if the user's quantity change succeeded. So they get to checkout with a quantity of 1 but a price n times that.
Here is the Rule with another action to set the line item's total price to the line item product's unit price:
{ "rules_force_index_quantity_to_1" : {
"LABEL" : "Force Index Quantity to 1",
"PLUGIN" : "reaction rule",
"REQUIRES" : [ "commerce_order", "rules", "entity" ],
"ON" : [ "commerce_line_item_presave" ],
"IF" : [
{ "commerce_order_contains_product" : {
"commerce_order" : [ "commerce-line-item:order" ],
"product_id" : "your_product_sku",
"operator" : "\u003E=",
"value" : "1"
}
},
{ "data_is" : { "data" : [ "commerce-line-item:type" ], "value" : "product" } },
{ "data_is" : {
"data" : [ "commerce-line-item:commerce-product:sku" ],
"value" : "your_product_sku"
}
}
],
"DO" : [
{ "data_set" : { "data" : [ "commerce-line-item:quantity" ], "value" : "1" } },
{ "data_set" : {
"data" : [ "commerce-line-item:commerce-total" ],
"value" : [ "commerce-line-item:commerce-unit-price" ]
}
},
{ "drupal_message" : {
"message" : "This product has already been added to your cart and is limited to one per purchase",
"type" : "warning",
"repeat" : 0
}
}
]
}
}
Hi,
Hi,
We tried a lot of different options. At the end the most stable and reliable solution was to reuse the commerce_stock rules, copy and modify them to act on a custom field that we added to the product (Max quantity). This way:
* You can restrict the quantity per product
* The checks are performed in the commerce_cart_form
* The quantity is checked with old carts when heading to checkout
We're thinking of creating a module for this. Just email if you want the rules export.
Qty restriction
this is the rule we used,
{ "rules_limit_quantity_to_1" : {
"LABEL" : "Limit Quantity to 1",
"PLUGIN" : "reaction rule",
"OWNER" : "rules",
"TAGS" : [ "limited" ],
"REQUIRES" : [ "rules", "rules_i18n", "entity" ],
"ON" : { "commerce_line_item_presave" : [] },
"IF" : [
{ "entity_is_of_bundle" : {
"entity" : [ "commerce-line-item" ],
"type" : "commerce_line_item",
"bundle" : { "value" : { "product" : "product" } }
}
},
{ "data_is" : {
"data" : [ "commerce-line-item:commerce-product:sku" ],
"value" : "5010494924800"
}
}
],
"DO" : [
//set the line item value to 1
{ "data_set" : { "data" : [ "commerce-line-item:quantity" ], "value" : "1" } },
//display a message for the user
{ "drupal_message" : {
"message" : "This article is limited to 1 per person.",
"type" : "error",
"repeat" : "0"
}
},
// to prevent the total amount adding up you replace the total line item amount with the unit price
{ "data_set" : {
"data" : [ "commerce-line-item:commerce-total" ],
"value" : [ "commerce-line-item:commerce-unit-price" ] // to prevent the total amount adding up you replace the total line item amount with the unit price
}
}
]
}
}