Don't allow user role buy option when stock is low woocommerce - woocommerce

I need something like this :
It is possible to set that when we have last 5 pcs on stock , some user role (wholesale) cant order that product ?
For example if we set quantity to 6 pcs than wholesale customer can will order only 1 pcs to stay minimum there 5 pcs and if is lower than 5 pcs than wholesale customer cant order than product ?

I don't know if you requirement is feasible or not. But i have a logic (which may or mayn't be the proper way)
get stock quantity and user role on clicking add to cart button
Check if user role is wholesale customer and stock quantity is the required one
if yes then block product from being added to cart
This is the basic implementation of the above logic. I have just checked the code and found that product is not added to cart. You can build on the code to meet your requirements.
function stock_quantity_validation($valid, $product_id, $quantity){
$qty = 7; // Your required stock quantity
if( is_user_logged_in() ) {
$user = wp_get_current_user();
$roles = ( array ) $user->roles;
if ( in_array( 'wholesale_customer', $roles ) ) {
$stock = get_post_meta( $product_id, '_stock', true ); // Getting stock quantity of product
if($stock < $qty){
$valid = false;
}
}
}
return $valid;
}
add_filter('woocommerce_add_to_cart_validation','stock_quantity_validation', 10, 3);

Related

Hide product price on country out of GB but show only IF products have a TAG

currently I hide all product price for out of GB but I would like to show product price only if they have a TAG.
my code to hide product price out of GB is anyone can help me ? please ?
/** hiding prices if outside of gb*/
add_filter( 'woocommerce_get_price_html', 'country_geolocated_based_hide_price', 10, 2 );
function country_geolocated_based_hide_price( $price, $product ) {
// Get an instance of the WC_Geolocation object class
$geo_instance = new WC_Geolocation();
// Get geolocated user geo data.
$user_geodata = $geo_instance->geolocate_ip();
// Get current user GeoIP Country
$country = $user_geodata['country'];
return $country !== 'GB' ? '' : $price;
}
/** fin hiding prices if outside of gb*/
thank you
show product price for out of GB and show product price only if they have a TAG
You can modify your code this way:
// This will show product prices for products with a specific tag and outside of GB
add_filter( 'woocommerce_get_price_html', 'show_price_based_on_country_and_tag', 10, 2 );
function show_price_based_on_country_and_tag( $price, $product ) {
// Get an instance of the WC_Geolocation object class
$geo_instance = new WC_Geolocation();
// Get geolocated user geo data.
$user_geodata = $geo_instance->geolocate_ip();
// Get current user GeoIP Country
$country = $user_geodata['country'];
// Check if the product has the tag 'my_tag'
$tag = 'my_tag';
$has_tag = has_term( $tag, 'product_tag', $product->get_id() );
// This will show price only if the user is outside of GB and the product has the tag 'my_tag'
return ( $country !== 'GB' && $has_tag ) ? $price : '';
}
Thank you Faisal ! you help me so much :)
first impression, I thought it working but prices are hided on GB as well is product haven't tag.
GB = can see everything
outside of GB = can see prices only product has the tag

WooCommerce function that disables an admin user to reduce the product stock quantity

I would like to add a function that is triggered every time that the stock quantity of a product will be changed in the admin product page, such that this function will not allow any reduce of the stock value - but only increase.
This is to prevent an admin user to reduce the stock quantity of the products.
Of course, this function should not be triggered if a product will be in an order, since then of course I would like the stock quantity to be reduced.
I tried the following function in the functions.php but unfortunately did not work.
Since I'm new to woocommerce and php, any ideas that could provide a solid solution to the problem?
// get old and new product stock quantity
function get_old_and_new_product_quantity_stock( $sql, $product_id_with_stock, $new_stock, $operation ) {
$product = wc_get_product( $product_id_with_stock );
$old_stock_quantity = $product->get_stock_quantity();
$new_stock_quantity = $new_stock;
echo $old_stock_quantity, $new_stock_quantity;
if ($new_stock_quantity < $old_stock_quantity) {
$new_stock = $old_stock_quantity;
$new_stock_quantity = $old_stock_quantity;
}
return $sql;
}
add_filter( 'woocommerce_update_product_stock_query', 'get_old_and_new_product_quantity_stock', 10, 4 );
You can use the update_post_meta action hook to check if the new value is less than the previous value and display error message.
This will work for quick edit and for product edit page. But the wp_die on product page will look bad so use the javascript to prevent submitting on product edit page (there was another question about it yesterday)
Be sure to test this snippet and create some orders that will reduce the stock automatically. I added is_admin() check but please do a good test.
add_action( 'update_post_meta', 'prevent_reducing_stock_metadata', 10, 4 );
function prevent_reducing_stock_metadata( $meta_id, $post_id, $meta_key, $meta_value ) {
// Check if the meta key is _stock and the new value is less than the previous value
if ( '_stock' == $meta_key && $meta_value < get_post_meta( $post_id, '_stock', true ) ) {
// Check if this is an update from the WordPress admin area
if ( is_admin() ) {
wp_die( __( 'Error: You cannot reduce the stock level for this product.' ), 'error' );
}
}
}

WooCommerce - Reset product quantity after validation error

I have a variable product that has variations based on a meal selection, like chicken, beef. I also have a custom field called Badge Name. I want the user to be able to add the product multiple times to the cart as a single quantity, with a different variation and/or badge name. So the cart should look like this:
Variation
Badge Name
Quantity
Full Package - Chicken
Tina
1
Full Package - Chicken
Mike
1
I have added a custom validation, verifying that the quantity is 1. If the quantity is changed to 2 then I get the error as expected. However, I'd like the quantity to reset to 1 but it stays at 2. I can't set the max quantity to 1 because I want the user to be able to add the product to the cart multiple times per order. I can't seem to find the correct function for changing the quantity back to 1 on the product page after a validation error. Am I over-thinking this and the answer is right in front of my nose?
Here is my validation code:
function filter_woocommerce_add_to_cart_validation( $passed, $product_id, $quantity, $variation_id = null, $variations = null ) {
// Product id for 2021 Full Package - Online
$product_id_full = 3164;
// If passed
if ( $passed ) {
// If product is added with $quantity > 1
if ( $product_id_full == $product_id && $quantity > 1 ) {
// Set error message
$message = 'Full Package must be added to the cart individually with dinner selection and badge name for each attendee.';
wc_add_notice( __( $message, 'woocommerce' ), 'error' );
$passed = false;
}
}
return $passed;
}
add_filter( 'woocommerce_add_to_cart_validation', 'filter_woocommerce_add_to_cart_validation', 10, 5 );

WooCommerce coupon calculate from regular price

I need functionality for "friend" customers, who can get products with better price. User role based solution is not what I'm looking for and customer wants it to work with coupons. They give coupon code to their customers and they get for example 8€ off from REGULAR price on certain products. The problem is, by default WooCommerce coupons calculate it from smallest price. If sale price is set, then this calculation is wrong and the customer gets it too cheap. Basically, I want coupon to give certain products fixed "friend" price.
I've been googling around and can't find a ready solution for it. Any suggestions how to solve this problem are welcome.
I have checked multiple plugins, but none of them has filled my requirements.
Add to functions.php. Based off of this code https://brilliantinfo.net/apply-coupon-discount-on-regular-price-in-woocommerce/
Modified for coupon type of fixed_product. If you need this to only work for a specific coupon then I can modify for that. (As it stands this will apply to any fixed_product coupons that are used)
add_action( 'woocommerce_before_calculate_totals', 'adjust_cart_coupon', 10, 1);
function adjust_cart_coupon( $cart_object) {
global $woocommerce;
if ( is_admin() && ! defined( 'DOING_AJAX' ) ){
return;
}
$coupon = False;
if ($coupons = WC()->cart->get_applied_coupons() == False ) {
$coupon = False;
} else {
foreach ( WC()->cart->get_applied_coupons() as $code ) {
$coupons1 = new WC_Coupon( $code );
if ($coupons1->type == 'fixed_product'){
$coupon = True;
}
}
}
if ($coupon == True){
foreach ( $cart_object->get_cart() as $cart_item ){
$price = $cart_item['data']->regular_price;
//sets cart item to use regular price and not sale price
$cart_item['data']->set_price( $price );
}
}
}
The Discount Rules for WooCommerce plugin might fit your requirements.
With it you can apply a coupon, or any discount rule, to specific customers.
Also there is a setting to Apply discount based on Sale price or Regular price.

How do I disable shipping in some of my woocommerce products

I have a WooCommerce online shop that offers shipping to most products. Some of the products are for local pickup. I've tried setting a class on shipping zones with cost equal to zero and assigning the class on the products. But so far, the checkout still displays the shipping cost. Is there any way where some products will not have a shipping cost?
If you are searching for plugin solution, try WooCommerce Conditional Shipping and Payments. By using this plugin, you could add restrictions on certain product or product categories.
You've might want to look into the woocommerce_package_rates filter, which allows you to filter the set of shipping options that are available to the customer. An example would be something like this:
<?php
// add this snippet to functions.php:
add_filter( 'woocommerce_package_rates', function ( $rates, $package ) {
// examine $package for products. this could be a whitelist of specific
// products that you wish to be treated in a special manner...
$special_ids = array( 1, 2, 3, 4, 5 );
$special_product_present = false;
foreach ( $package['contents'] as $line_item ) {
if ( in_array( $line_item['product_id'], $special_ids ) ) {
$special_product_present = true;
}
}
$rates = array_filter( $rates, function ( $r ) use ( $special_product_present ) {
// do some logic here to return true (for rates that you wish to be displayed), or false.
// example: only allow shipping methods that start with "local"
if ( $special_product_present ) {
return preg_match( '/^local/', strtolower( $r->label ) );
} else {
return true;
}
} );
return $rates;
}, 10, 2 );
This blog post here shows some variations on that idea using this hook, including how to customize the available rates based on shopping cart value, customer's country, number of items in the cart, etc. And here's the source code: https://github.com/woocommerce/woocommerce/blob/v2.2.3/includes/class-wc-shipping.php#L366

Resources