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/CalcPercent.php +34 -10 1.3.531.4.17 View file →
@@ -84,25 +84,45 @@
84 84 $discount_amount = 0;
85 85 $discount_value = $this->rule['discount_value'];
86 86 $price = CalcFactory::get_price( $this->item );
87 87 $quantity = (int) $this->item['quantity'];
88 +
89 + /**
90 + * "Count Quantity As" combined / variations mode: eligibility and the
91 + * eligible unit count were already resolved by QuantityCounter, so
92 + * discount only that many units and skip the per-line min/max/recursive
93 + * derivation below.
94 + */
95 + if ( isset( $this->item['disco_forced_qty'] ) ) {
96 + $forced = max( 0, (int) $this->item['disco_forced_qty'] );
97 + $product_discount = $price ? $price * $discount_value / 100 : 0; // phpcs:ignore
98 + $this->discounted_quantities = $forced;
99 +
100 + return apply_filters( 'disco_final_discounted_amount', $forced * $product_discount, 'percent' );
101 + }
102 +
88 103 $min = $this->rule['min'] ? (int) $this->rule['min'] : 0; //phpcs:ignore
89 104 $max = ! empty( $this->rule['max'] ) ? (int) $this->rule['max'] : ( $this->discount_intent === 'Bulk' ? PHP_INT_MAX : 0 ); // phpcs:ignore
90 105 $recursive = ! empty( $this->rule['recursive'] ) && $this->rule['recursive'] === 'yes'; // phpcs:ignore
91 - $item_id = $this->item['product_id'];
92 - $rule_ids = array_column( $this->rule['get_ids'], 'id' );
106 + $item_id = $this->item['product_id']; // phpcs:ignore
107 + $rule_ids = array_column( $this->rule['get_ids'], 'id' ); // phpcs:ignore
93 108 $discount_qty = $this->rule['get_quantity'] ? (int) $this->rule['get_quantity'] : 0; // phpcs:ignore
94 109
95 110 // Default discount for quantities.
96 111 $discount_for_quantities = $min;
97 112
98 - // Apply for the Bulk Discount when max is set.
99 - if ( $max && $quantity >= $max ) {
113 + /**
114 + * Bulk / range capping — only when NOT recursive. Recursive rules ignore
115 + * max: the bundle size is always min, so the qualifying quantity must not
116 + * be capped to max here, otherwise floor( qty / base ) would divide by
117 + * max instead of min and undercount the bundles.
118 + */
119 + if ( ! $recursive && $max && $quantity >= $max ) {
100 120 $discount_for_quantities = $max;
101 121 }
102 122
103 123 // If quantity between min and max then apply discount.
104 - if ( $quantity >= $min && $quantity <= $max ) {
124 + if ( ! $recursive && $quantity >= $min && $quantity <= $max ) {
105 125 $discount_for_quantities = $quantity;
106 126 }
107 127
108 128 /**
@@ -124,13 +144,17 @@
124 144
125 145 // Apply for the Bundle & BOGO Discount when recursive is set.
126 146 $multiplier = 1;
127 147
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 - }
148 + if ( $recursive && $min > 0 && $quantity >= $min ) {
149 + /**
150 + * Recursive: the number of bundles is floor( qty / min ). Divide by
151 + * min, never by $discount_for_quantities — for BuyXGetY the latter
152 + * holds the reward quantity (get_quantity) and would inflate the
153 + * multiplier (e.g. buy 2 get 1 with 2 in cart → 1 bundle, not 2).
154 + */
155 + $multiplier = (int) floor( $quantity / $min );
156 + $discount_for_quantities *= $multiplier;
133 157 }
134 158
135 159 // Discount per product.
136 160 $product_discount = 0;