diff --git a/classes/stock/StockAvailable.php b/classes/stock/StockAvailable.php index 3dafd613b..1dc7cf650 100644 --- a/classes/stock/StockAvailable.php +++ b/classes/stock/StockAvailable.php @@ -92,12 +92,14 @@ class StockAvailableCore extends ObjectModel * For a given {id_product, id_product_attribute and id_shop}, gets the stock id associated * * @param int $id_product - * @param int $id_product_attribute default null - * @param int $id_shop + * @param int $id_product_attribute Optional + * @param int $id_shop Optional * @return int */ - public static function getIdStockAvailable($id_product, $id_product_attribute = null, $id_shop = null) + + public static function getIdStockAvailableByProductId($id_product, $id_product_attribute = null, $id_shop = null) { + // if there is no $id_shop, gets the context one if (is_null($id_shop)) $id_shop = Context::getContext()->shop->getID(true); @@ -119,11 +121,11 @@ class StockAvailableCore extends ObjectModel */ public static function synchronize($id_product) { - // used var in algorithm + // inits the list of warehouse ids and product ids $ids_warehouse = array(); $ids_product_attribute = array(); - // builds query to get all warehouses/shops + // builds query to get every warehouses/shops $query = new DbQuery(); $query->select('id_warehouse, id_shop'); $query->from('warehouse_shop'); @@ -137,6 +139,7 @@ class StockAvailableCore extends ObjectModel foreach (Product::getProductAttributesIds($id_product) as $id_product_attribute) $ids_product_attribute[] = $id_product_attribute['id_product_attribute']; + $manager = StockManagerFactory::getManager(); // loops on ids_warehouse to synchronize foreach ($ids_warehouse as $id_shop => $warehouses) { @@ -144,12 +147,12 @@ class StockAvailableCore extends ObjectModel // if there are no product attributes if (empty($ids_product_attribute)) - $total_quantity = StockManagerFactory::getManager()->getProductRealQuantities($id_product, null, $warehouses, true); + $total_quantity = $manager->getProductRealQuantities($id_product, null, $warehouses, true); // else loops on id_product_attribute and to get $total_quantity foreach ($ids_product_attribute as $id_product_attribute) { - $quantity = StockManagerFactory::getManager()->getProductRealQuantities($id_product, $id_product_attribute, $warehouses, true); + $quantity = $manager->getProductRealQuantities($id_product, $id_product_attribute, $warehouses, true); $query = array( 'table' => 'stock_available', @@ -178,11 +181,11 @@ class StockAvailableCore extends ObjectModel /** * For a given id_product, sets if stock available depends on stock * - * @param int $depends_on_stock * @param int $id_product - * @param int $id_shop + * @param int $depends_on_stock Optional : true by default + * @param int $id_shop Optional : gets context by default */ - public static function setProductDependsOnStock($depends_on_stock, $id_product, $id_shop = null) + public static function setProductDependsOnStock($id_product, $depends_on_stock = true, $id_shop = null) { if (is_null($id_shop)) $id_shop = Context::getContext()->shop->getID(true); @@ -193,6 +196,8 @@ class StockAvailableCore extends ObjectModel 'UPDATE', 'id_product = '.(int)$id_product.' AND id_shop = '.(int)$id_shop ); + + // depends on stock.. hence synchronizes if ($depends_on_stock) StockAvailable::synchronize($id_product); } @@ -200,11 +205,11 @@ class StockAvailableCore extends ObjectModel /** * For a given id_product, sets if product is available out of stocks * - * @param int $out_of_stock * @param int $id_product - * @param int $id_shop + * @param int $out_of_stock Optional false by default + * @param int $id_shop Optional gets context by default */ - public static function setProductOutOfStock($out_of_stock, $id_product, $id_shop = null) + public static function setProductOutOfStock($id_product, $out_of_stock = false, $id_shop = null) { if (is_null($id_shop)) $id_shop = Context::getContext()->shop->getID(true); @@ -218,11 +223,11 @@ class StockAvailableCore extends ObjectModel } /** - * For a given id_product and id_product_attribute, gets stock available + * For a given id_product and id_product_attribute, gets its stock available * * @param int $id_product - * @param int $id_product_attribute - * @param int $id_shop + * @param int $id_product_attribute Optional + * @param int $id_shop Optional : gets context by default * @return int */ public static function getStockAvailableForProduct($id_product, $id_product_attribute = null, $id_shop = null) @@ -230,6 +235,10 @@ class StockAvailableCore extends ObjectModel if (is_null($id_shop)) $id_shop = Context::getContext()->shop->getID(true); + // if null, it's a product without attributes + if (!$id_product_attribute) + $id_product_attribute = 0; + $query = new DbQuery(); $query->select('quantity'); $query->from('stock_available'); @@ -251,7 +260,7 @@ class StockAvailableCore extends ObjectModel if ($this->id_product_attribute == 0) return true; - $id_stock_available = StockAvailable::getIdStockAvailable($this->id_product, 0, $this->id_shop); + $id_stock_available = StockAvailable::getIdStockAvailableByProductId($this->id_product, 0, $this->id_shop); $total_quantity = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue(' SELECT SUM(quantity) @@ -278,7 +287,7 @@ class StockAvailableCore extends ObjectModel */ public static function updateQuantity($id_product, $id_product_attribute, $delta_quantity, $id_shop = null) { - $id_stock = self::getIdStockAvailable($id_product, $id_product_attribute, $id_shop); + $id_stock = self::getIdStockAvailableByProductId($id_product, $id_product_attribute, $id_shop); if (!$id_stock) return false; @@ -286,7 +295,7 @@ 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((int)$product['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); diff --git a/classes/stock/StockManager.php b/classes/stock/StockManager.php index c9b86b8c1..6fc621a96 100644 --- a/classes/stock/StockManager.php +++ b/classes/stock/StockManager.php @@ -453,7 +453,6 @@ class StockManagerCore implements StockManagerInterface $ids_warehouse = array(); // Gets client_orders_qty - // @TODO: Add the warehouse the order will be shipped from $query = new DbQuery(); $query->select('SUM(od.product_quantity)'); $query->from('order_detail od'); @@ -463,6 +462,8 @@ class StockManagerCore implements StockManagerInterface $query->where('od.product_attribute_id = '.(int)$id_product_attribute); $query->where('o.delivery_number = 0'); $query->where('o.valid = 1'); + // @FIXME: Once part-shipping is done, remove the comment on the line below. + // $query->where('o.id_warehouse IN (0, '.implode(', ', $ids_warehouse).')'); $client_orders_qty = (int)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($query); // Gets supply_orders_qty diff --git a/controllers/admin/AdminProductsController.php b/controllers/admin/AdminProductsController.php index 09678ddb2..31d488fae 100644 --- a/controllers/admin/AdminProductsController.php +++ b/controllers/admin/AdminProductsController.php @@ -85,7 +85,7 @@ class AdminProductsController extends AdminController LEFT JOIN `'._DB_PREFIX_.'category_lang` cl ON (a.`id_category_default` = cl.`id_category` AND b.`id_lang` = cl.`id_lang`) LEFT JOIN `'._DB_PREFIX_.'image` i ON (i.`id_product` = a.`id_product` AND i.`cover` = 1) LEFT JOIN `'._DB_PREFIX_.'category_product` cp ON (cp.`id_product` = a.`id_product`) - LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (a.`id_tax_rules_group` = tr.`id_tax_rules_group` + LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (a.`id_tax_rules_group` = tr.`id_tax_rules_group` AND tr.`id_country` = '.(int)$this->context->country->id.' AND tr.`id_state` = 0) LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`)'; $this->_filter = 'AND cp.`id_category` = '.(int)$this->_category->id; @@ -122,7 +122,7 @@ class AdminProductsController extends AdminController foreach ($languages as $language) if (isset($_POST['meta_keywords_'.$language['id_lang']])) { - $_POST['meta_keywords_'.$language['id_lang']] = $this->_cleanMetaKeywords(Tools::strtolower($_POST['meta_keywords_'.$language['id_lang']])); + $_POST['meta_keywords_'.$language['id_lang']] = $this->_cleanMetaKeywords(Tools::strtolower($_POST['meta_keywords_'.$language['id_lang']])); // preg_replace('/ *,? +,* /', ',', strtolower($_POST['meta_keywords_'.$language['id_lang']])); $object->meta_keywords[$language['id_lang']] = $_POST['meta_keywords_'.$language['id_lang']]; } @@ -1601,7 +1601,7 @@ if (false) } $this->tpl_list_vars['category_tree'] = $category_tree; } - // @todo module free + // @todo module free $this->tpl_form_vars['vat_number'] = file_exists(_PS_MODULE_DIR_.'vatnumber/ajax.php'); parent::initContent(); } @@ -1789,7 +1789,7 @@ if (false) public function initForm() { $product = $this->object = new Product((int)(Tools::getValue('id_product'))); - // getLanguages init this->_languages + // getLanguages init this->_languages $this->getLanguages(); $languages = $this->_languages; $defaultLanguage = (int)(Configuration::get('PS_LANG_DEFAULT')); @@ -1826,8 +1826,8 @@ if (false) public function getPreviewUrl(Product $product) { $preview_url = $this->context->link->getProductLink( - $this->getFieldValue($product, 'id'), - $this->getFieldValue($product, 'link_rewrite', $this->context->language->id), + $this->getFieldValue($product, 'id'), + $this->getFieldValue($product, 'link_rewrite', $this->context->language->id), Category::getLinkRewrite($product->id_category_default, $this->context->language->id), null, null, Context::getContext()->shop->getID()); if (!$product->active) { @@ -1848,17 +1848,17 @@ if (false) } return $preview_url; } - + /** - * Post traitment for accounting + * Post traitment for accounting */ public function postProcessFormAccounting() { - + if (Validate::isLoadedObject($product = new Product((int)(Tools::getValue('id_product'))))) { $id_shop = $this->context->shop->getID(); - + // If zone still exist, then update the database with the new value if (count($zones = Zone::getZones())) { @@ -1871,8 +1871,8 @@ if (false) 'id_product' => $product->id, 'id_shop' => $id_shop, 'num' => $num); - - // Save to the database the account + + // Save to the database the account if (count($tab) && Accounting::saveProductAccountingInformations($tab)) $this->confirmations[] = $this->l('Account numbers have been updated'); else @@ -1880,7 +1880,7 @@ if (false) } } } - + /** * Init data for accounting */ @@ -1888,7 +1888,7 @@ if (false) { $error = ''; $token = Tools::getValue('token') ? Tools::getValue('token') : $this->token; - + if (count($this->context->shop->getListOfID()) > 1) $error = $this->l('Please select the shop you want to configure'); else @@ -1896,7 +1896,7 @@ if (false) $zones = Zone::getZones(); $id_shop = $this->context->shop->getID(); $detail = array(); - + // Set default zone value to the shop and sort it foreach($zones as $zone) { @@ -1904,12 +1904,12 @@ if (false) $detail['zones'][$zone['id_zone']]['account_number'] = ''; } $zoneAccountNumberList = Accounting::getProductAccountNumberZoneShop($product->id, $id_shop); - + // Set Account number to the id_zone for an id_shop if exist foreach($zoneAccountNumberList as $zone) $detail['zones'][$zone['id_zone']]['account_number'] = $zone['account_number']; } - + $this->context->smarty->assign(array( 'productAccountNumberList' => $detail, 'shopName' => $this->context->shop->name, @@ -2385,7 +2385,7 @@ if (false) $product->name['class'] = 'updateCurrentText'; if (!$product->id) $product->name['class'] .= ' copy2friendlyUrl'; - + $product->manufacturer_name = Manufacturer::getNameById($product->id_manufacturer); $product->supplier_name = Supplier::getNameById($product->id_supplier); @@ -2478,7 +2478,7 @@ if (false) $data->assign('countAttributes', (int)Db::getInstance()->getValue('SELECT COUNT(id_product) FROM '._DB_PREFIX_.'product_attribute WHERE id_product = '.(int)$product->id)); $data->assign('ps_order_out_of_stock', Configuration::get('PS_ORDER_OUT_OF_STOCK')); - + $default_category = Tools::getValue('id_category', 1); $data->assign('default_category', $default_category); if (!$product->id) @@ -2505,7 +2505,7 @@ if (false) 'search' => $this->l('Search a category') ); $data->assign('category_tree', Helper::renderAdminCategorieTree($trads, $selectedCat, 'categoryBox', false, true)); - + $images = Image::getImages($this->context->language->id, $product->id); foreach($images as $k => $image) @@ -2513,7 +2513,7 @@ if (false) $data->assign('ps_ssl_enabled', Configuration::get('PS_SSL_ENABLED')); $data->assign('images', $images); $data->assign('imagesTypes', ImageType::getImagesTypes('products')); - + $content .= ' @@ -2661,7 +2661,7 @@ if (false) foreach ($images as $k => $image) $images[$k] = new Image($image['id_image']); - + $data->assign('images', $images); $data->assign('token', $token); $data->assign($this->tpl_form_vars); @@ -2920,7 +2920,7 @@ if (false) $totalQuantity += $physicalQuantity[$attribute['id_product_attribute']]; // @TODO - $availableQuantity[$attribute['id_product_attribute']] = StockAvailable::getStockAvailableForProduct((int)$obj->id, $attribute['id_product_attribute']); + $availableQuantity[$attribute['id_product_attribute']] = StockAvailable::getIdStockAvailableByProductId((int)$obj->id, $attribute['id_product_attribute']); // Get all product designation $productDesignation[$attribute['id_product_attribute']] = rtrim($obj->name[$this->context->language->id].' - '.$attribute['attribute_designation'], ' - '); @@ -3267,7 +3267,7 @@ if (false) } else $content .= ''.$this->l('You must save this product before adding features').'.'; - + $content .= ''; @@ -3288,7 +3288,7 @@ if (false) if ((int)Tools::getValue('value') != 0 && (int)Tools::getValue('value') != 1) return Tools::jsonEncode(array('error' => 'Uncorrect value')); - StockAvailable::setProductDependsOnStock((int)Tools::getValue('value'), $product->id); + StockAvailable::setProductDependsOnStock($product->id, (int)Tools::getValue('value')); break; case 'out_of_stock': @@ -3297,7 +3297,7 @@ if (false) if (!in_array((int)Tools::getValue('value'), array(0, 1, 2))) return Tools::jsonEncode(array('error' => 'Uncorrect value')); - StockAvailable::setProductOutOfStock((int)Tools::getValue('value'), $product->id); + StockAvailable::setProductOutOfStock($product->id, (int)Tools::getValue('value')); break; case 'set_qty': @@ -3306,7 +3306,7 @@ if (false) if (Tools::getValue('id_product_attribute') === false) return Tools::jsonEncode(array('error' => 'Undefined id product attribute')); // @todo : Product class should handle that - $stock_available = new StockAvailable(StockAvailable::getIdStockAvailable($product->id, (int)Tools::getValue('id_product_attribute'))); + $stock_available = new StockAvailable(StockAvailable::getIdStockAvailableByProductId($product->id, (int)Tools::getValue('id_product_attribute'))); if (!$stock_available->id) { $stock_available->id_product = $product->id;