Index: uc_aac.module =================================================================== --- uc_aac.module (revision 62) +++ uc_aac.module (working copy) @@ -38,8 +38,36 @@ * Implementation of hook_form_alter(). */ function uc_aac_form_alter($form_id, &$form) { - if (strstr($form_id, 'uc_product_add_to_cart_form_')) { - $priced_attributes = db_result(db_query("SELECT COUNT(oid) FROM {uc_product_options} WHERE price <> 0 AND nid = %d", $form['nid']['#value'])); + // If form belongs to a product or a product kit + if (strstr($form_id, 'uc_product_add_to_cart_form_') || strstr($form_id, 'uc_product_kit_add_to_cart_form_')) { + // If form belongs to a product + if (strstr($form_id, 'uc_product_add_to_cart_form_')) { + $priced_attributes = db_result(db_query("SELECT COUNT(oid) FROM {uc_product_options} WHERE price <> 0 AND nid = %d", $form['nid']['#value'])); + } + // If form belongs to a product kit + else if (strstr($form_id, 'uc_product_kit_add_to_cart_form_')) { + // Build array of product_id's belonging to the product kit and its sub-products + $products[] = $form['nid']['#value']; + $result = db_query("SELECT product_id FROM {uc_product_kits} WHERE nid = %d", $form['nid']['#value']); + while ($product = db_fetch_array($result)) { + $products[] = $product['product_id']; + } + + // Build attribute query + $product_count = count($products); + $sql_query = "SELECT COUNT(*) FROM {uc_product_options} WHERE price <> 0 AND ("; + for($i = 0; $i < $product_count; ++$i) { + if ($i != 0) { + $sql_query .= " ||"; + } + $sql_query .= " nid = %d"; + } + $sql_query .= " )"; + + $priced_attributes = db_result(db_query($sql_query, $products)); + } + + // If product or product kit has attribute options if ($priced_attributes >= 1) { drupal_add_js(drupal_get_path('module', 'uc_aac') .'/jquery.form.js'); drupal_add_js(_uc_aac_markup($form_id, $form['nid']['#value']), 'inline'); @@ -70,16 +98,38 @@ } function _uc_aac_markup($form_id, $nid) { - $result = db_query('SELECT sell_price FROM {uc_products} WHERE nid=%d AND vid=(SELECT vid FROM {node} WHERE nid=%d)', $nid, $nid); - $total_attributes = db_num_rows(db_query("SELECT * FROM {uc_product_attributes} WHERE nid = %d ORDER BY ordering", $nid)); - $price = array(); - $price['full'] = 0; - $price['discount'] = 0; - if ($product = db_fetch_object($result)) { - $price['full'] = $product->sell_price; + $result = db_query('SELECT sell_price FROM {uc_products} WHERE nid = %d AND vid=(SELECT vid FROM {node} WHERE nid = %d)', $nid, $nid); + + // If form belongs to a product + if (strstr($form_id, 'uc_product_add_to_cart_form_')) { + $total_attributes = db_num_rows(db_query("SELECT * FROM {uc_product_attributes} WHERE nid = %d ORDER BY ordering", $nid)); + } + // If form belongs to a product kit + else if (strstr($form_id, 'uc_product_kit_add_to_cart_form_')) { + // Build array of product_id's belonging to the product kit and it's sub-products + $products[] = $nid; + $result = db_query("SELECT product_id FROM {uc_product_kits} WHERE nid = %d", $nid); + while ($product = db_fetch_array($result)) { + $products[] = $product['product_id']; + } + + // Build attribute query + $product_count = count($products); + $sql_query = "SELECT * FROM {uc_product_attributes} WHERE"; + for($i = 0; $i < $product_count; ++$i) { + if ($i != 0) { + $sql_query .= " OR"; + } + $sql_query .= " nid = %d"; + } + $sql_query .= " ORDER BY ordering"; + + $total_attributes = db_num_rows(db_query($sql_query, $products)); } - if (module_exists('uc_discounts')) { - $price['discount'] = uc_discounts_product_discount_price($product); + + $price = 0; + if ($product = db_fetch_object($result)) { + $price = $product->sell_price; } $update_attributes = 0; if (variable_get('uc_aac_attribute_reprice', '1') == 1 && (variable_get('uc_attribute_option_price_format', 'adjustment') == 'adjustment' || $total_attributes > 1) && (variable_get('uc_attribute_option_price_format', 'adjustment') != 'none')) { @@ -95,8 +145,7 @@ * divs as 'node-$nid'. */ return ' - var replace_full_price_'. $nid .' = "'. uc_currency_format($price['full']) .'"; - var replace_discount_price_'. $nid .' = "'. uc_currency_format($price['discount']) .'"; + var replace_price_'. $nid .' = "'. uc_currency_format($price) .'"; var aac_'. $nid .'_update = 0; /** @@ -208,30 +257,16 @@ } } } - var currentfullHTML = $("#node-'. $nid .' .full_price").html(); - var currentsellHTML = $("#node-'. $nid .' .sell_price").html(); + var currentsellHTML= $("#node-'. $nid .' .sell_price").html(); var currentdisplayHTML = $("#node-'. $nid .' .display_price").html(); - updated_full_price = json_results.updated_full_price; - updated_discount_price = json_results.updated_discount_price; - if (currentfullHTML) { - $("#node-'. $nid .' .full_price").html(currentfullHTML.replace(replace_full_price_'. $nid .', updated_full_price)); - if (currentdisplayHTML) { - $("#node-'. $nid .' .display_price").html(currentdisplayHTML.replace(replace_discount_price_'. $nid .', updated_discount_price)); - } - if (currentsellHTML) { - $("#node-'. $nid .' .sell_price").html(currentsellHTML.replace(replace_discount_price_'. $nid .', updated_discount_price)); - } + updated_price = json_results.updated_price; + if (currentdisplayHTML) { + $("#node-'. $nid .' .display_price").html(currentdisplayHTML.replace(replace_price_'. $nid .', updated_price)); } - else { - if (currentdisplayHTML) { - $("#node-'. $nid .' .display_price").html(currentdisplayHTML.replace(replace_full_price_'. $nid .', updated_full_price)); - } - if (currentsellHTML) { - $("#node-'. $nid .' .sell_price").html(currentsellHTML.replace(replace_full_price_'. $nid .', updated_full_price)); - } + if (currentsellHTML) { + $("#node-'. $nid .' .sell_price").html(currentsellHTML.replace(replace_price_'. $nid .', updated_price)); } - replace_full_price_'. $nid .' = updated_full_price; - replace_discount_price_'. $nid .' = updated_discount_price; + replace_price_'. $nid .' = updated_price; } }, error: function() { @@ -250,56 +285,80 @@ function _uc_aac_calculate_price() { drupal_set_header("Content-Type: plain/text; charset=utf-8"); - $field_values = $_POST; - $nid = $field_values['uc_aac_nid']; - $product = db_fetch_object(db_query('SELECT sell_price FROM {uc_products} WHERE nid=%d AND vid=(SELECT vid FROM {node} WHERE nid=%d)', $nid, $nid)); - $updated_full_price = $product->sell_price; - $updated_discount_price = $product->sell_price; - $uc_discounts = module_exists('uc_discounts'); - $attributes = $field_values['attributes']; - $types = array(0 => "text", 1 => "select", 2 => "radio"); + + $nid = $_POST['uc_aac_nid']; // Product/Kit nid + $attributes = $_POST['attributes']; // Product/Kit attributes + $products = $_POST['products']; // Product Kit sub-products + + // Start $updated_price at the base_price + $updated_price = db_result(db_query('SELECT sell_price FROM {uc_products} WHERE nid=%d AND vid=(SELECT vid FROM {node} WHERE nid=%d)', $nid, $nid)); + if ($attributes) { - foreach ($attributes as $attribute) { - $aid = db_result(db_query('SELECT aid FROM {uc_attribute_options} WHERE oid = %d', $attribute)); - $display = db_result(db_query('SELECT display FROM {uc_product_attributes} WHERE aid = %d AND nid = %d', $aid, $nid)); - $options = db_query('SELECT DISTINCT upo.oid, uao.name, upo.cost, upo.price FROM {uc_attribute_options} AS uao LEFT JOIN {uc_product_options} AS upo ON uao.oid = upo.oid WHERE uao.aid = %d AND upo.nid = %d ORDER BY upo.ordering, uao.ordering, uao.name', $aid, $nid); - $names = array(); - $prices = array(); - while ($option = db_fetch_object($options)) { - $names[$option->oid] = $option->name; - $prices[$option->oid] = $option->price; - if ($option->oid == $attribute) { - $used_price[$aid] = $option->price; - $updated_full_price += $option->price; - // If uc_discounts module is installed - if($uc_discounts) { - // Update product price - $product->sell_price += $option->price; - // Update discount price - $updated_discount_price = uc_discounts_product_discount_price($product); - } - } + // Rebuild Product/Kit attributes and update price + $output['attributes'] = _uc_aac_rebuild_attributes($nid, $attributes, $updated_price); + } + + if ($products) { + // For each sub-product + foreach($products as $nid => $product) { + // Rebuild sub-product attributes and update price + $rebuilt_attributes = _uc_aac_rebuild_attributes($nid, $product['attributes'], $updated_price, TRUE); + if (is_array($output['attributes'])) { + $output['attributes'] = array_merge($output['attributes'], $rebuilt_attributes); } - $attribute_options = array(); - foreach ($prices as $oid => $attribute_price) { - $adjusted_price = $attribute_price - $used_price[$aid]; - $price_text = ''; - if ($adjusted_price != 0) { - if ($adjusted_price > 0) { - $price_text .= "+"; - } - $price_text .= uc_currency_format($adjusted_price); - } - $attribute_options[] = array('key' => $oid, 'label' => $names[$oid], 'adjustment' => $price_text); + else { + $output['attributes'] = $rebuilt_attributes; } - $output['attributes'][] = array('name' => 'attributes['. $aid .']', 'type' => $types[$display], 'options' => $attribute_options); } } - $output['updated_full_price'] = uc_currency_format($updated_full_price); - // If uc_discounts module is installed - if($uc_discounts) { - $output['updated_discount_price'] = uc_currency_format($updated_discount_price); - } + + $output['updated_price'] = uc_currency_format($updated_price); print drupal_to_js($output); exit(); } + +/** + * Rebuild attributes based on selection and update the price in the process + */ +function _uc_aac_rebuild_attributes($nid, $attributes, &$updated_price, $sub_product = FALSE) { + $updated_attributes = array(); + $types = array(0 => "text", 1 => "select", 2 => "radio"); + + foreach ($attributes as $attribute) { + $aid = db_result(db_query('SELECT aid FROM {uc_attribute_options} WHERE oid = %d', $attribute)); + $display = db_result(db_query('SELECT display FROM {uc_product_attributes} WHERE aid = %d AND nid = %d', $aid, $nid)); + $options = db_query('SELECT DISTINCT upo.oid, uao.name, upo.cost, upo.price FROM {uc_attribute_options} AS uao LEFT JOIN {uc_product_options} AS upo ON uao.oid = upo.oid WHERE uao.aid = %d AND upo.nid = %d ORDER BY upo.ordering, uao.ordering, uao.name', $aid, $nid); + $names = array(); + $prices = array(); + while ($option = db_fetch_object($options)) { + $names[$option->oid] = $option->name; + $prices[$option->oid] = $option->price; + if ($option->oid == $attribute) { + $used_price[$aid] = $option->price; + $updated_price += $option->price; + } + } + $attribute_options = array(); + foreach ($prices as $oid => $attribute_price) { + $adjusted_price = $attribute_price - $used_price[$aid]; + $price_text = ''; + if ($adjusted_price != 0) { + if ($adjusted_price > 0) { + $price_text .= "+"; + } + $price_text .= uc_currency_format($adjusted_price); + } + $attribute_options[] = array('key' => $oid, 'label' => $names[$oid], 'adjustment' => $price_text); + } + + if ($sub_product) { + $updated_attributes[] = array('name' => 'products['. $nid .'][attributes]['. $aid .']', 'type' => $types[$display], 'options' => $attribute_options); + } + else { + $updated_attributes[] = array('name' => 'attributes['. $aid .']', 'type' => $types[$display], 'options' => $attribute_options); + } + } + + // Return array of updated attributes + return $updated_attributes; +}