<?php
/*
  osCommerce, Open Source E-Commerce Solutions 
http://www.oscommerce.com 
Copyright (c) 2003 osCommerce 
 
osConcert Seat Booking Software
https://www.osconcert.com
Copyright (c) 2024 osConcert
Released under the GNU General Public License
*/ 
// Check to ensure this file is included in osConcert!
defined('_FEXEC') or die();
class shoppingCart 
{
	var $contents, $total, $weight, $cartID, $content_type,$mode;
	function __construct() 
	{
		$this->reset();
	}
	 function restaurant_total() 
	 {
		 global $FSESSION;
		$product_id_list = '';
		if (is_array($this->contents)) 
		{
			reset($this->contents);
			$qty_tot = 0;
			foreach(array_keys($this->contents) as $products_id) 
			{
					$product_id_list .= "'" . tep_get_prid($products_id) ."'," ;
					$sql    = "
					SELECT
						products_number
					FROM
						products_description
					WHERE
						products_id = '" . $products_id . "'
					AND
						language_id = '" . (int)$FSESSION->languages_id . "'";
					$result = tep_db_query($sql);
					$arr = tep_db_fetch_array($result);
					$total = $arr ['products_number'];			
								
					//echo "<br>Product Id: ". $products_id. " qty: " .$this->contents[$products_id]['qty'] . " has " . $total ." as product_number in table";
					
					$qty_tot =  $qty_tot + ($this->contents[$products_id]['qty'] * $total);
					
					//echo "<br> Running total: " . $qty_tot ."<br>";
			}
		}
		return $qty_tot;
		}
	
	
	
	
	function restore_contents() 
	{ 
		//ICW replace line
		global $FSESSION, $gv_id,  $REMOTE_ADDR;
		$bol_insert=false;
		if (!$FSESSION->is_registered('customer_id')) return false;
		// insert current cart contents in database
      if (is_array($this->contents)) 
	  {
        //FOREACH
		foreach(array_keys($this->contents) as $products_id) 
		{
          $qty = $this->contents[$products_id]['qty'];
				$element_id=$products_id;
				
				
				$product_query = tep_db_query("select products_id from " . TABLE_CUSTOMERS_BASKET . " where customers_id = '" . (int)$FSESSION->customer_id . "' and products_id = '" . tep_db_input($element_id) . "' and products_type='".tep_db_input($this->contents[$products_id]['element_type'])."'");
				
				if (tep_db_num_rows($product_query)<=0) 
				{
				
					tep_db_query("delete from " .TABLE_CUSTOMERS_TEMP_BASKET ." where products_id='".tep_db_input($element_id)."' and products_type='".tep_db_input($this->contents[$products_id]['element_type'])."' and customers_id='". tep_db_input($FSESSION->ID) ."'"); 
					if($this->contents[$products_id]['old_orders_id']=="")$this->contents[$products_id]['old_orders_id']=0;
					if($qty=="")$qty=0;
					//if($this->contents[$products_id]['old_orders_id']=="")$this->contents[$products_id]['old_orders_id']=0;
					tep_db_query("insert into " . TABLE_CUSTOMERS_BASKET . " 
					                   (customers_id, 
									    products_id, 
										customers_basket_quantity, 
										customers_basket_date_added, 
										products_type,
										old_orders_id,
										discount_id, 
										session_id) 
					             values 
					                   ('" . (int)$FSESSION->customer_id . "', 
					                    '" . tep_db_input($element_id) . "', 
										'" . tep_db_input($qty) . "',now(),
										'" . tep_db_input($this->contents[$products_id]['element_type']) . "',
								    	'" . tep_db_input($this->contents[$products_id]['old_orders_id']) . "',
										'" . (int)$this->contents[$products_id]['discount_id'] . "',
										'" . tep_db_input($FSESSION->ID) . "')
										");

				} else 
				{
					tep_db_query("delete from " .TABLE_CUSTOMERS_TEMP_BASKET ." where products_id='".tep_db_input($element_id)."' and products_type='".tep_db_input($this->contents[$products_id]['element_type'])."' and customers_id='". tep_db_input($FSESSION->ID) ."'"); 
					if ($this->contents[$products_id]['element_type']=='P')
					{
						if($qty=="")$qty=0;
						tep_db_query("update " . TABLE_CUSTOMERS_BASKET . " set customers_basket_quantity = '" . tep_db_input($qty) . "',discount_id='" . (int)$this->contents[$products_id]['discount_id'] . "' where customers_id = '" . (int)$FSESSION->customer_id . "' and products_id = '" . tep_db_input($element_id) . "'");
					} 
				}
        	}
			//ICW ADDDED FOR CREDIT CLASS GV - START
			if ($FSESSION->is_registered('gv_id')) 
			{
				$gv_query = tep_db_query("insert into  " . TABLE_COUPON_REDEEM_TRACK . " (coupon_id, customer_id, redeem_date, redeem_ip) values ('" . tep_db_input($FSESSION->gv_id) . "', '" . (int)$FSESSION->customer_id . "', now(),'" . $REMOTE_ADDR . "')");
				$gv_update = tep_db_query("update " . TABLE_COUPONS . " set coupon_active = 'N' where coupon_id = '" . tep_db_input($FSESSION->gv_id) . "'");
				tep_gv_account_update((int)$FSESSION->customer_id, tep_db_input($FSESSION->gv_id));
				$FSESSION->remove('gv_id');
			}
			//ICW ADDDED FOR CREDIT CLASS GV - END
		}
		// reset per-session cart contents, but not the database contents
		$this->reset(false);
		$bol_taken=false;
		$products_query = tep_db_query("select products_id,customers_basket_quantity,products_type,old_orders_id,answer_type,answer_value,discount_id from " . TABLE_CUSTOMERS_BASKET . " where customers_id = '" . (int)$FSESSION->customer_id . "'");
		while ($products = tep_db_fetch_array($products_query)) {
				$products_id=$products['products_id'];
			
			$this->contents[$products_id] = array('qty' => $products['customers_basket_quantity'],'element_type'=>$products['products_type'],'old_orders_id'=>$products['old_orders_id'],'answer_type'=>$products['answer_type'],'answer_value'=>$products['answer_value'],'sessions'=>array(),'discount_id'=>$products['discount_id']);
		}
		$this->cleanup();
	}
	function reset($reset_database = false) 
	{
		global $FSESSION;
		$this->contents = array();
		$this->total = 0;
		$this->weight = 0;
		$this->content_type = false;
		if ($FSESSION->is_registered('customer_id') && ($reset_database == true)) 
		{
			tep_db_query("delete from " . TABLE_CUSTOMERS_BASKET . " where customers_id = '" . (int)$FSESSION->customer_id . "'");
		} else if (!$FSESSION->is_registered('customer_id') && ($reset_database == true)) 
		{
			tep_db_query("delete from " . TABLE_CUSTOMERS_TEMP_BASKET . " where customers_id = '" . tep_db_input($FSESSION->ID) . "'");
		} 
		unset($this->cartID);
		if ($FSESSION->is_registered('cartID')) $FSESSION->remove('cartID');
	}
	
	function add_cart($products_id, $qty = '1', $attributes = '', $notify = true,$sessions=array(),$old_orders_id=0,$salemaker_id=0) 
	{
		global $FSESSION;
		
		$products_id_string = tep_get_uprid($products_id, $attributes);
		$products_id = tep_get_prid($products_id_string);
		
		$attributes_pass_check = true;
		if (is_array($attributes)) {
			reset($attributes);
		}
		
		if (is_numeric($products_id) && is_numeric($qty) && ($attributes_pass_check == true)) 
		{
		$check_product_query = tep_db_query("select products_status,product_type,products_price_break 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;
			$FSESSION->set('new_products_id_in_cart',$new_products_id_in_cart);
		  }

		  // get the cross product_ids
		  if ($this->in_cart($products_id_string)) 
		  {
			
			if(($check_product['products_price_break']=='Y') || ($check_product['products_price_break']=='N'))
				$this->update_quantity($products_id_string, $qty, $attributes,array(),0,$salemaker_id);
		  } else 
		  {
			$this->contents[$products_id_string] = array('qty' => $qty,'element_type'=>'P','sessions'=>array(),'old_orders_id'=>0,'answer_type'=>'','answer_value'=>'','discount_id'=>$salemaker_id);
		   
		// insert into database
			if($qty=="")$qty=0;
			if($old_orders_id=="")$old_orders_id=0;
			
			if ($FSESSION->is_registered('customer_id')) 
				tep_db_query("insert into " . TABLE_CUSTOMERS_BASKET . " (customers_id, products_id, customers_basket_quantity, customers_basket_date_added,products_type,old_orders_id,discount_id, session_id) values ('" . (int)$FSESSION->customer_id . "', '" . tep_db_input($products_id_string) . "', '" . (int)$qty . "', now(),'P', '" . tep_db_input($old_orders_id) ."'," . tep_db_input($salemaker_id) . ",'".tep_db_input($FSESSION->ID)."')");
			else
				tep_db_query("insert into " . TABLE_CUSTOMERS_TEMP_BASKET . " (customers_id, products_id, customers_basket_quantity, customers_basket_date_added,products_type,old_orders_id,discount_id) values ('" . tep_db_input($FSESSION->ID) . "', '" . tep_db_input($products_id_string) . "', '" . (int)$qty . "', now(),'P', '" . (int)$old_orders_id ."'," . tep_db_input($salemaker_id) . ")");
				
			if (is_array($attributes)) 
			{

			}
		  }
	 
		  $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 to add to a box office refund cart
   	function add_cart_refund($products_id, $qty = '1',$old_orders_id=0, $attributes = '', $notify = true,$sessions=array(),$salemaker_id=0) {
	global $FSESSION;
	if(!$_SESSION['customer_country_id']==999 || !isset($_SESSION['box_office_refund'] )){
		exit('Unauthorised access to refund function');
		} 
	
	$products_id_string = tep_get_uprid($products_id, $attributes);
	$products_id = tep_get_prid($products_id_string);
	
	$attributes_pass_check = true;
	if (is_array($attributes)) 
	{
		reset($attributes);

	}
	
	if (is_numeric($products_id) && is_numeric($qty) && ($attributes_pass_check == true)) {
    $check_product_query = tep_db_query("select products_status,product_type,products_price_break from " . TABLE_PRODUCTS . " where products_id = '" . (int)$products_id . "'");//Support Packs
    $check_product = tep_db_fetch_array($check_product_query);
    if (($check_product !== false) ) {
      if ($notify == true) {
        $new_products_id_in_cart = $products_id;
        $FSESSION->set('new_products_id_in_cart',$new_products_id_in_cart);
      }
 
	   {
		$this->contents[$products_id_string] = array('qty' => $qty,'element_type'=>'P','sessions'=>array(),'old_orders_id'=>$old_orders_id,'answer_type'=>'','answer_value'=>'','discount_id'=>$salemaker_id);
       
// insert into database
		if($qty=="")$qty=0;
		if($old_orders_id=="")$old_orders_id=0;
		
        if ($FSESSION->is_registered('customer_id')) 
		{
		//GA Box Office - check for existing entry
		    $check=tep_db_query("select * from ".TABLE_CUSTOMERS_BASKET." where old_orders_id='".$old_orders_id."' and products_id ='" . tep_db_input($products_id) . "' and  old_orders_id > '0'");
			if (tep_db_num_rows($check)>0){//exists
			  $check_result=tep_db_fetch_array($check);
			
			tep_db_query("update " . TABLE_CUSTOMERS_BASKET . " set customers_basket_quantity = '" . (int)($qty) . "',discount_id='" . (int)$salemaker_id . "' where customers_id = '" . (int)$FSESSION->customer_id . "' and products_id = '" . tep_db_input($products_id) . "'");
			
			}else{
		
			tep_db_query("insert into " . TABLE_CUSTOMERS_BASKET . " (customers_id, products_id, customers_basket_quantity, customers_basket_date_added,products_type,old_orders_id,discount_id) values ('" . (int)$FSESSION->customer_id . "', '" . tep_db_input($products_id_string) . "', '" . (int)$qty . "', now(),'P', '" . tep_db_input($old_orders_id) ."'," . tep_db_input($salemaker_id) . ")");
		    }
		
		}else
		{
			tep_db_query("insert into " . TABLE_CUSTOMERS_TEMP_BASKET . " (customers_id, products_id, customers_basket_quantity, customers_basket_date_added,products_type,old_orders_id,discount_id) values ('" . tep_db_input($FSESSION->ID) . "', '" . tep_db_input($products_id_string) . "', '" . (int)$qty . "', now(),'P', '" . (int)$old_orders_id ."'," . tep_db_input($salemaker_id) . ")");
			}
			
        if (is_array($attributes)) 
		{
          reset($attributes);

        }
      }
 
      $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 to add to a box office reservation confirm cart
   	function add_cart_reservation($products_id, $qty = '1',$old_orders_id=0, $attributes = '', $notify = true,$sessions=array(),$salemaker_id=0) {
	global $FSESSION;
	if(!$_SESSION['customer_country_id']==999 )
	{
		exit('Unauthorised access to refund function');
		} 
	$products_id_string = tep_get_uprid($products_id, $attributes);
	$products_id = tep_get_prid($products_id_string);
	$attributes_pass_check = true;
	if (is_array($attributes)) {
		reset($attributes);

	}
	if (is_numeric($products_id) && is_numeric($qty) && ($attributes_pass_check == true)) 
	{
    $check_product_query = tep_db_query("select products_status,product_type,products_price_break from " . TABLE_PRODUCTS . " where products_id = '" . (int)$products_id . "'");
    $check_product = tep_db_fetch_array($check_product_query);
    if (($check_product !== false) ) {
      if ($notify == true) {
        $new_products_id_in_cart = $products_id;
        $FSESSION->set('new_products_id_in_cart',$new_products_id_in_cart);
      }
	   {
        //$this->contents[$products_id_string] = array('qty' => $qty,'element_type'=>'P','sessions'=>array(),'old_orders_id'=>0,'answer_type'=>'','answer_value'=>'')
		$this->contents[$products_id_string] = array('qty' => $qty,'element_type'=>'P','sessions'=>array(),'old_orders_id'=>$old_orders_id,'answer_type'=>'','answer_value'=>'','discount_id'=>$salemaker_id);
// insert into database
		if($qty=="")$qty=0;
		if($old_orders_id=="")$old_orders_id=0;
        if ($FSESSION->is_registered('customer_id')) {
		//GA Box Office - check for existing entry
		    $check=tep_db_query("select * from ".TABLE_CUSTOMERS_BASKET." where old_orders_id='".$old_orders_id."' and products_id ='" . tep_db_input($products_id) . "' and  old_orders_id > '0'");
			if (tep_db_num_rows($check)>0){//exists
			  $check_result=tep_db_fetch_array($check);
			tep_db_query("update " . TABLE_CUSTOMERS_BASKET . " set customers_basket_quantity = '" . (int)($qty) . "',discount_id='" . (int)$salemaker_id . "' where customers_id = '" . (int)$FSESSION->customer_id . "' and products_id = '" . tep_db_input($products_id) . "'");
			}else{
			tep_db_query("insert into " . TABLE_CUSTOMERS_BASKET . " (customers_id, products_id, customers_basket_quantity, customers_basket_date_added,products_type,old_orders_id,discount_id) values ('" . (int)$FSESSION->customer_id . "', '" . tep_db_input($products_id_string) . "', '" . (int)$qty . "', now(),'P', '" . tep_db_input($old_orders_id) ."'," . tep_db_input($salemaker_id) . ")");
		    }
		}else{
			tep_db_query("insert into " . TABLE_CUSTOMERS_TEMP_BASKET . " (customers_id, products_id, customers_basket_quantity, customers_basket_date_added,products_type,old_orders_id,discount_id) values ('" . tep_db_input($FSESSION->ID) . "', '" . tep_db_input($products_id_string) . "', '" . (int)$qty . "', now(),'P', '" . (int)$old_orders_id ."'," . tep_db_input($salemaker_id) . ")");
			}
        if (is_array($attributes)) {
          reset($attributes);

        }
      }
      $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 = '',$sessions=array(),$old_orders_id=0,$salemaker_id=0) {
		global $FSESSION;
		
		if (empty($quantity)) return true; // nothing needs to be updated if theres no quantity, so we return true..
		
		$products_id_string = tep_get_uprid($products_id, $attributes);
		$products_id = tep_get_prid($products_id_string);
		
		$attributes_pass_check = true;
		if (is_array($attributes)) {
			reset($attributes);

		}
		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' => $quantity,'element_type'=>'P','sessions'=>$sessions,'old_orders_id'=>$old_orders_id,'answer_type'=>'','answer_value'=>'','discount_id'=>$salemaker_id);
			// update database
			if($quantity=="")$quantity=0;
			if ($FSESSION->is_registered('customer_id')) 
			{
				tep_db_query("update " . TABLE_CUSTOMERS_BASKET . " set customers_basket_quantity = '" . (int)$quantity . "',discount_id='" . (int)$salemaker_id . "' where customers_id = '" . (int)$FSESSION->customer_id . "' and products_id = '" . tep_db_input($products_id_string) . "'");
			} else
				tep_db_query("update " . TABLE_CUSTOMERS_TEMP_BASKET . " set customers_basket_quantity = '" . (int)$quantity . "' where customers_id = '" . tep_db_input($FSESSION->ID) . "' and products_id = '" . tep_db_input($products_id_string) . "'");
			if (is_array($attributes)) {
				reset($attributes);

			}
		}
	}

	function cleanup() 
	{
	global $FSESSION;

      //FOREACH
	  foreach(array_keys($this->contents) as $key) 
	  {
        if ($this->contents[$key]['qty'] < 1) 
		{
          unset($this->contents[$key]);
		// remove from database
			if ($FSESSION->is_registered('customer_id')) 
			{
				tep_db_query("delete from " . TABLE_CUSTOMERS_BASKET . " where customers_id = '" . (int)$FSESSION->customer_id . "' and products_id = '" . tep_db_input($key) . "'");

				} else 
				{
				tep_db_query("delete from " . TABLE_CUSTOMERS_TEMP_BASKET . " where customers_id = '" . tep_db_input($FSESSION->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 count_contents() 
	 {  // get total number of items in cart

      $total_items = 0;
      if (is_array($this->contents)) 
	  {
        //FOREACH
		foreach ( array_keys($this->contents) as $products_id ) 
		{
          $total_items += $this->get_quantity($products_id);
        }
      }
     // unset ($products_id);

      return $total_items;
	 }
	 // following function is an alternative to the one above.
	 // it counts Gift Vouchers as ONE item and should be used 
	 // where the number of items in the cart is displayed to the 
	 // user
	 // it utilises the next function (get_quantity_gt) and the
	 // check_for_voucher_gt
	 function count_contents_gt() 
	 {  // get total number of items in cart

      $total_items = 0;
      if (is_array($this->contents)) 
	  {
        foreach ( array_keys($this->contents) as $products_id ) 
		{
          $total_items += $this->get_quantity_gt($products_id);
        }
      }
      unset ($products_id);

      return $total_items;
	 }
	
    function get_quantity_gt($products_id_string) 
	{
		if (isset($this->contents[$products_id_string])) 
		{   
		  if ($this->check_for_voucher_gt($products_id_string))
			{
				return 1;
				}else{
			return $this->contents[$products_id_string]['qty'];
			}
		} else {
			return 0;
		}
	}
	 function check_for_voucher_gt($products_id)
	 //returns true if individual product is a voucher (sku==6)
    {
		$gv_query = tep_db_query("select products_sku from " . TABLE_PRODUCTS . " where products_id = '" . (int)$products_id . "'");
		$gv_result = tep_db_fetch_array($gv_query);
            if (($gv_result['products_sku'] == 6))
                {
                return true;				
                }else{ 
                return false;
        }
    }
    
	function get_quantity($products_id_string) 
	{
		if (isset($this->contents[$products_id_string])) 
		{
			return $this->contents[$products_id_string]['qty'];
		} else {
			return 0;
		}
	}
	
	function is_price_break($products_id){
		$query=tep_db_query("SELECT products_price_break from " . TABLE_PRODUCTS . " where products_id=" .(int)$products_id);
		$result=tep_db_fetch_array($query);
		if ($result["products_price_break"]=="Y") return true;
		else return false;
	}
	function in_cart($products_id_string) {
		if (isset($this->contents[$products_id_string])) 
		{
			return true;
		} else {
			return false;
		}
	}
	
	function remove($products_id) {
        global $FSESSION;       
        if ($products_id === ''){return;}       
        //empty the cart session of the product
        unset($this->contents[$products_id]);
        //delete from the tables       
        if ($FSESSION->is_registered('customer_id')) {
            tep_db_query("delete from " . TABLE_CUSTOMERS_BASKET . " where customers_id = '" . (int)$FSESSION->customer_id . "' and products_id = '" . tep_db_input($products_id) . "'");       
        }else{
            tep_db_query("delete from " . TABLE_CUSTOMERS_TEMP_BASKET . " where customers_id = '" . tep_db_input($FSESSION->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($only_product_ids=true) {
		$product_id_list = '';
		if (is_array($this->contents)) 
		{
			reset($this->contents);
			foreach(array_keys($this->contents) as $products_id) 
			{
					$product_id_list .= ($only_product_ids?',' . tep_get_prid($products_id):',' . $products_id);
			}
		}
		return substr($product_id_list, 1);
	}
	function calculate() 
	{
		global $dates;
		$this->total_virtual = 0; // ICW Gift Voucher System
		$this->total = 0;
		$this->weight = 0;
		$this->stored_total = 0;
		if (!is_array($this->contents)) return 0;
	
		$owd_costs=0;
		reset($this->contents);
		$this->mode="";
		//FOREACH
		//while (list($products_id, ) = each($this->contents)) 
		//{
			foreach(array_keys($this->contents) as $products_id) 
			{

				$qty = $this->contents[$products_id]['qty'];
				$owd_cost = 0;
				$this->info['owd_cost'] = $owd_cost;
				$this->info['subtotal'] += $this->info['owd_cost'];

				//$owd_costs+=tep_owd_costs('quantity',$this->contents[$products_id]['qty']);
				// products price
				$this->mode=($this->mode=="" || $this->mode=="P"?"P":"M");
				$product_query = tep_db_query("select products_id, products_price,products_price_break,products_tax_class_id, products_weight from " . TABLE_PRODUCTS . " where products_id = '" . (int)$products_id . "'");
				if ($product = tep_db_fetch_array($product_query)) 
				{
					
					// ICW ORDER TOTAL CREDIT CLASS Start Amendment
					$no_count = 1;
					$gv_query = tep_db_query("select products_model from " . TABLE_PRODUCTS . " where products_id = '" . (int)$products_id . "'");
					$gv_result = tep_db_fetch_array($gv_query);
					if (preg_match('/^GIFT/', $gv_result['products_model'])){
						$no_count = 0;
						}
					// ICW ORDER TOTAL  CREDIT CLASS End Amendment
					
					$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'];
					$products_price=$this->get_product_price($products_id,$product,0);
					if ($this->contents[$products_id]['discount_id']>0) {
						$product_to_categories_query = tep_db_query("select categories_id from " . TABLE_PRODUCTS_TO_CATEGORIES . " where products_id = '" . (int)$prid . "'");
						$product_to_categories = tep_db_fetch_array($product_to_categories_query);
						//$category = $product_to_categories['categories_id'];
						//March 2013 - this is not returning correct categories - it need to check the top category
						$cats=explode('_',(tep_get_product_path($prid)));
						foreach($cats as $key=>$value){
						$cats1.='or sale_categories_all like \'%,'.$value.',%\' ';
						}
						$sale_option=" sale_id=" . $this->contents[$products_id]['discount_id'] .' and ' ;
						$sDate=getServerDate();
						$sale_query = tep_db_query("select sale_specials_condition, sale_deduction_value, sale_deduction_type,sale_id,sale_discount_type from " . TABLE_SALEMAKER_SALES . " where " . $sale_option . " ((sale_categories_all='' and sale_products_selected='') ".$cats1." or sale_products_selected like '%," . (int)$prid .",%') and sale_status = '1' and (sale_date_start <= '" . $sDate. "' or sale_date_start = '0000-00-00') and (sale_date_end >= '" . tep_db_input($sDate) . "' or sale_date_end = '0000-00-00')");
						//exit('.....'.print_r($cats1));
						
						if (tep_db_num_rows($sale_query)>0){
							$sale=tep_db_fetch_array($sale_query);
							$products_price=tep_get_salemaker_price($this->contents[$products_id]['special_price'],$products_price,$sale);
						}
					}
							
					$this->weight_virtual += ($qty * $products_weight) * $no_count;// ICW CREDIT CLASS;
					$this->weight += ($qty * $products_weight);
				}

				$this->total_virtual += tep_add_tax($products_price, $products_tax) * $qty * $no_count;// ICW CREDIT CLASS;
				$this->total += tep_add_tax($products_price, $products_tax) * $qty;
		
			}	
    }
	

	function get_products() 
	{
	global $FSESSION,$dates,$currencies;
	if (!is_array($this->contents)) 
		return false;
	$products_array = array();
	reset($this->contents);

      foreach(array_keys($this->contents) as $products_id) 
	  {
			
				$products_query = tep_db_query("select 
				p.products_id, 
				p.products_season, 
				p.master_quantity, 
				p.products_sku, 
				p.products_price_break,
				p.product_type,
				pd.products_name,
				pd.products_number, 
				pd.products_url,
				p.products_model,
				p.products_image_1,
				p.products_title_1,
				p.products_price, 
				p.products_date_available,
				p.products_weight, 
				p.products_tax_class_id, 
				p.section_id,
				cd.categories_name,
				cd.categories_id 
				from " . TABLE_PRODUCTS . " p left join " . TABLE_PRODUCTS_TO_CATEGORIES . " pc on  pc.products_id = p.products_id left join " . TABLE_CATEGORIES_DESCRIPTION ." as cd on cd.categories_id=pc.categories_id and cd.language_id = '" . (int)$FSESSION->languages_id . "' left join " . TABLE_PRODUCTS_DESCRIPTION . " as pd on pd.products_id =  '" . (int)$products_id . "' and pd.language_id = '" . (int)$FSESSION->languages_id . "' where p.products_id = '" . (int)$products_id . "'  "); 
	 
				if ($products = tep_db_fetch_array($products_query)) 
				{
					$prid = $products['products_id'];
					//$original_price=$products["products_price"];
					$original_price=$products_price = $this->get_product_price($products_id,$products,0);
					$products_tax=tep_get_tax_rate($products['products_tax_class_id']);
					$price_breaks=false;
					$discount_text='';
					$discount_whole_text='';
					if ($products["products_price_break"]=="Y") 
					{
						$price_breaks=tep_get_products_price_breaks_discount($prid,$this->contents[$products_id]['qty'] ); 
						$discount_text = $currencies->format($price_breaks);
						$discount_whole_text=TEXT_DISCOUNT_APPLIED . '&nbsp;' . $discount_text .'<br>';
					}
					else
					{
						
						// for salemaker display
						$sale_discount_type = $this->contents[$products_id]['special_price']?'S':'';
						if ($this->contents[$products_id]['discount_id'] > 0) 
						{
							$sale_option=" sale_id=" . $this->contents[$products_id]['discount_id'] . " and ";
							$sDate=getServerDate();
							
							//this is not returning correct categories - it need to check the top category
							$cats=explode('_',(tep_get_product_path($prid)));
							foreach($cats as $key=>$value){
							$cats1.='or sale_categories_all like \'%,'.$value.',%\' ';
							}
							$sale_option=" sale_id=" . $this->contents[$products_id]['discount_id'] .' and ' ;
							$sDate=getServerDate();
							$sale_query = tep_db_query("select sale_specials_condition, sale_deduction_value, sale_deduction_type,sale_id,sale_discount_type, choice_text from " . TABLE_SALEMAKER_SALES . " where " . $sale_option . " ((sale_categories_all='' and sale_products_selected='') ".$cats1." or sale_products_selected like '%," . (int)$prid .",%') and sale_status = '1' and (sale_date_start <= '" . $sDate. "' or sale_date_start = '0000-00-00') and (sale_date_end >= '" . tep_db_input($sDate) . "' or sale_date_end = '0000-00-00') and (sale_pricerange_from <= '" . $product["products_price"] . "' or sale_pricerange_from = '0') and (sale_pricerange_to >= '" . $product["products_price"] . "' or sale_pricerange_to = '0')");
							
							if (tep_db_num_rows($sale_query)>0)
							{
								$sale=tep_db_fetch_array($sale_query);
								$products_price=tep_get_salemaker_price($this->contents[$products_id]['special_price'],$products_price,$sale);
								$sale_discount_type=$sale['sale_discount_type'];
								
								//if ($special_price && $sale['sale_specials_condition']==2) $original_price=$special_price;
								switch($sale['sale_deduction_type']){
									case 1:
										$discount_text=$sale["choice_text"] . " (" . number_format($sale["sale_deduction_value"],2). "%)";
										break;
									case 2:
										//$discount_text=$sale["choice_text"] . " (" . $currencies->format($original_price) . ' ' .NEW_PRICE.' '. $currencies->format($sale["sale_deduction_value"]) . ")";
										$discount_text=$sale["choice_text"];
										break;
									default:
										$discount_text=$sale["choice_text"] . " (" . $currencies->format($sale["sale_deduction_value"]). ")";
										break;
									
								}
								$discount_whole_text=TEXT_DISCOUNT_APPLIED . '&nbsp;' . $discount_text .'<br>' . TEXT_ORIGINAL_AMOUNT . '&nbsp;' . $currencies->format(tep_add_tax($original_price,$products_tax)*$this->contents[$products_id]['qty']) . '<br>' . TEXT_DISCOUNT . '&nbsp;' .$currencies->format(tep_add_tax($original_price-$products_price,$products_tax)*$this->contents[$products_id]['qty']) . '<br>';
							}
						}
					}
					
					$products_sku=$products["products_sku"];

					
					$products_array[] = array(
						'element_type'=>$this->contents[$products_id]['element_type'],
						'old_orders_id'=>$this->contents[$products_id]['old_orders_id'],
						'answer_type'=>$this->contents[$products_id]['answer_type'],
						'answer_value'=>$this->contents[$products_id]['answer_value'],
						'id' => $prid,
						'sh_id'=>$products_id,
						'section_id'=>$products['section_id'],
						'sessions'=>array(),
						'name' => $products['products_name'],
						'model' => $products['products_model'],
						//'master' => $products['master_quantity'],
						'products_season' => $products['products_season'],
						'products_date_available' => $products['products_date_available'],
						'image' => $products['products_image_1'],
						'price' => ($original_price),
						'quantity' => $this->contents[$products_id]['qty'],
						'weight' => $products['products_weight'],
						'final_price' => ($products_price),
						'tax_class_id' => $products['products_tax_class_id'],
						'sku'=>$products_sku,
						'is_printable' => $this->printable($prid),
						'category_name' => $products['categories_name'],
						'price_breaks'=>$products['products_price_break'],
						'product_type'=>$products['product_type'],
						'discount_id'=>$this->contents[$products_id]['discount_id'],
						'discount_text'=>$discount_text,
						'discount_whole_text'=>$discount_whole_text,
						'discount_type'=>$sale_discount_type
					);
				}
			
		}

	    // === Group tickets (G) first, then menu items (B), then by products_id ===
		usort($products_array, function($a, $b) {
			// if product_type differs, G comes before B
			if ($a['product_type'] !== $b['product_type']) {
				if ($a['product_type'] === 'G') return -1;
				if ($b['product_type'] === 'G') return  1;
				// fallback for any other types
				return strcmp($a['product_type'], $b['product_type']);
			}
			// same type: sort numerically by the 'id' field
			return ((int)$a['id']) <=> ((int)$b['id']);
		});

		return $products_array;
	}
	
	function get_product_price($products_id,$product,$salemaker_id=0){
	  global $FSESSION;
		$products_price=$product["products_price"];
		if ($product["products_price_break"]=="Y"){
			$breaks_query=tep_db_query("SELECT discount_per_item from " . TABLE_PRODUCTS_PRICE_BREAK . " where products_id='" . (int)$product["products_id"] . "' and quantity='" . (int)$this->contents[$products_id]["qty"] . "'");
			if (tep_db_num_rows($breaks_query)>0){
				$break_result=tep_db_fetch_array($breaks_query);
				$products_price-=$break_result["discount_per_item"];
				return $products_price;
			}
		}
		$query = tep_db_query("select g.customers_groups_discount from " . TABLE_CUSTOMERS_GROUPS . " g inner join  " . TABLE_CUSTOMERS  . " c on g.customers_groups_id = c.customers_groups_id and c.customers_id = '" . (int)$FSESSION->customer_id . "'");
		$query_result = tep_db_fetch_array($query);
		$customers_groups_discount = $query_result['customers_groups_discount'];
		$query = tep_db_query("select customers_discount from " . TABLE_CUSTOMERS . " where customers_id =  '" . (int)$FSESSION->customer_id . "'");
		$query_result = tep_db_fetch_array($query);
		$customer_discount = $query_result['customers_discount'];
		$customer_discount = $customer_discount + $customers_groups_discount;
		if ($customer_discount >= 0) {
		 $products_price = $products_price + $products_price * abs($customer_discount) / 100;
		} else {
		 $products_price = $products_price - $products_price * abs($customer_discount) / 100;
		}
		$this->contents[$products_id]['special_price']=false;
		if ($special_price = tep_get_products_special_price($products_id,$salemaker_id,$products_id)) {
			$this->contents[$products_id]['special_price']=$special_price;
			$products_price = $special_price;
		}
		return $products_price;
	}
    function show_total() {
      $this->calculate();
      return $this->total;
    }
	function is_free_checkout(){
  // calculate total amount
  $this->calculate();
  // if the total is zero and only event is added to cart
  if ($this->total<=0 ){
   return true;
  } else {
   return false;
  }
 }
    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(){
		$weight=$this->show_weight();
		$this->content_type=false;
		reset($this->contents);
		
		//while (list($products_id, ) = each($this->contents)) {
		foreach(array_keys($this->contents) as $products_id) 
		{	
			
			if ($this->content_type=='mixed') break;
			switch($this->contents[$products_id]['element_type']){
				case 'V':
					if ($this->content_type=='physical') $this->content_type='mixed';
					else $this->content_type ='virtual';
					break;
				default:
					if ($weight==0) $this->content_type='virtual';
					else if ($this->content_type && $this->content_type=='virtual') $this->content_type='mixed';
					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'];
      }
    }
	
	function check_for_season_tickets()
    {
    if (is_array($this->contents))
        {
        reset($this->contents);
        //while (list($products_id,) = each($this->contents))
		foreach ( array_keys($this->contents) as $products_id )
            {
            $gv_query = tep_db_query("select product_type from " . TABLE_PRODUCTS . " where products_id = '" . (int)$products_id . "'");
            $gv_result = tep_db_fetch_array($gv_query);
            if (($gv_result['product_type'] == "X"))
                {
                return true;
				
                }
            }
 
        return false;
        }
    }
    
 function check_for_vouchers()
    {
    if (is_array($this->contents))
        {
        reset($this->contents);
        //while (list($products_id,) = each($this->contents))
		foreach ( array_keys($this->contents) as $products_id )
            {
            $gv_query = tep_db_query("select products_sku from " . TABLE_PRODUCTS . " where products_id = '" . (int)$products_id . "'");
            $gv_result = tep_db_fetch_array($gv_query);
            if (($gv_result['products_sku'] == 6))
                {
                return true;
				
                }
            }
 
        return false;
        }
    }
    
	function get_check_id_list() 
	{
		$product_id_list = '';
		if (is_array($this->contents)) 
		{
			reset($this->contents);
			//while (list($products_id, ) = each($this->contents))
			foreach (array_keys($this->contents) as $products_id) 		
			{
				if ( $this->contents[$products_id]['element_type']=='V')
					$product_id_list .= ',V' . tep_get_service_prid($products_id);
				else
					$product_id_list .= ',P' . tep_get_prid($products_id);
			}
		}
		return substr($product_id_list, 1);
	}
// Dec 2015 extra function to get a value for printable. Starts at the product and runs up through the product path looking for a zero (no printing) as soon as that is found wil break out of function - this will allow individual sub categories to be prevented from printing.
// Used in get_products() to pass is_printable to order class
	
function printable($the_product_id)
	{
	$printable = 1; //default true
	// take the product id, find the cPath, explode it and then run a check to see if any cat has a print setting of zero
	$p_path_array = array();
	$p_path_array = explode('_', tep_get_product_path($the_product_id)); //n.b. tep_get_product path requires products_status=1
	$max = sizeof($p_path_array);
	if ($max > 0)
		{
		for ($i = 0; $i < $max; $i++)
			{
			$category_p_query = tep_db_query("select categories_is_printable from " . TABLE_CATEGORIES . " where categories_id = '" . $p_path_array[$i] . "' limit 1");
			if (tep_db_num_rows($category_p_query))
				{
				$category_p = tep_db_fetch_array($category_p_query);
				if ($category_p['categories_is_printable'] == 0)
					{
					$printable = 0;
					break;
					}
				}
			}
		}
	return $printable;
	}
}
		function checkout_compare_price($a, $b)
{
    return strnatcmp($a['final_price'], $b['final_price']);
}


function cart_has_only_food() {
    global $cart;
    $hasFood   = false;
    $hasTicket = false;

    foreach ($cart->contents as $pid => $info) {
        // fetch type once per product
        $r = tep_db_query(
            "SELECT product_type
               FROM " . TABLE_PRODUCTS . "
              WHERE products_id = '" . (int)$pid . "'"
        );
        $row = tep_db_fetch_array($r);
        if ($row['product_type'] === 'G') {
            $hasTicket = true;
        }
        if ($row['product_type'] === 'A') {
            $hasFood = true;
        }
        // short-circuit if we see both
        if ($hasTicket && $hasFood) {
            return false;
        }
    }
    // only-food if there's at least one food and no ticket
    return ($hasFood && ! $hasTicket);
}
?>