Resend programmatically a WooCommerce customer_on_hold_order email notification

8.8k views Asked by At

I noticed that the customer on hold order email is not available so i tried to replace the actions with a single action that would send the appropriate email.

This seems to work except for the on-hold status. I dont see what the difference is between the on-hold and processing case other than its not in the $available_emails in class-wc-meta-box-order-actions.php and I have removed all the others and they still work.

What I am doing wrong? Is it a way to make this possible?

My code is:

    function ulmh_resend1( $actions ) {
    $actions['ulmh_resend'] = __( 'Resend Email', 'text_domain' );
    return $actions;
}
function ulmh_resend2( $order ) {
    $mailer = WC()->mailer();
    $mails = $mailer->get_emails();
    if ($order->has_status( 'on-hold' )) {
    $eml = 'customer_on_hold_order';    
    }elseif ($order->has_status( 'processing' )) {
    $eml = 'customer_processing_order'; 
    }elseif ($order->has_status( 'completed' )) {
    $eml = 'customer_completed_order';  
    } else {
    $eml = "nothing";
    }   
    if ( ! empty( $mails ) ) {
        foreach ( $mails as $mail ) {
            if ( $mail->id == eml ) {
               $mail->trigger( $order->id );
            }
         }
    }
}
function ulmh_resend3( $order_emails ) {
    $remove = array( 'new_order', 'cancelled_order', 'customer_processing_order', 'customer_completed_order', 'customer_invoice' );
    $order_emails = array_diff( $order_emails, $remove );
    return $order_emails;
}   
add_action( 'woocommerce_order_actions', 'ulmh_resend1' );
add_action( 'woocommerce_order_action_ulmh_resend', 'ulmh_resend2' );
add_filter( 'woocommerce_resend_order_emails_available', 'ulmh_resend3' );
1

There are 1 answers

2
LoicTheAztec On BEST ANSWER

I have revisited and compacted your code because there where some errors like a typo error in if ( $mail->id == eml ){ for eml as a variable nameā€¦ Also to get the Order ID from the WC_Order object you should use $order->get_id() method instead of $order->id.

Here is this new functional code:

add_action( 'woocommerce_order_actions', 'ulmh_resend1' );
function ulmh_resend1( $actions ) {
    $actions['ulmh_resend'] = __( 'Resend Email', 'text_domain' );
    return $actions;
}

add_action( 'woocommerce_order_action_ulmh_resend', 'ulmh_resend2' );
function ulmh_resend2( $order ) {
    $wc_emails = WC()->mailer()->get_emails();
    if( empty( $wc_emails ) ) return;

    if ($order->has_status( 'on-hold' ))
        $email_id = 'customer_on_hold_order';
    elseif ($order->has_status( 'processing' ))
        $email_id = 'customer_processing_order';
    elseif ($order->has_status( 'completed' ))
        $email_id = 'customer_completed_order';
    else
        $email_id = "nothing";

    foreach ( $wc_emails as $wc_mail )
        if ( $wc_mail->id == $email_id )
            $wc_mail->trigger( $order->get_id() );
}

add_filter( 'woocommerce_resend_order_emails_available', 'ulmh_resend3' );
function ulmh_resend3( $order_emails ) {
    $remove = array( 'new_order', 'cancelled_order', 'customer_processing_order', 'customer_completed_order', 'customer_invoice' );
    $order_emails = array_diff( $order_emails, $remove );
    return $order_emails;
}

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

This code is tested in WooCommerce 3+ and works fine now for on-hold order status email notifications, when resending