Woocomerce - Update max quantity for product variation - php

I'm trying to update max quantity for all variations of my variable product to ie 345.
$available_variations = $product->get_available_variations();
foreach ($available_variations as $variation)
{
$variation_ID = $variation->ID;
update_post_meta( $variation_ID , 'max_qty', 345 );
}
It doesn't happen.

You are not using the correct way to get the variation ID and the product meta key max_qty doesn't exist in WooCommerce database on wp_postmeta table for product_variation post type.
Instead you can use the following filter hook to set a specific maximum quantity to product variations:
add_filter( 'woocommerce_available_variation', 'wc_available_variation_max_qty', 10, 3 );
function wc_available_variation_max_qty( $data, $product, $variation ) {
$data['max_qty'] = 345;
return $data;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and work.

Why not set it to 345 by default?
$max_m = $max_l = $max_xl = $max_xxl = $max_xxxl = '345';
if($max_qty != 345){
//Limit Reached error
}
OR
$product->get_available_variations = '345';
if($variation_ID != 345){
$variation_ID->max_qty = 345;
}
Since it's an online shop why not use MySQLi? It's PHP powered so why not?
this way you can do MySQLi->query, and UPDATE the value.
Edited

Related

How get woocommerce product price before and after save

I want get and set log for woocommerce variation product price after product price change. (after click on update product)
EX :
Product 1 :
Variation 1 : old price : 10.000 , new price : 20.000
Variation 2 : old price : 30.000 , new price : 50.000
i test wp_insert_post_data filter and save_post_product action
but i can't get old price and two function return new price
How i can get product old price before new price saved in database
**die at the end of function for see result.
add_action('save_post_product', 'save_post_action', 10, 3);
function save_post_action( $post_id, $post, $update ) {
if (get_post_type($post_id) !== 'product') return;
$product = wc_get_product($post_id);
$current_products = $product->get_children();
foreach ($current_products as $variation_id) {
$variable_product = wc_get_product($variation_id);
//$regular_price = $variable_product->get_regular_price();
//$sale_price = $variable_product->get_sale_price();
$price = $variable_product->get_price();
var_dump($price);
}
die;
}
Variable products are saved using Ajax before saving the parent.
So woocommerce_admin_process_variation_object action precedes save product variation.
add_action('woocommerce_admin_process_variation_object', 'get_previous_variation_price', 10, 1);
function get_previous_variation_price($variation) {
$previous_price = $variation->get_price();
}

Enable decimal quantities and stock for WooCommerce products

I want to change the default quantity from the products, from 1 to 0,1 but I can't seem to figure it out.
I tried the following:
function custom_quantity_input_args($args, $product) {
$args['input_value'] = 0.10;
$args['min_value'] = 0.10;
$args['step'] = 0.10;
$args['pattern'] = '[0-9.]*';
$args['inputmode'] = 'numeric';
return $args;
}
The problem with this is that modifies the quantity input from cart as well, which isn't what I want.
To be more specific I want the following:
when I go to the product page I want to show 0,1;
when I go to the cart page I want to show the current quantity;
The solution I mention above shows 0,1 both in product page and in cart page.
I found another solution, but it shows the current quantity both in product and in cart which, again, it's not what I want.
Any ideas?
Based on Decimal quantity step for specific product categories in WooCommerce answer code, try the following revisited code:
// Defined quantity arguments
add_filter( 'woocommerce_quantity_input_args', 'custom_quantity_input_args', 9000, 2 );
function custom_quantity_input_args( $args, $product ) {
if( ! is_cart() ) {
$args['input_value'] = 0.1; // Starting value
}
$args['min_value'] = 0.1; // Minimum value
$args['step'] = 0.1; // Quantity steps
return $args;
}
// For Ajax add to cart button (define the min value)
add_filter( 'woocommerce_loop_add_to_cart_args', 'custom_loop_add_to_cart_quantity_arg', 10, 2 );
function custom_loop_add_to_cart_quantity_arg( $args, $product ) {
$args['quantity'] = 0.1; // Min value
return $args;
}
// For product variations (define the min value)
add_filter( 'woocommerce_available_variation', 'filter_wc_available_variation_price_html', 10, 3);
function filter_wc_available_variation_price_html( $data, $product, $variation ) {
$data['min_qty'] = 0.1;
return $data;
}
// Enable decimal quantities (in frontend and backend)
remove_filter('woocommerce_stock_amount', 'intval');
add_filter('woocommerce_stock_amount', 'floatval');
Code goes in functions.php file of the active child theme (or active theme). Tested and works.

Set all variations out of stock if one variation is out of stock in WooCommerce

We run a self-storage system with WooCommerce and we use WooCommerce Subscriptions plugin. Our storage units is a unique product with a Variable Subscription. Each variation has a different billing period (1 month, 3 months, 6 months and 12 months). I need the whole parent product, or at least all variations, to be out of stock if one variation is out of stock.
I didn't find any related setting and I didn't find how to make that possible yet.
Any help is appreciated.
The following will make all variations out of stock (for specific variable product(s)), when one variation is out of stock (also works with WooCommerce subscriptions):
add_filter('woocommerce_available_variation', 'set_all_variations_out_of_stock', 10, 3 );
function set_all_variations_out_of_stock( $data, $product, $variation ) {
// Set the Id(s) of the related variable product(s) below in the array
if( in_array( $product->get_id(), array(738) ) ){
$out_of_stock = false; // initializing
// Loop through children variations of the parent variable product
foreach( $product->get_visible_children() as $_variation_id ) {
if( $_variation_id != $data['variation_id'] ) {
$_variation = wc_get_product($_variation_id);
if( ! $_variation->is_in_stock() ) {
$out_of_stock = true; // Flag as out of stock
break;
}
}
}
if ( $out_of_stock ) {
$data['availability_html'] = '<p class="stock out-of-stock">'. __('Out of stock', 'woocommerce') .'</p>';
$data['is_in_stock'] = false;
}
}
return $data;
}
Code goes in function.php file of your active child theme (active theme). Tested and works.
Important note:
Stock can be managed on the parent variable product.
Enable stock management on the variable product (on Inventory tab) and set the stock there.
Disable stock management on each variation for this variable product.
You are done. The stock management is now handled on the variable
product.

Woocommerce Force Sells/Bookings - Snippet to force number of person in a booking

With WooCommerce, I am using WooCommerce bookings and WooCommerce force sells plugins.
I want to use WooCommerce Force Sells to add one force-sold item per number of person in a booking.
Woocommerce guys already provided a snippet to be added in functions.php which modifies the behavior of Force Sells. With this snippet you can set a fixed quantity (1) of side product to be added :
// only add one force sell item per product no matter how many of the original product are added
function my_wc_force_sell_add_to_cart_product( $product ){
$product['quantity'] = 1;
return $product;
}
add_filter( 'wc_force_sell_add_to_cart_product', 'my_wc_force_sell_add_to_cart_product' );
// when a synced force sell product is updated always set it to 1
function my_wc_force_sell_update_quantity( $quantity, $product ){
return 1;
}
add_filter( 'wc_force_sell_update_quantity', 'my_wc_force_sell_update_quantity' );
What I would like to do: Replacing the fixed quantity (1) with a function retrieving the number of people specified in the booking.
Any help would be awesome.
I think I found it !
function my_wc_force_sell_add_to_cart_product( $product ){
foreach(WC()->cart->get_cart() as $cart_item) {
// The item persons count
$person = array_sum( $cart_item['booking']['_persons'] );
}
$product['quantity'] = $person;
return $product;
}
add_filter( 'wc_force_sell_add_to_cart_product', 'my_wc_force_sell_add_to_cart_product' );
// when a synced force sell product is updated always set it to 1
function my_wc_force_sell_update_quantity( $quantity, $product ){
return 1;
}
add_filter( 'wc_force_sell_update_quantity', 'my_wc_force_sell_update_quantity' );

Set bookable product base cost programatically in Woocommerce Bookings

I am trying to calculate the Base cost of a WooCommerce bookable product and managed to get it done using this:
function modify_baseprice() {
global $post;
$productid = $post->ID;
$product = new WC_Product($productid);
$product_block_price = $product->wc_booking_block_cost;
$product->wc_booking_cost = ($product_block_price*0.6) + 100;
$pricing_data = update_post_meta( $productid, '_wc_booking_cost', $product->wc_booking_cost);
return $pricing_data;
}
add_action( 'woocommerce_bookings_after_booking_base_cost', 'modify_baseprice', 10, 3 );
It does calculate the Base cost correctly but I need to refresh the page twice to see it appearing on the Base cost field. Is there a way that I can get it to appear after the first save?
Since Woocommerce 3 release, CRUD objects have been implemented. It's the case of WC_Product object and also for Woocommerce Bookings plugin. So you can use available Getters and setters methods as properties are not anymore accessible (in most cases).
The following code use this better way (The cost is set in the product without any need of refreshing the page):
add_action( 'woocommerce_process_product_meta_booking', 'modify_bookable_product_base_cost', 100, 1 );
function modify_bookable_product_base_cost( $product_id ){
// Get an instance of the WC_Product object
$product = wc_get_product( $product_id );
// We check that we have a block cost before
if ( $product->get_block_cost() > 0 ){
// Calculation
$new_booking_cost = ( $product->get_block_cost() * 0.6 ) + 100;
$product->set_cost( $new_booking_cost ); // Set the new calculated cost in the product
$product->save(); // Save the product data
}
}
Code goes in function.php file of your active child theme (active theme). Tested and works.

Categories