I am trying to programatically disable a product via a price rule. The price comes from a webservice and sets it fine. However if there is no price returned i wish to disable the item.

Approach #1:
In my rule I can safely and cleanly call

$line_item_wrapper->commerce_unit_price->data = commerce_price_component_delete(
          $line_item_wrapper->commerce_unit_price->value(),
          'base_price'
  );
  $line_item_wrapper->commerce_unit_price->amount = NULL;

This removes the price from displaying on the item, but still leaves the "Add to cart" button, and i believe so because of this line here
file: commerce_cart.module:1905

    // 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'),
        ...

Approach #2:

$line_item->commerce_unit_price[LANGUAGE_NONE][0]['data']['components'] = array();
// Clear price, disables item if no price is found
unset($line_item->commerce_unit_price[LANGUAGE_NONE][0]);

This way i am able to get the "Product not available" text appearing over the "add to cart" button, however i receive
Notice: Undefined index: amount in commerce_price_field_formatter_view() (line 442 of .../modules/contrib/commerce/modules/price/commerce_price.module).

Approach #3:
If I attempt to disable the product instance by programmatically setting it's 'status' to 0 nothing happens,

  $line_item_wrapper = entity_metadata_wrapper('commerce_line_item', $line_item);
  $product = commerce_product_load($line_item_wrapper->commerce_product->product_id->value());
  $product_wrapper = entity_metadata_wrapper('commerce_product', $product);
  $product_wrapper->status = 0; //disable

this is because the code that checks this calls the database and checks the status field there, and not one set in a loaded instance of the product.

file:commerce_cart.module:1479
$products = commerce_product_load_multiple($product_ids, array('status' => 1));

Can there be some formal way through code to possibly allow what I am doing, or is there another way?

Comments

svilleintel’s picture

Title: Programmatically disable item. » Programmatically disable product (via price set)
Status: Needs work » Needs review
StatusFileSize
new741 bytes

I have found a quick work around and that is to use approach #2 since it seems most effective at doing what I want, and requires the least and safest code changes in the commerce price module. Patch attached.

svilleintel’s picture

Status: Needs review » Patch (to be ported)
rszrama’s picture

Status: Patch (to be ported) » Needs review

Nothing in here to be ported; the issue and solution still need to be reviewed.

summit’s picture

Status: Needs review » Needs work

Hi,
I think that this #1 tries to be the functionality that when the price of a product is empty or zero (0.00) the product should not be shown in the node-display, right?
I tried #1 but this didn't work. When I have a product-entity with price 0 it is still shown in the node-display, it can be added to add-to-cart and sold.
This is not what I want and what I think the functionality wants to achieve. I want to be able to automatically disable products which prices are not filled or zero.
Would this be possible please?
Greetings, Martijn

summit’s picture

Issue summary: View changes

file path