For DrupalCon sites, we want to limit people to buying one ticket per person. (If you want more, prepaid tickets can be bought in bulk, and then handed to the actual people for registration.) If someone already has a registration, we can use rules to alert users to their status on the product page, and remove the item from the cart as it is added. But we can't disable or replace the actual button. If someone misses the status message and clicks, it isn't great UI.

I think there should be a rules action to achieve this.

CommentFileSizeAuthor
#5 1909098.add_to_cart_availability.patch754 bytesrszrama
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

rszrama’s picture

Status: Active » Needs review

I'm pretty sure this is already works as is, so let me throw out a solution and see if it works for you:

  1. Create a new product pricing rule with the conditions you're using to determine if the customer has a registration.
  2. Also add a "Data value is empty" condition whose "Data to check" data selector is commerce-line-item:line-item-id and check the "Negate" checkbox.
  3. Add a "Set a data value" action whose "Data" data selector is commerce-line-item:commerce-unit-price:amount but leave the "Value" field blank.

The product pricing system currently answers two questions (we'll be splitting these out to separate events in D8): does the product have a valid sale price for the current user right now? and what is that sale price? By unsetting the unit price amount in a pricing rule, you're basically telling Commerce that the product does not have a valid sale price, and it will unset the button on the Add to Cart form accordingly.

Step 2 ensures that this only happens on the Add to Cart form, not for products already in a shopping cart. I can't recall exactly how this works for product displays unfortunately, so lemme know if it screws up pricing somewhere on the page. For an example of this, look at the default product pricing rule titled "Unset the price of disabled products in the cart."

drumm’s picture

Status: Needs review » Active

I did try that, but without step 2. In commerce_cart_add_to_cart_form() has

    // Do not allow products without a price to be purchased.
    if (is_null(commerce_product_calculate_sell_price($form_state['default_product']))) {
      $form['submit'] = array(
        '#type' => 'submit',
        '#value' => t('Product not available'),
        '#weight' => 50,
        // Do not set #disabled in order not to prevent submission.
        '#attributes' => array('disabled' => 'disabled'),
        '#validate' => array('commerce_cart_add_to_cart_form_disabled_validate'),
      );
    }
    else {
      $form['submit'] = array(
        '#type' => 'submit',
        '#value' => t('Add to cart'),
        '#weight' => 50,
      );
    }

commerce_product_calculate_sell_price() returns

Array
(
    [amount] => 
    [currency_code] => USD
    [data] => Array
        (
            [components] => Array
                (
                    [0] => Array
                        (
                            [name] => base_price
                            [price] => Array
                                (
                                    [amount] => 50000
                                    [currency_code] => USD
                                    [data] => Array
                                        (
                                            [components] => Array
                                                (
                                                )

                                        )

                                )

                            [included] => 1
                        )

                )

        )

)

It does blank out the amount, but doesn't make the price data structure null, which would disable the button.

I tried adding step 2, but I think there isn't a line item yet on viewing a product page, so line-item-id is empty.

I'm testing with commerce 1.4, is this something that has changed in 1.x-dev?

rszrama’s picture

Sorry, I instructed you backwards on Step 2. I was copying the condition from the default rule that only should operate on products in the shopping cart, not products on an Add to Cart form. If you un-negate it, does it work as expected?

drumm’s picture

No, I tried negated, un-negated, and without the condition. None disables the add to cart button.

rszrama’s picture

I'm not sure I realized we had this inconsistency between the Add to Cart form and shopping cart refresh process. Pretty clear we need the if statements to match, this being the one from the cart refresh process:

    // Delete this line item if it no longer has a valid price.
    $current_line_item_wrapper = entity_metadata_wrapper('commerce_line_item', $cloned_line_item);

    if (is_null($current_line_item_wrapper->commerce_unit_price->value()) ||
      is_null($current_line_item_wrapper->commerce_unit_price->amount->value()) ||
      is_null($current_line_item_wrapper->commerce_unit_price->currency_code->value())) {
      commerce_cart_order_product_line_item_delete($order, $cloned_line_item->line_item_id, TRUE);
    }

Can you test the attached patch? I think it'll fix this for ya and I can get it in for 1.5.

rszrama’s picture

Status: Active » Needs review

(Updating for test bot.)

drumm’s picture

Status: Needs review » Reviewed & tested by the community

Looks good!

rszrama’s picture

Status: Reviewed & tested by the community » Fixed

Great, thanks for the test, Neil. Glad it worked. : )

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

tahiticlic’s picture

Issue summary: View changes

A bit late, but solution using Rules only :

  1. use "Line item : After saving new line item" condition (sorry, French here, but you've got it!)
  2. use "Delete entity" action

It's not an answer to the question though, since it doesn't stop the add to cart. So you still have the "your product has been added to cart" :-(