types = Array( 'percent_total_amount' => 'Percentage of cart total amount', 'percent_product_price' => 'Percentage of product price', 'fixed_product_price' => 'Fixed price of product price', 'fixed_cart_amount' => 'Fixed price of cart total amount', ); } /** * * Ensures only one instance of AWDP is loaded or can be loaded. * * @since 1.0.0 * @static * @see WordPress_Plugin_Template() * @return Main AWDP instance */ public static function instance($file = '', $version = '1.0.0') { if (is_null(self::$_instance)) { self::$_instance = new self($file, $version); } return self::$_instance; } /** * @return bool */ public function isActive() { return $this->_active; } public function cart_discount_items( $item_price, $cart_item ) { $prod_ID = $cart_item['data']->get_data()['slug']; if(sizeof($this->discount_rules) >= 1 && $this->check_discount($prod_ID)) { $discounted_price = abs(wc_remove_number_precision($this->discounted_price[$prod_ID])); $actual_price = isset ( $this->actual_price ) ? ( array_key_exists($prod_ID, $this->actual_price) ? $this->actual_price[$prod_ID] : $cart_item['data']->get_data()['price'] ) : $cart_item['data']->get_data()['price']; $quantity = $cart_item['quantity']; if( ( $discounted_price > 0.0000000001 && ( $discounted_price < $actual_price ) ) || $discounted_price == 0 ) { $item_price = ''; $item_price .= ''; $item_price .= ''.wc_price($actual_price).''; $item_price .= ''. wc_price($discounted_price).''; } else if( $discounted_price > $actual_price ) { $item_price = ''; $item_price .= ''; $item_price .= ''.wc_price($actual_price).''; $item_price .= ''. wc_price($discounted_price).''; } } return $item_price; } public function get_product_price_html($item_price, $product) { $prod_ID = $product->get_data()['slug']; if(sizeof($this->discount_rules) >= 1 && $this->check_discount($prod_ID)) { $latest_price = isset ( $this->discounted_price ) ? ( array_key_exists($prod_ID, $this->discounted_price) ? abs(wc_remove_number_precision($this->discounted_price[$prod_ID]) ) : 0 ) : 0; $actual_price = isset ( $this->actual_price ) ? ( array_key_exists($prod_ID, $this->actual_price) ? $this->actual_price[$prod_ID] : $product->get_data()['price'] ) : $product->get_data()['price']; if( ( $latest_price > 0.0000000001 && ( $latest_price < $actual_price ) ) || $latest_price == 0 ) { $item_price = ''; $item_price .= ''; $item_price .= ''.wc_price($actual_price).''; $item_price .= ''. wc_price($latest_price).''; } else if( $latest_price > $actual_price ) { $item_price = ''; $item_price .= ''; $item_price .= ''.wc_price($actual_price).''; $item_price .= ''. wc_price($latest_price).''; } } return $item_price; } public function show_pricing_table(){ $pricing_table = $this->pricing_table; $id = get_the_ID(); echo $pricing_table[$id]; } public function get_product_price($price, $product) { if($product) { $id = $product->get_id(); if (isset($this->product_lists[$id])) { return $this->product_lists[$id]['price']; } return $this->calculate_discount($price, $product); } } public function calculate_discount( $price, $product ) { // Resetting discounts before cart totals if (did_action('woocommerce_before_calculate_totals') && ! defined('AWDP_CART_LOADED')) { define('AWDP_CART_LOADED', true); $this->actual_price[$product->get_data()['slug']] = $price; $this->discounts = $this->discounted_price = []; } else if(did_action('woocommerce_before_calculate_totals') && !isset($this->actual_price[$product->get_data()['slug']])){ $this->actual_price[$product->get_data()['slug']] = $price; } // Load discount rules $this->load_rules(); // Check if discount is active if($this->discount_rules == null) return $price; // return product price $products_with_discount = []; global $woocommerce; $awdp_product_id = $product->get_id(); $awdp_product_slug = $product->get_data()['slug']; $this->pricing_table[$awdp_product_id] = ''; $this->discounted_price[$awdp_product_slug] = -0.0000000001; foreach ($this->discount_rules as $k => $rule) { //validate cart based rules if (!$this->validate_discount_rules($product, $rule, ['cart_total_amount', 'cart_items', 'cust_prev_order_count'])) { continue; } if(!$this->get_items_to_apply_discount($product, $rule)){ continue; } if (!isset($this->discounts[$rule['id']])) { $this->discounts[$rule['id']] = ['label' => $rule['label'], 'discount_type' => $rule['type'], 'discount_remainder' => -1]; } // calculating discount if('percent_product_price' == $rule['type']) $this->apply_discount_percent_product_price($rule, $product, $price); else if('fixed_product_price' == $rule['type']) $this->apply_discount_fixed_product_price($rule, $product, $price); else if ('percent_total_amount' == $rule['type']) $this->apply_discount_percent_total_amount($rule, $product, $price); else if ('fixed_cart_amount' == $rule['type']) $this->apply_discount_fixed_price_total_amount($rule, $product, $price); else if ('cart_quantity' == $rule['type']) $this->apply_discount_cart_quantity($rule, $product, $price); } $_discounts = array(); foreach ($this->discounts as $discounts) { if($discounts['discount_type'] == 'percent_product_price' || $discounts['discount_type'] == 'fixed_product_price' || $discounts['discount_type'] == 'cart_quantity'){ if(array_key_exists('discounts', $discounts)) { if(!array_key_exists('type', $discounts['discounts'])) { foreach ($discounts['discounts'] as $key => $discount) { if (!isset($_discounts[$key])) { $_discounts[$key] = 0.0; } if( $discount != '') $_discounts[$key] += $discount; } } } } } if(!isset($_discounts[$product->get_data()['slug']])) $latest_price = $price; else if($price >= wc_remove_number_precision($_discounts[$product->get_data()['slug']])) $latest_price = $price - wc_remove_number_precision($_discounts[$product->get_data()['slug']]); else $latest_price = 0; return $latest_price; } public function load_rules() { if ($this->discount_rules === false) { // Get wordpress timezone settings $gmt_offset = get_option('gmt_offset'); $timezone_string = get_option('timezone_string'); if( $timezone_string ) { $datenow = new DateTime(current_time('mysql'), new DateTimeZone($timezone_string)); } else { $min = 60 * get_option('gmt_offset'); $sign = $min < 0 ? "-" : "+"; $absmin = abs($min); $tz = sprintf("%s%02d%02d", $sign, $absmin/60, $absmin%60); $datenow = new DateTime(current_time('mysql'), new DateTimeZone($tz)); } // Converting to UTC+000 (moment isoString timezone) $datenow->setTimezone(new DateTimeZone('+000')); $datenow = $datenow->format('Y-m-d H:i:s'); $stop_date = date('Y-m-d H:i:s', strtotime($datenow . ' +1 day')); $day = date("l"); $awdp_discount_args = array( 'post_type' => AWDP_POST_TYPE, 'post_status' => 'publish', 'posts_per_page' => -1, 'meta_key' => 'discount_priority', 'orderby' => 'meta_value_num', 'order' => 'ASC', 'meta_query' => array( 'relation' => 'AND', array( 'key' => 'discount_status', 'value' => 1, 'compare' => '=', 'type' => 'NUMERIC' ), array( 'key' => 'discount_start_date', 'value' => $datenow, 'compare' => '<=', 'type' => 'DATETIME' ), array( 'relation' => 'OR', array( 'key' => 'discount_type', 'value' => 'cart_quantity', 'compare' => '=' ), array( 'key' => 'discount_value', 'value' => '', 'compare' => '!=' ), ), array( 'relation' => 'OR', array( 'key' => 'discount_end_date', 'value' => $datenow, 'compare' => '>=', 'type' => 'DATETIME' ), array( 'key' => 'discount_end_date', 'compare' => 'NOT EXISTS', ), array( 'key' => 'discount_end_date', 'value' => '', 'compare' => '=', ), ) ) ); $awdp_discount_rules = get_posts($awdp_discount_args); $discount_rules = array(); if($awdp_discount_rules) { foreach ($awdp_discount_rules as $rule) { $schedules = unserialize(get_post_meta($rule->ID, 'discount_schedules', true)); foreach($schedules as $schedule) { $mn_start_time = date('H:i' , strtotime($schedule['start_date'])); $mn_end_time = date('H:i' , strtotime($schedule['end_date'])); $current_time = strtotime(gmdate('H:i')); $awdp_start_date = $schedule['start_date']; $awdp_end_start = $schedule['end_date'] ? $schedule['end_date'] : $stop_date; if( ( $awdp_start_date <= $datenow ) && ( $awdp_end_start >= $datenow ) ) { $rule_type = get_post_meta($rule->ID, 'discount_type', true); $discount_config = get_post_meta($rule->ID, 'discount_config', true); $discount_rules[] = array( 'id' => $rule->ID, 'priority' => get_post_meta($rule->ID, 'discount_priority', true), 'label' => ($discount_config['label'] != '') ? $discount_config['label'] : $rule->post_title, 'discount' => get_post_meta($rule->ID, 'discount_value', true), 'inc_tax' => $discount_config['inc_tax'], 'inc_tax' => $discount_config['inc_tax'], 'disable_on_sale' => $discount_config['disable_on_sale'], 'sequentially' => $discount_config['sequentially'], 'product_list' => get_post_meta($rule->ID, 'discount_product_list', true), 'rules' => unserialize(base64_decode($discount_config['rules'])), 'type' => $rule_type, 'quantity_rules' => unserialize(get_post_meta($rule->ID, 'discount_quantityranges', true)), 'quantity_type' => get_post_meta($rule->ID, 'discount_quantity_type', true), 'pricing_table' => get_post_meta($rule->ID, 'discount_pricing_table', true), 'table_layout' => get_post_meta($rule->ID, 'discount_table_layout', true) ); } } } } // Moving Cart based rules to least priority $cart_rules = []; foreach($discount_rules as $key => $val){ if( 'cart_quantity' == $val['type'] || 'fixed_cart_amount' == $val['type'] || 'percent_total_amount' == $val['type'] ){ $cart_rules[] = $discount_rules[$key]; unset($discount_rules[$key]); } } $discount_rules = array_merge($discount_rules, $cart_rules); $discount_rules = array_values($discount_rules); $this->discount_rules = $discount_rules; } } public function validate_discount_rules($cart_obj, $rule, $rules_to_validate = array(), $item = false) { $evel_str = ''; // $rules_to_validate = ['cart_total_amount', 'cart_items', 'cust_prev_order_count']; $result = true;// if no rules, the validation must be true if (isset($rule['rules']) && is_array($rule['rules']) && !empty($rule['rules'])) { foreach ($rule['rules'] as $val) { if (is_array($val['rules']) && count($val['rules']) && !empty($val['rules'])) { // echo 'rule'; $evel_str .= '('; foreach ($val['rules'] as $rul) { $evel_str .= '('; if (in_array($rul['rule']['item'], $rules_to_validate)) { if ($this->eval_rule($rul['rule'], $cart_obj, $item)) { $evel_str .= ' true '; } else { $evel_str .= ' false '; } } else { $evel_str .= ' true '; } $evel_str .= ') ' . (($rul['operator'] !== false) ? $rul['operator'] : '') . ' '; } if (count($val['rules']) > 0 && !empty($val['rules'])) { preg_match_all('/\(.*\)/', $evel_str, $match); $evel_str = $match[0][0] . ' '; } $evel_str .= ') ' . (($val['operator'] !== false) ? $val['operator'] : '') . ' '; } } if (count($rule['rules']) > 0 && !empty($rule['rules']) && $evel_str != '') { preg_match_all('/\(.*\)/', $evel_str, $match); $evel_str = $match[0][0] . ' '; } $evel_str = str_replace(['and', 'or'], ['&&', '||'], $evel_str); if ($evel_str !== '') { $result = eval('return ' . $evel_str . ';'); } } return $result; } public function eval_rule($rule, $cart_obj, $item = false) { if ('cart_total_amount' == $rule['item']) { // $item_val = $cart_obj->get_total(); // Check if cart is empty if(!isset(WC()->cart) || WC()->cart->total == 0) return false; $item_val = (float)WC()->cart->total; $rel_val = (float)$rule['value']; } else if ('product_price' == $rule['item']) { // $item_val = $item['data']->get_price('edit'); $item_val = (float)$item->get_data()['price']; $rel_val = (float)$rule['value']; } else if ('cart_items' == $rule['item']) { // $item_val = $item['data']->get_price('edit'); // Check if cart is empty if(!isset(WC()->cart) || WC()->cart->get_cart_contents_count() == 0) return false; $item_val = (float)WC()->cart->get_cart_contents_count(); $rel_val = (float)$rule['value']; } else { return false; } switch ($rule['condition']) { case 'equal_to': if (@abs(($item_val - $rel_val) / $item_val) < 0.00001) { return true; } break; case 'less_than': if ($item_val < $rel_val) { return true; } break; case 'less_than_eq': if ($item_val < $rel_val || abs(($item_val - $rel_val) / $item_val) < 0.0001) { return true; } break; case 'greater_than': if ($item_val > $rel_val) { return true; } break; case 'greater_than_eq': if ($item_val > $rel_val || abs(($item_val - $rel_val) / $item_val) < 0.0001) { return true; } break; } return false; } public function get_items_to_apply_discount($product, $rule) { $items = array(); global $woocommerce; //validate with $rule if (!$this->check_in_product_list($product, $rule)) { return false; } if (!$this->validate_discount_rules($product, $rule, ['product_price'], $product)) { return false; } if (isset($rule['disable_on_sale']) && $rule['disable_on_sale'] && $product->is_on_sale('edit')) { return true; } return true; } public function check_in_product_list($product, $rule) { if (0 == $rule['product_list']) { return true; } else { $this->set_product_list(); $pro_id = $product->get_parent_id(); // in case of variation if ($pro_id == 0) { $pro_id = $product->get_id(); } return isset($this->product_lists[$rule['product_list']]) && in_array($pro_id, $this->product_lists[$rule['product_list']]); } } public function set_product_list() { if (false == $this->product_lists) { if (false === ($product_lists = get_transient(AWDP_PRODUCTS_TRANSIENT_KEY))) { $post_type = AWDP_PRODUCT_LIST; global $wpdb; $product_lists = array(); $lists = $wpdb->get_col($wpdb->prepare(" SELECT pm.meta_value FROM {$wpdb->postmeta} pm LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id WHERE pm.meta_key = '%s' AND p.post_status = '%s' AND p.post_type = '%s' ", 'discount_product_list', 'publish', AWDP_POST_TYPE)); $post_ids = get_posts( array( 'fields' => 'ids', 'post_type' => AWDP_PRODUCT_LIST, 'post__in' => $lists, 'posts_per_page' => -1, ) ); foreach ($post_ids as $id) { $list_type = get_post_meta($id, 'list_type', true); $other_config = get_post_meta($id, 'product_list_config', true); // $other_config = array( // 'selectedProducts' => serialize($data['selectedProducts']), // 'productAuthor' => serialize($data['productAuthor']), // 'excludedProducts' => serialize($data['excludedProducts']), // 'taxRelation' => serialize($data['taxRelation']), // 'rules' => serialize($data['rules']), // ); $product_lists[$id] = array(); if ('products_selection' == $list_type) { $product_lists[$id] = ($other_config['selectedProducts']); } else { $tax_rules = ($other_config['rules']); $tax_rules = ($tax_rules && is_array($tax_rules) && !empty($tax_rules)) ? $tax_rules : false; $excludedProducts = ($other_config['excludedProducts']); $args = array( 'post_type' => 'product', 'posts_per_page' => -1, 'post__not_in' => $excludedProducts ); if (false !== $tax_rules) { if (isset($tax_rules[0]['rules']) && is_array($tax_rules[0]['rules'])) { $tax_query = array( 'relation' => ('or' == strtolower($other_config['taxRelation'])) ? 'OR' : 'AND' ); foreach (array_filter($tax_rules[0]['rules']) as $tr) { $tax_query[] = array( 'taxonomy' => $tr['rule']['item'], 'field' => 'term_id', 'terms' => $tr['rule']['value'], ); } $args['tax_query'] = $tax_query; } } $query = new WP_Query($args); $product_lists[$id] = wp_list_pluck($query->posts, 'ID'); } } set_transient(AWDP_PRODUCTS_TRANSIENT_KEY, $product_lists, 7 * 24 * HOUR_IN_SECONDS); } $this->product_lists = $product_lists; } } // Cart Total Discount /////////////////////////////// public function apply_discount_percent_total_amount($rule, $item, $price) { $total_discount = 0; $cart_total = 0; $prod_ID = $item->get_data()['slug']; if(( $this->discounted_price[$prod_ID] != '' && $this->discounted_price[$prod_ID] > 0 ) || $this->discounted_price[$prod_ID] == 0 ) { $price_to_discount = $this->discounted_price[$prod_ID]; } else { // Find out how much price is available to discount for the item. // $discounted_price = $this->get_discounted_price_in_cents($item, $rule['inc_tax'], true); // $actual_price = $this->get_discounted_price_in_cents($item, $rule['inc_tax'], false); $price_to_discount = wc_add_number_precision($price); } $discount = $price_to_discount * ((int)$rule['discount'] / 100); $discount = min($price_to_discount, $discount); // Store code and discount amount per item. $cart_total = $cart_total + $price_to_discount; $total_discount = $total_discount + $discount; // $prod_ID = $item->get_data()['slug']; // if(!$this->discounts[$rule['id']]['discount_applied'][$prod_ID]) { $this->discounts[$rule['id']]['discounts'][$prod_ID] = $discount; // $this->discounts[$rule['id']]['discount_applied'][$prod_ID] = true; // } } public function apply_discount_fixed_price_total_amount($rule, $item, $price) { $total_discount = 0; $cart_total = 0; $prod_ID = $item->get_data()['slug']; if(( $this->discounted_price[$prod_ID] != '' && $this->discounted_price[$prod_ID] > 0 ) || $this->discounted_price[$prod_ID] == 0) { $price_to_discount = $this->discounted_price[$prod_ID]; } else { // $price_to_discount = wc_add_number_precision($this->get_discounted_price_in_cents($item, $rule['inc_tax'], false)); // $price_to_discount = wc_add_number_precision($item->get_data()['price']); $price_to_discount = wc_add_number_precision($price); } $discount = wc_add_number_precision($rule['discount']); if($this->discounts[$rule['id']]['discount_remainder'] >= 0){ $discount = $this->discounts[$rule['id']]['discount_remainder']; } if( !isset($this->discounts[$rule['id']]['discounts'][$prod_ID]) ) { if(intval($price_to_discount) >= $discount && $discount >= 0) { $discounted_price = $price_to_discount - $discount; $product_discount = $discount; $this->discounts[$rule['id']]['discount_remainder'] = 0; } else if(intval($price_to_discount) < $discount && $discount >= 0){ $discounted_price = $price_to_discount; $product_discount = $discounted_price; $this->discounts[$rule['id']]['discount_remainder'] = $discount - $price_to_discount; } else { $product_discount = 0; } $this->discounts[$rule['id']]['discounts'][$prod_ID] = $product_discount; } } // Quantity based discount ///////////////////////////////// public function apply_discount_cart_quantity($rule, $item, $price) { $quantity_rules = $rule['quantity_rules']; $quantity_type = $rule['quantity_type']; $table_layout = $rule['table_layout']; $prod_ID = $item->get_data()['slug']; $discount = ''; // Get product price if(( $this->discounted_price[$prod_ID] != '' && $this->discounted_price[$prod_ID] > 0 ) || $this->discounted_price[$prod_ID] == 0) { $price_to_discount = $this->discounted_price[$prod_ID]; } else { // $price_to_discount = wc_add_number_precision($this->get_discounted_price_in_cents($item, $rule['inc_tax'], false)); // $price_to_discount = wc_add_number_precision($item->get_data()['price']); $price_to_discount = wc_add_number_precision($price); } // Sort array_multisort( array_column($quantity_rules, "end_range"), SORT_ASC, $quantity_rules ); $last_key = end($quantity_rules); $max_range = $last_key["end_range"]; // if ( WC()->cart->get_cart_contents_count() > 0 ) { if ( $quantity_type == 'type_cart' && WC()->cart ) { $cart_items_count = WC()->cart->get_cart_contents_count(); $cart_total = WC()->cart->total; foreach( $quantity_rules as $quantity_rule ) { if( $cart_items_count >= $quantity_rule['start_range'] && $cart_items_count <= $quantity_rule['end_range'] ){ $discount_val = $quantity_rule['dis_value']; $discount_typ = $quantity_rule['dis_type']; $discount_amt = 0; if($discount_typ == 'percentage') { $discount_amt = $cart_total * ($discount_val / 100); $this->discounts[$rule['id']]['discounts']['type'] = 'percentage'; $this->discounts[$rule['id']]['discounts']['value'] = $discount_val; } else if ($discount_typ == 'fixed') { $discount_amt = $discount_val; $this->discounts[$rule['id']]['discounts']['type'] = 'fixed'; $this->discounts[$rule['id']]['discounts']['value'] = $discount_val; } else { $discount_amt = 0; $this->discounts[$rule['id']]['discounts']['type'] = ''; $this->discounts[$rule['id']]['discounts']['value'] = 0; } $cart_total = $cart_total - $discount_amt; $cart_fee = $discount_amt; } else if( $cart_items_count >= $max_range ) { $discount_val = $last_key['dis_value']; $discount_typ = $last_key['dis_type']; $discount_amt = 0; if($discount_typ == 'percentage') { $discount_amt = $cart_total * ($discount_val / 100); $this->discounts[$rule['id']]['discounts']['type'] = 'percentage'; $this->discounts[$rule['id']]['discounts']['value'] = $discount_val; } else if ($discount_typ == 'fixed') { $discount_amt = $discount_val; $this->discounts[$rule['id']]['discounts']['type'] = 'fixed'; $this->discounts[$rule['id']]['discounts']['value'] = $discount_val; } else { $discount_amt = 0; $this->discounts[$rule['id']]['discounts']['type'] = ''; $this->discounts[$rule['id']]['discounts']['value'] = 0; } $cart_total = $cart_total - $discount_amt; $cart_fee = $discount_amt; } } } else if ( $quantity_type == 'type_product' ) { // product quantity if(WC()->cart) { $cart_contents = WC()->cart->get_cart(); } else { $cart_contents = []; } $prod_QNT = []; if( $cart_contents ) { foreach($cart_contents as $cart_content){ $prod_QNT[$cart_content['data']->get_data()['slug']] = $cart_content['quantity']; } } if( $table_layout == 'horizontal' ) { $table = '

Quantity Discounts

'; $tr_qn = ''; $tr_pr = ''; } else { $table = '

Quantity Discounts

Quantity
Price
'; } foreach( $quantity_rules as $quantity_rule ) { $discount_val = $quantity_rule['dis_value']; $discount_typ = $quantity_rule['dis_type']; // $discount = ''; if( array_key_exists($prod_ID, $prod_QNT) ) { if( $prod_QNT[$prod_ID] >= $quantity_rule['start_range'] && $prod_QNT[$prod_ID] <= $quantity_rule['end_range'] ) { if( $discount_typ == 'percentage' ) { $discount = $price_to_discount * ((int)$discount_val / 100); $discount = min($price_to_discount, $discount); } else if ($discount_typ == 'fixed') { $discount = wc_add_number_precision($discount_val); } } else if( $prod_QNT[$prod_ID] >= $max_range ) { $discount_val_max = $last_key['dis_value']; $discount_typ_max = $last_key['dis_type']; if( $discount_typ_max == 'percentage' ) { $discount = $price_to_discount * ((int)$discount_val_max / 100); $discount = min($price_to_discount, $discount); } else if ($discount_typ_max == 'fixed') { $discount = wc_add_number_precision($discount_val_max); } } } // Pricing Table Calculations if( $discount_typ == 'percentage' ) { $discount_pt = $price_to_discount * ((int)$discount_val / 100); $discount_pt = min($price_to_discount, $discount_pt); } else if ($discount_typ == 'fixed') { $discount_pt = wc_add_number_precision($discount_val); } $discounted_new_price = wc_remove_number_precision( $price_to_discount - $discount_pt ); if( $discounted_new_price < 0 ) $discounted_new_price = 0; // if($table_layout == 'horizontal') { // $tr_qn .= ''; // $tr_pr .= ''; // } else { // $table .= ''; // } if($table_layout == 'horizontal') { if($quantity_rule['end_range']) { $tr_qn .= ''; } else { $tr_qn .= ''; } $tr_pr .= ''; } else { if($quantity_rule['end_range']) { $table .= ''; } else { $table .= ''; } } // End PT } if($table_layout == 'horizontal') { $tr_qn .= ''; $tr_pr .= ''; $table .= $tr_qn.$tr_pr.'
QuantityPrice
'. $quantity_rule['start_range'] .' - '. $quantity_rule['end_range'] .''. get_woocommerce_currency_symbol() . $discounted_new_price .'
'. $quantity_rule['start_range'] .' - '. $quantity_rule['end_range'] .''. get_woocommerce_currency_symbol() . $discounted_new_price .'
'. $quantity_rule['start_range'] .' - '. $quantity_rule['end_range'] .'Above '. $quantity_rule['start_range'] .''. get_woocommerce_currency_symbol() . $discounted_new_price .'
'. $quantity_rule['start_range'] .' - '. $quantity_rule['end_range'] .''. get_woocommerce_currency_symbol() . $discounted_new_price .'
Above '. $quantity_rule['start_range'] .''. get_woocommerce_currency_symbol() . $discounted_new_price .'
'; } else { $table .= ''; } // Prcinig Table if($rule['pricing_table'] == 1) $this->pricing_table[$item->get_id()] = $table; if( array_key_exists($prod_ID, $prod_QNT) ) { $this->discounts[$rule['id']]['discounts'][$prod_ID] = $discount; if($price_to_discount >= $discount && $discount != '') { $updated_product_price = $price_to_discount - $discount; } else { $updated_product_price = $price_to_discount; } $this->discounted_price[$prod_ID] = $updated_product_price; } } // } } // Product Based Discounts //////////////////////////////// public function apply_discount_fixed_product_price($rule, $item, $price) { $prod_ID = $item->get_data()['slug']; if(( $this->discounted_price[$prod_ID] != '' && $this->discounted_price[$prod_ID] > 0 ) || $this->discounted_price[$prod_ID] == 0 ) { $product_original_price = $this->discounted_price[$prod_ID]; } else { // $product_original_price = $this->get_individual_discounted_price_in_cents($item, $rule['inc_tax'], false);] $product_original_price = wc_add_number_precision($price); } $discount_amount = wc_add_number_precision($rule['discount']); if($product_original_price >= $discount_amount) { $updated_product_price = $product_original_price - $discount_amount; $single_discount_amount = $discount_amount; } else { $updated_product_price = 0; $single_discount_amount = $product_original_price; } $this->discounts[$rule['id']]['discounts'][$prod_ID] = $single_discount_amount; $this->discounted_price[$prod_ID] = $updated_product_price; } public function apply_discount_percent_product_price($rule, $item, $price) { $total_discount = 0; $cart_total = 0; global $woocommerce; $prod_ID = $item->get_data()['slug']; if(( $this->discounted_price[$prod_ID] != '' && $this->discounted_price[$prod_ID] > 0 ) || $this->discounted_price[$prod_ID] == 0) { $product_original_price = $this->discounted_price[$prod_ID]; } else { // Find out how much price is available to discount for the item. // $discounted_price = $this->get_individual_discounted_price_in_cents($item, $rule['inc_tax'], true); // $actual_price = $this->get_individual_discounted_price_in_cents($item, $rule['inc_tax'], false); // sequential // $product_original_price = ($rule['sequentially']) ? $discounted_price : $actual_price; // check if apply_ sequential // $product_original_price = wc_add_number_precision($item->get_data()['price']); $product_original_price = wc_add_number_precision($price); } $discount = floor($product_original_price * ($rule['discount'] / 100)); // $discount = min($discounted_price, $discount); if($product_original_price >=$discount) $updated_product_price = $product_original_price - $discount; else $updated_product_price = 0; $this->discounts[$rule['id']]['discounts'][$prod_ID] = $discount; $this->discounted_price[$prod_ID] = $updated_product_price; } ///////////////////////////// public function get_discounted_price_in_cents($item, $include_tax = true, $sequential = false) { $actual_price = $item->get_data()['price']; if ($include_tax) { $price = wc_get_price_including_tax($item, array( 'price' => $actual_price, )); } else { $price = wc_get_price_excluding_tax($item, array( 'price' => $actual_price, )); } if($sequential) return absint(round($price - wc_remove_number_precision($this->get_discount($item->get_id(), true)))); else return $price; } public function get_individual_discounted_price_in_cents($item, $include_tax = true, $sequential = false) { $latest_price = ''; if ($include_tax) { $price = wc_get_price_including_tax($item, array( 'price' => $item->get_data()['price'], )); } else { $price = wc_get_price_excluding_tax($item, array( 'price' => $item->get_data()['price'], )); } if($sequential) return absint(round($price - $this->get_discount($item->get_id(), true))); else return $price; } public function get_discount($key, $in_cents = false) { $item_discount_totals = $this->get_discounts_by_item($in_cents); return isset($item_discount_totals[$key]) ? $item_discount_totals[$key] : 0; } public function get_discounts_by_item($in_cents = false) { $discounts = $this->discounts; $item_discount_totals = array(); foreach ($discounts as $item_discounts) { if($item_discounts['discounts']){ foreach ($item_discounts['discounts'] as $item_key => $item_discount) { if (!isset($item_discount_totals[$item_key])) { $item_discount_totals[$item_key] = 0.0; } $item_discount_totals[$item_key] += $item_discount; } } } return $in_cents ? $item_discount_totals : $item_discount_totals; } protected function apply_discount_remainder($rule, $items_to_apply, $amount) { $total_discount = 0; foreach ($items_to_apply as $item) { for ($i = 0; $i < $item->quantity; $i++) { // Find out how much price is available to discount for the item. $discounted_price = $this->get_discounted_price_in_cents($item); // $price_to_discount = (false) ? $discounted_price : $item->price;// check if apply_ sequential $discount = min($discounted_price, 1); // Store totals. $total_discount += $discount; // Store code and discount amount per item. $this->discounts[$rule['id']]['discounts'][$item->key] += $discount; if ($total_discount >= $amount) { break 2; } } if ($total_discount >= $amount) { break; } } return $total_discount; } public function show_discounts($cart_obj) { if (is_admin() && !defined('DOING_AJAX')) return; $cart_contents = $cart_obj->get_cart(); $prod_QNT = []; foreach($cart_contents as $cart_content){ $prod_QNT[$cart_content['data']->get_data()['slug']] = $cart_content['quantity']; } global $woocommerce; $_discounts = array(); foreach ($this->discounts as $discounts) { if($discounts['discount_type'] == 'percent_total_amount' || $discounts['discount_type'] == 'fixed_cart_amount'){ $total = 0; if(array_key_exists('discounts', $discounts)) { foreach ($discounts['discounts'] as $key => $discount) { if($discounts['discount_type'] == 'fixed_cart_amount') { $total = $total + ( wc_remove_number_precision($discount) ); } else { $total = $total + ( wc_remove_number_precision($discount) * $prod_QNT[$key] ); } } if ( $total > 0 ) { $woocommerce->cart->add_fee($discounts['label'], $total * -1); } } } else if($discounts['discount_type'] == 'cart_quantity') { if(array_key_exists('type', $discounts['discounts'])) { if($discounts['discounts']['type'] == 'percentage') { $cart_discount = $cart_obj->cart_contents_total * ( $discounts['discounts']['value'] / 100 ); } else if($discounts['discounts']['type'] == 'fixed') { $cart_discount = $discounts['discounts']['value']; } else { $cart_discount = 0; } if ( $cart_discount > 0 ) { $woocommerce->cart->add_fee($discounts['label'], $cart_discount * -1); } } } } } public function check_discount($slug) { $_discounts = array(); foreach ($this->discounts as $discounts) { if($discounts['discount_type'] == 'percent_product_price' || $discounts['discount_type'] == 'fixed_product_price' || $discounts['discount_type'] == 'cart_quantity'){ if(array_key_exists('discounts', $discounts)) { if(!array_key_exists('type', $discounts['discounts'])) { foreach ($discounts['discounts'] as $key => $discount) { if (!isset($_discounts[$key])) { $_discounts[$key] = 0.0; } if( $discount != '') $_discounts[$key] += $discount; } } } } } if(isset($_discounts[$slug]) && $_discounts[$slug] > 0) return true; else return false; } /** * Cloning is forbidden. * * @since 1.0.0 */ public function __clone() { _doing_it_wrong(__FUNCTION__, __('Cheatin’ huh?'), $this->_version); } /** * Unserializing instances of this class is forbidden. * * @since 1.0.0 */ public function __wakeup() { _doing_it_wrong(__FUNCTION__, __('Cheatin’ huh?'), $this->_version); } }