diff -rupN uc_discounts/uc_discounts.admin.inc uc_discounts-fct/uc_discounts.admin.inc --- uc_discounts/uc_discounts.admin.inc 2010-01-08 12:00:21.000000000 -0500 +++ uc_discounts-fct/uc_discounts.admin.inc 2010-07-14 20:06:20.000000000 -0400 @@ -1,5 +1,5 @@ qualifying_type_options(), "#default_value" => $form_state["values"]["qualifying_type"], ); +// Multiple values patch + if(isset($form_state["values"]["qualifying_amount"])) + { + $form_state["values"]["qualifying_amount"] = unserialize($form_state["values"]["qualifying_amount"]); + if (is_array($form_state["values"]["qualifying_amount"])) + { + $form_state["values"]["qualifying_amount"] = implode(',', $form_state["values"]["qualifying_amount"]); + } + } + $form["qualifications"]["qualifying_amount"] = array( "#type" => "textfield", "#title" => t("Qualification amount"), - "#description" => t("The amount of qualification type required. E.g. 50 (for $50), 5 (for 5 items). Remember for a discount like 'buy 4 get 1 free' the qualifying amount is '5'."), + "#description" => t("The amount required to qualify for the discount. E.g. 50 (for $50), 5 (for 5 items). Remember for a discount like 'buy 4 get 1 free' the qualifying amount is '5'. Separate multiple values with a comma e.g. 5,10,15."), "#default_value" => $form_state["values"]["qualifying_amount"], "#size" => 15, "#required" => TRUE, + "#maxlength" => NULL, // Multiple values patch ); $has_qualifying_amount_max = isset($form_state["values"]["has_qualifying_amount_max"]) ? $form_state["values"]["has_qualifying_amount_max"] : HAS_QUALIFYING_AMOUNT_MAX_DEFAULT; @@ -242,8 +253,17 @@ function uc_discounts_form($form_state, "#options" => discount_type_options(), "#default_value" => $form_state["values"]["discount_type"], ); - - $form["discount_set"]["discount_amount"] = array( + // Multiple values patch + if(isset($form_state["values"]["discount_amount"])) + { + $form_state["values"]["discount_amount"] = unserialize($form_state["values"]["discount_amount"]); + if (is_array($form_state["values"]["discount_amount"])) + { + $form_state["values"]["discount_amount"] = implode(',', $form_state["values"]["discount_amount"]); + } + } + + $form["discount_set"]["discount_amount"] = array( "#type" => "textfield", "#title" => t("Discount amount"), "#description" => t("The amount of discount. E.g. 50 (for $50), 5 (for 5 items), or 0.05 (for 5%)"), @@ -391,9 +411,14 @@ function uc_discounts_form($form_state, //Create SKUs form element $options = array(); - $result = db_query("SELECT p.model, n.title FROM {uc_products} p, {node} n WHERE p.nid=n.nid ORDER BY p.model"); + //FCT adjustment SKU's patch query + $result = db_query("SELECT a.model, p.model AS pmodel, n.title + FROM {uc_products} p + LEFT OUTER JOIN {uc_product_adjustments} a ON p.nid = a.nid + INNER JOIN {node} n ON p.nid = n.nid"); $options[ALL_SKUS] = t(""); - while ($row = db_fetch_object($result)) $options[$row->model] = $row->model ." (". $row->title .")"; + // FCT adjustment SKU's patch conditional + while ($row = db_fetch_object($result)) $options[$row->model] = ($row->model ? $row->model : $row->pmodel) ." (". $row->title .")"; $form["discount_set"]["skus"] = array( "#type" => "select", "#title" => t("SKUs") . sprintf("*"), @@ -623,18 +648,47 @@ function uc_discounts_form_validate($for //Check discount_amount - if (($index = strpos($values["discount_amount"], "%")) !== FALSE) { - - $value = substr($values["discount_amount"], 0, $index); - - } - else $value = $values["discount_amount"]; - - if (!is_numeric($value)) { - form_set_error("discount_amount", t("Discount amount must be integer, decimal or percentage.")); - $has_errors = TRUE; - } - +// Multiple values patch +// Check qualifying and discount amount(s) + $fields = array("qualifying_amount" => -1, "discount_amount" => -1); + foreach ($fields as $field => $value) + { + $form_state["values"][$field] = array_filter(array_map("_uc_discounts_trim_values", explode(',', $form_state["values"][$field])), "_uc_discounts_filter_values"); + } + + if (count($form_state["values"]["qualifying_amount"]) != count($form_state["values"]["discount_amount"])) + { + $error_field = count($form_state["values"]["discount_amount"]) > count($form_state["values"]["qualifying_amount"]) ? 'discount_amount' : 'qualifying_amount'; + form_set_error($error_field, t("There are too many values in the !field field. (Qualifying and discount amount fields must have the same number of values).", array("!field" => $error_field))); + $has_errors = TRUE; + } + else + { + for ($i = 0; $i < count($form_state["values"]["discount_amount"]); $i++) + { + if (($index = strpos($form_state["values"]["discount_amount"][$i], "%")) !== FALSE) + { + $form_state["values"]['discount_amount'][$i] = drupal_substr($form_state["values"]['discount_amount'][$i], 0, $index) / 100; + } + foreach ($fields as $field => $amount) + { + if (!is_numeric($amount)) + { + form_set_error($field, t("Incorrect or blank amount entered: @amount", array("@amount" => $amount))); + $has_errors = TRUE; + } + elseif ($form_state["values"][$field][$i] <= $amount) + { + form_set_error($field, t("!field must be sequential (error at @amount), e.g. 5,6,7.", array("!field" => $field, "@amount" => $form_state["values"][$field][$i]))); + $has_errors = TRUE; + } + else + { + $fields[$field] = $form_state["values"][$field][$i]; + } + } + } + } if ($values["filter_type"] == FILTER_TYPE_PRODUCTS) { if (empty($values["product_ids"])) { @@ -681,6 +735,22 @@ function uc_discounts_form_validate($for } } +// Multiple values patch +/** + * Callback for array_map in uc_discounts_form_validate(). + */ +function _uc_discounts_trim_values($var) { + return preg_replace("/\s+/", "", $var); +} +/** + * Callback for array_filter in uc_discounts_form_validate(). + */ +function _uc_discounts_filter_values($var) { + if ($var != "") { + return TRUE; + } +} + /** * Submit handler for uc_discounts_form(). */ @@ -732,10 +802,16 @@ function uc_discounts_form_submit($form, else $expiration = 0; //Set discount_amount - if (($index = strpos($form_state["values"]["discount_amount"], "%")) !== FALSE) - $discount_amount = floatval(substr($form_state["values"]["discount_amount"], 0, $index)) / 100; - } - else $discount_amount = floatval($form_state["values"]["discount_amount"]); + // Multiple values patch - todo - need to add this validation for patched version +// if ($form_state["values"]["discount_amount"] && (strpos($form_state["values"]["discount_amount"], "%")) !== FALSE) +// $discount_amount = floatval(substr($form_state["values"]["discount_amount"], 0, $index)) / 100; + } + else $discount_amount = serialize($form_state["values"]["discount_amount"]); + + // Multiple values patch + $form_state["values"]["discount_amount"] = serialize($form_state["values"]["discount_amount"]); + $discount_amount = $form_state["values"]["discount_amount"]; + $form_state["values"]["qualifying_amount"] = serialize($form_state["values"]["qualifying_amount"]); if (empty($form_state["values"]["discount_id"])) { //Insert base discount diff -rupN uc_discounts/uc_discounts.install uc_discounts-fct/uc_discounts.install --- uc_discounts/uc_discounts.install 2009-10-04 20:58:21.000000000 -0400 +++ uc_discounts-fct/uc_discounts.install 2010-07-14 10:23:08.000000000 -0400 @@ -39,9 +39,8 @@ function uc_discounts_schema() { "default" => 0, ), "qualifying_amount" => array( - "type" => "float", - "not null" => TRUE, - "default" => 0.0, + "type" => "text", + "size" => "big", "description" => t("Minimum quantity or price required to qualify for this discount."), ), "has_qualifying_amount_max" => array( @@ -63,9 +62,8 @@ function uc_discounts_schema() { "default" => 0, ), "discount_amount" => array( - "type" => "float", - "not null" => TRUE, - "default" => 0.0, + "type" => "text", + "size" => "big", "description" => t("Amount to discount (i.e. 1 free item, 25%, or $2.00)"), ), "requires_code" => array( @@ -541,6 +539,20 @@ function uc_discounts_update_5() { db_add_column($queries, "uc_discounts", "required_product", "varchar(255)", array("not null" => TRUE, "default" => "") ); + $new_schemas = array( + "qualifying_amount" => array( + "type" => "text", + "size" => "big", + "description" => t("Minimum quantity or price required to qualify for this discount."), + ), + "discount_amount" => array( + "type" => "text", + "size" => "big", + "description" => t("Amount to discount (i.e. 1 free item, 25%, or $2.00)"), + ), + ); + db_change_field($queries, "uc_discounts", "qualifying_amount", "qualifying_amount", $new_schemas["qualifying_amount"]); + db_change_field($queries, "uc_discounts", "discount_amount", "discount_amount", $new_schemas["discount_amount"]); break; } diff -rupN uc_discounts/uc_discounts.js uc_discounts-fct/uc_discounts.js --- uc_discounts/uc_discounts.js 2010-07-07 17:20:43.000000000 -0400 +++ uc_discounts-fct/uc_discounts.js 2010-07-14 22:30:22.000000000 -0400 @@ -11,14 +11,14 @@ function uc_discountsOnLoad(context) uc_discountsProcessCodes(context); - //Add click event listener to discounts pane button once - $("input[@id*=uc-discounts-button]:not(.uc_discountsOnLoad-processed)", - context).addClass("uc_discountsOnLoad-processed").click(function() - { - uc_discountsProcessCodes(context); - //Return false to prevent default actions and propogation - return false; - }); + //Add click event listener to discounts pane button once + $("input[id*=uc-discounts-button]:not(.uc_discountsOnLoad-processed)", + context).addClass("uc_discountsOnLoad-processed").click(function() + { + uc_discountsProcessCodes(context); + //Return false to prevent default actions and propogation + return false; + }); } //Processes currently entered discounts @@ -31,22 +31,22 @@ function uc_discountsProcessCodes(contex return; } - var parameterMap = {}; - parameterMap["uc-discounts-codes"] = $("textarea[@id*=uc-discounts-codes]", context).val(); + var parameterMap = {}; + parameterMap["uc-discounts-codes"] = $("textarea[id*=uc-discounts-codes]", context).val(); - //Show loading container - var progress = new Drupal.progressBar("uc_discountsProgress"); - progress.setProgress(-1, Drupal.settings.uc_discounts.progress_msg); - var messages_container = $(".uc-discounts-messages-container"); - messages_container.empty().append(progress.element); - messages_container.addClass("solid-border"); - - $.ajax({ - type: "POST", - url: Drupal.settings.basePath + "?q=cart/checkout/uc_discounts/calculate", - data: parameterMap, - complete : function(xmlHttpRequest, textStatus) - { + //Show loading container + var progress = new Drupal.progressBar("uc_discountsProgress"); + progress.setProgress(-1, Drupal.settings.uc_discounts.progress_msg); + var messages_container = $(".uc-discounts-messages-container"); + messages_container.empty().append(progress.element); + messages_container.addClass("solid-border"); + + $.ajax({ + type: "POST", + url: Drupal.settings.basePath + "?q=cart/checkout/uc_discounts/calculate", + data: parameterMap, + complete : function(xmlHttpRequest, textStatus) + { //Hide loading container $(".uc-discounts-messages-container").removeClass("solid-border").empty(); diff -rupN uc_discounts/uc_discounts.module uc_discounts-fct/uc_discounts.module --- uc_discounts/uc_discounts.module 2009-11-26 12:21:45.000000000 -0500 +++ uc_discounts-fct/uc_discounts.module 2010-07-14 21:16:56.000000000 -0400 @@ -1,5 +1,5 @@ discount_id); while ($row = db_fetch_array($result)) $product_ids[] = $row["nid"]; return $product_ids; - - case FILTER_TYPE_SKUS: - $query = "SELECT DISTINCT p.nid FROM {uc_products} p - INNER JOIN {uc_discounts_skus} ds ON p.model=ds.sku - WHERE ds.discount_id=%d"; - uc_discounts_log($query); - $result = db_query($query, $discount->discount_id); - while ($row = db_fetch_array($result)) $product_ids[] = $row["nid"]; - return $product_ids; - - case FILTER_TYPE_CLASS: - $query = "SELECT DISTINCT n.nid FROM {node} n - INNER JOIN {uc_discounts_classes} dcl ON n.type=dcl.class - WHERE dcl.discount_id=%d"; + +// FCT adjustment SKU's patch query + case FILTER_TYPE_SKUS: + $query = "SELECT a.nid AS anid, p.nid AS pnid + FROM uc_discounts_skus ds + LEFT OUTER JOIN uc_product_adjustments a ON ds.sku = a.model + LEFT OUTER JOIN uc_products p ON ds.sku = p.model + WHERE ds.discount_id = %d"; uc_discounts_log($query); $result = db_query($query, $discount->discount_id); - while ($row = db_fetch_array($result)) $product_ids[] = $row["nid"]; - return $product_ids; + // FCT adjustment SKU's patch conditional + while ($row = db_fetch_array($result)) $product_ids[] = ($row["pnid"] ? $row["pnid"] : $row["anid"]); + return array_unique($product_ids); } return array(); } @@ -1320,9 +1317,11 @@ function get_discounts_for_order($order, break; } } - + // Multiple values patch + $discount->qualifying_amount = unserialize($discount->qualifying_amount); + $discount->discount_amount = unserialize($discount->discount_amount); //If order does not qualify for this discount - if ($order_qualifying_amount < $discount->qualifying_amount) { + if ($order_qualifying_amount < $discount->qualifying_amount[0]) { //If this is a coded discount, add warning message if (!is_null($warnings) && !is_null($discount->code)) { switch ($discount->qualifying_type) { @@ -1342,6 +1341,15 @@ function get_discounts_for_order($order, } continue; } + // Multiple values patch + else { + for ($i = 0; $i < count($discount->qualifying_amount); $i++) { + if ($order_qualifying_amount < $discount->qualifying_amount[$i]) { + break; + } + $discount->qualifying_tier = $i; + } + } //If this discount has a maximum qualifying amount and the order exceeds it if ($discount->has_qualifying_amount_max && ($order_qualifying_amount > $discount->qualifying_amount_max)) { @@ -1366,8 +1374,9 @@ function get_discounts_for_order($order, } //Determine number of times to apply discount - if ($discount->qualifying_amount != 0) { - $discount->times_applied = (int)($order_qualifying_amount / $discount->qualifying_amount); + // Multiple values patch + if ($discount->qualifying_amount[$discount->qualifying_tier] != 0) { + $discount->times_applied = (int)($order_qualifying_amount / $discount->qualifying_amount[$discount->qualifying_tier]); } else $discount->times_applied = 1; if ($discount->max_times_applied != 0) { @@ -1395,6 +1404,8 @@ function get_discounts_for_order($order, $this_product_price = $this_product->price; $product_sum = $product_sum + $this_product_price; } + // Multiple values patch + $discount->amount = $product_sum - ($product_sum * $discount->discount_amount[$discount->qualifying_tier]); } $discount->amount = $product_sum * $discount->discount_amount; break; @@ -1403,7 +1414,8 @@ function get_discounts_for_order($order, $discount_amount = 0; //The variable free_items_remaining is the [max] number of free items for the order - $free_items_remaining = $discount->discount_amount * $discount->times_applied; + // Multiple values patch + $free_items_remaining = $discount->discount_amount[$discount->qualifying_tier] * $discount->times_applied; //Loop until all free items have been applied or there are no more products to //discount (discount cheapest first) @@ -1491,8 +1503,9 @@ function get_discounts_for_order($order, if ($are_equal) { //($last_discount->amount / $last_discount->discount_amount) == last discount's subtotal - $local_order_subtotal = ($last_discount->amount / $last_discount->discount_amount); - $discount->amount = $local_order_subtotal * $discount->discount_amount; + // Multiple values patch + $local_order_subtotal = ($last_discount->amount / $last_discount->discount_amount[$last_discount->qualifying_tier]); + $discount->amount = $local_order_subtotal * $discount->discount_amount[$discount->qualifying_tier]; break; } } @@ -1511,23 +1524,27 @@ function get_discounts_for_order($order, foreach ($order_and_discount_products as $product) { $discounted_products_amount += $product->price * $product->qty; } - $discount->amount = $discounted_products_amount * $discount->discount_amount; + // Multiple values patch + $discount->amount = $discounted_products_amount * $discount->discount_amount[$discount->qualifying_tier]; // Discount the subtotal so far } else { - $discount->amount = max($order_subtotal - $total_discount_amount, 0) * $discount->discount_amount; + // Multiple values patch + $discount->amount = max($order_subtotal - $total_discount_amount, 0) * $discount->discount_amount[$discount->qualifying_tier]; } //End patch from lutegrass break; case DISCOUNT_TYPE_FIXED_AMOUNT_OFF: - $discount->amount = $discount->discount_amount * $discount->times_applied; + // Multiple values patch + $discount->amount = $discount->discount_amount[$discount->qualifying_tier] * $discount->times_applied; break; case DISCOUNT_TYPE_FIXED_AMOUNT_OFF_PER_QUALIFYING_ITEM: //Discount is the total quantity of qualifying items in order (order_qualifying_amount) //times the discount amount - $discount->amount = $discount->discount_amount * $order_qualifying_amount; + // Multiple values patch + $discount->amount = $discount->discount_amount[$discount->qualifying_tier] * $order_qualifying_amount; break; } @@ -1616,14 +1633,12 @@ function get_codeless_discounts_for_prod //Get SKUs for product $skus = array(); $skus[] = "'". db_escape_string(ALL_SKUS) ."'"; - $result = db_query("SELECT DISTINCT model FROM {uc_products} WHERE nid=%d", $product->nid); - while ($row = db_fetch_array($result)) $skus[] = "'". db_escape_string($row["model"]) ."'"; - - //Get classes for product - $classes = array(); - $classes[] = "'". db_escape_string(ALL_CLASSES) ."'"; - $result = db_query("SELECT DISTINCT type FROM {node} WHERE nid=%d", $product->nid); - while ($row = db_fetch_array($result)) $classes[] = "'". db_escape_string($row["type"]) ."'"; + // FCT Multiple SKU's patch Query + $result = db_query("SELECT DISTINCT a.model, p.model AS pmodel FROM {uc_products} p + LEFT OUTER JOIN {uc_product_adjustments} a ON p.nid = a.nid + WHERE p.nid = %d", $product->nid); + // FCT Multiple SKU's patch Conditional + while ($row = db_fetch_array($result)) $skus[] = "'". db_escape_string($row["model"] ? $row["model"] : $row["pmodel"]) ."'"; //Create roles clause global $user;