如何根据用户角色对某些产品应用数量折扣?

问题描述 投票:0回答:3

我需要对某些产品的某些用户角色进行折扣,当购买一定数量的产品时。

折扣仅适用于我们选择的产品数量:

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


```

php wordpress woocommerce price
3个回答
0
投票

这就是我解决这个问题的方式:

  1. 收集要打折的商品数量
  2. 整数将项目总数除以
    $required_quantity
  3. 将该数字乘以重新计算的每组所需数量的折扣值。

在将购物车传递给 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;


0
投票

正如我在你的最后一个例子中看到的那样

首先你可以打破之前的逻辑

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$


0
投票

这是我对不同数量折扣(5%)的回答的测试结果:

  • quantity is bellow 10
  • quantity is 10
  • quantity is more then 10 and bellow 20
  • quantity is 20
  • quantity is more then 20 and bellow 30
  • quantity is bellow 30

<?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" );

如有任何更改或帮助,请告诉我

© www.soinside.com 2019 - 2024. All rights reserved.