Search code examples
wordpresswoocommercecheckoutordersemail-notifications

Save value from a custom row added after the order table and display it in WooCommerce orders and emails


This code I wrote displays personalized information on the WooCommerce checkout page.

add_action( 'woocommerce_cart_totals_after_order_total', 'show_total_discount_cart_checkout', 9999 );
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 => $cart_item ) {     
   $product = $cart_item['data'];
       
   $subtotal = WC()->cart->get_product_subtotal( $product, $cart_item['quantity'] );
        
   $total = WC()->cart->total;
   $pctm = 90.00;
   $valor_descontado = $total - ($total / 100 * $pctm); 
        
   $sale_price = '10%'; 
   $discount = ( WC()->cart->total - $valor_descontado );
   $discount_total = $discount;
   
}                
    if ( $discount_total > 0 ) {
      echo '<tr><th>VOCÊ RECEBERÁ DE CASHBACK:</th><td data-title="You">' . wc_price( $discount_total + WC()->cart->get_discount_total() ) .'</td></tr>';
    }
  
} 

The result:

enter image description here


I need this information to also be displayed in WooCommerce orders and emails. I believe I can come up with a solution myself to display this value on several other pages, but can someone first tell me how to save/store the value of this calculation?


Solution

  • First of all, I've rewritten your existing code for the following reasons:

    • Requesting subtotals and totals is best done outside the foreach loop, because otherwise these values ​​will be overwritten every time
    • The result of $subtotal is not used anywhere in your code
    • Since the result of $subtotal is not used anyway, loop through the cart seems unnecessary
    • $sale_price is also not used anywhere in your code
    • Since $discount_total = $discount it is not necessary to use a new variable
    • A session variable is created/added

    Your existing code, but optimized:

    function action_woocommerce_after_order_total() {
        // WC Cart NOT null
        if ( ! is_null( WC()->cart ) ) {
            // Get cart
            $cart = WC()->cart;
            
            // Getters
            $cart_total = $cart->total;
            $cart_discount_total = $cart->get_discount_total();
            
            // Settings
            $pctm = 90;
            
            // Calculations
            $discounted_value = $cart_total - ( $cart_total / 100 * $pctm );
            $discount_total = $cart_total - $discounted_value;
            
            // Greater than
            if ( $discount_total > 0 ) {
                // Result
                $result = $discount_total + $cart_discount_total;
                
                // The Output
                echo '<tr class="my-class">
                        <th>' . __( 'VOCÊ RECEBERÁ DE CASHBACK', 'woocommerce' ) . '</th>
                        <td data-title="You">' . wc_price( $result ) . '</td>
                      </tr>';
                
                // Set session
                WC()->session->set( 'session_result', $result );
            }
        }
    }
    add_action( 'woocommerce_cart_totals_after_order_total', 'action_woocommerce_after_order_total', 10 );
    add_action( 'woocommerce_review_order_after_order_total', 'action_woocommerce_after_order_total', 10 );
    

    To answer your question:

    Step 1) We get the result from the session variable and add it as order data, so that we can use/obtain this information everywhere via the $order object

    // Add as custom order meta data and reset WC Session variable
    function action_woocommerce_checkout_create_order( $order, $data ) {    
        // Isset
        if ( WC()->session->__isset( 'session_result' ) ) {
            // Get
            $result = (float) WC()->session->get( 'session_result' );
            
            // Add as meta data
            $order->update_meta_data( 'result', $result );
            
            // Unset
            WC()->session->__unset( 'session_result' );
        }
    }
    add_action( 'woocommerce_checkout_create_order', 'action_woocommerce_checkout_create_order', 10, 2 );
    

    Step 2) Use the woocommerce_get_order_item_totals filter hook, which will allow you to add a new row to the existing tables with the $result.

    The new row will be added in:

    • Email notifications
    • Order received (thank you page)
    • My account -> view order
    function filter_woocommerce_get_order_item_totals( $total_rows, $order, $tax_display ) {    
        // Get meta
        $result = $order->get_meta( 'result' );
        
        // NOT empty
        if ( ! empty ( $result ) ) {
            // Add new row
            $total_rows['total_result']['label'] = __( 'VOCÊ RECEBERÁ DE CASHBACK', 'woocommerce' );
            $total_rows['total_result']['value'] = wc_price( $result );
        }
    
        return $total_rows;
    }
    add_filter( 'woocommerce_get_order_item_totals', 'filter_woocommerce_get_order_item_totals', 10, 3 );