It should be implemented in the field formatter and in the add to cart form views handler.

Use case:

You have a store that sells file downloads, and you want to prevent users from buying more than 1 of the same item. With the cart as view patch you can remove the quantity field from the cart view/form. But users still can add multiple items of the same product to the cart by clicking several times on the "Add to cart" button.

Comments

pcambra’s picture

Title: Add options for turning the "Add to cart" button into a "Remove to cart" button » Add options for turning the "Add to cart" button into a "Remove from cart" button

This won't prevent "advanced" user from adding additional items even if the form button is not there.

I think we may should add a global setting for "disallow users to buy more than one item from a given product" which would turn these formatter options automatically. This should check the "Add to cart" action and validate the number of items added.

We would need an extra formatter setting for turning the add to cart into a remove from cart or just hide the button.

rszrama’s picture

One possible way to restrict this would be through Rules... on the "After adding a product to the cart" event, you can check the quantity of the new line item. If it's greater than 1, you can update the quantity to 1 and display a message that the customer has already added that to their cart.

recidive’s picture

Ok, so we presumably can do this with rules.

@rszrama: do you think it makes sense turning the "Add to cart" button into "Remove from cart" button? And an option to just hide it completely?

recidive’s picture

Tagging.

recidive’s picture

Issue tags: +views, +dcsprint5
rszrama’s picture

Status: Active » Closed (won't fix)

I think it's a nice feature for a contributed module - I did something similar with "UC Restrict Qty" for Ubercart. I'm going to close this for now in preference of the Rules solution and to keep the core simpler.

denisr’s picture

Actually, it looks like that "After adding a product to the cart" trigger does not work. It is quite a while that I am trying to achieve the same result with Rules

johnpitcairn’s picture

Anyone wishing to implement something like this may find the following useful. Adapted from sample code at http://www.agileadam.com/add-to-cart-tweaks. Not intended as all-purpose generic module code, use at your own risk.

/**
 * Implements hook_form_alter().
 */
function mymodule_form_alter(&$form, &$form_state, $form_id) {
   if (strpos($form_id, 'commerce_cart_add_to_cart_form_') === FALSE) {
    return;
  }
  
  $my_product_type = 'product';

  if ($form_state['line_item']->type == $my_product_type && ($items = _mymodule_get_cart_items())) {
    $label = $form_state['line_item']->line_item_label;
    
    foreach ($items as $item) {
      // Assuming label equals unique SKU.
      if ($label == $item->line_item_label->value()) {
        // Change the cart button text.
        $form['submit']['#value'] = t('Remove from cart');
        
        // Replace the form submit handlers.
        $form['#submit'] = array('_mymodule_cart_remove_submit');
        
        // Pass the order ID through to the submit handler.
        $form['order_id'] = array(
          '#type' => 'hidden',
          '#value' => $item->order_id->value(),
        );
        
        // Pass the line item ID through to the submit handler.
        $form['line_item_id'] = array(
          '#type' => 'hidden',
          '#value' => $item->line_item_id->value(),
        );
        
        break;
      }
    }
  }
}

/**
 * Gets all line items in the current user's cart.
 *
 * @return
 *  An array of line items keyed by line item id, or FALSE.
 */
function _mymodule_get_cart_items() {
  $items = &drupal_static(__FUNCTION__);

  if (!isset($items)) {
    global $user;
    $items = array();
    
    if ($order = commerce_cart_order_load($user->uid)) {
      $order_wrapper = entity_metadata_wrapper('commerce_order', $order);
      
      foreach ($order_wrapper->commerce_line_items as $delta => $line_item_wrapper) {
        $id = $line_item_wrapper->line_item_id->value();
        $items[$id] = $line_item_wrapper;
      }
    }
  }

  return !empty($items) ? $items : FALSE;
}

/**
 * Replacement submit handler for add-to-cart button.
 *
 * @see mymodule_form_alter().
 */
function _mymodule_cart_remove_submit(&$form, &$form_state) {
  if ($order = commerce_order_load($form['order_id']['#value'])) {
    commerce_cart_order_product_line_item_delete($order, $form['line_item_id']['#value']);
  }
}