WooCommerce - Transpose Cart loop in Order loop for pdf invoices - php

I'm using woocommerce and "Print Invoices & Packing lists"
available at "https://woocommerce.com/products/print-invoices-packing-lists/" .
For Display the Total Saving in the woocommerce cart & checkout pages I'm used this code and works perfectly :
function bbloomer_wc_discount_total() {
global $woocommerce;
$cart_subtotal = $woocommerce->cart->cart_contents;
$discount_total = 0;
foreach ($woocommerce->cart->cart_contents as $product_data) {
if ($product_data['variation_id'] > 0) {
$product = wc_get_product( $product_data['variation_id'] );
} else {
$product = wc_get_product( $product_data['product_id'] );
}
if ( !empty($product->sale_price) ) {
$discount = ($product->regular_price - $product->sale_price) * $product_data['quantity'];
$discount_total += $discount;
}
}
if ( $discount_total > 0 ) {
echo '<tr class="cart-discount">
<th>'. __( 'Total Saving :', 'woocommerce' ) .'</th>
<td data-title=" '. __( 'Total Saving :', 'woocommerce' ) .' ">'
. wc_price($discount_total+$woocommerce->cart->discount_cart) .'</td>
</tr>';
}
}
add_action( 'woocommerce_cart_totals_after_order_total', 'bbloomer_wc_discount_total');
add_action( 'woocommerce_review_order_after_order_total', 'bbloomer_wc_discount_total');
This function based in the woocommerce cart contents .
How I can Display The Total Saving in the Html Invoice generated By Print Invoices & Packing lists Plugin ( based On the Order Instead of the cart contents ) in the plugin Hooks like :
add_action( 'wc_pip_after_header', 'bbloomer_wc_discount_total');
add_action( 'wc_pip_document_header', 'bbloomer_wc_discount_total');

— Update 2 — (Added compatibility for WooCommerce version 3+)
Now as I know you are using WooCommerce PDF Invoices & Packing Slips plugin.
This code can only be used directly in invoice.php PIP template at the beginning, replacing <?php global $wpo_wcpdf ?> by this:
<?php
global $wpo_wcpdf, $woocommerce;
// Get the order object
$_order = $wpo_wcpdf->export->order;
foreach ( $_order->get_items() as $item ) {
// Added WC 3+ compatibility
$quantity = method_exists( $item, 'get_quantity' ) ? $item->get_quantity() : $item['quantity'];
$variation_id = method_exists( $item, 'get_variation_id' ) ? $item->get_variation_id() : $item['variation_id'];
$_product = version_compare( WC_VERSION, '3.0', '<' ) ? wc_get_product( $item['product_id'] ) : $item->get_product();
// Get the product object when it's a product variation ( Before version WC 3+)
if ( version_compare( WC_VERSION, '3.0', '<' ) )
if ($item['variation_id'] > 0) $_product = wc_get_product( $item['variation_id'] );
// Get prices
$sale_price = $_product->get_sale_price();
$regular_price = $_product->get_regular_price();
// Only when sale price exits
if ( ! empty( $sale_price ) && $sale_price > 0 ) {
$discount = ($regular_price - $sale_price) * $item->get_quantity();
$discount_total += $discount;
}
}
if ( $discount_total > 0 ) {
$display_discount = '<tr class="cart-discount">
<th>'. __( 'Total you saved :', 'woocommerce' ) .'</th>
<td data-title=" '. __( 'Total you saved :', 'woocommerce' ) .' ">' . wc_price( $discount_total + $_order->get_total_discount() ) .'</td>
</tr>';
}
?>
Then you can use it where you want in the template to output it, this way (inside html):
<?php echo $display_discount; ?>
Or (inside php code):
echo $display_discount;
This code is tested and works.

Related

Custom total savings amount display issue in WooCommerce Checkout

I'm using this code snippet to display the total order savings at WooCommerce checkout:
add_action( 'woocommerce_review_order_after_order_total', 'show_total_discount_cart_checkout', 9999 );
function show_total_discount_cart_checkout() {
$discount_total = 0;
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
$product = $values['data'];
if ( $product->is_on_sale() ) {
$regular_price = $product->get_regular_price();
$sale_price = $product->get_sale_price();
$discount = ( $regular_price - $sale_price ) * $values['quantity'];
$discount_total += $discount;
}
}
if ( $discount_total > 0 ) {
echo '<tr class="total-saved"><th>You Saved</th><td data-title="You Saved">' . wc_price( $discount_total + WC()->cart->get_discount_total() ) .'</td></tr>';
}
}
It should display the total amount of money a customer saved (sale prices plus coupon discounts). Screenshot: https://ibb.co/KXg2bDj
However, if there are no discounted products in the cart, the total order savings do not show up, even if there is a coupon code applied to the order. The total order savings show up only if there are discounted products in the cart. Screenshot: https://ibb.co/PCQPGZx
I would like the total order savings to show up if there is a coupon code applied to the order, if there are discounted products in the cart or if there's both. If there's neither 1 of those 2, the total order savings do not need to show up.
Could someone please help me achieve this?
Try the following instead, that will solve your issue and handle displaying tax settings:
add_action( 'woocommerce_review_order_after_order_total', 'show_total_discount_cart_checkout', 1000 );
function show_total_discount_cart_checkout() {
$discount_total = 0; // Initializing
// Loop through cart items
foreach ( WC()->cart->get_cart() as $item ) {
$product = $item['data'];
if ( $product->is_on_sale() ) {
$regular_args = array( 'price' => $product->get_regular_price() );
if ( WC()->cart->display_prices_including_tax() ) {
$active_price = wc_get_price_including_tax( $product );
$regular_price = wc_get_price_including_tax( $product, $regular_args );
} else {
$active_price = wc_get_price_excluding_tax( $product );
$regular_price = wc_get_price_excluding_tax( $product, $regular_args );
}
$discount_total += ( $regular_price - $active_price ) * $item['quantity'];
}
}
if ( WC()->cart->display_prices_including_tax() ) {
$discount_total += WC()->cart->get_discount_tax();
}
$discount_total += WC()->cart->get_discount_total();
if ( $discount_total > 0 ) {
$text = __("You Saved", "woocommerce");
printf( '<tr class="total-saved"><th>%s</th><td data-title="%s">%s</td></tr>', $text, $text, wc_price($discount_total) );
}
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.

Hide coupon discount raw if no coupon has been applied on WooCommerce cart page

I add coupons and discounts total savings to my cart page. My code works fine but I have an additional question.
This is the code I am currently using:
add_action( 'woocommerce_cart_totals_before_shipping', 'show_total_discount_cart_checkout', 9999 );
function show_total_discount_cart_checkout() {
global $woocommerce;
$discount_total = 0;
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
$product = $values['data'];
if ( $product->is_on_sale() ) {
$regular_price = $product->get_regular_price();
$sale_price = $product->get_sale_price();
$discount = ( $regular_price - $sale_price ) * $values['quantity'];
$regular_total = $regular_price * $values['quantity'];
$discount_total += $discount;
}
}
if ( $discount_total > 0 ) {
echo '
<tr><th colspan="2">You will save '. wc_price( $woocommerce->cart->subtotal - $woocommerce->cart->total + $woocommerce->cart->shipping_total*1.23 + $discount_total ) .'</td></tr>
<tr><th class="smalltl">Price normal</th><td data-title="Poupa" class="smalltot">'. wc_price( $regular_total ) .'</td></tr>
<tr><th class="smalltl">Dicsount Pack</th><td data-title="Poupa" class="smalltot">-'. wc_price( $discount_total ) .'</td></tr>
<tr><th class="smalltl">Discount Cupon</th><td data-title="Poupa" class="smalltot">-'. wc_price( $woocommerce->cart->subtotal - $woocommerce->cart->total + $woocommerce->cart->shipping_total*1.23 ) // need to hide this tr when there i no coupon applied
.'</td></tr>
';
}
}
Currently: if no coupons are applied, it shows 0.
My question: How can I hide the table output when 0 is displayed?
You could use WC_Cart::get_applied_coupons() and when NOT empty.
I've cleaned up your code and rewritten it a little bit
So you get:
function show_total_discount_cart_checkout() {
// Counter
$discount_total = 0;
// WC Cart
if ( WC()->cart ) {
// Get cart
$cart = WC()->cart;
// If cart is NOT empty
if ( ! $cart->is_empty() ) {
// Loop through cart items and calculate total volume
foreach( $cart->get_cart() as $cart_item ) {
// Get product
$product = $cart_item['data'];
// On sale
if ( $product->is_on_sale() ) {
// Getters
$regular_price = $product->get_regular_price();
$sale_price = $product->get_sale_price();
$quantity = $cart_item['quantity'];
// Calculations
$discount = ( $regular_price - $sale_price ) * $quantity;
$regular_total = $regular_price * $quantity;
$discount_total += $discount;
}
}
}
}
// Greater than
if ( $discount_total > 0 ) {
// Getters
$subtotal = $cart->get_subtotal();
$total = $cart->total;
$shipping_total = $cart->shipping_total;
// Output
echo '<tr><th colspan="2">You will save ' . wc_price( $subtotal - $total + $shipping_total * 1.23 + $discount_total ) . '</td></tr>';
echo '<tr><th class="smalltl">Price normal</th><td data-title="Poupa" class="smalltot">' . wc_price( $regular_total ) . '</td></tr>';
echo '<tr><th class="smalltl">Dicsount Pack</th><td data-title="Poupa" class="smalltot">-' . wc_price( $discount_total ) . '</td></tr>';
// Get applied coupons
$coupon_applieds = $cart->get_applied_coupons();
// NOT Empty coupon applieds
if ( ! empty ( $coupon_applieds ) ) {
echo '<tr><th class="smalltl">Discount Cupon</th><td data-title="Poupa" class="smalltot">-' . wc_price( $subtotal - $total + $shipping_total * 1.23 ) . '</td></tr>';
}
}
}
add_action( 'woocommerce_cart_totals_before_shipping', 'show_total_discount_cart_checkout', 10, 0 );

Add calculated saving total in Woocommerce order totals rows

In Woocommerce, I am using the following code to calculate and display 'Total Saving' on the order in Cart and checkout pages:
function wc_discount_total_30() {
global $woocommerce;
$discount_total = 0;
foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values) {
$_product = $values['data'];
if ( $_product->is_on_sale() ) {
$regular_price = $_product->get_regular_price();
$sale_price = $_product->get_sale_price();
$discount = ($regular_price - $sale_price) * $values['quantity'];
$discount_total += $discount;
}
}
if ( $discount_total > 0 ) {
echo '<tr class="cart-discount">
<th>'. __( 'Saved', 'tsavedis' ) .'</th>
<td data-title=" '. __( 'Saved', 'tsavedis' ) .' ">'
. wc_price( $discount_total + $woocommerce->cart->discount_cart ) .'</td>
</tr>';
}
}
// Hook our values to the Basket and Checkout pages
add_action( 'woocommerce_cart_totals_after_order_total', 'wc_discount_total_30', 99);
add_action( 'woocommerce_review_order_after_order_total', 'wc_discount_total_30', 99);
I need to display this total saving in 'Order Edit' page at backend as a custom field.
How to do that ?
Here is the way to add the same thing to orders totals table:
// Display the chosen delivery information
add_filter( 'woocommerce_get_order_item_totals', 'add_saving_total_order_totals', 10, 3 );
function add_saving_total_order_totals( $total_rows, $order, $tax_display ) {;
$saving_total = 0;
// Loop through Order items
foreach($order->get_items() as $item ){
$product = $item->get_product();
if( $product->is_on_sale() ){
$regular_price = (float) $product->get_regular_price();
$active_price = (float) $product->get_price();
$saving_total += ($regular_price - $active_price) * $item->get_quantity();
}
}
if( $saving_total > 0 ) {
$discount_total = $order->get_discount_total();
$label = __( 'Saved', 'tsavedis' );
$value = wc_price( $saving_total + $discount_total );
$total_rows['saving'] = array( 'label' => $label,'value' => $value );
}
return $total_rows;
}
Code goes in function.php file of your active child theme (or active theme). tested and works.

Replace on sale product price with saving amount and percentages in Woocommerce

I use some code that shows the discounted price on Woocommerce archive pages for on sale products:
add_filter( 'woocommerce_get_price_html', 'display_savings_as_price_and_percentage', 10, 2 );
//add_filter( 'woocommerce_variable_price_html','display_savings_as_price_and_percentage', 10, 2 );
function display_savings_as_price_and_percentage( $price, $product ) {
if( $product->is_on_sale() && ! is_admin() && ! $product->is_type('variable')){
$product_price = (float) $product->get_regular_price();
$sale_price = (float) $product->get_price();
$save_price = wc_price( $product_price - $sale_price );
$save_percentage = round( 100 - ( $sale_price / $product_price * 100 ), 1 ) . '%';
$price .= sprintf( __('<p class="saved-on-sale">Save: %s (%s)</p>', 'woocommerce' ), $save_price, $save_percentage );
}
return $price;
}
Discount on archives pages:
But it doesn't work for variable products and I've tried with every hook I've found but I cannot figure out how to make it work variable products.
(I commented out the hook for the variable in my code).
This is what I would like to have:
If the variable has a price span of 10-20 with a discount making it 10-15 I would like for that to be displayed like this with the default price striked through:
$40 - $50
$20 - $30
Save: $20 (40-50%)
How can I replace the on sale product price for variable products with saving amount and percentages?
The following code will handle both simple and variable on sale products:
add_filter( 'woocommerce_get_price_html', 'display_savings_price_and_percentages', 20, 2 );
function display_savings_price_and_percentages( $price_html, $product ) {
// Only on frontend and for on sale products
if( is_admin() || ! $product->is_on_sale() )
return $price_html;
// Only on archives pages
if( ! ( is_shop() || is_product_category() || is_product_tag() ) )
return $price_html;
// Variable product type
if( $product->is_type('variable')){
$percentages = $savings = array(); // Initializing
// Get all variation prices
$prices = $product->get_variation_prices();
// Loop through variation prices
foreach( $prices['price'] as $key => $price ){
// Only on sale variations
if( $prices['regular_price'][$key] !== $price ){
// Calculate and set in the array the percentage for each variation on sale
$percentages[] = round(100 - ($prices['sale_price'][$key] / $prices['regular_price'][$key] * 100), 1 );
// Calculate and set in the array the savings for each variation on sale
$savings[] = $prices['regular_price'][$key] - $prices['sale_price'][$key];
}
}
$save_price = wc_price( max($savings) );
if( min($percentages) !== max($percentages) ){
$save_percentage = min($percentages) . '-' . max($percentages) . '%';
$save_text = __( 'Save up to:', 'woocommerce' );
} else {
$save_percentage = max($percentages) . '%';
$save_text = __( 'Save:', 'woocommerce' );
}
}
// All other product types
else {
$regular_price = $product->get_regular_price();
$sale_price = $product->get_sale_price();
$save_price = wc_price( $regular_price - $sale_price );
$save_percentage = round( 100 - ( $sale_price / $regular_price * 100 ), 1 ) . '%';
$save_text = __( 'Save:', 'woocommerce' );
}
return '<p class="saved-on-sale">' . sprintf( '%s %s (%s)', $save_text, $save_price, $save_percentage ) . '</p>';
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.

WooCommerce: Display also product variation description on cart items

I'm trying to display my product variation description in my Cart. I have tried inserting this code in the cart.php template:
if ( $_product->is_type( 'variation' ) ) {echo $_product->get_variation_description();}
By following this documentation https://docs.woocommerce.com/document/template-structure/
But it's still not showing up.
Not sure what I'm doing wrong here.
Can anyone help on this?
Updated for WooCommerce version 3 and above
Since WooCommerce 3, get_variation_description() is now deprecated and replaced by get_description() WC_Product method.
To get your product item variation description (filtering variation product type condition), you can use the following hooked function instead:
// Cart page (and mini cart)
add_filter( 'woocommerce_cart_item_name', 'cart_item_product_description', 20, 3);
function cart_item_product_description( $item_name, $cart_item, $cart_item_key ) {
if ( ! is_checkout() ) {
if( $cart_item['variation_id'] > 0 ) {
$description = $cart_item['data']->get_description(); // variation description
} else {
$description = $cart_item['data']->get_short_description(); // product short description (for others)
}
if ( ! empty($description) ) {
return $item_name . '<br><div class="description">
<strong>' . __( 'Description', 'woocommerce' ) . '</strong>: '. $description . '
</div>';
}
}
return $item_name;
}
// Checkout page
add_filter( 'woocommerce_checkout_cart_item_quantity', 'cart_item_checkout_product_description', 20, 3);
function cart_item_checkout_product_description( $item_quantity, $cart_item, $cart_item_key ) {
if( $cart_item['variation_id'] > 0 ) {
$description = $cart_item['data']->get_description(); // variation description
} else {
$description = $cart_item['data']->get_short_description(); // product short description (for others)
}
if ( ! empty($description) ) {
return $item_quantity . '<br><div class="description">
<strong>' . __( 'Description', 'woocommerce' ) . '</strong>: '. $description . '
</div>';
}
return $item_quantity;
}
Now the description is just displayed between the title and the variation attributes values (if there is any).
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
This will work for WC 3.0
add_filter( 'woocommerce_cart_item_name', 'cart_variation_description', 20, 3);
function cart_variation_description( $title, $cart_item, $cart_item_key ) {
$item = $cart_item['data'];
if(!empty($item) && $item->is_type( 'variation' ) ) {
return $item->get_name();
} else
return $title;
}
You can get it via global variable $woocommerce also-
global $woocommerce;
$cart_data = $woocommerce->cart->get_cart();
foreach ($cart_data as $value) {
$_product = $value['data'];
if( $_product->is_type( 'variation' ) ){
echo $_product->id . '<br>';
}
}
I already check it.

Categories