/** * For a given {product, product attribute} gets warehouse list * * @param int $id_product ID of the product * @param int $id_product_attribute Optional, uses 0 if this product does not have attributes * @param int $id_shop Optional, ID of the shop. Uses the context shop id (@see Context::shop) * @return array Warehouses (ID, reference/name concatenated) */ public static function getProductWarehouseList($id_product, $id_product_attribute = 0, $id_shop = null) { // if it's a pack, returns warehouses if and only if some products use the advanced stock management if (Pack::isPack($id_product)) { $warehouses = Warehouse::getPackWarehouses($id_product); $res = array(); foreach ($warehouses as $warehouse) { $res[]['id_warehouse'] = $warehouse; } return $res; } $share_stock = false; if ($id_shop === null) { if (Shop::getContext() == Shop::CONTEXT_GROUP) { $shop_group = Shop::getContextShopGroup(); } else { $shop_group = Context::getContext()->shop->getGroup(); $id_shop = (int) Context::getContext()->shop->id; } $share_stock = $shop_group->share_stock; } else { $shop_group = Shop::getGroupFromShop($id_shop); $share_stock = $shop_group['share_stock']; } if ($share_stock) { $ids_shop = Shop::getShops(true, (int) $shop_group->id, true); } else { $ids_shop = array((int) $id_shop); } $query = new DbQuery(); $query->select('wpl.id_warehouse, CONCAT(w.reference, " - ", w.name) as name'); $query->from('warehouse_product_location', 'wpl'); $query->innerJoin('warehouse_shop', 'ws', 'ws.id_warehouse = wpl.id_warehouse AND id_shop IN (' . implode(',', array_map('intval', $ids_shop)) . ')'); $query->innerJoin('warehouse', 'w', 'ws.id_warehouse = w.id_warehouse'); $query->where('id_product = ' . (int) $id_product); $query->where('id_product_attribute = ' . (int) $id_product_attribute); $query->where('w.deleted = 0'); $query->groupBy('wpl.id_warehouse'); return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($query); }
/** * @see StockManagerInterface::removeProduct() * * @param int $id_product * @param int|null $id_product_attribute * @param Warehouse $warehouse * @param int $quantity * @param int $id_stock_mvt_reason * @param bool $is_usable * @param int|null $id_order * @param int $ignore_pack * @param Employee|null $employee * * @return array * @throws PrestaShopException */ public function removeProduct($id_product, $id_product_attribute = null, Warehouse $warehouse, $quantity, $id_stock_mvt_reason, $is_usable = true, $id_order = null, $ignore_pack = 0, $employee = null) { $return = array(); if (!Validate::isLoadedObject($warehouse) || !$quantity || !$id_product) { return $return; } if (!StockMvtReason::exists($id_stock_mvt_reason)) { $id_stock_mvt_reason = Configuration::get('PS_STOCK_MVT_DEC_REASON_DEFAULT'); } $context = Context::getContext(); // Special case of a pack if (Pack::isPack((int) $id_product) && !$ignore_pack) { if (Validate::isLoadedObject($product = new Product((int) $id_product))) { // Gets items if ($product->pack_stock_type == 1 || $product->pack_stock_type == 2 || $product->pack_stock_type == 3 && Configuration::get('PS_PACK_STOCK_TYPE') > 0) { $products_pack = Pack::getItems((int) $id_product, (int) Configuration::get('PS_LANG_DEFAULT')); // Foreach item foreach ($products_pack as $product_pack) { if ($product_pack->advanced_stock_management == 1) { $product_warehouses = Warehouse::getProductWarehouseList($product_pack->id, $product_pack->id_pack_product_attribute); $warehouse_stock_found = false; foreach ($product_warehouses as $product_warehouse) { if (!$warehouse_stock_found) { if (Warehouse::exists($product_warehouse['id_warehouse'])) { $current_warehouse = new Warehouse($product_warehouse['id_warehouse']); $return[] = $this->removeProduct($product_pack->id, $product_pack->id_pack_product_attribute, $current_warehouse, $product_pack->pack_quantity * $quantity, $id_stock_mvt_reason, $is_usable, $id_order); // The product was found on this warehouse. Stop the stock searching. $warehouse_stock_found = !empty($return[count($return) - 1]); } } } } } } if ($product->pack_stock_type == 0 || $product->pack_stock_type == 2 || $product->pack_stock_type == 3 && (Configuration::get('PS_PACK_STOCK_TYPE') == 0 || Configuration::get('PS_PACK_STOCK_TYPE') == 2)) { $return = array_merge($return, $this->removeProduct($id_product, $id_product_attribute, $warehouse, $quantity, $id_stock_mvt_reason, $is_usable, $id_order, 1)); } } else { return false; } } else { // gets total quantities in stock for the current product $physical_quantity_in_stock = (int) $this->getProductPhysicalQuantities($id_product, $id_product_attribute, array($warehouse->id), false); $usable_quantity_in_stock = (int) $this->getProductPhysicalQuantities($id_product, $id_product_attribute, array($warehouse->id), true); // check quantity if we want to decrement unusable quantity if (!$is_usable) { $quantity_in_stock = $physical_quantity_in_stock - $usable_quantity_in_stock; } else { $quantity_in_stock = $usable_quantity_in_stock; } // checks if it's possible to remove the given quantity if ($quantity_in_stock < $quantity) { return $return; } $stock_collection = $this->getStockCollection($id_product, $id_product_attribute, $warehouse->id); $stock_collection->getAll(); // check if the collection is loaded if (count($stock_collection) <= 0) { return $return; } $stock_history_qty_available = array(); $mvt_params = array(); $stock_params = array(); $quantity_to_decrement_by_stock = array(); $global_quantity_to_decrement = $quantity; // switch on MANAGEMENT_TYPE switch ($warehouse->management_type) { // case CUMP mode case 'WA': /** @var Stock $stock */ // There is one and only one stock for a given product in a warehouse in this mode $stock = $stock_collection->current(); $mvt_params = array('id_stock' => $stock->id, 'physical_quantity' => $quantity, 'id_stock_mvt_reason' => $id_stock_mvt_reason, 'id_order' => $id_order, 'price_te' => $stock->price_te, 'last_wa' => $stock->price_te, 'current_wa' => $stock->price_te, 'id_employee' => (int) $context->employee->id ? (int) $context->employee->id : $employee->id, 'employee_firstname' => $context->employee->firstname ? $context->employee->firstname : $employee->firstname, 'employee_lastname' => $context->employee->lastname ? $context->employee->lastname : $employee->lastname, 'sign' => -1); $stock_params = array('physical_quantity' => $stock->physical_quantity - $quantity, 'usable_quantity' => $is_usable ? $stock->usable_quantity - $quantity : $stock->usable_quantity); // saves stock in warehouse $stock->hydrate($stock_params); $stock->update(); // saves stock mvt $stock_mvt = new StockMvt(); $stock_mvt->hydrate($mvt_params); $stock_mvt->save(); $return[$stock->id]['quantity'] = $quantity; $return[$stock->id]['price_te'] = $stock->price_te; break; case 'LIFO': case 'FIFO': // for each stock, parse its mvts history to calculate the quantities left for each positive mvt, // according to the instant available quantities for this stock foreach ($stock_collection as $stock) { /** @var Stock $stock */ $left_quantity_to_check = $stock->physical_quantity; if ($left_quantity_to_check <= 0) { continue; } $resource = Db::getInstance(_PS_USE_SQL_SLAVE_)->query(' SELECT sm.`id_stock_mvt`, sm.`date_add`, sm.`physical_quantity`, IF ((sm2.`physical_quantity` is null), sm.`physical_quantity`, (sm.`physical_quantity` - SUM(sm2.`physical_quantity`))) as qty FROM `' . _DB_PREFIX_ . 'stock_mvt` sm LEFT JOIN `' . _DB_PREFIX_ . 'stock_mvt` sm2 ON sm2.`referer` = sm.`id_stock_mvt` WHERE sm.`sign` = 1 AND sm.`id_stock` = ' . (int) $stock->id . ' GROUP BY sm.`id_stock_mvt` ORDER BY sm.`date_add` DESC'); while ($row = Db::getInstance()->nextRow($resource)) { // break - in FIFO mode, we have to retreive the oldest positive mvts for which there are left quantities if ($warehouse->management_type == 'FIFO') { if ($row['qty'] == 0) { break; } } // converts date to timestamp $date = new DateTime($row['date_add']); $timestamp = $date->format('U'); // history of the mvt $stock_history_qty_available[$timestamp] = array('id_stock' => $stock->id, 'id_stock_mvt' => (int) $row['id_stock_mvt'], 'qty' => (int) $row['qty']); // break - in LIFO mode, checks only the necessary history to handle the global quantity for the current stock if ($warehouse->management_type == 'LIFO') { $left_quantity_to_check -= (int) $row['qty']; if ($left_quantity_to_check <= 0) { break; } } } } if ($warehouse->management_type == 'LIFO') { // orders stock history by timestamp to get newest history first krsort($stock_history_qty_available); } else { // orders stock history by timestamp to get oldest history first ksort($stock_history_qty_available); } // checks each stock to manage the real quantity to decrement for each of them foreach ($stock_history_qty_available as $entry) { if ($entry['qty'] >= $global_quantity_to_decrement) { $quantity_to_decrement_by_stock[$entry['id_stock']][$entry['id_stock_mvt']] = $global_quantity_to_decrement; $global_quantity_to_decrement = 0; } else { $quantity_to_decrement_by_stock[$entry['id_stock']][$entry['id_stock_mvt']] = $entry['qty']; $global_quantity_to_decrement -= $entry['qty']; } if ($global_quantity_to_decrement <= 0) { break; } } // for each stock, decrements it and logs the mvts foreach ($stock_collection as $stock) { if (array_key_exists($stock->id, $quantity_to_decrement_by_stock) && is_array($quantity_to_decrement_by_stock[$stock->id])) { $total_quantity_for_current_stock = 0; foreach ($quantity_to_decrement_by_stock[$stock->id] as $id_mvt_referrer => $qte) { $mvt_params = array('id_stock' => $stock->id, 'physical_quantity' => $qte, 'id_stock_mvt_reason' => $id_stock_mvt_reason, 'id_order' => $id_order, 'price_te' => $stock->price_te, 'sign' => -1, 'referer' => $id_mvt_referrer, 'id_employee' => (int) $context->employee->id ? (int) $context->employee->id : $employee->id); // saves stock mvt $stock_mvt = new StockMvt(); $stock_mvt->hydrate($mvt_params); $stock_mvt->save(); $total_quantity_for_current_stock += $qte; } $stock_params = array('physical_quantity' => $stock->physical_quantity - $total_quantity_for_current_stock, 'usable_quantity' => $is_usable ? $stock->usable_quantity - $total_quantity_for_current_stock : $stock->usable_quantity); $return[$stock->id]['quantity'] = $total_quantity_for_current_stock; $return[$stock->id]['price_te'] = $stock->price_te; // saves stock in warehouse $stock->hydrate($stock_params); $stock->update(); } } break; } if (Pack::isPacked($id_product, $id_product_attribute)) { $packs = Pack::getPacksContainingItem($id_product, $id_product_attribute, (int) Configuration::get('PS_LANG_DEFAULT')); foreach ($packs as $pack) { // Decrease stocks of the pack only if pack is in linked stock mode (option called 'Decrement both') if (!((int) $pack->pack_stock_type == 2) && !((int) $pack->pack_stock_type == 3 && (int) Configuration::get('PS_PACK_STOCK_TYPE') == 2)) { continue; } // Decrease stocks of the pack only if there is not enough items to constituate the actual pack stocks. // How many packs can be constituated with the remaining product stocks $quantity_by_pack = $pack->pack_item_quantity; $stock_available_quantity = $quantity_in_stock - $quantity; $max_pack_quantity = max(array(0, floor($stock_available_quantity / $quantity_by_pack))); $quantity_delta = Pack::getQuantity($pack->id) - $max_pack_quantity; if ($pack->advanced_stock_management == 1 && $quantity_delta > 0) { $product_warehouses = Warehouse::getPackWarehouses($pack->id); $warehouse_stock_found = false; foreach ($product_warehouses as $product_warehouse) { if (!$warehouse_stock_found) { if (Warehouse::exists($product_warehouse)) { $current_warehouse = new Warehouse($product_warehouse); $return[] = $this->removeProduct($pack->id, null, $current_warehouse, $quantity_delta, $id_stock_mvt_reason, $is_usable, $id_order, 1); // The product was found on this warehouse. Stop the stock searching. $warehouse_stock_found = !empty($return[count($return) - 1]); } } } } } } } // if we remove a usable quantity, exec hook if ($is_usable) { Hook::exec('actionProductCoverage', array('id_product' => $id_product, 'id_product_attribute' => $id_product_attribute, 'warehouse' => $warehouse)); } return $return; }
public function initFormQuantities($obj) { if (!$this->default_form_language) { $this->getLanguages(); } $data = $this->createTemplate($this->tpl_form); $data->assign('default_form_language', $this->default_form_language); if ($obj->id) { if ($this->product_exists_in_shop) { // Get all id_product_attribute $attributes = $obj->getAttributesResume($this->context->language->id); if (empty($attributes)) { $attributes[] = array('id_product_attribute' => 0, 'attribute_designation' => ''); } // Get available quantities $available_quantity = array(); $product_designation = array(); foreach ($attributes as $attribute) { // Get available quantity for the current product attribute in the current shop $available_quantity[$attribute['id_product_attribute']] = StockAvailable::getQuantityAvailableByProduct((int) $obj->id, $attribute['id_product_attribute']); // Get all product designation $product_designation[$attribute['id_product_attribute']] = rtrim($obj->name[$this->context->language->id] . ' - ' . $attribute['attribute_designation'], ' - '); } $show_quantities = true; $shop_context = Shop::getContext(); $shop_group = new ShopGroup((int) Shop::getContextShopGroupID()); // if we are in all shops context, it's not possible to manage quantities at this level if (Shop::isFeatureActive() && $shop_context == Shop::CONTEXT_ALL) { $show_quantities = false; } elseif (Shop::isFeatureActive() && $shop_context == Shop::CONTEXT_GROUP) { // if quantities are not shared between shops of the group, it's not possible to manage them at group level if (!$shop_group->share_stock) { $show_quantities = false; } } else { // if quantities are shared between shops of the group, it's not possible to manage them for a given shop if ($shop_group->share_stock) { $show_quantities = false; } } $data->assign('ps_stock_management', Configuration::get('PS_STOCK_MANAGEMENT')); $data->assign('has_attribute', $obj->hasAttributes()); // Check if product has combination, to display the available date only for the product or for each combination if (Combination::isFeatureActive()) { $data->assign('countAttributes', (int) Db::getInstance()->getValue('SELECT COUNT(id_product) FROM ' . _DB_PREFIX_ . 'product_attribute WHERE id_product = ' . (int) $obj->id)); } else { $data->assign('countAttributes', false); } // if advanced stock management is active, checks associations $advanced_stock_management_warning = false; if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') && $obj->advanced_stock_management) { $p_attributes = Product::getProductAttributesIds($obj->id); $warehouses = array(); if (!$p_attributes) { $warehouses[] = Warehouse::getProductWarehouseList($obj->id, 0); } foreach ($p_attributes as $p_attribute) { $ws = Warehouse::getProductWarehouseList($obj->id, $p_attribute['id_product_attribute']); if ($ws) { $warehouses[] = $ws; } } $warehouses = Tools::arrayUnique($warehouses); if (empty($warehouses)) { $advanced_stock_management_warning = true; } } if ($advanced_stock_management_warning) { $this->displayWarning($this->l('If you wish to use the advanced stock management, you must:')); $this->displayWarning('- ' . $this->l('associate your products with warehouses.')); $this->displayWarning('- ' . $this->l('associate your warehouses with carriers.')); $this->displayWarning('- ' . $this->l('associate your warehouses with the appropriate shops.')); } $pack_quantity = null; // if product is a pack if (Pack::isPack($obj->id)) { $items = Pack::getItems((int) $obj->id, Configuration::get('PS_LANG_DEFAULT')); // gets an array of quantities (quantity for the product / quantity in pack) $pack_quantities = array(); foreach ($items as $item) { if (!$item->isAvailableWhenOutOfStock((int) $item->out_of_stock)) { $pack_id_product_attribute = Product::getDefaultAttribute($item->id, 1); $pack_quantities[] = Product::getQuantity($item->id, $pack_id_product_attribute) / ($item->pack_quantity !== 0 ? $item->pack_quantity : 1); } } // gets the minimum if (count($pack_quantities)) { $pack_quantity = $pack_quantities[0]; foreach ($pack_quantities as $value) { if ($pack_quantity > $value) { $pack_quantity = $value; } } } if (!Warehouse::getPackWarehouses((int) $obj->id)) { $this->displayWarning($this->l('You must have a common warehouse between this pack and its product.')); } } $data->assign(array('attributes' => $attributes, 'available_quantity' => $available_quantity, 'pack_quantity' => $pack_quantity, 'stock_management_active' => Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT'), 'product_designation' => $product_designation, 'product' => $obj, 'show_quantities' => $show_quantities, 'order_out_of_stock' => Configuration::get('PS_ORDER_OUT_OF_STOCK'), 'token_preferences' => Tools::getAdminTokenLite('AdminPPreferences'), 'token' => $this->token, 'languages' => $this->_languages, 'id_lang' => $this->context->language->id)); } else { $this->displayWarning($this->l('You must save the product in this shop before managing quantities.')); } } else { $this->displayWarning($this->l('You must save this product before managing quantities.')); } $this->tpl_form_vars['custom_form'] = $data->fetch(); }
public function initContentForQuantities() { if ($this->object->id) { $tfowlgstly = "show_quantities"; ${"GLOBALS"}["ygzeqkb"] = "show_quantities"; $gmgclvkrjy = "attributes"; ${"GLOBALS"}["jhngqfjufp"] = "attributes"; $cggvbxsk = "attributes"; ${${"GLOBALS"}["jhngqfjufp"]} = $this->object->getAttributesResume($this->context->language->id); ${"GLOBALS"}["aofqmvff"] = "attribute"; ${"GLOBALS"}["vyyogyvfbtx"] = "attributes"; $nfdcluhk = "attributes"; $khzorwi = "shop_context"; if (empty(${$nfdcluhk})) { ${$cggvbxsk}[] = array("id_product_attribute" => 0, "attribute_designation" => ""); } ${"GLOBALS"}["klqbahrije"] = "shop_context"; ${${"GLOBALS"}["ldfuknydnzr"]} = array(); ${${"GLOBALS"}["ymshseez"]} = array(); ${"GLOBALS"}["lztnksxrb"] = "group_shop"; foreach (${${"GLOBALS"}["vyyogyvfbtx"]} as ${${"GLOBALS"}["aofqmvff"]}) { $rvrxkz = "product_designation"; $ycvvjwmxtnm = "attribute"; $dxuqsu = "available_quantity"; ${$dxuqsu}[${${"GLOBALS"}["iixdipeiyldv"]}["id_product_attribute"]] = StockAvailable::getQuantityAvailableByProduct((int) $this->object->id, ${$ycvvjwmxtnm}["id_product_attribute"]); ${$rvrxkz}[${${"GLOBALS"}["iixdipeiyldv"]}["id_product_attribute"]] = rtrim($this->object->name[$this->context->language->id] . " - " . ${${"GLOBALS"}["iixdipeiyldv"]}["attribute_designation"], " - "); } ${${"GLOBALS"}["ueicxl"]} = true; ${$khzorwi} = Shop::getContext(); ${${"GLOBALS"}["lztnksxrb"]} = $this->context->shop->getGroup(); $wktpughd = "pack_quantity"; ${"GLOBALS"}["eukvwdf"] = "advanced_stock_management_warning"; if (${${"GLOBALS"}["klqbahrije"]} == Shop::CONTEXT_ALL) { ${$tfowlgstly} = false; } elseif (${${"GLOBALS"}["ohyfjtkcy"]} == Shop::CONTEXT_GROUP) { if (!$group_shop->share_stock) { ${${"GLOBALS"}["ueicxl"]} = false; } } else { $eksumjgu = "show_quantities"; if ($group_shop->share_stock) { ${$eksumjgu} = false; } } self::$smarty->assign("ps_stock_management", Configuration::get("PS_STOCK_MANAGEMENT")); self::$smarty->assign("has_attribute", $this->object->hasAttributes()); if (Combination::isFeatureActive()) { self::$smarty->assign("countAttributes", (int) Db::getInstance()->getValue("SELECT COUNT(id_product) FROM " . _DB_PREFIX_ . "product_attribute WHERE id_product = " . (int) $this->object->id)); } ${${"GLOBALS"}["eukvwdf"]} = false; if (Configuration::get("PS_ADVANCED_STOCK_MANAGEMENT") && $this->object->advanced_stock_management) { ${"GLOBALS"}["awunkp"] = "p_attributes"; ${"GLOBALS"}["qxobmbos"] = "warehouses"; ${"GLOBALS"}["cjtetqei"] = "warehouses"; $ukjfpwyojlf = "p_attribute"; ${${"GLOBALS"}["iczelyves"]} = Product::getProductAttributesIds($this->object->id); ${"GLOBALS"}["kcjlbgqb"] = "advanced_stock_management_warning"; ${"GLOBALS"}["dlsnuhn"] = "warehouses"; ${${"GLOBALS"}["qxobmbos"]} = array(); ${"GLOBALS"}["ojmjigmfve"] = "p_attributes"; if (!${${"GLOBALS"}["awunkp"]}) { ${${"GLOBALS"}["mdrvdmghqrtc"]}[] = Warehouse::getProductWarehouseList($this->object->id, 0); } foreach (${${"GLOBALS"}["ojmjigmfve"]} as ${$ukjfpwyojlf}) { ${"GLOBALS"}["uevlubu"] = "ws"; ${"GLOBALS"}["fpbyfow"] = "warehouses"; ${"GLOBALS"}["inddsyj"] = "ws"; ${${"GLOBALS"}["yrbmurnh"]} = Warehouse::getProductWarehouseList($this->object->id, ${${"GLOBALS"}["bhprusfblhn"]}["id_product_attribute"]); if (${${"GLOBALS"}["uevlubu"]}) { ${${"GLOBALS"}["fpbyfow"]}[] = ${${"GLOBALS"}["inddsyj"]}; } } ${${"GLOBALS"}["dlsnuhn"]} = array_unique(${${"GLOBALS"}["cjtetqei"]}); if (empty(${${"GLOBALS"}["mdrvdmghqrtc"]})) { ${${"GLOBALS"}["kcjlbgqb"]} = true; } } if (${${"GLOBALS"}["uucoxnutvd"]}) { $this->displayWarning($this->getMessage("If you wish to use the advanced stock management, you have to:")); $this->displayWarning("- " . $this->getMessage("associate your products with warehouses")); $this->displayWarning("- " . $this->getMessage("associate your warehouses with carriers")); $this->displayWarning("- " . $this->getMessage("associate your warehouses with the appropriate shops")); } ${${"GLOBALS"}["qbmqjuoutyh"]} = null; if (Pack::isPack($this->object->id)) { ${"GLOBALS"}["wdcmwsfvsft"] = "pack_quantity"; $mdjqucflf = "items"; ${${"GLOBALS"}["wfbswtei"]} = Pack::getItems((int) $this->object->id, Configuration::get("PS_LANG_DEFAULT")); $mhikkwxp = "pack_quantities"; ${"GLOBALS"}["kamnnzyptd"] = "pack_quantities"; ${${"GLOBALS"}["kamnnzyptd"]} = array(); foreach (${$mdjqucflf} as ${${"GLOBALS"}["gpnqjgaosuld"]}) { if (!$item->isAvailableWhenOutOfStock((int) $item->out_of_stock)) { $gkwutr = "pack_id_product_attribute"; ${${"GLOBALS"}["wkyidmmlbbc"]} = Product::getDefaultAttribute($item->id, 1); ${${"GLOBALS"}["pnfrmcr"]}[] = Product::getQuantity($item->id, ${$gkwutr}) / ($item->pack_quantity !== 0 ? $item->pack_quantity : 1); } } $oissvbm = "pack_quantities"; ${${"GLOBALS"}["wdcmwsfvsft"]} = ${$oissvbm}[0]; foreach (${$mhikkwxp} as ${${"GLOBALS"}["kzwkbwmzgtl"]}) { ${"GLOBALS"}["iwrwjuvdmi"] = "value"; if (${${"GLOBALS"}["qbmqjuoutyh"]} > ${${"GLOBALS"}["iwrwjuvdmi"]}) { ${${"GLOBALS"}["qbmqjuoutyh"]} = ${${"GLOBALS"}["kzwkbwmzgtl"]}; } } if (!Warehouse::getPackWarehouses((int) $this->object->id)) { $this->displayWarning($this->getMessage("You must have a common warehouse between this pack and its product.")); } } ${${"GLOBALS"}["lixyhrpqnh"]} = new Language($this->id_language); self::$smarty->assign("iso_code", $lang->iso_code ? $lang->iso_code : "en"); self::$smarty->assign(array("attributes" => ${$gmgclvkrjy}, "available_quantity" => ${${"GLOBALS"}["ldfuknydnzr"]}, "pack_quantity" => ${$wktpughd}, "stock_management_active" => Configuration::get("PS_ADVANCED_STOCK_MANAGEMENT"), "product_designation" => ${${"GLOBALS"}["ymshseez"]}, "show_quantities" => ${${"GLOBALS"}["ygzeqkb"]}, "order_out_of_stock" => Configuration::get("PS_ORDER_OUT_OF_STOCK"))); } else { $this->displayWarning($this->getMessage("You must save this product before managing quantities.")); } }