Last active
July 6, 2023 10:42
-
-
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)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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' ); | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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!