2
votes

In WooCommerce, for a simple product I can add a "Sale!" badge this way:

add_action( 'woocommerce_before_shop_loop_item_title', function() {
    global $product; 
    $akc = get_post_meta(get_the_ID(), '_sale_price', true);
    if ( $akc > 0 ) {
        echo '<span class="onsale soldout">Sale!</span>';
    }
});

For variable products, it doesn't work…
How to get the value of all variation fields with the 'sale_price'?
So how to make it work for variable products?

Turned out only for everyone variable products by this code:

add_action( 'woocommerce_before_shop_loop_item_title', function($price, $_this) {
    global $product; 

    if($product->product_type == 'variable') {

        $variation_rrp_price = get_sale_price( $variation_price, $product_id );

        $t = get_post_meta(get_the_ID(), $prices_array['_sale_price'], $variation_price); var_dump($t);
        if ( !empty ($t)  ) {
            echo '<span class="onsale soldout">Sale!</span>';
        }
    }
});

UPDATE

So I get custom price by this code:

function get_rrp_price( $price, $product_id ) {
    $rooms2 = get_post_meta( $product_id, 'rooms2', true );
    if ( '' === $rooms2) {
        $rooms2 = 1; 
    }

    $kurs = 1;
    $kurs2 = 10;
    $kurs3 = 100;

    switch ( $rooms2 ) {
        case 1:
            $rrp_price = $price * $kurs2;
            break;
        case 2:
            $rrp_price = $price * $kurs3;
            break;
        default:
            $rrp_price = $price * $kurs;
            break;
    }

    return $rrp_price;
}

function filter_woocommerce_get_price( $price, $_this ) {
    $product_id = $_this->id;
    $rrp_price = get_rrp_price( $price, $product_id );
    update_post_meta( $product_id, 'rrp_price', $rrp_price );

    return $rrp_price;
}

function filter_736700_woocommerce_product_variation_get_price( $price, $_this) {
    if ( 'product_variation' === $_this->post_type ) {
        $data            = (object) $_this->get_data();
        $variation_price = $data->price;
        $product_id       = $data->parent_id;
        $variation_rrp_price = get_rrp_price( $variation_price, $product_id );
        $price = $variation_rrp_price;
    }

    return $price;
}

add_filter( 'woocommerce_product_variation_get_price', 'filter_736700_woocommerce_product_variation_get_price', 10, 2);

function filter_736700_woocommerce_variation_prices( $prices_array, $product, $include_taxes ) {


    $product_id = $product->id;

    foreach ( $prices_array['price'] as $key => $price ) {
        $prices_array['price'][ $key ] = get_rrp_price( $price, $product_id );
    }

    foreach ( $prices_array['regular_price'] as $key => $price ) {
        $prices_array['price'][ $key ] = get_rrp_price( $price, $product_id );
    }

    foreach ( $prices_array['sale_price'] as $key => $price ) {
        $prices_array['price'][ $key ] = get_rrp_price( $price, $product_id );
    }

    return $prices_array;
}

add_filter( 'woocommerce_variation_prices', 'filter_736700_woocommerce_variation_prices', 10, 3 );


function filter_738363_woocommerce_product_variation_get_regular_price( $price, $_this ) {
    if ( 'product_variation' === $_this->post_type ) {
        $data            = (object) $_this->get_data();
        $variation_price = $data->regular_price;
        $product_id       = $data->parent_id;
        $variation_rrp_price = get_rrp_price( $variation_price, $product_id );
        update_post_meta( $product_id, $data->name . ' - regular' , $variation_rrp_price );
        $price = $variation_rrp_price;
    }

    return $price;
}

add_filter( 'woocommerce_product_variation_get_regular_price', 'filter_738363_woocommerce_product_variation_get_regular_price', 10, 2);

But after this "Sale!" not assigned anymore (only for variable products)

1

1 Answers

1
votes

To make your code work for all products types, you should use WC_Product is_on_sale() method. This way you will only have one function for all product types this way:

add_action( 'woocommerce_before_shop_loop_item_title', 'custom_shop_loop_on_sale_badge' );
function custom_shop_loop_on_sale_badge(){
    global $product;

    if($product->is_on_sale())
        echo '<span class="onsale soldout">Sale!</span>';
}

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

Tested and works.


Update (related to the update in your question).

To get something functional with the your sale calculated price, try this instead:

// Prices calculation common function
function get_rrp_price( $price, $product_id ) {
    $rooms2 = get_post_meta( $product_id, 'rooms2', true );
    if ( '' === $rooms2 )
        $rooms2 = 1;

    if ( $rooms2 == 1 )
        $price *= 10;
    elseif ( $rooms2 == 2 )
        $price *= 100;

    return $price;
}

// Simple products prices
add_filter( 'woocommerce_product_get_price', 'custom_simple_product_price', 20, 2 );
add_filter( 'woocommerce_product_get_regular_price', 'custom_simple_product_price', 20, 2 );
function custom_simple_product_price( $price, $product ) {
    $price = get_rrp_price( $price, $product->get_id() );
    update_post_meta( $product->get_id(), 'rrp_price', $price );

    return $price;
}

// Variable products: Selected variation prices
add_filter( 'woocommerce_variation_prices_price', 'custom_variations_prices', 10, 3 );
add_filter( 'woocommerce_variation_prices_regular_price', 'custom_variations_prices', 10, 3 );
add_filter( 'woocommerce_variation_prices_sale_price', 'custom_variations_prices', 10, 3 );
function custom_variations_prices( $price, $variation, $product ) {
    if (  $variation->is_type('variation') ) {
        $product_id = $product->get_id();

        $price = get_rrp_price( $price, $product_id );
    }
    return $price;
}

// Variable products: Min/Max variations prices
add_filter( 'woocommerce_product_variation_get_regular_price', 'custom_variations_get_prices' , 10, 2 );
add_filter( 'woocommerce_product_variation_get_sale_price', 'custom_variations_get_prices' , 10, 2 );
add_filter( 'woocommerce_product_variation_get_price', 'custom_variations_get_prices', 10, 2 );
function custom_variations_get_prices( $price, $variation ) {

    if (  $variation->is_type('variation') ) {
        $parent_product_id = $variation->get_parent_id();
        $rrp_price = get_rrp_price( $price, $product_id );

        // Adding/Updating "rrp regular price" custom field
        $regular_price = $variation->get_regular_price();
        if( $regular_price == $price )
            update_post_meta( $product_id, $variation->get_name() . ' - regular' , $rrp_price );

        $price = $rrp_price;
    }
    return $price;
}

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

Tested and works.