예제 #1
0
 /**
  * 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);
 }
예제 #2
0
    /**
     * @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;
    }
예제 #3
0
 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."));
     }
 }