Conditional custom New Order Woocommerce email notification on different recippients - php

Okay I have had a question come from a client that doesn't seem impossible, but correctly setting up the conditions is a problem for me. Here is what is happening and what I need. i would really this to be a function of possible.
The store has a user hierarchy. There are 2x Super Admins (ID: admin), 5x Admins (ID: admin2), 15x Bank Customers (ID: banks), and 2x Real Estate customers (ID: real estate). I have already setup the custom users with the ID's. No products have pricing. Everything is invoiced in an email with the order_info. Everything is paid at a later date in house. So the site really relies on emails.
If the 15x Bank Customers place a new_order, these new_order(s) need to send the email invoice to the 5x Admins.
If the 2x Real Estate customers place a new_order, these new_order(s) need to send the email invoice to the 5x Admins.
If the 5x Admins place a new_order, these new_order(s) need to send the email invoice to the 2x Super Admins.
I am not the greatest with php and what I had previous was very sloppy.
Any help?

You can use wc hook as follows in functions.php filr
add_action( 'woocommerce_new_order', 'send_email_to_admin', 1, 1 );
function send_email_to_admin($order_id) {
// use order id to find user id and send email
}

Using a custom function hooked in woocommerce_thankyou action hook, will allow you to make that conditional email notifications based on user roles and on custom multiple recipients.
You will need to replace admins and super admins email in this function.
You will need also to check that the users roles are matching in the 3 if statements… The ID for Real estate can't have a space normally and should be instead: 'real_estate'
This will send email notifications for orders that have a status like 'on-hold', 'pending', 'processing' or 'completed'...
Once this custom email will be triggered a custom field '_custom_emails_sent' will be set for the order.
Here is the code:
add_action( 'woocommerce_thankyou', 'custom_new_order_email_notifications', 10, 1 );
function custom_new_order_email_notifications( $order_id ){
// If Custom Emails already sent we exit
if( get_post_meta( $order_id, '_custom_emails_sent', true ) ) return;
$targeted_statuses = array( 'wc-on-hold', 'wc-pending', 'wc-processing', 'wc-completed' );
$order_status = get_post_status( $order_id );
// Only for the correct order statuses; If not we exit
if( ! in_array( $order_status, $targeted_statuses ) ) return;
// HERE (below) replace super admins and admins REAL emails
$super_admin_emails = array(
'supadmin1#example.com', 'supadmin2#example.com' );
$admin_emails = array(
'admin1#example.com', 'admin2#example.com',
'admin3#example.com', 'admin4#example.com', 'admin5#example.com' );
// Get the user of the order
$user_id = get_post_meta( $order_id, '_customer_user', true );
$user = get_userdata( $user_id );
$recipient = '';
// 1. Bank Customers user role
if( in_array('banks', $user->roles) ){
$recipients = implode(',', $admin_emails);
}
// 2. Real estate Customers user role
if( in_array('real_estate', $user->roles) ){
$recipients = implode(',', $admin_emails);
}
// 3. Admins Customers user role
if( in_array('admin2', $user->roles) ){
$recipients = implode(',', $admin_emails);
}
// Sending new order email notification to the targeted recipients
if( '' != $recipients ){
$mailer = WC()->mailer()->get_emails();
$mailer['WC_Email_New_Order']->recipient = $recipients;
$mailer['WC_Email_New_Order']->trigger( $order_id ); // sending
// We set a custom field that will avoid repetitive sends
update_post_meta( $order_id, '_custom_emails_sent', '1' );
}
}
Code goes in function.php file of your active child theme (or active theme).
Tested and works

Related

Receiving duplicated Woocommerce mail for completed order

I was planning to get Notified by mail when the customer has a pending order and I found out that I can do it this way:
Send an Email notification to the admin for pending order status in WooCommerce
The thing that surprised me is after using this on function.php, now I can only get Woocommerce admin mail when an order is pending, even after I deleted this code, it didn't change (not receiving admin mail for completed orders).
But it's ok I wanted the pending mail anyways.
So after this change now I'm not receiving completed order mails as admin and I have found the solution on :
Allow re-sending New Order Notification in WooCommerce 5+
The only problem I have now is that I'm getting duplicated completed order for admin (customer mails are fine)
add_action( 'woocommerce_checkout_order_processed', 'pending_new_order_notification', 20, 1 );
function pending_new_order_notification( $order_id ) {
// Get an instance of the WC_Order object
$order = wc_get_order( $order_id );
// Only for "pending" order status
if( ! $order->has_status( 'pending' ) ) return;
// Get an instance of the WC_Email_New_Order object
$wc_email = WC()->mailer()->get_emails()['WC_Email_New_Order'];
## -- Customizing Heading, subject (and optionally add recipients) -- ##
// Change Subject
$wc_email->settings['subject'] = __('{site_title} - New customer Pending order ({order_number}) - {order_date}');
// Change Heading
$wc_email->settings['heading'] = __('New customer Pending Order');
// $wc_email->settings['recipient'] .= ',name#email.com'; // Add email recipients (coma separated)
// Send "New Email" notification (to admin)
$wc_email->trigger( $order_id );
}
add_action('woocommerce_order_status_completed', 'email_completed_order_admin_notification', 10, 2 );
function email_completed_order_admin_notification( $order_id, $order ) {
WC()->mailer()->get_emails()['WC_Email_New_Order']->trigger( $order_id );
}
add_filter('woocommerce_new_order_email_allows_resend', '__return_true' );
add_filter('woocommerce_new_order_email_allows_resend', '__return_true' ); this one is making me receive completed order mails again but also making it duplicated.

Remove product purchase notes in certain WooCommerce email notifications

I try to remove the purchase notes from the order completed mail. Currently the purchase notes are in the order confirmation mail and also in the order completed mail. But we do not want that info in the order completed mail.
So for that I found this input here: https://wordpress.stackexchange.com/questions/340045/how-do-i-hide-the-purchase-note-in-the-woocommerce-order-completed-email
I also found that snipped here below. But with that it removes it everywhere and not just in the order complete mail. Any advice?
add_filter('woocommerce_email_order_items_args','remove_order_note',12);
function remove_order_note($args){
$args['show_purchase_note']= false;
return $args;
}
You can use the email ID to target specific email notifications in WooCommerce.
However, because this is not known in the hook you are using, we will make the email id globally available via another hook
So you get:
// Setting the email_is as a global variable
function action_woocommerce_email_before_order_table( $order, $sent_to_admin, $plain_text, $email ) {
$GLOBALS['email_id_str'] = $email->id;
}
add_action( 'woocommerce_email_before_order_table', 'action_woocommerce_email_before_order_table', 10, 4 );
function filter_woocommerce_email_order_items_args( $args ) {
// Getting the email ID global variable
$refNameGlobalsVar = $GLOBALS;
$email_id = isset( $refNameGlobalsVar['email_id_str'] ) ? $refNameGlobalsVar['email_id_str'] : '';
// Targeting specific email. Multiple statuses can be added, separated by a comma
if ( in_array( $email_id, array( 'customer_completed_order', 'customer_invoice' ) ) ) {
// False
$args['show_purchase_note'] = false;
}
return $args;
}
add_filter( 'woocommerce_email_order_items_args', 'filter_woocommerce_email_order_items_args', 10, 1 );
Note: How to target other WooCommerce order emails
Used in this answer: Changing in WooCommerce email notification Order Item table "Product" label

Add account email conditionally on Customer processing Order email notification in Woocommerce

So this is more of my solution here but I wanted to open this up to see if the community could find a better alternative or potentially find use for this solve.
Our client asked us for the following alteration to the email order receipts received on order creation: The receipts should go to the account holder and cc the billing email if it's different
As we know Woocommerce by default sends the order receipt (Customer Processing) based on only the set billing_email on checkout so I started to look for a way to add on the tack on the account owner email to it as well.
I did some digging and found a few answers on Stackoverflow on how to do this and the proposed solution utilized the woocommerce_email_recipient_customer_processing_order built-in function. This approach would only add on the email in the "to" header -less than ideal. It also doesn't account for potential duplicate sends to the same email address which, at least in the case of our server here, caused the email to not be delivered. No bueno.
The function below represents a work around this wherein we're calling upon the WP Core function wp_get_current_user() to obtain the email that the user is associated with and then checking whether it's the same as the billing email.
add_filter( 'woocommerce_email_headers', 'add_email_recipient', 10, 3);
function add_email_recipient($header, $email_id, $order) {
// Only for "Customer Processing Emails" email notifications
if( ! ( 'customer_processing_order' == $email_id ) ) return;
$curr_user = wp_get_current_user();
$account_holder_email = $curr_user->user_email;
$billing_email = $order->get_billing_email();
$header ='';
if ( $account_holder_email != $billing_email ) {
$header .= 'Cc: '.$account_holder_email;
}
return $header;
}
The logic intends to flow the following way:
Adjust the woocommerce email headers
If the email is the "customer_processing_order" continue
Get the current user email
Get the billing email set in the order
assign a CC field of the current user email
done
As far as I could tell there wasn't an easier way to handle this so I'm posting this up here in the hopes to see if someone else has a more elegant solution. The above code works by placing in the child theme functions.php.
You can't get the current user or the current user ID on email notification hooks.
You need first to get the customer ID from the order, then you can get the WP_User object to get the account email.
There is 2 different ways to add the customer account email when it's different from the order billing email in Customer processing order email notification:
1) Add the customer account email as an additional recipient:
add_filter( 'woocommerce_email_recipient_customer_processing_order', 'add_customer_processing_order_email_recipient', 10, 2 );
function add_customer_processing_order_email_recipient( $recipient, $order ) {
// Not in backend (avoiding errors)
if( is_admin() ) return $recipient;
if( $order->get_customer_id() > 0 ){
// Get the customer WP_User object
$wp_user = new WP_User($order->get_customer_id());
if ( $wp_user->user_email != $order->get_billing_email() ) {
// Add account user email to existing recipient
$recipient .= ','.$wp_user->user_email;
}
}
return $recipient;
}
Code goes in function.php file of your active child theme (active theme). It should works.
2) Add the customer account email as a CC email address:
add_filter( 'woocommerce_email_headers', 'add_cc_email_to_headers', 10, 3);
function add_cc_email_to_headers($header, $email_id, $order) {
// Only for "Customer Processing Emails" email notifications
if( 'customer_processing_order' == $email_id ) {
if( $order->get_customer_id() > 0 ){
// Get the customer WP_User object
$wp_user = new WP_User($order->get_customer_id());
if ( $wp_user->user_email != $order->get_billing_email() ) {
$header .= 'Cc: ' . utf8_decode($order->get_formatted_billing_full_name() . ' <' . $wp_user->user_email . '>') . "\r\n";
}
}
}
return $header;
}
Code goes in function.php file of your active child theme (active theme). It should works.

Send Woocommerce new order email notification from specific user role to specific user

We have a "main wholesaler" who is in charge of other wholesalers. This wholesaler is assigned to user role: wholesale_customer just as the other wholesalers.
This "main wholesaler" places orders for his stores, and the other wholesalers place orders for their own stores as normal.
I would like that the "main wholesaler" receive an email notification when the other wholesalers place their orders, so he will get notified when other wholesalers are ordering because he gets a commission.
So is there a way that we can make the "main wholesaler" to receive an email notification when the other wholesalers place their orders?
Maybe this can be done with a function somewhat like this:
WooCommerce email notifications: different email recipient for different cities
Any help is appreciated.
Updated (solved a bug in backend email settings)
The following function will send an additional "new order" email notidfication to the "Wholesale manager" when others wholesale_customer user roles will make a purchase.
You will just need to set in this function the User ID for the "Wholesale manager"…
add_filter( 'woocommerce_email_recipient_new_order', 'wholesale_manager_email_recipient', 20, 2 );
function wholesale_manager_email_recipient( $recipient, $order ) {
if( is_admin() ) return $recipient;
// Only for 'wholesale_customer' user role
if( is_admin() || ! user_can( $order->get_user_id(), 'wholesale_customer' ) )
return $recipient; // Exit if not a 'wholesale_customer'
// HERE Set the main wholesale manager user ID
$manager_id = 5;
$manager_user = new WP_User( $manager_id );
$manager_email = $manager_user->user_email;
// Add manager email when other 'wholesale_customer' place orders
if ( $order->get_user_id() != $manager_id )
$recipient .= ',' . $manager_email; // coma separate emails
return $recipient;
}
Code goes in function.php file of your active child theme (or theme). Tested and works.

Get customer order count in new order email notification

I'd like to indicate in WooCommerce "new order" email notification, if it's a repeat customer.
It seems simple, but I've tried about 5 different methods and none worked. I've tried putting this into 2 different hooks:
woocommerce_email_after_order_table
woocommerce_email_subject_new_order.
Seems like wc_get_customer_order_count($user->ID) should work but it appears that the $user object is not passed into those hook's functions, right?
I'm also wondering if this is possible when it's a guest and not a registered user, maybe by comparing the email address?
Thanks
WooCommerce Email notifications are related to orders.
In woocommerce_email_after_order_table hook, you have the Order object as an argument in your hooked custom function and also the $email object.
With that $order object, you can get the user ID this way:
$user_id = $user_id = $order->get_user_id();
From the $email object you can target the new order email notification.
So the working code is going to be:
add_action( 'woocommerce_email_after_order_table', 'customer_order_count', 10, 4);
function customer_order_count( $order, $sent_to_admin, $plain_text, $email ){
if ( $order->get_user_id() > 0 ){
// Targetting new orders (that will be sent to customer and to shop manager)
if ( 'new_order' == $email->id ){
// Getting the user ID
$user_id = $order->get_user_id();
// Get the user order count
$order_count = wc_get_customer_order_count( $user_id );
// Display the user order count
echo '<p>Customer order count: '.$order_count.'</p>';
}
}
}
You can also use instead the woocommerce_email_before_order_table hook for example…
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and works.

Categories