Jump to content

wholesale price ?


Recommended Posts

Hi ,
If I want to add a products, i can see the wholesale price option, but how can i use it ?
I Know about the Groups but i don't want show two prices , one for user, and one for wholesale costumers, but not depends on the % , such as gropu but two different prices,
can you help me to find this option ?

Link to comment
Share on other sites

There is no option in the Back Office to do this. You will have to modify code. Here is a solution I came up with. Create a customer group called "Wholesalers" with a reduction amount of 0. Make a backup of the getPriceStatic function classes/Product.php on line 1229 in case anything goes wrong, then change it to:

public static function getPriceStatic($id_product, $usetax = true, $id_product_attribute = NULL, $decimals = 6, $divisor = NULL, $only_reduc = false, $usereduc = true, $quantity = 1, $forceAssociatedTax = false)
{
   global $cookie;

   // Get id_customer if exists
   $id_customer = ((isset($cookie) AND get_class($cookie) == 'Cookie' AND isset($cookie->id_customer) AND $cookie->id_customer)
       ? intval($cookie->id_customer) : null);

   $customer = new Customer($id_customer);
   $wholesaler = $customer->isMemberOfGroup(2);

   if (!Validate::isBool($usetax) OR !Validate::isUnsignedId($id_product))
       die(Tools::displayError());

   // Caching system
   $cacheId = $id_product.'-'.($usetax?'1':'0').'-'.$id_product_attribute.'-'.$decimals.'-'.$divisor.'-'.($only_reduc?'1':'0').'-'.($usereduc?'1':'0').'-'.$quantity.'-'.($wholesaler?'1':'0');
   if (isset(self::$_prices[$cacheId]))
       return self::$_prices[$cacheId];

   // Getting price
   $result = Db::getInstance()->getRow('
   SELECT p.`price`, p.`wholesale_price`, p.`reduction_price`, p.`reduction_percent`, p.`reduction_from`, p.`reduction_to`, p.`id_tax`, t.`rate`, 
   '.($id_product_attribute ? 'pa.`price`' : 'IFNULL((SELECT ' . ($wholesaler ? 'pa.wholesale_price' : 'pa.price') . ' FROM `'._DB_PREFIX_.'product_attribute` pa WHERE id_product = '.intval($id_product).' AND default_on = 1), 0)').' AS attribute_price
   FROM `'._DB_PREFIX_.'product` p
   '.($id_product_attribute ? 'LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa ON pa.`id_product_attribute` = '.intval($id_product_attribute) : '').'
   LEFT JOIN `'._DB_PREFIX_.'tax` AS t ON t.`id_tax` = p.`id_tax`
   WHERE p.`id_product` = '.intval($id_product));
   $price = $wholesaler ? $result['wholesale_price'] : $result['price'];

   // Exclude tax
   $tax = floatval(Tax::getApplicableTax(intval($result['id_tax']), floatval($result['rate'])));
   if ($forceAssociatedTax)
       $tax = floatval($result['rate']);
   if (Tax::excludeTaxeOption() OR !$tax)
       $usetax = false;
   if ($usetax)
       $price *= (1 + ($tax / 100));

   // Attribute price
   $attribute_price = $usetax ? $result['attribute_price'] : ($result['attribute_price'] / (1 + (($tax ? $tax : $result['rate']) / 100)));
   if (isset($result['attribute_price']))
       $price += $attribute_price;
   if (!$wholesaler)
       $reduc = self::getReductionValue($result['reduction_price'], $result['reduction_percent'], $result['reduction_from'], $result['reduction_to'],
           $price, $usetax, floatval($result['rate']));

   // Only reduction
   if ($only_reduc)
       return $reduc;

   // Reduction
   if ($usereduc)
       $price -= $reduc;

   // Quantity discount
   if (!$wholesaler AND $quantity > 1 AND ($qtyD = QuantityDiscount::getDiscountFromQuantity($id_product, $quantity)))
       $price -= QuantityDiscount::getValue($price, $qtyD->id_discount_type, $qtyD->value);

   // Group reduction
   if ($id_customer)
       $price *= ((100 - Group::getReduction($id_customer))/100);

   self::$_prices[$cacheId] = ($divisor AND $divisor != 'NULL') ? number_format($price/$divisor, $decimals, '.', '') : number_format($price, $decimals, '.', '');

   return self::$_prices[$cacheId];
}



This code checks whether the currently logged in customer is in the "Wholesaler" customer group (change the ID in isMemberOfGroup(2) to the ID of the "Wholesaler" group). If the customer is in that group, the function will get the wholesale price entered on the product page instead of the retail price and then add tax to it. If needed, it then adds on the attribute wholesale price. Note that this function will ignore price reductions and quantity discounts, but will still apply the group reduction. Let me know if this is what you want and whether you want any changes.

Link to comment
Share on other sites

Hi,
Grate option
this is excactly what I wanted, I have to thank you for the support.
I am very gratefull to find such a good members which help other user whiouth any charge.

I need also deactive the normal user prices, and get the call for price in place of the normall price.
Is this possible?


I mean I donot want to show any price online and just show price for wholesale customers.

bye

Link to comment
Share on other sites

In that case, change the getPriceStatic function to:

public static function getPriceStatic($id_product, $usetax = true, $id_product_attribute = NULL, $decimals = 6, $divisor = NULL, $only_reduc = false, $usereduc = true, $quantity = 1, $forceAssociatedTax = false)
{
   global $cookie;

   // Get id_customer if exists
   $id_customer = ((isset($cookie) AND get_class($cookie) == 'Cookie' AND isset($cookie->id_customer) AND $cookie->id_customer)
       ? intval($cookie->id_customer) : null);

   $customer = new Customer($id_customer);
   $wholesaler = $customer->isMemberOfGroup(2);

   if (!$wholesaler)
       return -1;

   if (!Validate::isBool($usetax) OR !Validate::isUnsignedId($id_product))
       die(Tools::displayError());

   // Caching system
   $cacheId = $id_product.'-'.($usetax?'1':'0').'-'.$id_product_attribute.'-'.$decimals.'-'.$divisor.'-'.($only_reduc?'1':'0').'-'.($usereduc?'1':'0').'-'.$quantity;
   if (isset(self::$_prices[$cacheId]))
       return self::$_prices[$cacheId];

   // Getting price
   $result = Db::getInstance()->getRow('
   SELECT p.`wholesale_price`, p.`reduction_price`, p.`reduction_percent`, p.`reduction_from`, p.`reduction_to`, p.`id_tax`, t.`rate`, 
   '.($id_product_attribute ? 'pa.`price`' : 'IFNULL((SELECT ' . ($wholesaler ? 'pa.wholesale_price' : 'pa.price') . ' FROM `'._DB_PREFIX_.'product_attribute` pa WHERE id_product = '.intval($id_product).' AND default_on = 1), 0)').' AS attribute_price
   FROM `'._DB_PREFIX_.'product` p
   '.($id_product_attribute ? 'LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa ON pa.`id_product_attribute` = '.intval($id_product_attribute) : '').'
   LEFT JOIN `'._DB_PREFIX_.'tax` AS t ON t.`id_tax` = p.`id_tax`
   WHERE p.`id_product` = '.intval($id_product));
   $price = $result['wholesale_price'];

   // Exclude tax
   $tax = floatval(Tax::getApplicableTax(intval($result['id_tax']), floatval($result['rate'])));
   if ($forceAssociatedTax)
       $tax = floatval($result['rate']);
   if (Tax::excludeTaxeOption() OR !$tax)
       $usetax = false;
   if ($usetax)
       $price *= (1 + ($tax / 100));

   // Attribute price
   $attribute_price = $usetax ? $result['attribute_price'] : ($result['attribute_price'] / (1 + (($tax ? $tax : $result['rate']) / 100)));
   if (isset($result['attribute_price']))
       $price += $attribute_price;
   if (!$wholesaler)
       $reduc = self::getReductionValue($result['reduction_price'], $result['reduction_percent'], $result['reduction_from'], $result['reduction_to'],
           $price, $usetax, floatval($result['rate']));

   // Only reduction
   if ($only_reduc)
       return $reduc;

   // Reduction
   if ($usereduc)
       $price -= $reduc;

   // Quantity discount
   if (!$wholesaler AND $quantity > 1 AND ($qtyD = QuantityDiscount::getDiscountFromQuantity($id_product, $quantity)))
       $price -= QuantityDiscount::getValue($price, $qtyD->id_discount_type, $qtyD->value);

   // Group reduction
   if ($id_customer)
       $price *= ((100 - Group::getReduction($id_customer))/100);

   self::$_prices[$cacheId] = ($divisor AND $divisor != 'NULL') ? number_format($price/$divisor, $decimals, '.', '') : number_format($price, $decimals, '.', '');

   return self::$_prices[$cacheId];
}



and change the convertPrice function in classes/Product.php to:

static function convertPrice($params, &$smarty)
{
   if ($params['price'] == -1)
       return 'Call for price';
   else
       return Tools::displayPrice($params['price'], $smarty->ps_currency);
}


This code will make it so customers who are not logged in or who are not wholesalers will see "Call for price" and wholesalers will see the wholesale price.

Link to comment
Share on other sites

I just test it on my installation and it is working fine, though I did notice that I missed a couple of function that need to be updated:

static function convertPriceWithCurrency($params, &$smarty)
{
   if (!isset($params['convert']))
       $params['convert'] = true;
   if ($params['price'] == -1)
       return 'Call for price';
   else
       return Tools::displayPrice($params['price'], $params['currency'], false, $params['convert']);
}

static function displayWtPrice($params, &$smarty)
{
   if ($params['p'] == -1)
       return 'Call for price';
   else
       return Tools::displayPrice($params['p'], $smarty->ps_currency);
}

static function displayWtPriceWithCurrency($params, &$smarty)
{
   if ($params['price'] == -1)
       return 'Call for price';
   else        
       return Tools::displayPrice($params['price'], $params['currency'], false, $params['convert']);
}



Check your PHP error_log or modify config/config.inc.php and set 'display_errors' to 'on' to see what it is causing the error in the right column.

Link to comment
Share on other sites

This is the Error±

Fatal error: Smarty error: [in /customers/parsicomputer.nl/parsicomputer.nl/httpd.www/modules/blockcart/blockcart.tpl line 46]: [plugin] function 'displayWtPrice' is not implemented (core.load_plugins.php, line 36) in /customers/parsicomputer.nl/parsicomputer.nl/httpd.www/tools/smarty/Smarty.class.php on line 1095


Where should i put the last codes that you mentioned ? which line ?

Link to comment
Share on other sites

  • 1 month later...

Great job!
Rocky, I have one problem with this code. After when I made changes, everything works fine. But I put a new goods on my shop, and the price is showed (only for new goods). Do You have any solution for this? Could You help please?
Sorry for my english :)

Link to comment
Share on other sites

  • 1 month later...

1, After I made changes, products with "combinations" shows prices on FO. It´s no problem, because I can show some products price, for a customer enticement.
The problem:
2, You can change the product attributes, and put into a basket, but in basket you will find always a "default product". For other than default product shows: Notify me when product is available. It´s happening - ONLY - when the customer is logged in. If customer is unlogged then it´s working well.

My question is: is it possible to solve somehow the second problem - problem with attributes?

Link to comment
Share on other sites

  • 7 months later...
  • 3 months later...
  • 4 months later...
  • 3 months later...

Hi, I tried to implement the above code (I want a price for normal users and a reduced price for wholesalers) and found that it didn't work. I compared the code above to that in my version of Prestashop and found it to be very different - the code above is from 2009!

 

I implemented the changes manually and integrated it with our version 1.3.1.1 and got it to work. Here is a copy of 2 of the functions that I had to change in classes/product.php

public static function getPriceStatic($id_product, $usetax = true, $id_product_attribute = NULL, $decimals = 6, $divisor = NULL, $only_reduc = false, $usereduc = true, $quantity = 1, $forceAssociatedTax = false, $id_customer = NULL, $id_cart = NULL, $id_address_delivery = NULL)
{
	global $cookie, $cart;

	// Get id_customer if exists
	if (!$id_customer)
		$id_customer = ((Validate::isCookie($cookie) AND isset($cookie->id_customer) AND $cookie->id_customer) ? intval($cookie->id_customer) : null);

	 $customer = new Customer($id_customer);
	 $wholesaler = $customer->isMemberOfGroup(2);


	if (!is_object($cart))
	{
		/*
		* When a user (e.g., guest, customer, Google...) is on PrestaShop, he has already its cart as the global (see /init.php)
		* When a non-user calls directly this method (e.g., payment module...) is on PrestaShop, he does not have already it BUT knows the cart ID
		*/
		if (!$id_cart AND !Validate::isCookie($cookie))
			die(Tools::displayError());
		$cart = $id_cart ? new Cart(intval($id_cart)) : new Cart(intval($cookie->id_cart));
	}

	if (Validate::isLoadedObject($cart))
		$currency = new Currency(intval($cart->id_currency));
	elseif (isset($cookie->id_currency) AND intval($cookie->id_currency))
		$currency = new Currency(intval($cookie->id_currency));
	else
		$currency = new Currency(intval(Configuration::get('PS_CURRENCY_DEFAULT')));

	if (!$id_address_delivery)
		$id_address_delivery = $cart->id_address_delivery;

	if (!Validate::isBool($usetax) OR !Validate::isUnsignedId($id_product))
		die(Tools::displayError());

	if (Tax::excludeTaxeOption())
		$usetax = false;

	// Caching system
	$cacheId = $id_product.'-'.($usetax?'1':'0').'-'.$id_product_attribute.'-'.$decimals.'-'.$divisor.'-'.($only_reduc?'1':'0').'-'.($usereduc?'1':'0').'-'.$quantity;
	if (isset(self::$_prices[$cacheId]))
		return self::$_prices[$cacheId];

	// Getting price
	$result = Db::getInstance()->getRow('
	SELECT p.`price`, p.`wholesale_price`, p.`reduction_price`, p.`reduction_percent`, p.`reduction_from`, p.`reduction_to`, p.`id_tax`, t.`rate`, 
	'.($id_product_attribute ? 'pa.`price`' : 'IFNULL((SELECT  ' . ($wholesaler ? 'pa.wholesale_price' : 'pa.price') . '  FROM `'._DB_PREFIX_.'product_attribute` pa WHERE id_product = '.intval($id_product).' AND default_on = 1), 0)').' AS attribute_price
	FROM `'._DB_PREFIX_.'product` p
	'.($id_product_attribute ? 'LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa ON pa.`id_product_attribute` = '.intval($id_product_attribute) : '').'
	LEFT JOIN `'._DB_PREFIX_.'tax` AS t ON t.`id_tax` = p.`id_tax`
	WHERE p.`id_product` = '.intval($id_product));
	$price = $wholesaler ? $result['wholesale_price'] : $result['price'];
	$price = Tools::convertPrice(floatval($price), $currency);

	// Exclude tax
	$tax = floatval(Tax::getApplicableTax(intval($result['id_tax']), floatval($result['rate']), ($id_address_delivery ? intval($id_address_delivery) : NULL)));
	if ($forceAssociatedTax)
		$tax = floatval($result['rate']);
	if (!$tax)
		$usetax = false;
	if ($usetax)
		$price = $price * (1 + ($tax / 100));

	// Attribute price
	$attribute_price = Tools::convertPrice((array_key_exists('attribute_price', $result) ? floatval($result['attribute_price']) : 0), $currency);
	$attribute_price = $usetax ? Tools::ps_round($attribute_price, 2) : ($attribute_price / (1 + (($tax ? $tax : $result['rate']) / 100)));
	$price += $attribute_price;
	$reduc = Tools::convertPrice($result['reduction_price'], $currency);
	if (($only_reduc OR $usereduc) && !$wholesaler)
		$reduc = self::getReductionValue($reduc, $result['reduction_percent'], $result['reduction_from'], $result['reduction_to'], $price, $usetax, floatval($result['rate']));

	// Only reduction
	if ($only_reduc)
		return $reduc;

	// Reduction
	if ($usereduc)
		$price -= $reduc;

	if (intval($id_cart))
	// Quantity discount
	{
		$totalQuantity = intval(Db::getInstance()->getValue('
			SELECT SUM(`quantity`)
			FROM `'._DB_PREFIX_.'cart_product`
			WHERE `id_product` = '.intval($id_product).' AND `id_cart` = '.intval($id_cart))
		) + intval($quantity);
	}
	if (!$wholesaler AND $quantity > 1 AND ($qtyD = QuantityDiscount::getDiscountFromQuantity($id_product, $quantity)))
	{
		$discount_qty_price = QuantityDiscount::getValue($price, $qtyD->id_discount_type, $qtyD->value, $usetax, floatval($result['rate']));
		$price -= $discount_qty_price;
	}
	// Group reduction
	if (!$wholesaler)
	$price *= ((100 - Group::getReduction(((isset($id_customer) AND $id_customer) ? $id_customer : 0))) / 100);
	$price = ($divisor AND $divisor != NULL) ? $price/$divisor : $price;
	if ($quantity <= 1 OR !$qtyD)
		$price = Tools::ps_round($price, $decimals);
	self::$_prices[$cacheId] = $price;
	return self::$_prices[$cacheId];
}

 

and the second...

public function getPriceWithoutReduct($notax = false)
{
	global $cookie;

	$id_customer = ((Validate::isCookie($cookie) AND isset($cookie->id_customer) AND $cookie->id_customer) ? intval($cookie->id_customer) : null);

	 $customer = new Customer($id_customer);
	 $wholesaler = $customer->isMemberOfGroup(2);


	$res = Db::getInstance()->getRow('
		SELECT p.`price`,p.`wholesale_price`, t.`rate`, t.`id_tax`
		FROM `'._DB_PREFIX_.$this->table.'` p
		LEFT JOIN `'._DB_PREFIX_.'tax`t ON (p.`id_tax` = t.`id_tax`)
		WHERE p.`id_product` = '.intval($this->id));
	if (!$res)
		return false;
	$tax = floatval(Tax::getApplicableTax(intval($res['id_tax']), floatval($res['rate'])));
	$price = $wholesaler ? $res['wholesale_price'] : $res['price'];

	if (!Tax::excludeTaxeOption())
		return (Tools::convertPrice($price) * (1 + $tax / 100));
	return (Tools::convertPrice($price));
}

Link to comment
Share on other sites

  • 2 weeks later...

Later on I noticed that if a product has attributes which affect the price, regardless of whether you are a wholesaler or not, it added on the same price. Some more tweaks were needed to have different price modifiers for wholesalers and normal users...

 

In classes/product.php around line 1839 we need to add in wholesale price to the query

 

public function getAttributesGroups($id_lang)
{
return Db::getInstance()->ExecuteS('
SELECT ag.`id_attribute_group`, ag.`is_color_group`, agl.`name` AS group_name, agl.`public_name` AS public_group_name, a.`id_attribute`, al.`name` AS attribute_name,
a.`color` AS attribute_color, pa.`id_product_attribute`, pa.`quantity`, pa.`price`, pa.`wholesale_price`, pa.`ecotax`, pa.`weight`, pa.`default_on`, pa.`reference`
FROM `'._DB_PREFIX_.'product_attribute` pa
LEFT JOIN `'._DB_PREFIX_.'product_attribute_combination` pac ON pac.`id_product_attribute` = pa.`id_product_attribute`
LEFT JOIN `'._DB_PREFIX_.'attribute` a ON a.`id_attribute` = pac.`id_attribute`
LEFT JOIN `'._DB_PREFIX_.'attribute_group` ag ON ag.`id_attribute_group` = a.`id_attribute_group`
LEFT JOIN `'._DB_PREFIX_.'attribute_lang` al ON a.`id_attribute` = al.`id_attribute`
LEFT JOIN `'._DB_PREFIX_.'attribute_group_lang` agl ON ag.`id_attribute_group` = agl.`id_attribute_group`
WHERE pa.`id_product` = '.intval($this->id).'
AND al.`id_lang` = '.intval($id_lang).'
AND agl.`id_lang` = '.intval($id_lang).'
ORDER BY al.`name`');
}

 

Also, we need to change product.php in the root folder (not in the classes folder) around line 265 replace...

$combinations[$row['id_product_attribute']]['price'] = floatval($row['price']);

 

with...

global $cookie;
$id_customer = ((Validate::isCookie($cookie) AND isset($cookie->id_customer) AND $cookie->id_customer) ? intval($cookie->id_customer) : null);
$customer = new Customer($id_customer);
$wholesaler = $customer->isMemberOfGroup(2);
if(!$wholesaler)
$combinations[$row['id_product_attribute']]['price'] = floatval($row['price']);
else
$combinations[$row['id_product_attribute']]['price'] = floatval($row['wholesale_price']);

 

Not that in the product attribute page in the admin section, we don't use price modifiers, instead we must remove the wholesale price from the product information tab, and enter the full price into the attribute wholesale price field (if that makes sense)

Link to comment
Share on other sites

  • 3 weeks later...

I opened another tread but no reply, so seen that you are Final Prices EXPERTS ... has anyone a solution to this problem ?

 

I have a product with real cost of 199,00 Euro.

I make a discount of 10% and i get 179,10 Euro.

 

I would like to have 179,00 Euro, both on the product page, both when you go into the basket, both when you pay it.

 

I do calculations and i found that PS works with 4 decimals on % calculation ...

But the same, isn' so good to have 179,00 Euro with % discount of 10,0019% (example) on your product page.

Someway to force the prices or the rounding ??

Link to comment
Share on other sites

  • 1 year later...
×
×
  • Create New...