Jump to content
  • Checkout
  • Login
  • Get in touch

osCommerce

The e-commerce.

[Contribution] QTpro - Quantity Tracking Professional


zonetown

Recommended Posts

Hmmm... (a bit more thinking aloud, sorry folks!)

 

So it works on the front end, but doesn't subtract the attribute stock, leaving me with products requiring doctoring, as it were. I've got PayPal IPN 2.3.4.7 running via the sandbox, but, guess what? It's not subtracting stock. Is it worth having a crack at applying the fix and seeing if it sorts out both issues?!

Link to comment
Share on other sites

What's the page source code showing?

my code product_info.php:

<?php
/*
 $Id$

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

 Copyright (c) 2010 osCommerce

 Released under the GNU General Public License
*/

 require('includes/application_top.php');

 require(DIR_WS_LANGUAGES . $language . '/' . FILENAME_PRODUCT_INFO);

 $product_check_query = tep_db_query("select count(*) as total from " . TABLE_PRODUCTS . " p, " . TABLE_PRODUCTS_DESCRIPTION . " pd where p.products_status = '1' and p.products_id = '" . (int)$HTTP_GET_VARS['products_id'] . "' and pd.products_id = p.products_id and pd.language_id = '" . (int)$languages_id . "'");
 $product_check = tep_db_fetch_array($product_check_query);

 require(DIR_WS_INCLUDES . 'template_top.php');

 if ($product_check['total'] < 1) {
?>

<div class="contentContainer">
 <div class="contentText">
   <?php echo TEXT_PRODUCT_NOT_FOUND; ?>
 </div>

 <div style="float: right;">
   <?php echo tep_draw_button(IMAGE_BUTTON_CONTINUE, 'triangle-1-e', tep_href_link(FILENAME_DEFAULT)); ?>
 </div>
</div>

<?php
 } else {
   $product_info_query = tep_db_query("select p.products_id, pd.products_name, pd.products_description, p.products_model, p.products_quantity, p.products_image, pd.products_url, p.products_price, p.products_tax_class_id, p.products_date_added, p.products_date_available, p.manufacturers_id from " . TABLE_PRODUCTS . " p, " . TABLE_PRODUCTS_DESCRIPTION . " pd where p.products_status = '1' and p.products_id = '" . (int)$HTTP_GET_VARS['products_id'] . "' and pd.products_id = p.products_id and pd.language_id = '" . (int)$languages_id . "'");
   $product_info = tep_db_fetch_array($product_info_query);

   tep_db_query("update " . TABLE_PRODUCTS_DESCRIPTION . " set products_viewed = products_viewed+1 where products_id = '" . (int)$HTTP_GET_VARS['products_id'] . "' and language_id = '" . (int)$languages_id . "'");

   if ($new_price = tep_get_products_special_price($product_info['products_id'])) {
     $products_price = '<del>' . $currencies->display_price($product_info['products_price'], tep_get_tax_rate($product_info['products_tax_class_id'])) . '</del> <span class="productSpecialPrice">' . $currencies->display_price($new_price, tep_get_tax_rate($product_info['products_tax_class_id'])) . '</span>';
   } else {
     $products_price = $currencies->display_price($product_info['products_price'], tep_get_tax_rate($product_info['products_tax_class_id']));
   }

   if (tep_not_null($product_info['products_model'])) {
     $products_name = $product_info['products_name'] . '<br /><span class="smallText">[' . $product_info['products_model'] . ']</span>';
   } else {
     $products_name = $product_info['products_name'];
   }
?>

<?php echo tep_draw_form('cart_quantity', tep_href_link(FILENAME_PRODUCT_INFO, tep_get_all_get_params(array('action')) . 'action=add_product')); ?>

<div>
 <h1 style="float: right;"><?php echo $products_price; ?></h1>
 <h1><?php echo $products_name; ?></h1>
</div>

<div class="contentContainer">
 <div class="contentText">

<?php
   if (tep_not_null($product_info['products_image'])) {
     $pi_query = tep_db_query("select image, htmlcontent from " . TABLE_PRODUCTS_IMAGES . " where products_id = '" . (int)$product_info['products_id'] . "' order by sort_order");

     if (tep_db_num_rows($pi_query) > 0) {
?>

   <div id="piGal" style="float: right;">
     <ul>

<?php
       $pi_counter = 0;
       while ($pi = tep_db_fetch_array($pi_query)) {
         $pi_counter++;

         $pi_entry = '        <li><a href="';

         if (tep_not_null($pi['htmlcontent'])) {
           $pi_entry .= '#piGalimg_' . $pi_counter;
         } else {
           $pi_entry .= tep_href_link(DIR_WS_IMAGES . $pi['image']);
         }

         $pi_entry .= '" target="_blank" rel="fancybox">' . tep_image(DIR_WS_IMAGES . $pi['image']) . '</a>';

         if (tep_not_null($pi['htmlcontent'])) {
           $pi_entry .= '<div style="display: none;"><div id="piGalimg_' . $pi_counter . '">' . $pi['htmlcontent'] . '</div></div>';
         }

         $pi_entry .= '</li>';

         echo $pi_entry;
       }
?>

     </ul>
   </div>

<script type="text/javascript">
$('#piGal ul').bxGallery({
 maxwidth: 300,
 maxheight: 200,
 thumbwidth: <?php echo (($pi_counter > 1) ? '75' : '0'); ?>,
 thumbcontainer: 300,
 load_image: 'ext/jquery/bxGallery/spinner.gif'
});
</script>

<?php
     } else {
?>

   <div id="piGal" align="center">
     <?php echo '<a href="' . tep_href_link(DIR_WS_IMAGES . $product_info['products_image']) . '" target="_blank" rel="fancybox">' . tep_image(DIR_WS_IMAGES . $product_info['products_image'], addslashes($product_info['products_name']), null, null, 'hspace="5" vspace="5"') . '</a>'; ?>                    
   </div>

<?php
     }
?>

<script type="text/javascript">
$("#piGal a[rel^='fancybox']").fancybox({
 cyclic: true
});
</script>

<?php
   }
?>

   <div style="clear: both;"></div>
 </div>
 <div align="left"><?php
}
//++++ QT Pro: End Changed Code
   $products_attributes_query = tep_db_query("select count(*) as total from " . TABLE_PRODUCTS_OPTIONS . " popt, " . TABLE_PRODUCTS_ATTRIBUTES . " patrib where patrib.products_id='" . (int)$HTTP_GET_VARS['products_id'] . "' and patrib.options_id = popt.products_options_id and popt.language_id = '" . (int)$languages_id . "'");
   $products_attributes = tep_db_fetch_array($products_attributes_query);
   if ($products_attributes['total'] > 0) {
//++++ QT Pro: Begin Changed code
     $products_id=(preg_match("/^\d{1,10}(\{\d{1,10}\}\d{1,10})*$/",$HTTP_GET_VARS['products_id']) ? $HTTP_GET_VARS['products_id'] : (int)$HTTP_GET_VARS['products_id']); 
     require(DIR_WS_CLASSES . 'pad_' . PRODINFO_ATTRIBUTE_PLUGIN . '.php');
     $class = 'pad_' . PRODINFO_ATTRIBUTE_PLUGIN;
     $pad = new $class($products_id);
     echo $pad->draw();
   }

//Display a table with which attributecombinations is on stock to the customer?
if(PRODINFO_ATTRIBUTE_DISPLAY_STOCK_LIST == 'True'): require(DIR_WS_MODULES . "qtpro_stock_table.php"); endif;

//++++ QT Pro: End Changed Code
?>
</div>
<div align="left"><h1 style="float: left; "> <?php echo $products_price; ?></h1><span class="buttonAction"><?php echo tep_draw_hidden_field('products_id', $product_info['products_id']) . tep_draw_button(IMAGE_BUTTON_IN_CART, 'cart', null, 'primary'); ?></span></div>
<?php
   $reviews_query = tep_db_query("select count(*) as count from " . TABLE_REVIEWS . " where products_id = '" . (int)$HTTP_GET_VARS['products_id'] . "' and reviews_status = 1");
   $reviews = tep_db_fetch_array($reviews_query);
?>

 <div class="buttonSet">
  <?php $referer = $_SERVER['HTTP_REFERER'];
if (!$referer == '') {
echo tep_draw_button(IMAGE_BUTTON_BACK, 'triangle-1-w', $referer, 'primary');
} else {
echo tep_draw_button(IMAGE_BUTTON_BACK, 'triangle-1-w', tep_href_link(FILENAME_DEFAULT, tep_get_path($current_category_id = '')), 'primary'); }
?>

<?php echo tep_draw_button(IMAGE_BUTTON_REVIEWS . (($reviews['count'] > 0) ? ' (' . $reviews['count'] . ')' : ''), 'comment', tep_href_link(FILENAME_PRODUCT_REVIEWS, tep_get_all_get_params())); ?>
 </div> 
<p> <br /></p>
</div>
<div><?php echo '<a href="' . tep_href_link(FILENAME_ASK_QUESTION, 'products_id='.$product_info['products_id']) . '">' . TEXT_ASK_QUESTION . '</a>'; ?></div>
<?php 
//PRONUX TMS START
include DIR_WS_INCLUDES.'TMS/Conf.php';

$TMS->tab[1]['content'] = $product_info['products_description']; 
$TMS->tab[2]['content'] =  $reviewTabContent = ''; 

 $reviews_query_raw = "select r.reviews_id, left(rd.reviews_text, 100) as reviews_text, r.reviews_rating, r.date_added, r.customers_name from " . TABLE_REVIEWS . " r, " . TABLE_REVIEWS_DESCRIPTION . " rd where r.products_id = '" . (int)$product_info['products_id'] . "' and r.reviews_id = rd.reviews_id and rd.languages_id = '" . (int)$languages_id . "' and r.reviews_status = 1 order by r.reviews_id desc"; 
 $reviews_split = new splitPageResults($reviews_query_raw, MAX_DISPLAY_NEW_REVIEWS); 

 if ($reviews_split->number_of_rows > 0) { 
   if ((PREV_NEXT_BAR_LOCATION == '1') || (PREV_NEXT_BAR_LOCATION == '3')) { 

       $reviewTabContent = ' 
         <div class="contentText"> 
           <p style="float: right;">'. TEXT_RESULT_PAGE . ' ' . $reviews_split->display_links(MAX_DISPLAY_PAGE_LINKS, tep_get_all_get_params(array('page', 'info'))) .'</p> 

           <p>'. $reviews_split->display_count(TEXT_DISPLAY_NUMBER_OF_REVIEWS) .'</p> 
         </div> 

         <br />'; 
   } 

   $reviews_query = tep_db_query($reviews_split->sql_query); 
   while ($reviews = tep_db_fetch_array($reviews_query)) { 

$reviewTabContent .= ' 
 <div> 
   <span style="float: right;">'.sprintf(TEXT_REVIEW_DATE_ADDED, tep_date_long($reviews['date_added'])) .'</span> 
   <h2><a href="' . tep_href_link(FILENAME_PRODUCT_REVIEWS_INFO, 'products_id=' . $product_info['products_id'] . '&reviews_id=' . $reviews['reviews_id']) . '">' . sprintf(TEXT_REVIEW_BY, tep_output_string_protected($reviews['customers_name'])) . '</a> </h2> 
 </div> 

 <div class="contentText"> 
   '. tep_break_string(tep_output_string_protected($reviews['reviews_text']), 60, '-<br />') . ((strlen($reviews['reviews_text']) >= 100) ? '..' : '') . '<br /><br /><i>' . sprintf(TEXT_REVIEW_RATING, tep_image(DIR_WS_IMAGES . 'stars_' . $reviews['reviews_rating'] . '.gif', sprintf(TEXT_OF_5_STARS, $reviews['reviews_rating'])), sprintf(TEXT_OF_5_STARS, $reviews['reviews_rating'])) . '</i> 
 </div>'; 
   } 
 } else { 

$reviewTabContent = ' 
 <div class="contentText"> 
   <?php echo TEXT_NO_REVIEWS; ?> 
 </div>'; 
 } 


$TMS->tab[2]['content'] = $reviewTabContent;
$TMS->tab[3]['content'] = $askTabContent =''; 
$TMS->tab[4]['content'] = $askTabContent; 
$TMS->tab[5]['content'] = $askTabContent; 
$TMS->tab[6]['content'] = $askTabContent;

$TMS->setLanguage('', $_SESSION['language']);
$TMS->generateTabMenuSection(true);
//PRONUX TMS END
?>
</form><br />
<div><a href="http://www.facebook.com/sharer.php" name="fb_share" id="fb_share" type="button_count"> Condividi</a><script src="http://static.ak.fbcdn.net/connect.php/js/FB.Share" type="text/javascript"></script> <br />
<a href="http://twitter.com/share" title="Condividi su Twitter"><img src="http://www.intimoclick.it/images/grafica/twitter.gif" alt="Condividi su Twitter" border="0"/></a><br />
<a href="http://www.google.com/buzz/post" title="Posta su Google Buzz"><img src="http://www.intimoclick.it/images/grafica/buzz.gif" alt="Posta su Google Buzz" border="0" /></a></div>
<?php
 }

 require(DIR_WS_INCLUDES . 'template_bottom.php');
 require(DIR_WS_INCLUDES . 'application_bottom.php');
?>

Link to comment
Share on other sites

Try

<?php
}
//++++ QT Pro: End Changed Code

 

change that to

 

<?php

//++++ QT Pro: End Changed Code

 

That is delete the first "}"

 

 

 

So the whole thing should look like

              <?php

//++++ QT Pro: End Changed Code
   $products_attributes_query = tep_db_query("select count(*) as total from " . TABLE_PRODUCTS_OPTIONS . " popt, " . TABLE_PRODUCTS_ATTRIBUTES . " patrib where patrib.products_id='" . (int)$HTTP_GET_VARS['products_id'] . "' and patrib.options_id = popt.products_options_id and popt.language_id = '" . (int)$languages_id . "'");
   $products_attributes = tep_db_fetch_array($products_attributes_query);
   if ($products_attributes['total'] > 0) {
//++++ QT Pro: Begin Changed code
     $products_id=(preg_match("/^\d{1,10}(\{\d{1,10}\}\d{1,10})*$/",$HTTP_GET_VARS['products_id']) ? $HTTP_GET_VARS['products_id'] : (int)$HTTP_GET_VARS['products_id']); 
     require(DIR_WS_CLASSES . 'pad_' . PRODINFO_ATTRIBUTE_PLUGIN . '.php');
     $class = 'pad_' . PRODINFO_ATTRIBUTE_PLUGIN;
     $pad = new $class($products_id);
     echo $pad->draw();
   }

//Display a table with which attributecombinations is on stock to the customer?
if(PRODINFO_ATTRIBUTE_DISPLAY_STOCK_LIST == 'True'): require(DIR_WS_MODULES . "qtpro_stock_table.php"); endif;

//++++ QT Pro: End Changed Code
?>

Edited by snights
Link to comment
Share on other sites

A bug in catalog/includes/functions/general.php

 

function tep_get_products_stock($products_id, $attributes=array()) {

global $languages_id;

$products_id = tep_get_prid($products_id);

//Fix ? Otherwise $all_nonstocked is not defined if there are no attributes:

$all_nonstocked = false;

if (sizeof($attributes)>0) {

$all_nonstocked = true;

$attr_list='';

$options_list=implode(",",array_keys($attributes));

/*Bug fix replace

$track_stock_query=tep_db_query("select products_options_id, products_options_track_stock from " . TABLE_PRODUCTS_OPTIONS . " where products_options_id in ($options_list) and language_id= '" . (int)$languages_id . "order by products_options_id'");

with*/

$track_stock_query=tep_db_query("select products_options_id, products_options_track_stock from " . TABLE_PRODUCTS_OPTIONS . " where products_options_id in ($options_list) and language_id= '" . (int)$languages_id . "' order by products_options_id");

 

while($track_stock_array=tep_db_fetch_array($track_stock_query)) {

if ($track_stock_array['products_options_track_stock']) {

$attr_list.=$track_stock_array['products_options_id'] . '-' . $attributes[$track_stock_array['products_options_id']] . ',';

$all_nonstocked=false;

}

}

$attr_list=substr($attr_list,0,strlen($attr_list)-1);

}

// Here the $all_nonstocked is undefined if the above fix isn't applied. Pipe symbol: $a | $b means either $a or $b

// NB there is NO condition for $all_nonstocked below. Shouldn't be something like $all_nonstocked==false;?

if ((sizeof($attributes)==0) | ($all_nonstocked)) {

$stock_query = tep_db_query("select products_quantity as quantity from " . TABLE_PRODUCTS . " where products_id = '" . (int)$products_id . "'");

} else {

$stock_query=tep_db_query("select products_stock_quantity as quantity from " . TABLE_PRODUCTS_STOCK . " where products_id='". (int)$products_id . "' and products_stock_attributes='$attr_list'");

}

 

if (tep_db_num_rows($stock_query)>0) {

$stock=tep_db_fetch_array($stock_query);

$quantity=$stock['quantity'];

} else {

$quantity = 0;

}

return $quantity;

//++++ QT Pro: End Changed Code

}

 

Have someone else found this and a correct fix?

Sara

Link to comment
Share on other sites

Not sure if anyone else has had this problem but drove me up a wall. While attributes stock was deducted correctly the total product was not. If you make this change this should correct it. Tested it several ways and worked perfect (No double deductions or anything) but suggest you make sure it works for you as you expect.

 

Find in checkout_process.php:

// do not decrement quantities if products_attributes_filename exists

if (!$download_selected) {

$stock_left = $stock_values['products_quantity'] - $actual_stock_bought;

tep_db_query("UPDATE " . TABLE_PRODUCTS . "

SET products_quantity = products_quantity - '" . $actual_stock_bought . "'

WHERE products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");

 

 

Change to:

// do not decrement quantities if products_attributes_filename exists

if (!$download_selected) {

$actual_stock_bought = $order->products[$i]['qty'];

$stock_left = $stock_values['products_quantity'] - $actual_stock_bought;

tep_db_query("UPDATE " . TABLE_PRODUCTS . "

SET products_quantity = products_quantity - '" . $actual_stock_bought . "'

WHERE products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");

 

btw: this is for the 2.3.1 version no idea if works differently with prior versions as Ive moved on

Edited by MHWD
Link to comment
Share on other sites

Hi,

 

I have SPPC 4 installed

 

Now I have QTpro 4.6 installed.

 

It word great for one thing. It does nog update the atribuut stock

 

Anyone have an Idea.

 

my checkout_process code ( i think it is in there)

 

<?php
/*
 $Id: checkout_process.php 1750 2007-12-21 05:20:28Z hpdl $
 adapted for Separate Pricing Per Customer 2006/09/09 (attribute prices for groups, hide attributes from groups)

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

 Copyright (c) 2007 osCommerce

 Released under the GNU General Public License
*/

 include('includes/application_top.php');

// 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 there is nothing in the customers cart, redirect them to the shopping cart page
 if ($cart->count_contents() < 1) {
   tep_redirect(tep_href_link(FILENAME_SHOPPING_CART));
 }

// if no shipping method has been selected, redirect the customer to the shipping method selection page
 if (!tep_session_is_registered('shipping') || !tep_session_is_registered('sendto')) {
   tep_redirect(tep_href_link(FILENAME_CHECKOUT_SHIPPING, '', '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');
 $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;

// 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));
   }
 }

 $payment_modules->update_status();

 if ( ( is_array($payment_modules->modules) && (sizeof($payment_modules->modules) > 1) && !is_object($$payment) ) || (is_object($$payment) && ($$payment->enabled == false)) ) {
   tep_redirect(tep_href_link(FILENAME_CHECKOUT_PAYMENT, 'error_message=' . urlencode(ERROR_NO_PAYMENT_MODULE_SELECTED), 'SSL'));
 }

 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' => trim($order->delivery['firstname'] . ' ' . $order->delivery['lastname']),
                         'delivery_company' => $order->delivery['company'],
                         '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']);
 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;

 for ($i=0, $n=sizeof($order->products); $i<$n; $i++) {
//++++ QT Pro: Begin Changed code
   $products_stock_attributes=null;
   if (STOCK_LIMITED == 'true') {
       //$products_attributes = $order->products[$i]['attributes'];
//      if (DOWNLOAD_ENABLED == 'true') {
//++++ QT Pro: End Changed Code
       $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
       //++++ QT Pro: Begin Changed code
//      $products_attributes = $order->products[$i]['attributes'];
//++++ QT Pro: End Changed Code
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);
$actual_stock_bought = $order->products[$i]['qty'];
       $download_selected = false;
       if ((DOWNLOAD_ENABLED == 'true') && isset($stock_values['products_attributes_filename']) && tep_not_null($stock_values['products_attributes_filename'])) {
         $download_selected = true;
         $products_stock_attributes='$$DOWNLOAD$$';
       }
// If not downloadable and attributes present, adjust attribute stock
       if (!$download_selected && is_array($products_attributes)) {
         $all_nonstocked = true;
         $products_stock_attributes_array = array();
         foreach ($products_attributes as $attribute) {
           if ($attribute['track_stock'] == 1) {
             $products_stock_attributes_array[] = $attribute['option_id'] . "-" . $attribute['value_id'];
             $all_nonstocked = false;
           }
         } 
         if ($all_nonstocked) {
           $actual_stock_bought = $order->products[$i]['qty'];
         }  else {
           asort($products_stock_attributes_array, SORT_NUMERIC);
           $products_stock_attributes = implode(",", $products_stock_attributes_array);
           $attributes_stock_query = tep_db_query("select products_stock_quantity from " . TABLE_PRODUCTS_STOCK . " where products_stock_attributes = '$products_stock_attributes' AND products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");
           if (tep_db_num_rows($attributes_stock_query) > 0) {
             $attributes_stock_values = tep_db_fetch_array($attributes_stock_query);
             $attributes_stock_left = $attributes_stock_values['products_stock_quantity'] - $order->products[$i]['qty'];
             tep_db_query("update " . TABLE_PRODUCTS_STOCK . " set products_stock_quantity = '" . $attributes_stock_left . "' where products_stock_attributes = '$products_stock_attributes' AND products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");
             $actual_stock_bought = ($attributes_stock_left < 1) ? $attributes_stock_values['products_stock_quantity'] : $order->products[$i]['qty'];
           } else {
             $attributes_stock_left = 0 - $order->products[$i]['qty'];
             tep_db_query("insert into " . TABLE_PRODUCTS_STOCK . " (products_id, products_stock_attributes, products_stock_quantity) values ('" . tep_get_prid($order->products[$i]['id']) . "', '" . $products_stock_attributes . "', '" . $attributes_stock_left . "')");
             $actual_stock_bought = 0;
           }
         }
       }
//        $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_selected) {
		$actual_stock_bought = $order->products[$i]['qty'];
         $stock_left = $stock_values['products_quantity'] - $actual_stock_bought;
         tep_db_query("UPDATE " . TABLE_PRODUCTS . " 
                       SET products_quantity = products_quantity - '" . $actual_stock_bought . "' 
                       WHERE products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");
//++++ QT Pro: End Changed Code
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']) . "'");
       }
     }
   }

// Update products_ordered (for bestsellers list)
   tep_db_query("update " . TABLE_PRODUCTS . " set products_ordered = products_ordered + " . sprintf('%d', $order->products[$i]['qty']) . " where products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");

   //++++ QT Pro: Begin Changed code
   if (!isset($products_stock_attributes)) $products_stock_attributes=null;
   $sql_data_array = array('orders_id' => $insert_id, 
                           'products_id' => tep_get_prid($order->products[$i]['id']), 
                           'products_model' => $order->products[$i]['model'], 
                           'products_name' => $order->products[$i]['name'], 
                           'products_price' => $order->products[$i]['price'], 
                           'final_price' => $order->products[$i]['final_price'], 
                           'products_tax' => $order->products[$i]['tax'], 
                           'products_quantity' => $order->products[$i]['qty'],
                           'products_stock_attributes' => $products_stock_attributes);
//++++ QT Pro: End Changed Code
tep_db_perform(TABLE_ORDERS_PRODUCTS, $sql_data_array);
   $order_products_id = tep_db_insert_id();

//------insert customer choosen option to order--------
   $attributes_exist = '0';
   $products_ordered_attributes = '';
   if (isset($order->products[$i]['attributes'])) {
     $attributes_exist = '1';
     for ($j=0, $n2=sizeof($order->products[$i]['attributes']); $j<$n2; $j++) {
       if (DOWNLOAD_ENABLED == 'true') {
         $attributes_query = "select popt.products_options_name, poval.products_options_values_name, pa.options_values_price, pa.price_prefix, pad.products_attributes_maxdays, pad.products_attributes_maxcount , pad.products_attributes_filename 
                              from " . TABLE_PRODUCTS_OPTIONS . " popt, " . TABLE_PRODUCTS_OPTIONS_VALUES . " poval, " . TABLE_PRODUCTS_ATTRIBUTES . " pa 
                              left join " . TABLE_PRODUCTS_ATTRIBUTES_DOWNLOAD . " pad
                               on pa.products_attributes_id=pad.products_attributes_id
                              where pa.products_id = '" . $order->products[$i]['id'] . "' 
                               and pa.options_id = '" . $order->products[$i]['attributes'][$j]['option_id'] . "' 
                               and pa.options_id = popt.products_options_id 
                               and pa.options_values_id = '" . $order->products[$i]['attributes'][$j]['value_id'] . "' 
                               and pa.options_values_id = poval.products_options_values_id 
                               and popt.language_id = '" . $languages_id . "' 
                               and poval.language_id = '" . $languages_id . "'";
         $attributes = tep_db_query($attributes_query);
       } else {
         $attributes = tep_db_query("select popt.products_options_name, poval.products_options_values_name, pa.options_values_price, pa.price_prefix from " . TABLE_PRODUCTS_OPTIONS . " popt, " . TABLE_PRODUCTS_OPTIONS_VALUES . " poval, " . TABLE_PRODUCTS_ATTRIBUTES . " pa where pa.products_id = '" . $order->products[$i]['id'] . "' and pa.options_id = '" . $order->products[$i]['attributes'][$j]['option_id'] . "' and pa.options_id = popt.products_options_id and pa.options_values_id = '" . $order->products[$i]['attributes'][$j]['value_id'] . "' and pa.options_values_id = poval.products_options_values_id and popt.language_id = '" . $languages_id . "' and poval.language_id = '" . $languages_id . "'");
       }
       $attributes_values = tep_db_fetch_array($attributes);
// BOF Separate Pricing Per Customer attribute_groups mod
 if (isset($_SESSION['sppc_customer_group_id']) && $_SESSION['sppc_customer_group_id'] != '0') {
   $attributes_group_query = tep_db_query("select pag.options_values_price, pag.price_prefix from " . TABLE_PRODUCTS_ATTRIBUTES . " pa left join " . TABLE_PRODUCTS_ATTRIBUTES_GROUPS . " pag using(products_attributes_id) where pa.products_id = '" . tep_get_prid($order->products[$i]['id']) . "' and pa.options_id = '" . $order->products[$i]['attributes'][$j]['option_id'] . "' and pa.options_values_id = '" . $order->products[$i]['attributes'][$j]['value_id'] . "' and pag.customers_group_id = '" . (int)$_SESSION['sppc_customer_group_id'] . "'");
	 if ($attributes_group = tep_db_fetch_array($attributes_group_query)) {
		 $attributes_values['options_values_price'] = $attributes_group['options_values_price'];
		 $attributes_values['price_prefix'] = $attributes_group['price_prefix'];
	 }
 }
// EOF Separate Pricing Per Customer attribute_groups mod

       $sql_data_array = array('orders_id' => $insert_id, 
                               'orders_products_id' => $order_products_id, 
                               'products_options' => $attributes_values['products_options_name'],
                               'products_options_values' => $attributes_values['products_options_values_name'], 
                               'options_values_price' => $attributes_values['options_values_price'], 
                               'price_prefix' => $attributes_values['price_prefix']);
       tep_db_perform(TABLE_ORDERS_PRODUCTS_ATTRIBUTES, $sql_data_array);

       if ((DOWNLOAD_ENABLED == 'true') && isset($attributes_values['products_attributes_filename']) && tep_not_null($attributes_values['products_attributes_filename'])) {
         $sql_data_array = array('orders_id' => $insert_id, 
                                 'orders_products_id' => $order_products_id, 
                                 'orders_products_filename' => $attributes_values['products_attributes_filename'], 
                                 'download_maxdays' => $attributes_values['products_attributes_maxdays'], 
                                 'download_count' => $attributes_values['products_attributes_maxcount']);
         tep_db_perform(TABLE_ORDERS_PRODUCTS_DOWNLOAD, $sql_data_array);
       }
       $products_ordered_attributes .= "\n\t" . $attributes_values['products_options_name'] . ' ' . $attributes_values['products_options_values_name'];
     }
   }
//------insert customer choosen option eof ----
   $total_weight += ($order->products[$i]['qty'] * $order->products[$i]['weight']);
   $total_tax += tep_calculate_tax($total_products_price, $products_tax) * $order->products[$i]['qty'];
   $total_cost += $total_products_price;

   $products_ordered .= $order->products[$i]['qty'] . ' x ' . $order->products[$i]['name'] . ' (' . $order->products[$i]['model'] . ') = ' . $currencies->display_price($order->products[$i]['final_price'], $order->products[$i]['tax'], $order->products[$i]['qty']) . $products_ordered_attributes . "\n";
 }


// Discount Code 2.3 - start
 if (MODULE_ORDER_TOTAL_DISCOUNT_STATUS == 'true') {
   if (!empty($discount)) {
     $discount_codes_query = tep_db_query("select discount_codes_id from " . TABLE_DISCOUNT_CODES . " where discount_codes = '" . tep_db_input($sess_discount_code) . "'");
     $discount_codes = tep_db_fetch_array($discount_codes_query);
     tep_db_perform(TABLE_CUSTOMERS_TO_DISCOUNT_CODES, array('customers_id' => $customer_id, 'discount_codes_id' => $discount_codes['discount_codes_id']));
     tep_db_query("update " . TABLE_DISCOUNT_CODES . " set number_of_orders = number_of_orders + 1 where discount_codes_id = '" . (int)$discount_codes['discount_codes_id'] . "'");

     tep_session_unregister('sess_discount_code');
   }
 }
 // Discount Code 2.3 - end

// lets start with the email confirmation
 $email_order = STORE_NAME . "\n" . 
                EMAIL_SEPARATOR . "\n" . 
                EMAIL_TEXT_ORDER_NUMBER . ' ' . $insert_id . "\n" .
                EMAIL_TEXT_INVOICE_URL . ' ' . tep_href_link(FILENAME_ACCOUNT_HISTORY_INFO, 'order_id=' . $insert_id, 'SSL', false) . "\n" .
                EMAIL_TEXT_DATE_ORDERED . ' ' . strftime(DATE_FORMAT_LONG) . "\n\n";
 if ($order->info['comments']) {
   $email_order .= tep_db_output($order->info['comments']) . "\n\n";
 }
 $email_order .= EMAIL_TEXT_PRODUCTS . "\n" . 
                 EMAIL_SEPARATOR . "\n" . 
                 $products_ordered . 
                 EMAIL_SEPARATOR . "\n";

 for ($i=0, $n=sizeof($order_totals); $i<$n; $i++) {
   $email_order .= strip_tags($order_totals[$i]['title']) . ' ' . strip_tags($order_totals[$i]['text']) . "\n";
 }

 if ($order->content_type != 'virtual') {
   $email_order .= "\n" . EMAIL_TEXT_DELIVERY_ADDRESS . "\n" . 
                   EMAIL_SEPARATOR . "\n" .
                   tep_address_label($customer_id, $sendto, 0, '', "\n") . "\n";
 }

 $email_order .= "\n" . EMAIL_TEXT_BILLING_ADDRESS . "\n" .
                 EMAIL_SEPARATOR . "\n" .
                 tep_address_label($customer_id, $billto, 0, '', "\n") . "\n\n";
 if (is_object($$payment)) {
   $email_order .= EMAIL_TEXT_PAYMENT_METHOD . "\n" . 
                   EMAIL_SEPARATOR . "\n";
   $payment_class = $$payment;
   $email_order .= $order->info['payment_method'] . "\n\n";
   if ($payment_class->email_footer) { 
     $email_order .= $payment_class->email_footer . "\n\n";
   }
 }
 tep_mail($order->customer['firstname'] . ' ' . $order->customer['lastname'], $order->customer['email_address'], EMAIL_TEXT_SUBJECT, $email_order, STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS);

// send emails to other people
 if (SEND_EXTRA_ORDER_EMAILS_TO != '') {
   tep_mail('', SEND_EXTRA_ORDER_EMAILS_TO, EMAIL_TEXT_SUBJECT, $email_order, STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS);
 }

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

 $cart->reset(true);

// unregister session variables used during checkout
 tep_session_unregister('sendto');
 tep_session_unregister('billto');
 tep_session_unregister('shipping');
 tep_session_unregister('payment');
 tep_session_unregister('comments');

 tep_redirect(tep_href_link(FILENAME_CHECKOUT_SUCCESS, '', 'SSL'));

 require(DIR_WS_INCLUDES . 'application_bottom.php');
?>

Edited by mbuist
Link to comment
Share on other sites

I fixed it.

 

here is the updated code

 

<?php
/*
 $Id: checkout_process.php 1750 2007-12-21 05:20:28Z hpdl $
 adapted for Separate Pricing Per Customer 2006/09/09 (attribute prices for groups, hide attributes from groups)

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

 Copyright (c) 2007 osCommerce

 Released under the GNU General Public License
*/

 include('includes/application_top.php');

// 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 there is nothing in the customers cart, redirect them to the shopping cart page
 if ($cart->count_contents() < 1) {
   tep_redirect(tep_href_link(FILENAME_SHOPPING_CART));
 }

// if no shipping method has been selected, redirect the customer to the shipping method selection page
 if (!tep_session_is_registered('shipping') || !tep_session_is_registered('sendto')) {
   tep_redirect(tep_href_link(FILENAME_CHECKOUT_SHIPPING, '', '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');
 $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;

// 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));
   }
 }

 $payment_modules->update_status();

 if ( ( is_array($payment_modules->modules) && (sizeof($payment_modules->modules) > 1) && !is_object($$payment) ) || (is_object($$payment) && ($$payment->enabled == false)) ) {
   tep_redirect(tep_href_link(FILENAME_CHECKOUT_PAYMENT, 'error_message=' . urlencode(ERROR_NO_PAYMENT_MODULE_SELECTED), 'SSL'));
 }

 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' => trim($order->delivery['firstname'] . ' ' . $order->delivery['lastname']),
                         'delivery_company' => $order->delivery['company'],
                         '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']);
 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;

 for ($i=0, $n=sizeof($order->products); $i<$n; $i++) {
//++++ QT Pro: Begin Changed code
   $products_stock_attributes=null;
   if (STOCK_LIMITED == 'true') {
       $products_attributes = $order->products[$i]['attributes'];
//      if (DOWNLOAD_ENABLED == 'true') {
//++++ QT Pro: End Changed Code
       $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
       //++++ QT Pro: Begin Changed code
//      $products_attributes = $order->products[$i]['attributes'];
//++++ QT Pro: End Changed Code
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);
$actual_stock_bought = $order->products[$i]['qty'];
       $download_selected = false;
       if ((DOWNLOAD_ENABLED == 'true') && isset($stock_values['products_attributes_filename']) && tep_not_null($stock_values['products_attributes_filename'])) {
         $download_selected = true;
         $products_stock_attributes='$$DOWNLOAD$$';
       }
// If not downloadable and attributes present, adjust attribute stock
       if (!$download_selected && is_array($products_attributes)) {
         $all_nonstocked = true;
         $products_stock_attributes_array = array();
         foreach ($products_attributes as $attribute) {
           if ($attribute['track_stock'] == 1) {
             $products_stock_attributes_array[] = $attribute['option_id'] . "-" . $attribute['value_id'];
             $all_nonstocked = false;
           }
         } 
         if ($all_nonstocked) {
           $actual_stock_bought = $order->products[$i]['qty'];
         }  else {
           asort($products_stock_attributes_array, SORT_NUMERIC);
           $products_stock_attributes = implode(",", $products_stock_attributes_array);
           $attributes_stock_query = tep_db_query("select products_stock_quantity from " . TABLE_PRODUCTS_STOCK . " where products_stock_attributes = '$products_stock_attributes' AND products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");
           if (tep_db_num_rows($attributes_stock_query) > 0) {
             $attributes_stock_values = tep_db_fetch_array($attributes_stock_query);
             $attributes_stock_left = $attributes_stock_values['products_stock_quantity'] - $order->products[$i]['qty'];
             tep_db_query("update " . TABLE_PRODUCTS_STOCK . " set products_stock_quantity = '" . $attributes_stock_left . "' where products_stock_attributes = '$products_stock_attributes' AND products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");
             $actual_stock_bought = ($attributes_stock_left < 1) ? $attributes_stock_values['products_stock_quantity'] : $order->products[$i]['qty'];
           } else {
             $attributes_stock_left = 0 - $order->products[$i]['qty'];
             tep_db_query("insert into " . TABLE_PRODUCTS_STOCK . " (products_id, products_stock_attributes, products_stock_quantity) values ('" . tep_get_prid($order->products[$i]['id']) . "', '" . $products_stock_attributes . "', '" . $attributes_stock_left . "')");
             $actual_stock_bought = 0;
           }
         }
       }
//        $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_selected) {
		$actual_stock_bought = $order->products[$i]['qty'];
         $stock_left = $stock_values['products_quantity'] - $actual_stock_bought;
         tep_db_query("UPDATE " . TABLE_PRODUCTS . " 
                       SET products_quantity = products_quantity - '" . $actual_stock_bought . "' 
                       WHERE products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");
//++++ QT Pro: End Changed Code
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']) . "'");
       }
     }
   }

// Update products_ordered (for bestsellers list)
   tep_db_query("update " . TABLE_PRODUCTS . " set products_ordered = products_ordered + " . sprintf('%d', $order->products[$i]['qty']) . " where products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");

   //++++ QT Pro: Begin Changed code
   if (!isset($products_stock_attributes)) $products_stock_attributes=null;
   $sql_data_array = array('orders_id' => $insert_id, 
                           'products_id' => tep_get_prid($order->products[$i]['id']), 
                           'products_model' => $order->products[$i]['model'], 
                           'products_name' => $order->products[$i]['name'], 
                           'products_price' => $order->products[$i]['price'], 
                           'final_price' => $order->products[$i]['final_price'], 
                           'products_tax' => $order->products[$i]['tax'], 
                           'products_quantity' => $order->products[$i]['qty'],
                           'products_stock_attributes' => $products_stock_attributes);
//++++ QT Pro: End Changed Code
tep_db_perform(TABLE_ORDERS_PRODUCTS, $sql_data_array);
   $order_products_id = tep_db_insert_id();

//------insert customer choosen option to order--------
   $attributes_exist = '0';
   $products_ordered_attributes = '';
   if (isset($order->products[$i]['attributes'])) {
     $attributes_exist = '1';
     for ($j=0, $n2=sizeof($order->products[$i]['attributes']); $j<$n2; $j++) {
       if (DOWNLOAD_ENABLED == 'true') {
         $attributes_query = "select popt.products_options_name, poval.products_options_values_name, pa.options_values_price, pa.price_prefix, pad.products_attributes_maxdays, pad.products_attributes_maxcount , pad.products_attributes_filename 
                              from " . TABLE_PRODUCTS_OPTIONS . " popt, " . TABLE_PRODUCTS_OPTIONS_VALUES . " poval, " . TABLE_PRODUCTS_ATTRIBUTES . " pa 
                              left join " . TABLE_PRODUCTS_ATTRIBUTES_DOWNLOAD . " pad
                               on pa.products_attributes_id=pad.products_attributes_id
                              where pa.products_id = '" . $order->products[$i]['id'] . "' 
                               and pa.options_id = '" . $order->products[$i]['attributes'][$j]['option_id'] . "' 
                               and pa.options_id = popt.products_options_id 
                               and pa.options_values_id = '" . $order->products[$i]['attributes'][$j]['value_id'] . "' 
                               and pa.options_values_id = poval.products_options_values_id 
                               and popt.language_id = '" . $languages_id . "' 
                               and poval.language_id = '" . $languages_id . "'";
         $attributes = tep_db_query($attributes_query);
       } else {
         $attributes = tep_db_query("select popt.products_options_name, poval.products_options_values_name, pa.options_values_price, pa.price_prefix from " . TABLE_PRODUCTS_OPTIONS . " popt, " . TABLE_PRODUCTS_OPTIONS_VALUES . " poval, " . TABLE_PRODUCTS_ATTRIBUTES . " pa where pa.products_id = '" . $order->products[$i]['id'] . "' and pa.options_id = '" . $order->products[$i]['attributes'][$j]['option_id'] . "' and pa.options_id = popt.products_options_id and pa.options_values_id = '" . $order->products[$i]['attributes'][$j]['value_id'] . "' and pa.options_values_id = poval.products_options_values_id and popt.language_id = '" . $languages_id . "' and poval.language_id = '" . $languages_id . "'");
       }
       $attributes_values = tep_db_fetch_array($attributes);
// BOF Separate Pricing Per Customer attribute_groups mod
 if (isset($_SESSION['sppc_customer_group_id']) && $_SESSION['sppc_customer_group_id'] != '0') {
   $attributes_group_query = tep_db_query("select pag.options_values_price, pag.price_prefix from " . TABLE_PRODUCTS_ATTRIBUTES . " pa left join " . TABLE_PRODUCTS_ATTRIBUTES_GROUPS . " pag using(products_attributes_id) where pa.products_id = '" . tep_get_prid($order->products[$i]['id']) . "' and pa.options_id = '" . $order->products[$i]['attributes'][$j]['option_id'] . "' and pa.options_values_id = '" . $order->products[$i]['attributes'][$j]['value_id'] . "' and pag.customers_group_id = '" . (int)$_SESSION['sppc_customer_group_id'] . "'");
	 if ($attributes_group = tep_db_fetch_array($attributes_group_query)) {
		 $attributes_values['options_values_price'] = $attributes_group['options_values_price'];
		 $attributes_values['price_prefix'] = $attributes_group['price_prefix'];

	 }
 }
// EOF Separate Pricing Per Customer attribute_groups mod

       $sql_data_array = array('orders_id' => $insert_id, 
                               'orders_products_id' => $order_products_id, 
                               'products_options' => $attributes_values['products_options_name'],
                               'products_options_values' => $attributes_values['products_options_values_name'], 
                               'options_values_price' => $attributes_values['options_values_price'], 
                               'price_prefix' => $attributes_values['price_prefix']);

       tep_db_perform(TABLE_ORDERS_PRODUCTS_ATTRIBUTES, $sql_data_array);

       if ((DOWNLOAD_ENABLED == 'true') && isset($attributes_values['products_attributes_filename']) && tep_not_null($attributes_values['products_attributes_filename'])) {
         $sql_data_array = array('orders_id' => $insert_id, 
                                 'orders_products_id' => $order_products_id, 
                                 'orders_products_filename' => $attributes_values['products_attributes_filename'], 
                                 'download_maxdays' => $attributes_values['products_attributes_maxdays'], 
                                 'download_count' => $attributes_values['products_attributes_maxcount']);
         tep_db_perform(TABLE_ORDERS_PRODUCTS_DOWNLOAD, $sql_data_array);
       }
       $products_ordered_attributes .= "\n\t" . $attributes_values['products_options_name'] . ' ' . $attributes_values['products_options_values_name'];
     }
   }
//------insert customer choosen option eof ----
   $total_weight += ($order->products[$i]['qty'] * $order->products[$i]['weight']);
   $total_tax += tep_calculate_tax($total_products_price, $products_tax) * $order->products[$i]['qty'];
   $total_cost += $total_products_price;

   $products_ordered .= $order->products[$i]['qty'] . ' x ' . $order->products[$i]['name'] . ' (' . $order->products[$i]['model'] . ') = ' . $currencies->display_price($order->products[$i]['final_price'], $order->products[$i]['tax'], $order->products[$i]['qty']) . $products_ordered_attributes . "\n";
 }


// Discount Code 2.3 - start
 if (MODULE_ORDER_TOTAL_DISCOUNT_STATUS == 'true') {
   if (!empty($discount)) {
     $discount_codes_query = tep_db_query("select discount_codes_id from " . TABLE_DISCOUNT_CODES . " where discount_codes = '" . tep_db_input($sess_discount_code) . "'");
     $discount_codes = tep_db_fetch_array($discount_codes_query);
     tep_db_perform(TABLE_CUSTOMERS_TO_DISCOUNT_CODES, array('customers_id' => $customer_id, 'discount_codes_id' => $discount_codes['discount_codes_id']));
     tep_db_query("update " . TABLE_DISCOUNT_CODES . " set number_of_orders = number_of_orders + 1 where discount_codes_id = '" . (int)$discount_codes['discount_codes_id'] . "'");

     tep_session_unregister('sess_discount_code');
   }
 }
 // Discount Code 2.3 - end

// lets start with the email confirmation
 $email_order = STORE_NAME . "\n" . 
                EMAIL_SEPARATOR . "\n" . 
                EMAIL_TEXT_ORDER_NUMBER . ' ' . $insert_id . "\n" .
                EMAIL_TEXT_INVOICE_URL . ' ' . tep_href_link(FILENAME_ACCOUNT_HISTORY_INFO, 'order_id=' . $insert_id, 'SSL', false) . "\n" .
                EMAIL_TEXT_DATE_ORDERED . ' ' . strftime(DATE_FORMAT_LONG) . "\n\n";
 if ($order->info['comments']) {
   $email_order .= tep_db_output($order->info['comments']) . "\n\n";
 }
 $email_order .= EMAIL_TEXT_PRODUCTS . "\n" . 
                 EMAIL_SEPARATOR . "\n" . 
                 $products_ordered . 
                 EMAIL_SEPARATOR . "\n";

 for ($i=0, $n=sizeof($order_totals); $i<$n; $i++) {
   $email_order .= strip_tags($order_totals[$i]['title']) . ' ' . strip_tags($order_totals[$i]['text']) . "\n";
 }

 if ($order->content_type != 'virtual') {
   $email_order .= "\n" . EMAIL_TEXT_DELIVERY_ADDRESS . "\n" . 
                   EMAIL_SEPARATOR . "\n" .
                   tep_address_label($customer_id, $sendto, 0, '', "\n") . "\n";
 }

 $email_order .= "\n" . EMAIL_TEXT_BILLING_ADDRESS . "\n" .
                 EMAIL_SEPARATOR . "\n" .
                 tep_address_label($customer_id, $billto, 0, '', "\n") . "\n\n";
 if (is_object($$payment)) {
   $email_order .= EMAIL_TEXT_PAYMENT_METHOD . "\n" . 
                   EMAIL_SEPARATOR . "\n";
   $payment_class = $$payment;
   $email_order .= $order->info['payment_method'] . "\n\n";
   if ($payment_class->email_footer) { 
     $email_order .= $payment_class->email_footer . "\n\n";
   }
 }
 tep_mail($order->customer['firstname'] . ' ' . $order->customer['lastname'], $order->customer['email_address'], EMAIL_TEXT_SUBJECT, $email_order, STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS);

// send emails to other people
 if (SEND_EXTRA_ORDER_EMAILS_TO != '') {
   tep_mail('', SEND_EXTRA_ORDER_EMAILS_TO, EMAIL_TEXT_SUBJECT, $email_order, STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS);
 }

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

 $cart->reset(true);

// unregister session variables used during checkout
 tep_session_unregister('sendto');
 tep_session_unregister('billto');
 tep_session_unregister('shipping');
 tep_session_unregister('payment');
 tep_session_unregister('comments');

 tep_redirect(tep_href_link(FILENAME_CHECKOUT_SUCCESS, '', 'SSL'));

 require(DIR_WS_INCLUDES . 'application_bottom.php');
?>

Link to comment
Share on other sites

I fixed it.

 

here is the updated code

 

<?php
/*
 $Id: checkout_process.php 1750 2007-12-21 05:20:28Z hpdl $
 adapted for Separate Pricing Per Customer 2006/09/09 (attribute prices for groups, hide attributes from groups)

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

 Copyright (c) 2007 osCommerce

 Released under the GNU General Public License
*/

 include('includes/application_top.php');

// 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 there is nothing in the customers cart, redirect them to the shopping cart page
 if ($cart->count_contents() < 1) {
   tep_redirect(tep_href_link(FILENAME_SHOPPING_CART));
 }

// if no shipping method has been selected, redirect the customer to the shipping method selection page
 if (!tep_session_is_registered('shipping') || !tep_session_is_registered('sendto')) {
   tep_redirect(tep_href_link(FILENAME_CHECKOUT_SHIPPING, '', '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');
 $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;

// 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));
   }
 }

 $payment_modules->update_status();

 if ( ( is_array($payment_modules->modules) && (sizeof($payment_modules->modules) > 1) && !is_object($$payment) ) || (is_object($$payment) && ($$payment->enabled == false)) ) {
   tep_redirect(tep_href_link(FILENAME_CHECKOUT_PAYMENT, 'error_message=' . urlencode(ERROR_NO_PAYMENT_MODULE_SELECTED), 'SSL'));
 }

 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' => trim($order->delivery['firstname'] . ' ' . $order->delivery['lastname']),
                         'delivery_company' => $order->delivery['company'],
                         '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']);
 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;

 for ($i=0, $n=sizeof($order->products); $i<$n; $i++) {
//++++ QT Pro: Begin Changed code
   $products_stock_attributes=null;
   if (STOCK_LIMITED == 'true') {
       $products_attributes = $order->products[$i]['attributes'];
//      if (DOWNLOAD_ENABLED == 'true') {
//++++ QT Pro: End Changed Code
       $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
       //++++ QT Pro: Begin Changed code
//      $products_attributes = $order->products[$i]['attributes'];
//++++ QT Pro: End Changed Code
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);
$actual_stock_bought = $order->products[$i]['qty'];
       $download_selected = false;
       if ((DOWNLOAD_ENABLED == 'true') && isset($stock_values['products_attributes_filename']) && tep_not_null($stock_values['products_attributes_filename'])) {
         $download_selected = true;
         $products_stock_attributes='$$DOWNLOAD$$';
       }
// If not downloadable and attributes present, adjust attribute stock
       if (!$download_selected && is_array($products_attributes)) {
         $all_nonstocked = true;
         $products_stock_attributes_array = array();
         foreach ($products_attributes as $attribute) {
           if ($attribute['track_stock'] == 1) {
             $products_stock_attributes_array[] = $attribute['option_id'] . "-" . $attribute['value_id'];
             $all_nonstocked = false;
           }
         } 
         if ($all_nonstocked) {
           $actual_stock_bought = $order->products[$i]['qty'];
         }  else {
           asort($products_stock_attributes_array, SORT_NUMERIC);
           $products_stock_attributes = implode(",", $products_stock_attributes_array);
           $attributes_stock_query = tep_db_query("select products_stock_quantity from " . TABLE_PRODUCTS_STOCK . " where products_stock_attributes = '$products_stock_attributes' AND products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");
           if (tep_db_num_rows($attributes_stock_query) > 0) {
             $attributes_stock_values = tep_db_fetch_array($attributes_stock_query);
             $attributes_stock_left = $attributes_stock_values['products_stock_quantity'] - $order->products[$i]['qty'];
             tep_db_query("update " . TABLE_PRODUCTS_STOCK . " set products_stock_quantity = '" . $attributes_stock_left . "' where products_stock_attributes = '$products_stock_attributes' AND products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");
             $actual_stock_bought = ($attributes_stock_left < 1) ? $attributes_stock_values['products_stock_quantity'] : $order->products[$i]['qty'];
           } else {
             $attributes_stock_left = 0 - $order->products[$i]['qty'];
             tep_db_query("insert into " . TABLE_PRODUCTS_STOCK . " (products_id, products_stock_attributes, products_stock_quantity) values ('" . tep_get_prid($order->products[$i]['id']) . "', '" . $products_stock_attributes . "', '" . $attributes_stock_left . "')");
             $actual_stock_bought = 0;
           }
         }
       }
//        $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_selected) {
		$actual_stock_bought = $order->products[$i]['qty'];
         $stock_left = $stock_values['products_quantity'] - $actual_stock_bought;
         tep_db_query("UPDATE " . TABLE_PRODUCTS . " 
                       SET products_quantity = products_quantity - '" . $actual_stock_bought . "' 
                       WHERE products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");
//++++ QT Pro: End Changed Code
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']) . "'");
       }
     }
   }

// Update products_ordered (for bestsellers list)
   tep_db_query("update " . TABLE_PRODUCTS . " set products_ordered = products_ordered + " . sprintf('%d', $order->products[$i]['qty']) . " where products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");

   //++++ QT Pro: Begin Changed code
   if (!isset($products_stock_attributes)) $products_stock_attributes=null;
   $sql_data_array = array('orders_id' => $insert_id, 
                           'products_id' => tep_get_prid($order->products[$i]['id']), 
                           'products_model' => $order->products[$i]['model'], 
                           'products_name' => $order->products[$i]['name'], 
                           'products_price' => $order->products[$i]['price'], 
                           'final_price' => $order->products[$i]['final_price'], 
                           'products_tax' => $order->products[$i]['tax'], 
                           'products_quantity' => $order->products[$i]['qty'],
                           'products_stock_attributes' => $products_stock_attributes);
//++++ QT Pro: End Changed Code
tep_db_perform(TABLE_ORDERS_PRODUCTS, $sql_data_array);
   $order_products_id = tep_db_insert_id();

//------insert customer choosen option to order--------
   $attributes_exist = '0';
   $products_ordered_attributes = '';
   if (isset($order->products[$i]['attributes'])) {
     $attributes_exist = '1';
     for ($j=0, $n2=sizeof($order->products[$i]['attributes']); $j<$n2; $j++) {
       if (DOWNLOAD_ENABLED == 'true') {
         $attributes_query = "select popt.products_options_name, poval.products_options_values_name, pa.options_values_price, pa.price_prefix, pad.products_attributes_maxdays, pad.products_attributes_maxcount , pad.products_attributes_filename 
                              from " . TABLE_PRODUCTS_OPTIONS . " popt, " . TABLE_PRODUCTS_OPTIONS_VALUES . " poval, " . TABLE_PRODUCTS_ATTRIBUTES . " pa 
                              left join " . TABLE_PRODUCTS_ATTRIBUTES_DOWNLOAD . " pad
                               on pa.products_attributes_id=pad.products_attributes_id
                              where pa.products_id = '" . $order->products[$i]['id'] . "' 
                               and pa.options_id = '" . $order->products[$i]['attributes'][$j]['option_id'] . "' 
                               and pa.options_id = popt.products_options_id 
                               and pa.options_values_id = '" . $order->products[$i]['attributes'][$j]['value_id'] . "' 
                               and pa.options_values_id = poval.products_options_values_id 
                               and popt.language_id = '" . $languages_id . "' 
                               and poval.language_id = '" . $languages_id . "'";
         $attributes = tep_db_query($attributes_query);
       } else {
         $attributes = tep_db_query("select popt.products_options_name, poval.products_options_values_name, pa.options_values_price, pa.price_prefix from " . TABLE_PRODUCTS_OPTIONS . " popt, " . TABLE_PRODUCTS_OPTIONS_VALUES . " poval, " . TABLE_PRODUCTS_ATTRIBUTES . " pa where pa.products_id = '" . $order->products[$i]['id'] . "' and pa.options_id = '" . $order->products[$i]['attributes'][$j]['option_id'] . "' and pa.options_id = popt.products_options_id and pa.options_values_id = '" . $order->products[$i]['attributes'][$j]['value_id'] . "' and pa.options_values_id = poval.products_options_values_id and popt.language_id = '" . $languages_id . "' and poval.language_id = '" . $languages_id . "'");
       }
       $attributes_values = tep_db_fetch_array($attributes);
// BOF Separate Pricing Per Customer attribute_groups mod
 if (isset($_SESSION['sppc_customer_group_id']) && $_SESSION['sppc_customer_group_id'] != '0') {
   $attributes_group_query = tep_db_query("select pag.options_values_price, pag.price_prefix from " . TABLE_PRODUCTS_ATTRIBUTES . " pa left join " . TABLE_PRODUCTS_ATTRIBUTES_GROUPS . " pag using(products_attributes_id) where pa.products_id = '" . tep_get_prid($order->products[$i]['id']) . "' and pa.options_id = '" . $order->products[$i]['attributes'][$j]['option_id'] . "' and pa.options_values_id = '" . $order->products[$i]['attributes'][$j]['value_id'] . "' and pag.customers_group_id = '" . (int)$_SESSION['sppc_customer_group_id'] . "'");
	 if ($attributes_group = tep_db_fetch_array($attributes_group_query)) {
		 $attributes_values['options_values_price'] = $attributes_group['options_values_price'];
		 $attributes_values['price_prefix'] = $attributes_group['price_prefix'];

	 }
 }
// EOF Separate Pricing Per Customer attribute_groups mod

       $sql_data_array = array('orders_id' => $insert_id, 
                               'orders_products_id' => $order_products_id, 
                               'products_options' => $attributes_values['products_options_name'],
                               'products_options_values' => $attributes_values['products_options_values_name'], 
                               'options_values_price' => $attributes_values['options_values_price'], 
                               'price_prefix' => $attributes_values['price_prefix']);

       tep_db_perform(TABLE_ORDERS_PRODUCTS_ATTRIBUTES, $sql_data_array);

       if ((DOWNLOAD_ENABLED == 'true') && isset($attributes_values['products_attributes_filename']) && tep_not_null($attributes_values['products_attributes_filename'])) {
         $sql_data_array = array('orders_id' => $insert_id, 
                                 'orders_products_id' => $order_products_id, 
                                 'orders_products_filename' => $attributes_values['products_attributes_filename'], 
                                 'download_maxdays' => $attributes_values['products_attributes_maxdays'], 
                                 'download_count' => $attributes_values['products_attributes_maxcount']);
         tep_db_perform(TABLE_ORDERS_PRODUCTS_DOWNLOAD, $sql_data_array);
       }
       $products_ordered_attributes .= "\n\t" . $attributes_values['products_options_name'] . ' ' . $attributes_values['products_options_values_name'];
     }
   }
//------insert customer choosen option eof ----
   $total_weight += ($order->products[$i]['qty'] * $order->products[$i]['weight']);
   $total_tax += tep_calculate_tax($total_products_price, $products_tax) * $order->products[$i]['qty'];
   $total_cost += $total_products_price;

   $products_ordered .= $order->products[$i]['qty'] . ' x ' . $order->products[$i]['name'] . ' (' . $order->products[$i]['model'] . ') = ' . $currencies->display_price($order->products[$i]['final_price'], $order->products[$i]['tax'], $order->products[$i]['qty']) . $products_ordered_attributes . "\n";
 }


// Discount Code 2.3 - start
 if (MODULE_ORDER_TOTAL_DISCOUNT_STATUS == 'true') {
   if (!empty($discount)) {
     $discount_codes_query = tep_db_query("select discount_codes_id from " . TABLE_DISCOUNT_CODES . " where discount_codes = '" . tep_db_input($sess_discount_code) . "'");
     $discount_codes = tep_db_fetch_array($discount_codes_query);
     tep_db_perform(TABLE_CUSTOMERS_TO_DISCOUNT_CODES, array('customers_id' => $customer_id, 'discount_codes_id' => $discount_codes['discount_codes_id']));
     tep_db_query("update " . TABLE_DISCOUNT_CODES . " set number_of_orders = number_of_orders + 1 where discount_codes_id = '" . (int)$discount_codes['discount_codes_id'] . "'");

     tep_session_unregister('sess_discount_code');
   }
 }
 // Discount Code 2.3 - end

// lets start with the email confirmation
 $email_order = STORE_NAME . "\n" . 
                EMAIL_SEPARATOR . "\n" . 
                EMAIL_TEXT_ORDER_NUMBER . ' ' . $insert_id . "\n" .
                EMAIL_TEXT_INVOICE_URL . ' ' . tep_href_link(FILENAME_ACCOUNT_HISTORY_INFO, 'order_id=' . $insert_id, 'SSL', false) . "\n" .
                EMAIL_TEXT_DATE_ORDERED . ' ' . strftime(DATE_FORMAT_LONG) . "\n\n";
 if ($order->info['comments']) {
   $email_order .= tep_db_output($order->info['comments']) . "\n\n";
 }
 $email_order .= EMAIL_TEXT_PRODUCTS . "\n" . 
                 EMAIL_SEPARATOR . "\n" . 
                 $products_ordered . 
                 EMAIL_SEPARATOR . "\n";

 for ($i=0, $n=sizeof($order_totals); $i<$n; $i++) {
   $email_order .= strip_tags($order_totals[$i]['title']) . ' ' . strip_tags($order_totals[$i]['text']) . "\n";
 }

 if ($order->content_type != 'virtual') {
   $email_order .= "\n" . EMAIL_TEXT_DELIVERY_ADDRESS . "\n" . 
                   EMAIL_SEPARATOR . "\n" .
                   tep_address_label($customer_id, $sendto, 0, '', "\n") . "\n";
 }

 $email_order .= "\n" . EMAIL_TEXT_BILLING_ADDRESS . "\n" .
                 EMAIL_SEPARATOR . "\n" .
                 tep_address_label($customer_id, $billto, 0, '', "\n") . "\n\n";
 if (is_object($$payment)) {
   $email_order .= EMAIL_TEXT_PAYMENT_METHOD . "\n" . 
                   EMAIL_SEPARATOR . "\n";
   $payment_class = $$payment;
   $email_order .= $order->info['payment_method'] . "\n\n";
   if ($payment_class->email_footer) { 
     $email_order .= $payment_class->email_footer . "\n\n";
   }
 }
 tep_mail($order->customer['firstname'] . ' ' . $order->customer['lastname'], $order->customer['email_address'], EMAIL_TEXT_SUBJECT, $email_order, STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS);

// send emails to other people
 if (SEND_EXTRA_ORDER_EMAILS_TO != '') {
   tep_mail('', SEND_EXTRA_ORDER_EMAILS_TO, EMAIL_TEXT_SUBJECT, $email_order, STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS);
 }

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

 $cart->reset(true);

// unregister session variables used during checkout
 tep_session_unregister('sendto');
 tep_session_unregister('billto');
 tep_session_unregister('shipping');
 tep_session_unregister('payment');
 tep_session_unregister('comments');

 tep_redirect(tep_href_link(FILENAME_CHECKOUT_SUCCESS, '', 'SSL'));

 require(DIR_WS_INCLUDES . 'application_bottom.php');
?>

 

Not sure if my issue is the same... I have I have QTpro 4.6; not sure what SPPC 4 is? But my stock does not subtract if there are attributes. Total number subtracts. What is the solution? Thanks for any help. LW

Link to comment
Share on other sites

  • 2 weeks later...

Hi

 

QTPRO is a good contrib but has a big downside.

It has no multiple attrib quantity boxes on the product info page, so in order to set quantity for each (say) size, customers have to go back and forth (add to cart bttn) many times if the product has several sizes.

 

This (http://addons.oscommerce.com/info/3345) contrib does exactly that, but unfortunately doesn't track attributes stock :(

 

So the perfect solution would be a combination of these 2 mods.

Is there any contribution which works like that or does anyone have an idea how to modify qtpro to show attrib quantity box next to each attribute ?

 

Thanks

Link to comment
Share on other sites

Not sure if my issue is the same... I have I have QTpro 4.6; not sure what SPPC 4 is? But my stock does not subtract if there are attributes. Total number subtracts. What is the solution? Thanks for any help. LW

LW - Did you remember to check the box "track stock" in your product attributes/options page for the attributes you have installed?

Dedicated OsCommerce user. 2011 will be the return of OsC

Link to comment
Share on other sites

LW - Did you remember to check the box "track stock" in your product attributes/options page for the attributes you have installed?

 

 

Yes - I have double checked that. Still keeps happening. LW

Link to comment
Share on other sites

Hi, I'm not sure what to call this to look it up on a search other than attribute title dropdowns. What I'm needing is for my attributes to have the title of each to be the first option on the dropdown and thus removing the need to have the option's title beside the dropdown. My client is wanting COLOR, SIZE and QUANTITY very neat on their site as dropdowns side by side and with no title beside it. Would this contribution by chance have this?

 

In ZenCart they had it setup that you could do it that way by making whatever title you need (Color, Quantity, Size) as an additional option to your list. Then you make it #1 in the sort order and they had an option that you could click on that one value not being clickable so no one could accidentally not choose an option. This is exactly what I need.

 

Does this contribution do that or does anyone know of any coding out there that might? B) :)

Link to comment
Share on other sites

Hi, I'm not sure what to call this to look it up on a search other than attribute title dropdowns. What I'm needing is for my attributes to have the title of each to be the first option on the dropdown and thus removing the need to have the option's title beside the dropdown. My client is wanting COLOR, SIZE and QUANTITY very neat on their site as dropdowns side by side and with no title beside it. Would this contribution by chance have this?

 

In ZenCart they had it setup that you could do it that way by making whatever title you need (Color, Quantity, Size) as an additional option to your list. Then you make it #1 in the sort order and they had an option that you could click on that one value not being clickable so no one could accidentally not choose an option. This is exactly what I need.

 

Does this contribution do that or does anyone know of any coding out there that might? B) :)

 

What QTPro does, primarily, is to allow tracking of stock for product options, not just the main product. Changing the way a dropdown displays would mean changing the html output of whatever function creates the dropdown list, and/or the html output surrounding it, ie in your instance you would add the option name as the first entry on the dropdown before the list is compiled from the option values for that product, and ignore/remove the text for the dropdown heading. Doable in QTPro but also in the core code.

 

Meanwhile... I've been faffing about tonight with displaying the actual price in the dropdown *only* when the attribute price is different to the product price, so that the vast majority of options which aren't changed don't have a scruffy and unnecessary price reference in the dropdown. It's taken me much longer than it should have, and all the information was there already, but in the end I've sussed it, so I thought I'd mention it here in case anyone else wants to know and doesn't want to spend an age scratching their head, lol. It's a very simple matter of moving the line

  if ($products_options['options_values_price'] != '0') {

from line 310-ish to line 296-ish, before

if(PRODINFO_ATTRIBUTE_ACTUAL_PRICE_PULL_DOWN == 'True'){

 

Now I just need to persuade it that the amount I've entered on the admin side is gross, rather than net of VAT, which will be a core code/AJAX Attribute Manager tweak...

Link to comment
Share on other sites

Hi all,

 

QTpro work like a charm for me but I have the following issue:

 

I also have Advanced Search - Attributes and when searching from advanced search I receive results of products are out of stock.

 

Ive tried to add a Check Box to advanced_searh.php saying Only Show Products in Stock and controling the tables products_stock but without sucsess... Im i going in the right direction at least?

 

Regards!!

Link to comment
Share on other sites

Have installed QTPro on my 2.3.1 shop now, clean install, just copied the files.

It doesn't work.

This is in the instructions:

REMEMBER; You must active attribute tracking here:

admin->catalog->product attributes->

when adding/editing an attribute, you must check the Track Stock? checkbox.

Can't find that option

 

When I try to administrate QTPro it doesn't work, looks like this

qtpro_1.jpg

 

And when I press Edit it looks like this

qtpro_2.jpg

osCommerce 2.3.1 - QTPro 4.6.1 - Ultimate SEO URL's 5 Pro r205 - Discount Code 3.1 - Column listing with smart columns - Products Sort and some more

Link to comment
Share on other sites

Hi

 

QTPRO is a good contrib but has a big downside.

It has no multiple attrib quantity boxes on the product info page, so in order to set quantity for each (say) size, customers have to go back and forth (add to cart bttn) many times if the product has several sizes.

 

This (http://addons.oscommerce.com/info/3345) contrib does exactly that, but unfortunately doesn't track attributes stock :(

 

So the perfect solution would be a combination of these 2 mods.

Is there any contribution which works like that or does anyone have an idea how to modify qtpro to show attrib quantity box next to each attribute ?

 

Thanks

 

I have the same question, I was looking for any possibilities to solve this issue, but no luck. Maybe there is someone who can halp. In 2.2 version it was working perfect, but not in 2.3.1 :(

Link to comment
Share on other sites

  • 2 weeks later...

is this contribution working on 2.3.1? Does anyone actually have it working?

Just asking before I install it.

 

Also, had a question about importing the config_and_new_install.sql file. How do you

do that?

 

I have installed on 2.3.1. It is really nice and working.

 

Im using qtpro4.6.1

http://addons.oscommerce.com/info/888

Dated on 7 Dec 2010

 

The only thing have to remove one } on product info page. (install instruction no. 20)

 

<?php
}
//++++ QT Pro: End Changed Code

 

to

 

<?php

//++++ QT Pro: End Changed Code

 

FYI: Get screenshot folder from qtpro4.6

Link to comment
Share on other sites

Just finished installing 4.6.1_1

 

The admin console appears to be working fine, however the e-commerce site now reports the following error.

 

Parse error: syntax error, unexpected T_CASE in /nfs/c06/h01/mnt/88348/domains/store.averagejoe2pro.com/html/includes/application_top.php on line 370

 

Here is the line of code that appears to be causing the problem :

 

case 'remove_product' : if (isset($HTTP_GET_VARS['products_id'])) {

 

Any thoughts ?

 

Thanks!

 

Anthony

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...