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

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

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

In Woocommerce, how to add custom attribute total on cart page

I am developing a diamond jewellery e-commerce website using Woocommerce.
I want to add custom attributes - Gold Weight and Diamond Carats for all the products.
My question is:
1. How to show these custom attributes as columns on cart page?
2. How to show total of gold weight and diamond carats on cart page?
Thank you.
For the first task try using this plugin https://wordpress.org/plugins/woocommerce-show-attributes/
For second task try following code:
function my_attribute_sum () {
$total = array();
$runningSum = 0;
foreach ( WC()->cart->get_cart() as $cart_item ) {
$product = $cart_item['data'];
$quantity = $cart_item['quantity'];
if(!empty($product)){
$product_attr = $product->get_attribute( 'pa_my_attribute' );
$product_quantity = $product->get_attribute( 'quantity' );
$runningSum = $product_attr * $quantity;
$total[] = $runningSum;
}
}
echo 'Total sum is: ' . array_sum ($total);
}
add_action ('woocommerce_after_cart_table', 'my_attribute_sum');
Swap pa_my_attribute with appropriate name. I am not sure this will work for variable products but this works for sure for simple products.

Sorry, this product cannot be purchased. Woocommerce

I have created a advance custom field using ACF wordpress plugin to check if the product is available for this month or not. The code I am using is below but when it does work to point where it shows add to cart button if the product is available for that month if not then shows the message.
Now the issue is when product is available to purchase if I click on add to cart it says "Sorry, this product cannot be purchased." I am not able to find what is wrong with it.
add_filter('woocommerce_is_purchasable', 'woocommerce_is_purchasable_filter_callback', 10, 2 );
function woocommerce_is_purchasable_filter_callback( $purchasable, $product ) {
$months = (array) get_field('availability');
$purchasable = in_array( date('F'), $months ) ? $purchasable : false;
return $purchasable;
}
add_action( 'woocommerce_single_product_summary', 'unavailable_product_display_message', 20 );
function unavailable_product_display_message() {
global $product;
if(! $product->is_purchasable() ){
echo '<p style="color:#e00000;">' . __("This product is currently unavailable.") . '</p>';
}
}
Try to change this line of code:
$months = (array) get_field('availability');
to:
$months = (array) get_field('availability', $product->get_id());
The get_field function doesn`t know from which product to get, so this will be an empty array. The variable $purchasable will always be false when this happens.

Don't allow user role buy option when stock is low 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);

Create a Woocommerce product sold in units of gram

I would like to create a product in WooCommerce that is sold in units of gram.
The customer would enter the number of grams they want (in an input field) on the product page, and the price would be computed on the fly and added to the cart.
My question is: is this possible, and if so, can someone give me just a "big picture" idea of how I would implement it?
I don't need line-by-line code, just hoping someone with more knowledge of the structure of Woo can guide me on how to best attack the problem.
I already have parts of it worked out:
I can decide that the price entered for the product is the price per
100 grams, so that is how the seller will enter the price.
Then I can
write a little bit of Javascript to compute the price on the fly and
display it on the page as the user types the amount they want. No
problem.
But... I think every discrete product in Woo needs to have its own price.. So for example, if a customer wants 123g of a product, it seems like I might have to create a variation on the fly for that specific price/amount, and then add that to the cart. Which (judging by this) looks non-trivial and a little hacky. Is there a better way to do this?
WooCommerce has an option to show the weights as grams.
The following code will display the KG weights as grams on the WooCommerce templates :
// Convert the product weight
function ag_woocommerce_product_get_weight( $weight ) {
// Only convert if we have a weight
if ($weight) {
// The weight is in KGS, and we want grams, to multiple by 1000
$weight = $weight * 1000;
}
return $weight;
};
// add the filter
add_filter( 'woocommerce_product_get_weight', 'ag_woocommerce_product_get_weight', 10, 1 );
Hope this might help. Cheers!
There is a free plugin for WooCommerce that allows you to input a unit of measure (UOM) for each product:
https://wordpress.org/plugins/woocommerce-unit-of-measure/
I found this plugin that does pretty much exactly what I need-- https://woocommerce.com/products/measurement-price-calculator/
It's easier and quicker to give you that real example, than explain step by step… You will see which hooks are used for all steps or tasks.
You dont need variable products or generate a variation on the fly.
You just need to set on each simple product the price for one gram (or any other base). Now in this code, you can target those products with:
an array of product Ids
or by product categories (or even product tags).
Your concern is about the way to pass the data in the cart, to update the final price for each product and display the chosen grams amount in cart, checkout and in the order.
So in each product you will only set the price by gram… (or you can also make changes in the code and set the product price for 100 grs or even any other base).
The code:
// Add a product custom field "grams_quantity" that will update the displayed price
add_action('woocommerce_before_add_to_cart_button', 'special_product_by_grams', 25);
function special_product_by_grams(){
global $product;
// HERE Define the special product IDs sold by grams
$targeted_product_ids = array(37);
// or HERE Define a product categories (ids, slugs or names)
$categories = array('sold-by-gram');
// Only for products sold by gram
$product_id = $product->get_id();
if ( ! ( in_array( $product_id, $targeted_product_ids ) || has_term( $categories, 'product_cat', $product_id ) ) ) return;
?>
<div class="grams-field">
<label for="grams_quantity"><?php _e('Grams: ','woocoomerce'); ?><span></span><br>
<input type="number" step="1" name="grams_quantity" class="grams_quantity" id="grams_quantity" value="1">
</label>
</div><br>
<script type="text/javascript">
(function($){
// variables initialization
var priceByGram = <?php echo wc_get_price_to_display( $product ); ?>,
currencySymbol = $(".woocommerce-Price-currencySymbol").html(),
updatedPrice;
// On live event: imput number fields
$('input#grams_quantity').on( "click blur", function(){
updatedPrice = ($(this).val() * priceByGram).toFixed(2);
$(".woocommerce-Price-amount.amount").html('<span class="woocommerce-Price-amount amount">'+updatedPrice+' '+currencySymbol+'</span>');
console.log("event"); // <== To be removed
});
})(jQuery);
</script>
<?php
}
// Save the "grams_quantity" custom product field data in Cart item
add_filter( 'woocommerce_add_cart_item_data', 'save_in_cart_the_custom_product_field', 10, 2 );
function save_in_cart_the_custom_product_field( $cart_item_data, $product_id ) {
if( isset( $_POST['grams_quantity'] ) ) {
$cart_item_data[ 'grams_quantity' ] = $_POST['grams_quantity'];
// When add to cart action make an unique line item
$cart_item_data['unique_key'] = md5( microtime().rand() );
WC()->session->set( 'custom_data', $_POST['grams_quantity'] );
}
return $cart_item_data;
}
// Update product price by grams in cart and checkout
add_filter( 'woocommerce_before_calculate_totals', 'update_prices_by_gram', 10, 1 );
function update_prices_by_gram( $cart_object ) {
// HERE Define the special product IDs sold by grams
$targeted_product_ids = array(37);
// or HERE Define a product categories (ids, slugs or names)
$categories = array('sold-by-gram');
foreach ( $cart_object->get_cart() as $cart_item ) {
// Only for products sold by gram
$product_id = $cart_item['product_id'];
if ( in_array( $product_id, $targeted_product_ids ) || has_term( $categories, 'product_cat', $product_id ) ){
// Get an instance of the WC_Product object and the
$product = $cart_item['data'];
$grams = $cart_item['grams_quantity'];
// Method is_on_sale() manage everything (dates…)
$product->set_price( $product->get_price() * $grams);
}
}
}
// Render "grams_quantity" the custom product field in cart and checkout
add_filter( 'woocommerce_get_item_data', 'render_product_custom_field_meta_on_cart_and_checkout', 10, 2 );
function render_product_custom_field_meta_on_cart_and_checkout( $cart_data, $cart_item ) {
$custom_items = array();
if( !empty( $cart_data ) )
$custom_items = $cart_data;
if( isset( $cart_item['grams_quantity'] ) )
$custom_items[] = array(
'name' => __( 'Grams', 'woocommerce' ),
'value' => sanitize_text_field( $cart_item['grams_quantity'] ),
'display' => sanitize_text_field( $cart_item['grams_quantity'] ),
);
return $custom_items;
}
// Save "grams_quantity" to the order items meta data
add_action('woocommerce_add_order_item_meta','add_product_custom_fiel_to_order_item_meta', 1, 3 );
function add_product_custom_fiel_to_order_item_meta( $item_id, $item_values, $item_key ) {
if( isset( $item_values['grams_quantity'] ) )
wc_update_order_item_meta( $item_id, 'Grams', sanitize_text_field( $item_values['grams_quantity'] ) );
}
Code goes in function.php file of your active child theme (or active theme) or in any plugin file.
Tested and works.

Resources