Save custom delivery dates range calculations to WooCommerce order meta data

為{幸葍}努か 提交于 2021-01-28 10:05:53

问题


I use woocommerce and have written a function, which displays a date range for expected delivery based on the stock status...
For reference: Display an estimated delivery date range based on WooCommerce cart item stock

Now I want to output the calculated date range into my admin panel for each order.

For the Orders edit pages in the Wordpress backend I use this code:

 add_action( 'add_meta_boxes', 'add_meta_boxes' );
function add_meta_boxes() {
    add_meta_box(  'woocommerce-order-my-custom', __( 'Order Custom' ), 
        'order_my_custom', 'shop_order', 'side', 'default' 
    );
}

function order_my_custom(){
  echo "Voraussichtliche Lieferung<br> $from - $to";
}

The date range is calculated and displayed on front end with this code:

add_filter ( 'woocommerce_cart_collaterals', 'lieferzeit');
add_filter ( 'woocommerce_thankyou_lieferung', 'lieferzeit');
function lieferzeit() {

    $all_items_in_stock = true; // initializing

    // Iterating through cart items (to get the stock info)
    foreach (WC()->cart->get_cart() as $cart_item) {

        # HANDLING SIMPLE AND VARIABLE PRODUCTS

        // Variable products
        $variation_id = $cart_item['variation_id']; 
        if( 0 != $variation_id) {
            $variation_obj = new WC_Product_variation($variation_id);
            $stock = $variation_obj->get_stock_quantity();
        } else { 
            // Simple products
            $product_id = $cart_item['product_id'];
            $product_obj = new WC_Product($product_id);
            $stock = $product_obj->get_stock_quantity();
        }

        if( $stock <= 0 ){
            // if an item is out of stock
            $all_items_in_stock = false;
            break; // We break the loop
        }
    }

    // Items "in stock" (1 to 4 week days)
    if( $all_items_in_stock ){
        for( $start=0, $count=-1 ; $count < 4; $start++ ){
            $weekdays = date('w', strtotime("+$start days"));
            if( $weekdays > 0 && $weekdays < 6 ){
                $count++;
//            echo date('D j (w)', strtotime("+$start days")).', ';
                if($count == 1){
                    $from = date('D, d.m.', strtotime("+$start days") );
                } elseif($count == 4) {
                    $to = date('D, d.m.', strtotime("+$start days") );
                }
            }
        }
    } else { // 1 is Items Out of stock (14 to 21 week days)
        for( $start=0, $count=-1 ; $count < 21; $start++ ){
            $weekdays = date('w', strtotime("+$start days"));
            if( $weekdays > 0 && $weekdays < 6 ){
                $count++;
                if($count == 14){
                    $from = date('D, d.m.', strtotime("+$start days") );
                } elseif($count == 21) {
                    $to = date('D, d.m.', strtotime("+$start days") );
                }
            }
        }
    }

    ## TRANSLATION ##

    // DAYS IN ENGLISH (Source)
    $days_en = array('Mon''Tue','Wed','Thu','Fri');

    // TRANSLATE the DAYS in GERMAN (replacement)
    $days_ge = array('Mo','Di','Mi','Do','Fr');

    $from = str_replace($days_en, $days_ge, $from);
    $to   = str_replace($days_en, $days_ge, $to);

    ## OUTPUT ##
    //    echo "Voraussichtliche Lieferung<br> $from - $to";
    echo '<i class="shipping_icon fa fa-truck fa-flip-horizontal" aria-hidden="true"></i> <div class="lieferung"> Vorauslichtliche Lieferung </div>  <div class="fromto_date"> ' . $from . ' – ' . $to . ' </div> <div class="tooltip">
  <span class="tooltiptext">Gilt nur bei Lieferungen nach Deutschland.</span></div>' ;
}

My problem is that the "estimated delivery range" data of function lieferzeit() don't appear in function add_meta_boxes().

It would like to store the "estimated delivery range" data (of function lieferzeit()) when order is submitted to display it in the corresponding order backend metabox.

If I try to add the output of function lieferzeit() in the thank you page it works, but it doesn't store the data.

So how to save and get the calculated date rage data to use it everywhere I need?

Thanks


回答1:


I have make some little changes in your code.

  1. I have embed all the cart calculations code around delivery range based on product stock availability in a separate function (non hooked) that I can call anywhere.

  2. I have added and changed some hooks:

    • A checkout hook to display the range
    • A checkout hook to add hidden imput fields, with the $from and $to values, to post that data when submitting the order.
    • A hook that will save the delivery range data in the order meta data

So your code is going to be:

// The function that calculate the delivery dates range (Not hooked)
function calculate_delivery_range() { 

    $all_items_in_stock = true; // initializing

    // Iterating through cart items (to get the stock info)
    foreach (WC()->cart->get_cart() as $cart_item) {

        # HANDLING SIMPLE AND VARIABLE PRODUCTS

        // Variable products
        $variation_id = $cart_item['variation_id'];
        if( 0 != $variation_id) {
            $variation_obj = new WC_Product_variation($variation_id);
            $stock = $variation_obj->get_stock_quantity();
        } else {
            // Simple products
            $product_id = $cart_item['product_id'];
            $product_obj = new WC_Product($product_id);
            $stock = $product_obj->get_stock_quantity();
        }

        if( $stock <= 0 ){
            // if an item is out of stock
            $all_items_in_stock = false;
            break; // We break the loop
        }
    }

    // Items "in stock" (1 to 4 week days)
    if( $all_items_in_stock ){
        for( $start=0, $count=-1 ; $count < 4; $start++ ){
            $weekdays = date('w', strtotime("+$start days"));
            if( $weekdays > 0 && $weekdays < 6 ){
                $count++;
//            echo date('D j (w)', strtotime("+$start days")).', ';
                if($count == 1){
                    $from = date('D, d.m.', strtotime("+$start days") );
                } elseif($count == 4) {
                    $to = date('D, d.m.', strtotime("+$start days") );
                }
            }
        }
    } else { // One or more Items are Out of stock (14 to 21 week days)
        for( $start=0, $count=-1 ; $count < 21; $start++ ){
            $weekdays = date('w', strtotime("+$start days"));
            if( $weekdays > 0 && $weekdays < 6 ){
                $count++;
                if($count == 14){
                    $from = date('D, d.m.', strtotime("+$start days") );
                } elseif($count == 21) {
                    $to = date('D, d.m.', strtotime("+$start days") );
                }
            }
        }
    }

    ## TRANSLATION ##

    // DAYS IN ENGLISH (Source)
    $days_en = array( 'Mon', 'Tue', 'Wed', 'Thu', 'Fri' );

    // TRANSLATE the DAYS in GERMAN (replacement)
    $days_ge = array( 'Mo', 'Di', 'Mi', 'Do', 'Fr' );

    $from = str_replace($days_en, $days_ge, $from);
    $to   = str_replace($days_en, $days_ge, $to);

    // Return the "from" and "to" values in an array
    return array( 'from' => $from, 'to' => $to );
}

// Displaying the dates delivery range in Cart, Checkout and Order reiceived pages
add_filter ( 'woocommerce_cart_collaterals', 'lieferzeit'); // cart page
add_action ( 'woocommerce_review_order_before_payment', 'lieferzeit'); // checkout page
add_action ( 'woocommerce_thankyou', 'lieferzeit'); // Order recieved
function lieferzeit() {

    // Calling the "delivery date range calculation"
    $days_range = calculate_delivery_range();

    ## DISPLAYING ##
    echo '<i class="shipping_icon fa fa-truck fa-flip-horizontal" aria-hidden="true"></i> <div class="lieferung"> Vorauslichtliche Lieferung </div>  <div class="fromto_date"> ' . $days_range['from'] . ' – ' . $days_range['to'] . ' </div> <div class="tooltip">
  <span class="tooltiptext">Gilt nur bei Lieferungen nach Deutschland.</span></div>' ;

}


add_action ( 'woocommerce_review_order_before_payment', 'include_delivery_range_hidden_checkout_fields');
function include_delivery_range_hidden_checkout_fields() {

    // Calling the "delivery date range calculation"
    $days_range = calculate_delivery_range();

    // Output hidden imput fields with delivery dates range values
    echo '<input type="hidden" name="delivery_range_from" value="'.$days_range['from'].'">
    <input type="hidden" name="delivery_range_to" value="'.$days_range['to'].'">';

}

// Save the "delivery range values" in order meta data
add_action( 'woocommerce_checkout_update_order_meta', 'save_delivery_range_in_order_meta',  100, 1 );
function save_delivery_range_in_order_meta( $order_id ) {

    $delivery_range_from = $_POST['delivery_range_from'];
    if ( ! empty( $delivery_range_from ) )
        add_post_meta( $order_id, '_delivery_range_from', $delivery_range_from );

    $delivery_range_to = $_POST['delivery_range_to'];
    if ( ! empty( $delivery_range_to ) )
        add_post_meta( $order_id, '_delivery_range_to', $delivery_range_to );

}

// Adding Delivery range metabox to Order edit pages
add_action( 'add_meta_boxes', 'add_order_delivery_range_meta_boxe' );
function add_order_delivery_range_meta_boxe(){
    add_meta_box(
        'woocommerce-order-delivery-range-values', __( 'Voraussichtliche Lieferung', 'woocommerce' ),
        'order_delivery_range_values', 'shop_order', 'side', 'default'
    );
}

// Adding content to Delivery range metabox to Order edit pages
function order_delivery_range_values(){
    global $post;

    $from = get_post_meta($post->ID, '_delivery_range_from', true);
    $to = get_post_meta($post->ID, '_delivery_range_to', true);

    echo "<p>$from - $to</p>";
}

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

This code is tested and works

The you will get in Backend Order Edit pages:




回答2:


I suggest you prefix your functions to avoid conflict.

For example add_action( 'add_meta_boxes', 'cust_add_meta_boxes' );

It would be great if there was a way to store the output of function lieferzeit() in a way which doesn't change the output anymore.

You can store it as meta data, for example

$order_id = WC()->order->id;
update_post_meta( $order_id, '_lieferzeit_from', $from );
update_post_meta( $order_id, '_lieferzeit_to', $to );

Modify function order_my_custom() to:

function order_my_custom()
{
   global $post;  
   $from = get_post_meta($post->ID, '_lieferzeit_from', true);
   $to = get_post_meta($post->ID, '_lieferzeit_to', true);
   echo "Voraussichtliche Lieferung<br> $from - $to";
}


来源:https://stackoverflow.com/questions/45215391/save-custom-delivery-dates-range-calculations-to-woocommerce-order-meta-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!