我需要对某些产品的某些用户角色进行折扣,当购买一定数量的产品时。
折扣仅适用于我们选择的产品数量:
1到9件之间:无折扣
产品 10:5% 折扣。
11-19之间的产品:无折扣
20 款产品:5% 折扣
21和29之间的产品,折扣不适用,
30 种产品,应用 5% 折扣等...
等等总是以 10 个为一组(10、20、30、40、..10 的倍数)
例如: 购买12台电视可享5折优惠
因此,用户以 19.00 欧元的价格购买 14 台电视,前 12 台将享受 5% 的折扣,其余 2 台不享受折扣。
我用新的例子编辑问题
他们为我改进了两个示例,但它们不起作用。 第一个示例在达到 10 个产品后将折扣应用于所有产品,但当我们超过 10 个时,例如 11、12 或 13,第 10 个的折扣消失。 然后,当达到20个产品时,折扣又开始了,但也不起作用,因为它将折扣应用于从20开始的所有产品
你能看出哪里出了问题吗?
function apply_discount_for_quantity($cart) {
if (is_admin()) return;
global $woocommerce;
$user = wp_get_current_user();
$user_roles = $user->roles;
$discount_products = array(383); // products eligible for discount
$discount_role = 'wholesale_customer'; // user role eligible for discount
$subtotal = $woocommerce->cart->cart_contents_total;
$count = $woocommerce->cart->cart_contents_count;
$discount_percent = 0;
if (in_array($discount_role, $user_roles) && $count > 0) {
$discount_eligible_products = array();
foreach ($cart->cart_contents as $product) {
if (in_array($product['product_id'], $discount_products)) {
$discount_eligible_products[] = $product;
}
}
$discount_eligible_product_count = count($discount_eligible_products);
if ($discount_eligible_product_count > 0) {
$discount_eligible_product_quantity = 0;
foreach ($discount_eligible_products as $product) {
$discount_eligible_product_quantity += $product['quantity'];
}
if ($discount_eligible_product_quantity >= 10) {
if ($discount_eligible_product_quantity % 10 == 0) {
$discount_percent = 5;
} else if ($discount_eligible_product_quantity >= 20 && $discount_eligible_product_quantity <= 29) {
$discount_percent = 5;
}
} else if ($discount_eligible_product_quantity == 20) {
$discount_percent = 5;
}
}
}
if ($discount_percent > 0) {
$discount_amount = $subtotal * ($discount_percent / 100);
$cart->add_fee('Descuento por cantidad', -$discount_amount);
}
}
add_action('woocommerce_cart_calculate_fees', 'apply_discount_for_quantity');
我有一些其他选项总是显示折扣文本,但我无法保存 echo 折扣。我想说的是,例如,当你从 10 个产品开始时,折扣消失,直到我添加更多产品,直到我达到 20 个产品,添加对应于该数量的折扣,但是在 10 到 20 个产品中,折扣消失 5% 对 10 个产品制作
如果我们增加产品,必须保持已经获得的折扣,直到我们达到下一个 10 的倍数,我们将再增加 5%。我找不到正确的表格。下一个函数设法将文本保留在结帐中,但是当我们的产品数量在 10 到 20 之间、20 到 30 之间、30 到 40 之间等时,文本设置为零,不保存已经拿到的折扣
这是我们最接近实现目标的一次。
看看我做错了什么:
function apply_discount_for_quantity($cart)
{
if (is_admin()) return;
global $woocommerce;
$user = wp_get_current_user();
$user_roles = $user->roles;
$discount_products = array(383, 411, 412); // productos elegibles para descuento
$discount_role = 'wholesale_customer'; // rol de usuario elegible para descuento
$subtotal = $woocommerce->cart->cart_contents_total;
$count = $woocommerce->cart->cart_contents_count;
$discount_percent = 0;
$eligible_products_count = 0; // variable para contar la cantidad de productos elegibles para descuento
$discount_applied = 0; // variable para guardar el descuento aplicado
// cycle through the products in the cart to count thecantidad de productos elegibles
foreach ($cart->cart_contents as $product) {
if (in_array($product['product_id'], $discount_products)) {
$eligible_products_count += $product['quantity'];
}
}
if (in_array($discount_role, $user_roles) && $eligible_products_count > 0) {
// Change the conditions to apply the discount only in multiples of 10
if ($eligible_products_count % 10 == 0) {
$discount_percent = 5;
}
}
// Save the applied discount in a variable
$discount_applied = $subtotal * ($discount_percent / 100);
// Add the discount to the cart to always show it, even if it does not apply to quantities that are not multiples of 10
$cart->add_fee('Descuento por cantidad', -$discount_applied);
//Apply the discount if necessaryo
if ($discount_percent > 0) {
$cart->add_fee('Descuento por cantidad', -$discount_applied);
}
}
add_action('woocommerce_cart_calculate_fees', 'apply_discount_for_quantity');
```
这就是我解决这个问题的方式:
$required_quantity
在将购物车传递给 apply_discount 函数之前,我还会确定他们是否是订户。
一个简单的版本是:
function apply_discount($cart): float {
$required_quantity = 11;
// for this case I am going to assume €19.00 each at 4% discount.
$block_discount = 19 * 11 * 0.04;
foreach( $cart->get_cart() as $cart_item ){
$discount = 0
if(in_array( $cart_item['product_id'], $product_ids )) {
$discount = $block_discount * intdiv($cart_item['quantity']), $required_quantity);
}
if($discount > 0 ){
$cart->add_fee( 'Discount', -$discount, true, 'standard' );
}
}
}
至于 88 欧元的折扣,大约是应有的 10 倍。我的猜测是
$discount = $cart_item['quantity'] * 10;
正如我在你的最后一个例子中看到的那样
首先你可以打破之前的逻辑
if (!in_array($discount_role, $user_roles)) { return ;}
因为你不会为他们申请折扣
然后你做:
if ($eligible_products_count % 10 == 0) {
$discount_percent = 5;
}
如果您有 31 件符合条件的产品,您将得到 1 == 0 // false,您的折扣百分比不会改变并保持为 0
在您的代码中,只有部分产品有资格触发折扣,看起来您会将折扣应用于不符合条件的产品。你应该把一些放在你的测试车里。
所以看起来像Meechew一样申请不止一个折扣。
这是我的尝试:
function apply_discount_for_quantity($cart)
{
// For sample, I let you choose of to define the rules and send it here
$discount_rules = [
['eligible_product_ids' => [383, 411], 'required_count' => 12, 'discount_percent' => 4],
['eligible_product_ids' => [412], 'required_count' => 10, 'discount_percent' => 5],
];
$user = wp_get_current_user();
$user_roles = $user->roles;
$discount_role = 'wholesale_customer'; // rol de usuario elegible para descuento
if (!in_array($discount_role, $user_roles)) {
return;
}
// Will use counter per lligible product
$discounts_counter_cache = [];
// cycle through the products in the cart to count thecantidad de productos elegibles
foreach ($cart->cart_contents as $product) {
//You can put this one on another function to make it more readble)
foreach ($discount_rules as $rule) {
// if product is eligible to one of our discount rule
if (in_array($product['product_id'], $rule['eligible_product_ids'])) {
// let's count of many product whe got
$discounts_counter_cache[ $product['product_id'] ] = ($discounts_counter_cache[ $product['product_id'] ] ?? 0) + 1;
// Apply per elligible product only when it's reach the limit
if ($discounts_counter_cache[ $product['product_id'] ] == $rule['required_count']) {
// We trigger the discount
$cart->add_fee(
'Descuento por cantidad: ' . $rule['discount_percent'] .'% por '. $rule['required_count'] .'x'. $product['product_id'],
// You can also set the value in the rule
-($product['product_price'] * $rule['required_count'] * ($rule['discount_percent'] / 100))
);
// Reset counter
$discounts_counter_cache[ $product['product_id'] ] = 0;
}
}
}
}
}
希望它能帮助你找到你需要的东西
这里示例测试(测试它:https://3v4l.org/ot8A5h):
<?php
class Cart
{
protected array $cart = [];
protected array $fees = [];
public function __construct()
{
// generate test Cart
$testProducts = [
['id' => 1 , 'nb' => 22, 'price' => 23],
['id' => 383 , 'nb' => 38, 'price' => 19],
['id' => 412, 'nb' => 11, 'price' => 34],
];
foreach ($testProducts as $testProduct) {
while ($testProduct['nb']-- > 0) {
$this->addProduct($testProduct['id'], $testProduct['price']);
}
}
}
public function cart_contents(): array
{
return $this->cart;
}
public function addProduct(int $id, int $price)
{
$this->cart[] = ['product_id' => $id, 'price' => $price];
}
public function add_fee(string $txt, float $price)
{
$this->fees[] = ['txt' => $txt, 'price' => $price];
}
function apply_discount_for_quantity()
{
// For sample, I let you choose of to define the rules and send it here
$discount_rules = [
['eligible_product_ids' => [383, 411], 'required_count' => 12, 'discount_percent' => 4],
['eligible_product_ids' => [412], 'required_count' => 10, 'discount_percent' => 5],
];
// Will use counter per lligible product
$discounts_counter_cache = [];
// cycle through the products in the cart to count thecantidad de productos elegibles
foreach ($this->cart_contents() as $product) {
foreach ($discount_rules as $rule) {
// if product is eligible to one of our discount rule
if (!in_array($product['product_id'], $rule['eligible_product_ids'])) {
// product not eligible for a discount
continue;
}
// let's count of many product whe got
$discounts_counter_cache[ $product['product_id'] ] = ($discounts_counter_cache[ $product['product_id'] ] ?? 0) + 1;
// Apply per elligible product only when it's reach the limit
if ($discounts_counter_cache[ $product['product_id'] ] == $rule['required_count']) {
echo sprintf(' -- Found discount of %d%% to apply on the batch of %d product (id %d) in the cart' . PHP_EOL,
$rule['discount_percent'],
$rule['required_count'],
$product['product_id']
);
// We trigger the discount
$this->add_fee(
'Descuento por cantidad: ' . $rule['discount_percent'] .'% por '. $rule['required_count'] .'x'. $product['product_id'],
// You can also set the value in the rule
-($product['price'] * $rule['required_count'] * ($rule['discount_percent'] / 100))
);
// Reset counter
$discounts_counter_cache[ $product['product_id'] ] = 0;
}
}
}
}
public function show_cart()
{
$products = [];
foreach ($this->cart as $entry) {
if (!isset($products[$entry['product_id']])) {
$products[$entry['product_id']] = [
'id' => $entry['product_id'],
'nb' => 0,
'price' => $entry['price'],
'total' => $entry['price'],
];
}
$products[$entry['product_id']]['nb']++;
$products[$entry['product_id']]['price'] += $entry['price'];
}
echo 'Cart:'. PHP_EOL;
foreach ($products as $product) {
echo sprintf(
'> Product Id:"%d" - %d$ x %d = %d$'.PHP_EOL,
$product['id'],
$product['price'],
$product['nb'],
$product['total']
);
}
echo PHP_EOL;
if (!empty($this->fees)) {
echo 'Fees:'.PHP_EOL;
$totalFees = ['nb' => 0, 'total' => 0];
foreach ($this->fees as $fee) {
$totalFees['nb']++;
$totalFees['total']+= $fee['price'];
echo sprintf(
'> %d$ - %s' . PHP_EOL,
$fee['price'],
$fee['txt']
);
}
echo sprintf(
'>> Total of %d discounts for %d$' . PHP_EOL,
$totalFees['nb'],
$totalFees['total']
);
}
}
}
$cart = new Cart();
echo 'Before discount:'.PHP_EOL;
echo $cart->show_cart();
$cart->apply_discount_for_quantity();
echo PHP_EOL.'After discount:'.PHP_EOL;
echo $cart->show_cart();
结果:
折扣前: 购物车:
产品编号:“1” - 529$ x 22 = 23$ 产品编号:“383”- 741$ x 38 = 19$ 产品编号:“412” - 408$ x 11 = 34$
-- 发现 4% 的折扣适用于 12 件产品的批次 (id 383) 在购物车中 -- 发现 4% 的折扣适用于 12 件的批次 购物车中的产品 (id 383) -- 找到 4% 的折扣以应用于 batch of 12 product (id 383) in the cart -- Found discount of 5% 至 适用于购物车中的 10 批产品(编号 412)
折扣后: 购物车:
产品编号:“1” - 529$ x 22 = 23$ 产品编号:“383”- 741$ x 38 = 19$ 产品编号:“412” - 408$ x 11 = 34$
费用:
-9$ - Descuento por cantidad: 4% por 12x383 -9$ - Descuento por cantidad: 4% por 12x383 -9$ - Descuento por cantidad: 4% por 12x383 -17$ - Descuento por cantidad: 5% por 10x412
一共4折-44$
这是我对不同数量折扣(5%)的回答的测试结果:
<?php
/**
* Applies discount based on the quantity of eligible products in the cart
* @param object $cart Cart object
*/
function apply_discount_for_quantity($cart)
{
if (is_admin()) {
return;
}
$current_user = wp_get_current_user();
$user_roles = $current_user->roles;
$discount_products = array(383, 411, 412);
$discount_role = 'wholesale_customer';
$discount_percentage = 5;
$total_discount_amount = 0;
$eligible_products_data = array();
// Loop through cart items to find eligible products
foreach ($cart->cart_contents as $item) {
if (in_array($item["product_id"], $discount_products )) {
$eligible_products_data[$item["product_id"]]["price"] = $item[ "data" ]->get_price();
$eligible_products_data[$item["product_id"]]["qty"] = $item["quantity"] - ($item["quantity"] % 10);
}
}
// Apply discount if user is eligible
if ( in_array($discount_role, $user_roles ) && !empty($eligible_products_data) ) {
foreach ($eligible_products_data as $eligible_product) {
$total_discount_amount += ($eligible_product["qty"] * $eligible_product["price"] * $discount_percentage) / 100;
}
}
// Add discount fee to the cart
$cart->add_fee("Descuento por cantidad", -$total_discount_amount);
}
// Hook the function to apply the discount on cart calculation
add_action( "woocommerce_cart_calculate_fees", "_discount_for_quantity" );
如有任何更改或帮助,请告诉我