D. Bleumink
D. Bleumink

Reputation: 69

Attaching additional hidden information to Woocommerce order

So I'm stuck with a problem in Woocommerce here. I don't know if the subject of this question is the solution here, but let me explain what I want to achieve.

I've created this function that sums all the total prices of the products in a cart within a certain category into a subtotal. Based on that subtotal the user gets a message that says what amount in € users get:

## Category based sum ##
function cat_cart_sum($cat_id) {
    if ( ! is_page( 'winkelmand' ) ) {
        return;
    }
    $cat_count = 0; 
    // Iterating through each cart item
    foreach(WC()->cart->get_cart() as $cart_item)  
        if( has_term( $cat_id, 'product_cat', $cart_item['product_id'])) {
            $regularprice = $cart_item['data']->get_price();
            $price = $regularprice * $cart_item['quantity'];
            $cat_count += $price;
        }
    if ($cat_count >= 40 && $cat_count <= 100) {
        wc_add_notice('U krijgt bij het afhalen €10 gratis vuurwerk!', 'notice');
        } elseif ($cat_count > 100 && $cat_count <= 200) {
            wc_add_notice('U krijgt bij het afhalen €25 gratis vuurwerk!', 'notice');
        } elseif ($cat_count > 200 && $cat_count <= 300) {
            wc_add_notice('U krijgt bij het afhalen €50 gratis vuurwerk!', 'notice');
        } elseif ($cat_count > 300 && $cat_count <= 400) {
            wc_add_notice('U krijgt bij het afhalen €75 gratis vuurwerk!', 'notice');
        } elseif ($cat_count >= 400) {
            wc_add_notice('U krijgt bij het afhalen €100 gratis vuurwerk!', 'notice');
        }
    return $cat_count;
}

The users now know how much they are getting. But only in their cart. I want to be able to call this amount from anywhere e-mail, invoice or whatever. I'm lost in this problem. Does anyone have a solution?

Kind regards

Upvotes: 1

Views: 226

Answers (1)

LoicTheAztec
LoicTheAztec

Reputation: 254212

The WC()->cart object will not work with Orders and with Email notifications… So you cant use it once customer has checkout.

Also with if ( ! is_page( 'winkelmand' ) ) return; this code will only work on page 'winkelmand'… For Order.

Below you will find your rearranged function with 3 arguments:

  • $cat_id (the category ID)
  • $arg (optional: The order ID or the WC_Order Object)
  • $is_email (optional: (boolean) to be set to 'true' on email notifications only)

This function has 2 loops:

  • The cart items loop that will work if $arg is not defined…
  • The Order items loop that will work instead if $arg is defined (by the Order Id or the order object).

Here is the code of your function:

function cat_sum( $cat_id, $arg = null, $is_email = false ) {
    // Will work everywhere except on page 'winkelmand'
    if ( is_page( 'winkelmand' ) ) return;

    $total_count = 0;
    $type = gettype($arg);

    // 1. WC_Cart
    if( $type == 'NULL' && gettype(WC()->cart) == 'object' && ! WC()->cart->is_empty() ){
        // Iterating through each cart item
        foreach(WC()->cart->get_cart() as $cart_item)
            if( has_term( $cat_id, 'product_cat', $cart_item['product_id'] ) )
                $total_count += $cart_item['data']->get_price() * $cart_item['quantity'];
        $is_order = false; // Not an order
    }
    // Order ID is set in $arg
    elseif( $type == 'integer' || $type == 'string' ){
        // get an instance of the WC_Order object
        $order = wc_get_order($arg);
        $is_order = true; // An order
    }
    // WC_Order Object is set in $arg
    elseif( $type == 'object' ){
        $order = $arg;
        $is_order = true; // An order
    }
    else return;

    // 2. WC_Order
    if( $is_order )
        foreach($order->get_items() as $item )
            if( has_term( $cat_id, 'product_cat', $item->get_product_id() ) )
                $total_count += $item->get_product()->get_price() * $item->get_quantity();

    // Display notice
    if ( $total_count >= 40 && $total_count <= 100 )
        $message = __( 'U krijgt bij het afhalen €10 gratis vuurwerk!' );
    elseif ( $total_count > 100 && $total_count <= 200 )
        $message = __( 'U krijgt bij het afhalen €25 gratis vuurwerk!' );
    elseif ( $total_count > 200 && $total_count <= 300 )
        $message = __( 'U krijgt bij het afhalen €50 gratis vuurwerk!' );
    elseif ( $total_count > 300 && $total_count <= 400 )
        $message = __( 'U krijgt bij het afhalen €75 gratis vuurwerk!' );
    elseif ( $total_count >= 400 )
        $message = __( 'U krijgt bij het afhalen €100 gratis vuurwerk!' );
    else return;

    if( ! $is_email ){
        wc_add_notice( $message, 'notice' );
        return $total_count;
    } else {
        return array(
            'total' => $total_count,
            'notice' => $message
        );
    }
}

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


USAGE:

1) When WC_Cart object is available (before customer has checkout). You will use it as you do (for example with 'clothing' category):

$cat_count = cat_sum( 'clothing' );
echo '<p>'.$cat_count.'</p>';

2) When WC_Cart object is not available (after customer has checkout). you will need to set the Order ID or the WC_Order Object like in this example in Order received page (Thankyou):

add_action( 'woocommerce_thankyou', 'cat_count_in_thankyou', 10, 1 );
function cat_count_in_thankyou( $order_id ) {
    echo '<p>'.cat_sum( 'clothing', $order_id ).'</p>';
}

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

3) In Email notifications (the WC_Cart object is not available and Notices are not displayed) and you will need to set the Order ID or the WC_Order Object. For this case, we use the third argument set to true. The function will return an array with the category count and the corresponding message (notice).

This example will work on email notifications:

// Display the total Cat in email notifications
add_action( 'woocommerce_email_after_order_table', 'add_cat_sum_to_emails', 9, 4 );
function add_cat_sum_to_emails( $order, $sent_to_admin, $plain_text, $email ){
    $cat_sum = cat_sum( 'clothing', $order, true );
    echo '<p>Total cat: '.$cat_sum['total'].'</p>';
}

// Display the notice in email notifications
add_action( 'woocommerce_email_order_details', 'add_custom_notice_to_emails', 4, 4 );
function add_custom_notice_to_emails( $order, $sent_to_admin, $plain_text, $email ){
    $cat_sum = cat_sum( 'clothing', $order, true );
    echo '<p style="border:solid 1px #333; padding:12px;"> '.$cat_sum['notice'].'</p>';
}

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

Everything is tested and works.

Upvotes: 1

Related Questions