With stock tracking enabled on a product, I am still able to use the quantity input field on a view to add a large quantity to my cart, exceeding the available stock. I can complete the order and the stock level ends up being large and negative.

The way the commerce_stock module works is to provide validation functions for the checkout and add to cart forms, but of course it doesn't do anything to the form created by commerce_add_to_cart_extras_handler_field_quantity.inc.

I'm not sure whether writing a stock check into that file is the right approach, or if there's a better way that this module could be made to respect stock limits.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

AaronBauman’s picture

Issue summary: View changes

bump

mglaman’s picture

For the curious, here's how I implemented the stock check via form_alter() in a custom module.

/**
 * Implements hook_form_alter().
 *
 * Since there are so many patches for such a small module, some will probably
 * fail. This implements Commerce Stock. We're doing it here because it changes
 * so much of the handler it would be impossible to manage.
 *
 * @todo: Try to move this upstream into Commerce Add to Cart Extras.
 */
function mymodule_form_alter(&$form, &$form_state, $form_id) {
  $is_quantity_form = FALSE;

  if (strpos($form_id, 'views_form_') === 0) {
    $view = $form_state['build_info']['args'][0];
    foreach ($view->field as $field) {
      if ($field instanceof commerce_add_to_cart_extras_handler_field_quantity) {
        $is_quantity_form = TRUE;
      }
    }
  }

  // Disable input boxes if needed, add validator.
  if ($is_quantity_form) {
    // Add our validator to invoke stock.
    $form['#validate'][] = 'mymodule_stock_validation';

    foreach (element_children($form['add_to_cart_quantity']) as $row_num) {
      // Commerce Stock doesn't provide this in its own function, so it has
      // to be replicated.
      $product = commerce_product_load($form['add_to_cart_quantity'][$row_num]['#product_id']);
      $stop = null;
      $product_wrapper = entity_metadata_wrapper('commerce_product', $product);

      if(isset($product_wrapper->commerce_stock) ){
        if (!(isset($product_wrapper->commerce_stock_override) && $product_wrapper->commerce_stock_override->value() == 1)) {
          if($product_wrapper->commerce_stock->value() <= 0){
            $form['add_to_cart_quantity'][$row_num]['#disabled'] = TRUE;
          }
        }
      }
    }
  }
}

/**
 * Validation handler to invoke Stock check.
 */
function mymodule_stock_validation($form, &$form_state) {
  foreach (element_children($form['add_to_cart_quantity']) as $row_num) {
    if ($form_state['values']['add_to_cart_quantity'][$row_num] > 0) {
      // We have a quantity worth checking.

      // Since we have a different form state, provide the Commerce Stock
      // validation module with what it needs.

      $stock_form_state = array(
        'input' => array(
          'quantity' => $form_state['values']['add_to_cart_quantity'][$row_num],
          'product_id' => $form['add_to_cart_quantity'][$row_num]['#product_id'],
        ),
      );
      commerce_stock_add_to_cart_validate($form, $stock_form_state);
    }
  }
}
lsolesen’s picture

Any reason why it is not added to this module with a check for whether the stock module exists?

mglaman’s picture

I only posted snippet because I have a feeling one of the RTBC'd patches will cause this patch to fail. Was going to see if RTBC could get pushed through then write proper patch.

AaronBauman’s picture

Status: Active » Needs review
FileSize
2.45 KB

Here's a patch.

joelpittet’s picture

Status: Needs review » Needs work

Would providing a hook here be useful so we can provide integration a bit better?

bisonbleu’s picture

I copy-pasted the code snippet in #2 in a custom module but it does not stop someone from adding more products than available in stock. I do realize it dates from 3 years ago. That being said, the checkout validation prevents that. I also tried the patch without success.

bisonbleu’s picture

Ah! I think I get it now. The code does not validate if there's enough stock to satisfy the bulk Add-to-cart form. But it will disable the quantity field in the bulk Add-to-cart form when the product is out of stock.

So we first need to be out of stock before this code kicks in.

But let's say product A has a stock level of 5. Any ideas how I could strop the Add-to-Cart from submitting if Quantity for product A is set to 6 or more?