Woocommerce, update price when added by admin via

2019-07-23 19:40发布

问题:

I would like to set a 50% discount when and only when the admin adds a product to the existing order via the admin area.

I've tried with this:

function admin_set_custom_price( $item, $item_id ) {
    $item->set_subtotal( ( ( ( 100 - 50 ) * $item->get_subtotal() ) / 100 ) );
    $item->set_total( ( ( ( 100 - 50 ) * $item->get_total() ) / 100 ) );

    $item->apply_changes();
    $item->save();

    return $item;
}
add_filter( 'woocommerce_ajax_order_item', 'admin_set_custom_price', 10, 2 );

And the result is that when the item is added the price is the original price.

If I then simply refresh the page, it shows the prices with 50% discount.

What else do I need to do show the price with discount right away when it is added without the need to refresh the page?

Looks like something is overriding it as it is saved I would guess since the price is correct on refresh.

Talking about simple/variation product types.

回答1:

So I've used this hook instead:

woocommerce_ajax_added_order_items

And then in the function:

foreach ( $order->get_items() as $order_item_id => $order_item_data ) {
    //    Set custom price.
}

Seems to work just fine.

UPDATE:

It turns out that the above hook only get the last item in case you want to add multiple items at once.

A better hook which is executed in the loop ONLY for the items added via ajax (not affecting the existing ones) is:

woocommerce_ajax_add_order_item_meta

Then in the loop you can do a loop over the items in the cart and if the cart id matches, you can change the product.

function update_order_prices_on_admin_ajax( $item_id, $item, $order )
    foreach ( $order->get_items() as $order_item_id => $order_item_data ) {
        if ( $order_item_id == $item_id ) {
            // Do changes here.

            // Runs this after making a change to $order_item_data
            $order->apply_changes();
            $order->save();
        }
    }
}
add_action( 'woocommerce_ajax_add_order_item_meta', 'update_order_prices_on_admin_ajax', 99, 3 );