phpwordpresswoocommercehook-woocommercecoupon

Split discount (coupon) row into multiple deducted cost rows in WooCommerce order totals table


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:

I want to change this to:

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?


Solution

  • 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