diff --git a/admin-dev/themes/default/template/controllers/products/quantities.tpl b/admin-dev/themes/default/template/controllers/products/quantities.tpl index ec9872352..0ad805a88 100644 --- a/admin-dev/themes/default/template/controllers/products/quantities.tpl +++ b/admin-dev/themes/default/template/controllers/products/quantities.tpl @@ -211,7 +211,7 @@ - {include file="products/input_text_lang.tpl" + {include file="controllers/products/input_text_lang.tpl" languages=$languages input_value=$product->available_now input_name='available_now'} @@ -221,7 +221,7 @@ - {include file="products/input_text_lang.tpl" + {include file="controllers/products/input_text_lang.tpl" languages=$languages input_value=$product->available_later input_name='available_later'} diff --git a/classes/Product.php b/classes/Product.php index 3dbe27eca..77c8aa208 100644 --- a/classes/Product.php +++ b/classes/Product.php @@ -365,8 +365,8 @@ class ProductCore extends ObjectModel const CUSTOMIZE_FILE = 0; const CUSTOMIZE_TEXTFIELD = 1; - - + + // Note: prefix is "PTYPE" because TYPE_ is used in ObjectModel (definition) const PTYPE_SIMPLE = 0; const PTYPE_PACK = 1; @@ -1034,7 +1034,7 @@ class ProductCore extends ObjectModel $price = str_replace(',', '.', $price); $weight = str_replace(',', '.', $weight); - + $combination = new Combination(); $combination->id_product = (int)$this->id; $combination->price = (float)$price; @@ -1052,9 +1052,9 @@ class ProductCore extends ObjectModel if (!$combination->id) return false; - + Product::updateDefaultAttribute($this->id); - + if (!empty($id_images)) $combination->setImages($id_images); @@ -1071,9 +1071,9 @@ class ProductCore extends ObjectModel $id_product_attribute = $this->addAttribute( $price, $weight, $unit_impact, $ecotax, 0, $id_images, $reference, $ean13, $default, $location, $upc, $minimal_quantity); - + $this->addSupplierReference($supplier_reference, $id_product_attribute); - + $result = Db::getInstance()->execute( 'UPDATE `'._DB_PREFIX_.'product_attribute` SET `wholesale_price` = '.(float)$wholesale_price.' @@ -1179,7 +1179,7 @@ class ProductCore extends ObjectModel $this->addSupplierReference($supplier_reference, $id_product_attribute); return $return; } - + public function addSupplierReference($supplier_reference, $id_product_attribute = null, $id_currency = null) { //Try to set the default supplier reference @@ -1245,10 +1245,10 @@ class ProductCore extends ObjectModel $combination->minimal_quantity = (int)$minimal_quantity; $combination->available_date = pSQL($available_date); $combination->save(); - + if (!empty($id_images)) $combination->setImages($id_images); - + Hook::exec('actionProductAttributeUpdate', array('id_product_attribute' => $id_product_attribute)); Product::updateDefaultAttribute($this->id); diff --git a/classes/order/OrderHistory.php b/classes/order/OrderHistory.php index ca16cd372..656923132 100644 --- a/classes/order/OrderHistory.php +++ b/classes/order/OrderHistory.php @@ -95,6 +95,8 @@ class OrderHistoryCore extends ObjectModel && $oldOrderStatus->logable)) { ProductSale::addProductSale($product['product_id'], $product['product_quantity']); + if ($oldOrderStatus->id == Configuration::get('PS_OS_ERROR') || $oldOrderStatus->id == Configuration::get('PS_OS_CANCELED')) + StockAvailable::updateQuantity($product['product_id'], $product['product_attribute_id'], -(int)$product['product_quantity'], $order->id_shop); } /* If becoming unlogable => removing sale */ else if (!$newOS->logable diff --git a/classes/stock/StockAvailable.php b/classes/stock/StockAvailable.php index d2cfd5b0a..fcce70cd0 100644 --- a/classes/stock/StockAvailable.php +++ b/classes/stock/StockAvailable.php @@ -279,44 +279,19 @@ class StockAvailableCore extends ObjectModel if (is_null($id_product_attribute)) $id_product_attribute = 0; - // if product is a pack - if (Pack::isPack($id_product)) - { - $items = Pack::getItems((int)$id_product, Configuration::get('PS_LANG_DEFAULT')); + $query = new DbQuery(); + $query->select('SUM(quantity)'); + $query->from('stock_available'); - // gets an array of quantities (quantity for the product / quantity in pack) - $quantities = array(); - foreach ($items as $item) - if (!$item->isAvailableWhenOutOfStock((int)$item->out_of_stock)) - $quantities[] = Product::getQuantity($item->id) / ($item->pack_quantity !== 0 ? $item->pack_quantity : 1); + // if null, it's a product without attributes + if (!is_null($id_product)) + $query->where('id_product = '.(int)$id_product); - // gets the minimum - $quantity = $quantities[0]; - foreach ($quantities as $value) - { - if ($quantity > $value) - $quantity = $value; - } + $query->where('id_product_attribute = '.(int)$id_product_attribute); - // returns the number of pack available - return $quantity; - } - else // else - { - $query = new DbQuery(); - $query->select('SUM(quantity)'); - $query->from('stock_available'); + $query = StockAvailable::addSqlShopRestriction($query, $id_shop); - // if null, it's a product without attributes - if (!is_null($id_product)) - $query->where('id_product = '.(int)$id_product); - - $query->where('id_product_attribute = '.(int)$id_product_attribute); - - $query = StockAvailable::addSqlShopRestriction($query, $id_shop); - - return (int)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($query); - } + return (int)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($query); } /** @@ -382,10 +357,10 @@ class StockAvailableCore extends ObjectModel // Update quantity of the pack products if (Pack::isPack($id_product)) { - $products_pack = Pack::getItems((int)$product['id_product'], (int)Configuration::get('PS_LANG_DEFAULT')); + $products_pack = Pack::getItems($id_product, (int)Configuration::get('PS_LANG_DEFAULT')); foreach ($products_pack as $product_pack) { - $pack_id_product_attribute = Product::getDefaultAttribute($tab_product_pack['id_product'], 1); + $pack_id_product_attribute = Product::getDefaultAttribute($product_pack->id, 1); StockAvailable::updateQuantity($product_pack->id, $pack_id_product_attribute, $product_pack->pack_quantity * $delta_quantity, $id_shop); } } diff --git a/controllers/admin/AdminProductsController.php b/controllers/admin/AdminProductsController.php index b6839f894..758e23999 100644 --- a/controllers/admin/AdminProductsController.php +++ b/controllers/admin/AdminProductsController.php @@ -3471,7 +3471,6 @@ class AdminProductsControllerCore extends AdminController // 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'], @@ -3510,11 +3509,15 @@ class AdminProductsControllerCore extends AdminController $advanced_stock_management_warning = false; if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') && $obj->advanced_stock_management) { - $attributes = Product::getProductAttributesIds($obj->id); + $p_attributes = Product::getProductAttributesIds($obj->id); $warehouses = array(); - foreach ($attributes as $attribute) + + if (!$p_attributes) + $warehouses[] = Warehouse::getProductWarehouseList($obj->id, 0); + + foreach ($p_attributes as $p_attribute) { - $ws = Warehouse::getProductWarehouseList($obj->id, $attribute['id_product_attribute']); + $ws = Warehouse::getProductWarehouseList($obj->id, $p_attribute['id_product_attribute']); if ($ws) $warehouses[] = $ws; } @@ -3531,9 +3534,31 @@ class AdminProductsControllerCore extends AdminController $this->displayWarning('- '.$this->l('associate your warehouses with the appropriates 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_quantities[] = Product::getQuantity($item->id) / ($item->pack_quantity !== 0 ? $item->pack_quantity : 1); + + // gets the minimum + $pack_quantity = $pack_quantities[0]; + foreach ($pack_quantities as $value) + { + if ($pack_quantity > $value) + $pack_quantity = $value; + } + } + $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, @@ -3715,46 +3740,50 @@ class AdminProductsControllerCore extends AdminController public function ajaxProcessProductQuantity() { if (!Tools::getValue('actionQty')) - return Tools::jsonEncode(array('error' => 'Undefined action')); + return Tools::jsonEncode(array('error' => $this->l('Undefined action'))); $product = new Product((int)Tools::getValue('id_product')); switch (Tools::getValue('actionQty')) { case 'depends_on_stock': if (Tools::getValue('value') === false) - return Tools::jsonEncode(array('error' => 'Undefined value')); + die (Tools::jsonEncode(array('error' => $this->l('Undefined value')))); if ((int)Tools::getValue('value') != 0 && (int)Tools::getValue('value') != 1) - return Tools::jsonEncode(array('error' => 'Uncorrect value')); + die (Tools::jsonEncode(array('error' => $this->l('Uncorrect value')))); if (!$product->advanced_stock_management && (int)Tools::getValue('value') == 1) - return Tools::jsonEncode(array('error' => 'Not possible if advanced stock management is not enabled')); + die (Tools::jsonEncode(array('error' => $this->l('Not possible if advanced stock management is not enabled')))); + if ($product->advanced_stock_management && Pack::isPack($product->id)) + die (Tools::jsonEncode(array('error' => $this->l('Not possible if the product is a pack')))); StockAvailable::setProductDependsOnStock($product->id, (int)Tools::getValue('value')); break; case 'out_of_stock': if (Tools::getValue('value') === false) - return Tools::jsonEncode(array('error' => 'Undefined value')); + die (Tools::jsonEncode(array('error' => $this->l('Undefined value')))); if (!in_array((int)Tools::getValue('value'), array(0, 1, 2))) - return Tools::jsonEncode(array('error' => 'Uncorrect value')); + die (Tools::jsonEncode(array('error' => $this->l('Uncorrect value')))); StockAvailable::setProductOutOfStock($product->id, (int)Tools::getValue('value')); break; case 'set_qty': if (Tools::getValue('value') === false) - return Tools::jsonEncode(array('error' => 'Undefined value')); + die (Tools::jsonEncode(array('error' => $this->l('Undefined value')))); if (Tools::getValue('id_product_attribute') === false) - return Tools::jsonEncode(array('error' => 'Undefined id product attribute')); + die (Tools::jsonEncode(array('error' => $this->l('Undefined id product attribute')))); StockAvailable::setQuantity($product->id, (int)Tools::getValue('id_product_attribute'), (int)Tools::getValue('value')); break; case 'advanced_stock_management' : if (Tools::getValue('value') === false) - return Tools::jsonEncode(array('error' => 'Undefined value')); + die (Tools::jsonEncode(array('error' => $this->l('Undefined value')))); if ((int)Tools::getValue('value') != 1 && (int)Tools::getValue('value') != 0) - return Tools::jsonEncode(array('error' => 'Uncorrect value')); + die (Tools::jsonEncode(array('error' => $this->l('Uncorrect value')))); if (!Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') && (int)Tools::getValue('value') == 1) - return Tools::jsonEncode(array('error' => 'Not possible if advanced stock management is not enabled')); + die (Tools::jsonEncode(array('error' => $this->l('Not possible if advanced stock management is not enabled')))); + if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') && Pack::isPack($product->id)) + die (Tools::jsonEncode(array('error' => $this->l('Not possible if the product is a pack')))); $product->advanced_stock_management = (int)Tools::getValue('value'); $product->save(); @@ -3817,8 +3846,8 @@ class AdminProductsControllerCore extends AdminController /** * delete all items in pack, then check if type_product value is 2. * if yes, add the pack items from input "inputPackItems" - * - * @param Product $product + * + * @param Product $product * @return boolean */ public function updatePackItems($product)