i want see attributes in the back end on the all products page.
and can it shows the quanity vs in stock out of stock?
many plugins tried so far none suitable
I don't know about any plugin for these kind of functionality. But, I've created this functionality. Let me share the details with you.
Add following snippets of code to your active child-theme's functions.php file.
Below displayed snippets will add new columns to All Products page's Product Table. i.e. Stock Quantity and Color. Here Color is my product's attribute.
add_filter( 'manage_edit-product_columns', 'admin_products_column', 9999 );
function admin_products_column( $columns ){
$columns['stock_quantity'] = 'Stock Quantity'; // Stock
$columns['color'] = 'Color'; // Attribute
return $columns;
}
Now we need to bring the data in these columns, So for the Stock Quantity use below mentioned code snippets.
add_action( 'manage_product_posts_custom_column', 'admin_products_stock_column_content', 10, 2 );
function admin_products_stock_column_content( $column, $product_id ){
if ( $column == 'stock_quantity' ) { // condition to check stock qty. column.
$product = wc_get_product( $product_id );
echo $product->get_stock_quantity();
}
}
To get data in color attribute column use below mentioned code snippets.
add_action( 'manage_product_posts_custom_column', 'admin_products_attribute_color_column_content', 10, 2 );
function admin_products_attribute_color_column_content( $column, $product_id ){
if ( $column == 'color' ) { // condition to check color attribute column
$product = wc_get_product( $product_id );
echo $product->get_attribute('pa_color'); // 'pa_color' is Slug of Color Attribute.
}
}
Final result will look like this image.
With WooCommerce, I have the following function that allow me to make a discount on my products prices:
add_filter('woocommerce_product_get_regular_price', 'custom_price' , 99, 2 );
function custom_price( $price, $product )
{
$price = $price - 2;
return $price
}
This is working everywhere (in the shop, in the cart, in the backend), but not in my custom product list plugin:
add_action( 'woocommerce_account_nybeorderlist_endpoint', 'patrickorderlist_my_account_endpoint_content' );
function patrickorderlist_my_account_endpoint_content() {
//All WP_Query
echo wc_price($price);
}
This shows the regular price without the discount. Both pieces of code are in the same plugin.
For info, wc_price() is just a formatting function used to format prices and has nothing to do with the $price itself main argument. Your problem is that in your 2nd function, the variable $price certainly doesn't use the WC_Product method get_regular_price(), which is required in your case… So in your WP_Query loop, you need to get the WC_Product object instance, then from this object get the price using the method get_regular_price()…
So try something like (it's an example as you don't provide your WP_Query in your question):
add_action( 'woocommerce_account_nybeorderlist_endpoint', 'rm_orderlist_my_account_endpoint_content' );
function rm_orderlist_my_account_endpoint_content() {
$products = new WP_Query( $args ); // $args variable is your arguments array for this query
if ( $products->have_posts() ) :
while ( $products->have_posts() ) : $products->the_post();
// Get the WC_Product Object instance
$product = wc_get_product( get_the_id() );
// Get the regular price from the WC_Product Object
$price = $product->get_regular_price();
// Output the product formatted price
echo wc_price($price);
endwhile;
wp_reset_postdata();
endif;
}
Now it should work as expected.
I have a Woocommerce variable product. I need to get the attribute (pa_brand) of the parent of that variation? Here is the code I have which is not returning anything. How can I get a product variation from a product id?
global $product;
global $post;
$post_id = $post->ID;
$parent_id = wp_get_post_parent_id( $post_id );
$brand = $product->get_attribute( 'pa_brand' );
#Rob Gelhausen already answered it as a comment for the question. To get more notice, I'm making it as an answer.
To get Main product ID / Parent product from variation product id, we can use below code.
$variation = wc_get_product($variation_id);
$product = wc_get_product( $variation->get_parent_id() );
To get attribute, we can use below code.
$brand = $product->get_attribute( 'pa_brand' );
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.
I have the following code to echo an announcement when a customer visits a specific product category, but I can't get it to work:
function gvi_announcement() {
if ( is_product_category( 'accessories' ) ) {
echo '<p class="my-alert"><span>This is an accessory</span></p>';
};
}
add_action ('woocommerce_single_product_summary', 'gvi_announcement' , 10);
It works fine without the conditional tag, but I've exhausted every other way to make this work using conditions.
UPDATE:
Thanks for your suggestion #Ibrahim, but I still cannot get it to work. Here's my code now:
function gvi_announcement() {
global $post;
$terms = get_the_terms( $post->ID, 'accessories' );
if ( $terms ) {
echo '<p class="my-alert"><span>This is an accessory</span></p>';
};
}
add_action ('woocommerce_single_product_summary', 'gvi_announcement' , 10);
The condition is_product_category is used to check if the page you are viewing is a product category page or not and the action woocommerce_single_product_summary is used on single product page. So the condition will invariably fail.
In a single product page, you will have to use get_the_terms to get the product categories to which the product belongs to. Something like this :
global $post;
$categories = get_the_terms( $post->ID, 'product_cat' );
You can then apply your conditions.