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 = '| Quantity | ';
$tr_pr = '
| Price | ';
} 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 .= ''. $quantity_rule['start_range'] .' - '. $quantity_rule['end_range'] .' | ';
// $tr_pr .= ''. get_woocommerce_currency_symbol() . $discounted_new_price .' | ';
// } else {
// $table .= '| '. $quantity_rule['start_range'] .' - '. $quantity_rule['end_range'] .' | '. get_woocommerce_currency_symbol() . $discounted_new_price .' |
';
// }
if($table_layout == 'horizontal') {
if($quantity_rule['end_range']) {
$tr_qn .= ''. $quantity_rule['start_range'] .' - '. $quantity_rule['end_range'] .' | ';
} else {
$tr_qn .= 'Above '. $quantity_rule['start_range'] .' | ';
}
$tr_pr .= ''. get_woocommerce_currency_symbol() . $discounted_new_price .' | ';
} else {
if($quantity_rule['end_range']) {
$table .= '| '. $quantity_rule['start_range'] .' - '. $quantity_rule['end_range'] .' | '. get_woocommerce_currency_symbol() . $discounted_new_price .' |
';
} else {
$table .= '| Above '. $quantity_rule['start_range'] .' | '. get_woocommerce_currency_symbol() . $discounted_new_price .' |
';
}
}
// End PT
}
if($table_layout == 'horizontal') {
$tr_qn .= '';
$tr_pr .= '';
$table .= $tr_qn.$tr_pr.'
';
} 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);
}
}