Jump to content
  • Checkout
  • Login
  • Get in touch

osCommerce

The e-commerce.

Bundled Products


lildog

Recommended Posts

But when you come again there is only 3 lines. If you added 4, 5 , 6 or more products these dont appear

Modified for more lines and diferent order.

The contrib works fine.

<?php

?>
<div id="bundled_subproducts">
<?
   for ($i=0, $n = $bundle_count ? $bundle_count+1:6; $i<$n; $i++) {

     echo "\n" . '<input type="text" size="3" name="subproduct_' . $i . '_qty" value="' . $bundle_array[$i]['qty'] . '">';
     echo "\n" . '<input type="text" size="70" name="subproduct_' . $i . '_name" value="' . $bundle_array[$i]['name'] . '">';
     echo "\n" . '<input type="text" size="6" name="subproduct_' . $i . '_id" value="' . $bundle_array[$i]['id'] . '">';

     echo "\n" . '<a href="javascript:clearSubproduct(' . $i . ')">[x]</a><br>';
   }
?>

</div>
<?
   echo tep_draw_hidden_field('bundled_subproducts_i', $i,'id="bundled_subproducts_i"');
   echo 'Product : <select name="subproduct_selector" onChange="fillCodes()">';
   echo '<option name="null" value="" SELECTED></option>';
   $products = tep_db_query("select pd.products_name, p.products_id, p.products_model from " . TABLE_PRODUCTS . " p, " . TABLE_PRODUCTS_DESCRIPTION . " pd where pd.products_id = p.products_id and pd.language_id = '" . $languages_id . "' and p.products_id <> '" . $HTTP_GET_VARS['pID'] . "' order by pd.products_name");
// byMODEL     $products = tep_db_query("select pd.products_name, p.products_id, p.products_model from " . TABLE_PRODUCTS . " p, " . TABLE_PRODUCTS_DESCRIPTION . " pd where pd.products_id = p.products_id and pd.language_id = '" . $languages_id . "' and p.products_id <> '" . $HTTP_GET_VARS['pID'] . "' order by p.products_model");

   while($products_values = tep_db_fetch_array($products)) {
     echo "\n" . '<option name="' . $products_values['products_id'] . '" value="' . $products_values['products_id'] . '">' . $products_values['products_id'] . ' - - - ' . $products_values['products_name'] . " (" . $products_values['products_model'] . ')</option>';
// byID               echo "\n" . '<option name="' . $products_values['products_id'] . '" value="' . $products_values['products_id'] . '">' . $products_values['products_id'] . ' - - - ' . $products_values['products_name'] . " (" . $products_values['products_model'] . ')</option>';
// byMODEL     echo "\n" . '<option name="' . $products_values['products_id'] . '" value="' . $products_values['products_id'] . '">' . $products_values['products_id'] . ' - - - ' . $products_values['products_name'] . " (" . $products_values['products_model'] . ')</option>';
   }
   echo '</select>';
?>
                 </td>
               </tr>
             </table>
           </td>
         </tr>
         <!-- EOF Bundled Products -->

 

In other hand I think there is a bug. If anyone can try this.

1. create a bundle of 3 products.

2. then in admin/atributes asign 2 or 3 options to it.

 

3. In the shop front end. Buy it. It goes to the basket.

4. Then go to shoping cart (shoping_cart.php)

5. Click on the bundled product.

6. The error:

1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '{2}3 and language_id = '3'' at line 7

 

SELECT pd.products_name, pb.*, p.products_bundle, p.products_id, p.products_price, p.products_image FROM products p INNER JOIN products_description pd ON p.products_id=pd.products_id INNER JOIN products_bundles pb ON pb.subproduct_id=pd.products_id WHERE pb.bundle_id = 16546{2}3 and language_id = '3'

 

[TEP STOP]

Link to comment
Share on other sites

  • Replies 52
  • Created
  • Last Reply

Top Posters In This Topic

Hello Everybody,

 

is there an example shop where this contibution is used?

 

I want to use bundled products but i dont know if thats exactly what i need:

The costumer must be able to individual combine sub-products?

E.g. when i want to offer a six-pack of wine from 22 sorts of wine...?

 

 

 

thanks for replies

 

Andreas

Link to comment
Share on other sites

Can someone upload screenshots of the admin and customer side? I am in desperate need to for something like this as I have many "kits" that are comprised of many individual parts - all of which customers can also buy individually. i need something that is invisible to the customer and just appears as one product. on the admin side it should list the products within the bundle for easy and accurate order fullfillment.

 

make sense?

Link to comment
Share on other sites

  • 1 month later...

Hi

 

I just installed this contrib and I have a question. I managed to create bundled products, but when i try a buy, the stock value of each item is not updated (no -1 for example). However, if I cancel the order ans check the "restore stock value", each item is updated (+1).

 

Does anybody know how to fix that ?

 

Tx

Link to comment
Share on other sites

  • 1 month later...

I'm testing this contribution offline and have this question:

 

When I'm adding two products with different Tax Classes, I'm not able to get both these products to display the right price including taxes. It seems that the Bundle's Tax Class is controlling both products. Is this the case, or am I missing something?

 

Peter

Link to comment
Share on other sites

...having a problem where if I create or edit a product and set it up with other products as bundle products and exit, everything works fine. If I then go back in to the bundle product, the bundled products are no longer listed, which if I save and exit as it is, and then go into the product on the customer side, the product is no longer a bundle and has no bundled products. This means that each time I edit a bundled product I have to setup the bundle products again.

 

Having looked at the code again in catalog/admin/categories.php I can see there is a call to perform an SQL delete or an insert, but no select....

 

Peter, I had the same problem and it appears to be caused by the variable $bundle_count not being set anywhere as far as I can tell. So, I added $bundle_count=sizeof($bundle_array); The remainder of the code is already there, and is the select you refer to. It just happens to be towards the beginning of the file, whereas the display code is toward the end. I'd give line numbers, but my site is so heavily modified it wouldn't help :(

 

    // BOF Bundled Products
   if (isset($pInfo->products_bundle) && $pInfo->products_bundle == "yes") {
   // this product is a bundle so get contents data 
     $bundle_query = tep_db_query("SELECT pb.subproduct_id, pb.subproduct_qty, pd.products_name FROM " . TABLE_PRODUCTS_DESCRIPTION . " pd INNER JOIN " . TABLE_PRODUCTS_BUNDLES . " pb ON pb.subproduct_id=pd.products_id WHERE pb.bundle_id = '" . $HTTP_GET_VARS['pID'] . "' and language_id = '" . (int)$languages_id . "'");
     while ($bundle_contents = tep_db_fetch_array($bundle_query)) {
       $bundle_array[] = array('id' => $bundle_contents['subproduct_id'],
                               'qty' => $bundle_contents['subproduct_qty'],
                               'name' => $bundle_contents['products_name']);
     }
     $bundle_count=sizeof($bundle_array);
   }
   // EOF Bundled Products

 

I hope this helps in some way....

 

Dave

Link to comment
Share on other sites

  • 1 month later...

I wanted to add one thing in case anyone has this issue. The change in admin/categories.php which displays the add bundle box on new products page cause issues on some web servers when using <? instead of <?php. Simple modification to make it show up correctly when adding new bundles.

 

<?
   for ($i=0, $n = $bundle_count ? $bundle_count+1:3; $i<$n; $i++) {
     echo "\n" . '<input type="text" size="30" name="subproduct_' . $i . '_name" value="' . $bundle_array[$i]['name'] . '">';
     echo "\n" . '<input type="text" size="3" name="subproduct_' . $i . '_id" value="' . $bundle_array[$i]['id'] . '">';
     echo "\n" . '<input type="text" size="2" name="subproduct_' . $i . '_qty" value="' . $bundle_array[$i]['qty'] . '">';
     echo "\n" . '<a href="javascript:clearSubproduct(' . $i . ')">[x]</a><br>';
   }
?>

</div>
<?
   echo tep_draw_hidden_field('bundled_subproducts_i', $i,'id="bundled_subproducts_i"');
   echo 'add : <select name="subproduct_selector" onChange="fillCodes()">';
   echo '<option name="null" value="" SELECTED></option>';
   $products = tep_db_query("select pd.products_name, p.products_id, p.products_model from " . TABLE_PRODUCTS . " p, " . TABLE_PRODUCTS_DESCRIPTION . " pd where pd.products_id = p.products_id and pd.language_id = '" . $languages_id . "' and p.products_id <> '" . $HTTP_GET_VARS['pID'] . "' order by p.products_model");

   while($products_values = tep_db_fetch_array($products)) {
     echo "\n" . '<option name="' . $products_values['products_id'] . '" value="' . $products_values['products_id'] . '">' . $products_values['products_id'] . ' - - - ' . $products_values['products_name'] . " (" . $products_values['products_model'] . ')</option>';
   }
   echo '</select>';
?>

 

to

 

<?php
   for ($i=0, $n = $bundle_count ? $bundle_count+1:3; $i<$n; $i++) {
     echo "\n" . '<input type="text" size="30" name="subproduct_' . $i . '_name" value="' . $bundle_array[$i]['name'] . '">';
     echo "\n" . '<input type="text" size="3" name="subproduct_' . $i . '_id" value="' . $bundle_array[$i]['id'] . '">';
     echo "\n" . '<input type="text" size="2" name="subproduct_' . $i . '_qty" value="' . $bundle_array[$i]['qty'] . '">';
     echo "\n" . '<a href="javascript:clearSubproduct(' . $i . ')">[x]</a><br>';
   }
?>

</div>
<?php
   echo tep_draw_hidden_field('bundled_subproducts_i', $i,'id="bundled_subproducts_i"');
   echo 'add : <select name="subproduct_selector" onChange="fillCodes()">';
   echo '<option name="null" value="" SELECTED></option>';
   $products = tep_db_query("select pd.products_name, p.products_id, p.products_model from " . TABLE_PRODUCTS . " p, " . TABLE_PRODUCTS_DESCRIPTION . " pd where pd.products_id = p.products_id and pd.language_id = '" . $languages_id . "' and p.products_id <> '" . $HTTP_GET_VARS['pID'] . "' order by p.products_model");

   while($products_values = tep_db_fetch_array($products)) {
     echo "\n" . '<option name="' . $products_values['products_id'] . '" value="' . $products_values['products_id'] . '">' . $products_values['products_id'] . ' - - - ' . $products_values['products_name'] . " (" . $products_values['products_model'] . ')</option>';
   }
   echo '</select>';
?>

Link to comment
Share on other sites

  • 3 weeks later...

Hello

 

I have instal this Bundle contri a few days ago,

done some reading and I could fix al the errors.

 

Everything was ok, was working, but now I have this Sql problem:

 

1062 - Duplicate entry '3157-0' for key 1

INSERT INTO products_bundles (bundle_id, subproduct_id, subproduct_qty) VALUES ('3157', '0', '1')

 

I have found this:

 

Go into phpmyadmin and edit the sesskey. Set it to int(32) and set it to auto-increment. Problems solved, and no more problems arise.

on this topic:

 

http://www.oscommerce.com/forums/topic/218403-1062-duplicate-entry-error-fix/

 

 

 

I have done this but it doensn't work, I still get this error.

 

 ALTER TABLE `products_bundles` CHANGE `bundle_id` `bundle_id` INT( 32 ) NULL AUTO_INCREMENT  

 ALTER TABLE `products_bundles` CHANGE `bundle_id` `bundle_id` INT( 32 ) NOT NULL AUTO_INCREMENT  

 

Can someone help me with this?

 

Thank you

Lili

Link to comment
Share on other sites

  • 2 months later...

Hi, just an idea for a modification for the bundled products contrib:

I want to use this contrib for selling product variations (just like options) not bundles.

There would be a master product that contains sub-products that can be bought. For example,

the master would be an apple, the sub-products would be a green apple, a red apple and a yellow apple.

The difference to product attributes is, that every sub-product is a product for itself (e.g. model no., picture, price, title, stock...).

I need that, because our facturing system and some export tools (like amazon, shopping.com) can't handle attributes.

 

Has anyone used the contrib in that way or has anyone an idea how to modificate it?

Link to comment
Share on other sites

  • 1 month later...

Hi, just an idea for a modification for the bundled products contrib:

I want to use this contrib for selling product variations (just like options) not bundles.

There would be a master product that contains sub-products that can be bought. For example,

the master would be an apple, the sub-products would be a green apple, a red apple and a yellow apple.

The difference to product attributes is, that every sub-product is a product for itself (e.g. model no., picture, price, title, stock...).

I need that, because our facturing system and some export tools (like amazon, shopping.com) can't handle attributes.

 

Has anyone used the contrib in that way or has anyone an idea how to modificate it?

 

It sounds to me like you just need to create entirely new products instead. Use the Copyto/Duplicate function if most of the information will remain the same and you could save yourself some typing.

Link to comment
Share on other sites

Bundled Products version 2.0 has been posted to the contribs. New features include:

 

--Changed database definitions of the fields so that the type of the ids in the product_bundles table is the same as the products_id in the products table. Also changed the products_bundles definition from tinytext to enumerated to save database space.

--Replaced hardcoded language in categories.php with defined language.

--Added capability of properly duplicating product bundles in categories.php.

--Added instruction for properly deleting a bundle.

--Added preview of bundle information in categories.php to match the one in product_info.php.

--If the same product is added to a bundle twice the quantities are combined so that only one line per subproduct exists in the product_bundles table which enables PRIMARY indexing on this table.

--Added headings for the Bundled products columns during edit, hid the fields for the subproduct ids, and disabled entry in the subproduct name fields to prevent possible errors that might be caused by tampering with these fields during entry/editing.

--Changed code that only allowed bundles to be nested one level to allow nesting to any level.

--Added code to prevent adding to a bundle another bundle that, directly or via nested bundles, contains the bundle being edited.

--Added code for checking bundle stock that was missing from checkout_payment.php.

--Added code to verify that a product marked as a bundle actually is one. If a product is marked as a bundle during editing in categories.php but no products are added to it the bundle will be changed to "no" while saving the product in the database.

--Bundle weight is calculated automatically from the products it contains when saving the bundle to the database.

--Added code for the packaging routines added to the shopping cart class by the UPSXML contribution so that information for bundle products comes from the products contained in the bundle.

Link to comment
Share on other sites

  • 1 month later...
  • 3 weeks later...

I'm trying to install this contribution.

I got stuck at Step 8: I can't find

// Stock Check

$any_out_of_stock = false;

if (STOCK_CHECK == 'true') {

for ($i=0, $n=sizeof($order->products); $i<$n; $i++) {

if (tep_check_stock($order->products[$i]['id'], $order->products[$i]['qty'])) {

$any_out_of_stock = true;

}

}

// Out of Stock

if ( (STOCK_ALLOW_CHECKOUT != 'true') && ($any_out_of_stock == true) ) {

tep_redirect(tep_href_link(FILENAME_SHOPPING_CART));

}

}

 

I've been trying to search even for single bits of that code but nothing...

 

this is what I have in the file (it's the code until the second change in step 8)

 

<?php
/*
$Id: checkout_process.php,v 1.128 2003/05/28 18:00:29 hpdl Exp $

osCommerce, Open Source E-Commerce Solutions
http://www.oscommerce.com

Copyright (c) 2003 osCommerce

Released under the GNU General Public License
*/

include('includes/application_top.php');

//Order IP Record BEGIN
 $ip = $HTTP_SERVER_VARS["REMOTE_ADDR"];
 $client = gethostbyaddr($HTTP_SERVER_VARS["REMOTE_ADDR"]);
 $str = preg_split("/\./", $client);
 $i = count($str);
 $x = $i - 1;
 $n = $i - 2;
 $isp = $str[$n] . "." . $str[$x];
//Order IP Record END

//mod to set payment to default currency
$currency = DEFAULT_CURRENCY;

// if the customer is not logged on, redirect them to the login page
if (!tep_session_is_registered('customer_id')) {
$navigation->set_snapshot(array('mode' => 'SSL', 'page' => FILENAME_CHECKOUT_PAYMENT));
tep_redirect(tep_href_link(FILENAME_LOGIN, '', 'SSL'));
}

if (!tep_session_is_registered('sendto')) {
tep_redirect(tep_href_link(FILENAME_CHECKOUT_PAYMENT, '', 'SSL'));
}

if ( (tep_not_null(MODULE_PAYMENT_INSTALLED)) && (!tep_session_is_registered('payment')) ) {
tep_redirect(tep_href_link(FILENAME_CHECKOUT_PAYMENT, '', 'SSL'));
}

// avoid hack attempts during the checkout procedure by checking the internal cartID
if (isset($cart->cartID) && tep_session_is_registered('cartID')) {
if ($cart->cartID != $cartID) {
	tep_redirect(tep_href_link(FILENAME_CHECKOUT_SHIPPING, '', 'SSL'));
}
}

include(DIR_WS_LANGUAGES . $language . '/' . FILENAME_CHECKOUT_PROCESS);

// load selected payment module
require(DIR_WS_CLASSES . 'payment.php');
if ($credit_covers) $payment=''; // CCGV
$payment_modules = new payment($payment);

// load the selected shipping module
require(DIR_WS_CLASSES . 'shipping.php');
$shipping_modules = new shipping($shipping);

require(DIR_WS_CLASSES . 'order.php');
$order = new order;



require(DIR_WS_CLASSES . 'order_total.php');
$order_total_modules = new order_total;

$order_totals = $order_total_modules->process();

// load the before_process function from the payment modules
$payment_modules->before_process();

$sql_data_array = array('customers_id' => $customer_id,
'customers_name' => $order->customer['firstname'] . ' ' . $order->customer['lastname'],
'customers_company' => $order->customer['company'],
'customers_street_address' => $order->customer['street_address'],
'customers_suburb' => $order->customer['suburb'],
'customers_city' => $order->customer['city'],
'customers_postcode' => $order->customer['postcode'],
'customers_state' => $order->customer['state'],
'customers_country' => $order->customer['country']['title'],
'customers_telephone' => $order->customer['telephone'],
'customers_email_address' => $order->customer['email_address'],
'customers_address_format_id' => $order->customer['format_id'],
'delivery_name' => $order->delivery['firstname'] . ' ' . $order->delivery['lastname'],
'delivery_company' => $order->delivery['company'],

//PIVACF start
'billing_piva' => $order->billing['piva'],
'billing_cf' => $order->billing['cf'],
//PIVACF end
'delivery_street_address' => $order->delivery['street_address'],
'delivery_suburb' => $order->delivery['suburb'],
'delivery_city' => $order->delivery['city'],
'delivery_postcode' => $order->delivery['postcode'],
'delivery_state' => $order->delivery['state'],
'delivery_country' => $order->delivery['country']['title'],
'delivery_address_format_id' => $order->delivery['format_id'],
'billing_name' => $order->billing['firstname'] . ' ' . $order->billing['lastname'],
'billing_company' => $order->billing['company'],
'billing_street_address' => $order->billing['street_address'],
'billing_suburb' => $order->billing['suburb'],
'billing_city' => $order->billing['city'],
'billing_postcode' => $order->billing['postcode'],
'billing_state' => $order->billing['state'],
'billing_country' => $order->billing['country']['title'],
'billing_address_format_id' => $order->billing['format_id'],
'payment_method' => $order->info['payment_method'],
'cc_type' => $order->info['cc_type'],
'cc_owner' => $order->info['cc_owner'],
'cc_number' => $order->info['cc_number'],
'cc_expires' => $order->info['cc_expires'],
'date_purchased' => 'now()',
'orders_status' => $order->info['order_status'],
'currency' => $order->info['currency'],
'currency_value' => $order->info['currency_value'],
//Order IP Record BEGIN
'ipaddy' => $ip,
'ipisp' => $isp);
//Order IP Record END
tep_db_perform(TABLE_ORDERS, $sql_data_array);
$insert_id = tep_db_insert_id();
for ($i=0, $n=sizeof($order_totals); $i<$n; $i++) {
$sql_data_array = array('orders_id' => $insert_id,
'title' => $order_totals[$i]['title'],
'text' => $order_totals[$i]['text'],
'value' => $order_totals[$i]['value'],
'class' => $order_totals[$i]['code'],
'sort_order' => $order_totals[$i]['sort_order']);
tep_db_perform(TABLE_ORDERS_TOTAL, $sql_data_array);
}

$customer_notification = (SEND_EMAILS == 'true') ? '1' : '0';
$sql_data_array = array('orders_id' => $insert_id,
'orders_status_id' => $order->info['order_status'],
'date_added' => 'now()',
'customer_notified' => $customer_notification,
'comments' => $order->info['comments']);
tep_db_perform(TABLE_ORDERS_STATUS_HISTORY, $sql_data_array);

// initialized for the email confirmation
$products_ordered = '';
$subtotal = 0;
$total_tax = 0;

// begin product bundles
 function reduce_bundle_stock($bundle_id, $qty_sold) {

from then on there's the rest of change of step 8

 

any clue where I have to add:

 

$any_bundle_only = false;

$products = $cart->get_products();

for ($i=0, $n=sizeof($products); $i<$n; $i++) {

if ($products[$i]['sold_in_bundle_only'] == 'yes') $any_bundle_only = true;

}

if ($any_bundle_only) tep_redirect(tep_href_link(FILENAME_SHOPPING_CART));

Link to comment
Share on other sites

  • 4 weeks later...

I have one problem with this contribution.

In the admin pannel when i add a new line (after the first 3) this appear but it dosen't work. I can't add the product in the new line. To add the product i have to exit from the product page and reenter, so i can add the new bundle product from the list.

 

Somebody can help me please?

 

p.s. sorry for my english.

Edited by shock01
Link to comment
Share on other sites

  • 3 weeks later...

I have one problem with this contribution.

In the admin pannel when i add a new line (after the first 3) this appear but it dosen't work. I can't add the product in the new line. To add the product i have to exit from the product page and reenter, so i can add the new bundle product from the list.

 

Somebody can help me please?

 

p.s. sorry for my english.

 

First of all... happy new year!!!

 

About my post nobody can't help me?

Edited by shock01
Link to comment
Share on other sites

  • 2 months later...

Hi,

 

all going good at my store from this excellent plugin. but i have installed oscommerce ultimate SEO plugin "http://www.oscommerce.com/community/contributions,2823".

Now its not updating cart with all the bundled products. it just add only the main item at which the bundle offer is offering. :(

 

for example:

http://www.shoppingtingle.com/old/matrix-p-6.html?osCsid=kokc6ijq5pm952derag19m3kr0

 

please help me with many thanks

 

 

Best Regards

Paula

Link to comment
Share on other sites

  • 2 months later...

Thanks for this add on

 

Only would like to modify this to show products listed by sort order in products_info.php

in admin also to use some sorting by categories when using the drop down box to select product or to select product category first then product when using large store

 

Any help on this would be greatly appreciated

Getting the Phoenix off the ground

Link to comment
Share on other sites

  • 2 months later...

I am currently preparing the install of this excellent module.

 

Can somebody clear out the comment:

 

***IMPORTANT NOTE If you do not use the MSRP contribution then make sure

that you delete the references to products_msrp from both queries above

in the section under calculate total MSRP and weight.

Waht exacly should the below code be changed to?

 

Thanks so much, HONDA4.

 

      	  // BOF Bundled Products
         if ($HTTP_POST_VARS['products_bundle'] == "yes") {
           $to_avoid = bundle_avoid($products_id);
           $subprods = array();
           $subprodqty = array();
           tep_db_query("DELETE FROM " . TABLE_PRODUCTS_BUNDLES . " WHERE bundle_id = '" . (int)$products_id . "'");
           for ($i=0, $n=100; $i<$n; $i++) {
             if (isset($HTTP_POST_VARS['subproduct_' . $i . '_qty']) && ((int)$HTTP_POST_VARS['subproduct_' . $i . '_qty'] > 0) && !in_array($HTTP_POST_VARS['subproduct_' . $i . '_id'], $to_avoid)) {
               if (in_array($HTTP_POST_VARS['subproduct_' . $i . '_id'], $subprods)) {
                 $subprodqty[$HTTP_POST_VARS['subproduct_' . $i . '_id']] += (int)$HTTP_POST_VARS['subproduct_' . $i . '_qty'];
                 tep_db_query('update ' . TABLE_PRODUCTS_BUNDLES . ' set subproduct_qty = ' . (int)$subprodqty[$HTTP_POST_VARS['subproduct_' . $i . '_id']] . ' where bundle_id = ' . (int)$products_id . ' and subproduct_id = ' . (int)$HTTP_POST_VARS['subproduct_' . $i . '_id']);
               } else {
                 $subprods[] = $HTTP_POST_VARS['subproduct_' . $i . '_id'];
                 $subprodqty[$HTTP_POST_VARS['subproduct_' . $i . '_id']] = (int)$HTTP_POST_VARS['subproduct_' . $i . '_qty'];
                 tep_db_query("INSERT INTO " . TABLE_PRODUCTS_BUNDLES . " (bundle_id, subproduct_id, subproduct_qty) VALUES ('" . (int)$products_id . "', '" . (int)$HTTP_POST_VARS['subproduct_' . $i . '_id'] . "', '" . (int)$HTTP_POST_VARS['subproduct_' . $i . '_qty'] . "')");
               }
      	      }
           }
           if (empty($subprods)) { // not a bundle if no subproducts set
             tep_db_query('update ' . TABLE_PRODUCTS . ' set products_bundle = "no" where products_id = ' . (int)$products_id);
           } else { // calculate total MSRP and weight from subproducts
             $msrp = 0;
             $weight = 0;
             foreach ($subprodqty as $id => $qty) {
               $subprod_query = tep_db_query('select products_msrp, products_weight from ' . TABLE_PRODUCTS . ' where products_id = ' . (int)$id);
               $subprod = tep_db_fetch_array($subprod_query);
               $msrp += ($subprod['products_msrp'] * $qty);
               $weight += ($subprod['products_weight'] * $qty);
             }
             tep_db_query('update ' . TABLE_PRODUCTS . ' set products_quantity = 1, products_msrp = "' . tep_db_input($msrp) . '", products_weight = "' . tep_db_input($weight) . '" where products_id = ' . (int)$products_id);
           }
         }
         // EOF Bundled Products

Edited by honda4
Link to comment
Share on other sites

  • 3 weeks later...
  • 2 months later...
  • 2 weeks later...

I had installed the bundled products add with out a problem. But know, I want to add the attributes on product listing add on, where the attributes of each products are shown down the product title at the product listing page, and not at the product info one.

How can I get to see the attributes for the products inside the bundle?

Thanks, hope you understand my problem.

Link to comment
Share on other sites

  • 2 months later...

Hi, i need some assistance plz, i have reach step 19

catalog/includes/classes/shopping_cart.php:

 

Can't find (under function add_cart):

 

$check_product_query = tep_db_query("select products_status from " . TABLE_PRODUCTS . " where products_id = '" . (int)$products_id . "'");

$check_product = tep_db_fetch_array($check_product_query);

 

if (($check_product !== false) && ($check_product['products_status'] == '1')) {

 

here you have my current code:

 

<?php
/*
 $Id: shopping_cart.php,v 1.35 2003/06/25 21:14:33 hpdl Exp $
 E-Commerce Solutions
 Copyright (c) 2005 www.flash-template-design.com
 Released under the GNU General Public License
*/
 class shoppingCart {
   var $contents, $total, $weight, $cartID, $content_type;
   function shoppingCart() {
  $this->reset();
   }
   function restore_contents() {
  global $customer_id;
  if (!tep_session_is_registered('customer_id')) return false;
// insert current cart contents in database
  if (is_array($this->contents)) {
    reset($this->contents);
    while (list($products_id, ) = each($this->contents)) {
	  $qty = $this->contents[$products_id]['qty'];
	  $product_query = tep_db_query("select products_id from " . TABLE_CUSTOMERS_BASKET . " where customers_id = '" . (int)$customer_id . "' and products_id = '" . tep_db_input($products_id) . "'");
	  if (!tep_db_num_rows($product_query)) {
	    tep_db_query("insert into " . TABLE_CUSTOMERS_BASKET . " (customers_id, products_id, customers_basket_quantity, customers_basket_date_added) values ('" . (int)$customer_id . "', '" . tep_db_input($products_id) . "', '" . $qty . "', '" . date('Ymd') . "')");
	    if (isset($this->contents[$products_id]['attributes'])) {
		  reset($this->contents[$products_id]['attributes']);
		  while (list($option, $value) = each($this->contents[$products_id]['attributes'])) {
		    tep_db_query("insert into " . TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " (customers_id, products_id, products_options_id, products_options_value_id) values ('" . (int)$customer_id . "', '" . tep_db_input($products_id) . "', '" . (int)$option . "', '" . (int)$value . "')");
		  }
	    }
	  } else {
	    tep_db_query("update " . TABLE_CUSTOMERS_BASKET . " set customers_basket_quantity = '" . $qty . "' where customers_id = '" . (int)$customer_id . "' and products_id = '" . tep_db_input($products_id) . "'");
	  }
    }
  }
// reset per-session cart contents, but not the database contents
  $this->reset(false);
  $products_query = tep_db_query("select products_id, customers_basket_quantity from " . TABLE_CUSTOMERS_BASKET . " where customers_id = '" . (int)$customer_id . "'");
  while ($products = tep_db_fetch_array($products_query)) {
    $this->contents[$products['products_id']] = array('qty' => $products['customers_basket_quantity']);
// attributes
    $attributes_query = tep_db_query("select products_options_id, products_options_value_id from " . TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " where customers_id = '" . (int)$customer_id . "' and products_id = '" . tep_db_input($products['products_id']) . "'");
    while ($attributes = tep_db_fetch_array($attributes_query)) {
	  $this->contents[$products['products_id']]['attributes'][$attributes['products_options_id']] = $attributes['products_options_value_id'];
    }
  }
  $this->cleanup();
   }
   function reset($reset_database = false) {
  global $customer_id;
  $this->contents = array();
  $this->total = 0;
  $this->weight = 0;
  $this->content_type = false;
  if (tep_session_is_registered('customer_id') && ($reset_database == true)) {
    tep_db_query("delete from " . TABLE_CUSTOMERS_BASKET . " where customers_id = '" . (int)$customer_id . "'");
    tep_db_query("delete from " . TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " where customers_id = '" . (int)$customer_id . "'");
  }
  unset($this->cartID);
  if (tep_session_is_registered('cartID')) tep_session_unregister('cartID');
   }
   function add_cart($products_id, $qty = '1', $attributes = '', $notify = true) {
  global $new_products_id_in_cart, $customer_id;
  $products_id = tep_get_uprid($products_id, $attributes);
  if ($notify == true) {
    $new_products_id_in_cart = $products_id;
    tep_session_register('new_products_id_in_cart');
  }
  if ($this->in_cart($products_id)) {
    $this->update_quantity($products_id, $qty, $attributes);
  } else {
    $this->contents[] = array($products_id);
    $this->contents[$products_id] = array('qty' => $qty);
// insert into database
    if (tep_session_is_registered('customer_id')) tep_db_query("insert into " . TABLE_CUSTOMERS_BASKET . " (customers_id, products_id, customers_basket_quantity, customers_basket_date_added) values ('" . (int)$customer_id . "', '" . tep_db_input($products_id) . "', '" . $qty . "', '" . date('Ymd') . "')");
    if (is_array($attributes)) {
	  reset($attributes);
	  while (list($option, $value) = each($attributes)) {
	    $this->contents[$products_id]['attributes'][$option] = $value;
// insert into database
	    if (tep_session_is_registered('customer_id')) tep_db_query("insert into " . TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " (customers_id, products_id, products_options_id, products_options_value_id) values ('" . (int)$customer_id . "', '" . tep_db_input($products_id) . "', '" . (int)$option . "', '" . (int)$value . "')");
	  }
    }
  }
  $this->cleanup();
// assign a temporary unique ID to the order contents to prevent hack attempts during the checkout procedure
  $this->cartID = $this->generate_cart_id();
   }
   function update_quantity($products_id, $quantity = '', $attributes = '') {
  global $customer_id;
  if (empty($quantity)) return true; // nothing needs to be updated if theres no quantity, so we return true..
  $this->contents[$products_id] = array('qty' => $quantity);
// update database
  if (tep_session_is_registered('customer_id')) tep_db_query("update " . TABLE_CUSTOMERS_BASKET . " set customers_basket_quantity = '" . $quantity . "' where customers_id = '" . (int)$customer_id . "' and products_id = '" . tep_db_input($products_id) . "'");
  if (is_array($attributes)) {
    reset($attributes);
    while (list($option, $value) = each($attributes)) {
	  $this->contents[$products_id]['attributes'][$option] = $value;
// update database
	  if (tep_session_is_registered('customer_id')) tep_db_query("update " . TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " set products_options_value_id = '" . (int)$value . "' where customers_id = '" . (int)$customer_id . "' and products_id = '" . tep_db_input($products_id) . "' and products_options_id = '" . (int)$option . "'");
    }
  }
   }
   function cleanup() {
  global $customer_id;
  reset($this->contents);
  while (list($key,) = each($this->contents)) {
    if ($this->contents[$key]['qty'] < 1) {
	  unset($this->contents[$key]);
// remove from database
	  if (tep_session_is_registered('customer_id')) {
	    tep_db_query("delete from " . TABLE_CUSTOMERS_BASKET . " where customers_id = '" . (int)$customer_id . "' and products_id = '" . tep_db_input($key) . "'");
	    tep_db_query("delete from " . TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " where customers_id = '" . (int)$customer_id . "' and products_id = '" . tep_db_input($key) . "'");
	  }
    }
  }
   }
   function count_contents() {  // get total number of items in cart
  $total_items = 0;
  if (is_array($this->contents)) {
    reset($this->contents);
    while (list($products_id, ) = each($this->contents)) {
	  $total_items += $this->get_quantity($products_id);
    }
  }
  return $total_items;
   }
   function get_quantity($products_id) {
  if (isset($this->contents[$products_id])) {
    return $this->contents[$products_id]['qty'];
  } else {
    return 0;
  }
   }
   function in_cart($products_id) {
  if (isset($this->contents[$products_id])) {
    return true;
  } else {
    return false;
  }
   }
   function remove($products_id) {
  global $customer_id;
  unset($this->contents[$products_id]);
// remove from database
  if (tep_session_is_registered('customer_id')) {
    tep_db_query("delete from " . TABLE_CUSTOMERS_BASKET . " where customers_id = '" . (int)$customer_id . "' and products_id = '" . tep_db_input($products_id) . "'");
    tep_db_query("delete from " . TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " where customers_id = '" . (int)$customer_id . "' and products_id = '" . tep_db_input($products_id) . "'");
  }
// assign a temporary unique ID to the order contents to prevent hack attempts during the checkout procedure
  $this->cartID = $this->generate_cart_id();
   }
   function remove_all() {
  $this->reset();
   }
   function get_product_id_list() {
  $product_id_list = '';
  if (is_array($this->contents)) {
    reset($this->contents);
    while (list($products_id, ) = each($this->contents)) {
	  $product_id_list .= ', ' . $products_id;
    }
  }
  return substr($product_id_list, 2);
   }
   function calculate() {
  $this->total = 0;
  $this->weight = 0;
  if (!is_array($this->contents)) return 0;
  reset($this->contents);
  while (list($products_id, ) = each($this->contents)) {
    $qty = $this->contents[$products_id]['qty'];
// products price
    $product_query = tep_db_query("select products_id, products_price, products_tax_class_id, products_weight from " . TABLE_PRODUCTS . " where products_id = '" . (int)$products_id . "'");
    if ($product = tep_db_fetch_array($product_query)) {
	  $prid = $product['products_id'];
	  $products_tax = tep_get_tax_rate($product['products_tax_class_id']);
	  $products_price = $product['products_price'];
	  $products_weight = $product['products_weight'];
	  $specials_query = tep_db_query("select specials_new_products_price from " . TABLE_SPECIALS . " where products_id = '" . (int)$prid . "' and status = '1'");
	  if (tep_db_num_rows ($specials_query)) {
	    $specials = tep_db_fetch_array($specials_query);
	    $products_price = $specials['specials_new_products_price'];
	  }
	  $this->total += tep_add_tax($products_price, $products_tax) * $qty;
	  $this->weight += ($qty * $products_weight);
    }
// attributes price
    if (isset($this->contents[$products_id]['attributes'])) {
	  reset($this->contents[$products_id]['attributes']);
	  while (list($option, $value) = each($this->contents[$products_id]['attributes'])) {
	    $attribute_price_query = tep_db_query("select options_values_price, price_prefix from " . TABLE_PRODUCTS_ATTRIBUTES . " where products_id = '" . (int)$prid . "' and options_id = '" . (int)$option . "' and options_values_id = '" . (int)$value . "'");
	    $attribute_price = tep_db_fetch_array($attribute_price_query);
	    if ($attribute_price['price_prefix'] == '+') {
		  $this->total += $qty * tep_add_tax($attribute_price['options_values_price'], $products_tax);
	    } else {
		  $this->total -= $qty * tep_add_tax($attribute_price['options_values_price'], $products_tax);
	    }
	  }
    }
  }
   }
   function attributes_price($products_id) {
  $attributes_price = 0;
  if (isset($this->contents[$products_id]['attributes'])) {
    reset($this->contents[$products_id]['attributes']);
    while (list($option, $value) = each($this->contents[$products_id]['attributes'])) {
	  $attribute_price_query = tep_db_query("select options_values_price, price_prefix from " . TABLE_PRODUCTS_ATTRIBUTES . " where products_id = '" . (int)$products_id . "' and options_id = '" . (int)$option . "' and options_values_id = '" . (int)$value . "'");
	  $attribute_price = tep_db_fetch_array($attribute_price_query);
	  if ($attribute_price['price_prefix'] == '+') {
	    $attributes_price += $attribute_price['options_values_price'];
	  } else {
	    $attributes_price -= $attribute_price['options_values_price'];
	  }
    }
  }
  return $attributes_price;
   }
   function get_products() {
  global $languages_id;
  if (!is_array($this->contents)) return false;
  $products_array = array();
  reset($this->contents);
  while (list($products_id, ) = each($this->contents)) {
    $products_query = tep_db_query("select p.products_id, pd.products_name, p.products_model, p.products_image, p.products_price, p.products_weight, p.products_tax_class_id from " . TABLE_PRODUCTS . " p, " . TABLE_PRODUCTS_DESCRIPTION . " pd where p.products_id = '" . (int)$products_id . "' and pd.products_id = p.products_id and pd.language_id = '" . (int)$languages_id . "'");
    if ($products = tep_db_fetch_array($products_query)) {
	  $prid = $products['products_id'];
	  $products_price = $products['products_price'];
	  $specials_query = tep_db_query("select specials_new_products_price from " . TABLE_SPECIALS . " where products_id = '" . (int)$prid . "' and status = '1'");
	  if (tep_db_num_rows($specials_query)) {
	    $specials = tep_db_fetch_array($specials_query);
	    $products_price = $specials['specials_new_products_price'];
	  }
	  $products_array[] = array('id' => $products_id,
							    'name' => $products['products_name'],
							    'model' => $products['products_model'],
							    'image' => $products['products_image'],
							    'price' => $products_price,
							    'quantity' => $this->contents[$products_id]['qty'],
							    'weight' => $products['products_weight'],
							    'final_price' => ($products_price + $this->attributes_price($products_id)),
							    'tax_class_id' => $products['products_tax_class_id'],
							    'attributes' => (isset($this->contents[$products_id]['attributes']) ? $this->contents[$products_id]['attributes'] : ''));
    }
  }
  return $products_array;
   }
   function show_total() {
  $this->calculate();
  return $this->total;
   }
   function show_weight() {
  $this->calculate();
  return $this->weight;
   }
   function generate_cart_id($length = 5) {
  return tep_create_random_value($length, 'digits');
   }
   function get_content_type() {
  $this->content_type = false;
  if ( (DOWNLOAD_ENABLED == 'true') && ($this->count_contents() > 0) ) {
    reset($this->contents);
    while (list($products_id, ) = each($this->contents)) {
	  if (isset($this->contents[$products_id]['attributes'])) {
	    reset($this->contents[$products_id]['attributes']);
	    while (list(, $value) = each($this->contents[$products_id]['attributes'])) {
		  $virtual_check_query = tep_db_query("select count(*) as total from " . TABLE_PRODUCTS_ATTRIBUTES . " pa, " . TABLE_PRODUCTS_ATTRIBUTES_DOWNLOAD . " pad where pa.products_id = '" . (int)$products_id . "' and pa.options_values_id = '" . (int)$value . "' and pa.products_attributes_id = pad.products_attributes_id");
		  $virtual_check = tep_db_fetch_array($virtual_check_query);
		  if ($virtual_check['total'] > 0) {
		    switch ($this->content_type) {
			  case 'physical':
			    $this->content_type = 'mixed';
			    return $this->content_type;
			    break;
			  default:
			    $this->content_type = 'virtual';
			    break;
		    }
		  } else {
		    switch ($this->content_type) {
			  case 'virtual':
			    $this->content_type = 'mixed';
			    return $this->content_type;
			    break;
			  default:
			    $this->content_type = 'physical';
			    break;
		    }
		  }
	    }
	  } else {
	    switch ($this->content_type) {
		  case 'virtual':
		    $this->content_type = 'mixed';
		    return $this->content_type;
		    break;
		  default:
		    $this->content_type = 'physical';
		    break;
	    }
	  }
    }
  } else {
    $this->content_type = 'physical';
  }
  return $this->content_type;
   }
   function unserialize($broken) {
  for(reset($broken);$kv=each($broken);) {
    $key=$kv['key'];
    if (gettype($this->$key)!="user function")
    $this->$key=$kv['value'];
  }
   }
 }
?>

Link to comment
Share on other sites

  • 4 weeks later...
  • 2 years later...

(It looks like this thread has not had any activity in over two years... )

 

I have installed this in a 2.3.3.4 store. And, I am having the same admin issue that others have had:

 

I can build a bundle with, in my case, 5 items. The cart side of the store works fine. However, if the admin goes back into bundle definition, the bundle appears to be gone. Has *anyone* been able to resolve this?

 

The default bundle definition is only 3 parts, but one can add additional lines/parts when setting up the bundle. If someone were to address the above issue, it would helpful that, when the admin goes back into a bundle that already has more than 3 parts, all of the parts in the bundle are displayed.

 

Thanks in advance!

 

Malcolm

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...