Jump to content
Sign in to follow this  
SDeath

Product Accessory Multiplier Sub-total is off.

Recommended Posts

Goodday,

 

I got some very helpfull information last couple of months from this forum thank you for this guys !!!

I'm setting up a online webshop for garden articles.

Though I could always find my answer on this forum, now I am really stuck.

 

I have about 90% done of my webshop and I have several contributions installed they all work as they should luckily.

I am having some problems now with the Product Accessory Multiplier contribution.

 

It all works as it should except for the sub-total in the shopping cart and in the cart info box. it is off several euro's. But only if I use a attribute with a '*' prefix. And I can't find why, I played around with the sub-total calculation line and had several results but it's never the same as the one product in the basket. All other prefixes work as they should and the sub-total is correct.

 

It does calculate the correct prices during checkout when a '*' prefix is used, only place where it goes wrong is the shopping cart.

 

Line 372 is where the sub-total is calculated and that's what I altered to try en error, only thing I get is error.

This is the line :

$this->total += (tep_add_tax($products_price, $products_tax) + $attributes_price) * $qty;

Could you please help me out !?!? It be much appriciated.

 

<?php
/*
 $Id: shopping_cart.php,v 1.35 2003/06/25 21:14:33 hpdl Exp $

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

 Copyright (c) 2003 osCommerce

 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) . "', '" . tep_db_input($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 = '" . tep_db_input($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_string = tep_get_uprid($products_id, $attributes);
  $products_id = tep_get_prid($products_id_string);

  if (defined('MAX_QTY_IN_CART') && (MAX_QTY_IN_CART > 0) && ((int)$qty > MAX_QTY_IN_CART)) {
	  $qty = MAX_QTY_IN_CART;
  }

  $attributes_pass_check = true;

  if (is_array($attributes)) {
	reset($attributes);
	while (list($option, $value) = each($attributes)) {
	  if (!is_numeric($option) || !is_numeric($value)) {
		$attributes_pass_check = false;
		break;
	  }
	}
  }

  if (is_numeric($products_id) && is_numeric($qty) && ($attributes_pass_check == true)) {
	$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')) {
	  if ($notify == true) {
		$new_products_id_in_cart = $products_id;
		tep_session_register('new_products_id_in_cart');
	  }

	  if ($this->in_cart($products_id_string)) {
		$this->update_quantity($products_id_string, $qty, $attributes);
	  } else {
		$this->contents[$products_id_string] = array('qty' => (int)$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_string) . "', '" . (int)$qty . "', '" . date('Ymd') . "')");

		if (is_array($attributes)) {
		  reset($attributes);
		  while (list($option, $value) = each($attributes)) {
			$this->contents[$products_id_string]['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_string) . "', '" . (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..
  if (empty($quantity) || !is_numeric($quantity)) return true;
  // the quanity should be rounded
  // $quantity = round($quantity);
  $quantity = (int)($quantity);

  $products_id_string = tep_get_uprid($products_id, $attributes);
  $products_id = tep_get_prid($products_id_string);

  if (defined('MAX_QTY_IN_CART') && (MAX_QTY_IN_CART > 0) && ((int)$quantity > MAX_QTY_IN_CART)) {
	  $quantity = MAX_QTY_IN_CART;
  }	

  $attributes_pass_check = true;

  if (is_array($attributes)) {
	reset($attributes);
	while (list($option, $value) = each($attributes)) {
	  if (!is_numeric($option) || !is_numeric($value)) {
		$attributes_pass_check = false;
		break;
	  }
	}
  }

  if (is_numeric($products_id) && isset($this->contents[$products_id_string]) && is_numeric($quantity) && ($attributes_pass_check == true)) {
	$this->contents[$products_id_string] = array('qty' => (int)$quantity);
// update database
	if (tep_session_is_registered('customer_id')) tep_db_query("update " . TABLE_CUSTOMERS_BASKET . " set customers_basket_quantity = '" . (int)$quantity . "' where customers_id = '" . (int)$customer_id . "' and products_id = '" . tep_db_input($products_id_string) . "'");

	if (is_array($attributes)) {
	  reset($attributes);
	  while (list($option, $value) = each($attributes)) {
		$this->contents[$products_id_string]['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_string) . "' 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() {
  global $currencies;

  $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 += $currencies->calculate_price($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);
		//BOF Multiply Contribution
		if ($attribute_price['price_prefix'] == '+') {
		  $this->total += $qty * tep_add_tax($attribute_price['options_values_price'], $products_tax);
		} elseif ($attribute_price['price_prefix'] == '-') {
		  $this->total -= $qty * tep_add_tax($attribute_price['options_values_price'], $products_tax);
		} elseif ($attribute_price['price_prefix'] == '*') {
		  $this->total = $this->total * $qty * tep_add_tax($attribute_price['options_values_price'], $products_tax);
		}
		//EOF Multiply Contribution
	  }
	}
  }
}
//BOF Multiply Contribution
function attributes_price($products_id, $products_price) {
  $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'];
	  } elseif ($attribute_price['price_prefix'] == '-') {
		  $attributes_price -= $attribute_price['options_values_price'];
	  } elseif ($attribute_price['price_prefix'] == '*') {
		  $attributes_price = ($products_price * $attribute_price['options_values_price'])-$products_price;
	  }
	  //EOF Multiply Contribution
	}
  }

  return $attributes_price;
}
*/
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'];
  $attributes_price = 0;
  $this->attribute_price = 0;
  $price_multiplier = 1;

	 $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, for shopping cart total
   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->attribute_price += tep_add_tax($attribute_price['options_values_price'], $products_tax);
$attributes_price += $attribute_price['options_values_price'];
	   } elseif ($attribute_price['price_prefix'] == '-') {
		   $attribute_price -= $attribute_price['options_values_price'];
 } elseif ($attribute_price['price_prefix'] == '*') {
		  $price_multiplier *= $attribute_price['options_values_price'];
	   }
	 }
	 $attributes_price = ($price_multiplier * $attributes_price) + ($price_multiplier * $products_price) - $products_price;  
  } else {
  $attributes_price = 0;
}
$this->total += (tep_add_tax($products_price, $products_tax) + $attributes_price) * $qty;
//$this->total = ($this->total * $qty * tep_add_tax($attribute_price['options_values_price'], $products_tax))/$qty;
}
}

  function attributes_price($products_id, $products_price) {
 $attributes_price = 0;
 $price_multiplier = 1;

 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'];
	 } elseif ($attribute_price['price_prefix'] == '-') {
		 $attributes_price -= $attribute_price['options_values_price'];
  } elseif ($attribute_price['price_prefix'] == '*') {
$price_multiplier *=  $attribute_price['options_values_price'];
	 }
   }
 $attributes_price = ($price_multiplier * $attributes_price) + ($price_multiplier * $products_price) - $products_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)),
								//BOF Multiply Contribution
								'final_price' => ($products_price + $this->attributes_price($products_id, $products_price)),
								//EOF Multiply Contribution
								'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'];
  }
}

 }
?>

Share this post


Link to post
Share on other sites

No one can help me with my problem here ?

 

This is about the last thing I need to do before going live.

 

Please help me !?!?

Share this post


Link to post
Share on other sites

Simple noninvasive implementation of
Price-Multiplicative product attributes ( was missing from oscommerce ... eg. *1.1 was interpreted as -1.1).
I found the "bof-eof" contrib too difficult to apply and review.

shopping_cart.php in the shopping_cart.php_MULTIPLICATIVE_attributes_cleanly.zip has the .diff (also included) already applied.

The diff adds only about +10 codelines, and another 10 lines rewritten for readability (avoiding some copypaste in the orig code).
If product has multiple (sets of) attributes, avoid mixing *M and +A (except +0.0 which should be fine), otherwise operator precedence might not be deterministic/consistent as the order of product options sometimes gets messed up in oscommerce orders (which does not effect result if only + -  used as traditionally; or only *,* options with this patch).

The main part of the code is:

              $ovp = $attribute_price[$n]['options_values_price'];
               $pp = $attribute_price[$n]['price_prefix'];
            if ($pp == '+') {
              $attributes_price += $ovp;
            } elseif($pp == '-') {
              $attributes_price -= $ovp;
            } elseif($pp == '*') {
                       $attributes_price += $this->last_products_price * ($ovp-1.0);
                       $this->last_products_price *= $ovp;
             }

shopping_cart.php_MULTIPLICATIVE_attributes_cleanly.zip

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×