Woocommerce return price not showing properly - php

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.

Related

Calculate tax in onsale badge amount

I would need your help, if there is someone willing to help me, I would greatly appreciate it. In my website prices include a 10.0000% tax.
I want to calculate in my onsale badge my tax from woocommerce which is of 10.0000%. This is my code:
Badge: onsale badge from site
add_filter( 'woocommerce_sale_flash', 'add_amount_to_sale_badge', 20, 3 );
function add_amount_to_sale_badge( $html, $post, $product ) {
if( $product->is_type('variable')){
$amount_off = array();
$prices = $product->get_variation_prices();
foreach( $prices['price'] as $key => $price ){
if( $prices['regular_price'][$key] !== $price ){
$amount_off[] = $prices['regular_price'][$key] - $prices['sale_price'][$key];
}
}
$amount_off_s = "up to -$" . round(max($amount_off));
} else {
$regular_price = (float) $product->get_regular_price();
$sale_price = (float) $product->get_sale_price();
$amount_off_s = "-$" . ($regular_price - $sale_price);
}
return '<span class="onsale">' . esc_html__( 'Save', 'woocommerce' ) . ' ' . $amount_off_s . '</span>';
}
my knowledge in php is limited and for this reason I am unable to solve this problem.

Woocommerce change product price programmatically

I want to show the price of the products to the user with a little change.
These changes are actually some calculations that are applied to the price of each product.
Everything works fine. And it shows the calculated price correctly.
The only problem is that the price is wrong through the WooCommerce api.
In WooCommerce, we have a price field for each product.
My code applies a calculation on that price And finally it shows to the user.
But when I call the product through rest-api, it only shows the price entered in the product price field. Not the calculation price.
This is my code:
add_filter('woocommerce_get_price_html', 'didoprice_override_price', 200, 2);
function didoprice_override_price($price='', $product){
$gram = $product->get_weight();
if ( empty( $gram ) ){
$gram = 100;
}
$all_tax_rates = [];
$tax_classes = WC_Tax::get_tax_classes(); // Retrieve all tax classes.
if ( !in_array( '', $tax_classes ) ) { // Make sure "Standard rate" (empty class name) is present.
array_unshift( $tax_classes, '' );
}
foreach ( $tax_classes as $tax_class ) { // For each tax class, get all rates.
$taxes = WC_Tax::get_rates_for_tax_class( $tax_class );
$all_tax_rates = array_merge( $all_tax_rates, $taxes );
}
$tax_rate = $all_tax_rates[0]->tax_rate/100;
$reg_price = '';
if($product->is_type( 'variable' ))
{
$variations = $product->get_children();
$reg_prices = array();
$sale_prices = array();
foreach ($variations as $value) {
$single_variation=new WC_Product_Variation($value);
array_push($reg_prices, $single_variation->get_regular_price());
array_push($sale_prices, $single_variation->get_price());
}
sort($reg_prices);
sort($sale_prices);
$min_price = $reg_prices[0];
$min_price = didoprice_calculation( $min_price, $gram );
$min_price += $tax_rate*$min_price;
$max_price = $reg_prices[count($reg_prices)-1];
$max_price = didoprice_calculation( $max_price, $gram );
$max_price += $tax_rate*$max_price;
if($min_price == $max_price)
{
$reg_price = wc_price($min_price);
}
else
{
$reg_price = wc_format_price_range($min_price, $max_price);
}
$min_price = $sale_prices[0];
$min_price = didoprice_calculation( $min_price, $gram );
$min_price += $tax_rate*$min_price;
$max_price = $sale_prices[count($sale_prices)-1];
$max_price = didoprice_calculation( $max_price, $gram );
$max_price += $tax_rate*$max_price;
if($min_price == $max_price)
{
$sale_price = wc_price($min_price);
}
else
{
$sale_price = wc_format_price_range($min_price, $max_price);
}
$suffix = $product->get_price_suffix($price);
return wc_format_sale_price($reg_price, $sale_price).$suffix;
}
$orig_price = wc_get_price_excluding_tax( $product );
$regular = wc_get_price_excluding_tax( $product, array( 'price' => $product->get_regular_price() ) );
$sale = wc_get_price_excluding_tax( $product, array( 'price' => $product->get_sale_price() ) );
$regular = didoprice_calculation( $regular, $gram );
$regular += $regular*$tax_rate;
$sale = didoprice_calculation( $sale, $gram );
$sale += $sale *$tax_rate;
if ( $product->is_on_sale() ) {
return wc_format_sale_price( $regular, $sale );
}else{
return wc_price( $regular );
}
// return $price;
}
/**
* override cart items price based on the Formula.
*/
add_action( 'woocommerce_before_calculate_totals', 'didoprice_alter_price_cart', 9999 );
function didoprice_alter_price_cart( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) return;
// IF CUSTOMER NOT LOGGED IN, DONT APPLY DISCOUNT
// if ( ! wc_current_user_has_role( 'customer' ) ) return;
// LOOP THROUGH CART ITEMS & APPLY 20% DISCOUNT
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$product = $cart_item['data'];
$price = $product->get_price();
$gram = $product->get_weight();
if ( empty( $gram ) ){
$gram = 100;
}
$price = didoprice_calculation( $price, $gram );
$cart_item['data']->set_price( $price );
}
}
You're using the hook woocommerce_get_price_html, which is to adjust the outputted HTML for the price.
The correct hook(s) to use would be either woocommerce_get_price_excluding_tax or woocommerce_get_price_including_tax, depending on what you prefer.
So the first line would be, for example:
add_filter('woocommerce_get_price_including_tax', 'didoprice_override_price', 200, 2);
You can find more information about the hooks within WooCommerce in the documentation.

WooCommerce sort by percentage discount amount in woo shortcode

I want to make custom sort option and use it into shortcode.
i want to make custom sort by percent discont for sale products.
Here is my code:
add_action('woocommerce_process_product_meta', 'woo_calc_my_discount');
function woo_calc_my_discount( $product_id ) {
$_product = wc_get_product( $product_id );
$regular = (float) $_product->get_regular_price();
$sale = (float) $_product->get_sale_price();
$discount = round( 100 - ( $sale / $regular * 100), 2 );
update_post_meta( $product_id, '_discount_amount', $discount );
}
add_action('woocommerce_product_quick_edit_save', 'sv_woo_calc_my_discount_quickedit');
function sv_woo_calc_my_discount_quickedit( $post ) {
$_product = wc_get_product( $post );
$regular = (float) $_product->get_regular_price();
$sale = (float) $_product->get_sale_price();
$discount = round( 100 - ( $sale / $regular * 100), 2 );
update_post_meta( $_product->get_id(), '_discount_amount', $discount );
}
add_filter( 'woocommerce_get_catalog_ordering_args', 'misha_custom_product_sorting' );
function misha_custom_product_sorting( $args ) {
// Discount percentage: High to Low
if( isset( $_GET['orderby'] ) && '_discount_amount' === $_GET['orderby'] ) {
$args['meta_key'] = '_discount_amount';
$args['order'] = 'desc';
}
return $args;
}
add_filter( 'woocommerce_catalog_orderby', 'misha_add_custom_sorting_options' );
function misha_add_custom_sorting_options( $options ){
$options['_discount_amount'] = 'Sale: High to Low';
return $options;
}
I use also:
[products on_sale="true" orderby="_discount_amount"]
but seems it's without success for now..
Any ideas? thanks!

Woocommerce single variation price displaying not as intended

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.

Replace on sale product price with saving amount and percentages in Woocommerce

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.

Categories