PluginProbe
Discount Rules for WooCommerce – Disco | Dynamic Pricing, Conditions, Bulk, Bundle, BOGO / 1.4.17
Discount Rules for WooCommerce – Disco | Dynamic Pricing, Conditions, Bulk, Bundle, BOGO v1.4.17
1.4.17 1.4.16 1.4.15 1.4.14 1.4.13 1.4.12 1.4.11 1.4.10 1.4.9 1.4.8 1.4.7 1.4.6 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 1.3.54 1.3.53 1.3.52 1.3.51 1.3.50 1.3.49 1.3.48 All 180 releases
← All changes | app/Calc/CalcPercentPerProduct.php +27 -9 1.4.01.4.17 View file →
@@ -83,8 +83,17 @@
83 83 $discount_amount = 0;
84 84 $discount_value = $this->rule['discount_value'];
85 85 $price = CalcFactory::get_price( $this->item );
86 86 $quantity = (int) $this->item['quantity'];
87 +
88 + // "Count Quantity As" combined / variations: discount only the eligible units.
89 + if ( isset( $this->item['disco_forced_qty'] ) ) {
90 + $forced = max( 0, (int) $this->item['disco_forced_qty'] );
91 + $product_discount = $price ? $price * $discount_value / 100 : 0;
92 + $this->discounted_quantities = $forced;
93 +
94 + return apply_filters( 'disco_final_discounted_amount', $forced * $product_discount, 'percent_per_product' );
95 + }
87 96 $min = $this->rule['min'] ? (int) $this->rule['min'] : 0; //phpcs:ignore
88 97 $max = ! empty( $this->rule['max'] ) ? (int) $this->rule['max'] : ( $this->discount_intent === 'Bulk' ? PHP_INT_MAX : 0 ); // phpcs:ignore
89 98 $recursive = ! empty( $this->rule['recursive'] ) && $this->rule['recursive'] === 'yes'; // phpcs:ignore
90 99
@@ -90,15 +99,20 @@
90 99
91 100 // Default discount for quantities.
92 101 $discount_for_quantities = $min;
93 102
94 - // Apply for the Bulk Discount when max is set.
95 - if ( $max && $quantity >= $max ) {
103 + /**
104 + * Bulk / range capping — only when NOT recursive. Recursive rules ignore
105 + * max: the bundle size is always min, so the qualifying quantity must not
106 + * be capped to max here, otherwise floor( qty / base ) would divide by
107 + * max instead of min and undercount the bundles.
108 + */
109 + if ( ! $recursive && $max && $quantity >= $max ) {
96 110 $discount_for_quantities = $max;
97 111 }
98 112
99 113 // If quantity between min and max then apply discount.
100 - if ( $quantity >= $min && $quantity <= $max ) {
114 + if ( ! $recursive && $quantity >= $min && $quantity <= $max ) {
101 115 $discount_for_quantities = $quantity;
102 116 }
103 117
104 118 // Apply for the Bundle & BOGO Discount when recursive is set.
@@ -103,13 +117,17 @@
103 117
104 118 // Apply for the Bundle & BOGO Discount when recursive is set.
105 119 $multiplier = 1;
106 120
107 - if ( $recursive ) {
108 - if ( $quantity % $min === 0 || $quantity > $discount_for_quantities ) {
109 - $multiplier = floor( $quantity / $discount_for_quantities );
110 - $discount_for_quantities *= $multiplier;
111 - }
121 + if ( $recursive && $min > 0 && $quantity >= $min ) {
122 + /**
123 + * Recursive: the number of bundles is floor( qty / min ). Divide by
124 + * min, never by $discount_for_quantities — for BuyXGetY the latter
125 + * holds the reward quantity (get_quantity) and would inflate the
126 + * multiplier (e.g. buy 2 get 1 with 2 in cart → 1 bundle, not 2).
127 + */
128 + $multiplier = (int) floor( $quantity / $min );
129 + $discount_for_quantities *= $multiplier;
112 130 }
113 131
114 132 // Discount per product.
115 133 $product_discount = 0;
@@ -132,9 +150,9 @@
132 150 }
133 151
134 152 $this->discounted_quantities = $discount_for_quantities;
135 153
136 - return $discount_amount;
154 + return apply_filters( 'disco_final_discounted_amount', $discount_amount, 'percent_per_product' );
137 155 }
138 156
139 157 /**
140 158 * Calculate Price.