Skip to content

Conversation

@ransomweaver
Copy link
Contributor

This PR only works if commerce is patched with drupalcommerce/commerce#593

This hook_form_alter in commerce_stock_local.module addresses several problems:

  1. the base AddToCartForm does not check availability, therefore always allows clicking "Add to Cart" even if not available. PR will check availability and disable button, changing button text to "Unavailable". This will work with whatever stock checker is in use (e.g. commerce_stock_backorderable which overrides the default checker).

  2. hook_form_alter AddToCart form object only gives the default purchaseable entity when loading the form via ajax or using query params (product/1?v=2), but if the form uses attributes to select the variation, there is a "selected_variation" storage key that we can use to load the correct variation.

@BBGuy
Copy link
Owner

BBGuy commented Oct 20, 2017

Hi @ransomweaver started looking into this and looks to me like we also need to update StockAvailabilityChecker.check as it currently only returns a Boolean or is this in another PR?
Just finishing for the week will continue next week.

@ransomweaver
Copy link
Contributor Author

@BBGuy You are right. Because I use my commerce_stock_backorderable module that follows PR 593 with its own checker returning AvailabilityResponse, this PR doesn't have the change to StockAvailabilityChecker. It is in PR #12, though that also has an old inferior version of this hook_form_alter code. I suggest you edit PR #12 to remove the change to commerce_stock_local and just take the change to the checker. Also I see I had made a redundant PR #17 that you can close.

$availability = $form_object->getAvailabilityManager()->check($variation, 1, $context);

if ($availability->isUnavailable()) {
$form['actions']['submit']['#value'] = t('Unavailable');
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should let the stock service determine the text for "Unavailable" but that can go after.

@BBGuy
Copy link
Owner

BBGuy commented Oct 24, 2017

Happy for this to go in after drupalcommerce/commerce#593 great work :)

@BBGuy
Copy link
Owner

BBGuy commented Oct 24, 2017

I closed the two old PR's and made a new one #38

@GarethSmall
Copy link

I modified this a bit so it doesn't require the patch you're speaking about.

function commerce_stock_local_form_alter(&$form, FormState $form_state, $form_id) {
  if (strpos($form_id, 'commerce_order_item_add_to_cart_form') === 0) {
    /** @var \Drupal\commerce_cart\Form\AddToCartForm $form_object */
    $form_object = $form_state->getBuildInfo()['callback_object'];
    
    $storage = $form_state->getStorage();

    $variation = isset($storage['selected_variation']) ? ProductVariation::load($storage['selected_variation'])
      : $form_object->getEntity()->getPurchasedEntity();
    
    if (empty($variation)) return;
    
    $stockServiceManager = \Drupal::service('commerce_stock.service_manager');
    $stock = $stockServiceManager->getStockLevel($variation);
    
    if ($stock <= 0) {
      $form['actions']['submit']['#value'] = t('Out of stock');
      $form['actions']['submit']['#attributes'] = [
        'disabled' => 'disabled',
      ];
    }
  }
}

@steveoriol
Copy link

If you use quantity input you can modif as follwing for add the max option:

function commerce_stock_local_form_alter(&$form, FormState $form_state, $form_id) {
  if (strpos($form_id, 'commerce_order_item_add_to_cart_form') === 0) {
    /** @var \Drupal\commerce_cart\Form\AddToCartForm $form_object */
    $form_object = $form_state->getBuildInfo()['callback_object'];
    
    $storage = $form_state->getStorage();

    $variation = isset($storage['selected_variation']) ? ProductVariation::load($storage['selected_variation'])
      : $form_object->getEntity()->getPurchasedEntity();
    
    if (empty($variation)) return;
    
    $stockServiceManager = \Drupal::service('commerce_stock.service_manager');
    $stock = $stockServiceManager->getStockLevel($variation);
    
    if ($stock <= 0) {
      $form['actions']['submit']['#value'] = t('Out of stock');
      $form['actions']['submit']['#attributes'] = [
        'disabled' => 'disabled',
      ];
      $form['quantity']['widget'][0]['value']['#default_value'] = 0;
      $form['quantity']['widget'][0]['value']['#min'] = 0;
      $form['quantity']['widget'][0]['value']['#max'] = 0;
    }
    else {
      $form['quantity']['widget'][0]['value']['#max'] = $stock;
    }
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants