禁用 Woocommerce 购物车订单项数量价格计算

Posted

技术标签:

【中文标题】禁用 Woocommerce 购物车订单项数量价格计算【英文标题】:Disable Woocommerce cart line item quantity price calculation 【发布时间】:2017-10-19 04:45:52 【问题描述】:

我正在寻找可以在购物车页面中禁用数量x 商品价格的功能。

通常如果产品价格为€1 且数量为3 |订单项小计是 €3... (1€ x 3)

现在我想在没有 x 数量计算的情况下保持产品价格,如下所示: 产品价格€1 数量3 |订单项小计为 €1

有人知道如何禁用此数量价格计算吗?

【问题讨论】:

【参考方案1】:

是的,可以禁用数量项目价格计算,但它相当复杂......

代码:

// Custom line item Total/Subtotal price display
add_filter( 'woocommerce_cart_product_subtotal', 'custom_cart_subtotal', 10, 4 );
function custom_cart_subtotal( $product_subtotal, $product, $quantity, $wc_cart ) 
    $price   = $product->get_price();
    $taxable = $product->is_taxable();
    $quantity = 1; // HERE We set the quantity to 1 (So the price is calculated on a quantitity of 1)

    // Taxable
    if ( $taxable ) 
        if ( 'excl' === $wc_cart->tax_display_cart ) 
            $row_price        = wc_get_price_excluding_tax( $product, array( 'qty' => $quantity ) );
            $product_subtotal = wc_price( $row_price );

            if ( $wc_cart->prices_include_tax && $wc_cart->tax_total > 0 ) 
                $product_subtotal .= ' <small class="tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>';
            
         else 
            $row_price        = wc_get_price_including_tax( $product, array( 'qty' => $quantity ) );
            $product_subtotal = wc_price( $row_price );

            if ( ! $wc_cart->prices_include_tax && $wc_cart->tax_total > 0 ) 
                $product_subtotal .= ' <small class="tax_label">' . WC()->countries->inc_tax_or_vat() . '</small>';
            
        

     // Non-taxable
    else 
        $row_price        = $price * $quantity;
        $product_subtotal = wc_price( $row_price );
    
    return $product_subtotal;


// Custom cart subtotal and totals (Prices calculated on quatity = 1)
add_action( 'woocommerce_calculate_totals', 'custom_item_price', 10, 1);
function custom_item_price( $wc_cart ) 
    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;

    $cart_contents_total = 0;

    foreach ( $wc_cart->get_cart() as $cart_item_key => $cart_item )
        $cart_contents_total += floatval( strip_tags( $wc_cart->get_product_subtotal( $cart_item['data'], 1 ) ) );

    $wc_cart->subtotal = $cart_contents_total;
    $wc_cart->subtotal_ex_tax = $cart_contents_total;
    $wc_cart->cart_contents_total = $cart_contents_total;


// Custom cart subtotal and totals (Prices calculated on quatity = 1)
add_action( 'woocommerce_cart_get_taxes', 'custom_cart_get_taxes', 10, 2);
function custom_cart_get_taxes( $taxes, $wc_cart ) 
    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;

    $taxes = $subtotal_taxes = array();

    foreach ( $wc_cart->get_cart() as $cart_item_key => $cart_item )
        foreach( $cart_item['line_tax_data']['subtotal'] as $key => $tax_price )
            if( $tax_price > 0 )
                if( array_key_exists($key, $subtotal_taxes))
                    $subtotal_taxes[$key] += number_format( $tax_price / $cart_item['quantity'], 2 );
                else
                    $subtotal_taxes[$key] = number_format( $tax_price / $cart_item['quantity'], 2 );
             else 
                if( array_key_exists($key, $subtotal_taxes))
                    $subtotal_taxes[$key] += $tax_price;
                else
                    $subtotal_taxes[$key] = $tax_price;
            
        
    
    foreach ( array_keys( $subtotal_taxes + $wc_cart->get_shipping_taxes() ) as $key ) 
        $taxes[ $key ] = ( isset( $wc_cart->get_shipping_taxes()[ $key ] ) ? $wc_cart->get_shipping_taxes()[ $key ] : 0 ) + ( isset( $subtotal_taxes[ $key ] ) ? $subtotal_taxes[ $key ] : 0 );
    
    return $taxes;



// Custom line item Total/Subtotal set order prices (Prices calculated on quatity = 1)
add_action( 'woocommerce_checkout_create_order_line_item', 'custom_checkout_create_order_line_item', 10, 4  );
function custom_checkout_create_order_line_item( $item, $cart_item_key, $values, $order )

    $line_tax_data = array();
    foreach( $values['line_tax_data'] as $key_line => $tax )
        foreach( $tax as $key => $tax_price )
            if( $tax_price > 0 )
                $line_tax_data[$key_line] = array( $key => number_format( $tax_price / $values['quantity'], 2 ) );
            else
                $line_tax_data[$key_line] = array( $key => $tax_price );
        
    

    $item->set_props( array(
        'quantity'     => $values['quantity'],
        'variation'    => $values['variation'],
        'subtotal'     => number_format( $values['line_subtotal'] / $values['quantity'], 2 ),
        'total'        => number_format( $values['line_total'] / $values['quantity'], 2 ),
        'subtotal_tax' => number_format( $values['line_subtotal_tax'] / $values['quantity'], 2 ),
        'total_tax'    => number_format( $values['line_tax'] / $values['quantity'], 2 ),
        'taxes'        => $line_tax_data,
    ) );


// Get the correct Cart gran total amount
add_filter( 'woocommerce_calculated_total', 'custom_calculated_total', 10, 2 );
function custom_calculated_total( $price_total, $wc_cart )
    $tax_total = 0;
    $taxes_arr = $wc_cart->get_taxes();
    foreach($taxes_arr as $tax)
        $tax_total += $tax;
    return round( $wc_cart->cart_contents_total + $tax_total + $wc_cart->shipping_total + $wc_cart->fee_total, $wc_cart->dp );


// Replacing the total tax amount
add_action( 'woocommerce_checkout_create_order', 'custom_set_order_tax_total', 10, 1 );
function custom_set_order_tax_total( $order ) 
    $subtotal_taxes = 0;

    foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item )
        foreach( $cart_item['line_tax_data']['subtotal'] as $key => $tax_price )
            if( $tax_price > 0 )
                $subtotal_taxes += number_format( $tax_price / $cart_item['quantity'], 2 );
             else 
                $subtotal_taxes += $tax_price;
            
        
    
    $order->set_cart_tax( $subtotal_taxes );



// Update order line item tax total
add_action( 'woocommerce_checkout_update_order_meta', 'custom_update_order_item_tax_total', 10, 1 );
function custom_update_order_item_tax_total( $order_id ) 

    global $wpdb;
    $query = $wpdb->get_results( "
        SELECT woim.meta_id, woim.order_item_id as item_id, woi.order_item_type as type, woim.meta_key as akey, woim.meta_value as value
        FROM $wpdb->prefixwoocommerce_order_items AS woi
        INNER JOIN $wpdb->prefixwoocommerce_order_itemmeta AS woim ON woi.order_item_id = woim.order_item_id
        WHERE woi.order_id = $order_id
        AND woim.meta_key IN ( 'tax_amount', '_line_tax_data', 'rate_id' )
    " );

    $taxes = $items = array();
    foreach( $query as $result)
        if( $result->type == 'line_item' )
            $result_taxes = maybe_unserialize( $result->value );
            foreach( $result_taxes['subtotal'] as $tax_id => $tax_price )
                $taxes[$tax_id] = $tax_price;
         elseif( $result->type == 'tax' && $result->akey == 'rate_id' ) 
            $items[$result->item_id] = array(
                'price' => $taxes[$result->value],
                'rate_id' => $result->value
            );
         else 
            $items[$result->item_id]['meta_id'] = $result->meta_id;
        
    
    foreach($items as $item_id => $values)
        wc_update_order_item_meta( $item_id, 'tax_amount', $values['price'] );
    

代码进入您的活动子主题(或主题)的 function.php 文件或任何插件文件中。

在 WooCommerce 3+ 上测试并有效(价格含税或不含税)。

我没有用费用和折扣测试它。所以你可能需要一些额外的代码......

【讨论】:

以上是关于禁用 Woocommerce 购物车订单项数量价格计算的主要内容,如果未能解决你的问题,请参考以下文章

使用MVC / EF总结购物车中的重复订单项

用户购物(数据库)案例

隐藏产品价格并禁用 Woocommerce 中特定产品类别的添加到购物车

在 Woocommerce 3+ 中使用订单项以编程方式创建订单

在 woocommerce 3 中获取订单项的元数据

如何从 Woocommerce 中的订单项中获取产品 sku [重复]