WooCommerce - Customize "Total" text on Thankyou order received page - php

In WooCommerce I have a problem on my thankyou page (once the customer has placed his order). I have tryed to change it manualy but the problem is that the code is generated in an unknown file which I can't find.
<tfoot>
<?php
foreach ( $order->get_order_item_totals() as $key => $total ) {
?>
<tr>
<th scope="row"><?php echo $total['label']; ?></th>
<td><?php echo $total['value']; ?></td>
</tr>
<?php
}
?>
</tfoot>
This code give me all information in my order like a coupon the shipping etc.
On this picture I would like to replace the text in the black bordered rectangle (Here 'Gesamt:' mean "Total" by "Total inkl. vat"
Also I want to remove the red bordered rectangle block: "Inkl. 19% MwSt.".
Is it possible?
How can I do it?
Thanks.

Here the extract of the end on woocommerce/order/order-details.php template that is loaded in thank you page.
To override the 'Total' text displayed by foreach loop with the method get_order_item_totals() applied to the $order object (that generate an array of key/values), you have to add a condition for each language used by your web site. Here in my code you got english and german.
In your active theme go to woocommerce > order, and open/edit
order-details.php template file.
Replace the end of your template with this:
<tfoot>
<?php
$order_item_totals = $order->get_order_item_totals();
$count_lines = count($order_item_totals) - 1;
$count = 0;
foreach ( $order_item_totals as $key => $total ) {
$count++;
// The condition to replace "Total:" text in english and german
if( $total['label'] == 'Total:' || $total['label'] == 'Gesamt:')
$total_label = __( 'Total inkl. vat:', 'woocommerce' );
else
$total_label = $total['label'];
// End of the condition
?>
<tr>
<th scope="row"><?php echo $total_label; // <== == Replaced $total['label'] by $total_label ?></th>
<td><?php echo $total['value']; ?></td>
</tr>
<?php
// this should avoid displaying last line
if( $count >= $count_lines ) break;
}
?>
</tfoot>
</table>
<?php do_action( 'woocommerce_order_details_after_order_table', $order ); ?>
<?php if ( $show_customer_details ) : ?>
<?php wc_get_template( 'order/order-details-customer.php', array( 'order' => $order ) ); ?>
<?php endif; ?>
Now you can save, you are done…
This code is tested and works.
References:
Template Structure + Overriding Templates via a Theme
Woocommerce template checkout > review-order.php
Customize the text "Total" in WooCommerce checkout page

Hey I think this would work for you
Just make sure that inkl. 19%.... is correctly written.
foreach ( $order->get_order_item_totals() as $key => $total ) {
?>
<tr>
<th scope="row"><?php echo ($total['label']=='inkl. 19% Mwst.'?'Vat Only':$total['label']); ?></th>
<td><?php echo $total['value']; ?></td>
</tr>
<?php
}

Related

How to display the discount for each item in the invoice?

Hi there so I'm pretty new to php in woocommerce. I need to try and get the discount to show for each product in the invoice and was wondering if anyone could help with this.
So far I have been able to figure out this part and my only problem is getting the discount to show up.
<?php
$items = $this->get_order_items();
$discount = $order->get_discount_to_display();
if( sizeof( $items ) > 0 ) : foreach( $items as $item_id => $item ) : ?>
<tr class="<?php echo apply_filters( 'wpo_wcpdf_item_row_class', $item_id, $this->type, $this->order, $item_id ); ?>">
<td class="quantity"><?php echo $item['quantity']; ?></td>
<td class="discount"><?php echo $discount ?></td>
<td class="price"><?php echo $item['order_price']; ?></td>
i m using your code in my invoice template it shows me 0$ discount for every order??

How to localize Woocommerce weight

So, in settings of Woocommerce weight and other metric system in Russian language.
But in product page for example it still in English (g - gramm).
I have copied file in to my theme: /wp-content/themes/my_theme/woocommerce/single-product/product-attributes.php
What should I do in this file to display right Weight metric system in Russian language? This code did not help:
<td class="product_weight"><?php echo wc_format_localized_decimal( $product->get_weight() ) . ' ' . __(esc_attr( get_option( 'woocommerce_weight_unit' ) ), 'woocommerce'); ?></td>
Code of /product-attributes.php:
defined( 'ABSPATH' ) || exit;
if ( ! $product_attributes ) {
return;
}
?>
<table class="woocommerce-product-attributes shop_attributes">
<?php foreach ( $product_attributes as $product_attribute_key => $product_attribute ) : ?>
<tr class="woocommerce-product-attributes-item woocommerce-product-attributes-item--<?php echo esc_attr( $product_attribute_key ); ?>">
<th class="woocommerce-product-attributes-item__label"><?php echo wp_kses_post( $product_attribute['label'] ); ?></th>
<td class="woocommerce-product-attributes-item__value"><?php echo wp_kses_post( $product_attribute['value'] ); ?></td>
</tr>
<?php endforeach; ?>
</table>
Thank you!
Done, just posted this code in theme's functions.php
function localize_weight_units($weight) {
return str_replace('g', 'г', $weight);
}
add_filter('woocommerce_format_weight', 'localize_weight_units');

Get unformatted order totals amounts in WooCommerce PDF Invoices & Packing Slips template

I have made a copy of the Simple invoice(this is the default), and created a new one, the problem I have is that I can't cast the string value to float. Here is the code:
<?php foreach( $this->get_woocommerce_totals() as $key => $total ) : ?>
<tr class="<?php echo $key; ?>">
<td class="no-borders"></td>
<th class="description"><?php echo $total['label']; ?></th>
<td class="price"><span class="totals-price"><?php echo $total['value']; ?></span></td>
</tr>
<?php endforeach; ?>
the $total['value']; displays the price in a string format.
I tried using (float)$total['label'] and floatval($total['label']) to cast it but did not work, It gives back a value of 0.
You can't really get that, but you can use the $key to target the the total line type and you can use $this->order that is the instance of the WC_Order object with any WC_Order method.
To get the gran total unformatted amount (including taxes) you will use $this->order->get_total()…
Some of the available $keys are:
cart_subtotal
discount (if there is coupons applied)
shipping
fee_1234 (if there is a fee and where 1234 is the item ID… they can be many different)
tax (depending on how taxes are displayed on your settings)
payment_method (it seems hidden by some CSS)
order_total
So in this code:
<?php
// The line totals data array (in a variable)
$wc_totals = $this->get_woocommerce_totals();
// Some order unformatted amounts
$order_total = $this->order->get_total();
$order_total_tax = $this->order->get_total_tax();
## Manipulating amounts (example) ##
// Order Total (rounding total amount)
$wc_totals['order_total']['value'] = strip_tags( wc_price( round( $order_total ) ) );
?>
<?php foreach( $wc_totals as $key => $total ) : ?>
<tr class="<?php echo $key; ?>">
<td class="no-borders"></td>
<th class="description"><?php echo $total['label']; ?></th>
<td class="price"><span class="totals-price"><?php echo $total['value']; ?></span></td>
</tr>
<?php endforeach; ?>
Tested and works.
You can also add additional totals lines or remove them with unset() and the correct key…
To add a line after the shipping total line (example):
<?php
// The line totals data array (in a variable)
$wc_totals = $this->get_woocommerce_totals();
$wc_new_totals = []; // Initialising
foreach ( $wc_totals as $key => $total ) {
$wc_new_totals[$key] = $total;
if ( $key === 'shipping' ) {
$wc_new_totals['shipping_avg'] = [
'label' => __( "Shipping average" ),
'value' => __( "15 days" ),
];
}
}
?>
<?php foreach( $wc_new_totals as $key => $total ) : ?>
<tr class="<?php echo $key; ?>">
<td class="no-borders"></td>
<th class="description"><?php echo $total['label']; ?></th>
<td class="price"><span class="totals-price"><?php echo $total['value']; ?></span></td>
</tr>
<?php endforeach; ?>

Grouped product parent vs Grouped product child in woocommerce

I am using PDF packing plugin (WooCommerce PDF Invoices) to create packing slips after order is placed. And Product Bundles plugin for bundled products.
In those PDFs I want to differentiate between the container of a bundled product and its child.
Currently I am using this from Product Bundles:
if(wc_pb_is_bundle_container_cart_item($item) )
it checks if an item is container of a bundled product then returns true. I need a similar function which would return true if the item is child or is inside a bundle.
here is the code of packing slip pdf body:
<?php
/**
* PDF packing slip template body.
*
* This template can be overridden by copying it to youruploadsfolder/woocommerce-pdf-invoices/templates/packing-slip/simple/yourtemplatename/body.php.
*
* HOWEVER, on occasion WooCommerce PDF Invoices will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* #author Bas Elbers
* #package WooCommerce_PDF_Invoices/Templates
* #version 0.0.1
*/
$templater = WPI()->templater();
$order = $templater->order;
$formatted_shipping_address = $order->get_formatted_shipping_address();
$formatted_billing_address = $order->get_formatted_billing_address();
$line_items = $order->get_items( 'line_item' );
$color = $templater->get_option( 'bewpi_color_theme' );
?>
<table>
<tr class="title">
<td colspan="3">
<h2><?php _e( 'Packing Slip', 'woocommerce-pdf-invoices' ); ?></h2>
</td>
</tr>
<tr class="information">
<td width="50%">
<?php echo nl2br( $templater->get_option( 'bewpi_company_address' ) ); ?>
</td>
<td>
<?php
if ( $templater->get_option( 'bewpi_show_ship_to' ) && ! empty( $formatted_shipping_address ) && $formatted_shipping_address !== $formatted_billing_address && ! $templater->has_only_virtual_products( $line_items ) ) {
printf( '<strong>%s</strong><br />', __( 'Ship to:', 'woocommerce-pdf-invoices' ) );
echo $formatted_shipping_address;
}
?>
</td>
<td>
<?php echo $formatted_billing_address; ?>
</td>
</tr>
</table>
<table>
<thead>
<tr class="heading" bgcolor="<?php echo $color; ?>;">
<th>
<?php _e( 'Qty', 'woocommerce-pdf-invoices' ); ?>
</th>
<th>
<?php _e( 'Product', 'woocommerce-pdf-invoices' ); ?>
</th>
<th>
<?php _e( 'SKU', 'woocommerce-pdf-invoices' ); ?>
</th>
</tr>
</thead>
<tbody>
<?php
//$parentItem = 0;
foreach ( $line_items as $item_id => $item ) {
$product = BEWPI_WC_Order_Compatibility::get_product( $order, $item );
if(wc_pb_is_bundle_container_cart_item($item) ){
?>
<tr class="item">
<td width="10%">
<?php echo $item['qty']; ?>
<?php // print_r($item); die(); ?>
</td>
<td width="65%">
<?php
echo $item['name'];
do_action( 'woocommerce_order_item_meta_start', $item_id, $item, $order );
$templater->wc_display_item_meta( $item, true );
$templater->wc_display_item_downloads( $item, true );
do_action( 'woocommerce_order_item_meta_end', $item_id, $item, $order );
?>
</td>
<td width="25%">
<?php echo $product && $product->get_sku() ? $product->get_sku() : '-'; ?>
</td>
</tr>
<?php } else { ?>
<tr class="item">
<td width="10%" style="float:right;">
<?php echo $item['qty']; ?>
</td>
<td width="5%" style="float:right;">
<?php
echo '----'.$item['name'];
//echo 'i m child';
do_action( 'woocommerce_order_item_meta_start', $item_id, $item, $order );
$templater->wc_display_item_meta( $item, true );
$templater->wc_display_item_downloads( $item, true );
do_action( 'woocommerce_order_item_meta_end', $item_id, $item, $order );
?>
</td>
<td width="25%" style="float:right;">
<?php echo $product && $product->get_sku() ? $product->get_sku() : '-'; ?>
</td>
</tr>
<?php }} ?>
</tbody>
</table>
<table class="notes">
<tr>
<td>
<?php
// Customer notes.
if ( $templater->get_option( 'bewpi_show_customer_notes' ) ) {
// Note added by customer.
$customer_note = BEWPI_WC_Order_Compatibility::get_customer_note( $order );
if ( $customer_note ) {
printf( '<strong>' . __( 'Note from customer: %s', 'woocommerce-pdf-invoices' ) . '</strong><br />', nl2br( $customer_note ) );
}
// Notes added by administrator on 'Edit Order' page.
foreach ( $order->get_customer_order_notes() as $custom_order_note ) {
printf( '<strong>' . __( 'Note to customer: %s', 'woocommerce-pdf-invoices' ) . '</strong><br />', nl2br( $custom_order_note->comment_content ) );
}
}
?>
</td>
</tr>
</table>
I want to append ---- infront of the name of product only if the product is part of any bundle. just want this check, I cant figure out how can I do that
Thanks.
Issue is that you are using Cart Functions instead of Order Functions.
First you need to use wc_pb_is_bundle_container_order_item instead of wc_pb_is_bundle_container_cart_item as we are checking against Order Items.
Further to that wc_pb_is_bundled_order_item is the check you should be using to determine if the product is a child item of an container item. This is important because it will check if item has a parent container so your code can scale when you also have non-bundled items in order as well.
Below is just partial relevant code from question.
<?php } else { ?>
<tr class="item">
<td width="10%" style="float:right;">
<?php echo $item['qty']; ?>
</td>
<td width="5%" style="float:right;">
<?php
// Adding a check to see if current item is a child of a container
$item_name_padding = wc_pb_is_bundled_order_item( $item ) ? '----': '';
echo $item_name_padding . $item['name'];
//echo 'i m child';
do_action( 'woocommerce_order_item_meta_start', $item_id, $item, $order );
$templater->wc_display_item_meta( $item, true );
$templater->wc_display_item_downloads( $item, true );
do_action( 'woocommerce_order_item_meta_end', $item_id, $item, $order );
?>
</td>
<td width="25%" style="float:right;">
<?php echo $product && $product->get_sku() ? $product->get_sku() : '-'; ?>
</td>
</tr>
<?php }} ?>

Simple PHP Table Total

I've been trying for ages to simply calculate the "weight" field we have added to an invoice plugin called sliced invoices. All I need is for it to total the weight based on the value in the table.
The weight field has the div class, "adjust". Here's a link to the forms PDF and you'll see the empty table field - Weight. http://cavcon.co.za/sliced_quote/346-2/?create=pdf&id=346&print_pdf=8d39bfe988
Here's the code I'm working with:
<?php
$count = 0;
$items = sliced_get_invoice_line_items(); // gets quote and invoice
if( !empty( $items ) ) :
foreach ( $items[0] as $item ) {
$class = ($count % 2 == 0) ? 'even' : 'odd';
$item_tax = isset( $item['tax'] ) ? $item['tax'] : 0;
$line_total = $shared->get_line_item_sub_total( $item['qty'], $item['amount']);
?>
<tr class="row_<?php echo $class; ?> sliced-item">
<td class="qty"><?php echo esc_html( $item['qty'] ); ?></td>
<td class="service"><?php echo esc_html( isset( $item['title'] ) ? $item['title'] : '' ); ?>
<?php if ( isset( $item['description'] ) ) : ?>
<br/><span class="description"><?php echo esc_html( $item['description']); ?></span>
<?php endif; ?>
</td>
<td class="rate"><?php echo esc_html( $shared->get_formatted_currency( $item['amount'] ) ); ?></td>
<?php if ( sliced_hide_adjust_field() === false) { ?>
<td class="adjust"><?php echo esc_html( $item_tax ? $item['tax'] . 'kg' : '-' ); ?></td>
<?php } ?>
<td class="total"><?php echo esc_html( $shared->get_formatted_currency( $line_total ) ); ?></td>
</tr>
<?php $count++;
}
endif; ?>
</tbody>
</table>
<?php
}
endif;
if ( ! function_exists( 'sliced_display_invoice_totals' ) ) :
function sliced_display_invoice_totals() { ?>
<table class="table table-sm table-bordered" id="new-table">
<tbody>
<?php do_action( 'sliced_invoice_before_totals' ); ?>
<tr class="row-sub-total">
<td class="rate"><?php echo _e( 'Total Weight', 'sliced-invoices' ); ?></td>
<td class="total-weight"><?php echo esc_html( $item['weight'] ); ?>
</td>
</tr>
<tr class="row-sub-total">
<td class="rate"><?php echo _e( 'Sub Total', 'sliced-invoices' ); ?></td>
<td class="total"><?php echo esc_html( sliced_get_invoice_sub_total() ); ?></td>
</tr>
<tr class="row-tax">
<td class="rate"><?php echo esc_html( sliced_get_tax_name() ); ?></td>
<td class="total"><?php echo esc_html( sliced_get_invoice_tax() ); ?></td>
</tr>
<tr class="table-active row-total">
<td class="rate"><strong><?php echo _e( 'Total', 'sliced-invoices' ); ?></strong></td>
<td class="total"><strong><?php echo esc_html( sliced_get_invoice_total() ); ?></strong></td>
</tr>
<?php do_action( 'sliced_invoice_after_totals' ); ?>
</tbody>
</table>
<?php
}
endif;
THIS IS WHERE I'M AT
if ( ! function_exists( 'sliced_display_invoice_totals' ) ) :
$total_weight = 0;
foreach ( $items[0] as $item ) {
$total_weight = $total_weight + $item['tax'];
}
function sliced_display_invoice_totals() { ?>
<table class="table table-sm table-bordered" id="new-table">
<tbody>
<?php do_action( 'sliced_invoice_before_totals' ); ?>
<tr class="row-sub-total">
<td class="rate"><?php echo _e( 'Total Weight', 'sliced-
invoices' ); ?></td>
<td class="total-weight"><?php echo esc_html(
$total_weight . 'kg') ?>
</td>
If you run PHP version 5.5 or above, you can sum the weights in this way:
if( !empty( $items ) ) :
foreach ( $items[0] as $item ) {
(...)
}
$total_weight = array_sum( array_column( $items, 'tax' ) );
endif; ?>
Otherwise, you have to increment $total_weight inside foreach loop:
$total_weight = 0;
foreach ( $items[0] as $item ) {
$total_weight = $total_weight + $item['tax'];
(...)
}
If you output total weight in the same scope of above script, simply put echo $total_weight; where you want to print it (or echo esc_html( $total_weight . 'kg');, according with your other prints).
But maybe your totals is output through sliced_display_invoice_totals function (although I don't see any call to this function in your code); in this case, the $total_weight variable is not directly available in the function, due to different scope. You have to print it in this way:
function sliced_display_invoice_totals() { ?>
(...)
echo $GLOBALS['total_weight']; // or echo esc_html( $GLOBALS['total_weight'] . 'kg');
(...)
}
Pleae careful note:
In your code, the function sliced_display_invoice_totals declaration is prepended by condition if ( ! function_exists( 'sliced_display_invoice_totals' ) ): this means that, if the function is already defined, your function modification will be ignored: in this case, you have to modify the already declare function instead.
To see if the function is already declared, place this temporary code before if condition:
if( function_exists( 'sliced_display_invoice_totals' ) )
{
$reflFunc = new ReflectionFunction( 'sliced_display_invoice_totals' );
die( $reflFunc->getFileName() . ':' . $reflFunc->getStartLine() );
}
In this way you can see the filePath and line in which the function is defined and modify it.
See more about array_sum
See more about array_column
See more about Variables scope
See more about Reflection class
Here is a list of things to change:
1. Unpaired HTML tags
The code in your question does not include the <table> nor <tbody> tags which you later close. I assume they are present in your original code.
2. Unpaired braces
Maybe also just an error while drafting your question, but after the </table> there is a closing PHP } and endif which have no matching opening statements.
3. Use of _e
According to the documentation of _e() on wordpress.org:
Displays the returned translated text from translate()
[...]
This function does not return a value.
So you are not supposed to write echo _e(...), you should just write _e(...) instead.
4. Function sliced_display_invoice_totals
You define this function that displays the totals, but you never call it. If you intend to display that table then do just that, without function definition.
5. When $items is empty
You have a condition so that the first table is only produced when $items is not empty. However, the totals table is produced outside that context, so it would also be produced when $items is empty. This might not be what you want. Consider moving the code for the second table inside that if block.
6. Mixed use of normal and alternative syntax
You use often the : ... endif syntax, which can indeed be helpful to read code that is interrupted by HTML code. But you don't use it consistently. I suggest using it for all if statements and for the foreach construct as well.
7. Calculate and display the $total_weight
Inside your existing foreach loop, add the weight of each line to $total_weight. You must also initialise this value just before starting the loop with 0.
Then in the second table display that $total_weight with the same format as you display the individual weights in the first table.
Here is the code that has all of the above applied:
<table class="table table-sm table-bordered" id="detail-table">
<tbody>
<?php
$count = 0;
$items = sliced_get_invoice_line_items(); // gets quote and invoice
// *** add this line ***
$total_weight = 0;
if( !empty( $items ) ) :
foreach ( $items[0] as $item ) :
$class = ($count % 2 == 0) ? 'even' : 'odd';
$item_tax = isset( $item['tax'] ) ? $item['tax'] : 0;
// *** add this line ***
$total_weight += $item_tax;
$line_total = $shared->get_line_item_sub_total( $item['qty'], $item['amount']);
?>
<tr class="row_<?php echo $class; ?> sliced-item">
<td class="qty"><?php echo esc_html( $item['qty'] ); ?></td>
<td class="service"><?php echo esc_html( isset( $item['title'] ) ? $item['title'] : '' ); ?>
<?php if ( isset( $item['description'] ) ) :
?> <br/><span class="description"><?php echo esc_html( $item['description']); ?></span>
<?php endif;
?> </td>
<td class="rate"><?php echo esc_html( $shared->get_formatted_currency( $item['amount'] ) ); ?></td>
<?php if ( sliced_hide_adjust_field() === false) :
?> <td class="adjust"><?php echo esc_html( $item_tax ? $item['tax'] . 'kg' : '-' ); ?></td>
<?php endif;
?>
<td class="total"><?php echo esc_html( $shared->get_formatted_currency( $line_total ) ); ?></td>
</tr>
<?php $count++;
endforeach; // use consistent syntax (alternative)
?>
</tbody>
</table>
<?php
// **** Remove the IF and the FUNCTION. You want to execute this now. ***
?>
<table class="table table-sm table-bordered" id="new-table">
<tbody>
<?php do_action( 'sliced_invoice_before_totals' ); ?>
<tr class="row-sub-total">
<td class="rate"><?php _e( 'Total Weight', 'sliced-invoices' ); ?></td>
<td class="total-weight"><?php echo esc_html( $total_weight ? $total_weight . 'kg' : '-' ); ?></td>
</tr>
<tr class="row-sub-total">
<td class="rate"><?php _e( 'Sub Total', 'sliced-invoices' ); ?></td>
<td class="total"><?php echo esc_html( sliced_get_invoice_sub_total() ); ?></td>
</tr>
<tr class="row-tax">
<td class="rate"><?php echo esc_html( sliced_get_tax_name() ); ?></td>
<td class="total"><?php echo esc_html( sliced_get_invoice_tax() ); ?></td>
</tr>
<tr class="table-active row-total">
<td class="rate"><strong><?php _e( 'Total', 'sliced-invoices' ); ?></strong></td>
<td class="total"><strong><?php echo esc_html( sliced_get_invoice_total() ); ?></strong></td>
</tr>
<?php do_action( 'sliced_invoice_after_totals' ); ?>
</tbody>
</table>
<?php
// **** Consider closing the if (!empty($items)) here ***
endif;
?>
You did not specify the code for the many functions you call, like sliced_get_tax_name, sliced_get_invoice_tax,... etc. Unless there is a problem with any of these functions, the above code should work.

Categories