From 4180588c40e72e7ec00a17ce23c63a2d5ed91eaf Mon Sep 17 00:00:00 2001 From: bMancone Date: Tue, 13 Dec 2011 09:48:52 +0000 Subject: [PATCH] // Updated OrderHistory / StockManager. Added feature to StockCover: it is now possible to display the number of sales per product / and highlight products which coverage is less than a given threshold --- admin-dev/themes/default/admin.css | 2 +- .../helper/list/list_action_details.tpl | 14 ++- .../template/stock_cover/list_header.tpl | 17 ++- .../template/supply_orders/list_header.tpl | 13 ++- classes/order/OrderHistory.php | 5 + classes/stock/StockManager.php | 8 +- .../admin/AdminStockCoverController.php | 109 +++++++++++++++--- 7 files changed, 132 insertions(+), 36 deletions(-) diff --git a/admin-dev/themes/default/admin.css b/admin-dev/themes/default/admin.css index 3cf551047..1320884be 100644 --- a/admin-dev/themes/default/admin.css +++ b/admin-dev/themes/default/admin.css @@ -222,7 +222,7 @@ form#product_form h4 { font-size:18px; font-weight:normal;} .filter-module .button-filter { float:right;} /*FILTER STOCK*/ -.filter-stock { background-color:#ebedf4; border:1px solid #c2c4d9; margin-bottom:15px; padding:10px; display:block; min-height:25px;} +.filter-stock { background-color:#ebedf4; border:1px solid #c2c4d9; margin-bottom:15px; padding:10px; display:block; min-height:65px;} .filter-stock #stock_cover {float:left; margin-right:30px;} .filter-stock #stock_instant_state {float:left; margin-right:30px;} .filter-stock #supply_orders {float:left; margin-right:30px;} diff --git a/admin-dev/themes/template/helper/list/list_action_details.tpl b/admin-dev/themes/template/helper/list/list_action_details.tpl index 0160a654e..195d956c3 100644 --- a/admin-dev/themes/template/helper/list/list_action_details.tpl +++ b/admin-dev/themes/template/helper/list/list_action_details.tpl @@ -55,6 +55,10 @@ $(document).ready(function() { .attr('colspan', $('#details_{$id}').parent().parent().find('td').length))); $.each(data.data, function(it, row) { + var bg_color = ''; // Color + if (row.color) + bg_color = 'style="background:' + row.color +';"'; + var content = $(''); content.append($('')); var first = true; @@ -69,9 +73,9 @@ $(document).ready(function() { if (typeof(row[it]) == 'undefined') { if (first || count == 0) - content.append($('')); + content.append($('')); else - content.append($('')); + content.append($('')); } else { @@ -79,12 +83,12 @@ $(document).ready(function() { if (first) { first = false; - content.append($(''+row[it]+'')); + content.append($(''+row[it]+'')); } else if (count == 0) - content.append($(''+row[it]+'')); + content.append($(''+row[it]+'')); else - content.append($(''+row[it]+'')); + content.append($(''+row[it]+'')); } }); content.append($('')); diff --git a/admin-dev/themes/template/stock_cover/list_header.tpl b/admin-dev/themes/template/stock_cover/list_header.tpl index 0d4aa159c..c90286828 100644 --- a/admin-dev/themes/template/stock_cover/list_header.tpl +++ b/admin-dev/themes/template/stock_cover/list_header.tpl @@ -30,20 +30,31 @@ {if count($stock_cover_periods) > 1} - - {foreach from=$stock_cover_periods key=k item=i} {/foreach} + {/if} {if count($stock_cover_warehouses) > 0} - {foreach from=$stock_cover_warehouses key=k item=i} {/foreach} + {/if} +
+ + + +
{/block} diff --git a/admin-dev/themes/template/supply_orders/list_header.tpl b/admin-dev/themes/template/supply_orders/list_header.tpl index dcc63aecb..be2318592 100644 --- a/admin-dev/themes/template/supply_orders/list_header.tpl +++ b/admin-dev/themes/template/supply_orders/list_header.tpl @@ -30,13 +30,18 @@
- - - {foreach from=$warehouses key=k item=i} {/foreach} - + + +
+ + +
{/if} diff --git a/classes/order/OrderHistory.php b/classes/order/OrderHistory.php index 020e27bbb..69117a07b 100644 --- a/classes/order/OrderHistory.php +++ b/classes/order/OrderHistory.php @@ -127,6 +127,11 @@ class OrderHistoryCore extends ObjectModel true, (int)$id_order ); + + if (StockAvailable::dependsOnStock($product['id_product'], $order->id_shop)) + StockAvailable::synchronize($product['id_product']); + else + StockAvailable::updateQuantity($product['id_product'], $product['id_product_attribute'], -(int)$product['cart_quantity'], $order->id_shop); } else if ($newOS->shipped == 0 && $oldOrderStatus->shipped == 1 && Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) { diff --git a/classes/stock/StockManager.php b/classes/stock/StockManager.php index 5c50f2226..8f132e60f 100644 --- a/classes/stock/StockManager.php +++ b/classes/stock/StockManager.php @@ -554,7 +554,7 @@ class StockManagerCore implements StockManagerInterface /** * @see StockManagerInterface::getProductCoverage() * Here, $coverage is a number of days - * @return int number of days left + * @return int number of days left (-1 if infinite) */ public function getProductCoverage($id_product, $id_product_attribute, $coverage, $id_warehouse = null) { @@ -584,14 +584,14 @@ class StockManagerCore implements StockManagerInterface $quantity_out = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($query); if (!$quantity_out) - return '--'; + return -1; - $quantity_per_day = round($quantity_out / $coverage); + $quantity_per_day = Tools::ps_round($quantity_out / $coverage); $physical_quantity = $this->getProductPhysicalQuantities($id_product, $id_product_attribute, ($id_warehouse ? array($id_warehouse) : null), true); - $time_left = ($quantity_per_day == 0) ? '--' : round($physical_quantity / $quantity_per_day); + $time_left = ($quantity_per_day == 0) ? (-1) : Tools::ps_round($physical_quantity / $quantity_per_day); return $time_left; } diff --git a/controllers/admin/AdminStockCoverController.php b/controllers/admin/AdminStockCoverController.php index 7b60de98d..344e35ef2 100644 --- a/controllers/admin/AdminStockCoverController.php +++ b/controllers/admin/AdminStockCoverController.php @@ -39,6 +39,7 @@ class AdminStockCoverControllerCore extends AdminController $this->table = 'product'; $this->className = 'Product'; $this->lang = true; + $this->colorOnBackground = true; $this->fieldsDisplay = array( 'reference' => array( @@ -63,12 +64,19 @@ class AdminStockCoverControllerCore extends AdminController 'title' => $this->l('Name'), 'filter_key' => 'b!name' ), + 'qty_sold' => array( + 'title' => $this->l('Quantity sold'), + 'width' => 160, + 'orderby' => false, + 'search' => false, + 'hint' => $this->l('Quantity sold during the defined period.'), + ), 'coverage' => array( 'title' => $this->l('Coverage'), 'width' => 160, 'orderby' => false, 'search' => false, - 'hint' => $this->l('Days left before you run out of stock.') + 'hint' => $this->l('Days left before you run out of stock.'), ), 'stock' => array( 'title' => $this->l('Quantity'), @@ -135,11 +143,25 @@ class AdminStockCoverControllerCore extends AdminController { $data['name'] = Product::getProductName($data['id_product'], $data['id']); - if ($this->getCurrentCoverageWarehouse() == -1) - $data['coverage'] = StockManagerFactory::getManager()->getProductCoverage($data['id_product'], $data['id'], $period); - else - $data['coverage'] = StockManagerFactory::getManager()->getProductCoverage($data['id_product'], $data['id'], $period, $warehouse); + // computes coverage + $coverage = StockManagerFactory::getManager()->getProductCoverage( + $data['id_product'], + $data['id'], + $period, + (($this->getCurrentCoverageWarehouse() == -1) ? null : $warehouse) + ); + if ($coverage != -1) // if coverage is available + { + if ($coverage < $this->getCurrentWarning()) // if highlight needed + $data['color'] = '#BDE5F8'; + $data['coverage'] = $coverage; + } + else // infinity + $data['coverage'] = '--'; + + $data['qty_sold'] = $this->getQuantitySold($data['id_product'], $data['id'], $this->getCurrentCoveragePeriod()); } + echo Tools::jsonEncode(array('data'=> $datas, 'fields_display' => $this->fieldsDisplay)); } die; @@ -169,7 +191,12 @@ class AdminStockCoverControllerCore extends AdminController $this->tpl_list_vars['stock_cover_cur_period'] = $this->getCurrentCoveragePeriod(); $this->tpl_list_vars['stock_cover_warehouses'] = $this->stock_cover_warehouses; $this->tpl_list_vars['stock_cover_cur_warehouse'] = $this->getCurrentCoverageWarehouse(); - $this->ajax_params = array('period' => $this->getCurrentCoveragePeriod(), 'id_warehouse' => $this->getCurrentCoverageWarehouse()); + $this->tpl_list_vars['stock_cover_warn_days'] = $this->getCurrentWarning(); + $this->ajax_params = array( + 'period' => $this->getCurrentCoveragePeriod(), + 'id_warehouse' => $this->getCurrentCoverageWarehouse(), + 'warn_days' => $this->getCurrentWarning() + ); $this->displayInformation($this->l('Considering the coverage period choosen and the quantity of products/combinations that you sold, this interface gives you an idea of when one product will run out of stock.')); @@ -191,22 +218,30 @@ class AdminStockCoverControllerCore extends AdminController $item = &$this->_list[$i]; if ((int)$item['variations'] <= 0) { - if ($this->getCurrentCoverageWarehouse() == -1) // if all warehouses - $item['coverage'] = StockManagerFactory::getManager()->getProductCoverage( - $item['id'], - 0, - $this->getCurrentCoveragePeriod() - ); - else // else selected warehouse - $item['coverage'] = StockManagerFactory::getManager()->getProductCoverage( - $item['id'], - 0, - $this->getCurrentCoveragePeriod(), - $this->getCurrentCoverageWarehouse() - ); + // computes coverage and displays (highlights if needed) + $coverage = StockManagerFactory::getManager()->getProductCoverage( + $item['id'], + 0, + $this->getCurrentCoveragePeriod(), + (($this->getCurrentCoverageWarehouse() == -1) ? null : $this->getCurrentCoverageWarehouse()) + ); + if ($coverage != -1) // coverage is available + { + if ($coverage < $this->getCurrentWarning()) + $item['color'] = '#BDE5F8'; + + $item['coverage'] = $coverage; + } + else // infinity + $item['coverage'] = '--'; + + // computes quantity sold + $item['qty_sold'] = $this->getQuantitySold($item['id'], 0, $this->getCurrentCoveragePeriod()); // removes 'details' action on products without attributes $this->addRowActionSkipList('details', array($item['id'])); + + } else { @@ -253,4 +288,40 @@ class AdminStockCoverControllerCore extends AdminController } return $warehouse; } + + /** + * Gets the current warning + * + * @return int warn period + */ + private function getCurrentWarning() + { + static $warning = 0; + + if ($warning == 0) + { + $warning = 0; + if (Tools::getValue('warn_days') && Validate::isInt(Tools::getValue('warn_days'))) + $warning = (int)Tools::getValue('warn_days'); + } + return $warning; + } + + protected function getQuantitySold($id_product, $id_product_attribute, $coverage) + { + $query = new DbQuery(); + $query->select('SUM(od.product_quantity)'); + $query->from('order_detail od'); + $query->leftJoin('orders o ON (od.id_order = o.id_order)'); + $query->leftJoin('order_history oh ON (o.date_upd = oh.date_add)'); + $query->leftJoin('order_state os ON (os.id_order_state = oh.id_order_state)'); + $query->where('od.product_id = '.(int)$id_product); + $query->where('od.product_attribute_id = '.(int)$id_product_attribute); + $query->where('TO_DAYS(NOW()) - TO_DAYS(oh.date_add) <= '.(int)$coverage); + $query->where('o.valid = 1'); + $query->where('os.logable = 1 AND os.delivery = 1 AND os.shipped = 1'); + + $quantity = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($query); + return $quantity; + } }