I need Prestashop to calculate shipping price depend on items quantity in cart.
If there is more than one item in cart, i want the shipping price to be 50% of sum of all shipping costs.
I modyfied the cart module, but when i proceed to order page, the shipping cost is still full amount.
My code in blockcart:
if($nbTotalProducts>1) {
$shipping_cost_float = $shipping_cost_float/2;
$shipping_cost = $shipping_cost/2;
}
How can i store new shipping cost for all modules/controllers?
I think, i found the solution.
I have modified the cart class (classes/cart.php) - getPackageShippingCost function.
I add this code before the shipping cost is converting to float:
$product_array = $this->getProducts();
$pcount = 0; //quantity of products in cart
$moreThanOneQuantity = FALSE;
foreach($product_array as $product_item) {
$pcount++;
if($product_item['quantity']>1) $moreThanOneQuantity = TRUE;
}
if($shipping_cost>0 && ($pcount>1 || $moreThanOneQuantity )) $shipping_cost=$shipping_cost/2;
Hope it will help someone.
This is not that simple to manipulate shipping cost. They depends on the carrier used for the cart. I think you should try to set fixed value in the carrier option, and define many price range.
If it's not enough, the best solution for me is to use a new cartrule. Create one that give free shipping, and override CartRule class. In the method getContextualValue, the shipping cost is setted to 0 here. i think you may change it to remove 50% instead. You may have to change some template rendering too (your cart will display a free shipping).
Hope it help.
I dont think you need to code here. You can try to play with the weights of the productos.
For example, you put all your items with weight 1 and you configure your shipping cost to be 50% more if the weight is up to 1. This way you will have what you want if I understood correctly
Related
Currently, using the WooCommerce Smart Coupons plugin, when combining two different coupons, a store credit is used first and then a percentage is used on the total after the first coupon is used.
This is illogical when you give someone store credit and they want to take that amount off of the cart total AFTER using the full % off. I'd like for this to work the opposite - use the percentage off coupon, then the store credit.
To be clear: The way it works now is...
Cart subtotal = $100
$10 Store credit coupon = -$10
10% off coupon = -$9
Cart total = $81
The way it SHOULD work is...
Cart subtotal = $100
$10 Store credit coupon = -$10
10% off coupon = -$10
Cart total = $80
Does anyone else have this issue? If so, how can it be fixed? Thanks!
EDIT 1: I've narrowed down this issue to being with the Smart Coupons plugin after disabling it and the calculations working as they should once disabled.
The solution for me was to UNCHECK a line item in the Woocommerce settings under the "General" tab and "Enable Coupons" section that says "Calculate coupon discounts sequentially"
I'm trying to take account of the package weight in the total weight of the cart so I can bill the right shipping cost.
I tried adding a filter on 'woocommerce_cart_contents_weight' like explained there
So I added the following code snippet
function add_package_weight_to_cart_contents_weight( $weight ) {
$weight = $weight * 1.3; // add 30%
return $weight;
}
add_filter('woocommerce_cart_contents_weight', 'add_package_weight_to_cart_contents_weight');
I've also added a snippet to print cart weight on cart page, and I can see that the weight filter isn't applied : The total weight of the cart doesn't change wether the snippet is active or not.
I also tried putting exactly 900g articles in the cart so that, with the box weight, it goes over 1kg and change price, but the shipping price is still the one for under 1kg.
Any idea on why it isn't applied and how I could fix it ?
Your code works and only affects WC_Cart method get_cart_contents_weight() usage.
Now for shipping methods, as cart items can be divided into packages, the weight is calculated for each shipping package and doesn't use WC_Cart method get_cart_contents_weight(). Instead it will make a calculation on the cart items for each package.
A possible way should be to use the filter hook woocommerce_package_rates to alter cost based on the package weight calculation. But this is going to be much more complicated as it seems that you are using 3rd party plugins.
I am having a problem with the following:
I use "TM extra product options" to add some extra options when buying a product. For example:
Box of chocolate (€40,00)
Extra decorations (extra option) (€15,00)
I offer free shipping on orders above €50,00. The problem is, that the extra fees are calculated AFTER the subtotal, and the shipping is calculated based on this subtotal. In the example above, you still have to pay for the shipping, which i don't want to.
How can I make sure the fee is calculated inside the subtotal (but still mentioned as seperated product) of have the shipping calculated based on the subtotal+fees?
Thanks in advance!
PS:
Something along this way:
$woocommerce_subtotal = $woocommerce_subtotal + $woocommerce_product_fee;
// set fee on 0 after this line
$woocommerce_product_fee = 0;
I'm using magento C.E 1.7. I use all shipping methods of magento and I'm viewing only one shipping method in the front end, which has higher priority. I'm using table rate shipping for some countries.
I wanted to add special fixed shipping price for some products when they shipped to that countries only. So that, I added new shipping method namely 'flat rate per product', by using a new module.
Based on this module, a text box is added to all the products in admin to specify the special shipping price. If I filled this field with some value, It considers it as a special shipping price. And if not filled it, it will be considered as special shipping price is $0.
So I have given least priority in the sort order for this shipping method to avoid this method from viewing on front end when products without special shipping price and products with special shipping price both are added into the cart.
So that, If only the special shipping priced product is added to the cart, It shows only table rate shipping method in front end.
I checked the code in availble.phtml. There is a foreach loop to proceed with available shipping methods. I need to check the availability of the 'flat rate per product' and it's price value for the product before start of loop execution.
I tried to get all the values of the array. But I could not. Can anyone help on this?
you can use this code:
<?php
$methods = Mage::getSingleton('shipping/config')->getActiveCarriers();
$shipMethods = array();
foreach ($methods as $shippigCode=>$shippingModel)
{
$shippingTitle = Mage::getStoreConfig('carriers/'.$shippigCode.'/title');
$shipMethods[$shippigCode] = $shippingTitle;
}
return $shipMethods;
?>
I'm looking to implement some e-commerce functionality that gives discounts when certain quantities are reached. The catch is, its not quantities of one sku, any number of other products in a category can trigger the quantity break when in total they reach the threshold.
So if I have a model class for a Cart_Product lets say, I would typically put the logic for getting the prices in that class as a method. But since other instances of that class in the current cart need to be considered, I'm not sure of the best way to proceed.
Do I call the "owner" Cart instance inside of the Cart_Product get_price method and then add the logic to check for the quantity break? Or is there a better design pattern to use at this step?
First of all, model is not a class or instance. Model is a layer. What you are talking about in your question actually are domain objects (assuming they are not also responsible for saving themselves, which would violate SRP.
As for applying the discount, it depends on whether each product in your cart has a separate discount of the discount is same for all the products:
if each product can have a separate discount, then the logic for that should reside in the Product domain object.
if all products get the same discount, then the discount should affect only the sum total, therefore - compute in the Cart instance.
The logic you have described is a cart-wide feature; since the cart is the logical owner of the products inside, you would implement it there:
class Cart
{
private $products; // Cart_Product[]
// ...
function calculateDiscount()
{
$totalQuantity = array_reduce($this->products, function($sum, $product) {
return $sum + $product->getQuantity();
}, 0);
if ($totalQuantity > 10) {
$this->cartDiscount = 25; // apply 25% discount on the cart
} else {
$this->cartDiscount = 0;
}
}
}
This introduces a separate entity for a global cart discount. If you don't want that, you would have to apply the discount to each individual item.
i just went through something very similar. really the only thing the cart should know about is the product id and the quantity. everything else should be for display purposes only. in other words the product object is always responsible for the price. the only reason that a price is stored in the cart is to help show it in the view. otherwise we assume that the price always has to be checked with any insert or update, to prevent fraud.
here is another scenario - you have a special on shipping, like buy $100 worth of qualifying goods and you get free shipping. there might be a separate shipping special on specific products. the only way to calculate is with all of the cart items.
so my solution - which i am not sure is optimal - is to pass the cart items to a shipping object - do the shipping calculations - optionally add messaging for specific products to display in the cart - and then return the cart items.
otherwise you are having to put shipping methods in the cart class which does not make any sense but maybe there is another way to do this.
here is another scenario - inventory control. someone orders 30 blue widgets but you only have 10 blue widgets. ok you can check for inventory when you insert item in cart. but what if they update the cart and then increase to 30? that means that we have to check inventory - for every item in the cart - every time the cart is updated. and if we are doing that then might as well get the price in case it has gone up or down.
so i take the cart items - and pass them to a product object - which checks inventory - and if necessary reduces the quantity of the items down to current inventory - optionally adds messaging explaining that stock is limited - then passes back to cart object.
finally - suggest that you have an object that owns the shopping session. and then thats where the totals would be. that way the cart is never in charge of totals - its just a container. one way is you just start an order and then store the different totals there.