0

I've been asked to configure a specific WooCommerce behaviour, and I can't escape having to do it with filters. Which I'm not really competent in.

What is supposed to happen, exactly, is that when an order consists only of a product from the "abo" category, it is automatically marked as 'Complete' and the admin mail is sent to a different service.

I've gathered a few examples of code, changing the e-mail recipient, the order status, or making generic changes according to the product category. This is my Frankenstein monster of a code. Both the e-mail change and the order status change failed.

/**
 * Change email recipient for admin New Order emails when the order only has products from the 'abo' category
 *
 * @param string $recipient a comma-separated string of email recipients (will turn into an array after this filter!)
 * @param \WC_Order $order the order object for which the email is sent
 * @return string $recipient the updated list of email recipients
 */
add_filter( 'woocommerce_email_recipient_new_order', 'dada_conditional_email_recipient', 10, 2 );
function dada_conditional_email_recipient( $recipient, $order ) {
    // Bail on WC settings pages since the order object isn't yet set yet
    // Not sure why this is even a thing, but shikata ga nai
    $page = $_GET['page'] = isset( $_GET['page'] ) ? $_GET['page'] : '';
    if ( 'wc-settings' === $page ) {
        return $recipient; 
    }

    // just in case
    if ( ! $order instanceof WC_Order ) {
        return $recipient; 
    }
    $items = $order->get_items();

    foreach ( $items as $item ) {
        $product = $order->get_product_from_item( $item );

        // check if there's an "abo" in the order, then if there's anything else.
        if ( is_product() && has_term( 'abo', 'product_cat' ) ) {
            $abo_in_order = 'true';
        }
        if ( is_product() && has_term( 'livre', 'product_cat' ) || has_term( 'revue', 'product_cat' ) || has_term( 'livre', 'product_cat' ) ) {
            $abo_alone_in_order = 'false';
        }
        else {
            $abo_alone_in_order = 'true';
        }
    }
    // if there's an 'abo' and nothing else, change the e-mail recipient to dada@sotiaf.fr
    if ( ($abo_in_order == 'true')&&($abo_alone_in_order == 'true') ) $recipient = 'dada@sotiaf.fr';
    return $recipient;
}


/**
 * Autocomplete orders with only an 'abo' product
 */

add_filter( 'woocommerce_payment_complete_order_status', 'dada_abo_order_autocomplete', 10, 2 );
function dada_abo_order_autocomplete( $order_status, $order_id ) {

    $order = wc_get_order( $order_id );
    if ('processing' == $order_status && ('on-hold' == $order->status || 'pending' == $order->status || 'failed' == $order->status)) {

        // just in case
        if ( ! $order instanceof WC_Order ) {
            return $order_status; 
        }
        $items = $order->get_items();

        foreach ( $items as $item ) {
            $product = $order->get_product_from_item( $item );

            // check if there's an "abo" in the order, then if there's anything else.
            if ( is_product() && has_term( 'abo', 'product_cat' ) ) {
                $abo_in_order = 'true';
            }
            if ( is_product() && has_term( 'livre', 'product_cat' ) || has_term( 'revue', 'product_cat' ) || has_term( 'livre', 'product_cat' ) ) {
                $abo_alone_in_order = 'false';
            }
            else {
                $abo_alone_in_order = 'true';
            }
        }
        // if there's an 'abo' and nothing else, change the order status to 'completed'
        if ( ($abo_in_order == 'true')&&($abo_alone_in_order == 'true') ) $order_status = 'completed';
    }
    return $order_status;
}

Any idea where the issue comes from?

Thank you, Joss

1 Answers1

0
  1. You should implement "woocommerce_thankyou" hook for order status update instead of "woocommerce_payment_complete_order_status". Because, your current update order status code will trigerr when any order with completed status is placed. But your requirement is to change status to "Completed".

  2. For adding new email recepient dynamically, you should try this hook : "woocommerce_email_recipient_new_order" Refer to this : WooCommerce send new order email to customer

Community
  • 1
  • 1
Vidish Purohit
  • 1,048
  • 11
  • 20
  • Thanks, I'll try to use the "woocommerce_thankyou" hook. For the new email recipient, however, that's the code I started from, so I'm guessing it's failing somewhere around the category identification part. – YearZeroJoss Apr 14 '17 at 11:49
  • Yes. Check your category logic. If you found my answer helpful, you can accept it and upvote it. – Vidish Purohit Apr 14 '17 at 12:23