在后端订单版中挂钩 woocommerce 价格

Hook woocommerce price in backend order edition

我需要在 Woocommerce 后端 订单中更改商品价格。我尝试使用以下挂钩,但在尝试获取 order 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:不错的选择,但我找不到样本

Button: 不错的选择,但我不知道如何更改价格。我尝试了以下操作:

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);
}


                }
    }
}

您的代码需要调试。

  1. $post_id - 你的函数中没有这样的变量或参数。因此,请改用 $post->ID。

  2. var_dump( (array) $user->roles);

之前
if (in_array( 'my_role', (array) $user->roles ) )

行。并确保 my_role 存在于该数组中。

  1. 临时注释此行以供调试:

    // if (is_admin() && is_post_type_archive())

然后你会看到原因并能够修复它。

已更新

您使用的挂钩不是针对订单的,而是针对产品的,并且仅用于更改显示的价格。所以你不会得到订单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 文件或任何插件文件。

经过测试,终于可以使用了。

我添加了安全措施以避免订单商品被更新两次。

The method $order->calculate_totals(); slow down the process a little bit… It's normal as it will calculate totals, update data and refresh caches.