skip to Main Content

If there are 2 discount coupons used, it shows the sum of 2 coupons in the Woocommerce order totals table, while I want to show the deducted cost of each coupon separately.

For example, 2 coupons are inserted, currently it shows:

  • coupon : $100

I want to change this to:

  • coupon1(coupon code) : $50

  • coupon2(coupon code) : $50

Path from the WooCommerce template file: order-details.php

foreach ( $order->get_order_item_totals() as $key => $total ) {
    ?>
        <tr>
            <th scope="row"><?php echo esc_html( $total['label'] ); ?></th>
            <td><?php echo ( 'payment_method' === $key ) ? esc_html( $total['value'] ) : wp_kses_post( $total['value'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></td>
        </tr>
        <?php
}

Any advice on how to change this?

2

Answers


  1. add_filter('woocommerce_get_order_item_totals', 'woocommerce_get_order_item_totals', 10, 3);
    
    function woocommerce_get_order_item_totals($total_rows, $order, $tax_display) {
        // Loop through order items "coupon"
        $original_dicount_value = $total_rows['discount']['value'];
        $breaked_dicount_value = '';
        $wrapp_table_start = '<table style="width:100%">';
        $i = 1;
        foreach ($order->get_items('coupon') as $item_id => $item) {
            // Get the coupon array data
            $data = $item->get_data();
            $coupon_code = $data['code'];
            $coupon_amt = strip_tags(wc_price($data['discount'] + $data['discount_tax']));
            $breaked_dicount_value .= "<tr>
                <td>coupon$i($coupon_code)</td>
                <td>$coupon_amt</td>
              </tr>";
            $i++;
        }
        $wrapp_table_end = "</table>";
        $total_rows['discount']['value'] = ('' !== $breaked_dicount_value ) ? $wrapp_table_start . $breaked_dicount_value . $wrapp_table_end : $original_dicount_value;
        return $total_rows;
    }
    
    Login or Signup to reply.
  2. It is not necessary to add HTML table tags via the woocommerce_get_order_item_totals hook, since it concerns table rows.

    Next answer removes the default discount row and splits it over several rows with the desired details.

    Functions used in this answer:

    So you get:

    function filter_woocommerce_get_order_item_totals( $total_rows, $order, $tax_display ) {
        // Exit if there is no coupons applied
        if ( sizeof ( $order->get_coupon_codes() ) == 0 ) return $total_rows;
        
        // Initializing
        $new_rows = [];
        
        // Loop through order total lines
        foreach ( $total_rows as $total_key => $total_row ) {
            // Store current rows, except discount
            if ( $total_key != 'discount' ) {
                // Store
                $new_rows[$total_key] = $total_row;
            } else {            
                // For each coupon
                foreach ( $order->get_items('coupon') as $coupon ) {
                    // New rows
                    $new_rows[$coupon->get_code()] = array(
                        'label' => __( 'Coupon: ', 'woocommerce' ) . $coupon->get_code(),
                        'value' => wc_price( $coupon->get_discount() ),
                    );
                }   
            }
        }
    
        // Overwrite
        $total_rows = $new_rows;
    
        return $total_rows;
    }
    add_filter( 'woocommerce_get_order_item_totals', 'filter_woocommerce_get_order_item_totals', 10, 3 );
    

    Result:

    result


    Related: Add coupon names and percentage to WooCommerce view order details and email notifications

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search