* @copyright 2007-2012 PrestaShop SA * @version Release: $Revision: 7307 $ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * International Registered Trademark & Property of PrestaShop SA */ /** * @since 1.5.0 */ class AdminStockManagementControllerCore extends AdminController { public function __construct() { $this->context = Context::getContext(); $this->table = 'product'; $this->className = 'Product'; $this->lang = true; $this->multishop_context = Shop::CONTEXT_ALL; $this->fieldsDisplay = array( 'reference' => array( 'title' => $this->l('Product reference'), 'align' => 'center', 'filter_key' => 'a!reference', 'width' => 200 ), 'ean13' => array( 'title' => $this->l('EAN13'), 'align' => 'center', 'filter_key' => 'a!ean13', 'width' => 100 ), 'upc' => array( 'title' => $this->l('UPC'), 'align' => 'center', 'filter_key' => 'a!upc', 'width' => 100 ), 'name' => array( 'title' => $this->l('Name'), ), 'stock' => array( 'title' => $this->l('Quantity'), 'hint' => $this->l('Sum of quantities for all warehouses'), 'width' => 100, 'orderby' => false, 'filter' => false, 'search' => false, ), ); parent::__construct(); // overrides confirmation messages specifically for this controller $this->_conf = array( 1 => $this->l('The product was successfully added to stock'), 2 => $this->l('The product was successfully removed from the stock'), 3 => $this->l('The transfer was successfully done'), ); } /** * AdminController::renderList() override * @see AdminController::renderList() */ public function renderList() { // sets actions $this->addRowAction('details'); $this->addRowAction('addstock'); $this->addRowAction('removestock'); $this->addRowAction('transferstock'); // no link on list rows $this->list_no_link = true; // inits toolbar $this->toolbar_btn = array(); // overrides query $this->_select = 'a.id_product as id, COUNT(pa.id_product_attribute) as variations'; $this->_join = 'LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa ON (pa.id_product = a.id_product)'; $this->_where = 'AND a.cache_is_pack = 0 AND a.is_virtual = 0'; $this->_group = 'GROUP BY a.id_product'; // displays informations $this->displayInformation($this->l('This interface allows you to manage the stocks of each of your products and their variations.').'
'); $this->displayInformation($this->l('Through this interface, you can increase quantities (add) and decrease quantities (delete) of products for a given warehouse.')); $this->displayInformation($this->l('Furthermore, you can move quantities (transfer) of products between warehouses, or within one warehouse.').'
'); $this->displayInformation($this->l('Note that if you want to increase quantities of multiple products at once, you can use the supply orders tab.').'
'); $this->displayInformation($this->l('Finally, you will be asked to specify the state of the quantity you will add : ')); $this->displayInformation($this->l('usable for sale means that this quantity will be available in shop(s),')); $this->displayInformation($this->l('otherwise it will be considered reserved (i.e. for other purposes).')); return parent::renderList(); } /** * AdminController::renderForm() override * @see AdminController::renderForm() */ public function renderForm() { // gets the product $id_product = (int)Tools::getValue('id_product'); $id_product_attribute = (int)Tools::getValue('id_product_attribute'); // gets warehouses $warehouses_add = Warehouse::getWarehouses(true); $warehouses_remove = Warehouse::getWarehousesByProductId($id_product, $id_product_attribute); // displays warning if no warehouses if (!$warehouses_add) $this->displayWarning($this->l('You have to have Warehouses before adding stock. See Stock/Warehouses')); // gets the currencies $currencies = Currency::getCurrencies(); // switch, in order to display the form corresponding to the current action switch ($this->display) { case 'addstock' : // gets the last stock mvt for this product, so we can display the last unit price te and the last quantity added $last_sm_unit_price_te = $this->l('N/A'); $last_sm_quantity = 0; $last_sm_quantity_is_usable = -1; $last_sm = StockMvt::getLastPositiveStockMvt($id_product, $id_product_attribute); if ($last_sm != false) { $last_sm_currency = new Currency((int)$last_sm['id_currency']); $last_sm_quantity = (int)$last_sm['physical_quantity']; $last_sm_quantity_is_usable = (int)$last_sm['is_usable']; if (Validate::isLoadedObject($last_sm_currency)) $last_sm_unit_price_te = Tools::displayPrice((float)$last_sm['price_te'], $last_sm_currency); } $this->displayInformation($this->l('Note that rolling over the quantity and price fields will give you the details of the last stock movement.')); // fields in the form $this->fields_form[]['form'] = array( 'legend' => array( 'title' => $this->l('Add product to stock'), 'image' => '../img/admin/add_stock.png' ), 'input' => array( array( 'type' => 'hidden', 'name' => 'is_post', ), array( 'type' => 'hidden', 'name' => 'id_product', ), array( 'type' => 'hidden', 'name' => 'id_product_attribute', ), array( 'type' => 'hidden', 'name' => 'check', ), array( 'type' => 'text', 'label' => $this->l('Product reference:'), 'name' => 'reference', 'size' => 30, 'disabled' => true, ), array( 'type' => 'text', 'label' => $this->l('EAN13:'), 'name' => 'ean13', 'size' => 15, 'disabled' => true, ), array( 'type' => 'text', 'label' => $this->l('UPC:'), 'name' => 'upc', 'size' => 15, 'disabled' => true, ), array( 'type' => 'text', 'label' => $this->l('Name :'), 'name' => 'name', 'size' => 75, 'disabled' => true, ), array( 'type' => 'text', 'label' => $this->l('Quantity to add:'), 'name' => 'quantity', 'size' => 10, 'maxlength' => 6, 'required' => true, 'desc' => $this->l('Physical quantity to add'), 'hint' => sprintf( $this->l('Last physical quantity added : %s (%s)'), ($last_sm_quantity > 0 ? $last_sm_quantity : $this->l('N/A')), ($last_sm_quantity > 0 ? ($last_sm_quantity_is_usable >= 0 ? $this->l('usable') : $this->l('not usable')) : $this->l('N/A'))), ), array( 'type' => 'radio', 'label' => $this->l('Usable for sale?:'), 'name' => 'usable', 'required' => true, 'class' => 't', 'is_bool' => true, 'values' => array( array( 'id' => 'active_on', 'value' => 1, 'label' => $this->l('Enabled') ), array( 'id' => 'active_off', 'value' => 0, 'label' => $this->l('Disabled') ) ), 'desc' => $this->l('Is this quantity usable for sale on shops, or reserved in the warehouse for other purposes?') ), array( 'type' => 'select', 'label' => $this->l('Warehouse:'), 'name' => 'id_warehouse', 'required' => true, 'options' => array( 'query' => $warehouses_add, 'id' => 'id_warehouse', 'name' => 'name' ), 'desc' => $this->l('Select the warehouse where you want to add the product into') ), array( 'type' => 'text', 'label' => $this->l('Unit price (TE):'), 'name' => 'price', 'required' => true, 'size' => 10, 'maxlength' => 10, 'desc' => $this->l('Unit purchase price or unit manufacturing cost for this product, tax excluded'), 'hint' => sprintf($this->l('Last unit price (te) : %s'), $last_sm_unit_price_te), ), array( 'type' => 'select', 'label' => $this->l('Currency:'), 'name' => 'id_currency', 'required' => true, 'options' => array( 'query' => $currencies, 'id' => 'id_currency', 'name' => 'name' ), 'desc' => $this->l('The currency associated to the product unit price'), ), array( 'type' => 'select', 'label' => $this->l('Label :'), 'name' => 'id_stock_mvt_reason', 'required' => true, 'options' => array( 'query' => StockMvtReason::getStockMvtReasonsWithFilter($this->context->language->id, array(Configuration::get('PS_STOCK_MVT_TRANSFER_TO')), 1), 'id' => 'id_stock_mvt_reason', 'name' => 'name' ), 'desc' => $this->l('Label used in stock movements'), ), ), 'submit' => array( 'title' => $this->l(' Add to stock '), 'class' => 'button' ) ); $this->fields_value['usable'] = 1; break; case 'removestock' : $this->fields_form[]['form'] = array( 'legend' => array( 'title' => $this->l('Remove product from stock'), 'image' => '../img/admin/remove_stock.png' ), 'input' => array( array( 'type' => 'hidden', 'name' => 'is_post', ), array( 'type' => 'hidden', 'name' => 'id_product', ), array( 'type' => 'hidden', 'name' => 'id_product_attribute', ), array( 'type' => 'hidden', 'name' => 'check', ), array( 'type' => 'text', 'label' => $this->l('Product reference:'), 'name' => 'reference', 'size' => 30, 'disabled' => true, ), array( 'type' => 'text', 'label' => $this->l('EAN13:'), 'name' => 'ean13', 'size' => 15, 'disabled' => true, ), array( 'type' => 'text', 'label' => $this->l('Name :'), 'name' => 'name', 'size' => 75, 'disabled' => true, ), array( 'type' => 'text', 'label' => $this->l('Quantity to remove:'), 'name' => 'quantity', 'size' => 10, 'maxlength' => 6, 'required' => true, 'desc' => $this->l('Physical quantity to remove') ), array( 'type' => 'radio', 'label' => $this->l('Usable for sale:'), 'name' => 'usable', 'required' => true, 'class' => 't', 'is_bool' => true, 'values' => array( array( 'id' => 'active_on', 'value' => 1, 'label' => $this->l('Enabled') ), array( 'id' => 'active_off', 'value' => 0, 'label' => $this->l('Disabled') ) ), 'desc' => $this->l('Do you want to remove this quantity from the usable quantity(yes) or the physical quantity(no)?') ), array( 'type' => 'select', 'label' => $this->l('Warehouse:'), 'name' => 'id_warehouse', 'required' => true, 'options' => array( 'query' => $warehouses_remove, 'id' => 'id_warehouse', 'name' => 'name' ), 'desc' => $this->l('Select the warehouse from where you want to remove the product') ), array( 'type' => 'select', 'label' => $this->l('Label :'), 'name' => 'id_stock_mvt_reason', 'required' => true, 'options' => array( 'query' => StockMvtReason::getStockMvtReasonsWithFilter($this->context->language->id, array(Configuration::get('PS_STOCK_MVT_TRANSFER_FROM')), -1), 'id' => 'id_stock_mvt_reason', 'name' => 'name' ), 'desc' => $this->l('Label used in stock movements'), ), ), 'submit' => array( 'title' => $this->l(' Remove from stock '), 'class' => 'button' ) ); break; case 'transferstock' : $this->fields_form[]['form'] = array( 'legend' => array( 'title' => $this->l('Transfert product from warehouse to another'), 'image' => '../img/admin/transfer_stock.png' ), 'input' => array( array( 'type' => 'hidden', 'name' => 'is_post', ), array( 'type' => 'hidden', 'name' => 'id_product', ), array( 'type' => 'hidden', 'name' => 'id_product_attribute', ), array( 'type' => 'hidden', 'name' => 'check', ), array( 'type' => 'text', 'label' => $this->l('Product reference:'), 'name' => 'reference', 'size' => 30, 'disabled' => true, ), array( 'type' => 'text', 'label' => $this->l('EAN13:'), 'name' => 'ean13', 'size' => 15, 'disabled' => true, ), array( 'type' => 'text', 'label' => $this->l('Name :'), 'name' => 'name', 'size' => 75, 'disabled' => true, ), array( 'type' => 'text', 'label' => $this->l('Quantity to transfer:'), 'name' => 'quantity', 'size' => 10, 'maxlength' => 6, 'required' => true, 'desc' => $this->l('Physical quantity to transfer.') ), array( 'type' => 'select', 'label' => $this->l('Source Warehouse:'), 'name' => 'id_warehouse_from', 'required' => true, 'options' => array( 'query' => $warehouses_remove, 'id' => 'id_warehouse', 'name' => 'name' ), 'desc' => $this->l('Select the warehouse want to transfer the product from.') ), array( 'type' => 'radio', 'label' => $this->l('Usable for sale in source warehouse ?'), 'name' => 'usable_from', 'required' => true, 'class' => 't', 'is_bool' => true, 'values' => array( array( 'id' => 'active_on', 'value' => 1, 'label' => $this->l('Enabled') ), array( 'id' => 'active_off', 'value' => 0, 'label' => $this->l('Disabled') ) ), 'desc' => $this->l('Is this a usable quantity for sale?') ), array( 'type' => 'select', 'label' => $this->l('Destination Warehouse:'), 'name' => 'id_warehouse_to', 'required' => true, 'options' => array( 'query' => $warehouses_add, 'id' => 'id_warehouse', 'name' => 'name' ), 'desc' => $this->l('Select the warehouse to transfer the product to.') ), array( 'type' => 'radio', 'label' => $this->l('Usable for sale in destination warehouse ?'), 'name' => 'usable_to', 'required' => true, 'class' => 't', 'is_bool' => true, 'values' => array( array( 'id' => 'active_on', 'value' => 1, 'label' => $this->l('Enabled') ), array( 'id' => 'active_off', 'value' => 0, 'label' => $this->l('Disabled') ) ), 'desc' => $this->l('Do you want it to be usable for sale?') ), ), 'submit' => array( 'title' => $this->l(' Transfer '), 'class' => 'button' ) ); break; } $this->initToolbar(); } /** * AdminController::postProcess() override * @see AdminController::postProcess() */ public function postProcess() { parent::postProcess(); // Checks access if (Tools::isSubmit('addStock') && !($this->tabAccess['add'] === '1')) $this->errors[] = Tools::displayError('You do not have the required permission to add stock.'); if (Tools::isSubmit('removeStock') && !($this->tabAccess['delete'] === '1')) $this->errors[] = Tools::displayError('You do not have the required permission to delete stock.'); if (Tools::isSubmit('transferStock') && !($this->tabAccess['edit'] === '1')) $this->errors[] = Tools::displayError('You do not have the required permission to transfer stock.'); if (count($this->errors)) return; // Global checks when add / remove / transfer product if ((Tools::isSubmit('addstock') || Tools::isSubmit('removestock') || Tools::isSubmit('transferstock') ) && Tools::isSubmit('is_post')) { // get product ID $id_product = (int)Tools::getValue('id_product', 0); if ($id_product <= 0) $this->errors[] = Tools::displayError('The selected product is not valid.'); // get product_attribute ID $id_product_attribute = (int)Tools::getValue('id_product_attribute', 0); // check the product hash $check = Tools::getValue('check', ''); $check_valid = md5(_COOKIE_KEY_.$id_product.$id_product_attribute); if ($check != $check_valid) $this->errors[] = Tools::displayError('The selected product is not valid.'); // get quantity and check that the post value is really an integer // If it's not, we have to do nothing. $quantity = Tools::getValue('quantity', 0); if (!is_numeric($quantity) || (int)$quantity <= 0) $this->errors[] = Tools::displayError('The quantity value is not valid.'); $quantity = (int)$quantity; $token = Tools::getValue('token') ? Tools::getValue('token') : $this->token; $redirect = self::$currentIndex.'&token='.$token; } // Global checks when add / remove product if ((Tools::isSubmit('addstock') || Tools::isSubmit('removestock') ) && Tools::isSubmit('is_post')) { // get warehouse id $id_warehouse = (int)Tools::getValue('id_warehouse', 0); if ($id_warehouse <= 0 || !Warehouse::exists($id_warehouse)) $this->errors[] = Tools::displayError('The selected warehouse is not valid.'); // get stock movement reason id $id_stock_mvt_reason = (int)Tools::getValue('id_stock_mvt_reason', 0); if ($id_stock_mvt_reason <= 0 || !StockMvtReason::exists($id_stock_mvt_reason)) $this->errors[] = Tools::displayError('The reason is not valid.'); // get usable flag $usable = Tools::getValue('usable', null); if (is_null($usable)) $this->errors[] = Tools::displayError('You have to specify if the product quantity is usable for sale on shops.'); $usable = (bool)$usable; } if (Tools::isSubmit('addstock') && Tools::isSubmit('is_post')) { // get product unit price $price = str_replace(',', '.', Tools::getValue('price', 0)); if (!is_numeric($price)) $this->errors[] = Tools::displayError('The product price is not valid.'); $price = round(floatval($price), 6); // get product unit price currency id $id_currency = (int)Tools::getValue('id_currency', 0); if ($id_currency <= 0 || ( !($result = Currency::getCurrency($id_currency)) || empty($result) )) $this->errors[] = Tools::displayError('The selected currency is not valid.'); // if all is ok, add stock if (count($this->errors) == 0) { $warehouse = new Warehouse($id_warehouse); // convert price to warehouse currency if needed if ($id_currency != $warehouse->id_currency) { // First convert price to the default currency $price_converted_to_default_currency = Tools::convertPrice($price, $id_currency, false); // Convert the new price from default currency to needed currency $price = Tools::convertPrice($price_converted_to_default_currency, $warehouse->id_currency, true); } // add stock $stock_manager = StockManagerFactory::getManager(); if ($stock_manager->addProduct($id_product, $id_product_attribute, $warehouse, $quantity, $id_stock_mvt_reason, $price, $usable)) { StockAvailable::synchronize($id_product); if (Tools::isSubmit('addstockAndStay')) { $redirect = self::$currentIndex.'&id_product='.(int)$id_product; if ($id_product_attribute) $redirect .= '&id_product_attribute='.(int)$id_product_attribute; $redirect .= '&addstock&token='.$token; } Tools::redirectAdmin($redirect.'&conf=1'); } else $this->errors[] = Tools::displayError('An error occured. No stock was added.'); } } if (Tools::isSubmit('removestock') && Tools::isSubmit('is_post')) { // if all is ok, remove stock if (count($this->errors) == 0) { $warehouse = new Warehouse($id_warehouse); // remove stock $stock_manager = StockManagerFactory::getManager(); $removed_products = $stock_manager->removeProduct($id_product, $id_product_attribute, $warehouse, $quantity, $id_stock_mvt_reason, $usable); if (count($removed_products) > 0) { StockAvailable::synchronize($id_product); Tools::redirectAdmin($redirect.'&conf=2'); } else $this->errors[] = Tools::displayError('It is not possible to remove the specified quantity or an error occured. No stock was removed.'); } } if (Tools::isSubmit('transferstock') && Tools::isSubmit('is_post')) { // get source warehouse id $id_warehouse_from = (int)Tools::getValue('id_warehouse_from', 0); if ($id_warehouse_from <= 0 || !Warehouse::exists($id_warehouse_from)) $this->errors[] = Tools::displayError('The source warehouse is not valid.'); // get destination warehouse id $id_warehouse_to = (int)Tools::getValue('id_warehouse_to', 0); if ($id_warehouse_to <= 0 || !Warehouse::exists($id_warehouse_to)) $this->errors[] = Tools::displayError('The destination warehouse is not valid.'); // get usable flag for source warehouse $usable_from = Tools::getValue('usable_from', null); if (is_null($usable_from)) $this->errors[] = Tools::displayError('You have to specify if the product quantity is usable for sale on shops in source warehouse.'); $usable_from = (bool)$usable_from; // get usable flag for destination warehouse $usable_to = Tools::getValue('usable_to', null); if (is_null($usable_to)) $this->errors[] = Tools::displayError('You have to specify if the product quantity is usable for sale on shops in destination warehouse.'); $usable_to = (bool)$usable_to; // if all is ok, transfer stock if (count($this->errors) == 0) { // transfer stock $stock_manager = StockManagerFactory::getManager(); $is_transfer = $stock_manager->transferBetweenWarehouses( $id_product, $id_product_attribute, $quantity, $id_warehouse_from, $id_warehouse_to, $usable_from, $usable_to ); if ($is_transfer) Tools::redirectAdmin($redirect.'&conf=3'); else $this->errors[] = Tools::displayError('It is not possible to transfer the specified quantity, or an error occured. No stock was transfered.'); } } } /** * assign default action in toolbar_btn smarty var, if they are not set. * uses override to specifically add, modify or remove items * */ public function initToolbar() { switch ($this->display) { case 'addstock': $this->toolbar_btn['save-and-stay'] = array( 'short' => 'SaveAndStay', 'href' => '#', 'desc' => $this->l('Save and stay'), ); case 'removestock': case 'transferstock': $this->toolbar_btn['save'] = array( 'href' => '#', 'desc' => $this->l('Save') ); // Default cancel button - like old back link $back = Tools::safeOutput(Tools::getValue('back', '')); if (empty($back)) $back = self::$currentIndex.'&token='.$this->token; $this->toolbar_btn['cancel'] = array( 'href' => $back, 'desc' => $this->l('Cancel') ); break; default: parent::initToolbar(); } } /** * AdminController::init() override * @see AdminController::init() */ public function init() { parent::init(); if (Tools::isSubmit('addstock')) { $this->display = 'addstock'; $this->toolbar_title = $this->l('Stock : Add product'); } if (Tools::isSubmit('removestock')) { $this->display = 'removestock'; $this->toolbar_title = $this->l('Stock : Remove product'); } if (Tools::isSubmit('transferstock')) { $this->display = 'transferstock'; $this->toolbar_title = $this->l('Stock : Transfer product'); } } /** * method call when ajax request is made with the details row action * @see AdminController::postProcess() */ public function ajaxProcess() { // test if an id is submit if (Tools::isSubmit('id')) { // override attributes $this->identifier = 'id_product_attribute'; $this->display = 'list'; $this->lang = false; $this->addRowAction('addstock'); $this->addRowAction('removestock'); $this->addRowAction('transferstock'); // get current lang id $lang_id = (int)$this->context->language->id; // Get product id $product_id = (int)Tools::getValue('id'); // Load product attributes with sql override $this->table = 'product_attribute'; $this->_select = 'a.id_product_attribute as id, a.id_product, a.reference, a.ean13, a.upc'; $this->_where = 'AND a.id_product = '.$product_id; $this->_group = 'GROUP BY a.id_product_attribute'; // get list and force no limit clause in the request $this->getList($this->context->language->id, null, null, 0, false); // Render list $helper = new HelperList(); $helper->bulk_actions = array(); $helper->toolbar_fix = $this->toolbar_fix; $helper->show_toolbar = false; $helper->actions = $this->actions; $helper->list_skip_actions = $this->list_skip_actions; $helper->no_link = true; $helper->shopLinkType = ''; $helper->identifier = $this->identifier; // Force render - no filter, form, js, sorting ... $helper->simple_header = true; $content = $helper->generateList($this->_list, $this->fieldsDisplay); echo Tools::jsonEncode(array('use_parent_structure' => false, 'data' => $content)); } die; } /** * AdminController::getList() override * @see AdminController::getList() */ public function getList($id_lang, $order_by = null, $order_way = null, $start = 0, $limit = null, $id_lang_shop = false) { parent::getList($id_lang, $order_by, $order_way, $start, $limit, $id_lang_shop); if ($this->display == 'list') { // Check each row to see if there are combinations and get the correct action in consequence $nb_items = count($this->_list); for ($i = 0; $i < $nb_items; $i++) { $item = &$this->_list[$i]; // if it's an ajax request we have to consider manipulating a product variation if ($this->ajax == '1') { $item['name'] = Product::getProductName($item['id_product'], $item['id']); // no details for this row $this->addRowActionSkipList('details', array($item['id'])); // specify actions in function of stock $this->skipActionByStock($item, true); } // If current product has variations else if ((int)$item['variations'] > 0) { // we have to desactivate stock actions on current row $this->addRowActionSkipList('addstock', array($item['id'])); $this->addRowActionSkipList('removestock', array($item['id'])); $this->addRowActionSkipList('transferstock', array($item['id'])); // does not display these informaions because this product has combinations $item['reference'] = '--'; $item['ean13'] = '--'; $item['upc'] = '--'; } else { //there are no variations of current product, so we don't want to show details action $this->addRowActionSkipList('details', array($item['id'])); // specify actions in function of stock $this->skipActionByStock($item, false); } // Checks access if (!($this->tabAccess['add'] === '1')) $this->addRowActionSkipList('addstock', array($item['id'])); if (!($this->tabAccess['delete'] === '1')) $this->addRowActionSkipList('removestock', array($item['id'])); if (!($this->tabAccess['edit'] === '1')) $this->addRowActionSkipList('transferstock', array($item['id'])); } } } /** * Check stock for a given product or product attribute * and manage available actions in consequence * * @param array $item reference to the current item * @param bool $is_product_attribute specify if it's a product or a product variation */ protected function skipActionByStock(&$item, $is_product_variation = false) { $stock_manager = StockManagerFactory::getManager(); //get stocks for this product if ($is_product_variation) $stock = $stock_manager->getProductPhysicalQuantities($item['id_product'], $item['id']); else $stock = $stock_manager->getProductPhysicalQuantities($item['id'], 0); //affects stock to the list for display $item['stock'] = $stock; if ($stock <= 0) { //there is no stock, we can only add stock $this->addRowActionSkipList('removestock', array($item['id'])); $this->addRowActionSkipList('transferstock', array($item['id'])); } } /** * AdminController::initContent() override * @see AdminController::initContent() */ public function initContent() { // Manage the add stock form if ($this->display == 'addstock' || $this->display == 'removestock' || $this->display == 'transferstock') { if (Tools::isSubmit('id_product') || Tools::isSubmit('id_product_attribute')) { // get id product and product attribute if possible $id_product = (int)Tools::getValue('id_product', 0); $id_product_attribute = (int)Tools::getValue('id_product_attribute', 0); $product_is_valid = false; $is_pack = false; $is_virtual = false; $lang_id = $this->context->language->id; // try to load product attribute first if ($id_product_attribute > 0) { // try to load product attribute $combination = new Combination($id_product_attribute); if (Validate::isLoadedObject($combination)) { $product_is_valid = true; $id_product = $combination->id_product; $reference = $combination->reference; $ean13 = $combination->ean13; $upc = $combination->upc; $manufacturer_reference = $combination->supplier_reference; // get the full name for this combination $query = new DbQuery(); $query->select('IFNULL(CONCAT(pl.`name`, \' : \', GROUP_CONCAT(agl.`name`, \' - \', al.`name` SEPARATOR \', \')),pl.`name`) as name'); $query->from('product_attribute', 'a'); $query->join('INNER JOIN '._DB_PREFIX_.'product_lang pl ON (pl.`id_product` = a.`id_product` AND pl.`id_lang` = '.$lang_id.') LEFT JOIN '._DB_PREFIX_.'product_attribute_combination pac ON (pac.`id_product_attribute` = a.`id_product_attribute`) LEFT JOIN '._DB_PREFIX_.'attribute atr ON (atr.`id_attribute` = pac.`id_attribute`) LEFT JOIN '._DB_PREFIX_.'attribute_lang al ON (al.`id_attribute` = atr.`id_attribute` AND al.`id_lang` = '.$lang_id.') LEFT JOIN '._DB_PREFIX_.'attribute_group_lang agl ON (agl.`id_attribute_group` = atr.`id_attribute_group` AND agl.`id_lang` = '.$lang_id.')' ); $query->where('a.`id_product_attribute` = '.$id_product_attribute); $name = Db::getInstance()->getValue($query); } } // try to load a simple product else { $product = new Product($id_product, false, $lang_id); if (is_int($product->id)) { $product_is_valid = true; $reference = $product->reference; $ean13 = $product->ean13; $upc = $product->upc; $name = $product->name; $manufacturer_reference = $product->supplier_reference; $is_pack = $product->cache_is_pack; $is_virtual = $product->is_virtual; } } if ($product_is_valid === true && $is_pack == false && $is_virtual == false) { // init form $this->renderForm(); $this->getlanguages(); $helper = new HelperForm(); // Check if form template has been overriden if (file_exists($this->context->smarty->getTemplateDir(0).'/'.$this->tpl_folder.'form.tpl')) $helper->tpl = $this->tpl_folder.'form.tpl'; $this->setHelperDisplay($helper); $helper->submit_action = $this->display; $helper->id = null; // no display standard hidden field in the form $helper->languages = $this->_languages; $helper->default_form_language = $this->default_form_language; $helper->allow_employee_form_lang = $this->allow_employee_form_lang; $helper->fields_value = array( 'id_product' => $id_product, 'id_product_attribute' => $id_product_attribute, 'reference' => $reference, 'manufacturer_reference' => $manufacturer_reference, 'name' => $name, 'ean13' => $ean13, 'upc' => $upc, 'check' => md5(_COOKIE_KEY_.$id_product.$id_product_attribute), 'quantity' => Tools::getValue('quantity', ''), 'id_warehouse' => Tools::getValue('id_warehouse', ''), 'usable' => ($this->fields_value['usable'] ? $this->fields_value['usable'] : Tools::getValue('usable', '')), 'price' => Tools::getValue('price', ''), 'id_currency' => Tools::getValue('id_currency', ''), 'id_stock_mvt_reason' => Tools::getValue('id_stock_mvt_reason', ''), 'is_post' => 1, ); if ($this->display == 'transferstock') { $helper->fields_value['id_warehouse_from'] = Tools::getValue('id_warehouse_from', ''); $helper->fields_value['id_warehouse_to'] = Tools::getValue('id_warehouse_to', ''); $helper->fields_value['usable_from'] = Tools::getValue('usable_from', ''); $helper->fields_value['usable_to'] = Tools::getValue('usable_to', ''); } $this->content .= $helper->generateForm($this->fields_form); $this->context->smarty->assign(array( 'content' => $this->content )); } else $this->errors[] = Tools::displayError('The specified product is not valid'); } } else { $this->display = 'list'; parent::initContent(); } } /** * Display addstock action link * @param string $token the token to add to the link * @param int $id the identifier to add to the link * @return string */ public function displayAddstockLink($token = null, $id) { if (!array_key_exists('AddStock', self::$cache_lang)) self::$cache_lang['AddStock'] = $this->l('Add stock'); $this->context->smarty->assign(array( 'href' => self::$currentIndex. '&'.$this->identifier.'='.$id. '&addstock&token='.($token != null ? $token : $this->token), 'action' => self::$cache_lang['AddStock'], )); return $this->context->smarty->fetch('helpers/list/list_action_addstock.tpl'); } /** * Display removestock action link * @param string $token the token to add to the link * @param int $id the identifier to add to the link * @return string */ public function displayRemovestockLink($token = null, $id) { if (!array_key_exists('RemoveStock', self::$cache_lang)) self::$cache_lang['RemoveStock'] = $this->l('Remove stock'); $this->context->smarty->assign(array( 'href' => self::$currentIndex. '&'.$this->identifier.'='.$id. '&removestock&token='.($token != null ? $token : $this->token), 'action' => self::$cache_lang['RemoveStock'], )); return $this->context->smarty->fetch('helpers/list/list_action_removestock.tpl'); } /** * Display transferstock action link * @param string $token the token to add to the link * @param int $id the identifier to add to the link * @return string */ public function displayTransferstockLink($token = null, $id) { if (!array_key_exists('TransferStock', self::$cache_lang)) self::$cache_lang['TransferStock'] = $this->l('Transfer stock'); $this->context->smarty->assign(array( 'href' => self::$currentIndex. '&'.$this->identifier.'='.$id. '&transferstock&token='.($token != null ? $token : $this->token), 'action' => self::$cache_lang['TransferStock'], )); return $this->context->smarty->fetch('helpers/list/list_action_transferstock.tpl'); } }