admin管理员组文章数量:1430956
For some custom functionality in Woocommerce, I need to copy order items with all metadata from one order to another order programatically. The source order is of type WC_Order
while destination order type is WC_Subscription
which extends WC_Order
and is a custom order type.
I have tried with a following function but it doesn't work. Although the order total is updated which matches to source order but the items in order are not added.
function wc_copy_order_items( &$from_order, &$to_order ) {
if ( ! is_a( $from_order, 'WC_Abstract_Order' ) || ! is_a( $to_order, 'WC_Abstract_Order' ) ) {
throw new InvalidArgumentException( _x( 'Invalid data. Orders expected aren\'t orders.', 'In wc_copy_order_items error message. Refers to origin and target order objects.', 'woocommerce-subscriptions' ) );
}
$from_order_all_items = $from_order->get_items( array( 'line_item', 'fee', 'shipping' ) );
foreach( $from_order_all_items as $item ) {
$to_order->add_item( $item );
}
$to_order->save();
}
I have also tried with woocommerce admin function wc_save_order_items
by hooking into woocommerce_process_shop_order_meta
while saving source order from admin but that also results in only update in totals of destination order and do not add items.
wc_save_order_items( $source_order_id, $_POST );
Basically, I want to copy all the data including all meta data and custom fields from source order to destination order. I've managed to copy other metadata by somehow but I can't get it right for copying order items with item metadata.
Please help me to find why above function doesn't work and guide me for a solution to copy order items between two orders.
For some custom functionality in Woocommerce, I need to copy order items with all metadata from one order to another order programatically. The source order is of type WC_Order
while destination order type is WC_Subscription
which extends WC_Order
and is a custom order type.
I have tried with a following function but it doesn't work. Although the order total is updated which matches to source order but the items in order are not added.
function wc_copy_order_items( &$from_order, &$to_order ) {
if ( ! is_a( $from_order, 'WC_Abstract_Order' ) || ! is_a( $to_order, 'WC_Abstract_Order' ) ) {
throw new InvalidArgumentException( _x( 'Invalid data. Orders expected aren\'t orders.', 'In wc_copy_order_items error message. Refers to origin and target order objects.', 'woocommerce-subscriptions' ) );
}
$from_order_all_items = $from_order->get_items( array( 'line_item', 'fee', 'shipping' ) );
foreach( $from_order_all_items as $item ) {
$to_order->add_item( $item );
}
$to_order->save();
}
I have also tried with woocommerce admin function wc_save_order_items
by hooking into woocommerce_process_shop_order_meta
while saving source order from admin but that also results in only update in totals of destination order and do not add items.
wc_save_order_items( $source_order_id, $_POST );
Basically, I want to copy all the data including all meta data and custom fields from source order to destination order. I've managed to copy other metadata by somehow but I can't get it right for copying order items with item metadata.
Please help me to find why above function doesn't work and guide me for a solution to copy order items between two orders.
Share Improve this question asked Jun 8, 2018 at 17:15 rmbitsrmbits 1011 silver badge7 bronze badges2 Answers
Reset to default 1Just change the $item_id
to $to_order_item_id
and you don't even have to touch the order_item_meta
since it is still associated with the proper $item_id
. So your foreach
from above would be ...
foreach($order->get_items() as $item_id=>$item) {
wc_update_order_item($item_id, array('order_id'=>$to_order_item_id));
}
Then you could even calculate the new totals of both orders after by using ...
$original_order = new WC_Order($original_order_id);
$original_order->calculate_totals();
$order = new WC_Order($to_order_item_id);
$order->calculate_totals();
I also discovered sometimes woocommerce will not let you change the order item
data so I ended up doing the same as above but with a straight to the database
update instead ...
global $wpdb;
$table = 'wp_woocommerce_order_items';
$data = array('order_id'=>$to_order_item_id);
foreach($order->get_items() as $item_id=>$item) {
$where = array('order_item_id'=>$item_id);
$updated = $wpdb->update($table, $data, $where);
if($updated === false) {
echo 'sorry dawg, there was an error';
}
else {
echo 'you got the soup!';
}
}
Ok, you need this for custom WOO functionality.
But WC_Subscription
is from the WOO Subscription plugin.
It feels wrong to duplicate an order, can't you just connect it somewhere, and where you want, collect the data from the original order when you need it?
I can see what you're missing.
When you do $order->get_items()
, it collects all the products in that order, this does not include all (product) item meta data.
For that you have to add something like this:
foreach ( $order->get_items() as $item_id => $item ) {
// get item_meta
$from_order_item_meta_data = wc_get_order_item_meta( $item_id, '_set_correct_meta_key_here', true );
// save item meta data
wc_update_order_item_meta($to_order_item_id, '_set_correct_meta_key_here', $from_order_item_meta_data);
}
You cannot use this directly in your function, the example above is just to show you the methods wc_get_order_item_meta()
& wc_update_order_item_meta()
;
Regards, Bjorn
本文标签: custom post typesCopy order items with metadata between ordersWoocommerce
版权声明:本文标题:custom post types - Copy order items with metadata between orders - Woocommerce 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745548133a2662802.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论