Example #1
0
 /**
  * Adjusts the price from get_price for the selected attributes
  * @author Nathan Hyde <*****@*****.**>
  * @author curlyroger from his post at <http://www.phpshop.org/phpbb/viewtopic.php?t=3052>
  *
  * @param int $product_id
  * @param string $description
  * @return array The adjusted price information
  */
 function get_adjusted_attribute_price($product_id, $description = '')
 {
     global $mosConfig_secret;
     $auth = $_SESSION['auth'];
     $price = $this->get_price($product_id);
     $base_price = $price["product_price"];
     $setprice = 0;
     $set_price = false;
     $adjustment = 0;
     // We must care for custom attribute fields! Their value can be freely given
     // by the customer, so we mustn't include them into the price calculation
     // Thanks to AryGroup@ua.fm for the good advice
     if (empty($_REQUEST["custom_attribute_fields"])) {
         if (!empty($_SESSION["custom_attribute_fields"])) {
             $custom_attribute_fields = vmGet($_SESSION, "custom_attribute_fields", array());
             $custom_attribute_fields_check = vmGet($_SESSION, "custom_attribute_fields_check", array());
         } else {
             $custom_attribute_fields = $custom_attribute_fields_check = array();
         }
     } else {
         $custom_attribute_fields = $_SESSION["custom_attribute_fields"] = vmGet($_REQUEST, "custom_attribute_fields", array());
         $custom_attribute_fields_check = $_SESSION["custom_attribute_fields_check"] = vmGet($_REQUEST, "custom_attribute_fields_check", array());
     }
     // if we've been given a description to deal with, get the adjusted price
     if ($description != '') {
         // description is safe to use at this point cause it's set to ''
         require_once CLASSPATH . 'ps_product_attribute.php';
         $product_attributes = ps_product_attribute::getAdvancedAttributes($product_id, true);
         $attribute_keys = explode(";", $description);
         for ($i = 0; $i < sizeof($attribute_keys); $i++) {
             $temp_desc = $attribute_keys[$i];
             $temp_desc = trim($temp_desc);
             // Get the key name (e.g. "Color" )
             $this_key = substr($temp_desc, 0, strpos($temp_desc, ":"));
             $this_value = substr($temp_desc, strpos($temp_desc, ":") + 1);
             if (in_array($this_key, $custom_attribute_fields)) {
                 if (@$custom_attribute_fields_check[$this_key] == md5($mosConfig_secret . $this_key)) {
                     // the passed value is valid, don't use it for calculating prices
                     continue;
                 }
             }
             if (isset($product_attributes[$this_key]['values'][$this_value])) {
                 $modifier = $product_attributes[$this_key]['values'][$this_value]['adjustment'];
                 $operand = $product_attributes[$this_key]['values'][$this_value]['operand'];
                 // if we have a number, allow the adjustment
                 if (true == is_numeric($modifier)) {
                     // Now add or sub the modifier on
                     if ($operand == "+") {
                         $adjustment += $modifier;
                     } else {
                         if ($operand == "-") {
                             $adjustment -= $modifier;
                         } else {
                             if ($operand == '=') {
                                 // NOTE: the +=, so if we have 2 sets they get added
                                 // this could be moded to say, if we have a set_price, then
                                 // calc the diff from the base price and start from there if we encounter
                                 // another set price... just a thought.
                                 $setprice += $modifier;
                                 $set_price = true;
                             }
                         }
                     }
                 }
             } else {
                 continue;
             }
         }
     }
     // no set price was set from the attribs
     if ($set_price == false) {
         $price["product_price"] = $base_price + $adjustment * (1 - $auth["shopper_group_discount"] / 100);
     } else {
         // otherwise, set the price
         // add the base price to the price set in the attributes
         // then subtract the adjustment amount
         // we could also just add the set_price to the adjustment... not sure on that one.
         if (!empty($adjustment)) {
             $setprice += $adjustment;
         }
         $setprice *= 1 - $auth["shopper_group_discount"] / 100;
         $price["product_price"] = $setprice;
     }
     // don't let negative prices get by, set to 0
     if ($price["product_price"] < 0) {
         $price["product_price"] = 0;
     }
     // Get the DISCOUNT AMOUNT
     $discount_info = $this->get_discount($product_id);
     $my_taxrate = $this->get_product_taxrate($product_id);
     // If discounts are applied after tax, but prices are shown without tax,
     // AND tax is EU mode and shopper is not in the EU,
     // then ps_product::get_product_taxrate() returns 0, so $my_taxrate = 0.
     // But, the discount still needs to be reduced by the shopper's tax rate, so we obtain it here:
     if (PAYMENT_DISCOUNT_BEFORE != '1' && $auth["show_price_including_tax"] != 1 && !ps_checkout::tax_based_on_vendor_address()) {
         $db = new ps_DB();
         $ps_vendor_id = $_SESSION["ps_vendor_id"];
         require_once CLASSPATH . 'ps_checkout.php';
         if (!ps_checkout::tax_based_on_vendor_address()) {
             if ($auth["user_id"] > 0) {
                 $q = "SELECT state, country FROM #__{vm}_user_info WHERE user_id='" . $auth["user_id"] . "'";
                 $db->query($q);
                 $db->next_record();
                 $state = $db->f("state");
                 $country = $db->f("country");
                 $q = "SELECT tax_rate FROM #__{vm}_tax_rate WHERE tax_country='{$country}' ";
                 if (!empty($state)) {
                     $q .= "AND (tax_state='{$state}' OR tax_state=' {$state} ' OR tax_state='-')";
                 }
                 $db->query($q);
                 if ($db->next_record()) {
                     $my_taxrate = $db->f("tax_rate");
                 } else {
                     $my_taxrate = 0;
                 }
             } else {
                 $my_taxrate = 0;
             }
         } else {
             if (empty($_SESSION['taxrate'][$ps_vendor_id])) {
                 // let's get the store's tax rate
                 $q = "SELECT `tax_rate` FROM #__{vm}_vendor, #__{vm}_tax_rate ";
                 $q .= "WHERE tax_country=vendor_country AND #__{vm}_vendor.vendor_id=1 ";
                 // !! Important !! take the highest available tax rate for the store's country
                 $q .= "ORDER BY `tax_rate` DESC";
                 $db->query($q);
                 if ($db->next_record()) {
                     $my_taxrate = $db->f("tax_rate");
                 } else {
                     $my_taxrate = 0;
                 }
             }
         }
     }
     // Apply the discount
     if (!empty($discount_info["amount"])) {
         $undiscounted_price = $base_price;
         switch ($discount_info["is_percent"]) {
             case 0:
                 if (PAYMENT_DISCOUNT_BEFORE == '1') {
                     // If we subtract discounts BEFORE tax
                     // Subtract the whole discount
                     $price["product_price"] -= $discount_info["amount"];
                 } else {
                     // But, if we subtract discounts AFTER tax
                     // Subtract the untaxed portion of the discount
                     $price["product_price"] -= $discount_info["amount"] / ($my_taxrate + 1);
                 }
                 break;
             case 1:
                 $price["product_price"] -= $price["product_price"] * ($discount_info["amount"] / 100);
                 break;
         }
     }
     return $price;
 }
Example #2
0
 /**
  * Calculate the tax charges for the current order.
  * You can switch the way, taxes are calculated:
  * either based on the VENDOR address,
  * or based on the ship-to address.
  * ! Creates the global $order_tax_details
  *
  * @param float $order_taxable
  * @param array $d
  * @return float
  */
 function calc_order_tax($order_taxable, $d)
 {
     global $order_tax_details, $discount_factor;
     $total = 0;
     $order_tax = 0;
     $auth = $_SESSION['auth'];
     $ps_vendor_id = $_SESSION["ps_vendor_id"];
     $db = new ps_DB();
     $ship_to_info_id = vmGet($_REQUEST, 'ship_to_info_id');
     require_once CLASSPATH . 'ps_tax.php';
     $ps_tax = new ps_tax();
     $discount_factor = 1;
     // Shipping address based TAX
     if (!ps_checkout::tax_based_on_vendor_address()) {
         $q = "SELECT state, country FROM #__{vm}_user_info ";
         $q .= "WHERE user_info_id='" . $ship_to_info_id . "'";
         $db->query($q);
         $db->next_record();
         $state = $db->f("state");
         $country = $db->f("country");
         $q = "SELECT * FROM #__{vm}_tax_rate WHERE tax_country='{$country}' ";
         if (!empty($state)) {
             $q .= "AND (tax_state='{$state}' OR tax_state=' {$state} ')";
         }
         $db->query($q);
         if ($db->next_record()) {
             $rate = $order_taxable * floatval($db->f("tax_rate"));
             if (empty($rate)) {
                 $order_tax = 0.0;
             } else {
                 $cart = $_SESSION['cart'];
                 $order_tax = 0.0;
                 if ((!empty($_SESSION['coupon_discount']) || !empty($d['payment_discount'])) && PAYMENT_DISCOUNT_BEFORE == '1') {
                     require_once CLASSPATH . 'ps_product.php';
                     $ps_product = new ps_product();
                     for ($i = 0; $i < $cart["idx"]; $i++) {
                         $item_weight = ps_shipping_method::get_weight($cart[$i]["product_id"]) * $cart[$i]['quantity'];
                         if ($item_weight != 0 or TAX_VIRTUAL) {
                             $price = $ps_product->get_adjusted_attribute_price($cart[$i]["product_id"], $cart[$i]["description"]);
                             $price['product_price'] = $GLOBALS['CURRENCY']->convert($price['product_price'], $price['product_currency']);
                             $tax_rate = $db->f("tax_rate");
                             $use_coupon_discount = @$_SESSION['coupon_discount'];
                             //if( !empty( $_SESSION['coupon_discount'] )) {
                             //    if( $auth["show_price_including_tax"] == 1 ) {
                             //        $use_coupon_discount = $_SESSION['coupon_discount'] / ($tax_rate+1);
                             //    }
                             //}
                             $factor = 100 * ($use_coupon_discount + @$d['payment_discount']) / $this->_subtotal;
                             $price["product_price"] = $price["product_price"] - $factor * $price["product_price"] / 100;
                             @($order_tax_details[$tax_rate] += $price["product_price"] * $tax_rate * $cart[$i]["quantity"]);
                             $order_tax += $price["product_price"] * $tax_rate * $cart[$i]["quantity"];
                             $total += $price["product_price"] * $cart[$i]["quantity"];
                         } else {
                             $order_tax += 0.0;
                         }
                     }
                 } else {
                     $order_tax = $rate;
                 }
             }
         } else {
             $order_tax = 0.0;
         }
         $order_tax_details[$db->f('tax_rate')] = $order_tax;
     } else {
         // Calculate the Tax with a tax rate for every product
         $cart = $_SESSION['cart'];
         $order_tax = 0.0;
         $total = 0.0;
         if ((!empty($_SESSION['coupon_discount']) || !empty($d['payment_discount'])) && PAYMENT_DISCOUNT_BEFORE == '1') {
             // We need to recalculate the tax details when the discounts are applied
             // BEFORE taxes - because they affect the product subtotals then
             $order_tax_details = array();
         }
         require_once CLASSPATH . 'ps_product.php';
         $ps_product = new ps_product();
         require_once CLASSPATH . 'ps_shipping_method.php';
         for ($i = 0; $i < $cart["idx"]; $i++) {
             $item_weight = ps_shipping_method::get_weight($cart[$i]["product_id"]) * $cart[$i]['quantity'];
             if ($item_weight != 0 or TAX_VIRTUAL) {
                 $price = $ps_product->get_adjusted_attribute_price($cart[$i]["product_id"], $cart[$i]["description"]);
                 $price['product_price'] = $GLOBALS['CURRENCY']->convert($price['product_price'], $price['product_currency']);
                 $tax_rate = $ps_product->get_product_taxrate($cart[$i]["product_id"]);
                 if ((!empty($_SESSION['coupon_discount']) || !empty($d['payment_discount'])) && PAYMENT_DISCOUNT_BEFORE == '1') {
                     $use_coupon_discount = @$_SESSION['coupon_discount'];
                     if (!empty($_SESSION['coupon_discount'])) {
                         if ($auth["show_price_including_tax"] == 1) {
                             $use_coupon_discount = $_SESSION['coupon_discount'] / ($tax_rate + 1);
                         }
                     }
                     $factor = 100 * ($use_coupon_discount + @$d['payment_discount']) / $this->_subtotal;
                     $price["product_price"] = $price["product_price"] - $factor * $price["product_price"] / 100;
                     @($order_tax_details[$tax_rate] += $price["product_price"] * $tax_rate * $cart[$i]["quantity"]);
                 }
                 $order_tax += $price["product_price"] * $tax_rate * $cart[$i]["quantity"];
                 $total += $price["product_price"] * $cart[$i]["quantity"];
             }
         }
         if ((!empty($_SESSION['coupon_discount']) || !empty($d['payment_discount'])) && PAYMENT_DISCOUNT_BEFORE != '1') {
             // Here we need to re-calculate the Discount
             // because we assume the Discount is "including Tax"
             $discounted_total = @$d['order_subtotal_withtax'] - @$_SESSION['coupon_discount'] - @$d['payment_discount'];
             if ($discounted_total != @$d['order_subtotal_withtax'] && @$d['order_subtotal_withtax'] > 0.0) {
                 $discount_factor = $discounted_total / $d['order_subtotal_withtax'];
                 foreach ($order_tax_details as $rate => $value) {
                     $order_tax_details[$rate] = $value * $discount_factor;
                 }
             }
         }
         if (is_object($this->_SHIPPING)) {
             $taxrate = $this->_SHIPPING->get_tax_rate();
             if ($taxrate) {
                 $rate = $this->_SHIPPING->get_rate($d);
                 if ($auth["show_price_including_tax"] == 1) {
                     @($order_tax_details[$taxrate] += $rate - $rate / ($taxrate + 1));
                 } else {
                     @($order_tax_details[$taxrate] += $rate * $taxrate);
                 }
             }
         }
     }
     return round($order_tax, 2);
 }
Example #3
0
 //}
 // SHOW TAX
 $tax_display = '';
 // mauri start
 if (empty($_REQUEST['ship_to_info_id']) && $auth["user_id"] > 0 && !ps_checkout::tax_based_on_vendor_address()) {
     $db = new ps_DB();
     $q = "SELECT user_info_id FROM #__{vm}_user_info ";
     $q .= "WHERE user_id = '" . $auth["user_id"] . "' ";
     $q .= "AND address_type = 'BT' ";
     $db->query($q);
     $db->next_record();
     $_REQUEST['ship_to_info_id'] = $db->f("user_info_id");
     ps_checkout::tax_based_on_vendor_address($_REQUEST['ship_to_info_id']);
 }
 // mauri end
 if (!empty($_REQUEST['ship_to_info_id']) || ps_checkout::tax_based_on_vendor_address()) {
     $show_tax = true;
     if ($weight_total != 0 or TAX_VIRTUAL == '1') {
         $order_taxable = $ps_checkout->calc_order_taxable($vars);
         $tax_total = $ps_checkout->calc_order_tax($order_taxable, $vars);
     } else {
         $tax_total = 0;
     }
     if ($auth['show_price_including_tax']) {
         $tax_total *= $discount_factor;
     }
     $tax_total += $shipping_tax;
     $tax_total = round($tax_total, 5);
     $tax_display = $GLOBALS['CURRENCY_DISPLAY']->getFullValue($tax_total);
     $tax_display .= ps_checkout::show_tax_details($order_tax_details);
 }