Example #1
0
 public function product()
 {
     // Update the cart ONLY if $this->cookies are available, in order to avoid ghost carts created by bots
     if (!$this->context) {
         $this->context = JeproshopContext::getContext();
     }
     if ($this->context->cookie->exists() && !$this->has_errors && !($this->context->customer->isLogged() && !$this->isTokenValid())) {
         // Send noindex to avoid ghost carts by bots
         header("X-Robots-Tag: noindex, nofollow", true);
         if (!$this->isInitialized()) {
             $this->initialize();
         }
         $app = JFactory::getApplication();
         $product_id = $app->input->get('product_id', null);
         $customization_id = (int) $app->input->get('customization_id', null);
         $address_delivery_id = (int) $app->input->get('address_delivery_id', null);
         $product_attribute_id = $app->input->get('product_attribute_id', null);
         $mode = $app->input->get('task') == 'update' && $product_id ? 'update' : 'add';
         if ($app->input->get('quantity') == 0) {
             $this->has_errors = true;
             echo JText::_('COM_JEPROSHOP_NULL_QUANTITY_MESSAGE') . ' ' . !$app->input->get('use_ajax');
         } elseif (!$product_id) {
             $this->has_errors = true;
             echo JText::_('COM_JEPROSHOP_PRODUCT_ID_NOT_FOUND_MESSAGE') . ' ' . !$app->input->get('use_ajax');
         }
         $product = new JeproshopProductModelProduct($product_id, true, $this->context->language->lang_id);
         if (!$product->product_id || !$product->published) {
             $this->has_errors = true;
             echo JText::_('COM_JEPROSHOP_THIS_PRODUCT_IS_NO_LONGER_AVAILABLE_MESSAGE.') . ' ' . !$app->input->get('use_ajax');
             exit;
         }
         $quantity = abs($app->input->get('quantity', 1));
         $qty_to_check = $quantity;
         $cart_products = $this->context->cart->getProducts();
         if (is_array($cart_products)) {
             foreach ($cart_products as $cart_product) {
                 if ((!isset($this->product_attribute_id) || $cart_product->product_attribute_id == $product_attribute_id) && (isset($product_id) && $cart_product->product_id == $product_id)) {
                     $qty_to_check = $cart_product->cart_quantity;
                     if ($app->input->get('op', 'up') == 'down') {
                         $qty_to_check -= $quantity;
                     } else {
                         $qty_to_check += $quantity;
                     }
                     break;
                 }
             }
         }
         // Check product quantity availability
         if ($product_attribute_id) {
             if (!JeproshopProductModelProduct::isAvailableWhenOutOfStock($product->out_of_stock) && !JeproshopAttributeModelAttribute::checkAttributeQty($product_attribute_id, $qty_to_check)) {
                 $this->has_errors = true;
                 echo JText::_('COM_JEPROSHOP_THERE_IS_NOT_ENOUGH_PRODUCT_IN_STOCK_MESSAGE') . ' ' . __LINE__ . !$app->input->get('use_ajax');
             }
         } elseif ($product->hasAttributes()) {
             $minimumQuantity = $product->out_of_stock == 2 ? !JeproshopSettingModelSetting::getValue('order_out_of_stock') : !$product->out_of_stock;
             $product_attribute_id = JeproshopProductModelProduct::getDefaultAttribute($product->product_id, $minimumQuantity);
             // @todo do something better than a redirect admin !!
             if (!$product_attribute_id) {
                 $app->redirect($this->getProductLink($product));
             } elseif (!JeproshopProductModelProduct::isAvailableWhenOutOfStock($product->out_of_stock) && !JeproshopAttributeModelAttribute::checkAttributeQty($product_attribute_id, $qty_to_check)) {
                 $this->has_errors = true;
                 echo JText::_('COM_JEPROSHOP_THERE_IS_NOT_ENOUGH_PRODUCT_IN_STOCK_MESSAGE') . ' ' . __LINE__ . !$app->input->get('use_ajax');
             }
         } elseif (!$product->checkQuantity($qty_to_check)) {
             $this->has_errors = true;
             echo JText::_('COM_JEPROSHOP_THERE_IS_NOT_ENOUGH_PRODUCT_IN_STOCK_MESSAGE') . ' ' . __LINE__ . !$app->input->get('use_ajax');
         }
         // If no errors, process product addition
         if ($mode == 'add') {
             // Add cart if no cart found
             if (!$this->context->cart->cart_id) {
                 if (JeproshopContext::getContext()->cookie->guest_id) {
                     $guest = new JeproshopGuestModelGuest(JeproshopContext::getContext()->cookie->guest_id);
                     $this->context->cart->mobile_theme = $guest->mobile_theme;
                 }
                 $this->context->cart->add();
                 if ($this->context->cart->cart_id) {
                     $this->context->cookie->cart_id = (int) $this->context->cart->cart_id;
                 }
             }
             // Check customizable fields
             if (!$product->hasAllRequiredCustomizableFields() && !$customization_id) {
                 // $this->errors[] = Tools::displayError('Please fill in all of the required fields, and then save your customizations.', !Tools::getValue('ajax'));
             }
             if (!$this->has_errors) {
                 $cart_rules = $this->context->cart->getCartRules();
                 $update_quantity = $this->context->cart->updateQuantity($quantity, $product_id, $product_attribute_id, $customization_id, $app->input->get('op', 'up'), $address_delivery_id);
                 if ($update_quantity < 0) {
                     // If product has attribute, minimal quantity is set with minimal quantity of attribute
                     $minimal_quantity = $product_attribute_id ? JeproshopAttributeModelAttribute::getAttributeMinimalQty($product_attribute_id) : $product->minimal_quantity;
                     $this->has_errors = true;
                     sprintf(Tools::displayError('You must add %d minimum quantity', !$app->input->get('use_ajax')), $minimal_quantity);
                 } elseif (!$update_quantity) {
                     $this->has_errors = true;
                     echo JText::_('COM_JEPROSHOP_YOU_ALREADY_HAVE_THE_MAXIMUM_AVAILABLE_FOR_THIS_PRODUCT_MESSAGE') . ' ' . !$app->input->get('use_ajax');
                 } elseif ((int) $app->input->get('allow_refresh')) {
                     // If the cart rules has changed, we need to refresh the whole cart
                     $cart_rules2 = $this->context->cart->getCartRules();
                     if (count($cart_rules2) != count($cart_rules)) {
                         $this->ajax_refresh = true;
                     } else {
                         $rule_list = array();
                         foreach ($cart_rules2 as $rule) {
                             $rule_list[] = $rule->cart_rule_id;
                         }
                         foreach ($cart_rules as $rule) {
                             if (!in_array($rule->cart_rule_id, $rule_list)) {
                                 $this->ajax_refresh = true;
                                 break;
                             }
                         }
                     }
                 }
             }
         }
         $removed = JeproshopCartRuleModelCartRule::autoRemoveFromCart();
         JeproshopCartRuleModelCartRule::autoAddToCart();
         if (count($removed) && (int) $app->input->get('allow_refresh')) {
             $this->ajax_refresh = true;
         }
         echo 'bonjour';
         exit;
     } elseif (!$this->context->cookie->exists()) {
         echo 'bonjour cookkie';
         exit;
     } elseif ($this->has_errors) {
     } elseif ($this->context->customer->isLogged() && !$this->isTokenValid()) {
     }
 }
Example #2
0
 private function initQuantitiesForm()
 {
     if (!$this->context->controller->default_form_language) {
         $this->languages = $this->context->controller->getLanguages();
     }
     if ($this->product->product_id) {
         if ($this->product_exists_in_shop) {
             //Get all product_attribute_id
             $attributes = $this->product->getAttributesResume($this->context->language->lang_id);
             if (empty($attributes)) {
                 $attributes[] = new JObject();
                 $attributes[0]->set('product_attribute_id', 0);
                 $attributes[0]->set('attribute_designation', '');
             }
             /** get available quantities **/
             $available_quantity = array();
             $product_designation = array();
             foreach ($attributes as $attribute) {
                 $product_attribute_id = is_object($attribute) ? $attribute->product_attribute_id : $attribute['product_attribute_id'];
                 $attribute_designation = is_object($attribute) ? $attribute->attribute_designation : $attribute['attribute_designation'];
                 // Get available quantity for the current product attribute in the current shop
                 $available_quantity[$product_attribute_id] = JeproshopStockAvailableModelStockAvailable::getQuantityAvailableByProduct((int) $this->product->product_id, $product_attribute_id);
                 // Get all product designation
                 $product_designation[$product_attribute_id] = rtrim($this->product->name[$this->context->language->lang_id] . ' - ' . $attribute_designation, ' - ');
             }
             $show_quantities = true;
             $shop_context = JeproshopShopModelShop::getShopContext();
             $shop_group = new JeproshopShopGroupModelShopGroup((int) JeproshopShopModelShop::getContextShopGroupID());
             // if we are in all shops context, it's not possible to manage quantities at this level
             if (JeproshopShopModelShop::isFeaturePublished() && $shop_context == JeproshopShopModelShop::CONTEXT_ALL) {
                 $show_quantities = false;
                 // if we are in group shop context
             } elseif (JeproshopShopModelShop::isFeaturePublished() && $shop_context == JeproshopShopModelShop::CONTEXT_GROUP) {
                 // if quantities are not shared between shops of the group, it's not possible to manage them at group level
                 if (!$shop_group->share_stock) {
                     $show_quantities = false;
                 }
             } else {
                 // if we are in shop context
                 // if quantities are shared between shops of the group, it's not possible to manage them for a given shop
                 if ($shop_group->share_stock) {
                     $show_quantities = false;
                 }
             }
             $stock_management = JeproshopSettingModelSetting::getValue('stock_management');
             $this->assignRef('stock_management', $stock_management);
             $has_attribute = $this->product->hasAttributes();
             $this->assignRef('has_attribute', $has_attribute);
             // Check if product has combination, to display the available date only for the product or for each combination
             $db = JFactory::getDBO();
             if (JeproshopCombinationModelCombination::isFeaturePublished()) {
                 $query = "SELECT COUNT(product_id) FROM " . $db->quoteName('#__jeproshop_product_attribute') . " WHERE ";
                 $query .= " product_id = " . (int) $this->product->product_id;
                 $db->setQuery($query);
                 $countAttributes = (int) $db->loadResult();
             } else {
                 $countAttributes = false;
             }
             $this->assignRef('count_attributes', $countAttributes);
             // if advanced stock management is active, checks associations
             $advanced_stock_management_warning = false;
             if (JeproshopSettingModelSetting::getValue('advanced_stock_management') && $this->product->advanced_stock_management) {
                 $product_attributes = JeproshopProductModelProduct::getProductAttributesIds($this->product->product_id);
                 $warehouses = array();
                 if (!$product_attributes) {
                     $warehouses[] = JeproshopWarehouseModelWarehouse::getProductWarehouseList($this->product->product_id, 0);
                 }
                 foreach ($product_attributes as $product_attribute) {
                     $ws = JeproshopWarehouseModelWarehouse::getProductWarehouseList($this->product->product_id, $product_attribute->product_attribute_id);
                     if ($ws) {
                         $warehouses[] = $ws;
                     }
                 }
                 $warehouses = JeproshopTools::arrayUnique($warehouses);
                 if (empty($warehouses)) {
                     $advanced_stock_management_warning = true;
                 }
             }
             if ($advanced_stock_management_warning) {
                 JError::raiseWarning(500, JText::_('If you wish to use the advanced stock management, you must:'));
                 JError::raiseWarning(500, '- ' . JText::_('associate your products with warehouses.'));
                 JError::raiseWarning(500, '- ' . JText::_('associate your warehouses with carriers.'));
                 JError::raiseWarning(500, '- ' . JText::_('associate your warehouses with the appropriate shops.'));
             }
             $pack_quantity = null;
             // if product is a pack
             if (JeproshopProductPack::isPack($this->product->product_id)) {
                 $items = JeproshopProductPack::getItems((int) $this->product->product_id, JeproshopSettingModelSetting::getValue('default_lang'));
                 // gets an array of quantities (quantity for the product / quantity in pack)
                 $pack_quantities = array();
                 foreach ($items as $item) {
                     if (!$item->isAvailableWhenOutOfStock((int) $item->out_of_stock)) {
                         $pack_id_product_attribute = JeproshopProductModelProduct::getDefaultAttribute($item->product_id, 1);
                         $pack_quantities[] = JeproshopProductModelProduct::getQuantity($item->id, $pack_id_product_attribute) / ($item->pack_quantity !== 0 ? $item->pack_quantity : 1);
                     }
                 }
                 // gets the minimum
                 if (count($pack_quantities)) {
                     $pack_quantity = $pack_quantities[0];
                     foreach ($pack_quantities as $value) {
                         if ($pack_quantity > $value) {
                             $pack_quantity = $value;
                         }
                     }
                 }
                 if (!JeproshopWarehouseModelWarehouse::getPackWarehouses((int) $this->product->product_id)) {
                     $this->displayWarning($this->l('You must have a common warehouse between this pack and its product.'));
                 }
             }
             $this->assignRef('attributes', $attributes);
             $this->assignRef('available_quantity', $available_quantity);
             $this->assignRef('pack_quantity', $pack_quantity);
             $stock_management_active = JeproshopSettingModelSetting::getValue('advanced_stock_management');
             $this->assignRef('stock_management_active', $stock_management_active);
             $this->assignRef('product_designation', $product_designation);
             $this->assignRef('show_quantities', $show_quantities);
             $order_out_of_stock = JeproshopSettingModelSetting::getValue('allow_out_of_stock_ordering');
             $this->assignRef('order_out_of_stock', $order_out_of_stock);
             /*'token_preferences' => Tools::getAdminTokenLite('AdminPPreferences'),
                       'token' => $this->token,
                       'languages' => $this->_languages,
                       'id_lang' => $this->context->language->id
               ));*/
         } else {
             JError::raiseWarning(500, JText::_('You must save the product in this shop before managing quantities.'));
         }
     } else {
         JError::raiseWarning(500, JText::_('You must save this product before managing quantities.'));
     }
 }
Example #3
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];
 }
Example #4
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];
 }