Always show single variation price in Woocommerce - wordpress

I'm bulding a store on woocommerce and I have variable products and every variation has its unique prices. What i'm trying to do is always show the lowest price, even if no option is selected. And this price should change when the options are selected later (like the one in the bottom after the options, but always displayed).
It's not important if it's show after or before the options.
I try to use this:
add_filter( 'woocommerce_show_variation_price', '__return_true' );
But It's not working in the latest version of woocommerce.
Thanks for your help.

To show the lowest price use below:
add_filter( 'woocommerce_variable_sale_price_html', 'custom_variation_price_format', 10, 2 );
add_filter( 'woocommerce_variable_price_html', 'custom_variation_price_format', 10, 2 );
function custom_variation_price_format( $price, $product ) {
// Main Price
$prices = array( $product->get_variation_price( 'min', true ), $product->get_variation_price( 'max', true ) );
$price = $prices[0] !== $prices[1] ? sprintf( __( 'From: %1$s', 'woocommerce' ), wc_price( $prices[0] ) ) : wc_price( $prices[0] );
// Sale Price
$prices = array( $product->get_variation_regular_price( 'min', true ), $product->get_variation_regular_price( 'max', true ) );
sort( $prices );
$saleprice = $prices[0] !== $prices[1] ? sprintf( __( 'From: %1$s', 'woocommerce' ), wc_price( $prices[0] ) ) : wc_price( $prices[0] );
if ( $price !== $saleprice ) {
$price = '<del>' . $saleprice . $product->get_price_suffix() . '</del> <ins>' . $price . $product->get_price_suffix() . '</ins>';
}
return $price;
}

Please use below function:
add_filter( 'woocommerce_format_sale_price', 'addweb_solu_sale_price', 20, 3 );
function addweb_solu_sale_price( $price, $regular_price, $sale_price ) {
return wc_price( $sale_price );
}

Related

WooCommerce: How to add hook for only one product? By ID?

I want to make a drop down list with quantity selection for only one item.
I'm using this code, but it turns on the dropdown on all products.
How can I use this script for only one product?
<?php
function woocommerce_quantity_input() {
global $product;
$defaults = array(
'input_name' => 'quantity',
'input_value' => '1',
'max_value' => apply_filters( 'woocommerce_quantity_input_max', '', $product ),
'min_value' => apply_filters( 'woocommerce_quantity_input_min', '', $product ),
'step' => apply_filters( 'woocommerce_quantity_input_step', '1', $product ),
'style' => apply_filters( 'woocommerce_quantity_style', 'float:left; margin-right:10px;', $product )
);
if ( ! empty( $defaults['min_value'] ) )
$min = $defaults['min_value'];
else $min = 1;
if ( ! empty( $defaults['max_value'] ) )
$max = $defaults['max_value'];
else $max = 20;
if ( ! empty( $defaults['step'] ) )
$step = $defaults['step'];
else $step = 1;
$options = '';
for ( $count = $min; $count <= $max; $count = $count+$step ) {
$options .= '<option value="' . $count . '">' . $count . '</option>';
}
echo '<div class="quantity_select" style="' . $defaults['style'] . '"><select name="' . esc_attr( $defaults['input_name'] ) . '" title="' . _x( 'Qty', 'Product quantity input tooltip', 'woocommerce' ) . '" class="qty">' . $options . '</select></div>';
}
?>
Wrap everything with an if statement where you check against ID that you have chosen.
function woocommerce_quantity_input() {
global $product;
if($product->get_id() === 14) :
endif;
}

Woocommerce get custom min price of variable products

I am trying to get a custom min price excluding some of the attribute values that contain the words lid and deckel but I am getting a fatal error. Can anyone please help with this?
add_filter( 'woocommerce_variable_price_html', 'bbloomer_variation_price_format', 10, 2 );
function bbloomer_variation_price_format( $price, $product ) {
$args = array(
'post_status' => 'publish',
'post_type' => 'product',
'meta_query' => array(
array(
'key' => 'pa_option',
'value' => array(Deckel),
'compare' => 'NOT LIKE',
)
)
);
}
// The Query
$query = new WP_Query( $args );
// The Loop
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
$min_var_reg_price = $product->get_variation_regular_price( 'min', true );
$min_var_sale_price = $product->get_variation_sale_price( 'min', true );
$max_var_reg_price = $product->get_variation_regular_price( 'max', true );
$max_var_sale_price = $product->get_variation_sale_price( 'max', true );
if ( ! ( $min_var_reg_price == $max_var_reg_price && $min_var_sale_price == $max_var_sale_price ) ) {
if ( $min_var_sale_price < $min_var_reg_price ) {
$price = sprintf( __( 'ab <del>%s</del><ins>%s</ins> %s', 'woocommerce' ), wc_price( $min_var_reg_price ), wc_price( $min_var_sale_price ), $product->get_price_suffix() );
} else {
$price = sprintf( __( 'ab %s %s', 'woocommerce' ), wc_price( $min_var_reg_price ), $product->get_price_suffix() );
}
}
return $price;
}
}

Woocommerce Variable Product Prices prefix

Currently I'm using a this code/plugin to show prefix and lowest price the shop:
function show_only_lowest_prices_in_woocommerce_variable_products_load_plugin_textdomain() {
load_plugin_textdomain( 'show-only-lowest-prices-in-woocommerce-variable-products', FALSE, basename( dirname( __FILE__ ) ) . '/languages/' );
}
add_action( 'plugins_loaded', 'show_only_lowest_prices_in_woocommerce_variable_products_load_plugin_textdomain' );
//Simple products
function wc_wc20_variation_price_format( $price, $product ) {
// Main prices
$prices = array( $product->get_variation_price( 'min', true ), $product->get_variation_price( 'max', true ) );
$price = $prices[0] !== $prices[1] ? sprintf( __( 'От %1$s', 'show-only-lowest-prices-in-woocommerce-variable-products' ), wc_price( $prices[0] ) ) : wc_price( $prices[0] );
// Sale price
$prices = array( $product->get_variation_regular_price( 'min', true ), $product->get_variation_regular_price( 'max', true ) );
sort( $prices );
$saleprice = $prices[0] !== $prices[1] ? sprintf( __( 'От %1$s', 'show-only-lowest-prices-in-woocommerce-variable-products' ), wc_price( $prices[0] ) ) : wc_price( $prices[0] );
if ( $price !== $saleprice ) {
$price = '<del>' . $saleprice . '</del> <ins>' . $price . '</ins>';
}
return $price;
}
add_filter( 'woocommerce_variable_sale_price_html', 'wc_wc20_variation_price_format', 10, 2 );
add_filter( 'woocommerce_variable_price_html', 'wc_wc20_variation_price_format', 10, 2 );
//Grouped products
// Show product prices in WooCommerce 2.0 format
add_filter( 'woocommerce_grouped_price_html', 'wc_wc20_grouped_price_format', 10, 2 );
function wc_wc20_grouped_price_format( $price, $product ) {
$tax_display_mode = get_option( 'woocommerce_tax_display_shop' );
$child_prices = array();
foreach ( $product->get_children() as $child_id ) {
$child_prices[] = get_post_meta( $child_id, '_price', true );
}
$child_prices = array_unique( $child_prices );
$get_price_method = 'get_price_' . $tax_display_mode . 'uding_tax';
if ( ! empty( $child_prices ) ) {
$min_price = min( $child_prices );
$max_price = max( $child_prices );
} else {
$min_price = '';
$max_price = '';
}
if ( $min_price == $max_price ) {
$display_price = wc_price( $product->$get_price_method( 1, $min_price ) );
} else {
$from = wc_price( $product->$get_price_method( 1, $min_price ) );
$display_price = sprintf( __( 'От %1$s', 'show-only-lowest-prices-in-woocommerce-variable-products' ), $from );
}
return $display_price;
}
But I need to change it ot show the both prices (min and max) with prefix like this
From 10 to 25 lv
I tried to edited but in this code i cant get the max price to show to put prefix.
Try the following shorter function that use the dedicated hook for that:
add_filter( 'woocommerce_format_price_range', 'format_price_range_prefix', 20, 3 );
function format_price_range_prefix( $price, $from, $to ) {
$price = sprintf( _x( 'From %1$s to %2$s %3$s', 'Price range: from-to', 'woocommerce' ), is_numeric( $from ) ? wc_price( $from ) : $from, is_numeric( $to ) ? wc_price( $to ) : $to, __('lv', 'woocommerce') );
return $price;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.

WooCommerce Smart Coupon generated from which Item?

I am writing a business extension (pdf printing) for the smart coupons.
Now I need a relation from the generated coupon (of the order) and the order item.
For example, which order item has generated the coupon?
Is there a way to get the order item_id from the coupon?
Is use this code to get the coupons:
$coupons = get_post_meta($order_id, 'sc_coupon_receiver_details', true));
Thank you very much
I have found a solution, but i had to put the code inside "woocommerce-smart-coupons.php" file.
Line 379: Extend the Filter Variables
add_filter( 'generate_smart_coupon_action', array( $this, 'generate_smart_coupon_action' ), 1, 10 );
Line 4783: Extend the Variable with the $item_id
if( $this->is_coupon_amount_pick_from_product_price( array( $coupon_title ) ) ) {
$email_to_credit[$receivers_emails[$coupon->id][0]][] = $coupon->id . ':' . $sc_called_credit_details[$item_id] . ':' . $item_id;
} else {
$email_to_credit[$receivers_emails[$coupon->id][0]][] = $coupon->id . ':' . $coupon->amount . ':' . $item_id;
}
Line 4816: Get the $item_id from the details and refer it to the "generate_smart_coupon" method
foreach ( $email_to_credit[$email_id] as $coupon_credit => $qty ) {
$coupon_details = explode( ':', $coupon_credit );
$coupon_title = get_the_title( $coupon_details[0] );
$coupon = new WC_Coupon( $coupon_title );
$credit_amount = $coupon_details[1];
$item_id = $coupon_details[2];
$message_index = array_search( $email_id, $email[$coupon->id], true );
if ( $message_index !== false && isset( $receivers_messages[$coupon->id][$message_index] ) && !empty( $receivers_messages[$coupon->id][$message_index] ) ) {
$message_from_sender = $receivers_messages[$coupon->id][$message_index];
} else {
$message_from_sender = '';
}
for ( $i = 0; $i < $qty; $i++ ) {
if ( $coupon->type != 'smart_coupon' ) continue; // only process smart_coupon here, rest coupon will be processed by function update_coupon
$this->generate_smart_coupon( $email_id, $credit_amount, $order_id, $coupon, 'smart_coupon', $gift_certificate_receiver_name, $message_from_sender, $gift_certificate_sender_name, $gift_certificate_sender_email, $item_id );
$smart_coupon_codes = array();
}
}
Line 5194: Change the Method and extend the variables
public function generate_smart_coupon( $email, $amount, $order_id = '', $coupon = '', $discount_type = 'smart_coupon', $gift_certificate_receiver_name = '', $message_from_sender = '', $gift_certificate_sender_name = '', $gift_certificate_sender_email = '', $item_id = '' ) {
return apply_filters( 'generate_smart_coupon_action', $email, $amount, $order_id, $coupon, $discount_type, $gift_certificate_receiver_name, $message_from_sender, $gift_certificate_sender_name, $gift_certificate_sender_email, $item_id );
}
Line 5212: Extend the filter method to
public function generate_smart_coupon_action( $email, $amount, $order_id = '', $coupon = '', $discount_type = 'smart_coupon', $gift_certificate_receiver_name = '', $message_from_sender = '', $gift_certificate_sender_name = '', $gift_certificate_sender_email = '', $item_id = '' ) {
Line 5307: Store the $item_id in the post_meta
update_post_meta( $smart_coupon_id, 'apply_before_tax', $apply_before_tax );
update_post_meta( $smart_coupon_id, 'free_shipping', $free_shipping );
update_post_meta( $smart_coupon_id, 'product_categories', $product_categories );
update_post_meta( $smart_coupon_id, 'exclude_product_categories', $exclude_product_categories );
update_post_meta( $smart_coupon_id, 'generated_from_order_id', $order_id );
update_post_meta( $smart_coupon_id, 'generated_from_item_id', $item_id );

filter woocommerce cancel unpaid order

i want to ask how to overwrite this woocommerce function (wp_schedule_single_event and post_status) using filter/action
Plugin file location : /woocommerce/includes/wc-order-functions.php
Original File :
/**
* Cancel all unpaid orders after held duration to prevent stock lock for those products.
*
* #access public
*/
function wc_cancel_unpaid_orders() {
global $wpdb;
$held_duration = get_option( 'woocommerce_hold_stock_minutes' );
if ( $held_duration < 1 || get_option( 'woocommerce_manage_stock' ) != 'yes' )
return;
$date = date( "Y-m-d H:i:s", strtotime( '-' . absint( $held_duration ) . ' MINUTES', current_time( 'timestamp' ) ) );
$unpaid_orders = $wpdb->get_col( $wpdb->prepare( "
SELECT posts.ID
FROM {$wpdb->posts} AS posts
WHERE posts.post_type IN ('" . implode( "','", wc_get_order_types() ) . "')
AND posts.post_status = 'wc-pending'
AND posts.post_modified < %s
", $date ) );
if ( $unpaid_orders ) {
foreach ( $unpaid_orders as $unpaid_order ) {
$order = wc_get_order( $unpaid_order );
if ( apply_filters( 'woocommerce_cancel_unpaid_order', 'checkout' === get_post_meta( $unpaid_order, '_created_via', true ), $order ) ) {
$order->update_status( 'cancelled', __( 'Unpaid order cancelled - time limit reached.', 'woocommerce' ) );
}
}
}
wp_clear_scheduled_hook( 'woocommerce_cancel_unpaid_orders' );
wp_schedule_single_event( time() + ( absint( $held_duration ) * 60 ), 'woocommerce_cancel_unpaid_orders' );
}
add_action( 'woocommerce_cancel_unpaid_orders', 'wc_cancel_unpaid_orders' );
I want to change this variable :
$unpaid_orders = $wpdb->get_col( $wpdb->prepare( "
SELECT posts.ID
FROM {$wpdb->posts} AS posts
WHERE posts.post_type IN ('" . implode( "','", wc_get_order_types() ) . "')
AND posts.post_status = '**wc-on-hold**'
AND posts.post_modified < %s
", $date ) );
and this
**wp_schedule_single_event( time() + 3600 ),** 'woocommerce_cancel_unpaid_orders' );
please help..
Thanks
Azreal
This is absolutely possible - wc_cancel_unpaid_orders is not called directly, rather it's hooked on to the woocommerce_cancel_unpaid_orders action, at line 488 of that file:
add_action( 'woocommerce_cancel_unpaid_orders', 'wc_cancel_unpaid_orders' );
this means that you can unhook THEIR wc_cancel_unpaid_orders, and assign your own. For example, you could add this to your functions.php file:
<?php
remove_action( 'woocommerce_cancel_unpaid_orders', 'wc_cancel_unpaid_orders' );
add_action( 'woocommerce_cancel_unpaid_orders', 'my_custom_wc_cancel_unpaid_orders' );
function my_custom_wc_cancel_unpaid_orders() {
global $wpdb;
$held_duration = get_option( 'woocommerce_hold_stock_minutes' );
if ( $held_duration < 1 || get_option( 'woocommerce_manage_stock' ) != 'yes' )
return;
$date = date( "Y-m-d H:i:s", strtotime( '-' . absint( $held_duration ) . ' MINUTES', current_time( 'timestamp' ) ) );
// write your own code here....
$unpaid_orders = $wpdb->get_col( $wpdb->prepare( "
SELECT posts.ID
FROM {$wpdb->posts} AS posts
WHERE posts.post_type IN ('" . implode( "','", wc_get_order_types() ) . "')
AND posts.post_status = 'wc-pending'
AND posts.post_modified < %s
", $date ) );
if ( $unpaid_orders ) {
foreach ( $unpaid_orders as $unpaid_order ) {
$order = wc_get_order( $unpaid_order );
if ( apply_filters( 'woocommerce_cancel_unpaid_order', 'checkout' === get_post_meta( $unpaid_order, '_created_via', true ), $order ) ) {
$order->update_status( 'cancelled', __( 'Unpaid order cancelled - time limit reached.', 'woocommerce' ) );
}
}
}
wp_clear_scheduled_hook( 'woocommerce_cancel_unpaid_orders' );
// do whatever you want here as well...
wp_schedule_single_event( time() + ( absint( $held_duration ) * 60 ), 'woocommerce_cancel_unpaid_orders' );
}

Resources