Jump to content

Shipping cost when products are in multiple warehouses


eldermaster

Recommended Posts

Hello ppl,
 
I have a real problem for that i spent a lot of time in order to find a solution.
In the end I got inside the Archive Board some info very useful, provided by bbgun91, but after i played 2 days with the proposed solution, I still have some issues.
 
And i kind request if is someone who can help me.
 
I explain the situation:
 
  • Avanced warehouse enabled.
  • Products in different warehouses. 
Issue:
If a cart containing two or more products from two diferrent warehouses the shipping costs are counted two times. 
f course Prestashop bind the carrier/shipping  with the warehouse - is logic and is normal
If a buyer get some products from the same warehouse it it will apply the shipping cost that is configured for that one. - Is correct and is logic.
If a buyer get some products from 2 warehouses that has different addresses it it will apply the shipping costs that are configured for that warehouses.  Is correct and is logic. More than that will split the order. Is ok also.
 
What is not logic and is not correct, it is when it occur the 3rd case when the buyer get products from the warehouses that share same address (same building). While the splitting the order is correct, the carrier cost should be for this case flat, for that location. Should get the carrier cost from 1 single warehouse, even are 3 or more in the building. Is the same building.....same address. The shipper will move only few steps to get the products :) . Is not right to charge the client.
Unfortunately Prestashop will add all the time the carrier costs that were binded for the warehouse location in the cart, and will not look on the real address of the warehouses.
 
Solution proposed by bbgun91 that suit my case
Works but still need to be improved
 
The code is in the Class Cart.php in the function getDeliveryOptionList().
Overide it.
 
Find:
$best_price_carrier[$id_carrier]['price_with_tax'] += $carriers_price[$id_address][$id_package][$id_carrier]['with_tax'];
$best_price_carrier[$id_carrier]['price_without_tax'] += $carriers_price[$id_address][$id_package][$id_carrier]['without_tax'];
and change the "+=" by "=" to remove the incrementation, like this:
$best_price_carrier[$id_carrier]['price_with_tax'] = $carriers_price[$id_address][$id_package][$id_carrier]['with_tax']; // count only 1 shipping fee whatever the number of packages.
$best_price_carrier[$id_carrier]['price_without_tax'] = $carriers_price[$id_address][$id_package][$id_carrier]['without_tax'];
Do the same for the 2 following pieces of code a few lines under by changing "+=" into "=" :
 
$best_grade_carrier[$id_carrier]['price_with_tax'] += $carriers_price[$id_address][$id_package][$id_carrier]['with_tax'];
$best_grade_carrier[$id_carrier]['price_without_tax'] += $carriers_price[$id_address][$id_package][$id_carrier]['without_tax'];
and for
$price_with_tax += $carriers_price[$id_address][$id_package][$id_carrier]['with_tax'];
$price_without_tax += $carriers_price[$id_address][$id_package][$id_carrier]['without_tax'];

Override also  getCarrierCost() with same modifications

 
Modify now the class PaymentModule.
Look for the following code:
foreach ($package_list as $id_address => $packageByAddress) { 
    foreach ($packageByAddress as $id_package => $package) {

and insert, just outside the first loop, a flag that we will create to detect in which package we are.

$packageCount = 1;

Inside the second loop, look for the $order->total_shipping_tax_excl declaration and add a condition like this:

$order->total_shipping_tax_excl = ($packageCount === 1 ? (float)$this->context->cart->getPackageShippingCost((int)$id_carrier, false, null, $order->product_list) : 0.00);
So if it's not the 1st package, then the total_shipping_tax_excl is 0 (float).
Do the same for $order->total_shipping_tax_incl.
 
At the end of the second loop, don't forget to increment our new flag, so we know that we are on the next package.
$packageCount++;
The problem with the above code is that  the TOTAL, inside the order details and also inside the invoice, even the shipping is 0 for one of the orders, still show sum of the product + shipping price.
It should show only the products price + discounts + wraping_price.
 
What i tried is to add a condition
$order->total_paid_tax_excl = ($packageCount === 1 ? (float)Tools::ps_round((float)$this->context->cart->getOrderTotal(false, Cart::BOTH, $order->product_list, $id_carrier), _PS_PRICE_COMPUTE_PRECISION_) : (float)Tools::ps_round((float)$this->context->cart->getOrderTotal(true, Cart::ONLY_PRODUCTS, $order->product_list, $id_carrier), _PS_PRICE_COMPUTE_PRECISION_));
$order->total_paid_tax_incl = ($packageCount === 1 ? (float)Tools::ps_round((float)$this->context->cart->getOrderTotal(true, Cart::BOTH, $order->product_list, $id_carrier), _PS_PRICE_COMPUTE_PRECISION_) : (float)Tools::ps_round((float)$this->context->cart->getOrderTotal(true, Cart::ONLY_PRODUCTS, $order->product_list, $id_carrier), _PS_PRICE_COMPUTE_PRECISION_));
But in this case, even the shipping is eliminated, the discounts are not counted and again I have a problem.
How can I have the TOTAL for, the all other packages except the 1st on as SUM of Products + Discounts + WrapingPrice?
 
Anyone can help me?
 
Initial forum post
 
Thank you,
Edited by eldermaster (see edit history)
  • Thanks 1
Link to comment
Share on other sites

Issue solved....by myself .. one second time  :wub:

the condition is OK but need to be modified to use Cart::BOTH_WITHOUT_SHIPPING so will be

$order->total_paid_tax_excl = ($packageCount === 1 ? (float)Tools::ps_round((float)$this->context->cart->getOrderTotal(false, Cart::BOTH, $order->product_list, $id_carrier), _PS_PRICE_COMPUTE_PRECISION_) : (float)Tools::ps_round((float)$this->context->cart->getOrderTotal(true, Cart::BOTH_WITHOUT_SHIPPING, $order->product_list, $id_carrier), _PS_PRICE_COMPUTE_PRECISION_));

All test finished!

Solution can be implemented^^

Edited by eldermaster (see edit history)
  • Thanks 2
Link to comment
Share on other sites

  • 2 years later...
On 1/8/2017 at 7:09 PM, eldermaster said:

Issue solved....by myself .. one second time  :wub:

the condition is OK but need to be modified to use Cart::BOTH_WITHOUT_SHIPPING so will be


$order->total_paid_tax_excl = ($packageCount === 1 ? (float)Tools::ps_round((float)$this->context->cart->getOrderTotal(false, Cart::BOTH, $order->product_list, $id_carrier), _PS_PRICE_COMPUTE_PRECISION_) : (float)Tools::ps_round((float)$this->context->cart->getOrderTotal(true, Cart::BOTH_WITHOUT_SHIPPING, $order->product_list, $id_carrier), _PS_PRICE_COMPUTE_PRECISION_));

All test finished!

Solution can be implemented^^

Hi, thank you eldermaster, this has been very usefull for me! 

I still have a problem, for example, when I have free shipping for orders over 50€, and the customer buys 3 items, two from warehouse A (65€ amount), and 1 for the other warehouse (30€ amount), one carrier cost is charged to the client, and that's a problem. 

 

How can I solve this issue?

 

Thanks! 

Link to comment
Share on other sites

  • 1 year later...
On 7/1/2019 at 5:55 PM, Nemertes said:

Hi, thank you eldermaster, this has been very usefull for me! 

I still have a problem, for example, when I have free shipping for orders over 50€, and the customer buys 3 items, two from warehouse A (65€ amount), and 1 for the other warehouse (30€ amount), one carrier cost is charged to the client, and that's a problem. 

 

How can I solve this issue?

 

Thanks! 

I have the same problem. I have products in China warehouse nad Poland warehouse, but in checkout it shows only the second one, not both.

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...