【问题标题】:Average Sale price of a product产品的平均售价
【发布时间】:2021-01-26 17:36:17
【问题描述】:

我正在尝试为单个产品页面创建一个短代码,以显示当前产品的平均销售价格。因此,短代码将在产品页面的描述中。 此值应适用于简单和可变产品。 我能够获得简单产品的平均值,但只有当订单中有一件商品并且我无法使用可变产品解决这个问题时。


function avg_sales_price () {

    global $product;
    if ( is_a($product, 'WC_Product') ) {
        $product_id = $product->get_id();
        $orders = wc_get_orders( array(
            'numberposts' => -1,
            'post_type' => 'shop_order',
        ) );

        foreach ( $orders as $order ) {
            if ( count( $order->get_items() ) > 0 ) {
                foreach ( $order->get_items() as $item_id => $item )
                $productid = $item->get_variation_id() ? $item->get_variation_id() : $item->get_product_id();
                if ( $productid == $product_id) {
                    $product_price_in_orders += $item->get_total();
                }
            }
        }


        $count_orders = 0;
        foreach ( $orders as $order ) {
            $has_product = false;
            foreach ( $order->get_items() as $item_values )
                if ( $item_values['product_id'] == $product_id )
                    $has_product = true;

            if ( $has_product )
                $count_orders++;
        }

        $avg_sales_price = round( $product_price_in_orders / $count_orders );
        
        echo '<div class="sales-price-number">
            <span class="sales-price-text">Average Sale Price </span>
            <span class="sales-price-value">' . esc_html( get_woocommerce_currency_symbol() . $avg_sales_price ). ' </span>
        </div>';
    }
}

任何想法如何得到这个工作? 谢谢。

【问题讨论】:

  • 问题是可变产品并没有真正的价格。价格仅为单一变体设定。在这种情况下,您要显示每个变体的所有平均价格吗?
  • @Vdga​​etano 不是每个变量,而是所有变量的平均值。例如我有三种变化:红色 10 美元,绿色 11 美元,蓝色 12 美元。如果所有这些变体都以相同的数量购买了相同的次数,那么平均价格将约为 11 美元。所以不是每个变化,而是平均。

标签: woocommerce


【解决方案1】:

要根据当前产品获取订单,您不必每次都查询所有订单。尤其是订单多的时候,占用资源太多。

Get all Orders IDs from a product ID in Woocommerce 回答代码,您可以使用函数get_orders_ids_by_product_id() 获取来自特定产品ID 的所有订单(您必须在其中设置所需的订单状态)

然后您可以使用这个其他函数计算每个产品(简单或变体)的平均价格基于产品 ID

// calculate the average price based on the product id using the query within the "get_orders_ids_by_product_id()" function
function calculates_average_price_based_on_product_id( $product_id ) {
    $orders = get_orders_ids_by_product_id( $product_id );
    $count = count( $orders );
    if ( $count <= 0 ) {
        return; // set the return value in case there are no orders for this product
    }
    $prices = 0;
    foreach ( $orders as $order_id ) {
        $order = wc_get_order( $order_id );
        if ( $order ) {
            foreach ( $order->get_items() as $item ) {
                $product = $item->get_product();
                if ( $product_id == $product->get_id() ) {
                    $qty = $item->get_quantity();
                    $total = $item->get_total();
                    $prices += $total / $qty;
                }
            }
        }
    }
    return $prices / $count;
}

它是如何工作的

  • 如果产品是变量
    • 计算平均价格仅在已购买的产品变体之间
    • 如果未购买任何变体,则计算当前设置的净价之间的平均价格
  • 如果产品简单
    • 根据包含此产品的所有订单的售价计算平均价格
    • 如果产品从未购买过,显示当前设置的净价

短代码

最后是显示基于当前页面产品的平均价格的简码。 如果产品是可变的,则会计算并显示所有变体之间的平均价格。

[average_price_product] 短代码仅适用于产品页面。

// create a shortcode showing the average price of the product
add_shortcode( 'average_price_product', 'shortcode_average_price_product' );
function shortcode_average_price_product() {
    global $product;
    // initialize prices
    $avg_price = 0;
    $current_avg_price = 0;
    // initializes the number of variations that have been purchased at least once
    $count = 0;
    // if the product is variable it calculates the average price of all the variations
    if ( $product->is_type( 'variable' ) ) {
        $variation_ids = $product->get_children();
        // gets the total number of variations
        $total_variations = count( $variation_ids );
        foreach ( $variation_ids as $variation_id ) {
            $variation = wc_get_product( $variation_id );
            // gets the average price of each single variation
            $avg_price_variation = calculates_average_price_based_on_product_id( $variation_id );
            // if the average price of the current product variation is greater than zero, it updates the price and count
            if ( $avg_price_variation > 0 ) {
                $avg_price += $avg_price_variation;
                $count++; 
            }
            // sum the current price of each single variation (in case no variation has ever been purchased)
            $current_avg_price += $variation->get_price();
        }
        // if no variation has been purchased, I display the average price between the current net prices
        if ( $avg_price == 0 ) {
            $avg_price = $current_avg_price / $total_variations;
        } else {
            $avg_price /= $count;
        }
    // if the product is simple
    } else {
        // gets the average price of the product
        $avg_price = calculates_average_price_based_on_product_id( $product->get_id() );
        // if the simple product has never been ordered, I will display the current price
        if ( $avg_price == 0 ) {
            $avg_price = $product->get_price();
        }
    }
    // creates the HTML content to display on the product page
    $html = '<div class="sales-price-number"><span class="sales-price-text">Average Sale Price </span><span class="sales-price-value">' . wc_price( $avg_price ) . ' </span></div>';
    return $html;
}

挂钩

作为短代码的替代方案,您可以使用 woocommerce_before_add_to_cart_form 钩子在产品页面上添加平均价格,具有以下功能:

// shows the average price on the product page
add_action( 'woocommerce_before_add_to_cart_form', 'shows_average_price_on_the_product_page', 10 );
function shows_average_price_on_the_product_page() {
    global $product;
    // initialize prices
    $avg_price = 0;
    $current_avg_price = 0;
    // initializes the number of variations that have been purchased at least once
    $count = 0;
    // if the product is variable it calculates the average price of all the variations
    if ( $product->is_type( 'variable' ) ) {
        $variation_ids = $product->get_children();
        // gets the total number of variations
        $total_variations = count( $variation_ids );
        foreach ( $variation_ids as $variation_id ) {
            $variation = wc_get_product( $variation_id );
            // gets the average price of each single variation
            $avg_price_variation = calculates_average_price_based_on_product_id( $variation_id );
            // if the average price of the current product variation is greater than zero, it updates the price and count
            if ( $avg_price_variation > 0 ) {
                $avg_price += $avg_price_variation;
                $count++; 
            }
            // sum the current price of each single variation (in case no variation has ever been purchased)
            $current_avg_price += $variation->get_price();
        }
        // if no variation has been purchased, I display the average price between the current net prices
        if ( $avg_price == 0 ) {
            $avg_price = $current_avg_price / $total_variations;
        } else {
            $avg_price /= $count;
        }
    // if the product is simple
    } else {
        // gets the average price of the product
        $avg_price = calculates_average_price_based_on_product_id( $product->get_id() );
        // if the simple product has never been ordered, I will display the current price
        if ( $avg_price == 0 ) {
            $avg_price = $product->get_price();
        }
    }
    // creates the HTML content to display on the product page
    $html = '<div class="sales-price-number"><span class="sales-price-text">Average Sale Price </span><span class="sales-price-value">' . wc_price( $avg_price ) . ' </span></div>';
    echo $html;
}

代码已经过测试并且可以运行。将其添加到活动主题的 functions.php 中。

建议

虽然上面的代码可以正常工作,但这并不是获得产品平均价格的最佳方法。

每当每个订单的状态发生变化时,您都可以为每个产品创建和更新自定义元数据,例如“wc-completed”。

您只需要该产品的订单数量和根据最后完成的订单计算的平均价格的计数器。

当新订单进入完成状态时,您将更新相应的字段。

【讨论】:

  • 不是每个变化,而是所有变化的平均值。例如我有三种变化:红色 10 美元,绿色 11 美元,蓝色 12 美元。如果所有这些变体都以相同的数量购买了相同的时间,那么平均价格将是 11 美元左右。所以不是每个变化,而是平均。
  • 我已经更新了代码。现在,如果产品是可变的,则计算所有变体的单一平均价格,而不是每个单一变体的平均价格。
  • Hm.. 如果我有 10 美元、11 美元、12 美元的三种变体并且只订购了其中一种(即 10 美元并且没有订购其他两种变体),那么我有 3.33 美元而不是 10 美元(因为 (10+0+0)/3 = 3.33 但它不正确,对吧?)。
  • 完全正确。我的错。我已经更新了函数。
猜你喜欢
  • 2016-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-30
  • 1970-01-01
相关资源
最近更新 更多