我需要在Woocommerce 后端订单中更改商品价格。我尝试使用以下钩子,但我在尝试获取订单ID 时遇到问题。有什么建议吗?提前谢谢!
function my_custom_prices ($price, $product)
{
if ( !is_admin() || ( is_admin() && is_post_type_archive() ) ) return $price;
global $post, $woocommerce;
$order = new WC_Order( $post_id );
$user_id = $order->user_id;
$user = get_user_by('id', $user_id);
if ( in_array( 'my_role', (array) $user->roles ) ) {
return $price * 2;
}
else {
return $price;
}
}
add_filter('woocommerce_get_price', 'my_custom_prices ', 10, 2);
完成问题:
完整的问题如下。我正在使用一个插件,为产品添加一个名为批发价格的字段。如果客户具有批发客户角色,则订单使用这些价格。该插件工作正常,但它不需要在后端的价格。我和作者交谈了,他们还没有打算改变。我的客户需要修改订单。但当它进入后端时,它需要共同的价格,而不是批发商。我需要在后端执行一些操作,以便检测订单是否来自具有批发客户角色的客户。如果是,请在添加产品时采用正确的价格。这里有与作者讨论的更多信息。 https://wordpress.org/support/topic/wholesale-prices-in-backend-editing-orders/非常感谢您给予我的帮助。
选项:
woocommerce_get_price :无效,因为我无法获取客户ID
woocommerce_ajax_add_order_item_meta :不错的选择,但我找不到样品
按钮:不错的选择,但我不知道如何更改价格。我尝试了以下内容:
add_action( 'woocommerce_order_item_add_action_buttons', 'action_aplicar_mayoristas', 10, 1);
function action_aplicar_mayoristas( $order )
{
echo '<button type="button" onclick="document.post.submit();" class="button button-primary generate-items">Aplicar precios mayoristas</button>';
echo '<input type="hidden" value="1" name="aplicar_mayoristas" />';
};
add_action('save_post', 'aplicar_mayoristas', 10, 3);
function aplicar_mayoristas($post_id, $post, $update){
$slug = 'shop_order';
if(is_admin()){
if ( $slug != $post->post_type ) {
return;
}
if(isset($_POST['aplicar_mayoristas']) && $_POST['aplicar_mayoristas']){
$order = wc_get_order( $post_id);
//$order_id = $order->get_user_id();
// Iterating through each "line" items in the order
foreach ($order->get_items() as $item_id => $item_data) {
//$item_data->set_subtotal("798");
$item_data->set_price("798");
//->set_price($custom_price);
}
}
}
}
答案 0 :(得分:2)
<强>更新强>
您正在使用的挂钩不是订单,而是仅适用于产品,并且只是更改显示的价格。所以你不会得到它的订单ID。
您可以更改多个挂钩中的价格显示,但如果您想更改实际的订单商品价格(不仅仅是显示的格式化价格),您应该在订单更新时触发此价格更改。
在这种情况下,您可以使用挂钩在save_post
动作挂钩中的自定义函数:
add_action( 'save_post', 'change_order_item_prices', 11, 1 );
function change_order_item_prices( $post_id ) {
// If this is an autosave (has not been submitted).
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return $post_id;
// Check the user's permissions.
if ( 'shop_order' == $_POST[ 'post_type' ] ){
if ( ! current_user_can( 'edit_shop_order', $post_id ) )
return $post_id;
} else {
if ( ! current_user_can( 'edit_post', $post_id ) )
return $post_id;
}
## ------------------- Changing prices Start code ------------------- ##
## ===> HERE define the targeted user role
$user_role = 'my_role';
## ===> HERE define the rate multiplier (for price calculations)
$multiplier = 2;
// If this Order items prices have already been updated, we exit
$items_prices_updated = get_post_meta( $post_id, 'line_item_updated', true );
if( ! empty( $items_prices_updated ) ) return $post_id; // Exit
$order = new WC_Order( $post_id ); // Get the order object
$user_id = $order->get_user_id(); // Get the user ID
$user_data = get_userdata( $user_id ); // Get the user data
// Check the user role
if ( ! in_array( $user_role, $user_data->roles ) ) return;
// Loop through order items
foreach( $order->get_items() as $item_id => $item ){
$item_data = $item->get_data(); // The item data
$taxes = array();
foreach( $item_data['taxes'] as $key_tax => $values ){
if( ! empty( $values ) ){
foreach( $values as $key => $tax_price ){
$taxes[$key_tax][$key] = floatval($tax_price) * $multiplier;
}
}
}
$new_line_subtotal = floatval( $item_data['subtotal'] ) * $multiplier;
$new_line_subt_tax = floatval( $item_data['subtotal_tax'] ) * $multiplier;
$new_line_total = floatval( $item_data['total'] ) * $multiplier;
$new_line_total_tax = floatval( $item_data['total_tax'] ) * $multiplier;
// Update Order item prices
$item->set_subtotal($new_line_subtotal);
$item->set_subtotal_tax($new_line_subt_tax);
$item->set_total($new_line_total);
$item->set_total_tax($new_line_total_tax);
$item->set_taxes($taxes);
// Save the updated data
$item->save();
}
// Udpate order totals and cache
$order->calculate_totals();
// We mark the order as updated (to avoid repetition)
update_post_meta( $post_id, 'line_item_updated', true );
}
代码放在活动子主题(或主题)的function.php文件中,或者放在任何插件文件中。
经过测试,最后工作。
我添加了一项安全措施,以避免订单商品更新两次。
方法
$order->calculate_totals();
使进程稍微减慢......这是正常的,因为它会计算总数,更新数据和刷新缓存。
答案 1 :(得分:0)
您的代码需要调试。
$ post_id - 函数中没有这样的变量或参数。因此,请改用$ post-&gt; ID。
做
var_dump((array)$ user-&gt; roles);
if (in_array( 'my_role', (array) $user->roles ) )
线。并确保my_role存在于该数组中。
临时评论此行以进行调试:
// if(is_admin()&amp;&amp; is_post_type_archive())
然后你会看到原因并能够解决它。