1

Based on "Update fee dynamically based on radio buttons in Woocommerce checkout" answer code, I have been able add a custom dynamic fee applied on customer delivery choice (with custom delivery option choices).

Here is the working code that I have adapted for my needs:

add_action( 'woocommerce_cart_calculate_fees', 'add_delivery_fee', 20, 1 );
function add_delivery_fee( $cart ) {
    $domain = 'woocommerce';
    $NipostFST = '2000';
    $NIPOSTSUB = '250';

    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    $packing_fee = WC()->session->get( 'chosen_delivery_option' ); // Dynamic delivery fee
    $Dlabel = $packing_fee == 'home_delivery' ? __('To Your Doorstep', $domain) : __('Local Pickup', $domain);
    $weight_of_item = WC()->cart->cart_contents_weight;

    if ( $weight_of_item > 1 ) {
        $nipostFee = $NipostFST + ( ($weight_of_item - 1)*$NIPOSTSUB );
    }elseif ( $weight_of_item == 1 ) {
        $nipostFee = $NipostFST;
    }

    $fee = (isset($weight_of_item)) ? $packing_fee == 'home_delivery' ? $nipostFee : 0.00 : 'Not Available';
    $cart->add_fee( !is_cart() ? __( 'Delivery Fee [ '.$Dlabel.' ]', $domain ) : __( 'Delivery Fee', $domain ), $fee );
}

// Add a custom radio fields for Delivery Option selection
add_action( 'woocommerce_checkout_before_order_review', 'checkout_delivery_fee_addition', 20 );
function checkout_delivery_fee_addition(){
    $domain       = 'woocommerce';
    $weight_of_item = WC()->cart->cart_contents_weight;

    $NipostFST = '2000';
    $NIPOSTSUB = '250';


    if ( $weight_of_item > 1 ) {
        $nipostFee = $NipostFST + ( ($weight_of_item - 1)*$NIPOSTSUB );
    }elseif ( $weight_of_item == 1 ) {
        $nipostFee = $NipostFST;
    }

    echo '<div id="izzycart_checkout_addons"><tr class="deliveryOption-select"><th>' . __('Delivery Method', $domain) . '</th><td>';

    $chosen   = WC()->session->get('chosen_delivery_option');
    $chosen   = empty($chosen) ? WC()->checkout->get_value('radio_delivery_option') : $chosen;
    $chosen   = empty($chosen) ? 'local_pickup' : $chosen;

    // Add a custom checkbox field
    woocommerce_form_field( 'radio_delivery_option', array(
        'type' => 'radio',
        'class' => array( 'form-row-wide delivery_option' ),
        'options' => array(
            'local_pickup' => __('Local Pickup '.wc_price(0.00), $domain),
            'home_delivery' => (!isset($weight_of_item)) ? __('To Your Doorstep <br><span style="color:red">Not Available</span>', $domain) : __('To Your Doorstep '.wc_price($nipostFee), $domain),
        ),
        'default' => $chosen,
    ), $chosen );

    echo '</td></tr></div>';
}

// Display fees with zero amount
add_filter( 'woocommerce_get_order_item_totals_excl_free_fees', '__return_false' );

My question: In Woocommerce, how I can display the chosen delivery method on order detail table for order received page, My account view order pages and on all email notifications.

So I will like the result to look like this:

result

Continuation of: Make appear a zero fee in Woocommerce Orders and email notifications

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399

1 Answers1

1

Updated: I have added 2 functions that will grab the selected delivery option to the order and display it in order detail table for order received page, My account view order pages and on all email notifications:

// Save chosen delivery as order custom meta data
add_action('woocommerce_checkout_create_order', 'save_order_delivery_option', 10, 2 );
function save_order_delivery_option(  $order, $data ) {
    if ( isset($_POST['radio_delivery_option']) ) {
        $order->update_meta_data( '_chosen_delivery_method', esc_attr($_POST['radio_delivery_option']) );
    }
}

// Display the chosen delivery information
add_filter( 'woocommerce_get_order_item_totals', 'chosen_delivery_item_order_totals', 10, 3 );
function chosen_delivery_item_order_totals( $total_rows, $order, $tax_display ) {;
    $new_total_rows = [];

    // Loop through Order total lines
    foreach($total_rows as $key => $total ){
        // Get the chosen delivery
        $chosen_delivery = $order->get_meta('_chosen_delivery_method');

        if( ! empty($chosen_delivery) && 'payment_method' === $key ){
            $domain = 'woocommerce';
            $label  = __('Delivery method:', 'woocommerce');
            $value  = 'local_pickup' === $chosen_delivery ? __('Local Pickup', $domain) : __('To Your Doorstep', $domain);
            // Display 'Delivery method' line
            $new_total_rows['chosen_delivery'] = array( 'label' => $label,'value' => $value );
        }
        $new_total_rows[$key] = $total;
    }

    return $new_total_rows;
}

Code goes in function.php file of your active child theme (or active theme). Tested and works.

enter image description here

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • For some reason, To Your Doorstep Delivery option doesn't show after i used your above code ( only local pickup is showing )and i got a error saying variable $delivery is not defined on line `// Set the WC_Session default delivery to "Pickup" (first choice) if( ! WC()->session->get('chosen_delivery') ) WC()->session->set('chosen_delivery', $delivery );` – Kolawole Emmanuel Izzy Feb 20 '19 at 12:31
  • @KolawoleEmmanuelIzzy I have just kept the 2 last hooked functions *(making the necessary changes)* that will work with our code. Try that… it should works. – LoicTheAztec Feb 20 '19 at 13:40
  • I retraced my footstep and its working fine... Not sure why i got that undefined $delivery on my first test. i thought it was because i didn't add the ajax function on same file but when i copied all your code exactly as is, then the To Your Doorstep option appeared. Then with all your code as is i removed the Ajax function from the same page and copied to the file i created for all ajax functions and i didn't get any undefined error. Didn't know what i did differently before. Everything works fine now. Thanks so much – Kolawole Emmanuel Izzy Feb 20 '19 at 13:44
  • i see that you've removed the other codes and added just the two new ones, will be nice to have the complete code, incase someone have related problem in future. Thanks for the great work @LoicTheAztec. Now i need to figure out to to automatically delete products when orders attached to it has been marked as completed as asked [here](https://stackoverflow.com/questions/54754930/how-to-delete-a-product-that-belongs-to-a-category-when-its-order-is-completed-i) earlier. Will appreciate or help or idea on how i can accomplish this. – Kolawole Emmanuel Izzy Feb 20 '19 at 13:50
  • Just out of curiosity, as i'm still on a local environment, will this options (i.e Delivery Method: Local Pickup) be passed into the order email table. I mean when user receive email notification regarding their order, will the chosen option be available in the email table? – Kolawole Emmanuel Izzy Feb 20 '19 at 13:59
  • 1
    @KolawoleEmmanuelIzzy Yes! On the email table too as the order line totals are also displayed there… I Will add all the revisited needed code later in this answer. – LoicTheAztec Feb 20 '19 at 14:43