I had a requirement recently to limit the number of total products, and/or the qty of each product, that can be used with a particular coupon. They wanted to be able to set the limit in the coupon edit form.

Not sure how common the requirement would be but I thought I'd post the code back to the project in case someone else could use it.

/**
 * Adds option to uc_coupon edit form
 */
function storemod_form_uc_coupon_add_form_alter(&$form, &$form_state, $coupon) {
  $value = $form['#uc_coupon'];
  $form['order_max'] = array(
    '#type' => 'fieldset',
    '#title' => t('Maximum order limits'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );
  $form['order_max']['maximum_qty'] = array(
    '#type' => 'textfield',
    '#title' => t('Maximum order quantity'),
    '#default_value' => isset($value->data['maximum_qty']) ? $value->data['maximum_qty'] : '',
    '#size' => 5,
    '#description' => t('If set, this is the maximum number of products in the cart for the coupon to be accepted.'),
  );
  $form['order_max']['maximum_qty_error'] = array(
    '#type' => 'textarea',
    '#title' => t('Max order quantity error message'),
    '#default_value' => isset($value->data['maximum_qty_error']) ? $value->data['maximum_qty_error'] : '',
    '#size' => 5,
    '#description' => t('Enter the message you would like to display when the coupon fails this validation.'),
  );
  $form['order_max']['maximum_qty_per_product'] = array(
    '#type' => 'textfield',
    '#title' => t('Maximum quantity per product'),
    '#default_value' => isset($value->data['maximum_qty_per_product']) ? $value->data['maximum_qty_per_product'] : '',
    '#size' => 5,
    '#description' => t('If set, this is the maximum number of each product in the cart for the coupon to be accepted.'),
  );
  $form['order_max']['maximum_qty_per_product_error'] = array(
    '#type' => 'textarea',
    '#title' => t('Max per product error message'),
    '#default_value' => isset($value->data['maximum_qty_per_product_error']) ? $value->data['maximum_qty_per_product_error'] : '',
    '#size' => 5,
    '#description' => t('Enter the message you would like to display when the coupon fails this validation.'),
  );
}

/**
 * hook_uc_coupon_presave().
 */
function storemod_uc_coupon_presave(&$coupon, $edit) {
  // Set max qty
  if (isset($edit['maximum_qty'])) {
    $coupon->data['maximum_qty'] = $edit['maximum_qty'];
    $coupon->data['maximum_qty_error'] = $edit['maximum_qty_error'];
  }
  // Set max qty per product
  if (isset($edit['maximum_qty_per_product'])) {
    $coupon->data['maximum_qty_per_product'] = $edit['maximum_qty_per_product'];
    $coupon->data['maximum_qty_per_product_error'] = $edit['maximum_qty_per_product_error'];
  }
}

/**
 * Add extra validation to a coupon.
 */
function storemod_uc_coupon_validate(&$coupon, $order, $account) {
  $qty = 0;
  $max_per_product = isset($coupon->data['maximum_qty_per_product']) && $coupon->data['maximum_qty_per_product'] > 0 ? $coupon->data['maximum_qty_per_product'] : NULL;
  
  // Run through products, building qty and checking for max per product
  $product_count = count($order->products);
  if ($product_count > 0) {
    foreach ($order->products as $product) {
      $qty += $product->qty;
      if (isset($max_per_product) && $product->qty > $max_per_product) {
        return !empty($coupon->data['maximum_qty_per_product_error']) ? $coupon->data['maximum_qty_per_product_error'] : t('This coupon is not valid for more than :product_count products.', array(':product_count' => $coupon->data['maximum_qty_per_product']));
      }
    }
  }
  // Max qty check
  if (isset($coupon->data['maximum_qty']) && $coupon->data['maximum_qty'] > 0) {
    if ($qty > $coupon->data['maximum_qty']) {
      return !empty($coupon->data['maximum_qty_error']) ? $coupon->data['maximum_qty_error'] : t('This coupon is not valid for more than :product_count products.', array(':product_count' => $coupon->data['maximum_qty']));
    }
  }
}

Comments

mgladding’s picture

Can this be used with the Drupal 6 version of the moule?

NenadP’s picture

Great feature, but for me it does not dissalow customer to enter more products than defined in maximum quantity!

NenadP’s picture

Oops, it works, in fact... i had issue with cache or something! Thanks for sharing code!

thalemn’s picture

How do I implement this code? As a module? Please advise, thank you!

thalemn’s picture

I was able to implement the code using a custom module. Works great!