I am a relative n00b with regard to oscommerce, but not php or mysql in general.
I have recently installed the Bundled Products contrib to my new oscommerce site and was very happy with how it worked, until I realized that it wasn't updating the stock/quantity of the individual items in the bundle, while it was updating the stock of the master.
I realized that the IPN module was somehow interfering with the stock update part of the product bundle contrib and, although it doesn't say so anywhere, a n00b like me didn't think about the fact that the IPN module repeats the stock update section from catalog/checkout_process.php, thereby superceding the necessary mod.
So if you've got the IPN module, in addition to changing catalog/checkout_process.php, you've got to change catalog/includes/module/payment/paypal_ipn.php from:
for ($i=0, $n=sizeof($order->products); $i<$n; $i++) {
// Stock Update - Joao Correia
if (STOCK_LIMITED == 'true') {
if (DOWNLOAD_ENABLED == 'true') {
$stock_query_raw = "SELECT products_quantity, pad.products_attributes_filename
FROM " . TABLE_PRODUCTS . " p
LEFT JOIN " . TABLE_PRODUCTS_ATTRIBUTES . " pa
ON p.products_id=pa.products_id
LEFT JOIN " . TABLE_PRODUCTS_ATTRIBUTES_DOWNLOAD . " pad
ON pa.products_attributes_id=pad.products_attributes_id
WHERE p.products_id = '" . tep_get_prid($order->products[$i]['id']) . "'";
// Will work with only one option for downloadable products
// otherwise, we have to build the query dynamically with a loop
$products_attributes = $order->products[$i]['attributes'];
if (is_array($products_attributes)) {
$stock_query_raw .= " AND pa.options_id = '" . $products_attributes[0]['option_id'] . "' AND pa.options_values_id = '" . $products_attributes[0]['value_id'] . "'";
}
$stock_query = tep_db_query($stock_query_raw);
} else {
$stock_query = tep_db_query("select products_quantity from " . TABLE_PRODUCTS . " where products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");
}
if (tep_db_num_rows($stock_query) > 0) {
$stock_values = tep_db_fetch_array($stock_query);
// do not decrement quantities if products_attributes_filename exists
if ((DOWNLOAD_ENABLED != 'true') || (!$stock_values['products_attributes_filename'])) {
$stock_left = $stock_values['products_quantity'] - $order->products[$i]['qty'];
} else {
$stock_left = $stock_values['products_quantity'];
}
tep_db_query("update " . TABLE_PRODUCTS . " set products_quantity = '" . $stock_left . "' where products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");
if ( ($stock_left < 1) && (STOCK_ALLOW_CHECKOUT == 'false') ) {
tep_db_query("update " . TABLE_PRODUCTS . " set products_status = '0' where products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");
}
}
}
to this:
for ($i=0, $n=sizeof($order->products); $i<$n; $i++) {
// Stock Update - Joao Correia
if (STOCK_LIMITED == 'true') {
if (DOWNLOAD_ENABLED == 'true') {
$stock_query_raw = "SELECT products_quantity, products_bundle, pad.products_attributes_filename
FROM " . TABLE_PRODUCTS . " p
LEFT JOIN " . TABLE_PRODUCTS_ATTRIBUTES . " pa
ON p.products_id=pa.products_id
LEFT JOIN " . TABLE_PRODUCTS_ATTRIBUTES_DOWNLOAD . " pad
ON pa.products_attributes_id=pad.products_attributes_id
WHERE p.products_id = '" . tep_get_prid($order->products[$i]['id']) . "'";
// Will work with only one option for downloadable products
// otherwise, we have to build the query dynamically with a loop
$products_attributes = $order->products[$i]['attributes'];
if (is_array($products_attributes)) {
$stock_query_raw .= " AND pa.options_id = '" . $products_attributes[0]['option_id'] . "' AND pa.options_values_id = '" . $products_attributes[0]['value_id'] . "'";
}
$stock_query = tep_db_query($stock_query_raw);
} else {
$stock_query = tep_db_query("select products_quantity, products_bundle from " . TABLE_PRODUCTS . " where products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");
}
if (tep_db_num_rows($stock_query) > 0) {
$stock_values = tep_db_fetch_array($stock_query);
if ($stock_values['products_bundle'] == 'yes') {
// order item is a bundle and must be separated
$report_text .= "Bundle found in order : " . tep_get_prid($order->products[$i]['id']) . "<br>\n";
$bundle_query = tep_db_query("select pb.subproduct_id, pb.subproduct_qty, p.products_model, p.products_quantity, p.products_bundle
from " . TABLE_PRODUCTS_BUNDLES . " pb
LEFT JOIN " . TABLE_PRODUCTS . " p
ON p.products_id=pb.subproduct_id
where pb.bundle_id = '" . tep_get_prid($order->products[$i]['id']) . "'");
while ($bundle_data = tep_db_fetch_array($bundle_query)) {
if ($bundle_data['products_bundle'] == "yes") {
$report_text .= "<br>level 2 bundle found in order : " . $bundle_data['products_model'] . "<br>";
$bundle_query_nested = tep_db_query("select pb.subproduct_id, pb.subproduct_qty, p.products_model, p.products_quantity, p.products_bundle
from " . TABLE_PRODUCTS_BUNDLES . " pb
LEFT JOIN " . TABLE_PRODUCTS . " p
ON p.products_id=pb.subproduct_id
where pb.bundle_id = '" . $bundle_data['subproduct_id'] . "'");
while ($bundle_data_nested = tep_db_fetch_array($bundle_query_nested)) {
$stock_left = $bundle_data_nested['products_quantity'] - $bundle_data_nested['subproduct_qty'] * $order->products[$i]['qty'];
$report_text .= "updating level 2 item " . $bundle_data_nested['products_model'] . " : was " . $bundle_data_nested['products_quantity'] . " and number ordered is " . ($bundle_data_nested['subproduct_qty'] * $order->products[$i]['qty']) . " <br>\n";
tep_db_query("update " . TABLE_PRODUCTS . " set products_quantity = '" . $stock_left . "' where products_id = '" . $bundle_data_nested['subproduct_id'] . "'");
}
} else {
$stock_left = $bundle_data['products_quantity'] - $bundle_data['subproduct_qty'] * $order->products[$i]['qty'];
$report_text .= "updating level 1 item " . $bundle_data['products_model'] . " : was " . $bundle_data['products_quantity'] . " and number ordered is " . ($bundle_data['subproduct_qty'] * $order->products[$i]['qty']) . " <br>\n";
tep_db_query("update " . TABLE_PRODUCTS . " set products_quantity = '" . $stock_left . "' where products_id = '" . $bundle_data['subproduct_id'] . "'");
}
}
} else {
// order item is normal and should be treated as such
$report_text .= "Normal product found in order : " . tep_get_prid($order->products[$i]['id']) . "\n";
// do not decrement quantities if products_attributes_filename exists
if ((DOWNLOAD_ENABLED != 'true') || (!$stock_values['products_attributes_filename'])) {
$stock_left = $stock_values['products_quantity'] - $order->products[$i]['qty'];
} else {
$stock_left = $stock_values['products_quantity'];
}
tep_db_query("update " . TABLE_PRODUCTS . " set products_quantity = '" . $stock_left . "' where products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");
if ( ($stock_left < 1) && (STOCK_ALLOW_CHECKOUT == 'false') ) {
tep_db_query("update " . TABLE_PRODUCTS . " set products_status = '0' where products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");
}
}
}
}
-adam