0
votes

The store offers physical products and workshop classes. There are many product categories for physical products. There is ONE product category for workshop classes, called "ticket". I want the email invoice to display "Workshop Instructions/Policies" (location of venue; cancellation policy; etc.) if the order includes a workshop class and "Return Policies" if it includes physical products.

In other words, if any product in the order has a product category id corresponding to "ticket", I need to show Workshop Instructions/Policies. And if any product in the order has a product category id corresponding to ANYTHING OTHER THAN "ticket", I need to display "Return Policies".

I "sort of" have this working.

The problem is that I can only get this to work by displaying the policies ABOVE the Order Items table in the email. The customer wants the policies at the BOTTOM, which makes sense.

The code that works is at the bottom of the email-order-items.php template. Inside the foreach loop in that file, I have this:

$nwb_product_cat_ids[] = wc_get_product_cat_ids( $item['product_id'] );

After the close of the foreach loop is where I do some tweaking (reducing the multidimensional array to a simple array and removing duplicates) and then evaluating which policies need to be displayed.

I have defined the workshop ("ticket") product category in the variable $nwb_ticket_cat_id. Here are the two if loops:

if ( in_array( $nwb_ticket_cat_id, $nwb_product_cat_ids_reduced ) ) {
    $nwb_show_policy_class = true;
}

if ( count($nwb_product_cat_ids_reduced) > 1 
|| 
!in_array( $nwb_ticket_cat_id, $nwb_product_cat_ids_reduced ) ) {
    $nwb_show_policy_return = true;
}

Then I have this:

<?php if ( $nwb_show_policy_return ) : ?>
    <p>Here is our return policy:</p>
<?php endif; ?>

<?php if ( $nwb_show_policy_class ) : ?>
    <p>Here is our class policy:</p>
<?php endif; ?>

As I said, this works, but only by displaying the content ABOVE the order details table.

I've tried (rather blindly, I must admit) to utilize action hooks, to no avail.

Help wanted. I'm sure I need to provide more information and will do so gladly.

1

1 Answers

0
votes

I solved it. Here is the code:

function nwb_show_policies_under_items_table($order, $sent_to_admin) {
    if ( $sent_to_admin ) {
        return; // Not showing on the admin notice.
    }
    $nwb_ticket_cat_id = NWB_TICKET_CAT_ID; // The product_cat ID corresponding to "Ticikets"
    $nwb_product_cat_ids = array(); // init Array of product IDs for this order
    $nwb_show_policy_class = false; // init
    $nwb_show_policy_return = false; // init
    $items = $order->get_items(); // Get the items for this order
    // Populate the array of product category IDs for this order:
    foreach ( $items as $key => $item ) {
        $nwb_product_cat_ids[] = wc_get_product_cat_ids( $item['product_id'] );
    }
    // Reduce the multidimensional array to a flat one:
    $nwb_product_cat_ids_reduced = call_user_func_array('array_merge', $nwb_product_cat_ids);
    // Get rid of ducplicate product_cat IDS:
    $nwb_product_cat_ids_reduced = array_unique($nwb_product_cat_ids_reduced);

    // If our ticket product_cat_id is in there, then we need to show the Class Instructions/Policies
    if ( in_array( $nwb_ticket_cat_id, $nwb_product_cat_ids_reduced ) ) {
        $nwb_show_policy_class = true;
    }
    // And here's how we determine whether the order includes a product OTHER THAN "ticket"
    if ( count($nwb_product_cat_ids_reduced) > 1 || !in_array( $nwb_ticket_cat_id, $nwb_product_cat_ids_reduced ) ) {
        $nwb_show_policy_return = true;
    }

    // And now we show the policies if applicable:
    if ( $nwb_show_policy_class ) {
        echo nwb_woo_policy('class');
    }
    if ( $nwb_show_policy_return ) {
        echo nwb_woo_policy('other');
    }
}
add_action( 'woocommerce_email_after_order_table', 'nwb_show_policies_under_items_table', 10, 2 );

The nwb_woo_policy() function simply assembles and returns the verbiage for each case (class, or "ticket", and other) using a switch construct.