Skip to content

Instantly share code, notes, and snippets.

@Jany-M
Last active July 6, 2023 10:42
Show Gist options
  • Save Jany-M/06c03a92e669ace79364cd9131a435ee to your computer and use it in GitHub Desktop.
Save Jany-M/06c03a92e669ace79364cd9131a435ee to your computer and use it in GitHub Desktop.
[WP][WooCommerce] Calculate sale price dynamically / programmatically based on taxonomy term custom field % (also works for Facebook Catalog feed)
<?php
// The discount is set through a term meta 'sale_value' associated to the product, so that product regular or sales prices never need to changed manually
// The script also assumes the use of ACF, through get_field()
// BACKEND (Product list, FB feed)
function custom_dynamic_sale_price( $sale_price, $product ) {
$id = $product->get_id();
$tax = get_the_terms($id,'product_cat');
$regular_price = wc_format_decimal( $product->get_price() );
$discount_total = 0;
foreach ($tax as $term){
$disc_single = get_field('sale_value', $term->taxonomy . '_' . $term->term_id);
$discount_total += $disc_single;
}
if(!is_null($discount_total) && $discount_total !== 0 && $discount_total !== '') {
$new_price = wc_format_decimal($regular_price - ($regular_price / 100 * $discount_total));
//update_post_meta( $id, 'fb_product_price', $new_price); // Only if using Facebook for WooCommerce plugin
return $new_price;
} elseif(is_null($discount_total) || $discount_total == 0 || $discount_total == '') {
//update_post_meta( $id, 'fb_product_price', ''); // Only if using Facebook for WooCommerce plugin
return '';
} else {
//update_post_meta( $id, 'fb_product_price', $sale_price); // Only if using Facebook for WooCommerce plugin
return $sale_price;
}
}
if(is_admin()) {
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_html( $price_html, $product ) {
if( $product->is_type('variable') ) return $price_html;
if($product->get_sale_price() == '') 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;
}
if(is_admin()) {
add_filter( 'woocommerce_get_price_html', 'custom_dynamic_sale_price_html', 20, 2 );
}
// FRONTEND (Shop / Archive / Single)
function custom_change_product_price_display( $price ) {
$id = get_the_ID();
$tax = get_the_terms($id,'product_cat');
$discount_total = 0;
foreach ($tax as $term){
$disc_single = get_field('sale_value', $term->taxonomy . '_' . $term->term_id);
$discount_total += $disc_single;
}
if (!is_null($discount_total) && $discount_total !== 0){
$symbol = get_woocommerce_currency_symbol();
$new_price = preg_replace("/[^0-9,]/", "",$price);
$price = '<del>'.$price.'</del> '.wc_format_decimal(($new_price - ($new_price / 100 * $discount_total))).$symbol;
}
return $price;
}
if(!is_admin()) {
add_filter( 'woocommerce_get_price_html', 'custom_change_product_price_display', 999 );
}
add_filter( 'woocommerce_cart_item_price', 'custom_change_product_price_display', 999 );
// FRONTEND (Cart)
function prefix_add_discount_line( $cart ) {
$items = $cart->get_cart();
$disc_cart_total = 0;
foreach ($items as $item){
$item_id = $item['product_id'];
$discount_total = 0;
$tax = get_the_terms($item_id,'product_cat');
foreach ($tax as $term){
$disc_single = get_field('sale_value', $term->taxonomy . '_' . $term->term_id);
$discount_total += $disc_single;
}
if ($discount_total !== 0){
$current_price = $item['line_total'];
$discount_price = $current_price / 100 * $discount_total;
$disc_cart_total +=$discount_price;
}
}
if ($disc_cart_total !== 0){
$cart->add_fee( __( 'Sale', TEXT_DOMAIN ) , -$disc_cart_total );
}
}
add_action( 'woocommerce_cart_calculate_fees', 'prefix_add_discount_line' );
?>
@MicPass
Copy link

MicPass commented Jul 6, 2023

Very interesting!
Do you think there's a way to alter just the Sale Price sent to Facebook based on what is set from "Woo Discount Rules" Plugin (which is not saved and associated to product in the db)?

At the moment I'm using this filter but it overrides directly the regular price sent to facebook:

function odb_facebook_sync_price_update($price, $facebook_price, $product){
if ( ! $facebook_price && $product instanceof \WC_Product ) {
$price = apply_filters('advanced_woo_discount_rules_get_product_discount_price_from_custom_price', $price, $product, 1, $price, 'discounted_price', true, true);
}
return $price;
}
add_filter( 'wc_facebook_product_price', 'odb_facebook_sync_price_update', 10, 3 );

I would like to keep the regular price as is and override just the sale price which is actually not set in the product by the discount rules plugin.

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment