diff --git a/classes/Category.php b/classes/Category.php index c3d554814..ab76139a9 100644 --- a/classes/Category.php +++ b/classes/Category.php @@ -641,6 +641,7 @@ class CategoryCore extends ObjectModel .($active ? ' AND p.`active` = 1' : '') .($id_supplier ? ' AND p.id_supplier = '.(int)$id_supplier : ''). ' GROUP BY p.id_product'; + if ($random === true) { $sql .= ' ORDER BY RAND()'; diff --git a/classes/Product.php b/classes/Product.php index e79d9eb11..bb5154f00 100644 --- a/classes/Product.php +++ b/classes/Product.php @@ -1633,18 +1633,35 @@ class ProductCore extends ObjectModel { if (!Combination::isFeatureActive()) return array(); + $sql = 'SELECT pa.*, GROUP_CONCAT(agl.`name`, \''.pSQL($attribute_value_separator).'\', - al.`name` SEPARATOR \''.pSQL($attribute_separator).'\') as attribute_designation, IFNULL(stock.quantity, 0) + al.`name` SEPARATOR \''.pSQL($attribute_separator).'\') as attribute_designation FROM `'._DB_PREFIX_.'product_attribute` pa LEFT JOIN `'._DB_PREFIX_.'product_attribute_combination` pac ON pac.`id_product_attribute` = pa.`id_product_attribute` LEFT JOIN `'._DB_PREFIX_.'attribute` a ON a.`id_attribute` = pac.`id_attribute` LEFT JOIN `'._DB_PREFIX_.'attribute_group` ag ON ag.`id_attribute_group` = a.`id_attribute_group` LEFT JOIN `'._DB_PREFIX_.'attribute_lang` al ON (a.`id_attribute` = al.`id_attribute` AND al.`id_lang` = '.(int)$id_lang.') LEFT JOIN `'._DB_PREFIX_.'attribute_group_lang` agl ON (ag.`id_attribute_group` = agl.`id_attribute_group` AND agl.`id_lang` = '.(int)$id_lang.') - '.Product::sqlStock('pa', 'pa').' WHERE pa.`id_product` = '.(int)$this->id.' GROUP BY pa.`id_product_attribute`'; - return Db::getInstance()->executeS($sql); + + $res = Db::getInstance()->executeS($sql); + + //Get quantity of each variations + foreach ($res as $key => $row) + { + $cache_key = $row['id_product'].'_'.$row['id_product_attribute'].'_quantity'; + + if (!Cache::isStored($cache_key)) + Cache::store( + $cache_key, + StockAvailable::getQuantityAvailableByProduct($row['id_product'], $row['id_product_attribute']) + ); + + $res[$key]['quantity'] = Cache::retrieve($cache_key); + } + + return $res; } /** @@ -1657,18 +1674,35 @@ class ProductCore extends ObjectModel { if (!Combination::isFeatureActive()) return array(); + $sql = 'SELECT pa.*, ag.`id_attribute_group`, ag.`is_color_group`, agl.`name` AS group_name, al.`name` AS attribute_name, - a.`id_attribute`, pa.`unit_price_impact`, IFNULL(stock.quantity, 0) as quantity + a.`id_attribute`, pa.`unit_price_impact` FROM `'._DB_PREFIX_.'product_attribute` pa LEFT JOIN `'._DB_PREFIX_.'product_attribute_combination` pac ON pac.`id_product_attribute` = pa.`id_product_attribute` LEFT JOIN `'._DB_PREFIX_.'attribute` a ON a.`id_attribute` = pac.`id_attribute` LEFT JOIN `'._DB_PREFIX_.'attribute_group` ag ON ag.`id_attribute_group` = a.`id_attribute_group` LEFT JOIN `'._DB_PREFIX_.'attribute_lang` al ON (a.`id_attribute` = al.`id_attribute` AND al.`id_lang` = '.(int)$id_lang.') LEFT JOIN `'._DB_PREFIX_.'attribute_group_lang` agl ON (ag.`id_attribute_group` = agl.`id_attribute_group` AND agl.`id_lang` = '.(int)$id_lang.') - '.Product::sqlStock('pa', 'pa').' WHERE pa.`id_product` = '.(int)$this->id.' ORDER BY pa.`id_product_attribute`'; - return Db::getInstance()->executeS($sql); + + $res = Db::getInstance()->executeS($sql); + + //Get quantity of each variations + foreach ($res as $key => $row) + { + $cache_key = $row['id_product'].'_'.$row['id_product_attribute'].'_quantity'; + + if (!Cache::isStored($cache_key)) + Cache::store( + $cache_key, + StockAvailable::getQuantityAvailableByProduct($row['id_product'], $row['id_product_attribute']) + ); + + $res[$key]['quantity'] = Cache::retrieve($cache_key); + } + + return $res; } /** @@ -1683,18 +1717,34 @@ class ProductCore extends ObjectModel if (!Combination::isFeatureActive()) return array(); $sql = 'SELECT pa.*, ag.`id_attribute_group`, ag.`is_color_group`, agl.`name` AS group_name, al.`name` AS attribute_name, - a.`id_attribute`, pa.`unit_price_impact`, IFNULL(stock.quantity, 0) as quantity + a.`id_attribute`, pa.`unit_price_impact` FROM `'._DB_PREFIX_.'product_attribute` pa LEFT JOIN `'._DB_PREFIX_.'product_attribute_combination` pac ON pac.`id_product_attribute` = pa.`id_product_attribute` LEFT JOIN `'._DB_PREFIX_.'attribute` a ON a.`id_attribute` = pac.`id_attribute` LEFT JOIN `'._DB_PREFIX_.'attribute_group` ag ON ag.`id_attribute_group` = a.`id_attribute_group` LEFT JOIN `'._DB_PREFIX_.'attribute_lang` al ON (a.`id_attribute` = al.`id_attribute` AND al.`id_lang` = '.(int)$id_lang.') LEFT JOIN `'._DB_PREFIX_.'attribute_group_lang` agl ON (ag.`id_attribute_group` = agl.`id_attribute_group` AND agl.`id_lang` = '.(int)$id_lang.') - '.Product::sqlStock('pa', 'pa').' WHERE pa.`id_product` = '.(int)$this->id.' AND pa.`id_product_attribute` = '.(int)$id_product_attribute.' ORDER BY pa.`id_product_attribute`'; - return Db::getInstance()->executeS($sql); + + $res = Db::getInstance()->executeS($sql); + + //Get quantity of each variations + foreach ($res as $key => $row) + { + $cache_key = $row['id_product'].'_'.$row['id_product_attribute'].'_quantity'; + + if (!Cache::isStored($cache_key)) + Cache::store( + $cache_key, + StockAvailable::getQuantityAvailableByProduct($row['id_product'], $row['id_product_attribute']) + ); + + $res[$key]['quantity'] = Cache::retrieve($cache_key); + } + + return $res; } public function getCombinationImages($id_lang) diff --git a/classes/Supplier.php b/classes/Supplier.php index 1e0b69184..02a395cc6 100644 --- a/classes/Supplier.php +++ b/classes/Supplier.php @@ -294,12 +294,20 @@ class SupplierCore extends ObjectModel public function getProductsLite($id_lang) { - return Db::getInstance()->executeS(' + $sql = ' SELECT p.`id_product`, pl.`name` FROM `'._DB_PREFIX_.'product` p - LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.(int)$id_lang.') - WHERE p.`id_supplier` = '.(int)$this->id - ); + LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON ( + p.`id_product` = pl.`id_product` + AND pl.`id_lang` = '.(int)$id_lang.' + ) + INNER JOIN `'._DB_PREFIX_.'product_supplier` ps ON ( + ps.`id_product` = p.`id_product` + AND ps.`id_supplier` = '.(int)$this->id.' + ) + GROUP BY p.`id_product`'; + + return Db::getInstance()->executeS($sql); } /* diff --git a/classes/shop/Shop.php b/classes/shop/Shop.php index 59d55d0f5..689de4b5e 100644 --- a/classes/shop/Shop.php +++ b/classes/shop/Shop.php @@ -826,13 +826,13 @@ class ShopCore extends ObjectModel if ($tables_import && !isset($tables_import[$table_name])) continue; - // Special case for stock if current shop is in a share stock group - /*if ($table_name == 'stock') + // Special case for stock_available if current shop is in a share stock group + if ($table_name == 'stock_available') { $group = new GroupShop($this->id_group_shop); if ($group->share_stock && $group->haveShops()) continue; - }*/ + } $id = 'id_'.$row['type']; if ($row['type'] == 'fk_shop') diff --git a/classes/stock/StockAvailable.php b/classes/stock/StockAvailable.php index 9bf4c411e..0b6d83b5c 100644 --- a/classes/stock/StockAvailable.php +++ b/classes/stock/StockAvailable.php @@ -282,7 +282,7 @@ class StockAvailableCore extends ObjectModel $id_product_attribute = 0; $query = new DbQuery(); - $query->select('quantity'); + $query->select('SUM(quantity)'); $query->from('stock_available'); // if null, it's a product without attributes @@ -468,12 +468,17 @@ class StockAvailableCore extends ObjectModel { if ($group_shop->share_stock) { - $id_shops_list = implode(', ', Shop::getIdShopsByIdGroupShop($group_shop->id)); + $shop_list = Shop::getIdShopsByIdGroupShop($group_shop->id); - return Db::getInstance()->execute(' - DELETE FROM '._DB_PREFIX_.'stock_available - WHERE id_shop IN ('.$id_shops_list.')' - ); + if (count($shop_list) > 0) + { + $id_shops_list = implode(', ', $shop_list); + + return Db::getInstance()->execute(' + DELETE FROM '._DB_PREFIX_.'stock_available + WHERE id_shop IN ('.$id_shops_list.')' + ); + } } else { diff --git a/controllers/admin/AdminProductsController.php b/controllers/admin/AdminProductsController.php index 7ab7ad5a5..b41a8c754 100644 --- a/controllers/admin/AdminProductsController.php +++ b/controllers/admin/AdminProductsController.php @@ -176,7 +176,7 @@ class AdminProductsControllerCore extends AdminController $object->on_sale = Tools::isSubmit('on_sale'); $object->online_only = Tools::isSubmit('online_only'); } - + public function getList($id_lang, $orderBy = null, $orderWay = null, $start = 0, $limit = null, $id_lang_shop = null) { $orderByPriceFinal = (empty($orderBy) ? ($this->context->cookie->__get($this->table.'Orderby') ? $this->context->cookie->__get($this->table.'Orderby') : 'id_'.$this->table) : $orderBy); @@ -1898,7 +1898,7 @@ class AdminProductsControllerCore extends AdminController 'href' => '#todo'.$this->context->link->getAdminLink('AdminProducts').'&id_product='.$product->id, 'desc' => $this->l('Create'), ); - + $this->toolbar_btn['newCombinaison'] = array( 'short' => 'Add a new combination', 'desc' => $this->l('Add a new combination'), @@ -1920,7 +1920,7 @@ class AdminProductsControllerCore extends AdminController 'desc' => $this->l('Save and stay'), ); } - + } parent::initToolbar(); $this->context->smarty->assign('toolbar_fix', 1); @@ -2125,6 +2125,7 @@ class AdminProductsControllerCore extends AdminController 0 ) ); + $price = Tools::ps_round($price, 6); $id_currency = (int)Tools::getValue( 'product_price_currency_'.$product->id.'_'.$attribute['id_product_attribute'].'_'.$supplier->id_supplier, @@ -3093,7 +3094,7 @@ class AdminProductsControllerCore extends AdminController 'ean13' => array('title' => $this->l('EAN13'), 'align' => 'center', 'width' => 70), 'upc' => array('title' => $this->l('UPC'), 'align' => 'center', 'width' => 70) ); - + if ($id_product_download && !empty($product_download->display_filename)) { $this->fieldsDisplay['Filename'] = array('title' => $this->l('Filename'), 'align' => 'center', 'width' => 70); @@ -3137,7 +3138,7 @@ class AdminProductsControllerCore extends AdminController $groups[$combinaison['id_attribute_group']] = $combinaison['group_name']; } } - + $irow = 0; if (isset($combArray)) { @@ -3145,10 +3146,10 @@ class AdminProductsControllerCore extends AdminController { $list = ''; $jsList = ''; - + /* In order to keep the same attributes order */ asort($product_attribute['attributes']); - + foreach ($product_attribute['attributes'] as $attribute) { $list .= addslashes(htmlspecialchars($attribute[0])).' - '.addslashes(htmlspecialchars($attribute[1])).', '; @@ -3168,12 +3169,12 @@ class AdminProductsControllerCore extends AdminController $id_product_download = $product->productDownload->getIdFromIdAttribute((int) $product->id, (int) $id_product_attribute); if ($id_product_download) $product->productDownload = new ProductDownload($id_product_download); - + $available_date_attribute = substr($product->productDownload->date_expiration, 0, -9); - + if ($available_date_attribute == '0000-00-00') $available_date_attribute = ''; - + if ($id_product_download && !empty($product->productDownload->display_filename)) { if ($product->productDownload->is_shareable == 1) @@ -3185,9 +3186,9 @@ class AdminProductsControllerCore extends AdminController $combArray[$id_product_attribute]['nb_downloadable'] = $product->productDownload->nb_downloadable; $combArray[$id_product_attribute]['is_shareable'] = $is_shareable; } - + $exists_file = realpath(_PS_DOWNLOAD_DIR_).'/'.$product->productDownload->filename; - + if ($product->productDownload->id && file_exists($exists_file)) $filename = $product->productDownload->filename; else @@ -3289,10 +3290,10 @@ class AdminProductsControllerCore extends AdminController { $list = ''; $jsList = ''; - + /* In order to keep the same attributes order */ asort($product_attribute['attributes']); - + foreach ($product_attribute['attributes'] as $attribute) { $list .= addslashes(htmlspecialchars($attribute[0])).' - '.addslashes(htmlspecialchars($attribute[1])).', '; @@ -3302,21 +3303,21 @@ class AdminProductsControllerCore extends AdminController $jsList = rtrim($jsList, ', '); $attrImage = $product_attribute['id_image'] ? new Image($product_attribute['id_image']) : false; $available_date = ($product_attribute['available_date'] != 0) ? date('Y-m-d', strtotime($product_attribute['available_date'])) : '0000-00-00'; - + $id_product_download = $product->productDownload->getIdFromIdAttribute((int) $product->id, (int) $id_product_attribute); if ($id_product_download) $product->productDownload = new ProductDownload($id_product_download); - + $available_date_attribute = substr($product->productDownload->date_expiration, 0, -9); - + if ($available_date_attribute == '0000-00-00') $available_date_attribute = ''; - + if ($product->productDownload->is_shareable == 1) $is_shareable = $this->l('Yes'); else $is_shareable = $this->l('No'); - + $content .= '