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

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.

Related

How to display product attributes in WooCommerce and quantity in the back end all products page?

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.

How to apply custom subtotal on our woocommerce and make affect cart total

I'm used to working with wordpress and of course woocommerce for ecommerce sites,
So, for the past week, I have been facing a problem which is :
there is a category of products which, once added to the cart, should lead to a precise calculation in order to give the total. So, on each product and according to the quantity of the product, we do a calculation in order to find the subtotal. I made the formula, I manage to do the calculation from the price and the quantity but I can't apply it to the subtotal and the total cart. That why I need your help. Thanks in advance,
Take a look of what I've tried to implement. See my code in the on the next line
add_action('woocommerce_before_cart', 'action_before_cart');
function action_before_cart() {
$categories = ['circonscription'];
$has_category = false;
// Loop cart items
foreach ( WC()->cart->get_cart() as $cart_item ) {
$_product = wc_get_product( $cart_item['data']->get_id() );
//The category exist
if ( has_term( $categories, 'product_cat', $cart_item['product_id'] ) ) {
$has_category = true;
break;
}
}
// What next when there are product in cart that are from that category?
if ( $has_category ) {
/* Display Cart Items Content */
$_quantity = $cart_item['quantity'];
$_coefficient = ($_quantity/2) + 0.5;
$_price = $cart_item['data']->get_price();
$subtotal = round($_price * $_coefficient);
}
}

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.

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.

Woocommerce adding custom product count to products only in specific category and in specific page

I have caught onto some of the logic but battling with how to implement:
display my custom product count only on products in a specific product category
also display product count only on a specific custom WP page (which I used the product_category shortcode)
My code in functions.php is as follows and it does add the $top50_counter value before the product thumbnail but it is doing it site-wide, hence why I need to narrow it down as per my points above.
/* ADD NUMBERING TO TOP 50 LIST PRODUCTS */
add_action( 'woocommerce_before_shop_loop_item_title', 'custom_before_shop_loop_item', 5);
$top50_counter=1;
function custom_before_shop_loop_item() {
global $top50_counter;
echo '<h1>'.$top50_counter.'</h1>';
$top50_counter++;
}
I'm assuming I have to use the $terms = get_the_terms function in there somehow?
You need to use is_page and has_term conditionals. Try re-factoring the code to the following.
/* ADD NUMBERING TO TOP 50 LIST PRODUCTS */
add_action( 'woocommerce_before_shop_loop_item_title', 'custom_before_shop_loop_item', 5);
$top50_counter=1;
function custom_before_shop_loop_item() {
global $top50_counter;
/* Replace 42 with the actual page ID and "your-category" with the actual category slug */
if( ( is_page( 42 ) ) || ( has_term( 'your-category' , 'product_cat') ) ):
echo '<h1>'.$top50_counter.'</h1>';
$top50_counter++;
endif;
}
P.S: untested code.
Try this. Use corresponding category name and custom wp page slug in the following function.
function custom_before_shop_loop_item(){
global $post, $term, $top50_counter;
$id = $post->ID;
$taxonomy = 'product_cat';
$terms = get_the_terms( $id, $taxonomy );
if( ($terms[0]->name == 'Category Name') || ($post->post_name == 'custom-wp-page-slug') ){
echo '<h1>'.$top50_counter.'</h1>';
}
$top50_counter++;
}
Hope this helps.

Resources