I know this is an old thread but i managed to make this work. The fix works on 1.6.x.
We have specific products that have special shipping costs applied to them (due to their weight and the extra money the carrier charges us for them).
We needed a way to keep the shipping if under X $, and add the additional shipping fees, but if the order is greater than X $, only the additional shipping fees will count as shipping. Because the first situation is default in prestashop, i found a way to override the second situation (because PS always disregarded the additional shipping fees if shipping is free).
In cart.php, where the Free Fee is set, go ahead and replace the whole chunk of code to:
// Free fees
$free_fees_price = 0;
if (isset($configuration['PS_SHIPPING_FREE_PRICE'])) {
$free_fees_price = Tools::convertPrice((float)$configuration['PS_SHIPPING_FREE_PRICE'], Currency::getCurrencyInstance((int)$this->id_currency))
;
}
$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);
foreach ($products as $product) { //added line
$shipping_cost = $shipping_cost + ($product['additional_shipping_cost'] * $product['cart_quantity']); //added line
} //added line
return $shipping_cost;
}
Scroll down, where you will find // Additional Shipping Cost per product, edit the whole chunk of code with:
// Additional Shipping Cost per product
foreach ($products as $product) {
if (!$product['is_virtual'] && $product['additional_shipping_cost']) {
if ($shipping_cost > 0){
$shipping_cost += $product['additional_shipping_cost'] * $product['cart_quantity'];
} else $shipping_cost = $product['additional_shipping_cost'] * $product['cart_quantity'];
}
}
Then go up the the function getCarrierCost, edit the last part of it (i pasted the whole function here for convinience):
public function getCarrierCost($id_carrier, $useTax = true, Country $default_country = null, $delivery_option = null)
{
if (is_null($delivery_option)) {
$delivery_option = $this->getDeliveryOption($default_country);
}
$total_shipping = 0;
$delivery_option_list = $this->getDeliveryOptionList();
foreach ($delivery_option as $id_address => $key) {
if (!isset($delivery_option_list[$id_address]) || !isset($delivery_option_list[$id_address][$key])) {
continue;
}
if (isset($delivery_option_list[$id_address][$key]['carrier_list'][$id_carrier])) {
if ($useTax) {
$total_shipping += $delivery_option_list[$id_address][$key]['carrier_list'][$id_carrier]['price_with_tax'];
} else {
$total_shipping += $delivery_option_list[$id_address][$key]['carrier_list'][$id_carrier]['price_without_tax'];
}
}
}
// loop products in the cart to find the addition cost of each
foreach ($products as $product) {
// find the additional shopping price of products
if (!$product['is_virtual'] && $product['additional_shipping_cost']) {
// if shipping exists, then add additional fees to it (reduntant)
if ($total_shipping > 0){
$shipping_cost += $product['additional_shipping_cost'] * $product['cart_quantity'];
// if shipping is free, just add the additional shipping fees as shipping price
} else $shipping_cost = $product['additional_shipping_cost'] * $product['cart_quantity'];
}
}
// increment the shipping total
$total_shipping += $shipping_cost;
return $total_shipping;
}
I've tested the situation and it works regardless of the combinations of products you have in the cart. Free shipping, no free shipping, one or multiple products with additional shipping cost.
EDIT: Please note that the block of code below can also be inputed into the carrier.php to override the free shipping stuff PS does.
$shipping_cost + self::$price_by_price[$cache_key];
$price_by_price = Hook::exec('actionDeliveryPriceByPrice', array('id_carrier' => $id_carrier, 'order_total' => $order_total, 'id_zone' => $id_zone));
if (is_numeric($price_by_price)) {
self::$price_by_price[$cache_key] = $price_by_price;
}
//from here
foreach ($products as $product) {
$shipping_cost = $shipping_cost + ($product['additional_shipping_cost'] * $product['cart_quantity']);
}
$shipTax = $shipping_cost + self::$price_by_price[$cache_key];
return $shipTax;