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/CalcFixedPerProduct.php +25 -8 1.3.491.4.17 View file →
@@ -85,8 +85,16 @@
85 85 public function calculate_discount(): float { // phpcs:ignore
86 86 $discount_amount = 0;
87 87 $fixed_per_product = $this->rule['discount_value'];
88 88 $quantity = (int) $this->item['quantity'];
89 +
90 + // "Count Quantity As" combined / variations: discount only the eligible units.
91 + if ( isset( $this->item['disco_forced_qty'] ) ) {
92 + $forced = max( 0, (int) $this->item['disco_forced_qty'] );
93 + $this->discounted_quantities = $forced;
94 +
95 + return apply_filters( 'disco_final_discounted_amount', $forced * $fixed_per_product, 'fixed_per_product' );
96 + }
89 97 $min = $this->rule['min'] ? (int) $this->rule['min'] : 0; //phpcs:ignore
90 98 $max = ! empty( $this->rule['max'] ) ? (int) $this->rule['max'] : ( $this->discount_intent === 'Bulk' ? PHP_INT_MAX : 0 ); // phpcs:ignore
91 99 $recursive = ! empty( $this->rule['recursive'] ) && $this->rule['recursive'] === 'yes'; // phpcs:ignore
92 100 $item_id = $this->item['product_id'];
@@ -95,15 +103,20 @@
95 103
96 104 // Default discount for quantities.
97 105 $discount_for_quantities = $min;
98 106
99 - // Apply for the Bulk Discount when max is set.
100 - if ( $max && $quantity >= $max ) {
107 + /**
108 + * Bulk / range capping — only when NOT recursive. Recursive rules ignore
109 + * max: the bundle size is always min, so the qualifying quantity must not
110 + * be capped to max here, otherwise floor( qty / base ) would divide by
111 + * max instead of min and undercount the bundles.
112 + */
113 + if ( ! $recursive && $max && $quantity >= $max ) {
101 114 $discount_for_quantities = $max;
102 115 }
103 116
104 117 // If quantity between min and max then apply discount.
105 - if ( $quantity >= $min && $quantity <= $max ) {
118 + if ( ! $recursive && $quantity >= $min && $quantity <= $max ) {
106 119 $discount_for_quantities = $quantity;
107 120 }
108 121
109 122 /**
@@ -124,13 +137,17 @@
124 137
125 138 // Apply for the Bundle & BOGO Discount when recursive is set.
126 139 $multiplier = 1;
127 140
128 - if ( $recursive ) {
129 - if ( $quantity % $min === 0 || $quantity > $discount_for_quantities ) {
130 - $multiplier = floor( $quantity / $discount_for_quantities );
131 - $discount_for_quantities *= $multiplier;
132 - }
141 + if ( $recursive && $min > 0 && $quantity >= $min ) {
142 + /**
143 + * Recursive: the number of bundles is floor( qty / min ). Divide by
144 + * min, never by $discount_for_quantities — for BuyXGetY the latter
145 + * holds the reward quantity (get_quantity) and would inflate the
146 + * multiplier (e.g. buy 2 get 1 with 2 in cart → 1 bundle, not 2).
147 + */
148 + $multiplier = (int) floor( $quantity / $min );
149 + $discount_for_quantities *= $multiplier;
133 150 }
134 151
135 152 // Limit discount to Min or Max quantity.
136 153 if ( $quantity >= $discount_for_quantities ) {