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; }
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; }