PluginProbe
Discount Rules for WooCommerce – Disco | Dynamic Pricing, Conditions, Bulk, Bundle, BOGO / 1.3.42
Discount Rules for WooCommerce – Disco | Dynamic Pricing, Conditions, Bulk, Bundle, BOGO v1.3.42
1.4.18 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 All 181 releases
← All changes | app/Disco.php +57 -49 1.4.21.3.42 View file →
@@ -46,8 +46,12 @@
46 46 * @return float Product Price.
47 47 * @throws \Exception If setting is not found.
48 48 */
49 49 public function get_product_discounted_price( $price, $product ) {//phpcs:ignore
50 + if ( Settings::get( 'discount_priority_type' ) === 'woocommerce_coupon' ) {
51 + return $price; // Return original price if WooCommerce coupon is used.
52 + }
53 +
50 54 if ( $product instanceof \WC_Product ) {
51 55 // Init product base intents and exclude cart-based intents.
52 56 $this->intents = $this->prepare_intents( array( 'Product' ) );
53 57
@@ -64,8 +68,10 @@
64 68 }
65 69
66 70 $discounts = array();
67 71
72 + $prev_discount = PHP_INT_MAX;
73 +
68 74 // Foreach intent, apply the discount.
69 75 foreach ( $this->intents as $intent ) {
70 76 /**
71 77 * Get a discount limit form campaign.
@@ -90,10 +96,15 @@
90 96 if ( empty( $discount ) ) {
91 97 continue;
92 98 }
93 99
94 - // Store discount keyed by campaign id so the winning amount maps back to the right campaign.
95 - $discounts[ $intent->campaign->id ] = $discount;
100 + // Get applied discount campaign.
101 + if ( $discount > 0 && $prev_discount > $discount ) {
102 + $this->applied_campaign_id = $intent->campaign->id;
103 + $prev_discount = $discount;
104 + }
105 +
106 + $discounts[] = $discount;
96 107 }
97 108
98 109 // If no discount is applied, return the original price.
99 110 if ( empty( $discounts ) ) {
@@ -101,17 +112,13 @@
101 112 }
102 113
103 114 $discount_type = $intent->campaign->discount_rules[0]['discount_type'];
104 115
105 - // Pick the winning discount amount, then map it back to the campaign that produced it.
106 - $base_discount = $this->min_max_average( array_values( $discounts ) );
107 - $this->applied_campaign_id = (int) array_search( $base_discount, $discounts, true );
108 -
109 116 /**
110 117 * Get the min or max discount amount according to plugin settings.
111 118 * Apply the filter to modify final discounted amount based on discount types.
112 119 */
113 - $discounted_amount = apply_filters( 'disco_final_discounted_amount', $base_discount, $discount_type );
120 + $discounted_amount = apply_filters( 'disco_final_discounted_amount', $this->min_max_average( $discounts ), $discount_type );
114 121
115 122 if ( $discounted_amount <= $price ) {
116 123 // Get an applied campaign from DiscountLimit class.
117 124 ( new UserLimit )->disco_start_session_on_checkout( $this->applied_campaign_id );
@@ -136,8 +143,12 @@
136 143 if ( $cart->is_empty() ) {
137 144 return $cart;
138 145 }
139 146
147 + if ( Settings::get( 'discount_priority_type' ) === 'woocommerce_coupon' ) {
148 + return $cart;
149 + }
150 +
140 151 // Init Cart - Based Intents except Product & Shipping Intent.
141 152 $this->intents = $this->prepare_intents( array( 'Cart' ) );
142 153
143 154 if ( ! empty( $this->intents ) && $cart->get_cart_contents_count() > 0 ) {
@@ -200,10 +211,8 @@
200 211 if ( ! empty( $discount_label ) ) {
201 212 $label = $discount_label;
202 213 }
203 214
204 - $cart_fee = $this->get_discount_exclude_tax( $cart_fee, $cart );
205 -
206 215 $cart->add_fee( $label, -$cart_fee );
207 216 $cart->set_session();
208 217 }
209 218 }
@@ -226,8 +235,12 @@
226 235 if ( ! defined( 'DOING_AJAX' ) && is_admin() ) {
227 236 return $cart;
228 237 }
229 238
239 + if ( Settings::get( 'discount_priority_type' ) === 'woocommerce_coupon' ) {
240 + return $cart;
241 + }
242 +
230 243 // Init Cart - Based Intents except Product & Shipping Intent.
231 244 $this->intents = $this->prepare_intents( array( 'Bulk', 'Bundle', 'BOGO' ) );
232 245
233 246 $discounts = $this->prepare_item_discounts( $this->intents, $cart );
@@ -256,10 +269,8 @@
256 269 $total_discount += $discounts[ $id ];
257 270 }
258 271
259 272 if ( $total_discount > 0 ) {
260 - $total_discount = $this->get_discount_exclude_tax( $total_discount, $cart );
261 -
262 273 $cart->add_fee( __( 'Discount', 'disco' ), -$total_discount );
263 274 }
264 275
265 276 $cart->set_session();
@@ -283,8 +294,12 @@
283 294 if ( ! defined( 'DOING_AJAX' ) && is_admin() ) {
284 295 return $cart;
285 296 }
286 297
298 + if ( Settings::get( 'discount_priority_type' ) === 'woocommerce_coupon' ) {
299 + return $cart;
300 + }
301 +
287 302 // Init Cart - Based Intents except Product & Shipping Intent.
288 303 $this->intents = $this->prepare_intents( array( 'BOGO' ) );
289 304
290 305 return $this->prepare_item_discounts_bogo_free( $this->intents, $cart );
@@ -295,62 +310,55 @@
295 310 *
296 311 * @return bool
297 312 */
298 313 public function apply_free_shipping() { //phpcs:ignore
299 - return ! empty( $this->get_applied_free_shipping_campaign_ids() );
300 - }
301 -
302 - /**
303 - * Evaluate the Shipping intents and return the IDs of every campaign that
304 - * currently grants free shipping (respecting per-user usage limits).
305 - *
306 - * This is the single source of truth for "which free-shipping campaigns
307 - * apply right now". It is used both to decide whether to add a free shipping
308 - * rate and to persist the campaign IDs to the order meta at checkout. It does
309 - * NOT rely on the WC session or cached shipping rates, so it is safe to call
310 - * during order creation.
311 - *
312 - * @return array<int> Applied free-shipping campaign IDs.
313 - */
314 - public function get_applied_free_shipping_campaign_ids() {
315 314 if ( ! $this->cart_is_valid() ) {
316 - return array();
315 + return false;
317 316 }
318 317
319 - $cart = WC()->cart;
320 - $this->intents = $this->prepare_intents( array( 'Shipping' ) );
321 - $campaign_ids = array();
318 + $cart = WC()->cart;
322 319
323 - if ( empty( $this->intents ) ) {
324 - return $campaign_ids;
320 + if ( Settings::get( 'discount_priority_type' ) === 'woocommerce_coupon' ) {
321 + return false; // Return false if WooCommerce coupon is used.
325 322 }
326 323
327 - foreach ( $this->intents as $intent ) {
328 - /**
329 - * Get a discount limit from campaign.
330 - *
331 - * Compare with total applied count and skip if the user limit is hit.
332 - */
333 - $discount_limit = $intent->campaign->discount_max_user;
324 + $this->intents = $this->prepare_intents( array( 'Shipping' ) );
325 + $shippings = array();
334 326
335 - if ( ! empty( $discount_limit ) ) {
327 + if ( ! empty( $this->intents ) ) {
328 + foreach ( $this->intents as $intent ) {
329 + /**
330 + * Get a discount limit form campaign.
331 + *
332 + * Compare with total product meta and apply discount
333 + */
334 + $discount_limit = $intent->campaign->discount_max_user;
335 + $applied_campaign_id = $intent->campaign->id;
336 336 $total_applied_campaign = ( new UserLimit )->disco_get_total_applied_campaign( $intent->campaign->id );
337 337
338 - if ( $total_applied_campaign >= $discount_limit ) {
338 + if (
339 + ! empty( $discount_limit )
340 + && (
341 + $discount_limit >= 0
342 + && $total_applied_campaign >= $discount_limit
343 + )
344 + ) {
339 345 continue;
340 346 }
341 - }
342 347
343 - $items = $this->get_items_for_discount( $cart, $intent->campaign );
348 + $items = $this->get_items_for_discount( $cart, $intent->campaign );
349 + $shippings[] = $intent->get_discounts( $items, $cart );
344 350
345 - if ( 'free_shipping' !== $intent->get_discounts( $items, $cart ) ) {
346 - continue;
351 + if ( !in_array( 'free_shipping', $shippings, true ) ) {
352 + continue;
353 + }
354 +
355 + // Get an applied campaign from DiscountLimit class.
356 + ( new UserLimit )->disco_start_session_on_checkout( $applied_campaign_id );
347 357 }
348 -
349 - $campaign_ids[] = (int) $intent->campaign->id;
350 358 }
351 359
352 - return $campaign_ids;
360 + return in_array( 'free_shipping', $shippings, true );
353 361 }
354 362
355 363 /**
356 364 * Get offers for a product.