WooCommerce Role Based Pricing - wordpress

I'm currently working with WordPress and WooCommerce for the first time. I have a management software and 2 different Customers tiers (one with extra discounts and one with regular price). I found a plugin that can import both of the prices in the fields "Regular price" and "Sale Price". The problem is, WooCommerce will always give the customers the discounted price, no matter the user role. I worked with some snippets and managed to display the regular price to Tier2 customers. However in the cart the price is still discounted. I tried using snippets to modify the cart prices, but it was useless (or maybe i'm burning out and can't figure out the solution). Plugins won't work for me, I watched and read all of them in the wp plugin store, and no one works well with my needs since i have almost 2000 products and most of them have different discounts percentage.
Please help me out!
Working Snippet:
$user = wp_get_current_user();
$allowed_roles = array( 'tier2');
if ( array_intersect( $allowed_roles, $user->roles ) || !is_user_logged_in()) {
add_filter('woocommerce_get_price_html', 'custom_price_html', 10, 2 );
function custom_price_html( $price, $product ) {
if ( $product->is_on_sale() && ! is_admin() ) {
$price = wc_price( wc_get_price_to_display( $product, array( 'price' => $product->get_regular_price() ) ) ) . $product->get_price_suffix();
}
return $price;
}
}
I tried searching on the net for plugins or similar solutions, nothing is working.

Related

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' );
}
}
}

Set Discounted Price for Related Product on Product Page

I am trying to set the price of all related products on the products page to 10% less = 0.9
The goal is to provide a discount of all related products on the product page but when viewed as a product, give the normal price.
Overall, the idea is to provide incentive that generates up-selling of related products.
I am asking for two things here. ONE: change the product price for related products on the product page (10% off) and TWO: carry that discounted price into the cart and checkout when the related discounted product is added to cart from the product page.
I almost got the first part down, but the code I'm trying to get working is giving me an error saying:
Warning: A non-numeric value encountered
My code so far:
add_filter( 'woocommerce_get_price_html', 'related_product_price_discount', 100, 2 );
function related_product_price_discount( $price, $product ) {
global $woocommerce_loop;
// make sure this is a related product on product page
if( is_product() && $woocommerce_loop['name'] == 'related' ){
$price = $price * 0.9;
}
// return related product price with discount
return apply_filters( 'woocommerce_get_price', $price );
}
The rule in StackOverFlow is one question at the time, so I will answer only your first question, which is related to your code issue...
Note that the hook woocommerce_get_price_html is related to the displayed formatted price.
To avoid the error "Warning: A non-numeric value encountered", you will use the following:
add_filter( 'woocommerce_get_price_html', 'related_product_price_discount', 100, 2 );
function related_product_price_discount( $price_html, $product ) {
global $woocommerce_loop;
// make sure this is a related product on product page
if( is_product() && $woocommerce_loop['name'] == 'related' ){
$price_html = wc_price( wc_get_price_to_display( $product ) * 0.9 );
}
// return related product displayed discounted formatted price
return $price_html;
}
Code goes in functions.php file of your active child theme (active theme). Tested and works.

Woocommerce products editable by their author for specific user role

I have different users registered on my WordPress website with different roles. Apart from the rest of users, I want to allow advertisers (users with advertiser role - advertiser is a custom role that I have created) to place their own products on my site and also manage them. But they need to be limited only to manage (create, edit and delete) their own products, not of others.
So far, I have tried the following code but it seems to be not valid. I am sure I can accomplish my goal using pre_get_posts action and the following function can help me but I need some help in resolving the issues with this code. I am not sure about the post type of products.
Here is the code that I am trying to accomplish my goal with:
function show_specific_advertiser_products( $query ) {
$current_user = wp_get_current_user();
if ( is_admin() && in_array ($query->get( 'post_type'), array( 'woocommerce_products' ) ) && !user_can( $current_user, 'administrator' ) ) {
$query->set( 'author__in', $current_user->ID );
}
}
add_action( 'pre_get_posts', 'show_specific_advertiser_products' );
Any help will highly be appreciated.
The error in your code comes from the post_type… for woocommerce products it's simply product. You will have to replace administrator by your custom user role.
So try the following instead:
add_action( 'pre_get_posts', 'show_specific_advertiser_products' );
function show_specific_advertiser_products( $query ) {
$user = wp_get_current_user();
if ( is_admin() && $query->get( 'post_type') === 'product' && in_array('administrator', $user->roles) ) {
$query->set( 'author', $user->ID );
}
}
Code goes in function.php file of your active child theme (or active theme). It should works.

Product get out of stock after order on Woocommerce

I have a really weird behavior on Woocommerce with the stock management. On a product with stock management enabled, a stock of 100 items and stock status "available", every time I do an order the product stock go to negative and get out of stock.
For example, if I do an order of 2 items of the product, the stock go to -2 right after the order, even if the stock was at 100 right before.
The product is a simple one, without any attribute. I use the following hooks to alter some label and stuffs, but none seems related to this issue:
add_filter('woocommerce_product_single_add_to_cart_text', array(&$this->wc, 'add_to_cart_text'), 11);
add_filter('woocommerce_add_to_cart', array(&$this->wc, 'add_to_cart'), 10, 1);
add_action('woocommerce_cart_item_removed', array(&$this->wc, 'cart_item_removed'), 10, 1);
add_action('woocommerce_order_status_completed', array(&$this->wc, 'order_status_completed'), 10, 1);
add_action('woocommerce_after_shop_loop_item', array(&$this->wc, 'replace_add_to_cart'));
In short, woocommerce_product_single_add_to_cart_text change the add to cart button label, woocommerce_add_to_cart place some vars in session, woocommerce_cart_item_removed remove those session var on item removal from cart, woocommerce_order_status_completed do some stuffs with the session vars (update a CPT from those session vars - I don't touch the order or the product at all) and woocommerce_after_shop_loop_item display a button on product listing. I tried to disable the woocommerce_order_status_completed hook, it didn't change anything.
I will paste any code of those function if any of you think some could be related to this stock issue.
I'm using latest version of Woocommerce and Wordpress.
I found out the culprit, as helgatheviking suggested I disabled all the plugins one by one and found out that the plugin Progression One Click Import provided by the theme and marked as "recommended for theme use" was doing this.
My guess is that it is related to this filter in the plugin code:
add_filter( 'add_post_metadata', array( $this, 'check_previous_meta' ), 10, 5 );
Which is doing this:
public function check_previous_meta( $continue, $post_id, $meta_key, $meta_value, $unique ) {
$old_value = get_metadata( 'post', $post_id, $meta_key );
if ( count( $old_value ) == 1 ) {
if ( $old_value[0] === $meta_value ) {
return false;
} elseif ( $old_value[0] !== $meta_value ) {
update_post_meta( $post_id, $meta_key, $meta_value );
return false;
}
}
}
The flaw in this is that it is inserting the stock meta value raw (-2) instead of decrementing the existing meta value, which Woocommerce seems to do with some filter on his end - a behavior that is overwrited by this filter.
I guess this could be fixed by changing the filter priority but just disabling the plugin was good for me as I don't need to import preview data.

Prevent WooCommerce brand from being sellable

Hi there we have an online store running on WooCommerce and using the WooCommerce brands plugin (http://docs.woothemes.com/document/wc-brands/) but there is one brand that we are allowed show online with price but not allowed to actually sell.
Is there a function I can add for this particular brand to functions.php that will change the add to cart button in category or widget layout to "more info" and link to the product and then on the product page instead of the add to cart section just have a text message saying to call the store.
You can filter WooCommerce's is_purchasable method. Any item that returns false will not be able to be purchased.
function so_26378581_purchasable( $purchasable, $product ){
if ( has_term( 'your-brand', 'product_brand', $product->id ) ){
$purchasable = false;
}
return $purchasable;
}
add_action( 'woocommerce_is_purchasable', 'so_26378581_purchasable', 10, 2 );
This uses conditional logic to test whether the $product in question has the your-brand term in the product_brand taxonomy... via the has_term() function.
By the way, this is not the type of functionality that belongs in functions.php. Your theme should only be concerned with display/appearances. I would recommend that you make this its own plugin, or add to to a site specific snippets plugin.
to me it made no error message, but it did not work, as applied in my test subject and stand continues with two products of different brands.
I put this code:
function so_26378581_purchasable( $purchasable, $product ){
if ( has_term( 'product_brand', 'product_brand', $product->id ) ){
$purchasable = false;
}
return $purchasable;
}
add_action( 'woocommerce_is_purchasable', 'so_26378581_purchasable', 10, 2 );

Resources