PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/controllers/admin/AdminStockCoverController.php

https://bitbucket.org/yhjohn/ayanapure.com
PHP | 375 lines | 263 code | 38 blank | 74 comment | 31 complexity | d4c1aca887541027c3b821d24407ff10 MD5 | raw file
Possible License(s): LGPL-2.1, LGPL-3.0
  1. <?php
  2. /*
  3. * 2007-2012 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-2012 PrestaShop SA
  23. * @version Release: $Revision: 17889 $
  24. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  25. * International Registered Trademark & Property of PrestaShop SA
  26. */
  27. /**
  28. * @since 1.5.0
  29. */
  30. class AdminStockCoverControllerCore extends AdminController
  31. {
  32. protected $stock_cover_warehouses;
  33. protected $stock_cover_periods;
  34. public function __construct()
  35. {
  36. $this->context = Context::getContext();
  37. $this->table = 'product';
  38. $this->className = 'Product';
  39. $this->lang = true;
  40. $this->colorOnBackground = true;
  41. $this->multishop_context = Shop::CONTEXT_ALL;
  42. $this->fields_list = array(
  43. 'reference' => array(
  44. 'title' => $this->l('Reference'),
  45. 'align' => 'center',
  46. 'width' => 200,
  47. 'filter_key' => 'a!reference'
  48. ),
  49. 'ean13' => array(
  50. 'title' => $this->l('EAN13'),
  51. 'align' => 'center',
  52. 'width' => 100,
  53. 'filter_key' => 'a!ean13'
  54. ),
  55. 'upc' => array(
  56. 'title' => $this->l('UPC'),
  57. 'align' => 'center',
  58. 'width' => 100,
  59. 'filter_key' => 'a!upc'
  60. ),
  61. 'name' => array(
  62. 'title' => $this->l('Name'),
  63. 'filter_key' => 'b!name'
  64. ),
  65. 'qty_sold' => array(
  66. 'title' => $this->l('Quantity sold'),
  67. 'width' => 160,
  68. 'orderby' => false,
  69. 'search' => false,
  70. 'hint' => $this->l('Quantity sold during the defined period.'),
  71. ),
  72. 'coverage' => array(
  73. 'title' => $this->l('Coverage'),
  74. 'width' => 160,
  75. 'orderby' => false,
  76. 'search' => false,
  77. 'hint' => $this->l('Days left before you run out of stock.'),
  78. ),
  79. 'stock' => array(
  80. 'title' => $this->l('Quantity'),
  81. 'width' => 80,
  82. 'orderby' => false,
  83. 'search' => false,
  84. 'hint' => $this->l('Physical (usable) quantity.')
  85. ),
  86. );
  87. // pre-defines coverage periods
  88. $this->stock_cover_periods = array(
  89. $this->l('One week') => 7,
  90. $this->l('Two weeks') => 14,
  91. $this->l('Three weeks') => 21,
  92. $this->l('One month') => 31,
  93. $this->l('Six months') => 186,
  94. $this->l('One year') => 365
  95. );
  96. // gets the list of warehouses available
  97. $this->stock_cover_warehouses = Warehouse::getWarehouses(true);
  98. // gets the final list of warehouses
  99. array_unshift($this->stock_cover_warehouses, array('id_warehouse' => -1, 'name' => $this->l('All Warehouses')));
  100. parent::__construct();
  101. }
  102. /**
  103. * Method called when an ajax request is made
  104. * @see AdminController::postProcess()
  105. */
  106. public function ajaxProcess()
  107. {
  108. if (Tools::isSubmit('id')) // if a product id is submit
  109. {
  110. $this->lang = false;
  111. $lang_id = (int)$this->context->language->id;
  112. $id_product = (int)Tools::getValue('id');
  113. $period = (Tools::getValue('period') ? (int)Tools::getValue('period') : 7);
  114. $warehouse = Tools::getValue('id_warehouse', -1);
  115. $where_warehouse = '';
  116. if ($warehouse != -1)
  117. $where_warehouse = ' AND s.id_warehouse = '.(int)$warehouse;
  118. $query = new DbQuery();
  119. $query->select('pa.id_product_attribute as id, pa.id_product, stock_view.reference, stock_view.ean13,
  120. stock_view.upc, stock_view.usable_quantity as stock');
  121. $query->from('product_attribute', 'pa');
  122. $query->join('INNER JOIN
  123. (
  124. SELECT SUM(s.usable_quantity) as usable_quantity, s.id_product_attribute, s.reference, s.ean13, s.upc
  125. FROM '._DB_PREFIX_.'stock s
  126. WHERE s.id_product = '.($id_product).
  127. $where_warehouse.'
  128. GROUP BY s.id_product_attribute
  129. )
  130. stock_view ON (stock_view.id_product_attribute = pa.id_product_attribute)');
  131. $query->where('pa.id_product = '.$id_product);
  132. $query->groupBy('pa.id_product_attribute');
  133. $datas = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($query);
  134. foreach ($datas as &$data)
  135. {
  136. $data['name'] = Product::getProductName($data['id_product'], $data['id']);
  137. // computes coverage
  138. $coverage = StockManagerFactory::getManager()->getProductCoverage(
  139. $data['id_product'],
  140. $data['id'],
  141. $period,
  142. (($this->getCurrentCoverageWarehouse() == -1) ? null : $warehouse)
  143. );
  144. if ($coverage != -1) // if coverage is available
  145. {
  146. if ($coverage < $this->getCurrentWarning()) // if highlight needed
  147. $data['color'] = '#BDE5F8';
  148. $data['coverage'] = $coverage;
  149. }
  150. else // infinity
  151. $data['coverage'] = '--';
  152. // computes quantity sold
  153. $qty_sold = $this->getQuantitySold($data['id_product'], $data['id'], $this->getCurrentCoveragePeriod());
  154. if (!$qty_sold)
  155. $data['qty_sold'] = '--';
  156. else
  157. $data['qty_sold'] = $qty_sold;
  158. }
  159. echo Tools::jsonEncode(array('data'=> $datas, 'fields_display' => $this->fields_list));
  160. }
  161. die;
  162. }
  163. /**
  164. * AdminController::renderList() override
  165. * @see AdminController::renderList()
  166. */
  167. public function renderList()
  168. {
  169. $this->addRowAction('details');
  170. $this->toolbar_btn = array();
  171. // disables link
  172. $this->list_no_link = true;
  173. // query
  174. $this->_select = 'a.id_product as id, COUNT(pa.id_product_attribute) as variations, SUM(s.usable_quantity) as stock';
  175. $this->_join = 'LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa ON (pa.id_product = a.id_product)
  176. '.Shop::addSqlAssociation('product_attribute', 'pa', false).'
  177. INNER JOIN `'._DB_PREFIX_.'stock` s ON (s.id_product = a.id_product)';
  178. $this->_group = 'GROUP BY a.id_product';
  179. self::$currentIndex .= '&coverage_period='.(int)$this->getCurrentCoveragePeriod().'&warn_days='.(int)$this->getCurrentWarning();
  180. if ($this->getCurrentCoverageWarehouse() != -1)
  181. {
  182. $this->_where .= ' AND s.id_warehouse = '.(int)$this->getCurrentCoverageWarehouse();
  183. self::$currentIndex .= '&id_warehouse='.(int)$this->getCurrentCoverageWarehouse();
  184. }
  185. // Hack for multi shop ..
  186. $this->_where .= ' AND b.id_shop = 1';
  187. $this->tpl_list_vars['stock_cover_periods'] = $this->stock_cover_periods;
  188. $this->tpl_list_vars['stock_cover_cur_period'] = $this->getCurrentCoveragePeriod();
  189. $this->tpl_list_vars['stock_cover_warehouses'] = $this->stock_cover_warehouses;
  190. $this->tpl_list_vars['stock_cover_cur_warehouse'] = $this->getCurrentCoverageWarehouse();
  191. $this->tpl_list_vars['stock_cover_warn_days'] = $this->getCurrentWarning();
  192. $this->ajax_params = array(
  193. 'period' => $this->getCurrentCoveragePeriod(),
  194. 'id_warehouse' => $this->getCurrentCoverageWarehouse(),
  195. 'warn_days' => $this->getCurrentWarning()
  196. );
  197. $this->displayInformation($this->l('Considering the coverage period choosen and the quantity of products/combinations that you sold,'));
  198. $this->displayInformation($this->l('this interface gives you an idea of when a product will run out of stock.'));
  199. return parent::renderList();
  200. }
  201. /**
  202. * AdminController::getList() override
  203. * @see AdminController::getList()
  204. */
  205. public function getList($id_lang, $order_by = null, $order_way = null, $start = 0, $limit = null, $id_lang_shop = false)
  206. {
  207. parent::getList($id_lang, $order_by, $order_way, $start, $limit, $id_lang_shop);
  208. $nb_items = count($this->_list);
  209. for ($i = 0; $i < $nb_items; ++$i)
  210. {
  211. $item = &$this->_list[$i];
  212. if ((int)$item['variations'] <= 0)
  213. {
  214. // computes coverage and displays (highlights if needed)
  215. $coverage = StockManagerFactory::getManager()->getProductCoverage(
  216. $item['id'],
  217. 0,
  218. $this->getCurrentCoveragePeriod(),
  219. (($this->getCurrentCoverageWarehouse() == -1) ? null : $this->getCurrentCoverageWarehouse())
  220. );
  221. if ($coverage != -1) // coverage is available
  222. {
  223. if ($coverage < $this->getCurrentWarning())
  224. $item['color'] = '#BDE5F8';
  225. $item['coverage'] = $coverage;
  226. }
  227. else // infinity
  228. $item['coverage'] = '--';
  229. // computes quantity sold
  230. $qty_sold = $this->getQuantitySold($item['id'], 0, $this->getCurrentCoveragePeriod());
  231. if (!$qty_sold)
  232. $item['qty_sold'] = '--';
  233. else
  234. $item['qty_sold'] = $qty_sold;
  235. // removes 'details' action on products without attributes
  236. $this->addRowActionSkipList('details', array($item['id']));
  237. }
  238. else
  239. {
  240. $item['stock'] = $this->l('See details');
  241. $item['reference'] = '--';
  242. $item['ean13'] = '--';
  243. $item['upc'] = '--';
  244. }
  245. }
  246. }
  247. /**
  248. * Gets the current coverage period used
  249. *
  250. * @return int coverage period
  251. */
  252. protected function getCurrentCoveragePeriod()
  253. {
  254. static $coverage_period = 0;
  255. if ($coverage_period == 0)
  256. {
  257. $coverage_period = 7; // Week by default
  258. if ((int)Tools::getValue('coverage_period'))
  259. $coverage_period = (int)Tools::getValue('coverage_period');
  260. }
  261. return $coverage_period;
  262. }
  263. /**
  264. * Gets the current warehouse used
  265. *
  266. * @return int id_warehouse
  267. */
  268. protected function getCurrentCoverageWarehouse()
  269. {
  270. static $warehouse = 0;
  271. if ($warehouse == 0)
  272. {
  273. $warehouse = -1; // all warehouses
  274. if ((int)Tools::getValue('id_warehouse'))
  275. $warehouse = (int)Tools::getValue('id_warehouse');
  276. }
  277. return $warehouse;
  278. }
  279. /**
  280. * Gets the current warning
  281. *
  282. * @return int warn_days
  283. */
  284. protected function getCurrentWarning()
  285. {
  286. static $warning = 0;
  287. if ($warning == 0)
  288. {
  289. $warning = 0;
  290. if (Tools::getValue('warn_days') && Validate::isInt(Tools::getValue('warn_days')))
  291. $warning = (int)Tools::getValue('warn_days');
  292. }
  293. return $warning;
  294. }
  295. /**
  296. * For a given product, and a given period, returns the quantity sold
  297. *
  298. * @param int $id_product
  299. * @param int $id_product_attribute
  300. * @param int $coverage
  301. * @return int $quantity
  302. */
  303. protected function getQuantitySold($id_product, $id_product_attribute, $coverage)
  304. {
  305. $query = new DbQuery();
  306. $query->select('SUM(od.product_quantity)');
  307. $query->from('order_detail', 'od');
  308. $query->leftJoin('orders', 'o', 'od.id_order = o.id_order');
  309. $query->leftJoin('order_history', 'oh', 'o.date_upd = oh.date_add');
  310. $query->leftJoin('order_state', 'os', 'os.id_order_state = oh.id_order_state');
  311. $query->where('od.product_id = '.(int)$id_product);
  312. $query->where('od.product_attribute_id = '.(int)$id_product_attribute);
  313. $query->where('TO_DAYS(NOW()) - TO_DAYS(oh.date_add) <= '.(int)$coverage);
  314. $query->where('o.valid = 1');
  315. $query->where('os.logable = 1 AND os.delivery = 1 AND os.shipped = 1');
  316. $quantity = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($query);
  317. return $quantity;
  318. }
  319. public function initContent()
  320. {
  321. if (!Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT'))
  322. {
  323. $this->warnings[md5('PS_ADVANCED_STOCK_MANAGEMENT')] = $this->l('You need to activate advanced stock management prior to use this feature.');
  324. return false;
  325. }
  326. parent::initContent();
  327. }
  328. public function initProcess()
  329. {
  330. if (!Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT'))
  331. {
  332. $this->warnings[md5('PS_ADVANCED_STOCK_MANAGEMENT')] = $this->l('You need to activate advanced stock management prior to use this feature.');
  333. return false;
  334. }
  335. parent::initProcess();
  336. }
  337. }