Display purchase note in Woocommerce admin email notifications - php

I am using a function in my functions.php file to display the purchase note for products in Woocommerce customer email. It looks like this:
function sww_add_note_woocommerce_emails( $output, $order ) {
// set a flag so we don't recursively call this filter
static $run = 0;
// if we've already run this filter, bail out
if ( $run ) {
return $output;
}
$args = array(
'show_purchase_note' => true,
);
// increment our flag so we don't run again
$run++;
// if first run, give WooComm our updated table
return wc_get_email_order_items( $order, $args );
}
add_filter( 'wc_get_email_order_items', 'sww_add_note_woocommerce_emails', 10, 2 );
This works perfectly for the email that the customer receives, but I also want it to display the notes in the 'new order' email that admin receives.
They both use the same order table so I'm not sure why it isn't working.

I didn't find a hook for wc_get_email_order_items but a function with some other hooks. Try instead:
add_filter( 'woocommerce_email_order_items_args', 'display_customer_note_in_all_emails', 10, 1 );
function display_customer_note_in_all_emails( $args ) {
$args['show_purchase_note'] = true;
return $args;
}
Code goes in function.php file of your active child theme (or active theme). It should works.

Related

Remove cancel button from WooCommerce My account Orders conditionally

I want to make sure the cancel button is not visible in my-account> my-order when 'Payment Method Title' is 'Npay'.
The 'Npay' is an external payment gateway and does not work with the commerce. Therefore, payment cancellation must be done externally only.
add_filter('woocommerce_my_account_my_orders_actions', 'remove_my_cancel_button', 10, 2);
function remove_my_cancel_button($actions, $order){
if ( $payment_method->has_title( 'Npay' ) ) {
unset($actions['cancel']);
return $actions;
}
}
To remove the cancel button from My account Orders, we use the following:
add_filter('woocommerce_my_account_my_orders_actions', 'remove_myaccount_orders_cancel_button', 10, 2);
function remove_myaccount_orders_cancel_button( $actions, $order ){
unset($actions['cancel']);
return $actions;
}
But to remove the cancel button from My account Orders based on the payment title, you will use the WC_Order method get_payment_method_title() like:
add_filter('woocommerce_my_account_my_orders_actions', 'remove_myaccount_orders_cancel_button', 10, 2);
function remove_myaccount_orders_cancel_button( $actions, $order ){
if ( $order->get_payment_method_title() === 'Npay' ) {
unset($actions['cancel']);
}
return $actions;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
The main variable argument $actions need to be returned at the end outside the IF statement

Display custom text on WooCommerce Order Received page if specific coupons are used

I'm attempting to display a custom thank you message on the Woocommerce order received page if one of three specific coupon codes are used during checkout.
Our Woocommerce version is 2.6.11.
I've tried a few variations of the below code but cannot get it working, am I doing something incorrectly?
//show custom coupon thankyou
function coupon_thankyou($order_id) {
$coupon_id = '1635';
$order = wc_get_order($order_id);
foreach( $order->get_items('coupon') as $coupon_item ){
if( $coupon_item->get_code() = $coupon_id ){
echo '<p>This is an custom thank you.</p>';
}
}
}
add_action('woocommerce_thankyou','coupon_thankyou');
There is a mistake in your IF statement condition where = has to be replaced with == or ===. Also with coupons, you need to use the coupon code slug (but not the post ID).
To display a message on Order received page better use woocommerce_thankyou_order_received_text filter hook, this way (for Woocommerce 3+):
// On "Order received" page (add a message)
add_filter( 'woocommerce_thankyou_order_received_text', 'thankyou_applied_coupon_message', 10, 2 );
function thankyou_applied_coupon_message( $text, $order ) {
$coupon_code = '1635'; // coupon code name
foreach( $order->get_items('coupon') as $coupon ){
if( $coupon->get_code() === $coupon_code ){
$text .= '<p>'.__("This is an custom thank you.").'</p>';
}
}
return $text;
}
Code goes in function.php file of your active child theme (or active theme). It should works now.
Updated
For the versions of Woocommerce before 3.0, you should use use the following instead:
// On "Order received" page (add a message)
add_action( 'woocommerce_thankyou', 'thankyou_applied_coupon_message', 10, 1 );
function thankyou_applied_coupon_message( $order_id ) {
$coupon_code = '1635'; // coupon code name
$order = wc_get_order( $order_id );
foreach( $order->get_items('coupon') as $coupon ){
if( $coupon['name'] === $coupon_code ){
echo '<p>'.__("This is an custom thank you.").'</p>';
}
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.

Stop send specific email notification for specific users in Woocommerce

I want to stop send Woocommerce email for specific user/email. this is my example code to stop send email when order is completed.
<?php
add_filter( 'woocommerce_email_headers', 'ieo_ignore_function', 10, 2);
function ieo_ignore_function($headers, $email_id, $order) {
$list = 'admin#example.com,cs#example.com';
$user_email = (method_exists( $order, 'get_billing_email' ))? $order->get_billing_email(): $order->billing_email;
$email_class = wc()->mailer();
if($email_id == 'customer_completed_order'){
if(stripos($list, $user_email)!==false){
remove_action( 'woocommerce_order_status_completed_notification', array( $email_class->emails['WC_Email_Customer_Completed_Order'], 'trigger' ) );
}
}
}
But WP keep send the email. I try to search in Woocommerce docs and source (github) and Stackoverflow also but still cant solve this.
In this example "Customer completed order" notification is disable for specific customer email addresses:
// Disable "Customer completed order" for specifics emails
add_filter( 'woocommerce_email_recipient_customer_completed_order', 'completed_email_recipient_customization', 10, 2 );
function completed_email_recipient_customization( $recipient, $order ) {
// Disable "Customer completed order
if( is_a('WC_Order', $order) && in_array($order->get_billing_email(), array('jack#mail.com','emma#mail.com') ) ){
$recipient = '';
}
return $recipient;
}
Code goes in function.php file of your active child theme (active theme). Tested and works.
Note: A filter hook needs always to return the filtered main function argument
It can also be done from User IDs like:
// Disable "Customer completed order" for specifics User IDs
add_filter( 'woocommerce_email_recipient_customer_completed_order', 'completed_email_recipient_customization', 10, 2 );
function completed_email_recipient_customization( $recipient, $order ) {
// Disable "Customer completed order
if( is_a('WC_Order', $order) && in_array($order->get_customer_id(), array(25,87) ) ){
$recipient = '';
}
return $recipient;
}
Code goes in function.php file of your active child theme (active theme). Tested and works.
Similar: Stop specific customer email notification based on payment methods in Woocommerce
While answer above is working, this seems to be more straighforward solution:
add_filter( 'woocommerce_email_recipient_customer_completed_order', 'completed_email_recipient_customization', 10, 2 );
function completed_email_recipient_customization( $recipient, $order ) {
if( in_array($recipient, ['some#email2block.com', 'another#email2block.com'] ) ) {
$recipient = '';
}
return $recipient;
}

Add a custom column to My Account Orders table in Woocommerce 3+

Woocommerce 3.5.x has a special page at the user account (My Account) area where it displays the user's previous Orders.
This page is now 5 column displays as default.
Here the screenshot of the woocommerce Orders area with 5 column:
My Orders
I Can't find the way to change this.
How can I add a new column in the default?
This requires 2 functions that will add a new column
The second function hook is a composite hook: woocommerce_my_account_my_orders_column_{$column_id} where {$column_id} need to be replaced by the column key slug that is set in the first function.
That second function manage the displayed row values and you can add for example a custom field to get custom order meta data values.
The code:
add_filter( 'woocommerce_account_orders_columns', 'add_account_orders_column', 10, 1 );
function add_account_orders_column( $columns ){
$columns['custom-column'] = __( 'New Column', 'woocommerce' );
return $columns;
}
add_action( 'woocommerce_my_account_my_orders_column_custom-column', 'add_account_orders_column_rows' );
function add_account_orders_column_rows( $order ) {
// Example with a custom field
if ( $value = $order->get_meta( '_custom_field' ) ) {
echo esc_html( $value );
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
You are done and have added a custom column to My account orders table:
If you which to make changes in the table html output, you will have to override the template file: myaccount/orders.php
If you don't wanna change the order template under myaccount page. Here's what you have to do.
First:
function wc_add_myaccount_order_column( $columns ) {
$columns[ 'custom-column' ] = __( 'Custom Column', 'woocommerce' );
}
add_filter( 'woocommerce_my_account_my_orders_columns', 'wc_add_myaccount_order_column' );
Second:
function wc_custom_column_display( $order ) {
// do something here
echo "testing";
}
add_action( 'woocommerce_my_account_my_orders_column_custom-column', 'wc_custom_column_display' );
The code above will display "testing" in each order under "Custom Column" column.
Note: If you actually wanna change the entire template, like the design for example. You can follow the first answer above.
Just to improve the accepted answer I add a line to choose the position of the column (after total):
function sv_wc_add_my_account_orders_column( $columns ) {
$new_columns = array();
foreach ( $columns as $key => $name ) {
$new_columns[ $key ] = $name;
// add ship-to after order status column
if ( 'order-total' === $key ) { //this is the line!
$new_columns['custom-column'] = __( 'Custom Column', 'woocommerce' );
}
}
return $new_columns;
}
add_filter( 'woocommerce_my_account_my_orders_columns', 'sv_wc_add_my_account_orders_column' );
function wc_custom_column_display( $order ) {
// do something here
echo "testing";
}
add_action( 'woocommerce_my_account_my_orders_column_custom-column', 'wc_custom_column_display' );
With WooCommerce 5.9, I couldn't get LiocTheAztect's answer to work. What worked for me was:
add_filter( 'woocommerce_account_orders_columns',
'add_customer_email_column');
function add_customer_email_column( $columns ){
$new_columns = [
"order-number" => $columns["order-number"],
// ...
"customer-email" => __( 'Customer Email', '' ),
// ...
"order-actions" => $columns["order-actions"]
];
return $new_columns;
}
add_action( 'woocommerce_my_account_my_orders_column_customer-email',
'add_customer_email_content' );
function add_customer_email_content($order) {
echo esc_html($order->get_billing_email());
}
Without the if ($value = $order->get_meta( '_custom_field' )) block. Hope it helps.

Make state checkout field optional in Woocommerce

Since Woo 3.5.1 the billing state field is mandatory for certain countries and I'm trying to figure out how to not make it mandatory.
This is the code I'm using, which is not working. It seems to be a core change and I don't know if there's a new hook for it?
Code:
add_filter( 'woocommerce_billing_fields', 'remove_mandatory_state_billing', 10, 1 );
function remove_mandatory_state_billing( $address_fields ) {
$address_fields['billing_state']['required'] = false;
return $address_fields;
}
add_filter( 'woocommerce_shipping_fields', 'remove_mandatory_state_shipping', 10, 1 );
function remove_mandatory_state_shipping( $address_fields ) {
$address_fields['shipping_state']['required'] = false;
return $address_fields;
}
Any help is very much appreciated.
The following code will make the state field optional for all countries in Woocommerce:
add_filter( 'woocommerce_get_country_locale', 'custom_country_locale_state_optional', 10, 1 );
function custom_country_locale_state_optional( $locale ) {
foreach( $locale as $country_code => $state_field ) {
if( isset($locale[$country_code]['state']) ) {
$locale[$country_code]['state']['required'] = false;
}
}
return $locale;
}
Code goes in function.php file of your active child theme (active theme). Tested and works.
Related: Make state checkout field required for a specific country in Woocommerce

Categories