diff --git a/admin-dev/ajax.php b/admin-dev/ajax.php
index 31f10349d..ea0ea6084 100644
--- a/admin-dev/ajax.php
+++ b/admin-dev/ajax.php
@@ -83,6 +83,23 @@ if (Tools::isSubmit('ajaxProductManufacturers'))
die('['.implode(',', $jsonArray).']');
}
}
+
+if (Tools::isSubmit('ajaxProductQuantity'))
+{
+ require_once(dirname(__FILE__).'/tabs/AdminCatalog.php');
+ $catalog = new AdminCatalog();
+ $admin = new AdminProducts();
+
+ $languages = Language::getLanguages(false);
+ $defaultLanguage = (int)(Configuration::get('PS_LANG_DEFAULT'));
+ $product = new Product((int)(Tools::getValue('id_product')));
+ if (!Validate::isLoadedObject($product))
+ die (Tools::displayError('Product cannot be loaded'));
+
+ AdminTab::$currentIndex = 'index.php?tab=AdminCatalog';
+ echo $admin->ajaxProductQuantity($product);
+}
+
if (Tools::isSubmit('ajaxReferrers'))
{
require('tabs/AdminReferrers.php');
diff --git a/admin-dev/tabs/AdminProducts.php b/admin-dev/tabs/AdminProducts.php
index b6be9edcd..ee9be0dbc 100644
--- a/admin-dev/tabs/AdminProducts.php
+++ b/admin-dev/tabs/AdminProducts.php
@@ -555,15 +555,15 @@ class AdminProducts extends AdminTab
Tools::getValue('attribute_price') * Tools::getValue('attribute_price_impact'),
Tools::getValue('attribute_weight') * Tools::getValue('attribute_weight_impact'),
Tools::getValue('attribute_unity') * Tools::getValue('attribute_unit_impact'),
- Tools::getValue('attribute_ecotax'),
- Tools::getValue('attribute_quantity'),
- Tools::getValue('id_image_attr'),
- Tools::getValue('attribute_reference'),
- Tools::getValue('attribute_supplier_reference'),
- Tools::getValue('attribute_ean13'),
- Tools::getValue('attribute_default'),
- Tools::getValue('attribute_location'),
- Tools::getValue('attribute_upc'));
+ Tools::getValue('attribute_ecotax'),
+ Tools::getValue('attribute_quantity'),
+ Tools::getValue('id_image_attr'),
+ Tools::getValue('attribute_reference'),
+ Tools::getValue('attribute_supplier_reference'),
+ Tools::getValue('attribute_ean13'),
+ Tools::getValue('attribute_default'),
+ Tools::getValue('attribute_location'),
+ Tools::getValue('attribute_upc'));
$this->updateDownloadProduct($product, 0, $id_product_attribute);
}
else
@@ -1682,7 +1682,8 @@ class AdminProducts extends AdminTab
| '.$this->l('File:').' |
-
-
-
-
- 00
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
'.$this->l('Format:').' JPG, GIF, PNG. '.$this->l('Filesize:').' '.($this->maxImageSize / 1000).''.$this->l('Kb max.').'
@@ -3685,6 +3660,284 @@ class AdminProducts extends AdminTab
echo '
';
}
+
+
+ function displayQuantities($obj)
+ {
+
+ // Get all id_product_atribute
+ $attributes = $obj->getAttributeCombinaisons($this->context->language->id);
+ if (empty($attributes))
+ $attributes[] = array(
+ 'id_product_attribute' => 0,
+ 'attribute_name' => ''
+ );
+
+ // Get physical quantities & available quantities
+ $totalQuantity = 0;
+ $physicalQuantity = array();
+ $availableQuantity = array();
+ $productDesignation = array();
+ foreach ($attributes as $attribute)
+ {
+ $physicalQuantity[$attribute['id_product_attribute']] = (int)rand(0, 100);//StockManagerFactory::getManager()->getProductPhysicalQuantities((int)$obj->id, $attribute['id_product_attribute']);
+ $totalQuantity += $physicalQuantity[$attribute['id_product_attribute']];
+
+ // @TODO
+ $availableQuantity[$attribute['id_product_attribute']] = StockAvailable::getStockAvailableForProduct((int)$obj->id, $attribute['id_product_attribute']);
+
+ // Get all product designation
+ $productDesignation[$attribute['id_product_attribute']] = $obj->name[$this->context->language->id].' '.$attribute['attribute_name'];
+ }
+
+ $return = '
+
+ 8. '.$this->l('Quantities').'
+
+
+
+ |
+ '.$this->l('Available stock in warehouses').'
+ |
+
+
+
+
+ '.sprintf($this->l('There is %s quantities available in stock for this product'), ''.$totalQuantity.'').'
+
+
+
+
+
+
+
+ | '.$this->l('Quantity').' |
+ '.$this->l('Designation').' |
+
+
+ ';
+ foreach ($attributes as $attribute)
+ $return .= '
+
+ | '.$physicalQuantity[$attribute['id_product_attribute']].' |
+ '.$productDesignation[$attribute['id_product_attribute']].' |
+ ';
+ $return .= '
+
+
+ |
+
+
+
+
+
+
+
+ |
+ '.$this->l('Available quantities for sale').'
+ |
+
+
+
+
+
+
+
+ ';
+ $return .= '
+ ';
+ $return .= '
+
+ ';
+
+ return $return;
+ }
+
+ public function ajaxProductQuantity($obj)
+ {
+ if(!Tools::getValue('action'))
+ return Tools::jsonEncode(array('error' => 'Undefined action'));
+
+ switch(Tools::getValue('action'))
+ {
+ case 'depends_on_stock':elog((int)Tools::getValue('value'));
+ if (Tools::getValue('value') === false)
+ return Tools::jsonEncode(array('error' => 'Undefined value'));
+ if ((int)Tools::getValue('value') != 0 && (int)Tools::getValue('value') != 1)
+ return Tools::jsonEncode(array('error' => 'Uncorrect value'));
+
+ StockAvailable::setProductDependsOnStock((int)Tools::getValue('value'), $obj->id);
+ break;
+
+ case 'out_of_stock':
+ if (Tools::getValue('value') === false)
+ return Tools::jsonEncode(array('error' => 'Undefined value'));
+ if (!in_array((int)Tools::getValue('value'), array(0, 1, 2)))
+ return Tools::jsonEncode(array('error' => 'Uncorrect value'));
+
+ StockAvailable::setProductOutOfStock((int)Tools::getValue('value'), $obj->id);
+ break;
+
+ case 'set_qty':
+ if (Tools::getValue('value') === false)
+ return Tools::jsonEncode(array('error' => 'Undefined value'));
+ if (Tools::getValue('id_product_attribute') === false)
+ return Tools::jsonEncode(array('error' => 'Undefined id product attribute'));
+ $stock_available = new StockAvailable(StockAvailable::getIdStockAvailable($obj->id, (int)Tools::getValue('id_product_attribute')));
+ $stock_available->quantity = (int)Tools::getValue('value');
+ $stock_available->save();
+ break;
+ }
+
+ return Tools::jsonEncode(array('error' => false));
+ }
public function getLineTableImage($image, $imagesTotal, $token, $shops)
{
diff --git a/classes/Cart.php b/classes/Cart.php
index 0f0ec4b77..dc88e08b4 100644
--- a/classes/Cart.php
+++ b/classes/Cart.php
@@ -373,7 +373,7 @@ class CartCore extends ObjectModel
// Build SELECT
$sql->select('cp.`id_product_attribute`, cp.`id_product`, cp.`quantity` AS cart_quantity, cp.id_shop, pl.`name`, p.`is_virtual`,
pl.`description_short`, pl.`available_now`, pl.`available_later`, p.`id_product`, p.`id_category_default`, p.`id_supplier`, p.`id_manufacturer`,
- p.`on_sale`, p.`ecotax`, p.`additional_shipping_cost`, p.`available_for_order`, p.`price`, p.`weight`, p.`width`, p.`height`, p.`depth`, p.`out_of_stock`,
+ p.`on_sale`, p.`ecotax`, p.`additional_shipping_cost`, p.`available_for_order`, p.`price`, p.`weight`, p.`width`, p.`height`, p.`depth`, sa.`out_of_stock`,
p.`active`, p.`date_add`, p.`date_upd`, t.`id_tax`, tl.`name` AS tax, t.`rate`, stock.quantity, pl.`link_rewrite`, cl.`link_rewrite` AS category,
CONCAT(cp.`id_product`, cp.`id_product_attribute`) AS unique_id');
@@ -388,6 +388,7 @@ class CartCore extends ObjectModel
AND tr.`id_state` = 0
AND tr.`zipcode_from` = 0');
$sql->leftJoin('tax t ON t.`id_tax` = tr.`id_tax`');
+ $sql->leftJoin('stock_available sa ON sa.`id_product` = p.`id_product` AND sa.id_product_attribute = 0');
$sql->leftJoin('tax_lang tl ON t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)$this->id_lang);
$sql->leftJoin('category_lang cl ON p.`id_category_default` = cl.`id_category` AND cl.`id_lang` = '.(int)$this->id_lang.Context::getContext()->shop->sqlLang('cl'));
@@ -632,7 +633,7 @@ class CartCore extends ObjectModel
{
if ($operator == 'up')
{
- $sql = 'SELECT p.out_of_stock, stock.quantity
+ $sql = 'SELECT stock.out_of_stock, stock.quantity
FROM '._DB_PREFIX_.'product p
'.Product::sqlStock('p', $id_product_attribute, true, $shop).'
WHERE p.id_product = '.$id_product;
@@ -673,7 +674,7 @@ class CartCore extends ObjectModel
/* Add product to the cart */
else
{
- $sql = 'SELECT p.out_of_stock, stock.quantity
+ $sql = 'SELECT stock.out_of_stock, stock.quantity
FROM '._DB_PREFIX_.'product p
'.Product::sqlStock('p', $id_product_attribute, true, $shop).'
WHERE p.id_product = '.$id_product;
diff --git a/classes/Category.php b/classes/Category.php
index 587dc0f97..39f6aec5c 100644
--- a/classes/Category.php
+++ b/classes/Category.php
@@ -567,7 +567,7 @@ class CategoryCore extends ObjectModel
return (int)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql);
}
- $sql = 'SELECT p.*, stock.quantity, pa.`id_product_attribute`, pl.`description`, pl.`description_short`, pl.`available_now`, pl.`available_later`, pl.`link_rewrite`, pl.`meta_description`, pl.`meta_keywords`, pl.`meta_title`, pl.`name`, i.`id_image`, il.`legend`, m.`name` AS manufacturer_name, tl.`name` AS tax_name, t.`rate`, cl.`name` AS category_default, DATEDIFF(p.`date_add`, DATE_SUB(NOW(), INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY)) > 0 AS new,
+ $sql = 'SELECT p.*, sa.out_of_stock, stock.quantity, pa.`id_product_attribute`, pl.`description`, pl.`description_short`, pl.`available_now`, pl.`available_later`, pl.`link_rewrite`, pl.`meta_description`, pl.`meta_keywords`, pl.`meta_title`, pl.`name`, i.`id_image`, il.`legend`, m.`name` AS manufacturer_name, tl.`name` AS tax_name, t.`rate`, cl.`name` AS category_default, DATEDIFF(p.`date_add`, DATE_SUB(NOW(), INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY)) > 0 AS new,
(p.`price` * IF(t.`rate`,((100 + (t.`rate`))/100),1)) AS orderprice
FROM `'._DB_PREFIX_.'category_product` cp
LEFT JOIN `'._DB_PREFIX_.'product` p ON p.`id_product` = cp.`id_product`
@@ -581,10 +581,11 @@ class CategoryCore extends ObjectModel
LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group`
AND tr.`id_country` = '.(int)$context->country->id.'
AND tr.`id_state` = 0
- AND tr.`zipcode_from` = 0)
- LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`)
+ AND tr.`zipcode_from` = 0)
+ LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`)
LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)$id_lang.')
LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON m.`id_manufacturer` = p.`id_manufacturer`
+ LEFT JOIN `'._DB_PREFIX_.'stock_available` sa ON sa.`id_product` = p.`id_product` AND sa.id_product_attribute = 0
WHERE cp.`id_category` = '.(int)($this->id)
.($active ? ' AND p.`active` = 1' : '')
.($id_supplier ? ' AND p.id_supplier = '.(int)$id_supplier : '');
diff --git a/classes/Manufacturer.php b/classes/Manufacturer.php
index b9a6a88d3..bb74bf40f 100644
--- a/classes/Manufacturer.php
+++ b/classes/Manufacturer.php
@@ -277,7 +277,7 @@ class ManufacturerCore extends ObjectModel
return (int)(sizeof($result));
}
- $sql = 'SELECT p.*, pa.`id_product_attribute`, pl.`description`, pl.`description_short`, pl.`link_rewrite`, pl.`meta_description`, pl.`meta_keywords`, pl.`meta_title`, pl.`name`, i.`id_image`, il.`legend`, m.`name` AS manufacturer_name, tl.`name` AS tax_name, t.`rate`, DATEDIFF(p.`date_add`, DATE_SUB(NOW(), INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY)) > 0 AS new,
+ $sql = 'SELECT p.*, sa.out_of_stock, pa.`id_product_attribute`, pl.`description`, pl.`description_short`, pl.`link_rewrite`, pl.`meta_description`, pl.`meta_keywords`, pl.`meta_title`, pl.`name`, i.`id_image`, il.`legend`, m.`name` AS manufacturer_name, tl.`name` AS tax_name, t.`rate`, DATEDIFF(p.`date_add`, DATE_SUB(NOW(), INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY)) > 0 AS new,
(p.`price` * ((100 + (t.`rate`))/100)) AS orderprice
FROM `'._DB_PREFIX_.'product` p
'.$context->shop->sqlAsso('product', 'p').'
@@ -286,12 +286,13 @@ class ManufacturerCore extends ObjectModel
LEFT JOIN `'._DB_PREFIX_.'image` i ON (i.`id_product` = p.`id_product` AND i.`cover` = 1)
LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.')
LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group`
- AND tr.`id_country` = '.(int)$context->country->id.'
- AND tr.`id_state` = 0
- AND tr.`zipcode_from` = 0)
- LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`)
+ AND tr.`id_country` = '.(int)$context->country->id.'
+ AND tr.`id_state` = 0
+ AND tr.`zipcode_from` = 0)
+ LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`)
LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)$id_lang.')
- LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON m.`id_manufacturer` = p.`id_manufacturer`
+ LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON (m.`id_manufacturer` = p.`id_manufacturer`)
+ LEFT JOIN `'._DB_PREFIX_.'stock_available` sa ON (sa.`id_product` = p.`id_product` AND sa.id_product_attribute = 0)
WHERE p.`id_manufacturer` = '.(int)($id_manufacturer).($active ? ' AND p.`active` = 1' : '').'
AND p.`id_product` IN (
SELECT cp.`id_product`
diff --git a/classes/Product.php b/classes/Product.php
index 952fcf43b..5973edff8 100644
--- a/classes/Product.php
+++ b/classes/Product.php
@@ -147,9 +147,6 @@ class ProductCore extends ObjectModel
/** @var string Meta tag title */
public $meta_title;
- /** @var integer Out of stock behavior */
- public $out_of_stock = 2;
-
/** @var boolean Product statuts */
public $quantity_discount = 0;
@@ -239,7 +236,6 @@ class ProductCore extends ObjectModel
'height' => 'isUnsignedFloat',
'depth' => 'isUnsignedFloat',
'weight' => 'isUnsignedFloat',
- 'out_of_stock' => 'isUnsignedInt',
'quantity_discount' => 'isBool',
'customizable' => 'isUnsignedInt',
'uploadable_files' => 'isUnsignedInt',
@@ -274,7 +270,6 @@ class ProductCore extends ObjectModel
'id_manufacturer' => array('xlink_resource' => 'manufacturers'),
'id_supplier' => array('xlink_resource' => 'suppliers'),
'id_category_default' => array('xlink_resource' => 'categories'),
- 'out_of_stock' => array('required' => true),
'new' => array(),
'cache_default_attribute' => array(),
'id_default_image' => array('getter' => 'getCoverWs', 'setter' => 'setCoverWs', 'xlink_resource' => array('resourceName' => 'images', 'subResourceName' => 'products')),
@@ -340,6 +335,8 @@ class ProductCore extends ObjectModel
* @FIXME
*/
$this->quantity = 0;
+ $this->out_of_stock = $this->getOutOfStock();
+ $this->depends_on_stock = $this->getDependsOnStock();
if ($this->id_category_default)
$this->category = Category::getLinkRewrite((int)$this->id_category_default, (int)$id_lang);
@@ -373,7 +370,6 @@ class ProductCore extends ObjectModel
$fields['height'] = (float)$this->height;
$fields['depth'] = (float)$this->depth;
$fields['weight'] = (float)$this->weight;
- $fields['out_of_stock'] = pSQL($this->out_of_stock);
$fields['quantity_discount'] = (int)$this->quantity_discount;
$fields['customizable'] = (int)$this->customizable;
$fields['uploadable_files'] = (int)$this->uploadable_files;
@@ -1407,7 +1403,7 @@ class ProductCore extends ObjectModel
}
$sql = new DbQuery();
- $sql->select('p.*, pl.`description`, pl.`description_short`, pl.`link_rewrite`, pl.`meta_description`, pl.`meta_keywords`, pl.`meta_title`, pl.`name`, p.`ean13`, p.`upc`,
+ $sql->select('p.*, sa.out_of_stock, pl.`description`, pl.`description_short`, pl.`link_rewrite`, pl.`meta_description`, pl.`meta_keywords`, pl.`meta_title`, pl.`name`, p.`ean13`, p.`upc`,
i.`id_image`, il.`legend`, t.`rate`, m.`name` AS manufacturer_name, DATEDIFF(p.`date_add`, DATE_SUB(NOW(),
INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY)) > 0 AS new,
(p.`price` * ((100 + (t.`rate`))/100)) AS orderprice');
@@ -1420,6 +1416,7 @@ class ProductCore extends ObjectModel
$sql->leftJoin('tax_rule tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group` AND tr.`id_country` = '.(int)$context->country->id.' AND tr.`id_state` = 0)');
$sql->leftJoin('tax t ON (t.`id_tax` = tr.`id_tax`)');
$sql->leftJoin('manufacturer m ON (m.`id_manufacturer` = p.`id_manufacturer`)');
+ $sql->leftJoin('stock_available sa ON (sa.`id_product` = p.`id_product` AND sa.id_product_attribute = 0)');
$sql->where('p.`active` = 1');
$sql->where('DATEDIFF(p.`date_add`, DATE_SUB(NOW(), INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY)) > 0');
@@ -1500,7 +1497,7 @@ class ProductCore extends ObjectModel
if (!$id_product)
return false;
- $sql = 'SELECT p.*, pl.`description`, pl.`description_short`, pl.`link_rewrite`, pl.`meta_description`, pl.`meta_keywords`, pl.`meta_title`, pl.`name`, p.`ean13`, p.`upc`,
+ $sql = 'SELECT p.*, sa.out_of_stock, sa.out_of_stock out_of_stock, pl.`description`, pl.`description_short`, pl.`link_rewrite`, pl.`meta_description`, pl.`meta_keywords`, pl.`meta_title`, pl.`name`, p.`ean13`, p.`upc`,
i.`id_image`, il.`legend`, t.`rate`
FROM `'._DB_PREFIX_.'product` p
LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.(int)$id_lang.$context->shop->sqlLang('pl').')
@@ -1510,6 +1507,7 @@ class ProductCore extends ObjectModel
AND tr.`id_country` = '.(int)Context::getContext()->country->id.'
AND tr.`id_state` = 0)
LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`)
+ LEFT JOIN `'._DB_PREFIX_.'stock_available` sa ON sa.`id_product` = p.`id_product` AND sa.id_product_attribute = 0
WHERE p.id_product = '.(int)$id_product;
$row = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow($sql);
@@ -1565,7 +1563,7 @@ class ProductCore extends ObjectModel
return (int)($result['nb']);
}
- $sql = 'SELECT p.*, stock.quantity, pl.`description`, pl.`description_short`, pl.`link_rewrite`, pl.`meta_description`, pl.`meta_keywords`, pl.`meta_title`,
+ $sql = 'SELECT p.*, sa.out_of_stock, stock.quantity, pl.`description`, pl.`description_short`, pl.`link_rewrite`, pl.`meta_description`, pl.`meta_keywords`, pl.`meta_title`,
pl.`name`, i.`id_image`, il.`legend`, t.`rate`, m.`name` AS manufacturer_name,
DATEDIFF(p.`date_add`, DATE_SUB(NOW(), INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY)) > 0 AS new
FROM `'._DB_PREFIX_.'product` p
@@ -1579,6 +1577,7 @@ class ProductCore extends ObjectModel
AND tr.`id_state` = 0)
LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`)
LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON (m.`id_manufacturer` = p.`id_manufacturer`)
+ LEFT JOIN `'._DB_PREFIX_.'stock_available` sa ON (sa.`id_product` = p.`id_product` AND sa.id_product_attribute = 0)
WHERE p.`active` = 1
AND p.`show_price` = 1
'.((!$beginning AND !$ending) ? ' AND p.`id_product` IN ('.((is_array($ids_product) AND count($ids_product)) ? implode(', ', $ids_product) : 0).')' : '').'
@@ -2066,7 +2065,7 @@ class ProductCore extends ObjectModel
{
// @todo remove this code when query builder is accepted or removed
$method = ($innerJoin) ? 'innerJoin' : 'leftJoin';
- $sql->$method('stock stock ON stock.id_product = '.pSQL($productAlias).'.id_product');
+ $sql->$method('stock_available stock ON stock.id_product = '.pSQL($productAlias).'.id_product');
if (!is_null($productAttribute))
{
if (!Combination::isFeatureActive())
@@ -2080,7 +2079,7 @@ class ProductCore extends ObjectModel
}
else
{
- $sql = (($innerJoin) ? ' INNER ' : ' LEFT ').'JOIN '._DB_PREFIX_.'stock stock ON stock.id_product = '.pSQL($productAlias).'.id_product';
+ $sql = (($innerJoin) ? ' INNER ' : ' LEFT ').'JOIN '._DB_PREFIX_.'stock_available stock ON stock.id_product = '.pSQL($productAlias).'.id_product';
if (!is_null($productAttribute))
{
if (!Combination::isFeatureActive())
@@ -2192,7 +2191,7 @@ class ProductCore extends ObjectModel
if (!isset(self::$cacheStock[$this->id][$id_product_attribute]))
{
$sql = 'SELECT quantity
- FROM '._DB_PREFIX_.'stock
+ FROM '._DB_PREFIX_.'stock_available
WHERE id_product = '.$this->id.'
AND id_product_attribute = '.(int)$id_product_attribute.
$context->shop->sqlRestriction(Shop::SHARE_STOCK);
@@ -2202,6 +2201,54 @@ class ProductCore extends ObjectModel
return self::$cacheStock[$this->id][$id_product_attribute];
}
+ /**
+ * Get the value of "out of stock" of current product
+ * "ouf of stock" allow to order product without stock
+ *
+ * @since 1.5.0
+ * @param Context $context
+ * @return int
+ */
+ public function getOutOfStock(Context $context = null)
+ {
+ if (!$this->id)
+ return 0;
+ if (!$context)
+ $context = Context::getContext();
+
+ $id_shop = $context->shop->getID(true);
+ $sql = 'SELECT out_of_stock
+ FROM '._DB_PREFIX_.'stock_available
+ WHERE id_product = '.$this->id.'
+ AND id_product_attribute = 0'.
+ $context->shop->sqlRestriction(Shop::SHARE_STOCK);
+ return (int)Db::getInstance()->getValue($sql);
+ }
+
+ /**
+ * Get the value of "depends on stock" of current product
+ * "depends on stock" allow managing quantity available manually
+ *
+ * @since 1.5.0
+ * @param Context $context
+ * @return int
+ */
+ public function getDependsOnStock(Context $context = null)
+ {
+ if (!$this->id)
+ return 0;
+ if (!$context)
+ $context = Context::getContext();
+
+ $id_shop = $context->shop->getID(true);
+ $sql = 'SELECT depends_on_stock
+ FROM '._DB_PREFIX_.'stock_available
+ WHERE id_product = '.$this->id.'
+ AND id_product_attribute = 0'.
+ $context->shop->sqlRestriction(Shop::SHARE_STOCK);
+ return (int)Db::getInstance()->getValue($sql);
+ }
+
/**
* Update available product quantities
*
@@ -2255,9 +2302,9 @@ class ProductCore extends ObjectModel
return true;
}
- public static function isAvailableWhenOutOfStock($oos)
+ public static function isAvailableWhenOutOfStock($out_of_stock)
{
- return !Configuration::get('PS_STOCK_MANAGEMENT') ? true : ((int)($oos) == 2 ? (int)(Configuration::get('PS_ORDER_OUT_OF_STOCK')) : (int)($oos));
+ return !Configuration::get('PS_STOCK_MANAGEMENT') ? true : ((int)($out_of_stock) == 2 ? (int)(Configuration::get('PS_ORDER_OUT_OF_STOCK')) : (int)($out_of_stock));
}
/**
@@ -2386,7 +2433,7 @@ class ProductCore extends ObjectModel
if (!$context)
$context = Context::getContext();
- $sql = 'SELECT p.*, pl.`description`, pl.`description_short`, pl.`link_rewrite`, pl.`meta_description`, pl.`meta_keywords`, pl.`meta_title`, pl.`name`, p.`ean13`, p.`upc`,
+ $sql = 'SELECT p.*, sa.out_of_stock, pl.`description`, pl.`description_short`, pl.`link_rewrite`, pl.`meta_description`, pl.`meta_keywords`, pl.`meta_title`, pl.`name`, p.`ean13`, p.`upc`,
i.`id_image`, il.`legend`, t.`rate`, m.`name` as manufacturer_name, cl.`name` AS category_default, DATEDIFF(p.`date_add`, DATE_SUB(NOW(),
INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY)) > 0 AS new
FROM `'._DB_PREFIX_.'accessory`
@@ -2401,6 +2448,7 @@ class ProductCore extends ObjectModel
AND tr.`id_country` = '.(int)Context::getContext()->country->id.'
AND tr.`id_state` = 0)
LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`)
+ LEFT JOIN `'._DB_PREFIX_.'stock_available` sa ON (sa.`id_product` = p.`id_product` AND sa.id_product_attribute = 0)
WHERE `id_product_1` = '.(int)($this->id).
($active ? ' AND p.`active` = 1' : '');
if (!$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql))
@@ -3633,5 +3681,20 @@ class ProductCore extends ObjectModel
return isset($row['reference']);
}
+
+ /**
+ * Get all product attributes ids
+ *
+ * @since 1.5.0
+ * @param int $id_product the id of the product
+ * @return array product attribute id list
+ */
+ public static function getProductAttributesIds($id_product)
+ {
+ return Db::getInstance()->executeS('
+ SELECT id_product_attribute
+ FROM `'._DB_PREFIX_.'product_attribute`
+ WHERE `id_product` = '.(int)$id_product);
+ }
}
diff --git a/classes/ProductSale.php b/classes/ProductSale.php
index 97fe24847..8c17e08ca 100644
--- a/classes/ProductSale.php
+++ b/classes/ProductSale.php
@@ -78,7 +78,7 @@ class ProductSaleCore
$groups = FrontController::getCurrentCustomerGroups();
$sqlGroups = (count($groups) ? 'IN ('.implode(',', $groups).')' : '= 1');
- $sql = 'SELECT p.*,
+ $sql = 'SELECT p.*, sa.out_of_stock,
pl.`description`, pl.`description_short`, pl.`link_rewrite`, pl.`meta_description`, pl.`meta_keywords`, pl.`meta_title`, pl.`name`, m.`name` AS manufacturer_name, p.`id_manufacturer` as id_manufacturer,
i.`id_image`, il.`legend`,
ps.`quantity` AS sales, t.`rate`, pl.`meta_keywords`, pl.`meta_title`, pl.`meta_description`,
@@ -91,9 +91,10 @@ class ProductSaleCore
LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.')
LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON (m.`id_manufacturer` = p.`id_manufacturer`)
LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON p.`id_tax_rules_group` = tr.`id_tax_rules_group`
- AND tr.`id_country` = '.(int)Context::getContext()->country->id.'
- AND tr.`id_state` = 0
- LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`)
+ AND tr.`id_country` = '.(int)Context::getContext()->country->id.'
+ AND tr.`id_state` = 0
+ LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`)
+ LEFT JOIN `'._DB_PREFIX_.'stock_available` sa ON (sa.`id_product` = p.`id_product` AND sa.id_product_attribute = 0)
WHERE p.`active` = 1
AND p.`id_product` IN (
SELECT cp.`id_product`
diff --git a/classes/Search.php b/classes/Search.php
index 1c4832d1a..0bc378293 100644
--- a/classes/Search.php
+++ b/classes/Search.php
@@ -256,17 +256,18 @@ class SearchCore
return $db->executeS($sql);
}
- $sql = 'SELECT p.*, pl.`description_short`, pl.`available_now`, pl.`available_later`, pl.`link_rewrite`, pl.`name`,
+ $sql = 'SELECT p.*, sa.out_of_stock, pl.`description_short`, pl.`available_now`, pl.`available_later`, pl.`link_rewrite`, pl.`name`,
tax.`rate`, i.`id_image`, il.`legend`, m.`name` manufacturer_name '.$score.', DATEDIFF(p.`date_add`, DATE_SUB(NOW(), INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY)) > 0 new
FROM '._DB_PREFIX_.'product p
INNER JOIN `'._DB_PREFIX_.'product_lang` pl ON (p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.(int)$id_lang.$context->shop->sqlLang('pl').')
LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group`
- AND tr.`id_country` = '.(int)$context->country->id.'
- AND tr.`id_state` = 0)
- LEFT JOIN `'._DB_PREFIX_.'tax` tax ON (tax.`id_tax` = tr.`id_tax`)
+ AND tr.`id_country` = '.(int)$context->country->id.'
+ AND tr.`id_state` = 0)
+ LEFT JOIN `'._DB_PREFIX_.'tax` tax ON (tax.`id_tax` = tr.`id_tax`)
LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON m.`id_manufacturer` = p.`id_manufacturer`
LEFT JOIN `'._DB_PREFIX_.'image` i ON (i.`id_product` = p.`id_product` AND i.`cover` = 1)
LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.')
+ LEFT JOIN `'._DB_PREFIX_.'stock_available` sa ON (sa.`id_product` = p.`id_product` AND sa.id_product_attribute = 0)
WHERE p.`id_product` '.$productPool.'
'.($orderBy ? 'ORDER BY '.$orderBy : '').($orderWay ? ' '.$orderWay : '').'
LIMIT '.(int)(($pageNumber - 1) * $pageSize).','.(int)$pageSize;
@@ -276,9 +277,9 @@ class SearchCore
FROM '._DB_PREFIX_.'product p
INNER JOIN `'._DB_PREFIX_.'product_lang` pl ON (p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.(int)$id_lang.$context->shop->sqlLang('pl').')
LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group`
- AND tr.`id_country` = '.(int)Context::getContext()->country->id.'
- AND tr.`id_state` = 0)
- LEFT JOIN `'._DB_PREFIX_.'tax` tax ON (tax.`id_tax` = tr.`id_tax`)
+ AND tr.`id_country` = '.(int)Context::getContext()->country->id.'
+ AND tr.`id_state` = 0)
+ LEFT JOIN `'._DB_PREFIX_.'tax` tax ON (tax.`id_tax` = tr.`id_tax`)
LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON m.`id_manufacturer` = p.`id_manufacturer`
LEFT JOIN `'._DB_PREFIX_.'image` i ON (i.`id_product` = p.`id_product` AND i.`cover` = 1)
LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.')
@@ -564,7 +565,7 @@ class SearchCore
return (int)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql);
}
- $sql = 'SELECT DISTINCT p.*, pl.`description_short`, pl.`link_rewrite`, pl.`name`, tax.`rate`, i.`id_image`, il.`legend`, m.`name` manufacturer_name, 1 position,
+ $sql = 'SELECT DISTINCT p.*, sa.out_of_stock, pl.`description_short`, pl.`link_rewrite`, pl.`name`, tax.`rate`, i.`id_image`, il.`legend`, m.`name` manufacturer_name, 1 position,
DATEDIFF(p.`date_add`, DATE_SUB(NOW(), INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY)) > 0 new
FROM `'._DB_PREFIX_.'product` p
INNER JOIN `'._DB_PREFIX_.'product_lang` pl ON (p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.(int)$id_lang.$context->shop->sqlLang('pl').')
@@ -574,12 +575,13 @@ class SearchCore
LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group`
AND tr.`id_country` = '.(int)$context->country->id.'
AND tr.`id_state` = 0)
- LEFT JOIN `'._DB_PREFIX_.'tax` tax ON (tax.`id_tax` = tr.`id_tax`)
+ LEFT JOIN `'._DB_PREFIX_.'tax` tax ON (tax.`id_tax` = tr.`id_tax`)
LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON (m.`id_manufacturer` = p.`id_manufacturer`)
LEFT JOIN `'._DB_PREFIX_.'product_tag` pt ON (p.`id_product` = pt.`id_product`)
LEFT JOIN `'._DB_PREFIX_.'tag` t ON (pt.`id_tag` = t.`id_tag` AND t.`id_lang` = '.(int)$id_lang.')
LEFT JOIN `'._DB_PREFIX_.'category_product` cp ON (cp.`id_product` = p.`id_product`)
LEFT JOIN `'._DB_PREFIX_.'category_group` cg ON (cg.`id_category` = cp.`id_category`)
+ LEFT JOIN `'._DB_PREFIX_.'stock_available` sa ON (sa.`id_product` = p.`id_product` AND sa.id_product_attribute = 0)
WHERE p.`active` = 1
AND cg.`id_group` '.(!$id_customer ? '= 1' : 'IN (
SELECT id_group FROM '._DB_PREFIX_.'customer_group
diff --git a/classes/Supplier.php b/classes/Supplier.php
index ac4d3fe6a..7d397c258 100644
--- a/classes/Supplier.php
+++ b/classes/Supplier.php
@@ -214,7 +214,7 @@ class SupplierCore extends ObjectModel
return (int)(sizeof($result));
}
- $sql = 'SELECT p.*, pl.`description`, pl.`description_short`, pl.`link_rewrite`, pl.`meta_description`, pl.`meta_keywords`, pl.`meta_title`, pl.`name`, i.`id_image`, il.`legend`, s.`name` AS supplier_name, tl.`name` AS tax_name, t.`rate`, DATEDIFF(p.`date_add`, DATE_SUB(NOW(), INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY)) > 0 AS new,
+ $sql = 'SELECT p.*, sa.out_of_stock, pl.`description`, pl.`description_short`, pl.`link_rewrite`, pl.`meta_description`, pl.`meta_keywords`, pl.`meta_title`, pl.`name`, i.`id_image`, il.`legend`, s.`name` AS supplier_name, tl.`name` AS tax_name, t.`rate`, DATEDIFF(p.`date_add`, DATE_SUB(NOW(), INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY)) > 0 AS new,
(p.`price` * ((100 + (t.`rate`))/100)) AS orderprice, m.`name` AS manufacturer_name
FROM `'._DB_PREFIX_.'product` p
LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.(int)$id_lang.Context::getContext()->shop->sqlLang('pl').')
@@ -224,10 +224,11 @@ class SupplierCore extends ObjectModel
AND tr.`id_country` = '.(int)Context::getContext()->country->id.'
AND tr.`id_state` = 0
AND tr.`zipcode_from` = 0)
- LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`)
+ LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`)
LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)$id_lang.')
LEFT JOIN `'._DB_PREFIX_.'supplier` s ON s.`id_supplier` = p.`id_supplier`
LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON m.`id_manufacturer` = p.`id_manufacturer`
+ LEFT JOIN `'._DB_PREFIX_.'stock_available` sa ON (sa.`id_product` = p.`id_product` AND sa.id_product_attribute = 0)
WHERE p.`id_supplier` = '.(int)$id_supplier.($active ? ' AND p.`active` = 1' : '').'
AND p.`id_product` IN (
SELECT cp.`id_product`
diff --git a/classes/stock/StockAvailable.php b/classes/stock/StockAvailable.php
index 9fc62a523..06a60ee75 100644
--- a/classes/stock/StockAvailable.php
+++ b/classes/stock/StockAvailable.php
@@ -60,8 +60,8 @@ class StockAvailableCore extends ObjectModel
'id_product_attribute' => 'isUnsignedId',
'id_shop' => 'isUnsignedId',
'quantity' => 'isInt',
- 'depends_on_stocks' => 'isBool',
- 'out_of_stock' => 'isBool'
+ 'depends_on_stock' => 'isBool',
+ 'out_of_stock' => 'isInt'
);
protected $table = 'stock_available';
@@ -74,7 +74,7 @@ class StockAvailableCore extends ObjectModel
$fields['id_product_attribute'] = (int)$this->id_product_attribute;
$fields['id_shop'] = (int)$this->id_shop;
$fields['quantity'] = (int)$this->quantity;
- $fields['depends_on_stocks'] = (bool)$this->depends_on_stocks;
+ $fields['depends_on_stock'] = (bool)$this->depends_on_stock;
$fields['out_of_stock'] = (bool)$this->out_of_stock;
return $fields;
}
@@ -87,8 +87,11 @@ class StockAvailableCore extends ObjectModel
* @param int $id_shop
* @return int
*/
- public static function getIdStockAvailable($id_product, $id_product_attribute = null, $id_shop)
+ public static function getIdStockAvailable($id_product, $id_product_attribute = null, $id_shop = null)
{
+ if (is_null($id_shop))
+ $id_shop = Context::getContext()->shop->getID(true);
+
$query = new DbQuery();
$query->select('id_stock_available');
$query->from('stock_available');
@@ -163,4 +166,97 @@ class StockAvailableCore extends ObjectModel
Db::getInstance()->autoExecute($query['table'], $query['data'], $query['type'], $query['where']);
}
}
+
+ /**
+ * 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
+ */
+ public static function setProductDependsOnStock($depends_on_stock, $id_product, $id_shop = null)
+ {
+ if (is_null($id_shop))
+ $id_shop = Context::getContext()->shop->getID(true);
+
+ Db::getInstance()->autoExecute(
+ 'stock_available',
+ array('depends_on_stock' => (boolean)$depends_on_stock),
+ 'UPDATE',
+ 'id_product = '.(int)$id_product.' AND id_shop = '.(int)$id_shop
+ );
+ if($depends_on_stock)
+ StockAvailable::synchronize($id_product);
+ }
+
+ /**
+ * 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
+ */
+ public static function setProductOutOfStock($out_of_stock, $id_product, $id_shop = null)
+ {
+ if (is_null($id_shop))
+ $id_shop = Context::getContext()->shop->getID(true);
+
+ Db::getInstance()->autoExecute(
+ 'stock_available',
+ array('out_of_stock' => (int)$out_of_stock),
+ 'UPDATE',
+ 'id_product = '.(int)$id_product.' AND id_shop = '.(int)$id_shop
+ );
+ }
+
+ /**
+ * For a given id_product and id_product_attribute, gets stock available
+ *
+ * @param int $id_product
+ * @param int $id_product_attribute
+ * @param int $id_shop
+ */
+ public static function getStockAvailableForProduct($id_product, $id_product_attribute = null, $id_shop = null)
+ {
+ if (is_null($id_shop))
+ $id_shop = Context::getContext()->shop->getID(true);
+
+ $query = new DbQuery();
+ $query->select('quantity');
+ $query->from('stock_available');
+ $query->where('id_product = '.(int)$id_product);
+ $query->where('id_product_attribute = '.(int)$id_product_attribute);
+ $query->where('id_shop = '.(int)$id_shop);
+ return (int)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($query);
+ }
+
+ /**
+ * After saving a quantity available, upgrade the total_quantity_available
+ */
+ public function save($nullValues = false, $autodate = true)
+ {
+ if (!parent::save($nullValues, $autodate))
+ return false;
+
+ if ($this->id_product_attribute = 0)
+ return true;
+
+ $id_stock_available = StockAvailable::getIdStockAvailable($this->id_product, 0, $this->id_shop);
+
+ $total_quantity = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('SELECT sum(quantity) FROM '._DB_PREFIX_.'stock_available
+ WHERE id_product = '.(int)$this->id_product.' AND id_shop = '.(int)$this->id_shop.' AND id_product_attribute <> 0');
+
+ if (!$id_stock_available)
+ {
+ return (int)Db::getInstance()->execute('INSERT '._DB_PREFIX_.'stock_available
+ SET id_product = '.(int)$this->id_product.', id_product_attribute = 0, id_shop = '.(int)$this->id_shop.'
+ quantity = '.(int)$total_quantity);
+ }
+ else
+ {
+ return (int)Db::getInstance()->execute('UPDATE '._DB_PREFIX_.'stock_available
+ SET quantity = '.(int)$total_quantity.'
+ WHERE id_stock_available = '.(int)$id_stock_available);
+ }
+ }
}
\ No newline at end of file
diff --git a/classes/stock/StockManager.php b/classes/stock/StockManager.php
index 7c3b6ffbb..94067eb12 100644
--- a/classes/stock/StockManager.php
+++ b/classes/stock/StockManager.php
@@ -32,9 +32,9 @@
class StockManagerCore implements StockManagerInterface
{
- /**
- * @see StockManagerInterface::isAvailable()
- */
+ /**
+ * @see StockManagerInterface::isAvailable()
+ */
public static function isAvailable()
{
// Default Manager : always available
diff --git a/modules/mailalerts/mailalerts.php b/modules/mailalerts/mailalerts.php
index fe53c1a1d..d663bda14 100644
--- a/modules/mailalerts/mailalerts.php
+++ b/modules/mailalerts/mailalerts.php
@@ -325,7 +325,7 @@ class MailAlerts extends Module
public function hookUpdateProductAttribute($params)
{
$sql = 'SELECT id_product, quantity
- FROM '._DB_PREFIX_.'stock
+ FROM '._DB_PREFIX_.'stock_available
WHERE id_product_attribute = '.(int)$params['id_product_attribute']
.Context::getContext()->shop->sqlRestriction(Shop::SHARE_STOCK);
$result = Db::getInstance()->getRow($sql);
|