예제 #1
0
 /**
  * Marked as deprecated but should not throw any "deprecated" message
  * This function is used in order to keep front office backward compatibility 14 -> 1.5
  * (Order History)
  *
  * @param $row
  */
 public function setProductPrices($row)
 {
     $tax_calculator = JeproshopOrderDetailModelOrderDetail::getStaticTaxCalculator((int) $row->order_detail_id);
     $row->tax_calculator = $tax_calculator;
     $row->tax_rate = $tax_calculator->getTotalRate();
     $row->product_price = JeproshopTools::roundPrice($row->unit_price_tax_excl, 2);
     $row->product_price_with_tax = JeproshopTools::roundPrice($row->unit_price_tax_incl, 2);
     $group_reduction = 1;
     if ($row->group_reduction > 0) {
         $group_reduction = 1 - $row->group_reduction / 100;
     }
     $row->product_price_with_tax_but_ecotax = $row->product_price_with_tax - $row->ecotax;
     $row->total_with_tax = $row->total_price_tax_incl;
     $row->total_price = $row->total_price_tax_excl;
 }
예제 #2
0
파일: view.php 프로젝트: jeprodev/jeproshop
            }
            ?>
											</td>
											<?php 
        }
        if ($this->stock_management) {
            ?>
<td class="productQuantity product_stock center"><?php 
            echo $product->current_stock;
            ?>
</td><?php 
        }
        ?>
											<td class="total_product">
												<?php 
        echo JeproshopTools::displayPrice(JeproshopTools::roundPrice($product_price, 2) * ($product->product_quantity - $product->customizationQuantityTotal), $this->currency->currency_id);
        ?>
											</td>
											<td colspan="2" style="display: none;" class="add_product_fields">&nbsp;</td>
											<td class="cancelCheck standard_refund_fields current-edit" style="display:none">
												<input type="hidden" name="jform[total_quantity_return]" id="jform_total_quantity_return" value="<?php 
        echo $product->product_quantity_return;
        ?>
" />
												<input type="hidden" name="jform[total_quantity]" id="jform_total_quantity" value="<?php 
        echo $product->product_quantity;
        ?>
" />
												<input type="hidden" name="jform[product_name]" id="jform_product_name" value="<?php 
        echo $product->product_name;
        ?>
예제 #3
0
파일: cart.php 프로젝트: jeprodev/jeproshop
    /**
     * Return cart products
     *
     * @result array Products
     * @param bool $refresh
     * @param bool $product_id
     * @param null $country_id
     * @return array|null
     */
    public function getProducts($refresh = false, $product_id = false, $country_id = null)
    {
        if (!$this->cart_id) {
            return array();
        }
        // Product cache must be strictly compared to NULL, or else an empty cart will add dozens of queries
        if ($this->_products !== null && !$refresh) {
            // Return product row with specified ID if it exists
            if (is_int($product_id)) {
                foreach ($this->_products as $product) {
                    if ($product->product_id == $product_id) {
                        return array($product);
                    }
                }
                return array();
            }
            return $this->_products;
        }
        $db = JFactory::getDBO();
        $select = $leftJoin = "";
        if (JeproshopCustomization::isFeaturePublished()) {
            $select .= 'cu.`id_customization`, cu.`quantity` AS customization_quantity';
            $leftJoin .= " LEFT JOIN " . $db->quoteName('#__jeproshop_customization') . " AS customization ";
            /*
                            'p.`id_product` = cu.`id_product` AND cart_product.`id_product_attribute` = cu.`id_product_attribute` AND cu.`id_cart` = '.(int)$this->id); */
        } else {
            $select .= 'NULL AS customization_quantity, NULL AS id_customization';
        }
        if (JeproshopCombinationModelCombination::isFeaturePublished()) {
            $select .= '
				product_attribute_shop.`price` AS price_attribute, product_attribute_shop.`ecotax` AS ecotax_attr,
				IF (IFNULL(pa.`reference`, \'\') = \'\', p.`reference`, pa.`reference`) AS reference,
				(p.`weight`+ pa.`weight`) weight_attribute,
				IF (IFNULL(pa.`ean13`, \'\') = \'\', p.`ean13`, pa.`ean13`) AS ean13,
				IF (IFNULL(pa.`upc`, \'\') = \'\', p.`upc`, pa.`upc`) AS upc,
				pai.`id_image` as pai_id_image, il.`legend` as pai_legend,
				IFNULL(product_attribute_shop.`minimal_quantity`, product_shop.`minimal_quantity`) as minimal_quantity
			';
            /*$sql->leftJoin('product_attribute', 'pa', 'pa.`id_product_attribute` = cart_product.`id_product_attribute`');
              $sql->leftJoin('product_attribute_shop', 'product_attribute_shop', '(product_attribute_shop.`id_shop` = cart_product.`id_shop` AND product_attribute_shop.`id_product_attribute` = pa.`id_product_attribute`)');
              $sql->leftJoin('product_attribute_image', 'pai', 'pai.`id_product_attribute` = pa.`id_product_attribute`');
              $sql->leftJoin('image_lang', 'il', 'il.`id_image` = pai.`id_image` AND il.`id_lang` = '.(int)$this->id_lang); */
        } else {
            $select .= 'p.`reference` AS reference, p.`ean13`,
				p.`upc` AS upc, product_shop.`minimal_quantity` AS minimal_quantity';
        }
        $query = "SELECT cart_product." . $db->quoteName('product_attribute_id') . ", cart_product." . $db->quoteName('product_id') . ", cart_product.";
        $query .= $db->quoteName('quantity') . " AS cart_quantity, cart_product." . $db->quoteName('shop_id') . ", product_lang." . $db->quoteName('name');
        $query .= ", product." . $db->quoteName('is_virtual') . ", product_lang." . $db->quoteName('short_description') . ", product_lang." . $db->quoteName('available_now');
        $query .= ", product_lang." . $db->quoteName('available_later') . ", product_shop." . $db->quoteName('default_category_id') . ", product.";
        $query .= $db->quoteName('supplier_id') . ", product." . $db->quoteName('manufacturer_id') . ", product_shop." . $db->quoteName('on_sale') . ", product_shop.";
        $query .= $db->quoteName('ecotax') . ", product_shop." . $db->quoteName('additional_shipping_cost') . ", product_shop." . $db->quoteName('available_for_order');
        $query .= ", product_shop." . $db->quoteName('price') . ", product_shop." . $db->quoteName('published') . ", product_shop." . $db->quoteName('unity');
        $query .= ", product_shop." . $db->quoteName('unit_price_ratio') . ", stock." . $db->quoteName('quantity') . " AS quantity_available, product." . $db->quoteName('width');
        $query .= ", product." . $db->quoteName('height') . ", product." . $db->quoteName('depth') . ", stock." . $db->quoteName('out_of_stock') . ", product.";
        $query .= $db->quoteName('weight') . ", product." . $db->quoteName('date_add') . ", product." . $db->quoteName('date_upd') . ", IFNULL(stock.quantity, 0) as quantity, ";
        $query .= "product_lang." . $db->quoteName('link_rewrite') . ", category_lang." . $db->quoteName('link_rewrite') . " AS category, CONCAT(LPAD(cart_product.";
        $query .= $db->quoteName('product_id') . ", 10, 0), LPAD(IFNULL(cart_product." . $db->quoteName('product_attribute_id') . ", 0), 10, 0), IFNULL(cart_product.";
        $query .= $db->quoteName('address_delivery_id') . ", 0)) AS unique_id, cart_product.address_delivery_id, product_shop." . $db->quoteName('wholesale_price');
        $query .= ", product_shop.advanced_stock_management, product_supplier.product_supplier_reference supplier_reference, IFNULL(specific_price." . $db->quoteName('reduction_type');
        $query .= ", 0) AS reduction_type FROM " . $db->quoteName('#__jeproshop_cart_product') . " AS cart_product LEFT JOIN " . $db->quoteName('#__jeproshop_product') . " AS product ";
        $query .= " ON (product." . $db->quoteName('product_id') . " = cart_product." . $db->quoteName('product_id') . ") INNER JOIN " . $db->quoteName('#__jeproshop_product_shop');
        $query .= " AS product_shop ON (product_shop." . $db->quoteName('shop_id') . " = cart_product." . $db->quoteName('shop_id') . " AND product_shop." . $db->quoteName('product_id');
        $query .= " = product." . $db->quoteName('product_id') . ") LEFT JOIN " . $db->quoteName('#__jeproshop_product_lang') . " AS product_lang ON (product." . $db->quoteName('product_id');
        $query .= " = product_lang." . $db->quoteName('product_id') . "\tAND product_lang." . $db->quoteName('lang_id') . " = " . (int) $this->lang_id;
        $query .= JeproshopShopModelShop::addSqlRestrictionOnLang('product_lang', 'cart_product.shop_id') . ") LEFT JOIN " . $db->quoteName('#__jeproshop_category_lang');
        $query .= " AS category_lang ON(product_shop." . $db->quoteName('default_category_id') . " = category_lang." . $db->quoteName('category_id') . " AND category_lang." . $db->quoteName('lang_id');
        $query .= " = " . (int) $this->lang_id . JeproshopShopModelShop::addSqlRestrictionOnLang('category_lang', 'cart_product.shop_id') . ") LEFT JOIN " . $db->quoteName('#__jeproshop_product_supplier');
        $query .= " AS product_supplier ON (product_supplier." . $db->quoteName('product_id') . " = cart_product." . $db->quoteName('product_id') . " AND product_supplier.";
        $query .= $db->quoteName('product_attribute_id') . " = cart_product." . $db->quoteName('product_attribute_id') . " AND product_supplier." . $db->quoteName('supplier_id');
        $query .= " = product." . $db->quoteName('supplier_id') . ") LEFT JOIN " . $db->quoteName('#__jeproshop_specific_price') . " AS specific_price ON (specific_price.";
        $query .= $db->quoteName('product_id') . " = cart_product." . $db->quoteName('product_id') . ") " . JeproshopProductModelProduct::sqlStock('cart_product');
        // AND 'sp.`id_shop` = cart_product.`id_shop`
        // @todo test if everything is ok, then refactorise call of this method
        //$sql->join(Product::sqlStock('cart_product', 'cart_product'));
        $query .= " WHERE cart_product." . $db->quoteName('cart_id') . " = " . (int) $this->cart_id;
        if ($product_id) {
            $query .= " AND cart_product." . $db->quoteName('product_id') . " = " . (int) $product_id;
        }
        $query .= " AND product." . $db->quoteName('product_id') . " IS NOT NULL GROUP BY unique_id ORDER BY cart_product." . $db->quoteName('date_add');
        $query .= ", product." . $db->quoteName('product_id') . ", cart_product." . $db->quoteName('product_attribute_id') . " ASC";
        $db->setQuery($query);
        $result = $db->loadObjectList();
        // Reset the cache before the following return, or else an empty cart will add dozens of queries
        $products_ids = array();
        $product_attribute_ids = array();
        if ($result) {
            foreach ($result as $row) {
                $products_ids[] = $row->product_id;
                $product_attribute_ids[] = $row->product_attribute_id;
            }
        }
        // Thus you can avoid one query per product, because there will be only one query for all the products of the cart
        JeproshopProductModelProduct::cacheProductsFeatures($products_ids);
        JeproshopCartModelCart::cacheSomeAttributesLists($product_attribute_ids, $this->lang_id);
        $this->_products = array();
        if (empty($result)) {
            return array();
        }
        $cart_shop_context = JeproshopContext::getContext()->cloneContext();
        foreach ($result as &$row) {
            if (isset($row->ecotax_attr) && $row->ecotax_attr > 0) {
                $row->ecotax = (double) $row->ecotax_attr;
            }
            $row->stock_quantity = (int) $row->quantity;
            // for compatibility with 1.2 themes
            $row->quantity = (int) $row->cart_quantity;
            if (isset($row->product_attribute_id) && (int) $row->product_attribute_id && isset($row->weight_attribute)) {
                $row->weight = (double) $row->weight_attribute;
            }
            if (JeproshopSettingModelSetting::getValue('tax_address_type') == 'address_invoice_id') {
                $address_id = (int) $this->address_invoice_id;
            } else {
                $address_id = (int) $row->address_delivery_id;
            }
            if (!JeproshopAddressModelAddress::addressExists($address_id)) {
                $address_id = null;
            }
            if ($cart_shop_context->shop->shop_id != $row->shop_id) {
                $cart_shop_context->shop = new JeproshopShopModelShop((int) $row->shop_id);
            }
            $specific_price_output = null;
            $null = null;
            if ($this->_taxCalculationMethod == COM_JEPROSHOP_TAX_EXCLUDED) {
                $row->price = JeproshopProductModelProduct::getStaticPrice((int) $row->product_id, false, isset($row->product_attribute_id) ? (int) $row->product_attribute_id : null, 2, null, false, true, (int) $row->cart_quantity, false, (int) $this->customer_id ? (int) $this->customer_id : null, (int) $this->cart_id, (int) $address_id ? (int) $address_id : null, $specific_price_output, true, true, $cart_shop_context);
                // Here taxes are computed only once the quantity has been applied to the product price
                $row->price_wt = JeproshopProductModelProduct::getStaticPrice((int) $row->product_id, true, isset($row->product_attribute_id) ? (int) $row->product_attribute_id : null, 2, null, false, true, (int) $row->cart_quantity, false, (int) $this->customer_id ? (int) $this->customer_id : null, (int) $this->cart_id, (int) $address_id ? (int) $address_id : null, $null, true, true, $cart_shop_context);
                $tax_rate = JeproshopTaxModelTax::getProductTaxRate((int) $row->product_id, (int) $address_id);
                $row->total_wt = JeproshopTools::roundPrice($row->price * (double) $row->cart_quantity * (1 + (double) $tax_rate / 100), 2);
                $row->total = $row->price * (int) $row->cart_quantity;
            } else {
                $row->price = JeproshopProductModelProduct::getStaticPrice((int) $row->product_id, false, (int) $row->product_attribute_id, 2, null, false, true, $row->cart_quantity, false, (int) $this->customer_id ? (int) $this->customer_id : null, (int) $this->cart_id, (int) $address_id ? (int) $address_id : null, $specific_price_output, true, true, $cart_shop_context);
                $row->price_wt = JeproshopProductModelProduct::getStaticPrice((int) $row->product_id, true, (int) $row->product_attribute_id, 2, null, false, true, $row->cart_quantity, false, (int) $this->customer_id ? (int) $this->customer_id : null, (int) $this->cart_id, (int) $address_id ? (int) $address_id : null, $null, true, true, $cart_shop_context);
                // In case when you use QuantityDiscount, getPriceStatic() can be return more of 2 decimals
                $row->price_wt = JeproshopTools::roundPrice($row->price_wt, 2);
                $row->total_wt = $row->price_wt * (int) $row->cart_quantity;
                $row->total = JeproshopTools::roundPrice($row->price * (int) $row->cart_quantity, 2);
                $row->description_short = JeproshopTools::nl2br($row->short_description);
            }
            if (!isset($row->product_attribute_id_image_id) || $row->product_attribute_id_image_id == 0) {
                $cache_id = 'jeproshop_cart_get_products_product_attribute_id_image_id_' . (int) $row->product_id . '_' . (int) $this->lang_id . '_' . (int) $row->shop_id;
                if (!JeproshopCache::isStored($cache_id)) {
                    $db = JFactory::getDBO();
                    $query = "SELECT image_shop." . $db->quoteName('image_id') . " AS image_id, image_lang." . $db->quoteName('legend') . " FROM ";
                    $query .= $db->quoteName('#__jeproshop_image') . " AS image JOIN " . $db->quoteName('#__jeproshop_image_shop') . " AS image_shop ON (";
                    $query .= " image.image_id = image_shop.image_id AND image_shop.cover=1 AND image_shop.shop_id = " . (int) $row->shop_id . ") LEFT JOIN ";
                    $query .= $db->quoteName('#__jeproshop_image_lang') . " AS image_lang ON (image_shop." . $db->quoteName('image_id') . " = image_lang.";
                    $query .= $db->quoteName('image_id') . " AND image_lang." . $db->quoteName('lang_id') . " = " . (int) $this->lang_id . ") WHERE image.";
                    $query .= $db->quoteName('product_id') . " = " . (int) $row->product_id . " AND image_shop." . $db->quoteName('cover') . " = 1";
                    $db->setQuery($query);
                    $row2 = $db->loadObject();
                    JeproshopCache::store($cache_id, $row2);
                }
                $row2 = JeproshopCache::retrieve($cache_id);
                if (!$row2) {
                    $row2 = new JObject();
                    $row2->image_id = false;
                    $row2->legend = false;
                } else {
                    $row = array_merge($row, $row2);
                }
            } else {
                $row->image_id = $row->product_attribute_id_image_id;
                $row->legend = $row->product_attribute_legend;
            }
            $row->reduction_applies = $specific_price_output && (double) $specific_price_output->reduction;
            $row->quantity_discount_applies = $specific_price_output && $row->cart_quantity >= (int) $specific_price_output->from_quantity;
            $row->image_id = JeproshopProductModelProduct::defineProductImage($row, $this->lang_id);
            $row->allow_out_of_sp = JeproshopProductModelProduct::isAvailableWhenOutOfStock($row->out_of_stock);
            $row->features = JeproshopProductModelProduct::getStaticFeatures((int) $row->product_id);
            if (array_key_exists($row->product_attribute_id . '_' . $this->lang_id, self::$_attributesLists)) {
                $row = array_merge($row, self::$_attributesLists[$row->product_attribute_id . '_' . $this->lang_id]);
            }
            $row = JeproshopProductModelProduct::getTaxesInformations($row, $cart_shop_context);
            $this->_products[] = $row;
        }
        return $this->_products;
    }
예제 #4
0
 /**
  * Return price with currency sign for a given product
  *
  * @param float $price Product price
  * @param object|array $currency Current currency (object, id_currency, NULL => context currency)
  * @return string Price correctly formatted (sign, decimal separator...)
  */
 public static function displayPrice($price, $currency = null, $no_utf8 = false, JeproshopContext $context = null)
 {
     if (!is_numeric($price)) {
         return $price;
     }
     if (!$context) {
         $context = JeproshopContext::getContext();
     }
     if ($currency === null) {
         $currency = $context->currency;
     } elseif (is_int($currency)) {
         // if you modified this function, don't forget to modify the Javascript function formatCurrency (in Tools.js)
         $currency = JeproshopCurrencyModelCurrency::getCurrencyInstance((int) $currency);
     }
     if (is_object($currency)) {
         $c_char = $currency->sign;
         $c_format = $currency->format;
         $c_decimals = (int) $currency->decimals * COM_JEPROSHOP_PRICE_DISPLAY_PRECISION;
         $c_blank = $currency->blank;
     } else {
         return false;
     }
     $blank = $c_blank ? ' ' : '';
     $ret = 0;
     if ($is_negative = $price < 0) {
         $price *= -1;
     }
     $price = JeproshopTools::roundPrice($price, $c_decimals);
     /*
      * If the language is RTL and the selected currency format contains spaces as thousands separator
      * then the number will be printed in reverse since the space is interpreted as separating words.
      * To avoid this we replace the currency format containing a space with the one containing a comma (,) as thousand
      * separator when the language is RTL.
      *
      * TODO: This is not ideal, a currency format should probably be tied to a language, not to a currency.
      */
     if ($c_format == 2 && $context->language->is_rtl == 1) {
         $c_format = 4;
     }
     switch ($c_format) {
         /* X 0,000.00 */
         case 1:
             $ret = $c_char . $blank . number_format($price, $c_decimals, '.', ',');
             break;
             /* 0 000,00 X*/
         /* 0 000,00 X*/
         case 2:
             $ret = number_format($price, $c_decimals, ',', ' ') . $blank . $c_char;
             break;
             /* X 0.000,00 */
         /* X 0.000,00 */
         case 3:
             $ret = $c_char . $blank . number_format($price, $c_decimals, ',', '.');
             break;
             /* 0,000.00 X */
         /* 0,000.00 X */
         case 4:
             $ret = number_format($price, $c_decimals, '.', ',') . $blank . $c_char;
             break;
             /* X 0'000.00  Added for the switzerland currency */
         /* X 0'000.00  Added for the switzerland currency */
         case 5:
             $ret = $c_char . $blank . number_format($price, $c_decimals, '.', "'");
             break;
     }
     if ($is_negative) {
         $ret = '-' . $ret;
     }
     if ($no_utf8) {
         return str_replace('�', chr(128), $ret);
     }
     return $ret;
 }
예제 #5
0
 public static function getProductProperties($lang_id, $row, JeproshopContext $context = null)
 {
     if (!$row->product_id) {
         return false;
     }
     if ($context == null) {
         $context = JeproshopContext::getContext();
     }
     // Product::getDefaultAttribute is only called if id_product_attribute is missing from the SQL query at the origin of it:
     // consider adding it in order to avoid unnecessary queries
     $row->allow_out_of_stock_ordering = JeproshopProductModelProduct::isAvailableWhenOutOfStock($row->out_of_stock);
     if (JeproshopCombinationModelCombination::isFeaturePublished() && (!isset($row->product_attribute_id) || !$row->product_attribute_id) && (isset($row->cache_default_attribute) && ($default_product_attribute_id = $row->cache_default_attribute) !== null || ($default_product_attribute_id = JeproshopProductModelProduct::getDefaultAttribute($row->product_id, !$row->allow_out_of_stock_ordering)))) {
         $row->product_attribute_id = $default_product_attribute_id;
     }
     if (!JeproshopCombinationModelCombination::isFeaturePublished() || !isset($row->product_attribute_id)) {
         $row->product_attribute_id = 0;
     }
     // Tax
     $useTax = JeproshopTaxModelTax::taxExcludedOption();
     $cache_key = $row->product_id . '_' . $row->product_attribute_id . '_' . $lang_id . '_' . (int) $useTax;
     if (isset($row->product_pack_id)) {
         $cache_key .= '_pack_' . $row->product_pack_id;
     }
     if (isset(self::$_productPropertiesCache[$cache_key])) {
         return JeproshopTools::updateObjectData($row, self::$_productPropertiesCache[$cache_key]);
     }
     // Datas
     $row->category = JeproshopCategoryModelCategory::getLinkRewrite((int) $row->default_category_id, (int) $lang_id);
     $row->link = $context->controller->getProductLink((int) $row->product_id, $row->link_rewrite, $row->category, $row->ean13);
     $row->attribute_price = 0;
     if (isset($row->product_attribute_id) && $row->product_attribute_id) {
         $row->attribute_price = (double) JeproshopProductModelProduct::getProductAttributePrice($row->product_attribute_id);
     }
     $row->price_tax_exc = JeproshopProductModelProduct::getStaticPrice((int) $row->product_id, false, isset($row->product_attribute_id) && !empty($row->product_attribute_id) ? (int) $row->product_attribute_id : null, self::$_taxCalculationMethod == COM_JEPROSHOP_TAX_EXCLUDED ? 2 : 6);
     if (self::$_taxCalculationMethod == COM_JEPROSHOP_TAX_EXCLUDED) {
         $row->price_tax_exc = JeproshopTools::roundPrice($row->price_tax_exc, 2);
         $row->price = JeproshopProductModelProduct::getStaticPrice((int) $row->product_id, true, isset($row->product_attribute_id) && !empty($row->product_attribute_id) ? (int) $row->product_attribute_id : null, 6);
         $row->price_without_reduction = JeproshopProductModelProduct::getStaticPrice((int) $row->product_id, false, isset($row->product_attribute_id) && !empty($row->product_attribute_id) ? (int) $row->product_attribute_id : null, 2, null, false, false);
     } else {
         $row->price = JeproshopTools::roundPrice(JeproshopProductModelProduct::getStaticPrice((int) $row->product_id, true, isset($row->product_attribute_id) && !empty($row->product_attribute_id) ? (int) $row->product_attribute_id : null, 2), 2);
         $row->price_without_reduction = JeproshopProductModelProduct::getStaticPrice((int) $row->product_id, true, isset($row->product_attribute_id) && !empty($row->product_attribute_id) ? (int) $row->product_attribute_id : null, 6, null, false, false);
     }
     $specific_prices = null;
     $row->reduction = JeproshopProductModelProduct::getStaticPrice((int) $row->product_id, (bool) $useTax, (int) $row->product_attribute_id, 6, null, true, true, 1, true, null, null, null, $specific_prices);
     $row->specific_prices = $specific_prices;
     $row->quantity = JeproshopProductModelProduct::getQuantity((int) $row->product_id, 0, isset($row->cache_is_pack) ? $row->cache_is_pack : null);
     $row->quantity_all_versions = $row->quantity;
     if ($row->product_attribute_id) {
         $row->quantity = JeproshopProductModelProduct::getQuantity((int) $row->product_id, $row->product_attribute_id, isset($row->cache_is_pack) ? $row->cache_is_pack : null);
     }
     $row->image_id = JeproshopProductModelProduct::defineProductImage($row, $lang_id);
     $row->features = JeproshopProductModelProduct::getFrontStaticFeatures((int) $lang_id, $row->product_id);
     $row->attachments = array();
     if (!isset($row->cache_has_attachments) || $row->cache_has_attachments) {
         $row->attachments = JeproshopProductModelProduct::getStaticAttachments((int) $lang_id, $row->product_id);
     }
     $row->virtual = !isset($row->is_virtual) || $row->is_virtual ? 1 : 0;
     // Pack management
     $row->pack = !isset($row->cache_is_pack) ? JeproshopProductPack::isPack($row->product_id) : (int) $row->cache_is_pack;
     $row->packItems = $row->pack ? JeproshopProductPack::getItemTable($row->product_id, $lang_id) : array();
     $row->no_pack_price = $row->pack ? JeproshopProductPack::noPackPrice($row->product_id) : 0;
     if ($row->pack && !JeproshopProductPack::isInStock($row->product_id)) {
         $row->quantity = 0;
     }
     $row->customization_required = false;
     if (isset($row->customizable) && $row->customizable && JeproshopCustomization::isFeaturePublished()) {
         if (count(JeproshopProductModelProduct::getStaticRequiredCustomizableFields((int) $row->product_id))) {
             $row->customization_required = true;
         }
     }
     $row = JeproshopProductModelProduct::getTaxesInformations($row, $context);
     self::$_productPropertiesCache[$cache_key] = $row;
     return self::$_productPropertiesCache[$cache_key];
 }
예제 #6
0
 /**
  * Assign price and tax to the template
  */
 protected function assignPriceAndTax()
 {
     $customer_id = isset($this->context->customer) ? (int) $this->context->customer->customer_id : 0;
     $group_id = (int) JeproshopGroupModelGroup::getCurrent()->group_id;
     $country_id = (int) $customer_id ? JeproshopCustomerModelCustomer::getCurrentCountry($customer_id) : JeproshopSettingModelSetting::getValue('default_country');
     $group_reduction = JeproshopGroupReductionModelGroupReduction::getValueForProduct($this->product->product_id, $group_id);
     if ($group_reduction === false) {
         $group_reduction = JeproshopGroupModelGroup::getReduction((int) $this->context->cookie->customer_id) / 100;
     }
     // Tax
     $tax = (double) $this->product->getTaxesRate(new JeproshopAddressModelAddress((int) $this->context->cart->{JeproshopSettingModelSetting::getValue('tax_address_type')}));
     $this->assignRef('tax_rate', $tax);
     $product_price_with_tax = JeproshopProductModelProduct::getStaticPrice($this->product->product_id, true, null, 6);
     if (JeproshopProductModelProduct::$_taxCalculationMethod == COM_JEPROSHOP_TAX_INCLUDED) {
         $product_price_with_tax = JeproshopTools::roundPrice($product_price_with_tax, 2);
     }
     $product_price_without_eco_tax = (double) $product_price_with_tax - $this->product->ecotax;
     $ecotax_rate = (double) JeproshopTaxModelTax::getProductEcotaxRate($this->context->cart->{JeproshopSettingModelSetting::getValue('tax_address_type')});
     $ecotax_tax_amount = JeproshopTools::roundPrice($this->product->ecotax, 2);
     if (JeproshopProductModelProduct::$_taxCalculationMethod == COM_JEPROSHOP_TAX_INCLUDED && (int) JeproshopSettingModelSetting::getValue('use_tax')) {
         $ecotax_tax_amount = JeproshopTools::roundPrice($ecotax_tax_amount * (1 + $ecotax_rate / 100), 2);
     }
     $currency_id = (int) $this->context->cookie->currency_id;
     $product_id = (int) $this->product->product_id;
     $shop_id = $this->context->shop->shop_id;
     $quantity_discounts = JeproshopSpecificPriceModelSpecificPrice::getQuantityDiscounts($product_id, $shop_id, $currency_id, $country_id, $group_id, null, true, (int) $this->context->customer->customer_id);
     foreach ($quantity_discounts as &$quantity_discount) {
         if ($quantity_discount->product_attribute_id) {
             $combination = new JeproshopCombinationModelCombination((int) $quantity_discount->product_attribute_id);
             $attributes = $combination->getAttributesName((int) $this->context->language->lang_id);
             foreach ($attributes as $attribute) {
                 $quantity_discount->attributes = $attribute->name . ' - ';
             }
             $quantity_discount->attributes = rtrim($quantity_discount->attributes, ' - ');
         }
         if ((int) $quantity_discount->currency_id == 0 && $quantity_discount->reduction_type == 'amount') {
             $quantity_discount->reduction = JeproshopTools::convertPriceFull($quantity_discount->reduction, null, JeproshopContext::getContext()->currency);
         }
     }
     $product_price = $this->product->getPrice(JeproshopProductModelProduct::$_taxCalculationMethod == COM_JEPROSHOP_TAX_INCLUDED, false);
     $address = new JeproshopAddressModelAddress($this->context->cart->{JeproshopSettingModelSetting::getValue('tax_address_type')});
     $quantity_discounts = $this->formatQuantityDiscounts($quantity_discounts, $product_price, (double) $tax, $ecotax_tax_amount);
     $this->assignRef('quantity_discounts', $quantity_discounts);
     $this->assignRef('ecotax_tax_included', $ecotax_tax_amount);
     $ecotax_tax_excluded = JeproshopTools::roundPrice($this->product->ecotax, 2);
     $this->assignRef('ecotax_tax_excluded', $ecotax_tax_excluded);
     $this->assignRef('ecotaxTax_rate', $ecotax_rate);
     $display_price = JeproshopSettingModelSetting::getValue('display_price');
     $this->assignRef('display_price', $display_price);
     $product_price_without_eco_tax = (double) $product_price_without_eco_tax;
     $this->assignRef('product_price_without_ecotax', $product_price_without_eco_tax);
     $this->assignRef('group_reduction', $group_reduction);
     $no_tax = JeproshopTaxModelTax::taxExcludedOption() || !$this->product->getTaxesRate($address);
     $this->assignRef('no_tax', $no_tax);
     $ecotax = !count($this->errors) && $this->product->ecotax > 0 ? JeproshopTools::convertPrice((double) $this->product->ecotax) : 0;
     $this->assignRef('ecotax', $ecotax);
     $tax_enabled = JeproshopSettingModelSetting::getValue('use_tax');
     $this->assignRef('tax_enabled', $tax_enabled);
     $customer_group_without_tax = JeproshopGroupModelGroup::getPriceDisplayMethod($this->context->customer->default_group_id);
     $this->assignRef('customer_group_without_tax', $customer_group_without_tax);
 }
예제 #7
0
								<th class="nowrap" ><span class="pull-right"><?php 
        echo JText::_('COM_JEPROSHOP_UNIT_PRICE_CURRENCY_LABEL');
        ?>
</span></th>
							</tr>
						</thead>
						<tbody>
							<?php 
        foreach ($this->attributes as $index => $attribute) {
            $reference = '';
            $price_te = '';
            $currency_id = $this->default_currency_id;
            foreach ($this->associated_suppliers_collection as $asc) {
                if ($asc->product_id == $attribute->product_id && $asc->product_attribute_id == $attribute->product_attribute_id && $asc->supplier_id == $supplier->supplier_id) {
                    $reference = $asc->product_supplier_reference;
                    $price_te = JeproshopTools::roundPrice($asc->product_supplier_price_te, 2);
                    if ($asc->currency_id) {
                        $currency_id = $asc->currency_id;
                    }
                }
            }
            ?>
							<tr class="row_<?php 
            echo $index % 2;
            ?>
" >
								<td><?php 
            echo $this->product_designation[$attribute->product_attribute_id];
            ?>
</td>
								<td>
예제 #8
0
    private function displaySpecificPriceModificationForm($default_currency, $shops, $currencies, $countries, $groups)
    {
        $content = '';
        if (!$this->product) {
            return null;
        }
        $specificPrices = JeproshopSpecificPriceModelSpecificPrice::getSpecificPricesByProductId((int) $this->product->product_id);
        $specificPricePriorities = JeproshopSpecificPriceModelSpecificPrice::getPriority((int) $this->product->product_id);
        $app = JFactory::getApplication();
        $taxRate = $this->product->getTaxesRate(JeproshopAddressModelAddress::initialize());
        $tmp = array();
        foreach ($shops as $shop) {
            $tmp[$shop->shop_id] = $shop;
        }
        $shops = $tmp;
        $tmp = array();
        foreach ($currencies as $currency) {
            $tmp[$currency->currency_id] = $currency;
        }
        $currencies = $tmp;
        $tmp = array();
        foreach ($countries as $country) {
            $tmp[$country->country_id] = $country;
        }
        $countries = $tmp;
        $tmp = array();
        foreach ($groups as $group) {
            $tmp[$group->group_id] = $group;
        }
        $groups = $tmp;
        $content .= '<table class="table table-striped" ><thead><tr><th>' . JText::_('COM_JEPROSHOP_RULES_LABEL');
        $content .= '</th><th>' . JText::_('COM_JEPROSHOP_COMBINATION_LABEL') . '</th>';
        $multi_shop = JeproshopShopModelShop::isFeaturePublished();
        if ($multi_shop) {
            $content .= '<th>' . JText::_('COM_JEPROSHOP_SHOP_LABEL') . '</th>';
        }
        $content .= '<th>' . JText::_('COM_JEPROSHOP_CURRENCY_LABEL') . '</th><th>';
        $content .= JText::_('COM_JEPROSHOP_COUNTRY_LABEL') . '</th><th>' . JText::_('COM_JEPROSHOP_GROUP_LABEL');
        $content .= '</th><th>' . JText::_('COM_JEPROSHOP_CUSTOMER_LABEL') . '</th><th>';
        $content .= JText::_('COM_JEPROSHOP_FIXED_PRICE_LABEL') . '</th><th>' . JText::_('COM_JEPROSHOP_IMPACT_LABEL');
        $content .= '</th><th>' . JText::_('COM_JEPROSHOP_PERIOD_LABEL') . '</th><th>' . JText::_('COM_JEPROSHOP_FROM_LABEL');
        $content .= '</th><th>' . JText::_('COM_JEPROSHOP_ACTIONS_LABEL') . '</th></tr></thead><tbody>';
        if (!is_array($specificPrices) || !count($specificPrices)) {
            $content .= '<tr><td class="text-center" colspan="13" ><i class="icon-warning-sign"></i>&nbsp;';
            $content .= JText::_('COM_JEPROSHOP_NO_SPECIFIC_PRICES_MESSAGE') . '</td></tr>';
        } else {
            $i = 0;
            foreach ($specificPrices as $specificPrice) {
                $currentSpecificCurrency = $currencies[$specificPrice->currency_id ? $specificPrice->currency_id : $default_currency->currency_id];
                if ($specificPrice->reduction_type == 'percentage') {
                    $impact = '- ' . $specificPrice->reduction * 100 . ' %';
                } elseif ($specificPrice->reduction > 0) {
                    $impact = '- ' . JeproshopTools::displayPrice(Tools::ps_round($specificPrice->reduction, 2), $currentSpecificCurrency);
                } else {
                    $impact = '--';
                }
                if ($specificPrice->from == '0000-00-00 00:00:00' && $specificPrice->to == '0000-00-00 00:00:00') {
                    $period = JText::_('COM_JEPROSHOP_UNLIMITED_LABEL');
                } else {
                    $period = JText::_('COM_JEPROSHOP_FROM_LABEL') . ' ' . ($specificPrice->from != '0000-00-00 00:00:00' ? $specificPrice['from'] : '0000-00-00 00:00:00') . '<br />' . $this->l('To') . ' ' . ($specificPrice['to'] != '0000-00-00 00:00:00' ? $specificPrice['to'] : '0000-00-00 00:00:00');
                }
                if ($specificPrice->product_attribute_id) {
                    $combination = new JeproshopCombinationModelCombination((int) $specificPrice->product_attribute_id);
                    $attributes = $combination->getAttributesName((int) $this->context->language->lang_id);
                    $attributes_name = '';
                    foreach ($attributes as $attribute) {
                        $attributes_name .= $attribute->name . ' - ';
                    }
                    $attributes_name = rtrim($attributes_name, ' - ');
                } else {
                    $attributes_name = JText::_('COM_JEPROSHOP_ALL_COMBINATIONS_LABEL');
                }
                $rule = new JeproshopSpecificPriceRuleModelSpecificPriceRule((int) $specificPrice->specific_price_rule_id);
                $rule_name = $rule->specific_price_rule_id ? $rule->name : '--';
                if ($specificPrice->customer_id) {
                    $customer = new JeproshopCustomerModelCustomer((int) $specificPrice->customer_id);
                    if (JeproshopTools::isLoadedObject($customer, 'customer_id')) {
                        $customer_full_name = $customer->firstname . ' ' . $customer->lastname;
                    }
                    unset($customer);
                }
                if (!$specificPrice->shop_id || in_array($specificPrice->shop_id, JeoroshopShopModelShop::getContextListShopID())) {
                    $content .= '<tr class="row_' . ($i % 2 ? '0' : '1') . '"><td>' . $rule_name . '</td><td>' . $attributes_name . '</td>';
                    $can_delete_specific_prices = true;
                    if (JeproshopShopModelShop::isFeaturePublished()) {
                        $sp_shop_id = $specificPrice->shop_id;
                        $can_delete_specific_prices = count($this->context->employee->getAssociatedShops()) > 1 && !$sp_shop_id || $sp_shop_id;
                        $content .= '<td>' . ($sp_shop_id ? $shops[$sp_shop_id]['name'] : JText::_('COM_JEPROSHOP_ALL_SHOPS_LABEL')) . '</td>';
                    }
                    $price = JeproshopTools::roundPrice($specificPrice->price, 2);
                    $fixed_price = $price == JeproshopTools::roundPrice($this->product->price, 2) || $specificPrice->price == -1 ? '--' : JeproshopTools::displayPrice($price, $current_specific_currency);
                    $content .= '<td>' . ($specificPrice->currency_id ? $currencies[$specificPrice->currency_id]->name : JText::_('COM_JEPROSHOP_ALL_CURRENCIES_LABEL')) . '</td>';
                    $content .= '<td>' . ($specificPrice->country_id ? $countries[$specificPrice->country_id]->name : JText::_('COM_JEPROSHOP_ALL_COUNTRIES_LABEL')) . '</td>';
                    $content .= '<td>' . ($specificPrice->group_id ? $groups[$specificPrice->group_id]->name : JText::_('COM_JEPROSHOP_ALL_GROUPS_LABEL')) . '</td>';
                    $content .= '<td title="' . JText::_('COM_JEPROSHOP_ID_LABEL') . ' ' . $specificPrice->customer_id . '">' . (isset($customer_full_name) ? $customer_full_name : JText::_('COM_JEPROSHOP_ALL_CUSTOMERS_LABEL')) . '</td>';
                    $content .= '<td>' . $fixed_price . '</td><td>' . $impact . '</td><td>' . $period . '</td><td>' . $specificPrice->from_quantity . '</th>';
                    $content .= '<td>' . (!$rule->specific_price_rule_id && $can_delete_specific_prices ? '<a class="btn btn-default" name="delete_link" href="' . JRoute::_('index.php?option=com_jeproshop&view=price&product_id=' . (int) $app->input->get('product_id') . '&task=delete_specific_price&specific_price_id=' . (int) $specificPrice->specific_price_id . '&' . JSession::getFormToken() . '=1') . '"><i class="icon-trash"></i></a>' : '') . '</td>';
                    $content .= '</tr>';
                    $i++;
                    unset($customer_full_name);
                }
            }
        }
        $content .= '</tbody></table>';
        // Not use id_customer
        if ($specificPricePriorities[0] == 'customer_id') {
            unset($specificPricePriorities[0]);
        }
        // Reindex array starting from 0
        $specificPricePriorities = array_values($specificPricePriorities);
        $content .= '<div class="panel"><div class="panel-title" >' . JText::_('Priority management') . '</div><div class="panel-content well" ><div class="alert alert-info">';
        $content .= JText::_('Sometimes one customer can fit into multiple price rules. Priorities allow you to define which rule applies to the customer.') . '</div>';
        $content .= '<div class="input-group" ><select id="jform_specific_price_priority_1" name="price_field[specific_price_priority[]]" class="middle_size" ><option value="shop_id"';
        $content .= ($specificPricePriorities[0] == 'shop_id' ? ' selected="selected"' : '') . '>' . JText::_('COM_JEPROSHOP_SHOP_LABEL') . '</option><option value="currency_id"';
        $content .= ($specificPricePriorities[0] == 'currency_id' ? ' selected="selected"' : '') . '>' . JText::_('COM_JEPROSHOP_CURRENCY_LABEL') . '</option><option value="country_id"';
        $content .= ($specificPricePriorities[0] == 'country_id' ? ' selected="selected"' : '') . '>' . JText::_('COM_JEPROSHOP_COUNTRY_LABEL') . '</option><option value="group_id"';
        $content .= ($specificPricePriorities[0] == 'group_id' ? ' selected="selected"' : '') . '>' . JText::_('COM_JEPROSHOP_GROUP_LABEL') . '</option></select>&nbsp;<span class="';
        $content .= 'input-group-addon"><i class="icon-chevron-right"></i></span>&nbsp;<select name="price_field[specific_price_priority[]]" class="middle_size" ><option value="shop_id"';
        $content .= ($specificPricePriorities[1] == 'shop_id' ? ' selected="selected"' : '') . '>' . JText::_('COM_JEPROSHOP_SHOP_LABEL') . '</option><option value="currency_id"';
        $content .= ($specificPricePriorities[1] == 'currency_id' ? ' selected="selected"' : '') . '>' . JText::_('COM_JEPROSHOP_CURRENCY_LABEL') . '</option><option value="country_id"';
        $content .= ($specificPricePriorities[1] == 'country_id' ? ' selected="selected"' : '') . '>' . JText::_('COM_JEPROSHOP_COUNTRY_LABEL') . '</option><option value="group_id"';
        $content .= ($specificPricePriorities[1] == 'group_id' ? ' selected="selected"' : '') . '>' . JText::_('COM_JEPROSHOP_GROUP_LABEL') . '</option></select>&nbsp;<span class="';
        $content .= 'input-group-addon"><i class="icon-chevron-right"></i></span>&nbsp;<select name="price_field[specific_price_priority[]]" class="middle_size" ><option value="shop_id"';
        $content .= ($specificPricePriorities[2] == 'shop_id' ? ' selected="selected"' : '') . '>' . JText::_('COM_JEPROSHOP_SHOP_LABEL') . '</option><option value="currency_id"';
        $content .= ($specificPricePriorities[2] == 'currency_id' ? ' selected="selected"' : '') . '>' . JText::_('COM_JEPROSHOP_CURRENCY_LABEL') . '</option><option value="country_id"';
        $content .= ($specificPricePriorities[2] == 'country_id' ? ' selected="selected"' : '') . '>' . JText::_('COM_JEPROSHOP_COUNTRY_LABEL') . '</option><option value="group_id"';
        $content .= ($specificPricePriorities[2] == 'group_id' ? ' selected="selected"' : '') . '>' . JText::_('COM_JEPROSHOP_GROUP_LABEL') . '</option></select><span class="';
        $content .= 'input-group-addon"><i class="icon-chevron-right"></i></span>&nbsp;<select name="price_field[specific_price_priority[]]" class="middle_size" ><option value="shop_id"';
        $content .= ($specificPricePriorities[3] == 'shop_id' ? ' selected="selected"' : '') . '>' . JText::_('COM_JEPROSHOP_SHOP_LABEL') . '</option><option value="currency_id"';
        $content .= ($specificPricePriorities[3] == 'currency_id' ? ' selected="selected"' : '') . '>' . JText::_('COM_JEPROSHOP_CURRENCY_LABEL') . '</option><option value="country_id"';
        $content .= ($specificPricePriorities[3] == 'country_id' ? ' selected="selected"' : '') . '>' . JText::_('COM_JEPROSHOP_COUNTRY_LABEL') . '</option><option value="group_id"';
        $content .= ($specificPricePriorities[3] == 'group_id' ? ' selected="selected"' : '') . '>' . JText::_('COM_JEPROSHOP_GROUP_LABEL') . '</option></select></div></div></div>';
        $content .= '<p class="checkbox"><label for="jform_specific_price_priority_to_all"><input type="checkbox" name="price_field[specific_price_priority_to_all]" id="jform_specific_';
        $content .= 'price_priority_to_all" />' . JText::_('Apply to all products') . '</label></p>';
        /*<div class="form-group">
                    <label class="control-label col-lg-3" for="specificPricePriority1">'.$this->l('Priorities').'</label>
                     col-lg-9">
        
        
        
                    </div>
                </div>
                <div class="form-group">
                    <div class="col-lg-9 col-lg-offset-3">
        
                    </div>
                </div>
                <div class="panel-footer">
                        <a href="'.$this->context->link->getAdminLink('AdminProducts').'" class="btn btn-default"><i class="process-icon-cancel"></i> '.$this->l('Cancel').'</a>
                        <button id="product_form_submit_btn"  type="submit" name="submitAddproduct" class="btn btn-default pull-right"><i class="process-icon-save"></i> '.$this->l('Save') .'</button>
                        <button id="product_form_submit_btn"  type="submit" name="submitAddproductAndStay" class="btn btn-default pull-right"><i class="process-icon-save"></i> '.$this->l('Save and stay') .'</button>
                    </div>
                </div>
                '; */
        $content .= '<script type="text/javascript">var currencies = new Array(); currencies[0] = new Array(); ';
        $content .= 'currencies[0]["sign"] = "' . $default_currency->sign . '"; currencies[0]["format"] = ' . $default_currency->format . '; ';
        foreach ($currencies as $currency) {
            $content .= '
				currencies[' . $currency->currency_id . '] = new Array();
				currencies[' . $currency->currency_id . ']["sign"] = "' . $currency->sign . '";
				currencies[' . $currency->currency_id . ']["format"] = ' . $currency->format . ';';
        }
        $content .= '</script>';
        return $content;
    }
예제 #9
0
 /**
  * Price calculation / Get product price
  *
  * @param integer $shop_id Shop id
  * @param integer $product_id Product id
  * @param integer $product_attribute_id Product attribute id
  * @param integer $country_id Country id
  * @param integer $state_id State id
  * @param $zipcode
  * @param integer $currency_id Currency id
  * @param integer $group_id Group id
  * @param integer $quantity Quantity Required for Specific prices : quantity discount application
  * @param boolean $use_tax with (1) or without (0) tax
  * @param integer $decimals Number of decimals returned
  * @param boolean $only_reduction Returns only the reduction amount
  * @param boolean $use_reduction Set if the returned amount will include reduction
  * @param boolean $with_ecotax insert ecotax in price output.
  * @param $specific_price
  * @param $use_group_reduction
  * @param int $customer_id
  * @param bool $use_customer_price
  * @param int $cart_id
  * @param int $real_quantity
  * @internal param \variable_reference $specific_price_output If a specific price applies regarding the previous parameters, this variable is filled with the corresponding SpecificPrice object*    If a specific price applies regarding the previous parameters, this variable is filled with the corresponding SpecificPrice object
  * @return float Product price
  */
 public static function priceCalculation($shop_id, $product_id, $product_attribute_id, $country_id, $state_id, $zipcode, $currency_id, $group_id, $quantity, $use_tax, $decimals, $only_reduction, $use_reduction, $with_ecotax, &$specific_price, $use_group_reduction, $customer_id = 0, $use_customer_price = true, $cart_id = 0, $real_quantity = 0)
 {
     static $address = null;
     static $context = null;
     if ($address === null) {
         $address = new JeproshopAddressModelAddress();
     }
     if ($context == null) {
         $context = JeproshopContext::getContext()->cloneContext();
     }
     if ($shop_id !== null && $context->shop->shop_id != (int) $shop_id) {
         $context->shop = new JeproshopShopModelShop((int) $shop_id);
     }
     if (!$use_customer_price) {
         $customer_id = 0;
     }
     if ($product_attribute_id === null) {
         $product_attribute_id = JeproshopProductModelProduct::getDefaultAttribute($product_id);
     }
     $cache_id = $product_id . '_' . $shop_id . '_' . $currency_id . '_' . $country_id . '_' . $state_id . '_' . $zipcode . '_' . $group_id . '_' . $quantity . '_' . $product_attribute_id . '_' . ($use_tax ? '1' : '0') . '_' . $decimals . '_' . ($only_reduction ? '1' : '0') . '_' . ($use_reduction ? '1' : '0') . '_' . $with_ecotax . '_' . $customer_id . '_' . (int) $use_group_reduction . '_' . (int) $cart_id . '-' . (int) $real_quantity;
     // reference parameter is filled before any returns
     $specific_price = JeproshopSpecificPriceModelSpecificPrice::getSpecificPrice((int) $product_id, $shop_id, $currency_id, $country_id, $group_id, $quantity, $product_attribute_id, $customer_id, $cart_id, $real_quantity);
     if (isset(self::$_prices[$cache_id])) {
         return self::$_prices[$cache_id];
     }
     $db = JFactory::getDBO();
     // fetch price & attribute price
     $cache_id_2 = $product_id . '-' . $shop_id;
     if (!isset(self::$_pricesLevel2[$cache_id_2])) {
         $select = "SELECT product_shop." . $db->quoteName('price') . ", product_shop." . $db->quoteName('ecotax');
         $from = $db->quoteName('#__jeproshop_product') . " AS product INNER JOIN " . $db->quoteName('#__jeproshop_product_shop');
         $from .= " AS product_shop ON (product_shop.product_id =product.product_id AND product_shop.shop_id = " . (int) $shop_id . ")";
         if (JeproshopCombinationModelCombination::isFeaturePublished()) {
             $select .= ", product_attribute_shop.product_attribute_id, product_attribute_shop." . $db->quoteName('price') . " AS attribute_price, product_attribute_shop.default_on";
             $leftJoin = " LEFT JOIN " . $db->quoteName('#__jeproshop_product_attribute') . " AS product_attribute ON product_attribute.";
             $leftJoin .= $db->quoteName('product_id') . " = product." . $db->quoteName('product_id') . " LEFT JOIN " . $db->quoteName('#__jeproshop_product_attribute_shop');
             $leftJoin .= " AS product_attribute_shop ON (product_attribute_shop.product_attribute_id = product_attribute.product_attribute_id AND product_attribute_shop.shop_id = " . (int) $shop_id . ")";
         } else {
             $select .= ", 0 as product_attribute_id";
             $leftJoin = "";
         }
         $query = $select . " FROM " . $from . $leftJoin . " WHERE product." . $db->quoteName('product_id') . " = " . (int) $product_id;
         $db->setQuery($query);
         $results = $db->loadObjectList();
         foreach ($results as $row) {
             $array_tmp = array('price' => $row->price, 'ecotax' => $row->ecotax, 'attribute_price' => isset($row->attribute_price) ? $row->attribute_price : null);
             self::$_pricesLevel2[$cache_id_2][(int) $row->product_attribute_id] = $array_tmp;
             if (isset($row->default_on) && $row->default_on == 1) {
                 self::$_pricesLevel2[$cache_id_2][0] = $array_tmp;
             }
         }
     }
     if (!isset(self::$_pricesLevel2[$cache_id_2][(int) $product_attribute_id])) {
         return null;
     }
     $result = self::$_pricesLevel2[$cache_id_2][(int) $product_attribute_id];
     if (!$specific_price || $specific_price->price < 0) {
         $price = (double) $result['price'];
     } else {
         $price = (double) $specific_price->price;
     }
     // convert only if the specific price is in the default currency (id_currency = 0)
     if (!$specific_price || !($specific_price->price >= 0 && $specific_price->currency_id)) {
         $price = JeproshopTools::convertPrice($price, $currency_id);
     }
     // Attribute price
     if (is_array($result) && (!$specific_price || !$specific_price->product_attribute_id || $specific_price->price < 0)) {
         $attribute_price = JeproshopTools::convertPrice($result['attribute_price'] !== null ? (double) $result['attribute_price'] : 0, $currency_id);
         // If you want the default combination, please use NULL value instead
         if ($product_attribute_id !== false) {
             $price += $attribute_price;
         }
     }
     // Tax
     $address->country_id = $country_id;
     $address->state_id = $state_id;
     $address->postcode = $zipcode;
     $tax_manager = JeproshopTaxManagerFactory::getManager($address, JeproshopProductModelProduct::getTaxRulesGroupIdByProductId((int) $product_id, $context));
     $product_tax_calculator = $tax_manager->getTaxCalculator();
     // Add Tax
     if ($use_tax) {
         $price = $product_tax_calculator->addTaxes($price);
     }
     // Reduction
     $specific_price_reduction = 0;
     if (($only_reduction || $use_reduction) && $specific_price) {
         if ($specific_price->reduction_type == 'amount') {
             $reduction_amount = $specific_price->reduction;
             if (!$specific_price->currency_id) {
                 $reduction_amount = JeproshopTools::convertPrice($reduction_amount, $currency_id);
             }
             $specific_price_reduction = !$use_tax ? $product_tax_calculator->removeTaxes($reduction_amount) : $reduction_amount;
         } else {
             $specific_price_reduction = $price * $specific_price->reduction;
         }
     }
     if ($use_reduction) {
         $price -= $specific_price_reduction;
     }
     // Group reduction
     if ($use_group_reduction) {
         $reduction_from_category = JeproshopGroupReductionModelGroupReduction::getValueForProduct($product_id, $group_id);
         if ($reduction_from_category !== false) {
             $group_reduction = $price * (double) $reduction_from_category;
         } else {
             // apply group reduction if there is no group reduction for this category
             $group_reduction = ($reduction = JeproshopGroupModelGroup::getReductionByGroupId($group_id)) != 0 ? $price * $reduction / 100 : 0;
         }
     } else {
         $group_reduction = 0;
     }
     if ($only_reduction) {
         return JeproshopTools::roundPrice($group_reduction + $specific_price_reduction, $decimals);
     }
     if ($use_reduction) {
         $price -= $group_reduction;
     }
     // Eco Tax
     if (($result['ecotax'] || isset($result['attribute_ecotax'])) && $with_ecotax) {
         $ecotax = $result['ecotax'];
         if (isset($result['attribute_ecotax']) && $result['attribute_ecotax'] > 0) {
             $ecotax = $result['attribute_ecotax'];
         }
         if ($currency_id) {
             $ecotax = JeproshopTools::convertPrice($ecotax, $currency_id);
         }
         if ($use_tax) {
             // reinitialize the tax manager for ecotax handling
             $tax_manager = JeproshopTaxManagerFactory::getManager($address, (int) JeproshopSettingModelSetting::getValue('ecotax_tax_rules_group_id'));
             $ecotax_tax_calculator = $tax_manager->getTaxCalculator();
             $price += $ecotax_tax_calculator->addTaxes($ecotax);
         } else {
             $price += $ecotax;
         }
     }
     $price = JeproshopTools::roundPrice($price, $decimals);
     if ($price < 0) {
         $price = 0;
     }
     self::$_prices[$cache_id] = $price;
     return self::$_prices[$cache_id];
 }