Jump to content

Shipping of virtual products, Need Help! [SOLVED]


Recommended Posts

Hello,im a very beginner on prestashop,

 

I have a shop in prestashop 1.6,and i want to sell virtual products and physics one´s. The thing is that i choose  to offer free shippment depending on the total price. the problem start when someone purchase a virtual product and a physic one in the same cart.With that i mean that it takes in count the price of virtual product to calculate the shippment of the physics one :(

 

I dont have so much skill in programming but i thing i can solve it touching the carrier.php in classes and modify this function to have in count the table  ps_product is_virtual=1 and dont take that price i suppose.

public function getDeliveryPriceByPrice($order_total, $id_zone, $id_currency = null)
	{
		$cache_key = $this->id.'_'.$order_total.'_'.$id_zone.'_'.$id_currency;
		if (!isset(self::$price_by_price[$cache_key]))
		{
			if (!empty($id_currency))
				$order_total = Tools::convertPrice($order_total, $id_currency, false);

			$sql = 'SELECT d.`price`
					FROM `'._DB_PREFIX_.'delivery` d
					LEFT JOIN `'._DB_PREFIX_.'range_price` r ON d.`id_range_price` = r.`id_range_price`
					WHERE d.`id_zone` = '.(int)$id_zone.'
						AND '.(float)$order_total.' >= r.`delimiter1`
						AND '.(float)$order_total.' < r.`delimiter2`
						AND d.`id_carrier` = '.(int)$this->id.'
						'.Carrier::sqlDeliveryRangeShop('range_price').'
					ORDER BY r.`delimiter1` ASC';
			$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow($sql);
			if (!isset($result['price']))
				self::$price_by_price[$cache_key] = $this->getMaxDeliveryPriceByPrice($id_zone);
			else
				self::$price_by_price[$cache_key] = $result['price'];
		}
		return self::$price_by_price[$cache_key];
	}

I used to know some basic programming in C++ but here im lost. Someone can give me a hand? 

Thanks for all and sorry for my bad english.

Edited by Leid (see edit history)
Link to comment
Share on other sites

You might consider this approach instead.

 

The configuration setting for "free shipping" is called PS_SHIPPING_FREE_PRICE.  Let's say you configure this for $50, then Prestashop will compare the order total to the free shipping price, and if it exceeds then shipping will be zero.

 

So I search Prestashop code looking for PS_SHIPPING_FREE_PRICE, and I get three hits

1) AdminShippingController: This is the back office where you configure the value, so we can ignore this hit

 

2) Cart: This is a core class and it has a function called "getPackageShippingCost".  This is where the comparison is made, and zero is returned if the price exceeds the configured value. ($shipping_cost is initialized as zero)

$orderTotalwithDiscounts = $this->getOrderTotal(true, Cart::BOTH_WITHOUT_SHIPPING, null, null, false);
if ($orderTotalwithDiscounts >= (float)($free_fees_price) && (float)($free_fees_price) > 0)
{
    Cache::store($cache_id, $shipping_cost);
    return $shipping_cost;
}

So I would suggest changing this function so you would only consider physical products and then perform the comparison.  I believe you could use the following to get the cost of physical products

$physical_cost = $this->getOrderTotal(true, Cart::ONLY_PHYSICAL_PRODUCTS_WITHOUT_SHIPPING, null, null, false);

3) blockcart: This is the block cart module and is usually responsible for showing the cart information.  This also performs a comparison which is likely controlling the display of shipping price in the cart.  So you would have to make a similar change here.

$total_free_shipping = 0;
if ($free_shipping = Tools::convertPrice(floatval(Configuration::get('PS_SHIPPING_FREE_PRICE')), $currency))
{
    $total_free_shipping =  floatval($free_shipping - ($params['cart']->getOrderTotal(true, Cart::ONLY_PRODUCTS) + $params['cart']->getOrderTotal(true, Cart::ONLY_DISCOUNTS)));
    $discounts = $params['cart']->getCartRules(CartRule::FILTER_ACTION_SHIPPING);
    if ($total_free_shipping < 0)
        $total_free_shipping = 0;
    if (is_array($discounts) && count($discounts))
        $total_free_shipping = 0;
}

  • Like 1
Link to comment
Share on other sites

Thank you so much for the reply bellini13, but i see that code and that sure will work if i use only free shipping at some point of  total price,but i have configured 2 shippement option of the same transport(sorry for no mention it before :( ) to fullfill the range of prices(from 0€ to 50€  1 of them and the other from 50€ to 99999999) and the diferrent shipping cost added to the different zones.(Example: for spain -> 6€ but for isles --> 12 )

It there a way to implement that? i think that it´s i bit more difficult... Sorry to bother you, and thank you for the effort

Link to comment
Share on other sites

Hello again i did this change on cart

$orderTotalwithDiscounts = $this->getOrderTotal(true, Cart::BOTH_WITHOUT_SHIPPING, null, null, false);
if ($orderTotalwithDiscounts >= (float)($free_fees_price) && (float)($free_fees_price) > 0)
{
    Cache::store($cache_id, $shipping_cost);
    return $shipping_cost;
}

i changed only Cart::BOTH_WITHOUT_SHIPPING to ONLY_PHYSICAL_PRODUCTS_WITHOUT_SHIPPING and it works :D

Aparently its now correct on all,i dunno if it does more comparison later but with this change it only take physical product.

 

Thank You so much for the help !

Link to comment
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
×
×
  • Create New...