Пример #1
0
function vtprd_format_amt_and_adjust_for_taxes($amt, $k = null)
{
    global $post, $wpdb, $woocommerce, $vtprd_cart, $vtprd_cart_item, $vtprd_setup_options, $vtprd_info;
    //error_log( print_r(  'vtprd_format_amt_and_adjust_for_taxes, Begin price= ' .$amt, true ) );
    //at a minimum, format $amt
    if (get_option('woocommerce_calc_taxes') == 'no' || vtprd_maybe_customer_tax_exempt()) {
        //v1.0.7.9
        return vtprd_format_money_element($amt);
    }
    $woocommerce_prices_include_tax = get_option('woocommerce_prices_include_tax');
    $woocommerce_tax_display_cart = get_option('woocommerce_tax_display_cart');
    if ($woocommerce_prices_include_tax == 'yes') {
        switch (true) {
            case $woocommerce_tax_display_cart == 'incl':
                $amt = vtprd_format_money_element($amt);
                break;
            case $woocommerce_tax_display_cart == 'excl':
                $product_id = $vtprd_cart->cart_items[$k]->product_id;
                $amt = vtprd_get_price_excluding_tax($product_id, $amt);
                $amt = vtprd_format_money_element($amt);
                break;
        }
    } else {
        // price does NOT include tax
        switch (true) {
            case $woocommerce_tax_display_cart == 'excl':
                $amt = vtprd_format_money_element($amt);
                break;
            case $woocommerce_tax_display_cart == 'incl':
                $qty = 1;
                $_tax = new WC_Tax();
                $product = get_product($vtprd_cart->cart_items[$k]->product_id);
                $tax_rates = $_tax->get_rates($product->get_tax_class());
                $taxes = $_tax->calc_tax($amt * $qty, $tax_rates, false);
                $tax_amount = $_tax->get_tax_total($taxes);
                $amt = round($amt * $qty + $tax_amount, absint(get_option('woocommerce_price_num_decimals')));
                $amt = vtprd_format_money_element($amt);
                break;
        }
    }
    $amt .= vtprd_maybe_load_incl_excl_vat_lit();
    return $amt;
}
Пример #2
0
 public function vtprd_upd_cart_discount($i, $d, $curr_prod_array)
 {
     global $post, $vtprd_setup_options, $vtprd_cart, $vtprd_rules_set, $vtprd_rule, $vtprd_info, $vtprd_template_structures_framework;
     //error_log( print_r(  'vtprd_upd_cart_discount AT TOP, $i= ' .$i. ' $d= ' .$d, true ) );
     //error_log( print_r(  '$curr_prod_array AT TOP= ', true ) );
     //error_log( var_export($curr_prod_array, true ) );
     $k = $curr_prod_array['prod_id_cart_occurrence'];
     $rule_id = $vtprd_rules_set[$i]->post_id;
     $product_id = $vtprd_cart->cart_items[$k]->product_id;
     //v1.1.1.2
     if ($curr_prod_array['prod_discount_amt'] == 0) {
         //v1.1.0.6 begin -  don't skip this if there is a zero priced product on an auto insert rule...
         $current_auto_add_array = $this->vtprd_get_current_auto_add_array();
         if ($vtprd_info['current_processing_request'] == 'cart' && $vtprd_rules_set[$i]->rule_contains_auto_add_free_product == 'yes' && $vtprd_cart->cart_items[$k]->product_auto_insert_rule_id == $vtprd_rules_set[$i]->post_id && isset($current_auto_add_array[$product_id]) && $vtprd_cart->cart_items[$k]->unit_price == 0) {
             $vtprd_cart->cart_items[$k]->cartAuditTrail[$vtprd_rules_set[$i]->post_id]['discount_msgs'][] = 'Zero price auto add product';
             $vtprd_cart->cart_items[$k]->zero_price_auto_add_free_item = 'yes';
             //MARK FOR PRINTING FUNCTIONS
             $vtprd_cart->cart_has_zero_price_auto_add_free_item = 'yes';
             //MARK FOR PRINTING FUNCTIONS
         } else {
             $vtprd_cart->cart_items[$k]->cartAuditTrail[$vtprd_rules_set[$i]->post_id]['discount_msgs'][] = 'No discount for this rule';
             return;
         }
         //v1.1.0.6 end
     }
     //just in case discount for this rule already applied to this product iteration....
     //mark exploded list product as already processed for this rule
     $occurrence = $curr_prod_array['exploded_group_occurrence'];
     if ($curr_prod_array['prod_discount_applied'] == 'yes' || $vtprd_rules_set[$i]->actionPop_exploded_found_list[$occurrence]['prod_discount_applied'] == 'yes') {
         $vtprd_cart->cart_items[$k]->cartAuditTrail[$vtprd_rules_set[$i]->post_id]['discount_msgs'][] = 'Discount already applied, can"t reapply';
         //exit stage left, can't apply discount for same rule to same product....
         return;
     }
     //*********************************************************************
     //CHECK THE MANY DIFFERENT MAX LIMITS BEFORE UPDATING THE DISCOUNT TO THE ARRAY
     //*********************************************************************
     //v1.0.8.4 begin
     if ($vtprd_rules_set[$i]->cumulativeRulePricing == 'no' && $vtprd_cart->cart_items[$k]->product_already_in_an_all_rule == 'yes') {
         $vtprd_cart->cart_items[$k]->cartAuditTrail[$vtprd_rules_set[$i]->post_id]['discount_msgs'][] = 'No Discount - counted as part of an "all" rule group from previous discount, no more allowed';
         return;
     }
     //v1.0.8.4 begin
     if (isset($vtprd_cart->cart_items[$k]->yousave_by_rule_info[$rule_id])) {
         if (sizeof($vtprd_cart->cart_items[$k]->yousave_by_rule_info) > 1 && $vtprd_rules_set[$i]->cumulativeRulePricing == 'no') {
             //1 discount rule already applied discount, no more allowed;
             $vtprd_cart->cart_items[$k]->cartAuditTrail[$vtprd_rules_set[$i]->post_id]['discount_msgs'][] = 'No Discount - 1 discount rule already applied discount, no more allowed';
             return;
         }
         if ($vtprd_setup_options['discount_floor_pct_per_single_item'] > 0) {
             if ($vtprd_rules_set[$i]->rule_deal_info[$d]['discount_amt_type'] != 'free') {
                 if ($vtprd_cart->cart_items[$k]->yousave_by_rule_info[$rule_id]['yousave_pct'] >= $vtprd_setup_options['discount_floor_pct_per_single_item'] || $vtprd_cart->cart_items[$k]->yousave_by_rule_info[$rule_id]['rule_max_amt_msg'] > ' ') {
                     //yousave percent max alread reached in a previous discount!!!!!!  Do Nothing
                     $vtprd_cart->cart_items[$k]->cartAuditTrail[$vtprd_rules_set[$i]->post_id]['discount_msgs'][] = 'No Discount - Discount floor percentage max reached, ' . $vtprd_setup_options['discount_floor_pct_msg'];
                     //floor percentage maxed out;
                     return;
                 }
             }
         }
         //v1.0.7.4 begin
         //CHECK if catalog discount already applied , from v1.0.7.4 in free version
         if ($vtprd_info['current_processing_request'] == 'cart') {
             if ($vtprd_cart->cart_items[$k]->unit_price < $vtprd_cart->cart_items[$k]->save_orig_unit_price && $vtprd_rules_set[$i]->cumulativeRulePricing == 'no') {
                 //A Catalog or other external discount previously applied, no
                 $vtprd_cart->cart_items[$k]->cartAuditTrail[$vtprd_rules_set[$i]->post_id]['discount_msgs'][] = 'No Discount - CATALOG discount rule already applied discount, no more allowed';
                 return;
             }
         }
         //v1.0.7.4 end
         switch ($vtprd_rules_set[$i]->rule_deal_info[0]['discount_rule_max_amt_type']) {
             case 'none':
                 $do_nothing;
                 break;
             case 'percent':
                 if ($vtprd_cart->cart_items[$k]->yousave_by_rule_info[$rule_id]['yousave_pct'] >= $vtprd_rules_set[$i]->rule_deal_info[0]['discount_rule_max_amt_count'] || $vtprd_cart->cart_items[$k]->yousave_by_rule_info[$rule_id]['rule_max_amt_msg'] > ' ') {
                     $vtprd_cart->cart_items[$k]->cartAuditTrail[$vtprd_rules_set[$i]->post_id]['discount_msgs'][] = 'No Discount - Rule Max Percent Previously Reached.';
                     //floor percentage maxed out;
                     return;
                 }
                 break;
             case 'quantity':
                 if ($vtprd_cart->cart_items[$k]->yousave_by_rule_info[$rule_id]['discount_applies_to_qty'] >= $vtprd_rules_set[$i]->rule_deal_info[0]['discount_rule_max_amt_count'] || $vtprd_cart->cart_items[$k]->yousave_by_rule_info[$rule_id]['rule_max_amt_msg'] > ' ') {
                     $vtprd_cart->cart_items[$k]->cartAuditTrail[$vtprd_rules_set[$i]->post_id]['discount_msgs'][] = 'No Discount - Rule Max Qty Previously Reached.';
                     //floor percentage maxed out;
                     return;
                 }
                 break;
             case 'currency':
                 if ($vtprd_cart->cart_items[$k]->yousave_by_rule_info[$rule_id]['yousave_amt'] >= $vtprd_rules_set[$i]->rule_deal_info[0]['discount_rule_max_amt_count'] || $vtprd_cart->cart_items[$k]->yousave_by_rule_info[$rule_id]['rule_max_amt_msg'] > ' ') {
                     $vtprd_cart->cart_items[$k]->cartAuditTrail[$vtprd_rules_set[$i]->post_id]['discount_msgs'][] = 'No Discount - Rule Max $$ Value Previously Reached.';
                     //floor percentage maxed out;
                     return;
                 }
                 break;
         }
         switch ($vtprd_rules_set[$i]->rule_deal_info[0]['discount_rule_cum_max_amt_type']) {
             case 'none':
                 $do_nothing;
                 break;
             case 'percent':
                 if ($vtprd_rules_set[$i]->discount_total_pct >= $vtprd_rules_set[$i]->rule_deal_info[0]['discount_rule_cum_max_amt_count']) {
                     $vtprd_cart->cart_items[$k]->cartAuditTrail[$vtprd_rules_set[$i]->post_id]['discount_msgs'][] = 'No Discount - Rule Cumulative Max Percent Previously Reached.';
                     //floor percentage maxed out;
                     return;
                 }
                 break;
             case 'quantity':
                 if ($vtprd_rules_set[$i]->discount_total_qty >= $vtprd_rules_set[$i]->rule_deal_info[0]['discount_rule_cum_max_amt_count']) {
                     $vtprd_cart->cart_items[$k]->cartAuditTrail[$vtprd_rules_set[$i]->post_id]['discount_status'] = 'rejected';
                     $vtprd_cart->cart_items[$k]->cartAuditTrail[$vtprd_rules_set[$i]->post_id]['discount_msgs'][] = 'No Discount - Rule Cumulative Max Qty Previously Reached.';
                     //floor percentage maxed out;
                     return;
                 }
                 break;
             case 'currency':
                 if ($vtprd_rules_set[$i]->discount_total_amt >= $vtprd_rules_set[$i]->rule_deal_info[0]['discount_rule_cum_max_amt_count']) {
                     $vtprd_cart->cart_items[$k]->cartAuditTrail[$vtprd_rules_set[$i]->post_id]['discount_msgs'][] = 'No Discount - Rule Cumulative Max $$ Value Previously Reached.';
                     //floor percentage maxed out;
                     return;
                 }
                 break;
         }
         $yousave_for_this_rule_id_already_exists = 'yes';
     } else {
         if (sizeof($vtprd_cart->cart_items[$k]->yousave_by_rule_info) > 0 && $vtprd_rules_set[$i]->cumulativeRulePricing == 'no') {
             //1 discount rule already applied discount, no more allowed
             $vtprd_cart->cart_items[$k]->cartAuditTrail[$vtprd_rules_set[$i]->post_id]['discount_msgs'][] = 'No Discount - Discount for this another rule already applied to this Product, multiple rule discounts not allowed.';
             return;
         }
         $yousave_for_this_rule_id_already_exists = 'no';
     }
     //*****************************************
     //find current product's yousave percent, altered as needed below
     //*****************************************
     if ($vtprd_rules_set[$i]->rule_deal_info[$d]['discount_amt_type'] == 'percent') {
         $yousave_pct = $vtprd_rules_set[$i]->rule_deal_info[$d]['discount_amt_count'];
     } else {
         //compute yousave_pct_at_upd_begin
         $computed_pct = $curr_prod_array['prod_discount_amt'] / $curr_prod_array['prod_unit_price'];
         //$computed_pct_2decimals = bcdiv($curr_prod_array['prod_discount_amt'] , $curr_prod_array['prod_unit_price'] , 2);
         $computed_pct_2decimals = round($curr_prod_array['prod_discount_amt'] / $curr_prod_array['prod_unit_price'], 2);
         //$remainder = $computed_pct - $computed_pct_2decimals;
         $remainder = round($computed_pct - $computed_pct_2decimals, 4);
         //v1.0.7.4  PHP floating point error fix - limit to 4 places right of the decimal!!
         if ($remainder > 0.005) {
             //v1.0.7.4 begin
             $increment = round($remainder, 2);
             //round the rounding error to 2 decimal points!  floating point
             if ($increment < 0.01) {
                 $increment = 0.01;
             }
             ////v1.0.7.4 end
             $yousave_pct = ($computed_pct_2decimals + $increment) * 100;
             //v1.0.7.4   floating point
         } else {
             $yousave_pct = $computed_pct_2decimals * 100;
         }
     }
     $max_msg = '';
     $discount_status = '';
     //compute current discount_totals for limits testing
     $discount_total_qty_for_rule = $vtprd_rules_set[$i]->discount_total_qty_for_rule + 1;
     $discount_total_amt_for_rule = $vtprd_rules_set[$i]->discount_total_amt_for_rule + $curr_prod_array['prod_discount_amt'];
     //$discount_total_unit_price_for_rule will be the unit qty * db_unit_price already, as this routine is done 1 by 1...
     $discount_total_unit_price_for_rule = $vtprd_rules_set[$i]->discount_total_unit_price_for_rule + $curr_prod_array['prod_unit_price'];
     //yousave pct whole number  = total discount amount / (orig unit price * number of units discounted)
     $discount_total_pct_for_rule = $discount_total_amt_for_rule / $discount_total_unit_price_for_rule * 100;
     //in round #s
     //adjust yousave_amt and yousave_pct as needed based on limits
     switch ($vtprd_rules_set[$i]->rule_deal_info[0]['discount_rule_max_amt_type']) {
         //var on the 1st iteration only
         case 'none':
             $do_nothing;
             break;
         case 'percent':
             if ($discount_total_pct_for_rule > $vtprd_rules_set[$i]->rule_deal_info[0]['discount_rule_max_amt_count']) {
                 // % = floor minus rule % totaled in previous iteration
                 $yousave_pct = $vtprd_rules_set[$i]->rule_deal_info[0]['discount_rule_max_amt_count'] - $vtprd_rules_set[$i]->discount_total_pct_for_rule;
                 //*********************************************************************
                 //reduce discount amount to max allowed by rule percentage
                 //*********************************************************************
                 //$discount_2decimals = bcmul(($yousave_pct / 100) , $curr_prod_array['prod_unit_price'] , 2);
                 $discount_2decimals = round($yousave_pct / 100 * $curr_prod_array['prod_unit_price'], 2);
                 //v1.0.7.6
                 //compute rounding
                 $temp_discount = $yousave_pct / 100 * $curr_prod_array['prod_unit_price'];
                 //$rounding = $temp_discount - $discount_2decimals;
                 $rounding = round($temp_discount - $discount_2decimals, 4);
                 //v1.0.7.4  PHP floating point error fix - limit to 4 places right of the decimal!!
                 if ($rounding > 0.005) {
                     //v1.0.7.4 begin
                     $increment = round($rounding, 2);
                     //round the rounding error to 2 decimal points!  floating point
                     if ($increment < 0.01) {
                         $increment = 0.01;
                     }
                     ////v1.0.7.4 end
                     $discount = $discount_2decimals + $increment;
                     //v1.0.7.4  floating point
                 } else {
                     $discount = $discount_2decimals;
                 }
                 $curr_prod_array['prod_discount_amt'] = $discount;
                 $max_msg = $vtprd_rules_set[$i]->discount_rule_max_amt_msg;
                 $vtprd_cart->cart_items[$k]->cartAuditTrail[$vtprd_rules_set[$i]->post_id]['discount_msgs'][] = 'Discount reduced due to max rule percent overrun.';
             }
             break;
         case 'quantity':
             if ($discount_total_qty_for_rule > $vtprd_rules_set[$i]->rule_deal_info[0]['discount_rule_max_amt_count']) {
                 //we've reached the max allowed by this rule, as we only process 1 at a time, exit
                 $vtprd_cart->cart_items[$k]->cartAuditTrail[$vtprd_rules_set[$i]->post_id]['discount_msgs'][] = 'No Discount - Discount Rule Max Qty already reached, discount skipped';
                 return;
             }
             break;
         case 'currency':
             if ($discount_total_amt_for_rule > $vtprd_rules_set[$i]->rule_deal_info[0]['discount_rule_max_amt_count']) {
                 //reduce discount to max...
                 $reduction_amt = $discount_total_amt_for_rule - $vtprd_rules_set[$i]->rule_deal_info[0]['discount_rule_max_amt_count'];
                 $curr_prod_array['prod_discount_amt'] = $curr_prod_array['prod_discount_amt'] - $reduction_amt;
                 //v1.0.9.3 begin
                 if ($curr_prod_array['prod_discount_amt'] > $curr_prod_array['prod_unit_price']) {
                     $curr_prod_array['prod_discount_amt'] = $curr_prod_array['prod_unit_price'];
                 }
                 //v1.0.9.3 end
                 $max_msg = $vtprd_rules_set[$i]->discount_rule_max_amt_msg;
                 $yousave_pct_temp = $curr_prod_array['prod_discount_amt'] / $curr_prod_array['prod_unit_price'];
                 // $yousave_pct = $yousave_amt / $curr_prod_array['prod_unit_price'] * 100;
                 //compute remainder
                 //$yousave_pct_2decimals = bcdiv($curr_prod_array['prod_discount_amt'] , $curr_prod_array['prod_unit_price'] , 2);
                 $yousave_pct_2decimals = round($curr_prod_array['prod_discount_amt'] / $curr_prod_array['prod_unit_price'], 2);
                 //$remainder = $yousave_pct_temp - $yousave_pct_2decimals;
                 $remainder = round($yousave_pct_temp - $yousave_pct_2decimals, 4);
                 //v1.0.7.4  PHP floating point error fix - limit to 4 places right of the decimal!!
                 if ($remainder > 0.005) {
                     //v1.0.7.4 begin
                     $increment = round($remainder, 2);
                     //round the rounding error to 2 decimal points!  floating point
                     if ($increment < 0.01) {
                         $increment = 0.01;
                     }
                     ////v1.0.7.4 end
                     $yousave_pct = ($yousave_pct_2decimals + $increment) * 100;
                     //v1.0.7.4  PHP floating point
                 } else {
                     $yousave_pct = $yousave_pct_2decimals * 100;
                 }
             }
             break;
     }
     //Test yousave for product across All Rules applied to the Product
     $yousave_product_total_amt = $vtprd_cart->cart_items[$k]->yousave_total_amt + $curr_prod_array['prod_discount_amt'];
     $yousave_product_total_qty = $vtprd_cart->cart_items[$k]->yousave_total_qty + 1;
     //  yousave_total_unit_price is a rolling full total of unit price already
     $yousave_total_unit_price = $vtprd_cart->cart_items[$k]->yousave_total_unit_price + $curr_prod_array['prod_unit_price'];
     //yousave pct whole number = (total discount amount / (orig unit price * number of units discounted))
     $yousave_pct_prod_temp = $yousave_product_total_amt / $yousave_total_unit_price;
     //$yousave_pct_prod_2decimals = bcdiv($yousave_product_total_amt , $yousave_total_unit_price , 2);
     $yousave_pct_prod_2decimals = round($yousave_product_total_amt / $yousave_total_unit_price, 2);
     //$remainder = $yousave_pct_prod_temp - $yousave_pct_prod_2decimals;
     $remainder = round($yousave_pct_prod_temp - $yousave_pct_prod_2decimals, 4);
     //v1.0.7.4  PHP floating point error fix - limit to 4 places right of the decimal!!
     if ($remainder > 0.005) {
         //v1.0.7.4 begin
         $increment = round($remainder, 2);
         //round the rounding error to 2 decimal points!  floating point
         if ($increment < 0.01) {
             $increment = 0.01;
         }
         ////v1.0.7.4 end
         $yousave_product_total_pct = ($yousave_pct_prod_2decimals + $increment) * 100;
         //v1.0.7.4  PHP floating point
     } else {
         $yousave_product_total_pct = $yousave_pct_prod_2decimals * 100;
     }
     $refigure_yousave_product_totals = 'no';
     //if amts have been massaged, recheck vs discount_floor_percentage
     if ($max_msg > ' ') {
         if ($vtprd_setup_options['discount_floor_pct_per_single_item'] > 0) {
             if ($yousave_product_total_pct > $vtprd_setup_options['discount_floor_pct_per_single_item']) {
                 //reduce discount amount to max allowed by max floor discount percentage
                 //    compute the allowed remainder percentage
                 // % = floor minus product % totaled *before now*
                 $yousave_pct = $vtprd_setup_options['discount_floor_pct_per_single_item'] - $vtprd_cart->cart_items[$k]->yousave_total_pct;
                 $percent_off = $yousave_pct / 100;
                 //compute rounding
                 //$discount_2decimals = bcmul($curr_prod_array['prod_unit_price'] , $percent_off , 2);
                 $discount_2decimals = round($curr_prod_array['prod_unit_price'] * $percent_off, 2);
                 //v1.0.7.6
                 $temp_discount = $curr_prod_array['prod_unit_price'] * $percent_off;
                 //$rounding = $temp_discount - $discount_2decimals;
                 $rounding = round($temp_discount - $discount_2decimals, 4);
                 //v1.0.7.4  PHP floating point error fix - limit to 4 places right of the decimal!!
                 if ($rounding > 0.005) {
                     //v1.0.7.4 begin
                     $increment = round($rounding, 2);
                     //round the rounding error to 2 decimal points!  floating point
                     if ($increment < 0.01) {
                         $increment = 0.01;
                     }
                     ////v1.0.7.4 end
                     $curr_prod_array['prod_discount_amt'] = $discount_2decimals + $increment;
                     //v1.0.7.4  PHP floating point
                 } else {
                     $curr_prod_array['prod_discount_amt'] = $discount_2decimals;
                 }
                 $refigure_yousave_product_totals = 'yes';
                 //$curr_prod_array['prod_discount_amt']  = ($yousave_pct / 100) * $curr_prod_array['prod_unit_price'];
             }
         }
     }
     //adjust yousave_amt and yousave_pct as needed based on limits
     switch ($vtprd_rules_set[$i]->rule_deal_info[0]['discount_rule_cum_max_amt_type']) {
         //var on the 1st iteration only
         case 'none':
             $do_nothing;
             break;
         case 'percent':
             if ($yousave_product_total_pct > $vtprd_rules_set[$i]->rule_deal_info[0]['discount_rule_cum_max_amt_count']) {
                 // % = floor minus rule % totaled *before now*
                 $yousave_pct = $vtprd_rules_set[$i]->rule_deal_info[0]['discount_rule_max_amt_count'] - $vtprd_cart->cart_items[$k]->yousave_total_pct;
                 //*********************************************************************
                 //reduce discount amount to max allowed by rule percentage
                 //*********************************************************************
                 //$discount_2decimals = bcmul(($yousave_pct / 100) , $curr_prod_array['prod_unit_price'] , 2);
                 $discount_2decimals = round($yousave_pct / 100 * $curr_prod_array['prod_unit_price'], 2);
                 //v1.0.7.6
                 //compute rounding
                 $temp_discount = $yousave_pct / 100 * $curr_prod_array['prod_unit_price'];
                 //$rounding = $temp_discount - $discount_2decimals;
                 $rounding = round($temp_discount - $discount_2decimals, 4);
                 //v1.0.7.4  PHP floating point error fix - limit to 4 places right of the decimal!!
                 if ($rounding > 0.005) {
                     //v1.0.7.4 begin
                     $increment = round($rounding, 2);
                     //round the rounding error to 2 decimal points!  floating point
                     if ($increment < 0.01) {
                         $increment = 0.01;
                     }
                     ////v1.0.7.4 end
                     $discount = $discount_2decimals + $increment;
                     //v1.0.7.4  PHP floating point
                 } else {
                     $discount = $discount_2decimals;
                 }
             }
             break;
         case 'quantity':
             if ($yousave_product_total_qty > $vtprd_rules_set[$i]->rule_deal_info[0]['discount_rule_cum_max_amt_count']) {
                 //we've reached the max allowed by this rule, as we only process 1 at a time, exit
                 $vtprd_cart->cart_items[$k]->cartAuditTrail[$vtprd_rules_set[$i]->post_id]['discount_msgs'][] = 'No Discount - Discount Rule Max Qty already reached, discount skipped';
                 return;
             }
             break;
         case 'currency':
             if ($yousave_product_total_amt > $vtprd_rules_set[$i]->rule_deal_info[0]['discount_rule_cum_max_amt_count']) {
                 //reduce discount to max...
                 $reduction_amt = $yousave_product_total_amt - $vtprd_rules_set[$i]->rule_deal_info[0]['discount_rule_cum_max_amt_count'];
                 $curr_prod_array['prod_discount_amt'] = $curr_prod_array['prod_discount_amt'] - $reduction_amt;
                 //v1.0.9.3 begin
                 if ($curr_prod_array['prod_discount_amt'] > $curr_prod_array['prod_unit_price']) {
                     $curr_prod_array['prod_discount_amt'] = $curr_prod_array['prod_unit_price'];
                 }
                 //v1.0.9.3 end
                 $max_msg = $vtprd_rules_set[$i]->discount_rule_cum_max_amt_msg;
                 $yousave_pct_temp = $curr_prod_array['prod_discount_amt'] / $curr_prod_array['prod_unit_price'];
                 // $yousave_pct = $yousave_amt / $curr_prod_array['prod_unit_price'] * 100;
                 //compute remainder
                 //$yousave_pct_2decimals = bcdiv($curr_prod_array['prod_discount_amt'] , $curr_prod_array['prod_unit_price'] , 2);
                 $yousave_pct_2decimals = round($curr_prod_array['prod_discount_amt'] / $curr_prod_array['prod_unit_price'], 2);
                 //$remainder = $yousave_pct_temp - $yousave_pct_2decimals;
                 $remainder = round($yousave_pct_temp - $yousave_pct_2decimals, 4);
                 //v1.0.7.4  PHP floating point error fix - limit to 4 places right of the decimal!!
                 if ($remainder > 0.005) {
                     //v1.0.7.4 begin
                     $increment = round($remainder, 2);
                     //round the rounding error to 2 decimal points!  floating point
                     if ($increment < 0.01) {
                         $increment = 0.01;
                     }
                     ////v1.0.7.4 end
                     $yousave_pct = ($yousave_pct_2decimals + $increment) * 100;
                     //v1.0.7.4  PHP floating point
                 } else {
                     $yousave_pct = $yousave_pct_2decimals * 100;
                 }
                 $refigure_yousave_product_totals = 'yes';
             }
             break;
     }
     //*************************************
     // PURCHASE HISTORY LIFETIME LIMIT
     //*************************************
     //adjust yousave_amt and yousave_pct as needed based on limits
     switch ($vtprd_rules_set[$i]->rule_deal_info[0]['discount_lifetime_max_amt_type']) {
         //var on the 1st iteration only
         case 'none':
             break;
         case 'quantity':
             //v1.0.4 begin => lifetime counted by group done elsewhere
             if ($vtprd_rules_set[$i]->rule_deal_info[$d]['discount_applies_to'] == 'all') {
                 break;
             }
             //v1.0.4 end
             //if ( ($yousave_product_total_qty +  <= instead of this, we're actually counting home many times the RULE was used, not the total qty it was applied to...
             if (1 + $vtprd_rules_set[$i]->purch_hist_rule_row_qty_total_plus_discounts > $vtprd_rules_set[$i]->rule_deal_info[0]['discount_lifetime_max_amt_count']) {
                 //we've reached the max allowed by this rule, as we only process 1 at a time, exit
                 $vtprd_cart->cart_items[$k]->cartAuditTrail[$vtprd_rules_set[$i]->post_id]['discount_msgs'][] = 'No Discount - Discount Rule Lifetime Max Qty already reached, discount skipped.  Prev purch hist= ' . $vtprd_rules_set[$i]->purch_hist_rule_row_qty_total_plus_discounts;
                 return;
             }
             break;
         case 'currency':
             if ($yousave_product_total_amt + $vtprd_rules_set[$i]->purch_hist_rule_row_price_total_plus_discounts > $vtprd_rules_set[$i]->rule_deal_info[0]['discount_lifetime_max_amt_count']) {
                 //Only store error msg at checkout validation time
                 if ($vtprd_info['checkout_validation_in_process'] == 'yes') {
                     //REMOVE any line breaks, etc, which would cause a JS error !!
                     $tempMsg = str_replace(array("\r\n", "\r", "\n", "\t"), ' ', $vtprd_setup_options['lifetime_purchase_button_error_msg']);
                     $vtprd_cart->error_messages[] = $tempMsg;
                 }
                 //reduce discount to max...
                 $reduction_amt = $yousave_product_total_amt + $vtprd_rules_set[$i]->purch_hist_rule_row_price_total_plus_discounts - $vtprd_rules_set[$i]->rule_deal_info[0]['discount_lifetime_max_amt_count'];
                 $curr_prod_array['prod_discount_amt'] = $curr_prod_array['prod_discount_amt'] - $reduction_amt;
                 //v1.0.9.3 begin
                 if ($curr_prod_array['prod_discount_amt'] > $curr_prod_array['prod_unit_price']) {
                     $curr_prod_array['prod_discount_amt'] = $curr_prod_array['prod_unit_price'];
                 }
                 //v1.0.9.3 end
                 $max_msg = $vtprd_rules_set[$i]->discount_lifetime_max_amt_msg;
                 $yousave_pct_temp = $curr_prod_array['prod_discount_amt'] / $curr_prod_array['prod_unit_price'];
                 // $yousave_pct = $yousave_amt / $curr_prod_array['prod_unit_price'] * 100;
                 //compute remainder
                 //$yousave_pct_2decimals = bcdiv($curr_prod_array['prod_discount_amt'] , $curr_prod_array['prod_unit_price'] , 2);
                 $yousave_pct_2decimals = round($curr_prod_array['prod_discount_amt'] / $curr_prod_array['prod_unit_price'], 2);
                 //$remainder = $yousave_pct_temp - $yousave_pct_2decimals;
                 $remainder = round($yousave_pct_temp - $yousave_pct_2decimals, 4);
                 //v1.0.7.4  PHP floating point error fix - limit to 4 places right of the decimal!!
                 if ($remainder > 0.005) {
                     //v1.0.7.4 begin
                     $increment = round($remainder, 2);
                     //round the rounding error to 2 decimal points!  floating point
                     if ($increment < 0.01) {
                         $increment = 0.01;
                     }
                     ////v1.0.7.4 end
                     $yousave_pct = ($yousave_pct_2decimals + $increment) * 100;
                     //v1.0.7.4  PHP floating point
                 } else {
                     $yousave_pct = $yousave_pct_2decimals * 100;
                 }
                 $refigure_yousave_product_totals = 'yes';
             }
             break;
     }
     //EXIT if Sale Price already lower than Discount
     if ($vtprd_cart->cart_items[$k]->product_is_on_special == 'yes' && $vtprd_rules_set[$i]->cumulativeSalePricing == 'replaceSalePrice') {
         //Replacement of Sale Price is requested, but only happens if Discount is GREATER THAN sale price
         $discounted_price = $curr_prod_array['prod_unit_price'] - $curr_prod_array['prod_discount_amt'];
         if ($vtprd_cart->cart_items[$k]->db_unit_price_special < $discounted_price) {
             $vtprd_cart->cart_items[$k]->unit_price = $vtprd_cart->cart_items[$k]->db_unit_price_special;
             $vtprd_cart->cart_items[$k]->db_unit_price = $vtprd_cart->cart_items[$k]->db_unit_price_special;
             $vtprd_cart->cart_items[$k]->cartAuditTrail[$vtprd_rules_set[$i]->post_id]['discount_status'] = 'rejected';
             $vtprd_cart->cart_items[$k]->cartAuditTrail[$vtprd_rules_set[$i]->post_id]['discount_msgs'][] = 'No Discount - Sale Price Less than Discounted price';
             return;
         }
     }
     //*********************************************************************
     //eND MAX LIMITS CHECKING
     //*********************************************************************
     //*************************************
     // Add Discount Totals into the Array
     //*************************************
     if ($yousave_for_this_rule_id_already_exists == 'yes') {
         $vtprd_cart->cart_items[$k]->yousave_by_rule_info[$rule_id]['yousave_amt'] += $curr_prod_array['prod_discount_amt'];
         //cumulative percentage
         $vtprd_cart->cart_items[$k]->yousave_by_rule_info[$rule_id]['discount_applies_to_qty']++;
         $vtprd_cart->cart_items[$k]->yousave_by_rule_info[$rule_id]['rule_max_amt_msg'] = $max_msg;
     } else {
         $vtprd_cart->cart_items[$k]->yousave_by_rule_info[$rule_id] = array('ruleset_occurrence' => $i, 'discount_amt_type' => '', 'discount_amt_count' => 0, 'discount_for_the_price_of_count' => '', 'discount_applies_to_qty' => 1, 'yousave_amt' => $curr_prod_array['prod_discount_amt'], 'yousave_pct' => $yousave_pct, 'rule_max_amt_msg' => $max_msg, 'rule_execution_type' => $vtprd_rules_set[$i]->rule_execution_type, 'rule_short_msg' => $vtprd_rules_set[$i]->discount_product_short_msg, 'rule_full_msg' => $vtprd_rules_set[$i]->discount_product_full_msg);
         //******************************************
         //for later ajaxVariations pricing    - BEGIN
         //******************************************
         if ($vtprd_rules_set[$i]->rule_deal_info[$d]['discount_amt_type'] == 'percent') {
             $pricing_rule_percent_discount = $yousave_pct;
             $pricing_rule_currency_discount = 0;
         } else {
             $pricing_rule_percent_discount = 0;
             $pricing_rule_currency_discount = $vtprd_rules_set[$i]->rule_deal_info[$d]['discount_amt_count'];
         }
         $vtprd_cart->cart_items[$k]->pricing_by_rule_array[] = array('pricing_rule_id' => $rule_id, 'pricing_rule_applies_to_variations_array' => $vtprd_rules_set[$i]->var_in_checked, 'pricing_rule_percent_discount' => $pricing_rule_percent_discount, 'pricing_rule_currency_discount' => $pricing_rule_currency_discount);
         //  ajaxVariations pricing - END
     }
     //recompute the discount totals for use in next iteration
     $vtprd_rules_set[$i]->discount_total_qty_for_rule = $vtprd_rules_set[$i]->discount_total_qty_for_rule + 1;
     $vtprd_rules_set[$i]->discount_total_amt_for_rule = $vtprd_rules_set[$i]->discount_total_amt_for_rule + $curr_prod_array['prod_discount_amt'];
     //$discount_total_unit_price_for_rule will be the unit qty * db_unit_price already, as this routine is done 1 by 1...
     $vtprd_rules_set[$i]->discount_total_unit_price_for_rule = $vtprd_rules_set[$i]->discount_total_unit_price_for_rule + $curr_prod_array['prod_db_unit_price'];
     //yousave pct whole number  = total discount amount / (orig unit price * number of units discounted)
     $vtprd_rules_set[$i]->discount_total_pct_for_rule = $discount_total_amt_for_rule / $discount_total_unit_price_for_rule * 100;
     //REFIGURE the product totals, if there was a reduction above...
     if ($refigure_yousave_product_totals == 'yes') {
         $yousave_product_total_amt = $vtprd_cart->cart_items[$k]->yousave_total_amt + $curr_prod_array['prod_discount_amt'];
         $yousave_product_total_qty = $vtprd_cart->cart_items[$k]->yousave_total_qty + 1;
         //  yousave_total_unit_price is a rolling full total of unit price already
         $yousave_total_unit_price = $vtprd_cart->cart_items[$k]->yousave_total_unit_price + $curr_prod_array['prod_unit_price'];
         //yousave pct whole number = (total discount amount / (orig unit price * number of units discounted))
         $yousave_pct_prod_temp = $yousave_product_total_amt / $yousave_total_unit_price;
         //$yousave_pct_prod_2decimals = bcdiv($yousave_product_total_amt , $yousave_total_unit_price , 2);
         $yousave_pct_prod_2decimals = round($yousave_product_total_amt / $yousave_total_unit_price, 2);
         //$remainder = $yousave_pct_prod_temp - $yousave_pct_prod_2decimals;
         $remainder = round($yousave_pct_prod_temp - $yousave_pct_prod_2decimals, 4);
         //v1.0.7.4  PHP floating point error fix - limit to 4 places right of the decimal!!
         if ($remainder > 0.005) {
             //v1.0.7.4 begin
             $increment = round($remainder, 2);
             //round the rounding error to 2 decimal points!  floating point
             if ($increment < 0.01) {
                 $increment = 0.01;
             }
             //v1.0.7.4 end
             $yousave_product_total_pct = ($yousave_pct_prod_2decimals + $increment) * 100;
             //v1.0.7.4   floating point
         } else {
             $yousave_product_total_pct = $yousave_pct_prod_2decimals * 100;
         }
     }
     $vtprd_cart->cart_items[$k]->yousave_total_amt = $yousave_product_total_amt;
     $vtprd_cart->cart_items[$k]->yousave_total_qty = $yousave_product_total_qty;
     $vtprd_cart->cart_items[$k]->yousave_total_pct = $yousave_product_total_pct;
     $vtprd_cart->cart_items[$k]->yousave_total_unit_price = $yousave_total_unit_price;
     //keep track of historical discount totals
     //instead of $yousave_product_total_qty;, we're actually counting home many times the RULE was used, not the total qty it was applied to...
     //v1.0.4 begin => lifetime counted by group (= 'all') added only after group processing for rule is complete
     if ($vtprd_rules_set[$i]->rule_deal_info[$d]['discount_applies_to'] != 'all') {
         $vtprd_rules_set[$i]->purch_hist_rule_row_qty_total_plus_discounts += 1;
         // +1 for each RULE OCCURRENCE usage...
     }
     //v1.0.4 end
     $vtprd_rules_set[$i]->purch_hist_rule_row_price_total_plus_discounts += $curr_prod_array['prod_discount_amt'];
     //used in lifetime limits
     $vtprd_rules_set[$i]->actionPop_rule_yousave_amt += $curr_prod_array['prod_discount_amt'];
     $vtprd_rules_set[$i]->actionPop_rule_yousave_qty += 1;
     //$yousave_product_total_qty;  not qty, but iterations of USAGE!
     //$vtprd_cart->cart_items[$k]->discount_price    = ($vtprd_cart->cart_items[$k]->db_unit_price * $vtprd_cart->cart_items[$k]->quantity) - $yousave_product_total_amt ;
     $vtprd_cart->cart_items[$k]->discount_price = $curr_prod_array['prod_unit_price'] * $vtprd_cart->cart_items[$k]->quantity - $yousave_product_total_amt;
     //v1.1.1 begin
     if ($vtprd_cart->cart_items[$k]->discount_price > 0) {
         $vtprd_cart->cart_items[$k]->discount_unit_price = round($vtprd_cart->cart_items[$k]->discount_price / $vtprd_cart->cart_items[$k]->quantity, 2);
     } else {
         $vtprd_cart->cart_items[$k]->discount_unit_price = '';
     }
     //v1.1.1 end
     $vtprd_rules_set[$i]->discount_applied == 'yes';
     $vtprd_cart->cart_items[$k]->cartAuditTrail[$vtprd_rules_set[$i]->post_id]['discount_status'] = 'applied';
     $vtprd_cart->cart_items[$k]->cartAuditTrail[$vtprd_rules_set[$i]->post_id]['discount_msgs'][] = __('Discount Applied', 'vtprd');
     $vtprd_cart->cart_items[$k]->cartAuditTrail[$vtprd_rules_set[$i]->post_id]['discount_amt'] = $curr_prod_array['prod_discount_amt'];
     $vtprd_cart->cart_items[$k]->cartAuditTrail[$vtprd_rules_set[$i]->post_id]['discount_pct'] = $yousave_pct;
     //                         *******************
     //if discount has applied, update rule totals after recalc to pick up most current total price info
     //                         *******************
     //add in total saved to yousave_total_amt for PRODUCT
     if ($curr_prod_array['prod_discount_amt'] > 0) {
         //v1.0.5.3 begin
         //  the vtprd_cart unit price and discounts all reflect the TAX STATE of 'woocommerce_prices_include_tax'
         global $woocommerce;
         $product_id = $vtprd_cart->cart_items[$k]->product_id;
         switch (true) {
             case get_option('woocommerce_calc_taxes') == 'no':
             case $woocommerce->customer->is_vat_exempt():
                 $prod_discount_amt_excl_tax = $curr_prod_array['prod_discount_amt'];
                 $prod_discount_amt_incl_tax = $curr_prod_array['prod_discount_amt'];
                 break;
             case get_option('woocommerce_prices_include_tax') == 'yes':
                 $prod_discount_amt_excl_tax = vtprd_get_price_excluding_tax($product_id, $curr_prod_array['prod_discount_amt']);
                 $prod_discount_amt_incl_tax = $curr_prod_array['prod_discount_amt'];
                 break;
             case get_option('woocommerce_prices_include_tax') == 'no':
                 $prod_discount_amt_excl_tax = $curr_prod_array['prod_discount_amt'];
                 $prod_discount_amt_incl_tax = vtprd_get_price_including_tax($product_id, $curr_prod_array['prod_discount_amt']);
                 break;
         }
         //THIS is where the cart SAVE TOTALS are stored!!
         $vtprd_cart->yousave_cart_total_amt_excl_tax += $prod_discount_amt_excl_tax;
         $vtprd_cart->yousave_cart_total_amt_incl_tax += $prod_discount_amt_incl_tax;
         //v1.0.5.3 end
         $vtprd_rules_set[$i]->discount_total_qty += 1;
         $vtprd_rules_set[$i]->discount_total_amt += $curr_prod_array['prod_discount_amt'];
         $vtprd_cart->yousave_cart_total_qty += 1;
         $vtprd_cart->yousave_cart_total_amt += $curr_prod_array['prod_discount_amt'];
     }
     //mark exploded list product as already processed for this rule
     $vtprd_rules_set[$i]->actionPop_exploded_found_list[$occurrence]['prod_discount_applied'] = 'yes';
     //**********************************************
     //  if this product is free, add the product qty to the tracking bucket
     //**********************************************
     if ($curr_prod_array['prod_discount_amt'] == $vtprd_cart->cart_items[$k]->unit_price) {
         $key = $vtprd_cart->cart_items[$k]->product_id;
         if (isset($vtprd_rules_set[$i]->free_product_array[$key])) {
             $vtprd_rules_set[$i]->free_product_array[$key]++;
         } else {
             $vtprd_rules_set[$i]->free_product_array[$key] = 1;
         }
     }
     //********************
     //v1.1.1.2 begin - reworked for multiple free
     //v1.1.0.6 begin
     //  SINGLE UNIT - mark free candidate as free, increment/decrement counters
     $current_auto_add_array = $this->vtprd_get_current_auto_add_array();
     $free_product_id = $vtprd_cart->cart_items[$k]->product_id;
     //v1.1.1.2
     //    if ( ($vtprd_rules_set[$i]->rule_contains_auto_add_free_product == 'yes') &&
     //         ($vtprd_cart->cart_items[$k]->product_auto_insert_state == 'candidate') ) {
     if ($vtprd_rules_set[$i]->rule_contains_auto_add_free_product == 'yes' && $vtprd_cart->cart_items[$k]->product_auto_insert_rule_id == $vtprd_rules_set[$i]->post_id && isset($current_auto_add_array[$free_product_id])) {
         $vtprd_cart->cart_items[$k]->product_auto_insert_state = 'free';
         $current_auto_add_array[$free_product_id]['free_qty']++;
         $current_auto_add_array[$free_product_id]['candidate_qty']--;
         $current_auto_add_array[$free_product_id]['current_qty'] = $current_auto_add_array[$free_product_id]['purchased_qty'] + $current_auto_add_array[$free_product_id]['free_qty'];
         //v1.1.1.2
         //error_log( print_r(  '$current_auto_add_array at ADD TO FREE_QTY time = ', true ) );
         //error_log( var_export($current_auto_add_array, true ) );
         $_SESSION['current_auto_add_array'] = serialize($current_auto_add_array);
     }
     //v1.1.0.6 end
     //v1.1.1.2 end
     //********************
     return;
 }