PageRenderTime 56ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/classes/ProductSale.php

https://github.com/netplayer/PrestaShop
PHP | 243 lines | 171 code | 21 blank | 51 comment | 29 complexity | 683d3769ade71b8a3748780f127f2613 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, LGPL-2.1, LGPL-3.0
  1. <?php
  2. /*
  3. * 2007-2014 PrestaShop
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@prestashop.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
  18. * versions in the future. If you wish to customize PrestaShop for your
  19. * needs please refer to http://www.prestashop.com for more information.
  20. *
  21. * @author PrestaShop SA <contact@prestashop.com>
  22. * @copyright 2007-2014 PrestaShop SA
  23. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  24. * International Registered Trademark & Property of PrestaShop SA
  25. */
  26. class ProductSaleCore
  27. {
  28. /*
  29. ** Fill the `product_sale` SQL table with data from `order_detail`
  30. ** @return bool True on success
  31. */
  32. public static function fillProductSales()
  33. {
  34. $sql = 'REPLACE INTO '._DB_PREFIX_.'product_sale
  35. (`id_product`, `quantity`, `sale_nbr`, `date_upd`)
  36. SELECT od.product_id, SUM(od.product_quantity), COUNT(od.product_id), NOW()
  37. FROM '._DB_PREFIX_.'order_detail od GROUP BY od.product_id';
  38. return Db::getInstance()->execute($sql);
  39. }
  40. /*
  41. ** Get number of actives products sold
  42. ** @return int number of actives products listed in product_sales
  43. */
  44. public static function getNbSales()
  45. {
  46. $sql = 'SELECT COUNT(ps.`id_product`) AS nb
  47. FROM `'._DB_PREFIX_.'product_sale` ps
  48. LEFT JOIN `'._DB_PREFIX_.'product` p ON p.`id_product` = ps.`id_product`
  49. '.Shop::addSqlAssociation('product', 'p', false).'
  50. WHERE product_shop.`active` = 1';
  51. return (int)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql);
  52. }
  53. /*
  54. ** Get required informations on best sales products
  55. **
  56. ** @param integer $id_lang Language id
  57. ** @param integer $page_number Start from (optional)
  58. ** @param integer $nb_products Number of products to return (optional)
  59. ** @return array from Product::getProductProperties
  60. */
  61. public static function getBestSales($id_lang, $page_number = 0, $nb_products = 10, $order_by = null, $order_way = null)
  62. {
  63. if ($page_number < 0) $page_number = 0;
  64. if ($nb_products < 1) $nb_products = 10;
  65. $final_order_by = $order_by;
  66. $order_table = '';
  67. if (is_null($order_by) || $order_by == 'position' || $order_by == 'price') $order_by = 'sales';
  68. if ($order_by == 'date_add' || $order_by == 'date_upd')
  69. $order_table = 'product_shop';
  70. if (is_null($order_way) || $order_by == 'sales') $order_way = 'DESC';
  71. $sql_groups = '';
  72. if (Group::isFeatureActive())
  73. {
  74. $groups = FrontController::getCurrentCustomerGroups();
  75. $sql_groups = 'WHERE cp.`id_product` IS NOT NULL AND cg.`id_group` '.(count($groups) ? 'IN ('.implode(',', $groups).')' : '= 1');
  76. }
  77. $interval = Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20;
  78. $products = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
  79. SELECT cp.`id_product`
  80. FROM `'._DB_PREFIX_.'category_group` cg
  81. INNER JOIN `'._DB_PREFIX_.'category_product` cp ON (cp.`id_category` = cg.`id_category`)
  82. '.$sql_groups);
  83. $ids = array();
  84. foreach ($products as $product)
  85. if (Validate::isUnsignedId($product['id_product']))
  86. $ids[$product['id_product']] = 1;
  87. $ids = array_keys($ids);
  88. $ids = array_filter($ids);
  89. sort($ids);
  90. $ids = count($ids) > 0 ? implode(',', $ids) : 'NULL';
  91. //Main query
  92. $sql = 'SELECT p.*, product_shop.*, stock.out_of_stock, IFNULL(stock.quantity, 0) as quantity,
  93. pl.`description`, pl.`description_short`, pl.`link_rewrite`, pl.`meta_description`,
  94. pl.`meta_keywords`, pl.`meta_title`, pl.`name`, pl.`available_now`, pl.`available_later`,
  95. m.`name` AS manufacturer_name, p.`id_manufacturer` as id_manufacturer,
  96. MAX(image_shop.`id_image`) id_image, il.`legend`,
  97. ps.`quantity` AS sales, t.`rate`, pl.`meta_keywords`, pl.`meta_title`, pl.`meta_description`,
  98. DATEDIFF(p.`date_add`, DATE_SUB(NOW(),
  99. INTERVAL '.$interval.' DAY)) > 0 AS new
  100. FROM `'._DB_PREFIX_.'product_sale` ps
  101. LEFT JOIN `'._DB_PREFIX_.'product` p ON ps.`id_product` = p.`id_product`
  102. '.Shop::addSqlAssociation('product', 'p', false).'
  103. LEFT JOIN `'._DB_PREFIX_.'product_lang` pl
  104. ON p.`id_product` = pl.`id_product`
  105. AND pl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('pl').'
  106. LEFT JOIN `'._DB_PREFIX_.'image` i ON (i.`id_product` = p.`id_product`)'.
  107. Shop::addSqlAssociation('image', 'i', false, 'image_shop.cover=1').'
  108. LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.')
  109. LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON (m.`id_manufacturer` = p.`id_manufacturer`)
  110. LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (product_shop.`id_tax_rules_group` = tr.`id_tax_rules_group`)
  111. AND tr.`id_country` = '.(int)Context::getContext()->country->id.'
  112. AND tr.`id_state` = 0
  113. LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`)
  114. '.Product::sqlStock('p').'
  115. WHERE product_shop.`active` = 1
  116. AND p.`visibility` != \'none\'
  117. AND p.`id_product` IN ('.$ids.')
  118. GROUP BY product_shop.id_product
  119. ORDER BY '.(!empty($order_table) ? '`'.pSQL($order_table).'`.' : '').'`'.pSQL($order_by).'` '.pSQL($order_way).'
  120. LIMIT '.(int)($page_number * $nb_products).', '.(int)$nb_products;
  121. $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
  122. if ($final_order_by == 'price')
  123. Tools::orderbyPrice($result, $order_way);
  124. if (!$result)
  125. return false;
  126. return Product::getProductsProperties($id_lang, $result);
  127. }
  128. /*
  129. ** Get required informations on best sales products
  130. **
  131. ** @param integer $id_lang Language id
  132. ** @param integer $page_number Start from (optional)
  133. ** @param integer $nb_products Number of products to return (optional)
  134. ** @return array keys : id_product, link_rewrite, name, id_image, legend, sales, ean13, upc, link
  135. */
  136. public static function getBestSalesLight($id_lang, $page_number = 0, $nb_products = 10, Context $context = null)
  137. {
  138. if (!$context)
  139. $context = Context::getContext();
  140. if ($page_number < 0) $page_number = 0;
  141. if ($nb_products < 1) $nb_products = 10;
  142. $sql_groups = '';
  143. if (Group::isFeatureActive())
  144. {
  145. $groups = FrontController::getCurrentCustomerGroups();
  146. $sql_groups = 'AND cg.`id_group` '.(count($groups) ? 'IN ('.implode(',', $groups).')' : '= 1');
  147. }
  148. //Subquery: get product ids in a separate query to (greatly!) improve performances and RAM usage
  149. $products = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
  150. SELECT cp.`id_product`
  151. FROM `'._DB_PREFIX_.'category_product` cp
  152. LEFT JOIN `'._DB_PREFIX_.'category_group` cg ON (cg.`id_category` = cp.`id_category`)
  153. WHERE cg.`id_group` '.$sql_groups);
  154. $ids = array();
  155. foreach ($products as $product)
  156. $ids[$product['id_product']] = 1;
  157. $ids = array_keys($ids);
  158. sort($ids);
  159. $ids = count($ids) > 0 ? implode(',', $ids) : 'NULL';
  160. //Main query
  161. $sql = '
  162. SELECT
  163. p.id_product, MAX(product_attribute_shop.id_product_attribute) id_product_attribute, pl.`link_rewrite`, pl.`name`, pl.`description_short`, product_shop.`id_category_default`,
  164. MAX(image_shop.`id_image`) id_image, il.`legend`,
  165. ps.`quantity` AS sales, p.`ean13`, p.`upc`, cl.`link_rewrite` AS category, p.show_price, p.available_for_order, IFNULL(stock.quantity, 0) as quantity, p.customizable,
  166. IFNULL(pa.minimal_quantity, p.minimal_quantity) as minimal_quantity, stock.out_of_stock,
  167. product_shop.`date_add` > "'.date('Y-m-d', strtotime('-'.(Configuration::get('PS_NB_DAYS_NEW_PRODUCT') ? (int)Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY')).'" as new
  168. FROM `'._DB_PREFIX_.'product_sale` ps
  169. LEFT JOIN `'._DB_PREFIX_.'product` p ON ps.`id_product` = p.`id_product`
  170. '.Shop::addSqlAssociation('product', 'p').'
  171. LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa
  172. ON (p.`id_product` = pa.`id_product`)
  173. '.Shop::addSqlAssociation('product_attribute', 'pa', false, 'product_attribute_shop.`default_on` = 1').'
  174. '.Product::sqlStock('p', 'product_attribute_shop', false, $context->shop).'
  175. LEFT JOIN `'._DB_PREFIX_.'product_lang` pl
  176. ON p.`id_product` = pl.`id_product`
  177. AND pl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('pl').'
  178. LEFT JOIN `'._DB_PREFIX_.'image` i ON (i.`id_product` = p.`id_product`)'.
  179. Shop::addSqlAssociation('image', 'i', false, 'image_shop.cover=1').'
  180. LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.')
  181. LEFT JOIN `'._DB_PREFIX_.'category_lang` cl
  182. ON cl.`id_category` = product_shop.`id_category_default`
  183. AND cl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('cl').'
  184. WHERE product_shop.`active` = 1
  185. AND p.`visibility` != \'none\'
  186. AND p.`id_product` IN ('.$ids.')
  187. GROUP BY product_shop.id_product
  188. ORDER BY sales DESC
  189. LIMIT '.(int)($page_number * $nb_products).', '.(int)$nb_products;
  190. if (!$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql))
  191. return false;
  192. return Product::getProductsProperties($id_lang, $result);
  193. }
  194. public static function addProductSale($product_id, $qty = 1)
  195. {
  196. return Db::getInstance()->execute('
  197. INSERT INTO '._DB_PREFIX_.'product_sale
  198. (`id_product`, `quantity`, `sale_nbr`, `date_upd`)
  199. VALUES ('.(int)$product_id.', '.(int)$qty.', 1, NOW())
  200. ON DUPLICATE KEY UPDATE `quantity` = `quantity` + '.(int)$qty.', `sale_nbr` = `sale_nbr` + 1, `date_upd` = NOW()');
  201. }
  202. public static function getNbrSales($id_product)
  203. {
  204. $result = Db::getInstance()->getRow('SELECT `sale_nbr` FROM '._DB_PREFIX_.'product_sale WHERE `id_product` = '.(int)$id_product);
  205. if (!$result || empty($result) || !array_key_exists('sale_nbr', $result))
  206. return -1;
  207. return (int)$result['sale_nbr'];
  208. }
  209. public static function removeProductSale($id_product, $qty = 1)
  210. {
  211. $total_sales = ProductSale::getNbrSales($id_product);
  212. if ($total_sales > 1)
  213. return Db::getInstance()->execute('
  214. UPDATE '._DB_PREFIX_.'product_sale
  215. SET `quantity` = `quantity` - '.(int)$qty.', `sale_nbr` = `sale_nbr` - 1, `date_upd` = NOW()
  216. WHERE `id_product` = '.(int)$id_product
  217. );
  218. elseif ($total_sales == 1)
  219. return Db::getInstance()->delete('product_sale', 'id_product = '.(int)$id_product);
  220. return true;
  221. }
  222. }