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??
Related
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; ?>
I am trying to add up all of my added coupons to get a discount total in the checkout. I tried adding a variable at the top of the checkout template file and doing ++ for each entry but I throws errors.
Any ideas how to add the values to a variable to get a total?
The checkout totals regenerate if you alter a value so I found my answer being outputted each time the loop runs.
My code:
<?php foreach ( WC()->cart->get_coupons() as $code => $coupon ) : ?>
<tr class="cart-discount coupon-<?php echo esc_attr( sanitize_title( $code ) ); ?>">
<th><?php wc_cart_totals_coupon_label( $coupon ); ?></th>
<td><?php $helloworld = wc_cart_totals_coupon_html( $coupon )++; ?></td>
</tr>
<?php endforeach; ?>
This can be done easily using some existing WC_Cart methods.
So in the template checkout/oreder-review.php, just after this:
<?php foreach ( WC()->cart->get_coupons() as $code => $coupon ) : ?>
<tr class="cart-discount coupon-<?php echo esc_attr( sanitize_title( $code ) ); ?>">
<th><?php wc_cart_totals_coupon_label( $coupon ); ?></th>
<td><?php wc_cart_totals_coupon_html( $coupon ); ?></td>
</tr>
<?php endforeach; ?>
You will insert the following code (after line 69):
<?php
$discount_excl_tax_total = WC()->cart->get_cart_discount_total();
$discount_tax_total = WC()->cart->get_cart_discount_tax_total();
$discount_total = $discount_excl_tax_total + $discount_tax_total;
if( ! empty($discount_total) ): ?>
<tr class="cart-discount coupon-<?php echo esc_attr( sanitize_title( $code ) ); ?>">
<th><?php _e('Discount total','woocommerce'); ?></th>
<td><?php echo wc_price(-$discount_total) ?></td>
</tr>
<?php endif; ?>
Tested and works.
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 }} ?>
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
}
I've already renamed my order status 'completed' to 'paid' using this code
function wc_renaming_order_status( $order_statuses ) {
foreach ( $order_statuses as $key => $status ) {
$new_order_statuses[ $key ] = $status;
if ( 'wc-completed' === $key ) {
$order_statuses['wc-completed'] = _x( 'Paid', 'Order status', 'woocommerce' );
}
}
return $order_statuses;
}
add_filter( 'wc_order_statuses', 'wc_renaming_order_status' );
My problem is that I did a page template with a list of all my orders:
<?php
while ( $loop->have_posts() ) : $loop->the_post();
$order_id = $loop->post->ID;
$order = new WC_Order($order_id);
?>
<tr>
<td style="text-align:left;"><?php echo $order->get_order_number(); ?></td>
<td style="text-align:left;"><?php echo $order->billing_first_name; ?>
<?php echo $order->billing_last_name; ?></td>
<td style="text-align:left;"><?php echo $order->billing_company; ?></td>
<td style="text-align:left;"><?php echo $order->status; ?></td>
</tr>
<?php endwhile; ?>
And the $order->status still returns 'completed' instead of 'paid'.
How can I solve this problem?
Thanks
This is normal and your this specific case you could use some additional code, creating a function to display your custom renamed status:
function custom_status($order){
if($order->status == 'completed')
return _x( 'Paid', 'woocommerce' );
else
return $order->status;
}
This code goes in function.php file of your active child theme (or theme) or also in any plugin file.
In your template page you will use it this way:
<?php
while ( $loop->have_posts() ) : $loop->the_post();
$order_id = $loop->post->ID;
$order = new WC_Order($order_id);
?>
<tr>
<td style="text-align:left;"><?php echo $order->get_order_number(); ?></td>
<td style="text-align:left;"><?php echo $order->billing_first_name; ?>
<?php echo $order->billing_last_name; ?></td>
<td style="text-align:left;"><?php echo $order->billing_company; ?></td>
<td style="text-align:left;"><?php echo custom_status($order); ?></td>
</tr>
<?php endwhile; ?>
This code is tested and works.
Reference: Renaming WooCommerce Order Status