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;
+}
