首页 > 解决方案 > 从现有的 WC_Order_Item_Product 创建订单?

问题描述

tldr:// 如何将现有的 WC_Order_Item_Product 克隆到新订单?

我浏览了很多现有的订阅插件,但并没有真正对它们感到满意。所以我决定创造一些东西作为一个学习项目。它不是针对客户的,我不指望它会成为商业上成功的产品,但我想它可以提升我的游戏水平。

所以我已经创建了一个自定义表来保存目标日期,并希望从现有的 WC_Order_Item_Product-Objects 创建新订单。通过简单地添加原始对象,它只会将它们从旧顺序中移出,这是我不希望发生的事情。我想知道如何“克隆”该对象并删除受保护的 [order_id] 无论如何都会被 WC_Order->add_item 覆盖而不会更改原始数据库条目。也许那是错误的方法或坏主意?

我还尝试找到一些关于如何创建完整的自定义 WC_Order_Item_Product 的更新提示,但在这方面并没有真正成功。

我得到的自动取款机:

function update ($reminder_id = null) {
global $woocommerce;
global $wpdb;
global $aboprodukt_table_name;

// TODO if reminder id 
if ( ! $reminder_id) {
    $neworders = [];
    
    // get all reminders from db and loop through them
    $aboprodukt_reminders = $wpdb->get_results( 'SELECT * FROM ' . $aboprodukt_table_name . ' ORDER BY ' . $aboprodukt_table_name . '.targetdate ASC');
    foreach ($aboprodukt_reminders as $item ) {
        
        // get original order item object to abstract
        $order_item = new \WC_Order_Item_Product($item->orderitem);
        // get order object
        $order = $order_item->get_order();
        // get customer id
        $customer = $order->get_customer_id();

        // TODO abstract order items
        // assign user, adresses if not existing yet, copy from last order
        if ( ! $neworders[$customer] ) {
            // check all reminders
            $customer_array = $order->get_data();
            $args = array(
                'customer_id'   => $customer,
                'created_via'   => 'Aboprodukt',
                'add_order_note' => __('Aboprodukt Custom Order', 'aboprodukt'),
            );

            $neworders[$customer] = \wc_create_order($args);
            // TODO Shipping
        }
        // add order items
        $neworders[$customer]->add_item($order_item);
        $neworders[$customer]->calculate_totals();
        $neworders[$customer]->save();

    }
return print_r($neworders,true);}

标签: woocommerce

解决方案


不确定它是否有帮助。但这是我设法做到的方式。

为了理解:我在数据库中获得了一个额外的“提醒”表,该表存储:日期、订单项 ID。它在用于创建新订单后被删除。

function update ($reminder_id = null) {
global $woocommerce;
global $wpdb;
global $aboprodukt_table_name; 

// TODO if order id 
if ( ! $reminder_id) {
    $neworders = [];
    // get all reminders from db and loop through them
    $aboprodukt_reminders = $wpdb->get_results( 'SELECT * FROM ' . $aboprodukt_table_name . ' ORDER BY ' . $aboprodukt_table_name . '.targetdate ASC');
    foreach ($aboprodukt_reminders as $item ) {
        // get original order item object to abstract
        $order_item = new \WC_Order_Item_Product($item->orderitem);
        $order = $order_item->get_order();
        $customer = $order->get_customer_id();
        // assign user, adresses if not existing yet, copy from last order
        if ( ! $neworders[$customer] ) {
            // check all reminders
            $args = array(
                'customer_id'   => $customer,
                'created_via'   => 'Aboprodukt',
                'add_order_note' => __('Aboprodukt Custom Order', 'aboprodukt'),
            );

            $neworders[$customer] = \wc_create_order($args);
            // order
            $customer_object = new \WC_Customer( $customer );
            $types = array('billing','shipping');
            foreach ($types as $type) {
               foreach ( $customer_object->{"get_{$type}"}() as $key => $value) {
                   if ( ! empty($value) ) {
                    if ( is_callable( array( $neworders[$customer], "set_{$type}_{$key}" ) ) ) {
                        $neworders[$customer]->{"set_{$type}_{$key}"}( $value );
                    }
                }
                }
            }
            // Set Shipping
            $shippingold =  $order->get_shipping_methods();
            $oldshippingitem = new \WC_Order_Item_Shipping( reset($shippingold) );
            $newshippingitem = new \WC_Order_Item_Shipping();
            $newshippingitem->set_method_id( $oldshippingitem->get_method_id() );
            $newshippingitem->set_instance_id( $oldshippingitem->get_instance_id() );
            $newshippingitem->set_method_title( $oldshippingitem->get_method_title() );
            $newshippingitem->set_total( $oldshippingitem->get_total() );
            $neworders[$customer]->add_item( $newshippingitem );
            
        }

        // if variation_id > 0 then is simple product, get product
        $item_variation_id = $order_item->get_variation_id();
        $item_id = $neworders[$customer]->add_product(
                wc_get_product(isset( $item_variation_id ) && $item_variation_id > 0 ? $item_variation_id : $order_item->get_product_id() ),
                $order_item->get_quantity()
                );

        // copy metadata for future use
        $neworderitem = new \WC_Order_Item_Product($item_id);
        $neworderitem->add_meta_data( '_aboprodukt_order', $order_item->get_meta('_aboprodukt_order'), true );
        $neworderitem->add_meta_data( '_aboprodukt_timespan', $order_item->get_meta('_aboprodukt_timespan'), true );
        $neworderitem->add_meta_data( '_aboprodukt_type', $order_item->get_meta('_aboprodukt_type'), true );
        $neworderitem->save();
        
        $neworders[$customer]->calculate_totals();
        $neworders[$customer]->save();
        $wpdb->query( 
            $wpdb->prepare( 
               "DELETE FROM $aboprodukt_table_name
                WHERE id = %d",
                   $item->id
               )
           );

    }
}

// send emails
foreach ( $neworders as $customers => $neworder ) {
    $mailer = \WC()->mailer();
    \WC()->mailer()->emails['WC_Email_Customer_Invoice']->trigger($neworder->get_id());
    $neworder->add_order_note( sprintf( __('%s email notification manually sent.', 'woocommerce'), $mail->title), false, true);
}
return $neworders;
}

推荐阅读