2

I am trying to add additional text to email for completed order if order contains two specfic product IDs. Here is my code so far:

function advmi_check_order_product_id($order_id)
{
    $order = new WC_Order($order_id);
    $items = $order->get_items();
    foreach($items as $item) {
        $product_id = $item['product_id'];
        if (($product_id == 56943 && $product_id == 95956 && 'completed' == $order->status )) {
            echo '<p>Added Text for both products in the order</p><p>Text </p>';
        }
        elseif ($product_id == 56943 && 'completed' == $order->status) {
            echo '<p>Text for only 56943 </p><p>Text </p>';
}
        }

I also need the order status to be completed.

I am stuck - Any help on this please?

I am using WC Version: 2.6.14

File_Submit
  • 395
  • 3
  • 13
  • I would assume it is because you are checking whether the product as both of the ids when the product can only have one id? – lky Nov 14 '17 at 09:16

2 Answers2

2

Update 2 - Added Compatibility WC from version 2.4 to 3.2+

Here is the correct way to make your code works (in woocommerce 2.6.x and above), keeping your function, that you will use in a second custom hooked function to get the display in email notifications:

// Your conditional function that output a custom text
// The argument needed is the WC_Order object (instead of the Order ID)
function advmi_check_order_product_id( $order )
{
    $has_product1 = $has_product2 = false; // Initializing
    // Added Compatibility WC from version 2.4 to 3.2+ (Get The order ID)
    ## $order_id = method_exists( $order, 'get_id' ) ? $order->get_id() : $order->id;
    ## $order = new WC_Order($order_id); // Get the WC_Order object

    foreach( $order->get_items() as $item ) {
        // Added Compatibility WC from version 2.4 to 3.2+
        $product_id = method_exists( $item, 'get_product_id' ) ? $item->get_product_id() : $item['product_id'];
        if( 56943 == $product_id ) $has_product1 = true;
        if( 95956 == $product_id ) $has_product2 = true;
    }

    if ( $has_product1 && $has_product2 ) {
        echo '<p>'.__('Added Text for both products in the order').'</p>
            <p>'.__('Text').'</p>';
    }
    elseif ( $has_product1 && ! $has_product2 ) {
        echo '<p>'.__('Text for only 56943').'</p>
            <p>'.__('Text').'</p>';
    }
}

// The email function hooked that display the text
add_action( 'woocommerce_email_order_details', 'add_text_conditionally', 10, 4 );
function add_text_conditionally( $order, $sent_to_admin, $plain_text, $email ) {
    // For customer completed orders status only
    if ( $sent_to_admin || ! $order->has_status('completed') ) return;
    advmi_check_order_product_id( $order );
}

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

Tested and works on versions 2.6.14 and 3.2.3…

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • He wants it for completed orders only not processing. – Andrew Schultz Nov 14 '17 at 12:26
  • @AndrewSchultz Thanks … just an oversight while testing on my side. updated. he can change what he wants… The code is correct there. – LoicTheAztec Nov 14 '17 at 13:20
  • You can also move the check for completed orders outside of the loop. There's no point checking multiple times if the order is complete, the code shouldn't run unless it's a completed order. Just a little optimisation ;) – Andrew Schultz Nov 14 '17 at 13:24
  • @AndrewSchultz yes you are right… updated … Talking optimization, you can also replace $order->get_status() by $order->has_status() in your code… Also $order_item_id is confusing with the Item ID which is very different than the product ID… – LoicTheAztec Nov 14 '17 at 13:39
  • What's the difference between get_status and has_status? They are both inherited from WC_Abstract_Order but I don't see what the benefit of using one over the other would be... Yes correct it should be named product_id, much clearer as to the nature of the variable. – Andrew Schultz Nov 14 '17 at 13:45
  • @AndrewSchultz has_status() is a conditional function, so is maid to be in an if statement for example. that is the difference… I leave to catch my boys at school now :) – LoicTheAztec Nov 14 '17 at 13:57
  • I am using WC Version: 2.6.14 – File_Submit Nov 14 '17 at 14:22
  • Then use the old school notion in the loop "$product_id = $item['product_id'];" – Andrew Schultz Nov 14 '17 at 14:25
  • @File_Submit Update 2 … Added WC Compatibility from version 2.4 to 3.2+ and **tested/working on WC version 2.6.14** – LoicTheAztec Nov 14 '17 at 18:28
1

This will add some text before the order table on completed order emails. I looped through the order items and set flags based on if those items are included in the order.

add_action( 'woocommerce_email_before_order_table', 'add_additonal_order_email_text', 10, 4 );
function add_additonal_order_email_text( $order, $sent_to_admin, $plain_text, $email ) {
    $product_id_1 = 56943;
    $product_id_2 = 95956;
    $product_1_exists = false;
    $product_2_exists = false;

    if ( ! $sent_to_admin && 'completed' == $order->get_status() ) {
        foreach( $order->get_items() as $order_item ) {
            $product_id = $order_item->get_product_id();

            if( $product_id == $product_id_1 )
                $product_1_exists = true;
            elseif( $product_id == $product_id_2 )
                $product_2_exists = true;
        }

        if ( $product_1_exists && $product_2_exists ) {
            echo '<p>Added Text for both products in the order</p><p>Text </p>';
        } 
        elseif ( $product_1_exists && ! product_2_exists ) {
            echo '<p>Text for only 56943 </p><p>Text </p>';
        }
    }
}
LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
Andrew Schultz
  • 4,092
  • 2
  • 21
  • 44
  • Hi, When I var_dump($product_2_exists) or var_dump($product_1_exists) it returns bool(false) and doesn't show the paragraphs. – File_Submit Nov 14 '17 at 11:26
  • Ah sorry I was using the "===" comparison operator when it should be "==" because the function get_product_id() returns a string. I've updated my code. – Andrew Schultz Nov 14 '17 at 12:33
  • @AndrewSchultz you can thank my code for get_product_id() and "==" … – LoicTheAztec Nov 14 '17 at 13:22
  • @LoicTheAztec yes I didn't know about that function thanks alot! I assumed it would return an integer as I have never seen a product ID that is a string. – Andrew Schultz Nov 14 '17 at 13:25
  • Order $items (line items) is a WC_Order_Item_Product object since WC 3+ so prperties can't be accessed directly and you should have to use the available methods getters and setters for this class… see: https://stackoverflow.com/questions/45706007/order-items-and-wc-order-item-product-object-in-woocommerce-3 – LoicTheAztec Nov 14 '17 at 13:29
  • Ok awesome, all my clients are still on WooCommerce 2.6 so this will be handy when I upgrade them to 3.0! – Andrew Schultz Nov 14 '17 at 13:32
  • I am using WC Version: 2.6.14 – File_Submit Nov 14 '17 at 14:22