产品的平均销售价格

时间:2021-01-26 17:36:17

标签: woocommerce

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


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

任何想法如何获得这项工作? 谢谢。

1 个答案:

答案 0 :(得分: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”。

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

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