Discount Rules for WooCommerce - Version 2.3.1

Version Description

  • 16/10/20 =
  • Fix - JS error
  • Improvement - Discount table improvement.
  • Improvement - Product page strikeout doesn't displays while dynamic strikeout option enabled in few cases.
  • Improvement - Added new event advanced_woo_discount_rules_user_on_condition_check in pro.
Download this release

Release Info

Developer flycart
Plugin Icon 128x128 Discount Rules for WooCommerce
Version 2.3.1
Comparing to
See all releases

Code changes from version 2.3.0 to 2.3.1

readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: https://flycart.org/
4
  Tags: woocommerce, coupons, discounts, dynamic pricing, Buy One Get One Free, pricing deals, bulk discount, discount
5
  Requires at least: 4.4.1
6
  Tested up to: 5.5
7
- Stable tag: 2.3.0
8
  License: GPLv3 or later
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
10
 
@@ -338,6 +338,12 @@ Discount - Enter minimum & Maximum quantity -> Adjustment Type -> Product Discou
338
 
339
  == Changelog ==
340
 
 
 
 
 
 
 
341
  = 2.3.0 - 14/10/20 =
342
  * Feature - Discount table for variants while changing variant options
343
  * Fix - Fatal error because of get_posts method.
4
  Tags: woocommerce, coupons, discounts, dynamic pricing, Buy One Get One Free, pricing deals, bulk discount, discount
5
  Requires at least: 4.4.1
6
  Tested up to: 5.5
7
+ Stable tag: 2.3.1
8
  License: GPLv3 or later
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
10
 
338
 
339
  == Changelog ==
340
 
341
+ = 2.3.1 - 16/10/20 =
342
+ * Fix - JS error
343
+ * Improvement - Discount table improvement.
344
+ * Improvement - Product page strikeout doesn't displays while dynamic strikeout option enabled in few cases.
345
+ * Improvement - Added new event advanced_woo_discount_rules_user_on_condition_check in pro.
346
+
347
  = 2.3.0 - 14/10/20 =
348
  * Feature - Discount table for variants while changing variant options
349
  * Fix - Fatal error because of get_posts method.
v2/App/Controllers/Admin/WDRAjax.php CHANGED
@@ -12,6 +12,7 @@ use Wdr\App\Helpers\Migration;
12
  use Wdr\App\Helpers\Rule;
13
  use Wdr\App\Helpers\Validation;
14
  use Wdr\App\Helpers\Woocommerce;
 
15
 
16
  if (!defined('ABSPATH')) exit;
17
 
@@ -608,6 +609,7 @@ class WDRAjax extends Base
608
  if($product){
609
  $price_html = "<div class='price'></div>";
610
  $price_html = self::$manage_discount->getPriceHtml($price_html, $product, $product_qty, true);
 
611
  $original_html = self::$woocommerce_helper->getPriceHtml($product);
612
  }
613
  }
12
  use Wdr\App\Helpers\Rule;
13
  use Wdr\App\Helpers\Validation;
14
  use Wdr\App\Helpers\Woocommerce;
15
+ use Wdr\App\Router;
16
 
17
  if (!defined('ABSPATH')) exit;
18
 
609
  if($product){
610
  $price_html = "<div class='price'></div>";
611
  $price_html = self::$manage_discount->getPriceHtml($price_html, $product, $product_qty, true);
612
+ remove_filter('woocommerce_get_price_html', array(Router::$manage_discount, 'getPriceHtml'), 100);
613
  $original_html = self::$woocommerce_helper->getPriceHtml($product);
614
  }
615
  }
v2/App/Controllers/DiscountCalculator.php CHANGED
@@ -81,10 +81,13 @@ class DiscountCalculator extends Base
81
  $filters = $rule->getFilter();
82
  $rule_id = $rule->getId();
83
  $has_bulk_discount = $rule->hasBulkDiscount();
84
- $get_variant_product = $this->getVariantProduct($product, $rule, $filters, $hasFilter);
85
- $is_filter_passed = isset($get_variant_product['is_filter_passed'])? $get_variant_product['is_filter_passed'] : false;
86
- $product = isset($get_variant_product['product'])? $get_variant_product['product'] : false;
87
- $is_variable_product = isset($get_variant_product['is_variable_product'])? $get_variant_product['is_variable_product'] : false;
 
 
 
88
  $product_price = $this->getProductPriceFromConfig($product, $calculate_discount_from, $is_variable_product);
89
  $product_price = apply_filters('advanced_woo_discount_rules_bulk_table_product_price', $product_price, $product, $calculate_discount_from, $hasFilter, $filters);
90
  if ($has_bulk_discount) {
@@ -148,14 +151,7 @@ class DiscountCalculator extends Base
148
  if ($calculate_discount_from == 'regular_price') {
149
  $product_price = self::$woocommerce_helper->getProductRegularPrice($product);
150
  if (empty($product_price) && $is_variable_product) {
151
- $variant_regular_price = array();
152
- $available_variations = Woocommerce::availableProductVariations($product);
153
- foreach ($available_variations as $variant){
154
- $variant_id = isset($variant['variation_id']) ? $variant['variation_id'] : 0;
155
- $regular_price = isset($variant['display_regular_price']) ? $variant['display_regular_price'] : 0;
156
- $variant_regular_price[$variant_id] = $regular_price;
157
- }
158
- $product_price = min($variant_regular_price);
159
  }
160
  if(empty($product_price)){
161
  $product_price = self::$woocommerce_helper->getProductPrice($product);
@@ -166,87 +162,6 @@ class DiscountCalculator extends Base
166
  return $product_price;
167
  }
168
 
169
- /**
170
- * get Variant Product
171
- *
172
- * @param $product
173
- * @param $rule
174
- * @param $filters
175
- * @param $hasFilter
176
- * @return array
177
- */
178
- function getVariantProduct($product, $rule, $filters, $hasFilter){
179
- $is_variable_product = Woocommerce::productTypeIs($product, array('variable', 'variation', 'subscription_variation', 'variable-subscription'));
180
- $is_filter_passed = $rule->isFilterPassed($product);
181
- $available_variations = Woocommerce::availableProductVariations($product);
182
- $rule_id = $rule->getId();
183
-
184
- if($is_filter_passed && $is_variable_product){
185
- foreach ($filters as $filter_val) {
186
- $filter_type = isset($filter_val->type) ? $filter_val->type : '';
187
- $filter_value = isset($filter_val->value) ? $filter_val->value : array();
188
- $filter_method = isset($filter_val->method) ? $filter_val->method : '';
189
- $term_id = $attribute_details = array();
190
- if ($filter_type == 'product_attributes' && $is_variable_product) {
191
- $parent_product_id = Woocommerce::getProductParentId($product);
192
- if (empty($parent_product_id)) {
193
- $variation_id = $this->haveDefaultVariant($product, $available_variations);
194
- } else {
195
- $parent_product = Woocommerce::getProduct($parent_product_id);
196
- $variation_id = Woocommerce::getProductId($product);
197
- $available_variations = Woocommerce::availableProductVariations($parent_product);
198
- }
199
- $attribute_details = $this->getProductAttributeDetails($available_variations);
200
- if(isset($attribute_details[$variation_id])){
201
- foreach ($attribute_details[$variation_id] as $key => $attribute_taxonomy){
202
- $terms = get_terms( array(
203
- 'taxonomy' => $attribute_taxonomy,
204
- 'hide_empty' => false,
205
- ) );
206
- foreach ($terms as $term){
207
- if($key == $term->slug){
208
- $term_id[] = $term->term_id;
209
- }
210
- }
211
- }
212
- $term_id = array_unique($term_id);
213
- if(count(array_intersect($filter_value, $term_id)) > 0){
214
- $is_attribute_filter_passed = true;
215
- }else{
216
- $is_attribute_filter_passed = false;
217
- }
218
- }else{
219
- $is_attribute_filter_passed = false;
220
- }
221
- }
222
- }
223
- }
224
- if(!$is_filter_passed && $is_variable_product){
225
- //$variation_ids = array();
226
- $default_variation_id = 0;
227
- $available_variations = Woocommerce::availableProductVariations($product);
228
- /* Default variation id get by product variants */
229
- $default_variation_id = $this->haveDefaultVariant($product, $available_variations);
230
-
231
- if(!empty($default_variation_id)){
232
- $product = Woocommerce::getProduct($default_variation_id);
233
- if($rule->isFilterPassed($product)){
234
- $is_filter_passed = true;
235
- }
236
- $is_filter_passed = apply_filters('advanced_woo_discount_rules_current_product_default_variation', $is_filter_passed, $rule_id, $rule);
237
- }
238
- }
239
- if(isset($is_attribute_filter_passed) && !$is_attribute_filter_passed){
240
- $is_filter_passed = false;
241
- }
242
- $is_filter_passed = apply_filters('advanced_woo_discount_rules_enable_bulk_table_for_products', $is_filter_passed, $rule_id, $rule, $product);
243
- return array(
244
- 'is_filter_passed' => $is_filter_passed,
245
- 'is_variable_product' => $is_variable_product,
246
- 'product' => $product,
247
- );
248
- }
249
-
250
  /**
251
  * @param $response_ranges
252
  * @param $from
@@ -275,63 +190,6 @@ class DiscountCalculator extends Base
275
  );
276
  }
277
 
278
- /**
279
- * Get default variant id
280
- * @param $product
281
- * @param $available_variations
282
- * @return int
283
- */
284
- function haveDefaultVariant($product, $available_variations){
285
- $default_variation_id = 0;
286
- if(!empty($available_variations)) {
287
- foreach($available_variations as $variation_values ){
288
- $is_default_variation_passed = array();
289
- if(isset($variation_values['attributes']) && !empty($variation_values['attributes'])){
290
- $variation_attributes = $variation_values['attributes'];
291
- foreach($variation_attributes as $key => $attribute_value ){
292
- $attribute_name = str_replace( 'attribute_', '', $key );
293
- $default_value = Woocommerce::getProductVariationDefaultAttribute($product,$attribute_name);
294
- if(!empty($default_value)){
295
- if( $default_value == $attribute_value ){
296
- $is_default_variation_passed[] = 1;
297
- } else {
298
- $is_default_variation_passed[] = 2;
299
- }
300
- }
301
- }
302
- $is_default_variation_passed = array_unique($is_default_variation_passed);
303
- }
304
-
305
- if( !empty($is_default_variation_passed) && isset($is_default_variation_passed[0]) && count($is_default_variation_passed) == 1 && $is_default_variation_passed[0] == 1){
306
- $default_variation_id = isset($variation_values['variation_id']) ? $variation_values['variation_id'] : 0;
307
- break;
308
- }
309
- }
310
- }
311
- return $default_variation_id;
312
- }
313
-
314
- /**
315
- * get product attributes details for variant products
316
- * @param $available_variations
317
- * @return array
318
- */
319
- function getProductAttributeDetails($available_variations){
320
- $attribute_details = array();
321
- if(!empty($available_variations)){
322
- foreach($available_variations as $variation_values ){
323
- if(isset($variation_values['attributes']) && !empty($variation_values['attributes'])){
324
- $variation_attributes = $variation_values['attributes'];
325
- $variation_id = isset($variation_values['variation_id']) ? $variation_values['variation_id'] : 0;
326
- foreach($variation_attributes as $key => $attribute_value ){
327
- $attribute_details[$variation_id][$attribute_value] = str_replace( 'attribute_', '', $key );
328
- }
329
- }
330
- }
331
- }
332
- return $attribute_details;
333
- }
334
-
335
  /**
336
  * get default layout messages by rules to display discount table
337
  * @param $product
81
  $filters = $rule->getFilter();
82
  $rule_id = $rule->getId();
83
  $has_bulk_discount = $rule->hasBulkDiscount();
84
+ if(Woocommerce::displayTableIfAnyOneVariantHasDiscount() === false){
85
+ $is_filter_passed = $rule->isFilterPassed($product, false, true);
86
+ } else {
87
+ $is_filter_passed = $rule->isFilterPassed($product, true);
88
+ }
89
+
90
+ $is_variable_product = Woocommerce::productTypeIs($product, array('variable', 'variable-subscription'));
91
  $product_price = $this->getProductPriceFromConfig($product, $calculate_discount_from, $is_variable_product);
92
  $product_price = apply_filters('advanced_woo_discount_rules_bulk_table_product_price', $product_price, $product, $calculate_discount_from, $hasFilter, $filters);
93
  if ($has_bulk_discount) {
151
  if ($calculate_discount_from == 'regular_price') {
152
  $product_price = self::$woocommerce_helper->getProductRegularPrice($product);
153
  if (empty($product_price) && $is_variable_product) {
154
+ $product_price = self::$woocommerce_helper->get_variation_regular_price($product, 'min');
 
 
 
 
 
 
 
155
  }
156
  if(empty($product_price)){
157
  $product_price = self::$woocommerce_helper->getProductPrice($product);
162
  return $product_price;
163
  }
164
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
  /**
166
  * @param $response_ranges
167
  * @param $from
190
  );
191
  }
192
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
  /**
194
  * get default layout messages by rules to display discount table
195
  * @param $product
v2/App/Controllers/ManageDiscount.php CHANGED
@@ -267,7 +267,7 @@ class ManageDiscount extends Base
267
  }
268
  return $this->getSetDiscountItemPriceHtml($discount_details, $initial_price, $discounted_price, $product, $price_html = true, $quantity, $ajax_price);
269
  }else{
270
- return $price_html;
271
  }
272
  }else {
273
  if (!$prices) {
267
  }
268
  return $this->getSetDiscountItemPriceHtml($discount_details, $initial_price, $discounted_price, $product, $price_html = true, $quantity, $ajax_price);
269
  }else{
270
+ return false;
271
  }
272
  }else {
273
  if (!$prices) {
v2/App/Helpers/Filter.php CHANGED
@@ -59,7 +59,7 @@ class Filter
59
  * @param $sale_badge
60
  * @return bool
61
  */
62
- function matchFilters($product, $filters, $sale_badge)
63
  {
64
  $rule = new Rule();
65
  $status = false;
@@ -95,7 +95,11 @@ class Filter
95
  $processing_result = $this->compareWithTags($product, $values, $method);
96
  } elseif ('product_attributes' === $type) {
97
  //$product = Woocommerce::getParentProduct($product);
98
- $processing_result = $this->compareWithAttributes($product, $values, $method, $cart_item);
 
 
 
 
99
  } elseif ('product_sku' === $type) {
100
  $processing_result = $this->compareWithSku($product, $values, $method);
101
  } elseif ('product_on_sale' === $type) {
59
  * @param $sale_badge
60
  * @return bool
61
  */
62
+ function matchFilters($product, $filters, $sale_badge, $product_table = false)
63
  {
64
  $rule = new Rule();
65
  $status = false;
95
  $processing_result = $this->compareWithTags($product, $values, $method);
96
  } elseif ('product_attributes' === $type) {
97
  //$product = Woocommerce::getParentProduct($product);
98
+ if($product_table === true && Woocommerce::productTypeIs($product, array('variable', 'variable-subscription'))){
99
+ $processing_result = false;
100
+ } else {
101
+ $processing_result = $this->compareWithAttributes($product, $values, $method, $cart_item);
102
+ }
103
  } elseif ('product_sku' === $type) {
104
  $processing_result = $this->compareWithSku($product, $values, $method);
105
  } elseif ('product_on_sale' === $type) {
v2/App/Helpers/Helper.php CHANGED
@@ -329,9 +329,9 @@ class Helper
329
 
330
  public static function displayCompatibleCheckMessages()
331
  {
332
- if (version_compare(WDR_VERSION, '2.3.0', '>=')) {
333
  if (defined('WDR_PRO_VERSION')) {
334
- if (version_compare(WDR_PRO_VERSION, '2.3.0', '<')) {
335
  $url = admin_url() . "plugins.php";
336
  $plugin_page = '<a target="_blank" href="' . $url . '">' . __('Update now', WDR_TEXT_DOMAIN) . '</a>';
337
  ?>
329
 
330
  public static function displayCompatibleCheckMessages()
331
  {
332
+ if (version_compare(WDR_VERSION, '2.3.1', '>=')) {
333
  if (defined('WDR_PRO_VERSION')) {
334
+ if (version_compare(WDR_PRO_VERSION, '2.3.1', '<')) {
335
  $url = admin_url() . "plugins.php";
336
  $plugin_page = '<a target="_blank" href="' . $url . '">' . __('Update now', WDR_TEXT_DOMAIN) . '</a>';
337
  ?>
v2/App/Helpers/Rule.php CHANGED
@@ -379,7 +379,7 @@ class Rule
379
  * @param $sale_badge
380
  * @return bool
381
  */
382
- function isFilterPassed($product, $sale_badge = false)
383
  {
384
  if (!$this->hasFilter()) {
385
  return true;
@@ -387,7 +387,7 @@ class Rule
387
  $filters = $this->getFilter();
388
  if (!empty($filters)) {
389
  $filter_helper = new Filter();
390
- $filter_passed = $filter_helper->matchFilters($product, $filters, $sale_badge);
391
  $conditions = $this->getConditions();
392
  $filter_passed_user_role = $filter_passed_user_list = $user_role_passed = $user_list_passed = $has_other_conditions = false;
393
  $condition_relationship = $this->getRelationship('condition', 'and');
@@ -438,7 +438,7 @@ class Rule
438
  $filter_passed = false;
439
  }
440
  $rule = $this;
441
- return apply_filters('advanced_woo_discount_rules_filter_passed', $filter_passed, $rule, $product, $sale_badge);
442
  }
443
 
444
  /**
379
  * @param $sale_badge
380
  * @return bool
381
  */
382
+ function isFilterPassed($product, $sale_badge = false, $product_table = false)
383
  {
384
  if (!$this->hasFilter()) {
385
  return true;
387
  $filters = $this->getFilter();
388
  if (!empty($filters)) {
389
  $filter_helper = new Filter();
390
+ $filter_passed = $filter_helper->matchFilters($product, $filters, $sale_badge, $product_table);
391
  $conditions = $this->getConditions();
392
  $filter_passed_user_role = $filter_passed_user_list = $user_role_passed = $user_list_passed = $has_other_conditions = false;
393
  $condition_relationship = $this->getRelationship('condition', 'and');
438
  $filter_passed = false;
439
  }
440
  $rule = $this;
441
+ return apply_filters('advanced_woo_discount_rules_filter_passed', $filter_passed, $rule, $product, $sale_badge, $product_table);
442
  }
443
 
444
  /**
v2/App/Helpers/Woocommerce.php CHANGED
@@ -1599,34 +1599,25 @@ class Woocommerce
1599
  return false;
1600
  }
1601
 
1602
-
1603
-
1604
  /**
1605
- * get available product variations
1606
- * @param $product
1607
- * @return array
 
 
 
1608
  */
1609
- public static function availableProductVariations($product){
1610
- $available_variations = array();
1611
- $is_variable_product = self::productTypeIs($product, 'variable');
1612
- if ($is_variable_product && method_exists($product, 'get_available_variations')){
1613
- $available_variations = $product->get_available_variations();
1614
  }
1615
- return $available_variations;
1616
  }
1617
 
1618
  /**
1619
- * get default attribute of variable product
1620
- * @param $product
1621
- * @param $attribute_name
1622
- * @return string
1623
- */
1624
- public static function getProductVariationDefaultAttribute($product, $attribute_name){
1625
- $default_value = '';
1626
- $is_variable_product = self::productTypeIs($product, 'variable');
1627
- if ($is_variable_product && method_exists($product, 'get_variation_default_attribute')){
1628
- $default_value = $product->get_variation_default_attribute($attribute_name);
1629
- }
1630
- return $default_value;
1631
  }
1632
  }
1599
  return false;
1600
  }
1601
 
 
 
1602
  /**
1603
+ * Get the min or max variation regular price.
1604
+ *
1605
+ * @param object $product
1606
+ * @param string $min_or_max Min or max price.
1607
+ * @param boolean $for_display If true, prices will be adapted for display based on the `woocommerce_tax_display_shop` setting (including or excluding taxes).
1608
+ * @return string
1609
  */
1610
+ public static function get_variation_regular_price($product, $min_or_max = 'min', $for_display = false){
1611
+ if(method_exists($product, 'get_variation_regular_price')){
1612
+ return $product->get_variation_regular_price($min_or_max, $for_display);
 
 
1613
  }
1614
+ return 0;
1615
  }
1616
 
1617
  /**
1618
+ * Load discount table if any one variant has discount
1619
+ * */
1620
+ public static function displayTableIfAnyOneVariantHasDiscount(){
1621
+ return apply_filters('advanced_woo_discount_rules_display_bulk_table_if_any_one_variant_has_discount', false);
 
 
 
 
 
 
 
 
1622
  }
1623
  }
v2/Assets/Js/site_main.js CHANGED
@@ -22,7 +22,7 @@
22
  $(document).ready(function ($) {
23
  function init_events() {
24
  if (awdr_params.enable_update_price_with_qty == 'show_dynamically') {
25
- $(document).on('change', '[name="quantity"]', function (){``
26
  var awdr_qty_object = $(this);
27
  setTimeout(function(){
28
  var $qty = awdr_qty_object.val();
22
  $(document).ready(function ($) {
23
  function init_events() {
24
  if (awdr_params.enable_update_price_with_qty == 'show_dynamically') {
25
+ $(document).on('change', '[name="quantity"]', function (){
26
  var awdr_qty_object = $(this);
27
  setTimeout(function(){
28
  var $qty = awdr_qty_object.val();
woo-discount-rules.php CHANGED
@@ -5,13 +5,13 @@
5
  * Description: Simple to complex discount rules for your WooCommerce store. Core package.
6
  * Author: Flycart Technologies LLP
7
  * Author URI: https://www.flycart.org
8
- * Version: 2.3.0
9
  * Slug: woo-discount-rules
10
  * Text Domain: woo-discount-rules
11
  * Domain Path: /i18n/languages/
12
  * Requires at least: 4.6.1
13
  * WC requires at least: 3.0
14
- * WC tested up to: 4.5
15
  */
16
  if (!defined('ABSPATH')) {
17
  exit;
@@ -21,7 +21,7 @@ if (!defined('ABSPATH')) {
21
  * Current version of our app
22
  */
23
  if (!defined('WDR_VERSION')) {
24
- define('WDR_VERSION', '2.3.0');
25
  }
26
 
27
  global $awdr_load_version;
5
  * Description: Simple to complex discount rules for your WooCommerce store. Core package.
6
  * Author: Flycart Technologies LLP
7
  * Author URI: https://www.flycart.org
8
+ * Version: 2.3.1
9
  * Slug: woo-discount-rules
10
  * Text Domain: woo-discount-rules
11
  * Domain Path: /i18n/languages/
12
  * Requires at least: 4.6.1
13
  * WC requires at least: 3.0
14
+ * WC tested up to: 4.6
15
  */
16
  if (!defined('ABSPATH')) {
17
  exit;
21
  * Current version of our app
22
  */
23
  if (!defined('WDR_VERSION')) {
24
+ define('WDR_VERSION', '2.3.1');
25
  }
26
 
27
  global $awdr_load_version;