Alright, this title may not really help you understand what I mean, so let’s put it in another way. When, as an administrator, you edit an order and are in the Order Items table, you have the chance to edit the item quantity, subtotal and discounted price (see screenshot below).
Now, what if you also want to have the freedom to display and edit another custom field, so that it is saved inside the order once you hit the “Save” button?
This could be useful for custom setups – for example let’s imagine the admin has the necessity to also define the “shipped quantity”, so that they know exactly if a specific order has been entirely fulfilled or requires a second shipment to get completed.
Either way, see the screenshot below, play with the snippet, and see how it goes. Enjoy!
PHP Snippet: Add Custom Column to Item Table @ WooCommerce Edit Order Page
/**
* @snippet Custom Order Items Column @ Admin
* @how-to businessbloomer.com/woocommerce-customization
* @author Rodolfo Melogli, Business Bloomer
* @compatible WooCommerce 7
* @community https://businessbloomer.com/club/
*/
add_action( 'woocommerce_admin_order_item_headers', 'bbloomer_admin_order_item_headers' );
function bbloomer_admin_order_item_headers( $order ) {
echo '<th class="shipped sortable" data-sort="int">Qty Shipped</th>';
}
add_action( 'woocommerce_admin_order_item_values', 'bbloomer_admin_order_item_values', 9999, 3 );
function bbloomer_admin_order_item_values( $product, $item, $item_id ) {
if ( $product ) {
$shipped = $item->get_meta( 'order_item_shipped' ) ? $item->get_meta( 'order_item_shipped' ) : 0;
echo '<td class="shipped" width="1%"><div class="view"><small class="times">x</small> ' . $shipped . '</div><div class="edit" style="display: none;"><input type="number" name="order_item_shipped[' . $item_id . ']" placeholder="0" value="' . $shipped . '" class="" max="' . $item->get_quantity() . '"></div></td>';
}
}
add_action( 'woocommerce_before_save_order_item', 'bbloomer_change_qty_shipped', 9999 );
function bbloomer_change_qty_shipped( $item ) {
if ( $item->get_type() !== 'line_item' ) return;
if ( ! $_POST ) return;
if ( isset( $_POST['items'] ) ) {
// ITS AJAX SAVE
parse_str( rawurldecode( $_POST['items'] ), $output );
} else {
$output = $_POST;
}
$item->update_meta_data( 'order_item_shipped', $output['order_item_shipped'][$item->get_id()] );
}