【问题标题】:Hook woocommerce price in backend order edition在后端订单版中挂钩 woocommerce 价格
【发布时间】:2018-05-26 11:37:31
【问题描述】:

我需要在 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);
}


                }
    }
}

【问题讨论】:

    标签: php wordpress woocommerce hook-woocommerce orders


    【解决方案1】:

    更新

    您使用的挂钩不是订单,而是产品,并且仅用于更改显示的价格。所以你不会得到订单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-&gt;calculate_totals(); 方法会稍微减慢处理速度……这很正常,因为它会计算总数、更新数据和刷新缓存。

    【讨论】:

    • 非常感谢。它不工作。我不知道为什么。但我习惯于采取一些想法。谢谢。
    • @jpussacq 我仍在编写代码……请给我一些时间。我正在测试一切。无论如何我都会有一些工作,所以请耐心等待,因为它非常复杂。
    • 谢谢! Sameone 建议使用 woocommerce_ajax_add_order_item_meta 我认为这可能是一个不错的选择,正是我所需要的。但我无法找到示例代码。你知道那个钩子吗?
    • @jpussacq 为什么您认为woocommerce_ajax_add_order_item_meta 正是您需要的钩子……您没有在问题中指定何时或如何更新订单商品价格。
    • @jpussacq 你好……1)是的,是的……2)woocommerce_ajax_add_order_item_meta 不是那个,这意味着当订单未锁定时,它与 WC 的编辑 ajax 功能一起用于订单项(所以对您的情况没有用)。...我的代码答案非常完美(我认为)...您将能够添加一个自定义字段,如复选框以启用该功能。如果您需要通过 Skype 聊天联系我(我的 ID 是 marsloic)...请不要忘记接受这个答案(如果不是您,请点赞)。谢谢。
    【解决方案2】:

    您的代码需要调试。

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

    2. var_dump((数组)$user->roles);

    之前

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

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

    1. 出于调试目的临时注释此行:

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

    然后你会看到原因并能够解决它。

    【讨论】:

    • 问题是我需要获取客户的用户ID。我怎样才能做到这一点?谢谢!
    • $user_id=get_current_user_id();
    • 谢谢!这是 woocommerce_get_price 过滤器中的客户(不是当前用户)吗?我问是因为我在后台以管理员身份登录。
    • 你可以使用 $order-get_user_id()
    猜你喜欢
    • 2017-06-10
    • 2016-04-27
    • 2021-04-21
    • 2020-08-17
    • 2021-02-02
    • 2016-11-27
    • 2017-09-17
    • 2018-04-26
    • 1970-01-01
    相关资源
    最近更新 更多