public function renderList() { $this->toolbar_title = $this->l('Inventory reports'); if (Tools::isSubmit('id_container') && Tools::getValue('id_container') > 0) { self::$currentIndex .= '&id_container=' . (int) Tools::getValue('id_container'); } // Get id container. if noone selected, take the first one if (($id_container = $this->getCurrentValue('id_container')) == false) { $id_container = (int) ErpInventory::getFirstId(); $this->tpl_list_vars['id_container'] = $id_container; } // get total stock gap of inventory $total_stock_gap = InventoryProduct::getTotalStockGap($id_container); $this->tpl_list_vars['total_gap'] = Tools::displayPrice($total_stock_gap); // Query $this->_select = 'p.id_product, IF(pa.id_product_attribute, pa.reference, p.reference) as reference, IFNULL(pa.id_product_attribute, 0) as id_product_attribute, IFNULL(CONCAT(pl.name, \' : \', GROUP_CONCAT(DISTINCT agl.`name`, \' - \', al.name SEPARATOR \', \')),pl.name) as name, p.id_product, IFNULL(pa.id_product_attribute, 0) as id_product_attribute, w.name as warehouse, a.qte_before, a.qte_after, smrl.name as reason, (qte_after - qte_before) as gap, ( SELECT ps.product_supplier_reference FROM ' . _DB_PREFIX_ . 'product_supplier ps WHERE ps.id_product = a.id_product AND ps.id_product_attribute = a.id_product_attribute LIMIT 1 )as first_supplier_ref'; $this->_join = 'INNER JOIN ' . _DB_PREFIX_ . 'product_lang pl ON (a.id_product = pl.id_product AND pl.id_lang = ' . (int) $this->context->language->id . ') INNER JOIN ' . _DB_PREFIX_ . 'product p ON a.id_product = p.id_product INNER JOIN ' . _DB_PREFIX_ . 'stock_mvt_reason_lang smrl ON (a.id_mvt_reason = smrl.id_stock_mvt_reason AND smrl.id_lang = ' . (int) $this->context->language->id . ') INNER JOIN ' . _DB_PREFIX_ . 'stock_mvt_reason smr ON a.id_mvt_reason = smr.id_stock_mvt_reason INNER JOIN ' . _DB_PREFIX_ . 'warehouse w ON w.id_warehouse = a.id_warehouse INNER JOIN ' . _DB_PREFIX_ . 'product_attribute pa ON a.id_product_attribute= pa.id_product_attribute INNER JOIN ' . _DB_PREFIX_ . 'product_attribute_combination pac ON pac.id_product_attribute = pa.id_product_attribute INNER JOIN ' . _DB_PREFIX_ . 'attribute atr ON atr.id_attribute= pac.id_attribute INNER JOIN ' . _DB_PREFIX_ . 'attribute_lang al ON (al.id_attribute= pac.id_attribute AND al.id_lang=' . (int) $this->context->language->id . ') INNER JOIN ' . _DB_PREFIX_ . 'attribute_group_lang agl ON (agl.id_attribute_group= atr.id_attribute_group AND agl.id_lang=' . (int) $this->context->language->id . ') INNER JOIN ' . _DB_PREFIX_ . 'erpip_inventory i ON a.id_erpip_inventory = i.id_erpip_inventory'; $this->_where = 'AND i.id_erpip_inventory = ' . $id_container; $this->_order = 'a.id_erpip_inventory_product DESC LIMIT 10'; $this->_group = 'GROUP BY a.id_product_attribute'; // Send values to view $this->tpl_list_vars['containers'] = ErpInventory::getContainers(); $list = parent::renderList(); return $list; }
public static function getTotalStockGap($id_container) { $query = new DbQuery(); $query->select('id_product, id_product_attribute, (qte_after - qte_before) as gap'); $query->from('erpip_inventory_product'); $query->where('id_erpip_inventory = ' . (int) $id_container); $rows = Db::getInstance()->executeS($query); $total = 0; if (!empty($rows)) { foreach ($rows as $row) { $wholesale_price = InventoryProduct::getWholesalePrice($row['id_product'], $row['id_product_attribute']); $total += (int) $row['gap'] * (int) $wholesale_price; } } return $total; }
public function productHandler($product) { if (empty($product['idproduct'])) { $this->errors[] = Tools::displayError($this->l('Error : the id of the product is missing !')); return false; } $inventory_product = new InventoryProduct(); $inventory_product->id_erpip_inventory = self::$id_erpip_inventory_static; $inventory_product->id_product = $product['idproduct']; $inventory_product->id_product_attribute = $product['idproductattribute']; $inventory_product->qte_before = !isset($product['physicalquantity']) || $product['physicalquantity'] == '' ? 0 : $product['physicalquantity']; $inventory_product->qte_after = !isset($product['foundquantity']) || $product['foundquantity'] == '' ? 0 : (int) $product['foundquantity']; $inventory_product->id_warehouse = Tools::isSubmit('id_warehouse') ? (int) Tools::getValue('id_warehouse') : -1; // if not mvt reason chosen => depend of quanities, select increate or decrease if (!isset($product['idreason']) || $product['idreason'] == '') { if ($inventory_product->qte_before <= $inventory_product->qte_after) { $inventory_product->id_mvt_reason = 1; } else { $inventory_product->id_mvt_reason = 2; } } else { $inventory_product->id_mvt_reason = $product['idreason']; } // Gireg: // only treat products that match to stock manager selected : // Products in advanced stock manager if we re in advanced stock manager // Or product in non advanced stock manager, if we are in non advanced stock manager if ($this->advanced_stock_management == StockAvailable::dependsOnStock((int) $product['idproduct'])) { // If record inventory line --> update stock if ($inventory_product->add()) { // if advanced stock manager if ($this->advanced_stock_management == 1) { $stock = new ErpStock(); $stock->id_product = $product['idproduct']; $stock->id_product_attribute = $product['idproductattribute']; $stock->id_warehouse = $this->id_warehouse; $stock->physical_quantity = !isset($product['foundquantity']) || $product['foundquantity'] == '' ? 0 : (int) $product['foundquantity']; $stock->usable_quantity = !isset($product['foundquantity']) || $product['foundquantity'] == '' ? 0 : (int) $product['foundquantity']; // get reference price $price = $stock->getPriceTe(); // if $price is false, we dont have stock for this product. si quantity is lower than stock, set price to 0 if (isset($product['foundquantity']) && (int) $product['foundquantity'] < $product['physicalquantity'] || ($price = false)) { $price = 0; } $stock->price_te = $price; // if we already have a stock line for this production, we update else we insert if ($stock->id = $stock->getStockId()) { $maj_stock = $stock->update(); } else { $maj_stock = $stock->add(); } } else { $maj_stock = StockAvailable::setQuantity($product['idproduct'], $product['idproductattribute'], (int) $product['foundquantity']); if (is_null($maj_stock)) { $maj_stock = true; } } // if update stock ok --> update location if ($maj_stock) { // no stock change if advanced stock inactive if ($this->advanced_stock_management == 1) { require_once _PS_MODULE_DIR_ . 'erpillicopresta/classes/stock/ErpWarehouseProductLocation.php'; $wpl_id = ErpWarehouseProductLocationClass::getWarehouseProductLocationId($product['idproduct'], $product['idproductattribute']); $warehouse_location = new ErpWarehouseProductLocationClass($wpl_id); $warehouse_location->id_product = $product['idproduct']; $warehouse_location->id_product_attribute = $product['idproductattribute']; $warehouse_location->id_warehouse = $this->id_warehouse; /*if ($product['area'] != '--') $warehouse_location->zone = $product['area']; if ($product['subarea'] != '--') $warehouse_location->sous_zone = $product['subarea'];*/ $warehouse_location->location = $product['location']; $warehouse_location->id_warehouse_product_location = $wpl_id; // if update location ok & advanced stock active -> generate stock movement if ($warehouse_location->update()) { //echo 'Maj location OK'; // No stock movement if advanced stock inactive if ($this->advanced_stock_management == 1) { $stock_mvt = new ErpStockMvt(); $stock_mvt->id_stock = $stock->id; $stock_mvt->id_order = 0; $stock_mvt->id_supply_order = 0; // if not mvt reason selected => depend of quantity to increase or decrease if (!isset($product['idreason']) || $product['idreason'] == '') { if ($inventory_product->qte_before <= $inventory_product->qte_after) { $stock_mvt->id_stock_mvt_reason = 1; } else { $stock_mvt->id_stock_mvt_reason = 2; } } else { $stock_mvt->id_stock_mvt_reason = $product['idreason']; } $stock_mvt->id_employee = $this->id_employee; $stock_mvt->employee_firstname = $this->firstname; $stock_mvt->employee_lastname = $this->lastname; $stock_mvt->price_te = $price; $stock_mvt->current_wa = $price; // Récupération du sign (flèche up / down) // Get sign (arrow up/down) if (isset($product['foundquantity']) && ((int) $product['foundquantity'] >= (int) $product['physicalquantity'] || (int) $product['foundquantity'] == 0)) { $stock_mvt->sign = 1; } else { $stock_mvt->sign = -1; } // calculate the quantity movement of stock $foundquantity = !isset($product['foundquantity']) || $product['foundquantity'] == '' ? 0 : (int) $product['foundquantity']; $physicalquantity = !isset($product['physicalquantity']) || $product['physicalquantity'] == '' ? 0 : (int) $product['physicalquantity']; $mvt = abs($foundquantity - $physicalquantity); $stock_mvt->physical_quantity = $mvt; // Synchronise available stock if ($stock_mvt->add(true)) { StockAvailable::synchronize($product['idproduct']); } else { $this->errors[] = Tools::displayError($this->l('Error while inserting stock movement. Please try again.')); } } else { $this->errors[] = Tools::displayError($this->l('No stock movement. You need to activate the advanced stock management in Preference > Products')); } } else { $this->errors[] = Tools::displayError($this->l('Error while updating product location')); } } } else { $this->errors[] = Tools::displayError($this->l('Error while updating stock')); } } else { $this->errors[] = Tools::displayError($this->l('Error while inserting product inventory row')); } } }