On our woocommerce site we have a price range that is from the lowest price to the highest price.$2 - $600 for example. Then we have a 10% discount on the whole range so it will then display as strikethrough the whole range $2 - $600 and display $1.80 - $540 for example.
When I now select a single variation it displays $540 - $0 for example. But I only want the $540 to display and the - $0 must be removed. I will show a screenshot example.
I have tried various filters but the actual output of a single variation price have not changed.
add_filter( 'woocommerce_get_price_html', 'custom_price_format', 10, 2 );
add_filter( 'woocommerce_variable_price_html', 'custom_price_format', 10, 2 );
function custom_price_format( $price, $product ) {
// 1. Variable products
if( $product->is_type('variable') ){
// Searching for the default variation
$default_attributes = $product->get_default_attributes();
// Loop through available variations
foreach($product->get_available_variations() as $variation){
$found = true; // Initializing
// Loop through variation attributes
foreach( $variation['attributes'] as $key => $value ){
$taxonomy = str_replace( 'attribute_', '', $key );
// Searching for a matching variation as default
if( isset($default_attributes[$taxonomy]) && $default_attributes[$taxonomy] != $value ){
$found = false;
break;
}
}
// When it's found we set it and we stop the main loop
if( $found ) {
$default_variaton = $variation;
break;
} // If not we continue
else {
continue;
}
}
// Get the default variation prices or if not set the variable product min prices
$regular_price = $product->get_variation_regular_price( 'min', true );
$sale_price = $product->get_variation_sale_price( 'min', true );
$regular_price_max = $product->get_variation_regular_price('max', true);
$sale_price_max = $product->get_variation_sale_price( 'max', true );
}
// 2. Other products types
else {
$regular_price = $product->get_regular_price();
$sale_price = $product->get_sale_price();
}
// Formatting the price
if ( $regular_price !== $sale_price && $product->is_on_sale()) {
// Percentage calculation and text
$percentage = round( ( $regular_price - $sale_price ) / $regular_price * 100 ).'%';
$txt = " - ";
$price = '<del>'.wc_price($regular_price).'</del><ins>'.$txt.'</ins><del>'.wc_price($regular_price_max).'</del><br><ins>'.wc_price($sale_price).$txt.wc_price($sale_price_max).'</ins>';
}
return $price;
}
add_filter( 'woocommerce_show_variation_price', 'filter_show_variation_price', 10, 3 );
function filter_show_variation_price( $condition, $product, $variation ){
if( $variation->get_price() === "" ) return false;
else return true;
}
That is my filters I currently have on my functions.php file.
Here is a screenshot of my problem:
I want the range variation price to show with the sale price and regular price with a strikethrough but only a single price to show as soon as you select a variation.
add_filter( 'woocommerce_get_price_html', 'custom_price_format', 10, 2 );
add_filter( 'woocommerce_variable_price_html', 'custom_price_format', 10, 2 );
function custom_price_format( $price, $product ) {
// 1. Variable products
if( $product->is_type('variable') ){
// Searching for the default variation
$default_attributes = $product->get_default_attributes();
// Loop through available variations
foreach($product->get_available_variations() as $variation){
$found = true; // Initializing
// Loop through variation attributes
foreach( $variation['attributes'] as $key => $value ){
$taxonomy = str_replace( 'attribute_', '', $key );
// Searching for a matching variation as default
if( isset($default_attributes[$taxonomy]) && $default_attributes[$taxonomy] != $value ){
$found = false;
break;
}
}
// When it's found we set it and we stop the main loop
if( $found ) {
$default_variaton = $variation;
break;
} // If not we continue
else {
continue;
}
}
// Get the default variation prices or if not set the variable product min prices
$regular_price = $product->get_variation_regular_price( 'min', true );
$sale_price = $product->get_variation_sale_price( 'min', true );
$regular_price_max = $product->get_variation_regular_price('max', true);
$sale_price_max = $product->get_variation_sale_price( 'max', true );
}
// 2. Other products types
else {
$regular_price = $product->get_regular_price();
$sale_price = $product->get_sale_price();
}
// Formatting the price
if ( $regular_price !== $sale_price && $product->is_on_sale()) {
// Percentage calculation and text
$percentage = round( ( $regular_price - $sale_price ) / $regular_price * 100 ).'%';
$txt = " - ";
//Check if Sale Price Exists
if(wc_price($sale_price_max) !== 0.00){
$price = '<del>'.wc_price($regular_price).'</del><ins>'.$txt.'</ins><del>'.wc_price($regular_price_max).'</del><br><ins>'.wc_price($sale_price).$txt.wc_price($sale_price_max).'</ins>';
} else {
//else return price without second sale price
$price = '<del>'.wc_price($regular_price).'</del><ins>'.$txt.'</ins><del>'.wc_price($regular_price_max).'</del><br><ins>'.wc_price($sale_price).'</ins>';
}
}
return $price;
}
Please try the above code and let me know.
Related
I've added this code which works for empty price fields, but I also need it to work for values of 0.
add_filter('woocommerce_empty_price_html', 'custom_call_for_price');
function custom_call_for_price() {
return 'Enquire';
}
Here is the complete way to do it for BOTH empty and zero displayed prices, so this code replace also your actual code (to be removed).
It handle simple, variable and variation displayed prices (for BOTH empty and zero displayed prices):
// Variable and simple product displayed prices
add_filter( 'woocommerce_get_price_html', 'empty_and_zero_price_html', 20, 2 );
function empty_and_zero_price_html( $price, $product ) {
$empty_price = __('Enquire', 'woocommerce');
if( $product->is_type('variable') )
{
$prices = $product->get_variation_prices( true );
if ( empty( $prices['price'] ) ) {
return $empty_price; // <=== HERE below for empty price
} else {
$min_price = current( $prices['price'] );
$max_price = end( $prices['price'] );
if ( $min_price === $max_price && 0 == $min_price ) {
return $empty_price; // <=== HERE for zero price
}
elseif ( $min_price !== $max_price && 0 == $min_price ) {
return wc_price( $max_price );
}
}
}
elseif( $product->is_type('simple') )
{
if ( '' === $product->get_price() || 0 == $product->get_price() ) {
return $empty_price; // <=== HERE for empty and zero prices
}
}
return $price;
}
// Product Variation displayed prices
add_filter( 'woocommerce_available_variation', 'empty_and_zero_variation_prices_html', 10, 3);
function empty_and_zero_variation_prices_html( $data, $product, $variation ) {
if( '' === $variation->get_price() || 0 == $variation->get_price() )
$data['price_html'] = __('Enquire', 'woocommerce'); // <=== HERE for empty and zero prices
return $data;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
I am trying display a custom price range for my variable products.
I managed to insert a price range with regular (min and max) prices and sale (min and max) prices.
Here is my code attempt:
add_filter( 'woocommerce_get_price_html', 'custom_price_format', 10, 2 );
add_filter( 'woocommerce_variable_price_html', 'custom_price_format', 10, 2 );
function custom_price_format( $price, $product ) {
// Main Price
$regular_priceMin = $product->is_type('variable') ? $product->get_variation_regular_price( 'min', true ) : $product->get_regular_price();
$regular_priceMax = $product->is_type('variable') ? $product->get_variation_regular_price( 'max', true ) : $product->get_regular_price();
$sale_priceMin = $product->is_type('variable') ? $product->get_variation_sale_price( 'min', true ) : $product->get_sale_price();
$sale_priceMax = $product->is_type('variable') ? $product->get_variation_sale_price( 'max', true ) : $product->get_sale_price();
if ( $regular_priceMin !== $sale_priceMin && $product->is_on_sale()) {
$price = '<p class="teste"><del>' . wc_price($regular_priceMin). 'a' . wc_price($regular_priceMax) . '</del></p> <ins>' . wc_price($sale_priceMin) . '</ins>';
}
return $price;
}
However some sale prices have the same values and the formatting is not correct.
It creates 3 lines:
One for the minimum price value,
another for the letter "a"
and another for the maximum price value.
How can I organize this correctly?
The tag <del> tag is not in the same line.
How can solved this? What I am doing wrong?
Would do you not use standart $product->get_price_html() that is available for all type products?
Try the following revisited code that will work everywhere on product loops except on single products for variable products custom price range:
// For variable product
add_filter( 'woocommerce_variable_price_html', 'variable_prices_range_formatted', 100, 2 );
function variable_prices_range_formatted( $price, $product ){
global $woocommerce_loop;
// Not on single products
if ( ( is_product() && isset($woocommerce_loop['name']) && ! empty($woocommerce_loop['name']) ) || ! is_product() )
{
// For on sale variable product
if ( $product->is_on_sale() )
{
$regular_price_min = $product->get_variation_regular_price( 'min', true );
$regular_price_max = $product->get_variation_regular_price( 'max', true );
$active_price_min = $product->get_variation_price( 'min', true );
$active_price_max = $product->get_variation_price( 'max', true );
if ( $regular_price_min !== $active_price_min || $regular_price_max !== $active_price_max )
{
// Regular price range (for <del> html tag)
if( $regular_price_min !== $regular_price_max ) {
$regular_price_del_html = sprintf( '<del>%s a %s</del>', wc_price($regular_price_min), wc_price($regular_price_max) );
} else {
$regular_price_del_html = sprintf( '<del>%s</del>', wc_price($regular_price_min) );
}
// Active price range (for <ins> html tag)
if( $active_price_min !== $active_price_max ) {
$active_price_ins_html = sprintf( '<ins>%s a %s</ins>', wc_price($active_price_min), wc_price($active_price_max) );
} else {
$active_price_ins_html = sprintf( '<ins>%s</ins>', wc_price($active_price_min) );
}
$price = sprintf( '<p class="teste">%s %s</p>', $regular_price_del_html, $active_price_ins_html );
}
}
}
return $price;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
A variable on sale product price:
I use some code that shows the discounted price on Woocommerce archive pages for on sale products:
add_filter( 'woocommerce_get_price_html', 'display_savings_as_price_and_percentage', 10, 2 );
//add_filter( 'woocommerce_variable_price_html','display_savings_as_price_and_percentage', 10, 2 );
function display_savings_as_price_and_percentage( $price, $product ) {
if( $product->is_on_sale() && ! is_admin() && ! $product->is_type('variable')){
$product_price = (float) $product->get_regular_price();
$sale_price = (float) $product->get_price();
$save_price = wc_price( $product_price - $sale_price );
$save_percentage = round( 100 - ( $sale_price / $product_price * 100 ), 1 ) . '%';
$price .= sprintf( __('<p class="saved-on-sale">Save: %s (%s)</p>', 'woocommerce' ), $save_price, $save_percentage );
}
return $price;
}
Discount on archives pages:
But it doesn't work for variable products and I've tried with every hook I've found but I cannot figure out how to make it work variable products.
(I commented out the hook for the variable in my code).
This is what I would like to have:
If the variable has a price span of 10-20 with a discount making it 10-15 I would like for that to be displayed like this with the default price striked through:
$40 - $50
$20 - $30
Save: $20 (40-50%)
How can I replace the on sale product price for variable products with saving amount and percentages?
The following code will handle both simple and variable on sale products:
add_filter( 'woocommerce_get_price_html', 'display_savings_price_and_percentages', 20, 2 );
function display_savings_price_and_percentages( $price_html, $product ) {
// Only on frontend and for on sale products
if( is_admin() || ! $product->is_on_sale() )
return $price_html;
// Only on archives pages
if( ! ( is_shop() || is_product_category() || is_product_tag() ) )
return $price_html;
// Variable product type
if( $product->is_type('variable')){
$percentages = $savings = array(); // Initializing
// Get all variation prices
$prices = $product->get_variation_prices();
// Loop through variation prices
foreach( $prices['price'] as $key => $price ){
// Only on sale variations
if( $prices['regular_price'][$key] !== $price ){
// Calculate and set in the array the percentage for each variation on sale
$percentages[] = round(100 - ($prices['sale_price'][$key] / $prices['regular_price'][$key] * 100), 1 );
// Calculate and set in the array the savings for each variation on sale
$savings[] = $prices['regular_price'][$key] - $prices['sale_price'][$key];
}
}
$save_price = wc_price( max($savings) );
if( min($percentages) !== max($percentages) ){
$save_percentage = min($percentages) . '-' . max($percentages) . '%';
$save_text = __( 'Save up to:', 'woocommerce' );
} else {
$save_percentage = max($percentages) . '%';
$save_text = __( 'Save:', 'woocommerce' );
}
}
// All other product types
else {
$regular_price = $product->get_regular_price();
$sale_price = $product->get_sale_price();
$save_price = wc_price( $regular_price - $sale_price );
$save_percentage = round( 100 - ( $sale_price / $regular_price * 100 ), 1 ) . '%';
$save_text = __( 'Save:', 'woocommerce' );
}
return '<p class="saved-on-sale">' . sprintf( '%s %s (%s)', $save_text, $save_price, $save_percentage ) . '</p>';
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
I've added this code which works for empty price fields, but I also need it to work for values of 0.
add_filter('woocommerce_empty_price_html', 'custom_call_for_price');
function custom_call_for_price() {
return 'Enquire';
}
Here is the complete way to do it for BOTH empty and zero displayed prices, so this code replace also your actual code (to be removed).
It handle simple, variable and variation displayed prices (for BOTH empty and zero displayed prices):
// Variable and simple product displayed prices
add_filter( 'woocommerce_get_price_html', 'empty_and_zero_price_html', 20, 2 );
function empty_and_zero_price_html( $price, $product ) {
$empty_price = __('Enquire', 'woocommerce');
if( $product->is_type('variable') )
{
$prices = $product->get_variation_prices( true );
if ( empty( $prices['price'] ) ) {
return $empty_price; // <=== HERE below for empty price
} else {
$min_price = current( $prices['price'] );
$max_price = end( $prices['price'] );
if ( $min_price === $max_price && 0 == $min_price ) {
return $empty_price; // <=== HERE for zero price
}
elseif ( $min_price !== $max_price && 0 == $min_price ) {
return wc_price( $max_price );
}
}
}
elseif( $product->is_type('simple') )
{
if ( '' === $product->get_price() || 0 == $product->get_price() ) {
return $empty_price; // <=== HERE for empty and zero prices
}
}
return $price;
}
// Product Variation displayed prices
add_filter( 'woocommerce_available_variation', 'empty_and_zero_variation_prices_html', 10, 3);
function empty_and_zero_variation_prices_html( $data, $product, $variation ) {
if( '' === $variation->get_price() || 0 == $variation->get_price() )
$data['price_html'] = __('Enquire', 'woocommerce'); // <=== HERE for empty and zero prices
return $data;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
I have very simple woocommerce code to show product price after a deduction. Please see the below code.
add_action( 'woocommerce_get_price_html' , 'rp_get_price' );
function rp_get_price($price){
$rp_percentage = 10;
$regular_price = get_post_meta( get_the_ID(), '_price', true );
$rp_discount = $regular_price * $rp_percentage / 100;
$price = $regular_price - $rp_discount;
return $price;
}
add_filter( 'woocommerce_variable_sale_price_html', 'wc_wc20_variation_price_format', 10, 2 );
add_filter( 'woocommerce_variable_price_html', 'wc_wc20_variation_price_format', 10, 2 );
function wc_wc20_variation_price_format( $price, $product ) {
$rp_percentage = 10;
$min_price = $product->get_variation_price( 'min', true );
$max_price = $product->get_variation_price( 'max', true );
$rp_min_discount = $min_price*10/100;
$rp_min_price = $min_price - $rp_min_discount;
$rp_max_discount = $max_price*10/100;
$rp_max_price = $max_price - $rp_max_discount;
if ($min_price != $max_price)
{
$price = $rp_min_price . '-' . $rp_max_price;
}
else
{
$price = $rp_min_price;
}
return $price;
}
For single product the price shows correctly. for variation product with same minimum and maximum rate shows correctly but my problem is for variation price low price to high price it is not showing like '20 -30' (it only shows the minimum price)
Could you please help me to sort it out.
Try out this code :
add_action( 'woocommerce_get_price_html' , 'rp_get_price' );
function rp_get_price($price){
global $product;
//get the sale price of the product whether it be simple, grouped or variable
$sale_price = get_post_meta( get_the_ID(), '_price', true);
//get the regular price of the product, but of a simple product
$regular_price = get_post_meta( get_the_ID(), '_regular_price', true);
$rp_percentage = 10;
if( $product->is_type( 'simple' ) ):
$rp_discount = $regular_price * $rp_percentage / 100;
$price = $regular_price - $rp_discount;
else:
if ($regular_price == ""){
$min_price = $product->get_variation_price( 'min', true );
$max_price = $product->get_variation_price( 'max', true );
$rp_min_discount = $min_price*10/100;
$rp_min_price = $min_price - $rp_min_discount;
$rp_max_discount = $max_price*10/100;
$rp_max_price = $max_price - $rp_max_discount;
if ($min_price != $max_price)
{
$price = $rp_min_price . '-' . $rp_max_price;
}
else
{
$price = $rp_min_price;
}
}
endif;
return $price;
}
EDITED:
add_action( 'woocommerce_get_price_html' , 'rp_get_price' );
function rp_get_price($price){
global $product;
//get the sale price of the product whether it be simple, grouped or variable
$sale_price = get_post_meta( get_the_ID(), '_price', true);
//get the regular price of the product, but of a simple product
$regular_price = get_post_meta( get_the_ID(), '_regular_price', true);
$rp_percentage = 10;
if ($regular_price == ""){
$currency = get_woocommerce_currency_symbol();
$min_price = $product->min_variation_price;
$max_price = $product->max_variation_price;
$rp_min_discount = $min_price*10/100;
$rp_min_price = $min_price - $rp_min_discount;
$rp_max_discount = $max_price*10/100;
$rp_max_price = $max_price - $rp_max_discount;
if ($min_price != $max_price)
{
$price = $rp_min_price . '-' . $rp_max_price;
}
else
{
$price = $rp_min_price;
}
}
else{
$rp_discount = $regular_price * $rp_percentage / 100;
$price = $regular_price - $rp_discount;
}
return $price;
}
Try new edited code as old one was not up to the mark.