Conditionally customize WooCommerce cart grand total output based on a fee - php

I try to do a quite simple thing but for me i don´t get it to work.
This is from the wc-cart-functions.php
if ( ! empty( $tax_string_array ) ) {
$taxable_address = WC()->customer->get_taxable_address();
$estimated_text = WC()->customer->is_customer_outside_base() && ! WC()->customer->has_calculated_shipping()
? sprintf( ' ' . __( 'estimated for %s', 'woocommerce' ), WC()->countries->estimated_for_prefix( $taxable_address[0] ) . WC()->countries->countries[ $taxable_address[0] ] )
: '';
$value .= '<small class="includes_tax">' . sprintf( __( '(includes %s)', 'woocommerce' ), implode( ', ', $tax_string_array ) . $estimated_text ) . '</small>';
}
}
echo apply_filters( 'woocommerce_cart_totals_order_total_html', $value );
}
The $value should be different if any $fee is applied.
But I only get 0.00 € Value from $fee Variable if I check for.
Could someone please help me with simply apply the Value of the FEE in a Variable and check in a simple if clause like:
if fee is applied ---> 1
else ---> 2
How can I do it?

As you can see you can use the woocommerce_cart_totals_order_total_html filter hook located in that wc-cart-functions.php core code, to alter the output of grand cart total:
add_filter( 'woocommerce_cart_totals_order_total_html', 'custom_cart_totals_order_total_html', 10, 1 );
function custom_cart_totals_order_total_html( $value ) {
// Get the fee cart amount
$fees_total = WC()->cart->fee_total;
// HERE is the condition
if( ! empty($fees_total) && $fees_total != 0 ){
// Change/customize HERE $value (just for test)
$value .= " <small>($fees_total)<small>";
}
// Always return $value
return $value;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and works.
Never overide core files, as this is something prohibited, dangerous and not convenient for many reasons
You will need to customize the code in the condition for $value

Related

After WooCommerce update, custom billing fields are not included any more

After an update of WooCommerce & WordPress a lot of custom settings was overwritten so I have tried to get back the same functionality as in the older version. (using childtheme so why it went missing in the first place I dont get)
Fixed everything except this. On the billing info at checkout several fields went missing, the default company_name I got working again , for some reason it was deactivated in the theme functions.php. However two custom fields are left for IVA number and Organization number.
So I used Checkout Manager for WooCommerce to add custom fields to the billing info.
It works on the check out page and the info end up on the order. But it doesn't show up on the thank you page and more importantly it doesn't show up on the email to customer.
Tried adding this to themes functions.php but no luck.
add_filter( 'woocommerce_email_order_meta_fields', 'custom_woocommerce_email_order_meta_fields', 10, 3 );
function custom_woocommerce_email_order_meta_fields( $fields, $sent_to_admin, $order ) {
$fields['billing_wooccm13'] = array(
'label' => __( 'Moms/IVA' ),
'value' => get_post_meta( $order->id, 'billing_wooccm13', true ),
);
return $fields;
}
And also tried this:
add_action('woocommerce_email_customer_details','add_custom_checkout_field_to_emails_notifications', 25, 4 );
function add_custom_checkout_field_to_emails_notifications( $order, $sent_to_admin, $plain_text, $email ) {
$output = '';
$billing_field_testing = get_post_meta( $order->id, 'billing_wooccm13', true );
if ( !empty($billing_wooccm13) )
$output .= '<div><strong>' . __( "Some text:", "woocommerce" ) . '</strong> <span class="text">' . $billing_wooccm13 . '</span></div>';
echo $output;
}
Any ideas how to go about this?
Since WoooCommerce 3 $order->id is replaced by $order->get_id()… Also there are some other ways.
Be sure that the meta key for your custom field is billing_wooccm13 (as it could be instead starting with an underscore like _billing_wooccm13).
Try the following:
add_filter( 'woocommerce_email_order_meta_fields', 'custom_woocommerce_email_order_meta_fields', 10, 3 );
function custom_woocommerce_email_order_meta_fields( $fields, $sent_to_admin, $order ) {
if ( $value = $order->get_meta( 'billing_wooccm13' ) ) {
$fields['billing_wooccm13'] = array(
'label' => __( 'Moms/IVA' ),
'value' => $value,
);
}
return $fields;
}
Code goes in functions.php file of the active child theme (or active theme). It should work.
Or this too:
add_action('woocommerce_email_customer_details','add_custom_checkout_field_to_emails_notifications', 25, 4 );
function add_custom_checkout_field_to_emails_notifications( $order, $sent_to_admin, $plain_text, $email ) {
if ( $value = $order->get_meta( 'billing_wooccm13' ) ) {
echo '<div><strong>' . __( "Some text:", "woocommerce" ) . '</strong> <span class="text">' . $value . '</span></div>';
}
}
Code goes in functions.php file of the active child theme (or active theme). It should work.
Thank you so much LoicTheAztec.
Both solutions worked but with the first one the text ended up to high up, before invoice address. The second one ended up below , unfortunately with some blank lines before but no biggie. Assume I have to use an email-template to remove those lines. The code I ended up with:
add_action('woocommerce_email_customer_details','add_custom_checkout_field_to_emails_notifications', 25, 4 );
function add_custom_checkout_field_to_emails_notifications( $order, $sent_to_admin, $plain_text, $email ) {
if ( $value = $order->get_meta( '_billing_wooccm11' ) ) {
echo '<div><strong>' . __( "Ert organisationsnummer", "woocommerce" ) . '</strong> <span class="text">' . $value . '</span></div>';
if ( $value = $order->get_meta( '_billing_wooccm13' ) ) {
echo '<div><strong>' . __( "Ert Moms/IVA:", "woocommerce" ) . '</strong> <span class="text">' . $value . '</span></div>';
}
}
}

WooCommerce variable products: Display the min price with a custom text for different prices

I'm setting up a function for Woocommerce that display discount price and the regular price for variable product, this function add a " from to " text before the price range.
The "WooCommerce variable products: keep only "min" price with a custom label" answer thread matches the best with what I am looking for and work like a charm!
But when all variations in a variable product have the same prices, the " start from " should not be displayed.
So I've made a simple try and add below the "if" condition
else {
$price = sprintf( __( '%1$s', 'woocommerce' ), $min_price_html );
return $price;
}
and integrate in the if condition:
$price = sprintf( __( 'À partir de %1$s', 'woocommerce' ), $min_price_html );
return $price;
But it doesn't really work. Some help is appreciated and welcome.
To handle when all variations of a variable product are the same, you need to use array_unique() php function and count() to look if all variation prices are the same.
So the code will be slightly different:
add_filter( 'woocommerce_variable_price_html', 'custom_min_max_variable_price_html', 10, 2 );
function custom_min_max_variable_price_html( $price, $product ) {
$prices = $product->get_variation_prices( true );
$count = (int) count( array_unique( $prices['price'] ));
// When all variations prices are the same
if( $count === 1 )
return $price;
$min_price = current( $prices['price'] );
$min_keys = current(array_keys( $prices['price'] ));
$min_reg_price = $prices['regular_price'][$min_keys];
$min_price_html = wc_price( $min_price ) . $product->get_price_suffix();
// When min price is on sale (Can be removed)
if( $min_reg_price != $min_price ) {
$min_price_reg_html = '<del>' . wc_price( $min_reg_price ) . $product->get_price_suffix() . '</del>';
$min_price_html = $min_price_reg_html .'<ins>' . $min_price_html . '</ins>';
}
$price = sprintf( __( 'À partir de %s', 'woocommerce' ), $min_price_html );
return $price;
}
Code goes in functions.php file of your active child theme (or theme) or also in any plugin file.

Add a delivery time based on custom fields calculations for WooCommerce Flat rate Shipping method

I use code that displays a custom field on the product edit page. This text box shows the cooking time on the single product page.
Here is the code:
// Backend: Display additional product fields
add_action( 'woocommerce_product_options_general_product_data', 'add_time_field_general_product_data' );
function add_time_field_general_product_data() {
// Custom Time Field
woocommerce_wp_text_input( array(
'id' => '_custom_time',
'label' => __( 'Time for cooking', 'woocommerce' ),
));
}
// Backend: Save the data value from the custom fields
add_action( 'woocommerce_admin_process_product_object', 'save_time_custom_fields_values' );
function save_time_custom_fields_values( $product ) {
// Save Custom Time Field
if( isset( $_POST['_custom_time'] ) ) {
$product->update_meta_data( '_custom_time', sanitize_text_field( $_POST['_custom_time'] ) );
}
}
// Display custom fields values under item name in checkout
add_filter( 'woocommerce_checkout_cart_item_quantity', 'custom_time_field_checkout_item_name', 10, 3 );
function custom_time_field_checkout_item_name( $item_qty, $cart_item, $cart_item_key ) {
if( $value4 = $cart_item['data']->get_meta('_custom_time') ) {
$item_qty .= '<br /><div class="my-custom-style"><strong>' . __("Time for cooking", "woocommerce") . ':</strong> ' . $value4 . ' min.</div>';
}
return $item_qty;
}
// Display custom fields values on orders and email notifications
add_filter( 'woocommerce_order_item_name', 'custom_time_field_order_item_name', 10, 2 );
function custom_time_field_order_item_name( $item_name, $item ) {
$product = $item->get_product();
if( $value4 = $product->get_meta('_custom_time') ) {
$item_name .= '<br /><span class="my-custom-style"><strong>' . __("Time for cooking", "woocommerce") . ':</strong> ' . $value4 . ' min.</span>';
}
return $item_name;
}
How can get the following functionality based on this code?
For example, a customer adds several dishes to a cart and checkout order. He sees how much time will be cooking this or that dish.
But when the customer chooses the delivery by courier (Flat Rate), in the same block, the delivery time is shown.
Flat Rate = $10
Delivery time = (the longest cooking time is selected from the order) min. + 45 min.
As I understand it, need to get the data of the custom field '_custom_time' when placing the order. Then, somehow need to get the highest value of this field and add 45 minutes.
I ask for your help! I hope that the answer to this question will be useful to many developers.
Try the following codethat will display a delivery time (calculated from the highest item cooking time value + 45 minutes) when a "flat rate" shipping method is selected on checkout page:
add_action( 'woocommerce_after_shipping_rate', 'action_after_shipping_rate_callback', 10, 2 );
function action_after_shipping_rate_callback( $method, $index ) {
$chosen_shipping_id = WC()->session->get( 'chosen_shipping_methods' )[$index];
if( is_checkout() && $method->method_id === 'flat_rate' && $method->id === $chosen_shipping_id ) {
$extra_time = 45; // Additional time to be added
$data_array = []; // Initializing
// Loop through car items
foreach ( WC()->cart->get_cart() as $cart_item ) {
if( $cooking_time = $cart_item['data']->get_meta('_custom_time') ) {
$data_array[] = (int) $cooking_time;
}
}
if ( sizeof($data_array) ) {
$max_time = (int) max($data_array);
$delivery_time = $max_time + $extra_time;
echo '<br><small style="margin-left:2em;border:solid 1px #ccc;padding:2px 5px;"><strong>' . __("Delivery time", "woocommerce") . '</strong>: ' . $delivery_time . ' min.</small>';
}
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
To enable that in cart page too, remove is_checkout() && from the IF statement.

Remove woocommerce cart (estimated by country) tax text

I'm building a site in wordpress and when I goto cart this keeps popping up
"(estimated for Australia)" right after TAX then gives the value of the tax on the item/s.
I checked out another question and answer on here for the same thing however they had different code to the code I have. I tried a few different things but can't figure it out.
This is the code when I inspect it on google chrome for the cart.
<tr class="tax-total">
<th>Tax <small>(estimated for Australia)</small></th>
<td data-title="Tax">
<span class="woocommerce-Price-amount amount">
<span class="woocommerce-Price-currencySymbol">$</span>109.80</span>
</td>
</tr>
Can someone figure out a filter fix for me?
You can do it by editing WooCommerce cart template file of your theme. I guess that is hardcoded there in cart.php.
Or if you want easier solution, just hide it with CSS.
This code hides "(estimated for {country})" part:
.tax-total th small {display:none!important}
This one hides
.tax-total {display:none!important}
The responsible function for that behavior is wc_cart_totals_order_total_html() … But hopefully you can change that using the following code hooked function:
add_filter( 'woocommerce_cart_totals_order_total_html', 'filtering_cart_totals_order_total_html', 20, 1 );
function filtering_cart_totals_order_total_html( $value ){
$value = '<strong>' . WC()->cart->get_total() . '</strong> ';
// If prices are tax inclusive, show taxes here.
if ( wc_tax_enabled() && WC()->cart->display_prices_including_tax() ) {
$tax_string_array = array();
$cart_tax_totals = WC()->cart->get_tax_totals();
if ( get_option( 'woocommerce_tax_total_display' ) == 'itemized' ) {
foreach ( $cart_tax_totals as $code => $tax ) {
$tax_string_array[] = sprintf( '%s %s', $tax->formatted_amount, $tax->label );
}
} elseif ( ! empty( $cart_tax_totals ) ) {
$tax_string_array[] = sprintf( '%s %s', wc_price( WC()->cart->get_taxes_total( true, true ) ), WC()->countries->tax_or_vat() );
}
if ( ! empty( $tax_string_array ) ) {
$value .= '<small class="includes_tax">' . sprintf( __( '(includes %s)', 'woocommerce' ), implode( ', ', $tax_string_array ) ) . '</small>';
}
}
return $value;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
You will get:
Instead of:
This is an update for Woocommerce 3.2+ slight different, based on this answer: Remove "estimated for {country}" text after tax amount in Woocommerce checkout page

Customizing the product sale flash badge

I am trying to add save amount total on the sale flash badge using this snippet here below but there is something wrong since it is not working.
Any advice would be really appreciated.
// Add save amount on the sale badge.
add_filter( 'woocommerce_sale_flash', 'woocommerce_custom_badge', 10, 2 );
function woocommerce_custom_badge( $price, $product ) {
$saved = wc_price( $product->regular_price - $product->sale_price );
return $price . sprintf( __(' <div class="savings">Save %s</div>', 'woocommerce' ), $saved );
}
Thanks
Added WC 3+ compatibility
You don't have the correct arguments in your filter ($price doesn't exist for example), see here the related source code for woocommerce_sale_flash filter hook to understand better:
/*
* The filter hook woocommerce_sale_flash is located in:
* templates/loop/sale-flash.php and templates/single-product/sale-flash.php
*/
<?php if ( $product->is_on_sale() ) : ?>
<?php echo apply_filters( 'woocommerce_sale_flash', '<span class="onsale">' . esc_html__( 'Sale!', 'woocommerce' ) . '</span>', $post, $product ); ?>
So your working code is going to be something like:
add_filter( 'woocommerce_sale_flash', 'woocommerce_custom_badge', 10, 3 );
function woocommerce_custom_badge( $output_html, $post, $product ) {
// Added compatibility with WC +3
$regular_price = method_exists( $product, 'get_regular_price' ) ? $product->get_regular_price() : $product->regular_price;
$sale_price = method_exists( $product, 'get_sale_price' ) ? $product->get_sale_price() : $product->sale_price;
$saved_price = wc_price( $regular_price - $sale_price );
$output_html = '<span class="onsale">' . esc_html__( 'Save', 'woocommerce' ) . ' ' . $saved_price . '</span>';
return $output_html;
}
The Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and works.

Categories