Display and style prices with and without tax in Woocommerce - php

I have a question about styling a php script and change the way it shows but i cant get it work well
I use this script to display prices including and excluding TAX in Woocommerce.
I would like to display the price excluding TAX first, it needs to be styled with the class amountex (the $price value also)
After the price excluding Tax i want to show the price including TAX on a new row, this must be styled with the class amount
I made a lot of changes but the price is shown without styling and i can't get the price without tax showing first.
Advice is very welcome
This is the part i had done some changes
if ( isset($price_incl_tax_html) && isset($price_excl_tax_html) ) {
$price_html = '<span class="amount">' . $price_incl_tax_html . ' Incl. BTW </span><br>';
$price_html .= '<span class="amountex">' . $price_excl_tax_html . ' Excl. BTW </span><br>';
$price_html .= $product->get_price_suffix();
}
}
return $price_html;
This is the full code
add_filter('woocommerce_get_price_html', 'display_prices_incl_and_excl_taxes', 100, 2 );
function display_prices_incl_and_excl_taxes( $price_html, $product ) {
global $woocommerce_loop; {
// For simple products and products variations
if( $product->is_type('simple') || $product->is_type('variation') ) {
// On sale products
if( $product->is_on_sale() ) {
$regular_price_incl_tax = wc_get_price_including_tax( $product, array( 'price' => $product->get_regular_price() ) );
$price_incl_tax_html = wc_format_sale_price( $regular_price_incl_tax, wc_get_price_including_tax( $product ) );
$regular_price_excl_tax = wc_get_price_excluding_tax( $product, array( 'price' => $product->get_regular_price() ) );
$price_excl_tax_html = wc_format_sale_price( $regular_price_excl_tax, wc_get_price_excluding_tax( $product ) );
}
// Not on sale
else {
$price_incl_tax_html = wc_price( wc_get_price_including_tax( $product ) );
$price_excl_tax_html = wc_price( wc_get_price_excluding_tax( $product ) );
}
}
// variable pproducts
elseif( $product->is_type('variable') ) {
$prices = $product->get_variation_prices( true );
if ( ! empty( $prices['price'] ) ) {
$act_keys = array_keys($prices['price']);
$reg_keys = array_keys($prices['regular_price']);
$min_price_incl_tax = wc_get_price_including_tax( wc_get_product(reset($act_keys)));
$max_price_incl_tax = wc_get_price_including_tax( wc_get_product(end($act_keys)));
$min_price_excl_tax = wc_get_price_excluding_tax( wc_get_product(reset($act_keys)));
$max_price_excl_tax = wc_get_price_excluding_tax( wc_get_product(end($act_keys)));
$min_reg_price_jncl_tax = wc_get_price_including_tax( wc_get_product(reset($reg_keys)));
$max_reg_price_incl_tax = wc_get_price_including_tax( wc_get_product(end($reg_keys)));
$min_reg_price_excl_tax = wc_get_price_excluding_tax( wc_get_product(reset($reg_keys)));
$max_reg_price_excl_tax = wc_get_price_excluding_tax( wc_get_product(end($reg_keys)));
if ( $min_price_excl_tax !== $max_price_excl_tax ) {
$price_incl_tax_html = wc_format_price_range( $min_price_incl_tax, $max_reg_price_incl_tax );
$price_excl_tax_html = wc_format_price_range( $min_price_excl_tax, $max_reg_price_excl_tax );
}
elseif ( $product->is_on_sale() && $min_reg_price_excl_tax === $max_reg_price_excl_tax ) {
$price_incl_tax_html = wc_format_sale_price( wc_price( $max_reg_price_incl_tax ), wc_price( $min_price_incl_tax ) );
$price_excl_tax_html = wc_format_sale_price( wc_price( $max_reg_price_excl_tax ), wc_price( $min_price_excl_tax ) );
}
else {
$price_incl_tax_html = wc_price( $min_price_incl_tax );
$price_excl_tax_html = wc_price( $min_price_excl_tax );
}
}
}
if ( isset($price_incl_tax_html) && isset($price_excl_tax_html) ) {
$price_html = '<span class="amount">' . $price_incl_tax_html . ' Incl. BTW </span><br>';
$price_html .= '<span class="amountex">' . $price_excl_tax_html . ' Excl. BTW </span><br>';
$price_html .= $product->get_price_suffix();
}
}
return $price_html;
}

edit. The order of displaying the tax is resolved by swapping these 2 rules :)
The only thing i can't get working for now is the styling of $price_excl_tax_html in the first rule. My class seemed to be overruled by the woocommerce class: woocommerce-Price-amount
if ( isset($price_incl_tax_html) && isset($price_excl_tax_html) ) {
$price_html = '<bdi><span class="amountex">' . $price_excl_tax_html . ' Excl. BTW </span><bdi><br>';
$price_html .= '<bdi><span class="amount">' . $price_incl_tax_html . ' Incl. BTW </span><bdi><br>';
$price_html .= $product->get_price_suffix();
}
}
return $price_html;

Related

Price not changing showing Static

I tried to change the price a single way, like WAS, NOW
it's working, But on the single product page, it's not working showing all variation prices line by line and when I change the variation price does not change(showing static).
snapshot here- https://prnt.sc/Tdg19atUacwq
code here below
add_filter( 'woocommerce_get_price_html', 'revent_custom_variable_product_price_customs' );
function revent_custom_variable_product_price_customs() {
global $product;
$id = $product->get_id();
echo '<p class="price">';
if( $product->is_type( 'variable' )){
// Regular Price
$v_prices = array($product->get_variation_regular_price( 'min', true ),$product->get_variation_regular_price( 'max', true ) );
sort( $v_prices );
$v_price = sprintf(__(' %1$s', 'woocommerce'), wc_price( $v_prices[1] ) ) ;
$v_saleprice = $v_prices[0]===$v_prices[1] ? sprintf(__('<span class="revent_custom_sale_price"> %1$s </span>','woocommerce') , wc_price( $v_prices[0] ) ) : wc_price( $v_prices[0] );
if ($product->is_on_sale() ) {
$v_price = ' <del><span class="revent_custom_regular_price">Was: ' .$v_price.'</span>' . $product->get_price_suffix() . '</del> <ins><span class="revent_custom_sale_price">Now: '.$v_saleprice.'</span>'.$product->get_price_suffix() . '</ins></p>';
}else{
$v_price = sprintf(__('<span class="revent_custom_regular_price">Now: %1$s</span></p>', 'woocommerce'), wc_price( $v_prices[0] ) ) ;
}
echo $v_price;
}else{
$regular_price = $product->get_regular_price();
$sale_price = $product->get_sale_price();
// Regular Price
if ($product->is_on_sale() ) {
$v_price = ' <del><span class="revent_custom_regular_price"><span class="woocommerce-Price-amount amount">Was: ' .$regular_price.'<span class="woocommerce-Price-currencySymbol">د.إ</span></span></span> </del> <ins><span class="revent_custom_sale_price">Now: '.$sale_price.'</span><span class="woocommerce-Price-currencySymbol">د.إ</span></ins></p>';
}else{
$v_price= sprintf(__('<span class="revent_custom_regular_price">Now: %1$s</span></p>','woocommerce'), wc_price($regular_price) );
}
echo $v_price;
}
}
Please help me to fix this.
As per my understanding you are using sales option in woo commerce, for that you need to use
$product->get_variation_sale_price( 'max', true )
It will get the sale price and you can display it as you want.

WooCommerce: Product price suffix based on product category

On my WooCommerce website I have fabric set to be sold per half meter, with the code below which is all working fine:
function conditional_price_suffix( $price, $product ) {
$product_id = $product->is_type('variation') ? $product->get_parent_id() : $product->get_id();
$product_categories = array('half-metre');
if( has_product_categories( $product_categories, $product_id ) )
$price .= ' ' . __('per ½ metre');
return $price;
}
However, how do I manipulate the code to add another option of per "quarter-metre" and output "per ¼ meter" as the suffix.
Any help?
could be something like
function conditional_price_suffix( $price, $product ) {
$product_id = $product->is_type('variation') ? $product->get_parent_id() : $product->get_id();
$product_categories = array('half-metre');
$product_categories2 = array('quarter-metre');
if( has_product_categories( $product_categories, $product_id ) ) {
$price .= ' ' . __('per ½ metre');
} elseif( has_product_categories( $product_categories2, $product_id ) ) {
$price .= ' ' . __('per ¼ metre');
}
return $price;
}

How to add custom text before price in Woocommerce

How can I add a custom text using a snippet to my Woocoomerce price in the category view and product page?
function sv_change_product_html( $price_html, $product ) {
$unit_price = get_post_meta( $product->id, 'unit_price', true );
if ( ! empty( $unit_price ) ) {
$price_html = '<span class="amount">' . wc_price( $unit_price ) . ' / Stück</span>';
}
return $price_html;
}
add_filter( 'woocommerce_get_price_html', 'sv_change_product_html', 10, 2 );
add_filter("wc_price","addtext",10,4);
function addtext($return, $price, $args, $unformatted_price){
if(is_product_category() || is_shop() || is_product()){
$return = 'like Preis:'.$return;
}
return $return;
}

Display a custom product price in woocommerce archive page and for upsells/related products

Is there a way to enable a backend field in the WordPress dashboard to show a custom price per product in the archive page and for upsells/related products but leave the price in product-summary?
Example: Product A has a price of 10€ but I would like to show "from 6€/kg" instead.
The easiest way would be to use a custom field which is overriding the woocommerce_template_loop_price but this code doesn't work but I don't understand why.
add_action('woocommerce_template_loop_price', 'shopprice_change', 10, 2);
function shopprice_change ($price, $product) {
global $post, $blog_id;
$post_id = $post->ID;
$price = get_post_meta($post_id, 'shoppricechange', true);
return $price;
wp_reset_query();
}
UPDATE
I've found a solution for changing the price in archive page without changing on single product page:
function cw_change_product_html( $price_html, $product ) {
$unit_price = get_post_meta( $product->id, 'shoppricechange', true );
if (is_product()) return $price_html;
if ( ! empty( $unit_price ) ) {
$price_html = '<span class="amount">' . wc_price( $unit_price ) . '</span>';
}
return $price_html;
}
add_filter( 'woocommerce_get_price_html', 'cw_change_product_html', 10, 2 );
Problem: Actually the upsells and related products should change as well on the single product page. But with if (is_product()) return $price_html; its excluding them as well. Who helps solving this will get the bounty. Thank you!
But with if (is_product()) return $price_html; its excluding them as
well.
Using this in place of the is_product() works well for me:
is_single( $product->get_id() )
And you shouldn't call $product->id directly. Instead, use $product->get_id().
Here's the full code I used:
function cw_change_product_html( $price_html, $product ) {
if ( is_single( $product->get_id() ) )
return $price_html;
$unit_price = get_post_meta( $product->get_id(), 'shoppricechange', true );
if ( ! empty( $unit_price ) ) {
$price_html = '<span class="amount">' . wc_price( $unit_price ) . '</span>';
}
return $price_html;
}
add_filter( 'woocommerce_get_price_html', 'cw_change_product_html', 10, 2 );
woocommerce_template_loop_price is not a action it's a function
Use the code below
function cw_change_product_html( $price_html, $product ) {
$unit_price = get_post_meta( $product->id, 'shoppricechange', true );
$returnedSignleProdctP =false;
$trace = debug_backtrace();
$callstack = (array) $trace;
foreach ($callstack as $key => $value) {
if(isset($value['function']) && $value['function'] == 'woocommerce_output_related_products' ){
if ( ! empty( $unit_price ) ) {
$price_html = '<span class="amount">' . wc_price( $unit_price ) . '</span>';
}
}
if(isset($value['function']) && $value['function'] == 'woocommerce_template_single_price' ){
$price_html = $price_html;
}
if(isset($value['function']) && $value['function'] == 'woocommerce_template_loop_price' ){
if ( ! empty( $unit_price ) ) {
$price_html = '<span class="amount">' . wc_price( $unit_price ) . '</span>';
}
}
}
return $price_html;
}
add_filter( 'woocommerce_get_price_html', 'cw_change_product_html', 10, 2 );
Maybe this plugin can help, Woocommerce Extra Price Fields (Source: https://wordpress.org/plugins/woocommerce-extra-price-fields/)

Sort a Woocommerce product variations custom output by their price

Bellow I have a custom shortcode function based on this answer code that displays a block of product data for both Simple products and each variation of a Variable product. The output of the variation blocks seems to be ordered by the ID of the variation itself.
For example, this is a screenshot of the frontend output:
Which you can see matches the order of the variation IDs (from smallest to largest) screenshot:
What I would like is to sort the variations by their prices instead (NOT by their IDs) from lowest to highest. Any help is appreciated.
This is the current customized code that I have:
add_shortcode("price_variation_table", "fs_custom_available_variations_table");
function fs_custom_available_variations_table( $atts ) {
global $post;
// Attributes
$atts = shortcode_atts(
array(
'id' => $post->ID
),
$atts, 'price_variation_table'
);
if( is_admin() ) return; // Only on front end
$product = wc_get_product($atts['id']); // Get the WC_Product Object
$output = '<div class="fs-product-data-wrapper">';
// Variable products
if( $product->is_type('variable'))
{
// Get available variations in the variable product
$available_variations = $product->get_available_variations();
if( count($available_variations) > 0 ){
foreach( $available_variations as $variation )
$output .= fs_format_product_data_output( $variation['variation_id'] );
}
}
// Simple products
elseif( $product->is_type('simple'))
{
$output .= fs_format_product_data_output( $product->get_id() );
}
else return; // Exit
return $output .= '</div>'; // return always for a shortcode
}
// Utility funtion: getting and formtting product data
function fs_format_product_data_output( $the_id ){
$empty = __( '<em>(empty)</em>', 'woocommerce' );
// Get an instance of the WC_Product_Variation object
$product = wc_get_product( $the_id );
// Only wc_get_price_to_display() respect if product is to be displayed with or without including taxes
$price = wc_price( wc_get_price_to_display( $product, array( 'price' => $product->get_regular_price() ) ) );
$sale_price = wc_get_price_to_display( $product, array( 'price' => $product->get_sale_price() ) );
$sale_price = ! empty( $sale_price ) ? wc_price($sale_price) : $empty;
// can use this class is there is no sale price set
if ( ! $product->is_on_sale() ) {
$no_sale_price = ' no-sale-price';
}
$size = $product->get_attribute( 'pa_size' );
$size = ! empty( $size ) ? get_term_by( 'slug', $size, 'pa_size' )->name : $empty;
$stock_qty = $product->get_stock_quantity();
$stock_qty = ! empty( $stock_qty ) ? $stock_qty : '0';
if ( $stock_qty <= 0 ) {
$stock_status = 'stock-sold-out';
}
else {
$stock_status = 'stock-available';
}
$output = '
<ul class="'. $stock_status .'">
<li class="fs-data-price">'.$price.' ea.</li>
<li class="fs-data-size">Size: '.$size.'</li>
<li class="fs-data-sale'. $no_sale_price .'">'.$sale_price.' ea. Preferred customer price</li>
<li class="fs-data-stock">Quantity in Stock: '.$stock_qty.'</li>
<li class="fs-data-notice">Quantities change quickly!</li>
</ul>';
return $output;
}
Try the following lightly changed code, where each displayed variations will be sorted by regular price (low to high):
add_shortcode("price_variation_table", "custom_available_variations_table");
function custom_available_variations_table( $atts ) {
global $post;
// Attributes
$atts = shortcode_atts(
array(
'id' => $post->ID
),
$atts, 'price_variation_table'
);
if( is_admin() ) return; // Only on front end
$product = wc_get_product($atts['id']); // Get the WC_Product Object
$output = '<div class="fs-product-data-wrapper">';
// Variable products
if( $product->is_type('variable'))
{
// Get available variations in the variable product
$available_variations = $product->get_available_variations();
if( count($available_variations) > 0 ){
$variations_ids = array();
// First loop - set variations Ids in an array with regular prices
foreach( $available_variations as $variation ){
$product = wc_get_product( $variation['variation_id'] );
$price = wc_price( wc_get_price_to_display( $product, array( 'price' => $product->get_regular_price() ) ) );
$variations_ids[$variation['variation_id']] = $price;
}
// Sorting variation Ids using prices from lower to highest
natsort($variations_ids);
// 2nd Loop - Display formatted variation data
foreach( array_keys($variations_ids) as $variations_id ){
$output .= format_product_data_output( $variations_id );
}
}
}
// Simple products
elseif( $product->is_type('simple'))
{
$output .= format_product_data_output( $product->get_id() );
}
else return; // Exit
return $output .= '</div>'; // return always for a shortcode
}
// Utility funtion: getting and formatting product data
function format_product_data_output( $the_id ){
$empty = __( '<em>(empty)</em>', 'woocommerce' );
// Get an instance of the WC_Product_Variation object
$product = wc_get_product( $the_id );
// Only wc_get_price_to_display() respect if product is to be displayed with or without including taxes
$price = wc_price( wc_get_price_to_display( $product, array( 'price' => $product->get_regular_price() ) ) );
$sale_price = wc_get_price_to_display( $product, array( 'price' => $product->get_sale_price() ) );
$sale_price = ! empty( $sale_price ) ? wc_price($sale_price) : $empty;
$size = $product->get_attribute( 'pa_size' );
$size = ! empty( $size ) ? get_term_by( 'slug', $size, 'pa_size' )->name : $empty;
$no_sale_price = ! $product->is_on_sale() ? ' no-sale-price' : '';
$size = $product->get_attribute( 'pa_size' );
$size = ! empty( $size ) ? get_term_by( 'slug', $size, 'pa_size' )->name : $empty;
$stock_qty = $product->get_stock_quantity();
$stock_qty = ! empty( $stock_qty ) ? $stock_qty : '0';
$stock_status = $stock_qty <= 0 ? 'stock-sold-out' : 'stock-available';
$output = '
<ul class="'. $stock_status .'">
<li class="fs-data-price">'.$price.' ea.</li>
<li class="fs-data-size">Size: '.$size.'</li>
<li class="fs-data-sale'. $no_sale_price .'">'.$sale_price.' ea. Preferred customer price</li>
<li class="fs-data-stock">Quantity in Stock: '.$stock_qty.'</li>
<li class="fs-data-notice">Quantities change quickly!</li>
</ul>';
return $output;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.

Categories