Set max weight per cart item in Woocommerce - wordpress

How can I set the maximum weight per product (not per order)?
The customer can buy any number (quantity) of products until the max weight is reached. If he buys 5 products, The weight of total unit of each product cant reach max weight. There can be many products in an order but Total units(quantity) per product has Max weight.
For example, In a single order:
3 units of product A (weighing total 2kg)
5 units of product B (weighing total 1.4kg)
3 units of product C (weighing total 2kg)

In this example, the hooked function is triggered on add to cart action and you can perform all kind of checks to validate or not the action (and display a custom error message).
So you will see that you can target the total item weight individually…
add_filter( 'woocommerce_add_to_cart_validation', 'custom_add_to_cart_validation', 20, 5 );
function custom_add_to_cart_validation( $passed, $product_id, $quantity, $variation_id = '', $variations = '' ) {
// HERE define the weight limit per item
$weight_limit = 2; // 2kg
$total_item_weight = 0;
// Check cart items
foreach( WC()->cart->get_cart() as $cart_item ) {
$item_product_id = empty($variation_id) ? $product_id : $variation_id;
// If the product is already in cart
if( $item_product_id == $cart_item['data']->get_id() ){
// Get total cart item weight
$total_item_weight += $cart_item['data']->get_weight() * $cart_item['quantity'];
}
}
// Get an instance of the WC_Product object
$product = empty($variation_id) ? wc_get_product($product_id) : wc_get_product($variation_id);
// Get total item weight
$total_item_weight += $product->get_weight() * $quantity;
if( $total_item_weight > $weight_limit ){
$passed = false ;
$message = __( "Custom warning message for weight exceed", "woocommerce" );
wc_add_notice( $message, 'error' );
}
return $passed;
}
You will need also an additional hooked function that will be triggered on cart item quantity change:
add_filter( 'woocommerce_after_cart_item_quantity_update', 'limit_cart_item_quantity', 20, 4 );
function limit_cart_item_quantity( $cart_item_key, $new_quantity, $old_quantity, $cart ){
// HERE define the weight limit per item
$weight_limit = 2; // 2kg
// Get an instance of the WC_Product object
$product = $cart->cart_contents[ $cart_item_key ]['data'];
$product_weight = $product->get_weight(); // The product weight
// Calculate the limit allowed max quantity from allowed weight limit
$max_quantity = floor( $weight_limit / $product_weight );
// If the new quantity exceed the weight limit
if( ( $new_quantity * $product_weight ) > $weight_limit ){
// Change the quantity to the limit allowed max quantity
$cart->cart_contents[ $cart_item_key ]['quantity'] = $max_quantity;
// Add a custom notice
$message = __( "Custom warning message for weight exceed", "woocommerce" );
wc_add_notice( $message, 'notice' );
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.

Related

No decrement on order wordpress

everybody !
I'm looking for a way to no decrement when an order is completed.
Exemple: I got 1 T-shirt with 20 quantity. When i order, i want the number to be still 20, and not 19.)
here my hook:
add_action( 'woocommerce_order_status_completed', 'action_on_order_completed' , 10, 1 );
function action_on_order_completed( $order_id )
{
// Get an instance of the order object
$order = wc_get_order( $order_id );
// Iterating though each order items
foreach ( $order->get_items() as $item_id => $item_values ) {
// Item quantity
$item_qty = $item_values['qty'];
// getting the product ID (Simple and variable products)
$product_id = $item_values['variation_id'];
if( $product_id == 0 || empty($product_id) ) $product_id = $item_values['product_id'];
// Get an instance of the product object
$product = wc_get_product( $product_id );
// Get the stock quantity of the product
$product_stock = $product->get_stock_quantity();
// Increase back the stock quantity
wc_update_product_stock( $product, $item_qty, 'increase' );
}
}
But when the order is completed, the quantity still decrease. Any idea ?
That is because your hooked function is triggered after stock quantity is decreased.
You are trying to get previous stock quantity with
$product_stock = $product->get_stock_quantity();
But in that case this method returns already decreased value.
So, try this:
wc_update_product_stock( $product, $product_stock + $item_qty, 'increase' );

Woocommerce Zone Based minimum Amount

How Can ı set this situation ?
How can i add minimum order limit to flat rate product by zone ?
we can only free shipping products.
You can use the following for this, based on the zone id
function zone_based_minimum_amount() {
// Only run it in Cart or Checkout pages
if( is_cart() || ( is_checkout() && ! is_wc_endpoint_url() ) ) {
// HERE below your targeted zone IDs
$targeted_zones_ids = array( 1, 2 );
$chosen_methods = WC()->session->get( 'chosen_shipping_methods' ); // The chosen shipping mehod
$chosen_method = explode(':', reset($chosen_methods) );
$shipping_zone = WC_Shipping_Zones::get_zone_by( 'instance_id', $chosen_method[1] );
$zone_name = $shipping_zone->get_zone_name(); // Get the zone name
$zone_id = $shipping_zone->get_id(); // Get the zone ID
// Total (before taxes and shipping charges)
$total = WC()->cart->subtotal;
// HERE Set minimum cart total amount
$min_total = 100;
// Add an error notice is cart total is less than the minimum required
if( $total <= $min_total && in_array( $zone_id, $targeted_zones_ids ) ) {
// Display an error message
wc_add_notice( '<strong>' . sprintf(
__("A minimum total purchase amount of %s is required to checkout."),
wc_price($min_total)
) . '<strong>', 'error' );
// Removing the Proceed to checkout button from the Cart page
remove_action( 'woocommerce_proceed_to_checkout', 'woocommerce_button_proceed_to_checkout', 20 );
}
}
}
add_action( 'woocommerce_check_cart_items', 'zone_based_minimum_amount', 10, 0 );

Split cart items when quantity is updated on cart page in WooCommerce

I want to split cart items of same product in individual lines. When I increase quantity on single product page and add to cart, it shows as separate cart items.
Im using WooCommerce - Treat cart items separate if quantity is more than 1 answer code.
I want when quantity is updated on cart page and clicked on 'Update cart', then items must split on individual lines.
How can I do that?
The code below will split items on individual lines when quantity is updated on the cart page.
Comment with explanation added to the code.
function on_action_cart_updated( $cart_updated ) {
if ( $cart_updated ) {
// Get cart
$cart_items = WC()->cart->get_cart();
foreach ( $cart_items as $cart_item_key => $cart_item ) {
$quantity = $cart_item['quantity'];
// If product has more than 1 quantity
if ( $quantity > 1 ) {
// Keep the product but set its quantity to 1
WC()->cart->set_quantity( $cart_item_key, 1 );
// Run a loop 1 less than the total quantity
for ( $j = 1; $j <= $quantity -1; $j++ ) {
// Set a unique key.
$cart_item['unique_key'] = md5( microtime() . rand() . "Hi Mom!" );
// Get vars
$product_id = $cart_item['product_id'];
$variation_id = $cart_item['variation_id'];
$variation = $cart_item['variation'];
// Add the product as a new line item with the same variations that were passed
WC()->cart->add_to_cart( $product_id, 1, $variation_id, $variation, $cart_item );
}
}
}
}
}
add_action( 'woocommerce_update_cart_action_cart_updated', 'on_action_cart_updated', 20, 1 );

Setting up an error message for minimum quantity in WooCommerce

I set up a minimum quantity for a product category in WooCommerce. In my case I set the minimum quantity to 5 items. The code I use works fine but I would like to add two error messages for the customer:
1) If the customer tries to change the the quantity to less than the minimum by clicking the "-" symbol I would like to have something like: "The minimum quantity of this product is 5, please add at least 5 items to the basket"
2) If the customer clicks the "add to the basket" button I would like to have something like this: "There is a minimum quantity of 5 items for this product. Please check your basket"
Is there some code I can add to my actual code?
add_filter( 'woocommerce_quantity_input_args', 'min_qty_filter_callback', 20, 2 );
function min_qty_filter_callback( $args, $product ) {
$category = 'Noten'; // The targeted product category
$min_qty = 5; // The minimum product quantity
$product_id = $product->is_type('variation') ? $product->get_parent_id() : $product->get_id();
if( has_term( $category, 'product_cat', $product_id ) ){
$args['min_value'] = $min_qty;
}
return $args;
}
For add to cart validation add the follows code snippet to validate your item quantity -
function add_to_cart_validation( $flag, $product_id, $qunatity ) {
if( $qunatity < 5 ) { // if quantity less than 5
wc_add_notice( __( 'There is a minimum quantity of 5 items for this product. Please check your basket', 'text-domain' ), 'error' );
$flag = false;
}
return $flag;
}
add_filter( 'woocommerce_add_to_cart_validation', 'add_to_cart_validation', 10, 3 );

How to get the value of the steps quantity product added to WooCommerce cart?

I used this code to filter the products added to the cart of a certain category (id = 70).
My goal is to count the number of step quantities added to the cart of a product belonging to the '70' category.
Example:
Minimum quantity: 0
Step: 100
I added the product to the cart with 300 quantities.
So the step number is 3.
Is there a way to get the number of step quantities of a product added to the cart?
// Utility function that count specific product category cart items
add_shortcode('palletcompleto', 'cat_cart_count');
function cat_cart_count( $term_ids ) {
$quantity = 0; // Initializing
// Loop through cart items
foreach ( WC()->cart->get_cart() as $cart_item ) {
if ( has_product_category( $cart_item['product_id'], array( 70 ) ) ) {
$quantity += $cart_item['step_quantity'];
}
}
// Returning category count
return $quantity == 0 ? false : $quantity;
}
I am using some code like has_product_category() function from this thread:
Set item quantity to multiples of “x” for products in a specific category in Woocommerce
// Custom conditional function that checks also for parent product categories
function has_product_category( $product_id, $category_ids ) {
$term_ids = array(); // Initializing
// Loop through the current product category terms to get only parent main category term
foreach( get_the_terms( $product_id, 'product_cat' ) as $term ){
if( $term->parent > 0 ){
$term_ids[] = $term->parent; // Set the parent product category
$term_ids[] = $term->term_id;
} else {
$term_ids[] = $term->term_id;
}
}
return array_intersect( $category_ids, array_unique($term_ids) );
}

Resources