If order has products on backorder - Split order and create new backorder from original

依然范特西╮ 提交于 2020-05-14 12:32:35

问题


I have the custom order status and it works.

What I need help with here is looping through the order items and checking if any of them are on backorder and if so, take the backorder items out of the original order and create a new order and give the new order the Backorder status.

The idea is to create the backorder if and only if there are items on backorder in the original order.

add_action( 'woocommerce_checkout_order_processed', 'split_order_if_order_has_backorder_products', 10, 1 );
function split_order_if_order_has_backorder_products( $order_id ) {
    if( ! $order_id ) return;

    // get order object
    $order = new WC_Order( $order_id );

    // get order currency
    $currency = $order->get_currency();

    // get order payment method
    $payment_gateway = $order->get_payment_method();

    // get order items = each product in the order
    $items = $order->get_items();

    foreach ( $items as $item ) {       
        $product = wc_get_product( $item['product_id'] );

        if ( $product->is_on_backorder() ) {

        // THIS IS NOT WORKING FOR SOME REASON?
        $backorder = wc_create_order();         
        $backorder->add_product( $product, $item['quantity'] );
        }
    }

    // THIS IS NOT WORKING EITHER = I NEED TO REMOVE THE BACKORDER ITEMS FROM THE ORIGINAL ORDER, RECALCULATE AND SAVE THE NEW TOTAL
    foreach($items as $backorder_product => $item){
        $order->remove_item($backorder_product);
        $order->calculate_totals();
        $order->save();
    }

    $address = array(
        'first_name' => $order->get_billing_first_name(),
        'last_name'  => $order->get_billing_last_name(),
        'email'      => $order->get_billing_email(),
        'phone'      => $order->get_billing_phone(),
        'address_1'  => $order->get_billing_address_1(),
        'address_2'  => $order->get_billing_address_2(),
        'city'       => $order->get_billing_city(),
        'state'      => $order->get_billing_state(),
        'postcode'   => $order->get_billing_postcode(),
        'country'    => $order->get_billing_country()
    );

    $shipping = array(
        'first_name' => $order->get_shipping_first_name(),
        'last_name'  => $order->get_shipping_last_name(),
        'address_1'  => $order->get_shipping_address_1(),
        'address_2'  => $order->get_shipping_address_2(),
        'city'       => $order->get_shipping_city(),
        'state'      => $order->get_shipping_state(),
        'postcode'   => $order->get_shipping_postcode(),
        'country'    => $order->get_shipping_country()
    );

    // Set addresses
    $backorder->set_address( $address, 'billing' );
    $backorder->set_address( $shipping, 'shipping' );

    // set the correct currency and payment gateway
    $backorder->set_currency($currency);
    $backorder->set_payment_method($payment_gateway);

    // calculate totals
    $backorder->calculate_totals();

    // set order note with original ID
    $backorder->add_order_note('Automated Backorder. Created from the original order ID: '.$order->get_id());

    // give the new backorder the correct status
    $backorder->update_status( 'backorder' );
}

回答1:


The code below ONLY creates a new order with the products that are in backorder, if the original order contains products with backorder status

add_action( 'woocommerce_checkout_order_processed', 'split_order_if_order_has_backorder_products', 10, 1 );
function split_order_if_order_has_backorder_products( $order_id ) {
    if( ! $order_id ) return;

    // get order object
    $order = new WC_Order( $order_id );

    // get order currency
    $currency = $order->get_currency();

    // get order payment method
    $payment_gateway = $order->get_payment_method();

    // get order items = each product in the order
    $items = $order->get_items();

    // check whether order contains back orders
    $check_for_back_orders = false;

    foreach ( $items as $item ) {       
        $product = wc_get_product( $item['product_id'] );

        if ( $product->is_on_backorder() ) {
            // will only be executed once if the order contains back orders
            if ( $check_for_back_orders == false ) {
                $check_for_back_orders = true;

                // create new order with backorders
                $backorder = wc_create_order();
            }

            // add product to 'backorder'
            $backorder->add_product( $product, $item['quantity'] );

            //delete item from original order
            $order->remove_item( $item->get_id() );
        }
    }

    $order->calculate_totals();
    $order->save();

    // If order contains backorders (true)
    if ( $check_for_back_orders ) {
        $address = array(
            'first_name' => $order->get_billing_first_name(),
            'last_name'  => $order->get_billing_last_name(),
            'email'      => $order->get_billing_email(),
            'phone'      => $order->get_billing_phone(),
            'address_1'  => $order->get_billing_address_1(),
            'address_2'  => $order->get_billing_address_2(),
            'city'       => $order->get_billing_city(),
            'state'      => $order->get_billing_state(),
            'postcode'   => $order->get_billing_postcode(),
            'country'    => $order->get_billing_country()
        );

        $shipping = array(
            'first_name' => $order->get_shipping_first_name(),
            'last_name'  => $order->get_shipping_last_name(),
            'address_1'  => $order->get_shipping_address_1(),
            'address_2'  => $order->get_shipping_address_2(),
            'city'       => $order->get_shipping_city(),
            'state'      => $order->get_shipping_state(),
            'postcode'   => $order->get_shipping_postcode(),
            'country'    => $order->get_shipping_country()
        );

        // Set addresses
        $backorder->set_address( $address, 'billing' );
        $backorder->set_address( $shipping, 'shipping' );

        // set the correct currency and payment gateway
        $backorder->set_currency($currency);
        $backorder->set_payment_method($payment_gateway);

        // calculate totals
        $backorder->calculate_totals();

        // set order note with original ID
        $backorder->add_order_note('Automated Backorder. Created from the original order ID: '.$order->get_id());

        // give the new backorder the correct status
        $backorder->update_status( 'backorder' );
    }
}


来源:https://stackoverflow.com/questions/59544167/if-order-has-products-on-backorder-split-order-and-create-new-backorder-from-o

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