i have a price table with different pricing per quantity. However, even if my lowest qty is 100, i can still add 1 item to the cart using the qty field. How can i (rules or otherwise) set this limit? nothing has worked so far

thanks!!

CommentFileSizeAuthor
#7 moq_field_on_product.png153.11 KBvegantriathlete
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

funkeyrandy’s picture

Status: Active » Fixed

if anyone needs this here is the rule i used to compare the min price table quantity with the current cart qty trying to be added:

{ "rules_add_to_cart_check" : {
    "LABEL" : "Add to Cart check",
    "PLUGIN" : "reaction rule",
    "REQUIRES" : [ "php", "rules", "commerce_rules_extra" ],
    "ON" : [ "line_item_quantity_changed" ],
    "IF" : [
      { "data_is" : {
          "data" : [ "commerce-line-item:quantity" ],
          "op" : "\u003C",
          "value" : {
            "select" : "commerce-product:product-id",
            "php" : { "code" : "$data= commerce_product_load($value) ;\r\nreturn $data-\u003Efield_pricing[\u0027und\u0027][0][\u0027min_qty\u0027];" }
          }
        }
      }
    ],
    "DO" : [
      { "entity_fetch" : {
          "USING" : { "type" : "commerce_product", "id" : [ "commerce-product:product-id" ] },
          "PROVIDE" : { "entity_fetched" : { "entity_fetched" : "Fetched entity" } }
        }
      },
      { "variable_add" : {
          "USING" : {
            "type" : "integer",
            "value" : {
              "select" : "entity-fetched:product-id",
              "php" : { "code" : "$data= commerce_product_load($value) ;\r\nreturn $data-\u003Efield_pricing[\u0027und\u0027][0][\u0027min_qty\u0027];" }
            }
          },
          "PROVIDE" : { "variable_added" : { "variable_added" : "Added variable" } }
        }
      },
      { "drupal_message" : {
          "message" : "Cannot add product to cart: Minimum Quantity not met.",
          "type" : "warning"
        }
      },
      { "data_set" : { "data" : [ "commerce-line-item:quantity" ], "value" : "0" } }
    ]
  }
}

cheers!

Status: Fixed » Closed (fixed)

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

msrc_spinks’s picture

Do you have any details on using this? I added the rule but it isn't going into effect.

vegantriathlete’s picture

Issue summary: View changes

Notice the dependencies for the rule: You must have the php filter enabled (BAD IDEA!) and you must also have commerce_rules_extra.

I used the idea of adding commerce_rules_extra to get the event of updating a line item quantity. But, then I wrote my own custom rules condition to check that the line item meets the minimum order quantity. I also used the Entity Delete action to remove the line item from the cart if the user attempted to set the quantity to less than the MOQ.

vegantriathlete’s picture

Define a custom condition

/**
 * Implements hook_rules_condition_info().
 */
function mymodule_rules_condition_info() {
  $conditions = array();
  $conditions['mymodule_commerce_line_item_quantity_meets_moq'] = array(
    'label' => t('Line Item Quantity is greater than or equal to MOQ'),
    'parameter' => array(
      'commerce_line_item' => array(
        'type' => 'commerce_line_item',
        'label' => t('Line Item'),
        'description' => t('The line item that whose quantity should be checked  against the MOQ. If the specified line item (quantity) does not exist, the comparison will act as if the quantity does not meet the MOQ.'),
      ),
    ),
    'group' => t('MyModule Custom'),
    'callbacks' => array(
      'execute' => 'mymodule_commerce_line_item_rules_compare_moq',
    ),
  );

  return $conditions;
}

Code the callback for the condition
NOTE: I happen to have a field attached to each product that specifies the MOQ. So, I'm not actually looking at the product price table.

/**
 * Condition callback: checks to see if a line item meets
 * the MOQ for an order.
 */
function mymodule_commerce_line_item_rules_compare_moq($line_item) {
  $line_item_wrapper = entity_metadata_wrapper('commerce_line_item', $line_item)
;
  if ($line_item_wrapper->quantity->value()) {
    $query = 'SELECT field_moq_value
              FROM {field_data_field_moq}
              WHERE entity_id = :product_id';
    $query_arguments = array(
      ':product_id' => $line_item_wrapper->commerce_product->product_id->value()
,
    );
    $quantity = db_query($query, $query_arguments)->fetchField();
    if ($line_item_wrapper->quantity->value() >= $quantity) {
      return TRUE;
    }
  }
  return FALSE;
}
Summit’s picture

Hi @vegantriathlete,
What sort of field is it you add to your product, and is it named field_moq ?
Can you also remove the line then...Product added to shoppingcard...because this is not the case if minimum quantity is not met?
Thanks for answering in advance!
Greetings, Martijn

vegantriathlete’s picture

FileSize
153.11 KB

@Summit

I added a plain text field to the product.

I don't understand your next question. I've got a custom condition that checks for MOQ. If the condition is false, then the action that is triggered is the Entity Delete to remove the line item.

joknjokn’s picture

Hi. Thank you for the Rule. It works fine, except that it's possible to update the qunatity in the cart-view. The warning-message still appears, but the quantity is set to what ever the user chooses.

Any idea how to fix this?

funkeyrandy’s picture

i disabled the qty field in the cart view :)

Andreas Radloff’s picture

Slightly related, I have just published a module for limiting the minimum quantity based on a multiplier so you're only allowed to add, say, 10s of items to your cart. https://www.drupal.org/project/commerce_fixed_quantity

funkeyrandy’s picture

NICE!!

joknjokn’s picture

I made a rule that fits my needs.
If the quantity of a line item becomes lower than the lowest interval-amount of the Price Table, but not 0, the quantity of the line item is set to the lowest interval-amount (minimum quantity), and displays an informative message to the user. It works both on the product display-page and when updating the cart at the View cart-page.

I don't think my solution is efficient, using PHP-condition, but I don't know what else to do.

{ "rules_add_to_cart_minimum_quantity_check" : {
    "LABEL" : "Add to cart minimum quantity check",
    "PLUGIN" : "reaction rule",
    "WEIGHT" : "10",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "php", "entity" ],
    "ON" : { "commerce_order_update" : [], "commerce_order_presave" : [] },
    "IF" : [
      { "entity_has_field" : { "entity" : [ "commerce-order" ], "field" : "commerce_line_items" } },
      { "php_eval" : { "code" : "global $user;\r\nif ( isset($commerce_order-\u003Ecommerce_line_items[\u0027und\u0027])) {\r\n$line_items = $commerce_order-\u003Ecommerce_line_items[\u0027und\u0027];\r\nforeach ($line_items as $lid) {\r\n   $line_item = commerce_line_item_load($lid[\u0027line_item_id\u0027]);\r\n\tif ( isset($line_item-\u003Ecommerce_product) \u0026\u0026 intval($line_item-\u003Equantity) \u003E 0) {\r\n       $pid = $line_item-\u003Ecommerce_product[\u0027und\u0027][0][\u0027product_id\u0027];\r\n       $product =  commerce_product_load($pid);\r\n           if ($product-\u003Efield_priser[\u0027und\u0027][0][\u0027min_qty\u0027] \u003E $line_item-\u003Equantity) {\r\n$line_item-\u003Equantity = $product-\u003Efield_price_table[\u0027und\u0027][0][\u0027min_qty\u0027];\r\ncommerce_line_item_save($line_item);\r\n\r\n$commerce_order-\u003Eerrormessage = \u0027The product \u0027.$product-\u003Etitle.\u0027 has a minimum quantity of \u0027.$product-\u003Efield_price_table[\u0027und\u0027][0][\u0027min_qty\u0027].\u0027 pieces.\u0027;\r\n             return TRUE;\r\n           }\r\n\t}\r\n}\r\n}\r\nreturn FALSE;" } }
    ],
    "DO" : [
      { "variable_add" : {
          "USING" : {
            "type" : "text",
            "value" : "\u003C?php return $commerce_order-\u003Eerrormessage; ?\u003E"
          },
          "PROVIDE" : { "variable_added" : { "variable_added" : "Added variable" } }
        }
      },
      { "drupal_message" : {
          "message" : "Alert! [variable-added:value]",
          "type" : "warning"
        }
      }
    ]
  }
}

The cleaned php-eval:

global $user;
if ( isset($commerce_order->commerce_line_items['und'])) {
	$line_items = $commerce_order->commerce_line_items['und'];
	foreach ($line_items as $lid) {
		$line_item = commerce_line_item_load($lid['line_item_id']);
		if ( isset($line_item->commerce_product) && intval($line_item->quantity) > 0) {
			$pid = $line_item->commerce_product['und'][0]['product_id'];
			$product =  commerce_product_load($pid);
			if ($product->field_price_table['und'][0]['min_qty'] > $line_item->quantity) {
				$line_item->quantity = $product->field_price_table['und'][0]['min_qty'];
				commerce_line_item_save($line_item);

				$commerce_order->errormessage = 'The product '.$product->title.' has a minimum quantity of '.$product->field_priser['und'][0]['min_qty'].' pieces.';
             			return TRUE;
			}
		}
	}
}
return FALSE;