Set Product Sale Price Programmatically in Woocommerce 3

Set product sale price programmatically in WooCommerce 3

The hook woocommerce_get_sale_price is deprecated since WooCommerce 3 and replaced by woocommerce_product_get_sale_price.

Also Product displayed prices are cached. When sale price is active, regular price is also active.

Try this instead:

// Generating dynamically the product "regular price"
add_filter( 'woocommerce_product_get_regular_price', 'custom_dynamic_regular_price', 10, 2 );
add_filter( 'woocommerce_product_variation_get_regular_price', 'custom_dynamic_regular_price', 10, 2 );
function custom_dynamic_regular_price( $regular_price, $product ) {
if( empty($regular_price) || $regular_price == 0 )
return $product->get_price();
else
return $regular_price;
}

// Generating dynamically the product "sale price"
add_filter( 'woocommerce_product_get_sale_price', 'custom_dynamic_sale_price', 10, 2 );
add_filter( 'woocommerce_product_variation_get_sale_price', 'custom_dynamic_sale_price', 10, 2 );
function custom_dynamic_sale_price( $sale_price, $product ) {
$rate = 0.8;
if( empty($sale_price) || $sale_price == 0 )
return $product->get_regular_price() * $rate;
else
return $sale_price;
};

// Displayed formatted regular price + sale price
add_filter( 'woocommerce_get_price_html', 'custom_dynamic_sale_price_html', 20, 2 );
function custom_dynamic_sale_price_html( $price_html, $product ) {
if( $product->is_type('variable') ) return $price_html;

$price_html = wc_format_sale_price( wc_get_price_to_display( $product, array( 'price' => $product->get_regular_price() ) ), wc_get_price_to_display( $product, array( 'price' => $product->get_sale_price() ) ) ) . $product->get_price_suffix();

return $price_html;
}

Code goes in function.php file of your active child theme (active theme).

Tested and works on single product, shop, product category and tag archive pages.

The continuation in:

Wrong Woocommerce cart item price after setting programmatically product sale price

Set programmatically product sale price and cart item prices in Woocommerce 3

The missing part to get it work for for cart and checkout pages (and also Orders and email notifications too) is a very simple trick:

add_action( 'woocommerce_before_calculate_totals', 'set_cart_item_sale_price', 20, 1 );
function set_cart_item_sale_price( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;

if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;

// Iterate through each cart item
foreach( $cart->get_cart() as $cart_item ) {
$price = $cart_item['data']->get_sale_price(); // get sale price
$cart_item['data']->set_price( $price ); // Set the sale price

}
}

Code goes in function.php file of your active child theme (active theme).

Tested and works.

So the code just set the product sale price as the product price in cart items and it works.

Set only specific products sale price programmatically in WooCommerce 3

To Set only specific product sale price (the products IDs are defined in the 1st function), try this:

// HERE below in the array set your specific product IDs
function specific_product_ids(){
return array(37, 43, 57); // <=== <=== <=== <=== Your Product IDs
}

// Generating dynamically the product "regular price"
add_filter( 'woocommerce_product_get_regular_price', 'custom_dynamic_regular_price', 10, 2 );
add_filter( 'woocommerce_product_variation_get_regular_price', 'custom_dynamic_regular_price', 10, 2 );
function custom_dynamic_regular_price( $regular_price, $product ) {
if( ( empty($regular_price) || $regular_price == 0 ) && in_array($product->get_id(), specific_product_ids() ) )
return $product->get_price();
else
return $regular_price;
}

// Generating dynamically the product "sale price"
add_filter( 'woocommerce_product_get_sale_price', 'custom_dynamic_sale_price', 10, 2 );
add_filter( 'woocommerce_product_variation_get_sale_price', 'custom_dynamic_sale_price', 10, 2 );
function custom_dynamic_sale_price( $sale_price, $product ) {
$rate = 0.8;
if( ( empty($regular_price) || $regular_price == 0 ) && in_array($product->get_id(), specific_product_ids() ) )
return $product->get_regular_price() * $rate;
else
return $sale_price;
};

// Displayed formatted regular price + sale price
add_filter( 'woocommerce_get_price_html', 'custom_dynamic_sale_price_html', 20, 2 );
function custom_dynamic_sale_price_html( $price_html, $product ) {
if( $product->is_type('variable') ) return $price_html;

if( in_array($product->get_id(), specific_product_ids() ) ) {
$price_html = wc_format_sale_price( wc_get_price_to_display( $product, array( 'price' => $product->get_regular_price() ) ), wc_get_price_to_display( $product, array( 'price' => $product->get_sale_price() ) ) ) . $product->get_price_suffix();
}
return $price_html;
}

Code goes in function.php file of your active child theme (active theme).

The continuation in:

Set only for specific products the generated sale price in woocommerce cart

Woocommerce issue on set programmatically sale price product

You should do it this way:

$product = wc_get_product($product_id);

$price = '40';
$sale_price = array();
$sale_price[0] = '20';
$sale_price[1] = date( 'Y-m-d 00:00:00', strtotime('2020-02-10'));
$sale_price[2] = date( 'Y-m-d 23:59:59', strtotime('2020-02-11'));

if ( !is_wp_error( $product ) ) {
$product->set_price( $price );
$product->set_regular_price( $price );

if( !empty($sale_price) ){
$product->set_price( $sale_price[0] );
$product->set_sale_price( $sale_price[0] );
$product->set_date_on_sale_from( $sale_price[1] );
$product->set_date_on_sale_to( $sale_price[2] );
}

$product->save(); // save the product
}

Set cart item product generated sale price only for specific products in Woocommerce

To get the right generated sale price in cart item for specific product IDs try the following:

// HERE below in the array set your specific product IDs
function specific_product_ids(){
return array(37, 41); // <=== <=== <=== <=== Your Product IDs
}

// Generating dynamically the product "regular price"
add_filter( 'woocommerce_product_get_regular_price', 'custom_dynamic_regular_price', 10, 2 );
add_filter( 'woocommerce_product_variation_get_regular_price', 'custom_dynamic_regular_price', 10, 2 );
function custom_dynamic_regular_price( $regular_price, $product ) {
if( ( empty($regular_price) || $regular_price == 0 ) && in_array($product->get_id(), specific_product_ids() ) )
return $product->get_price();
else
return $regular_price;
}

// Generating dynamically the product "sale price"
add_filter( 'woocommerce_product_get_sale_price', 'custom_dynamic_sale_price', 10, 2 );
add_filter( 'woocommerce_product_variation_get_sale_price', 'custom_dynamic_sale_price', 10, 2 );
function custom_dynamic_sale_price( $sale_price, $product ) {
$rate = 0.8;
if( ( empty($regular_price) || $regular_price == 0 ) && in_array($product->get_id(), specific_product_ids() ) )
return $product->get_regular_price() * $rate;
else
return $sale_price;
};

// Displayed formatted regular price + sale price
add_filter( 'woocommerce_get_price_html', 'custom_dynamic_sale_price_html', 20, 2 );
function custom_dynamic_sale_price_html( $price_html, $product ) {
if( $product->is_type('variable') ) return $price_html;

if( in_array($product->get_id(), specific_product_ids() ) ) {
$price_html = wc_format_sale_price( wc_get_price_to_display( $product, array( 'price' => $product->get_regular_price() ) ), wc_get_price_to_display( $product, array( 'price' => $product->get_sale_price() ) ) ) . $product->get_price_suffix();
}
return $price_html;
}

// Set cart item generated "sale price" for specific product IDs
add_action( 'woocommerce_before_calculate_totals', 'set_cart_item_sale_price', 10, 1 );
function set_cart_item_sale_price( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;

// Iterate through each cart item
foreach( $cart->get_cart() as $cart_item ) {
if( in_array($cart_item['data']->get_id(), specific_product_ids() ) ) {
$price = $cart_item['data']->get_sale_price(); // get sale price
$cart_item['data']->set_price( $price ); // Set the sale price
}
}
}

Code goes in function.php file of your active child theme (active theme). Tested and works.

Set Product sale price conditionally based on custom fields in Woocommerce

To do it that way is not a good idea as:

  • How you will manage the products that have been updated to avoid multiple successive prices updates.
  • Using that way, it will just kill your web site (to many processes)
  • Your products will not be on sale as you update the active price
  • You will not be able to revert back to the initial price when the period is finished.

Also your code is full of mistakes regarding WC_Products in Woocommerce and regarding date calculations. Last thing, when you write code, is better to name variables and functions in english, to comment your code in english too as anybody can understand it.

Instead try the following that will work for simple products, displaying a sale price for the related products when your conditions match (date and custom price):

add_filter( 'woocommerce_product_get_price', 'conditional_product_sale_price', 20, 2 );
add_filter( 'woocommerce_product_get_sale_price', 'conditional_product_sale_price', 20, 2 );
function conditional_product_sale_price( $price, $product ) {
if( is_admin() ) return $price;

$new_price = get_post_meta( $product->get_id(), 'iadi_price', true ); //new sale price
$date = get_post_meta( $product->get_id(), 'iadi_date', true ); // date

if( ! empty($date) && ! empty($new_price) ) {
$date_time = (int) strtotime($date); // Convert date in time
$now_time = (int) strtotime("now"); // Now time in seconds
$one_day = 86400; // One day in seconds

// Calculate the remaining days
$remaining_days = floor( ( $date_time - $now_time ) / $one_day );

if( $remaining_days >= 0 && $remaining_days < 4 )
$price = $new_price;
}
return $price;
}

Code goes in function.php file of your active child theme (or active theme). Tested and works.

Sample Image

Add sale price programmatically to product variations

Update: Prices are also cached in transient wp_options table.

Let say your product ID is 222, you will have that transients meta_keys in wp_options table (for this product ID):

'_transient_timeout_wc_product_children_22'
'_transient_wc_product_children_22'
'_transient_timeout_wc_var_prices_222' // <=== <=== HERE
'_transient_wc_var_prices_222' // <=== <=== <=== HERE

What you can try to do is to update expiration date meta_value to an outdated timestamp, this way:

// Set here your product ID
$main_product_id = 222
$transcient_product_meta_key = '_transient_wc_var_prices_'. $main_product_id;
update_option( $transcient_product_meta_key, strtotime("-12 hours") );
wp_cache_delete ( 'alloptions', 'options' ); // Refresh caches

This way you will force the system to rebuild this outdated cached transient.


Additionally you should try to add/update in your parent product ID (the main product where variation are set) these:

// Set here your Main product ID (for example the last variation ID of your product)
$post_id = 22;

// Set here your variation ID (for example the last variation ID of your product)
$variation_id = 24;

// Here your Regular price
$reg_price = 100;
// Here your Sale price
$sale_price = 50;

update_post_meta($post_id, '_min_variation_price', $sale_price);
update_post_meta($post_id, '_max_variation_price', $sale_price);
update_post_meta($post_id, '_min_variation_regular_price', $reg_price);
update_post_meta($post_id, '_max_variation_regular_price', $reg_price);
update_post_meta($post_id, '_min_variation_sale_price', $sale_price);
update_post_meta($post_id, '_max_variation_sale_price', $sale_price);

update_post_meta($post_id, '_min_price_variation_id', $variation_id);
update_post_meta($post_id, '_max_price_variation_id', $variation_id);
update_post_meta($post_id, '_min_regular_price_variation_id', $variation_id);
update_post_meta($post_id, '_max_regular_price_variation_id', $variation_id);
update_post_meta($post_id, '_min_sale_price_variation_id', $variation_id);
update_post_meta($post_id, '_max_sale_price_variation_id', $variation_id);

// Optionally
wc_delete_product_transients($variation_id);


Related Topics



Leave a reply



Submit