// Stock Available : Improve BackOffice interface + Update all SQL requests relative to StockAvailable + code refactoring on Product Class

git-svn-id: http://dev.prestashop.com/svn/v1/branches/1.5.x@10843 b9a71923-0436-4b27-9f14-aed3839534dd
This commit is contained in:
dSevere
2011-12-01 19:09:27 +00:00
parent 8e2102c8ce
commit 8b618652bb
13 changed files with 1241 additions and 619 deletions
@@ -178,6 +178,15 @@
$('.available_quantity input').trigger('change');
});
// bind enter key event on search field
$('.available_quantity').find('input').bind('keypress', function(e) {
var code = (e.keyCode ? e.keyCode : e.which);
if(code == 13) { //Enter keycode
e.stopPropagation();//Stop event propagation
return false;
}
});
$('.available_quantity').find('input').blur(function(e)
{
ajaxCall( { actionQty: 'set_qty', id_product_attribute: $(this).parent().attr('id').split('_')[1], value: $(this).val() } );
+8 -2
View File
@@ -171,11 +171,13 @@ class AttributeCore extends ObjectModel
if (!$shop)
$shop = Context::getContext()->shop;
$sql = 'SELECT quantity
$result = StockAvailable::getQuantityAvailableByProduct(null, (int)$id_product_attribute, $shop->getID());
/*$sql = 'SELECT quantity
FROM '._DB_PREFIX_.'stock_available
WHERE id_product_attribute = '.(int)$id_product_attribute
.$shop->addSqlRestriction();
$result = (int)Db::getInstance()->getValue($sql);
$result = (int)Db::getInstance()->getValue($sql);*/
return ($result && $qty <= $result);
}
@@ -191,6 +193,9 @@ class AttributeCore extends ObjectModel
{
Tools::displayAsDeprecated();
return StockAvailable::getQuantityAvailableByProduct($id_product);
/*
$row = Db::getInstance()->getRow('
SELECT SUM(quantity) as quantity
FROM `'._DB_PREFIX_.'product_attribute`
@@ -200,6 +205,7 @@ class AttributeCore extends ObjectModel
if ($row['quantity'] !== null)
return (int)$row['quantity'];
return false;
*/
}
/**
+1 -2
View File
@@ -357,7 +357,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`, sa.`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`, stock.`out_of_stock`,
sa.`quantity` quantity_available, 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`, cp.`id_address_delivery`) AS unique_id, cp.id_address_delivery');
@@ -416,7 +416,6 @@ class CartCore extends ObjectModel
else
$sql->select('p.`reference` AS reference, p.`supplier_reference` AS supplier_reference, p.`ean13`, p.`upc` AS upc, p.`minimal_quantity` AS minimal_quantity');
$result = Db::getInstance()->executeS($sql);
// Reset the cache before the following return, or else an empty cart will add dozens of queries
+1 -1
View File
@@ -597,7 +597,7 @@ class CategoryCore extends ObjectModel
return (int)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql);
}
$sql = 'SELECT p.*, stock.out_of_stock, stock.quantity, pa.`id_product_attribute`, pl.`description`, pl.`description_short`, pl.`available_now`,
$sql = 'SELECT p.*, stock.out_of_stock, stock.quantity as 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(),
+8 -9
View File
@@ -298,7 +298,7 @@ class ManufacturerCore extends ObjectModel
return (int)count($result);
}
$sql = 'SELECT p.*, sa.out_of_stock, pa.`id_product_attribute`, pl.`description`, pl.`description_short`, pl.`link_rewrite`,
$sql = 'SELECT p.*, stock.out_of_stock, stock.quantity as quantity, 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,
@@ -324,8 +324,7 @@ class ManufacturerCore extends ObjectModel
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)
'.Product::sqlStock('p', 0).'
WHERE p.`id_manufacturer` = '.(int)$id_manufacturer.($active ? '
AND p.`active` = 1' : '').'
AND p.`id_product` IN (
@@ -398,16 +397,16 @@ class ManufacturerCore extends ObjectModel
foreach ($id_addresses as $id)
$ids[] = (int)$id['id'];
$result1 = (Db::getInstance()->execute('
UPDATE `'._DB_PREFIX_.'address`
SET id_manufacturer = 0
WHERE id_manufacturer = '.(int)$this->id.'
UPDATE `'._DB_PREFIX_.'address`
SET id_manufacturer = 0
WHERE id_manufacturer = '.(int)$this->id.'
AND deleted = 0') !== false);
$result2 = true;
if (count($ids))
$result2 = (Db::getInstance()->execute('
UPDATE `'._DB_PREFIX_.'address`
SET id_customer = 0, id_supplier = 0, id_manufacturer = '.(int)$this->id.'
WHERE id_address IN('.implode(',', $ids).')
UPDATE `'._DB_PREFIX_.'address`
SET id_customer = 0, id_supplier = 0, id_manufacturer = '.(int)$this->id.'
WHERE id_address IN('.implode(',', $ids).')
AND deleted = 0') !== false);
return ($result1 && $result2);
}
+1036 -519
View File
File diff suppressed because it is too large Load Diff
+4 -3
View File
@@ -74,11 +74,11 @@ class ProductSaleCore
if ($nbProducts < 1) $nbProducts = 10;
if (empty($orderBy) || $orderBy == 'position') $orderBy = 'sales';
if (empty($orderWay)) $orderWay = 'DESC';
$groups = FrontController::getCurrentCustomerGroups();
$sqlGroups = (count($groups) ? 'IN ('.implode(',', $groups).')' : '= 1');
$sql = 'SELECT p.*, sa.out_of_stock,
$sql = 'SELECT p.*, stock.out_of_stock, stock.quantity as quantity,
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`,
@@ -94,7 +94,7 @@ class ProductSaleCore
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)
'.Product::sqlStock('p').'
WHERE p.`active` = 1
AND p.`id_product` IN (
SELECT cp.`id_product`
@@ -104,6 +104,7 @@ class ProductSaleCore
)
ORDER BY `'.pSQL($orderBy).'` '.pSQL($orderWay).'
LIMIT '.(int)($pageNumber * $nbProducts).', '.(int)$nbProducts;
$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
if ($orderBy == 'price')
+81 -38
View File
@@ -123,7 +123,7 @@ class SearchCore
if (!$indexation)
{
$alias = new Alias(NULL, $string);
$alias = new Alias(null, $string);
if (Validate::isLoadedObject($alias))
$string = $alias->search;
}
@@ -145,7 +145,8 @@ class SearchCore
return $string;
}
public static function find($id_lang, $expr, $pageNumber = 1, $pageSize = 1, $orderBy = 'position', $orderWay = 'desc', $ajax = false, $useCookie = true, Context $context = null)
public static function find($id_lang, $expr, $pageNumber = 1, $pageSize = 1, $orderBy = 'position',
$orderWay = 'desc', $ajax = false, $useCookie = true, Context $context = null)
{
if (!$context)
$context = Context::getContext();
@@ -161,15 +162,15 @@ class SearchCore
if ($pageNumber < 1) $pageNumber = 1;
if ($pageSize < 1) $pageSize = 1;
if (!Validate::isOrderBy($orderBy) OR !Validate::isOrderWay($orderWay))
if (!Validate::isOrderBy($orderBy) || !Validate::isOrderWay($orderWay))
return false;
$intersectArray = array();
$scoreArray = array();
$words = explode(' ', Search::sanitize($expr, $id_lang));
foreach ($words AS $key => $word)
if (!empty($word) AND strlen($word) >= (int)Configuration::get('PS_SEARCH_MINWORDLEN'))
foreach ($words as $key => $word)
if (!empty($word) && strlen($word) >= (int)Configuration::get('PS_SEARCH_MINWORDLEN'))
{
$word = str_replace('%', '\\%', $word);
$word = str_replace('_', '\\_', $word);
@@ -190,11 +191,11 @@ class SearchCore
else
unset($words[$key]);
if (!sizeof($words))
if (!count($words))
return ($ajax ? array() : array('total' => 0, 'result' => array()));
$score = '';
if (sizeof($scoreArray))
if (count($scoreArray))
$score = ',(
SELECT SUM(weight)
FROM '._DB_PREFIX_.'search_word sw
@@ -237,7 +238,7 @@ class SearchCore
array_unique($eligibleProducts);
$productPool = '';
foreach ($eligibleProducts AS $id_product)
foreach ($eligibleProducts as $id_product)
if ($id_product)
$productPool .= (int)$id_product.',';
if (empty($productPool))
@@ -249,17 +250,34 @@ class SearchCore
$sql = 'SELECT DISTINCT p.id_product, pl.name pname, cl.name cname,
cl.link_rewrite crewrite, pl.link_rewrite prewrite '.$score.'
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->addSqlRestrictionOnLang('pl').')
INNER JOIN `'._DB_PREFIX_.'category_lang` cl ON (p.`id_category_default` = cl.`id_category` AND cl.`id_lang` = '.(int)$id_lang.$context->shop->addSqlRestrictionOnLang('cl').')
INNER JOIN `'._DB_PREFIX_.'product_lang` pl ON (
p.`id_product` = pl.`id_product`
AND pl.`id_lang` = '.(int)$id_lang.$context->shop->addSqlRestrictionOnLang('pl').'
)
INNER JOIN `'._DB_PREFIX_.'category_lang` cl ON (
p.`id_category_default` = cl.`id_category`
AND cl.`id_lang` = '.(int)$id_lang.$context->shop->addSqlRestrictionOnLang('cl').'
)
WHERE p.`id_product` '.$productPool.'
ORDER BY position DESC LIMIT 10';
return $db->executeS($sql);
}
$sql = 'SELECT p.*, stock.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
$sql = 'SELECT p.*, stock.out_of_stock, stock.quantity as quantity,
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->addSqlRestrictionOnLang('pl').')
INNER JOIN `'._DB_PREFIX_.'product_lang` pl ON (
p.`id_product` = pl.`id_product`
AND pl.`id_lang` = '.(int)$id_lang.$context->shop->addSqlRestrictionOnLang('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)
@@ -275,7 +293,10 @@ class SearchCore
$sql = 'SELECT COUNT(*)
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->addSqlRestrictionOnLang('pl').')
INNER JOIN `'._DB_PREFIX_.'product_lang` pl ON (
p.`id_product` = pl.`id_product`
AND pl.`id_lang` = '.(int)$id_lang.$context->shop->addSqlRestrictionOnLang('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)
@@ -301,7 +322,7 @@ class SearchCore
SELECT t.name FROM '._DB_PREFIX_.'product_tag pt
LEFT JOIN '._DB_PREFIX_.'tag t ON (pt.id_tag = t.id_tag AND t.id_lang = '.(int)$id_lang.')
WHERE pt.id_product = '.(int)$id_product);
foreach ($tagsArray AS $tag)
foreach ($tagsArray as $tag)
$tags .= $tag['name'].' ';
return $tags;
}
@@ -317,7 +338,7 @@ class SearchCore
INNER JOIN '._DB_PREFIX_.'product_attribute_combination pac ON pa.id_product_attribute = pac.id_product_attribute
INNER JOIN '._DB_PREFIX_.'attribute_lang al ON (pac.id_attribute = al.id_attribute AND al.id_lang = '.(int)$id_lang.')
WHERE pa.id_product = '.(int)$id_product);
foreach ($attributesArray AS $attribute)
foreach ($attributesArray as $attribute)
$attributes .= $attribute['name'].' ';
return $attributes;
}
@@ -332,7 +353,7 @@ class SearchCore
SELECT fvl.value FROM '._DB_PREFIX_.'feature_product fp
LEFT JOIN '._DB_PREFIX_.'feature_value_lang fvl ON (fp.id_feature_value = fvl.id_feature_value AND fvl.id_lang = '.(int)$id_lang.')
WHERE fp.id_product = '.(int)$id_product);
foreach ($featuresArray AS $feature)
foreach ($featuresArray as $feature)
$features .= $feature['value'].' ';
return $features;
}
@@ -342,7 +363,8 @@ class SearchCore
// Adjust the limit to get only "whole" products, in every languages (and at least one)
$limit = max(1, round($limit / $total_languages) * $total_languages);
return Db::getInstance()->executeS('
SELECT p.id_product, pl.id_lang, pl.id_shop, pl.name pname, p.reference, p.ean13, p.upc, pl.description_short, pl.description, cl.name cname, m.name mname
SELECT p.id_product, pl.id_lang, pl.id_shop, pl.name pname, p.reference, p.ean13, p.upc,
pl.description_short, pl.description, cl.name cname, m.name mname
FROM '._DB_PREFIX_.'product p
LEFT JOIN '._DB_PREFIX_.'product_lang pl ON p.id_product = pl.id_product
LEFT JOIN '._DB_PREFIX_.'category_lang cl ON (cl.id_category = p.id_category_default AND pl.id_lang = cl.id_lang)
@@ -375,7 +397,7 @@ class SearchCore
$ids = array();
if ($products)
foreach($products AS $product)
foreach ($products as $product)
$ids[] = (int)$product['id_product'];
if (count($ids))
$db->Execute('DELETE FROM '._DB_PREFIX_.'search_index WHERE id_product IN ('.implode(',', $ids).')');
@@ -419,7 +441,8 @@ class SearchCore
$total_languages = count(Language::getLanguages(false));
// Products are processed 50 by 50 in order to avoid overloading MySQL
while ($products = Search::getProductsToIndex($total_languages, $id_product, 50) && count($products) > 0)
$count = count($products);
while ($products = Search::getProductsToIndex($total_languages, $id_product, 50) && $count > 0)
{
// Now each non-indexed product is processed one by one, langage by langage
foreach ($products as $product)
@@ -430,11 +453,11 @@ class SearchCore
// Data must be cleaned of html, bad characters, spaces and anything, then if the resulting words are long enough, they're added to the array
$pArray = array();
foreach ($product AS $key => $value)
foreach ($product as $key => $value)
if (strncmp($key, 'id_', 3))
{
$words = explode(' ', Search::sanitize($value, (int)$product['id_lang'], true));
foreach ($words AS $word)
foreach ($words as $word)
if (!empty($word))
{
$word = Tools::substr($word, 0, PS_SEARCH_MAX_WORD_LENGTH);
@@ -452,8 +475,8 @@ class SearchCore
{
$queryArray = array();
$queryArray2 = array();
foreach ($pArray AS $word => $weight)
if ($weight AND !isset($wordIdsByWord['_'.$word]))
foreach ($pArray as $word => $weight)
if ($weight && !isset($wordIdsByWord['_'.$word]))
{
$queryArray[$word] = '('.(int)$product['id_lang'].', '.(int)$product['id_shop'].', \''.pSQL($word).'\')';
$queryArray2[] = '\''.pSQL($word).'\'';
@@ -466,7 +489,7 @@ class SearchCore
AND id_lang = '.(int)$product['id_lang'].'
AND id_shop = '.(int)$product['id_shop']);
foreach($existingWords as $data)
foreach ($existingWords as $data)
unset($queryArray[Tools::replaceAccentedChars($data['word'])]);
if (count($queryArray))
@@ -474,7 +497,7 @@ class SearchCore
// The words are inserted...
$db->Execute('
INSERT IGNORE INTO '._DB_PREFIX_.'search_word (id_lang, id_shop, word)
VALUES '.implode(',',$queryArray));
VALUES '.implode(',', $queryArray));
}
if (count($queryArray2))
{
@@ -487,12 +510,12 @@ class SearchCore
AND sw.id_shop = '.(int)$product['id_shop'].'
LIMIT '.count($queryArray2));
// replace accents from the retrieved words so that words without accents or with differents accents can still be linked
foreach ($addedWords AS $wordId)
foreach ($addedWords as $wordId)
$wordIdsByWord[$product['id_shop']][$product['id_lang']]['_'.Tools::replaceAccentedChars($wordId['word'])] = (int)$wordId['id_word'];
}
}
foreach ($pArray AS $word => $weight)
foreach ($pArray as $word => $weight)
{
if (!$weight)
continue;
@@ -500,7 +523,8 @@ class SearchCore
continue;
if (!$wordIdsByWord[$product['id_shop']][$product['id_lang']]['_'.$word])
continue;
$queryArray3[] = '('.(int)$product['id_product'].','.(int)$wordIdsByWord[$product['id_shop']][$product['id_lang']]['_'.$word].','.(int)$weight.')';
$queryArray3[] = '('.(int)$product['id_product'].','.
(int)$wordIdsByWord[$product['id_shop']][$product['id_lang']]['_'.$word].','.(int)$weight.')';
// Force save every 200 words in order to avoid overloading MySQL
if (++$countWords % 200 == 0)
Search::saveIndex($queryArray3);
@@ -520,19 +544,28 @@ class SearchCore
protected static function setProductsAsIndexed(&$products)
{
if (count($products))
Db::getInstance()->execute('UPDATE '._DB_PREFIX_.'product SET indexed = 1 WHERE id_product IN ('.implode(',', $products).') LIMIT '.(int)count($products));
Db::getInstance()->execute(
'UPDATE '._DB_PREFIX_.'product SET indexed = 1
WHERE id_product IN ('.implode(',', $products).')
LIMIT '.(int)count($products)
);
$productsArray = array();
}
// $queryArray3 is automatically emptied in order to be reused immediatly
/** $queryArray3 is automatically emptied in order to be reused immediatly */
protected static function saveIndex(&$queryArray3)
{
if (count($queryArray3))
Db::getInstance()->execute('INSERT INTO '._DB_PREFIX_.'search_index (id_product, id_word, weight) VALUES '.implode(',', $queryArray3).' ON DUPLICATE KEY UPDATE weight = weight + VALUES(weight)');
Db::getInstance()->execute(
'INSERT INTO '._DB_PREFIX_.'search_index (id_product, id_word, weight)
VALUES '.implode(',', $queryArray3).'
ON DUPLICATE KEY UPDATE weight = weight + VALUES(weight)'
);
$queryArray3 = array();
}
public static function searchTag($id_lang, $tag, $count = false, $pageNumber = 0, $pageSize = 10, $orderBy = false, $orderWay = false, $useCookie = true, Context $context = null)
public static function searchTag($id_lang, $tag, $count = false, $pageNumber = 0, $pageSize = 10, $orderBy = false, $orderWay = false,
$useCookie = true, Context $context = null)
{
if (!$context)
$context = Context::getContext();
@@ -543,8 +576,8 @@ class SearchCore
else
$id_customer = 0;
if (!is_numeric($pageNumber) OR !is_numeric($pageSize) OR !Validate::isBool($count) OR !Validate::isValidSearch($tag)
OR $orderBy AND !$orderWay OR ($orderBy AND !Validate::isOrderBy($orderBy)) OR ($orderWay AND !Validate::isOrderBy($orderWay)))
if (!is_numeric($pageNumber) || !is_numeric($pageSize) || !Validate::isBool($count) || !Validate::isValidSearch($tag)
|| $orderBy && !$orderWay || ($orderBy && !Validate::isOrderBy($orderBy)) || ($orderWay && !Validate::isOrderBy($orderWay)))
return false;
if ($pageNumber < 1) $pageNumber = 1;
@@ -567,10 +600,20 @@ class SearchCore
return (int)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql);
}
$sql = 'SELECT DISTINCT p.*, stock.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
$sql = 'SELECT DISTINCT p.*, stock.out_of_stock, stock.quantity as quantity, 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->addSqlRestrictionOnLang('pl').')
INNER JOIN `'._DB_PREFIX_.'product_lang` pl ON (
p.`id_product` = pl.`id_product`
AND pl.`id_lang` = '.(int)$id_lang.$context->shop->addSqlRestrictionOnLang('pl').'
)
'.$context->shop->addSqlAssociation('product', 'p', false).'
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.')
+1
View File
@@ -231,6 +231,7 @@ class SupplierCore extends ObjectModel
$nb_days_new_product = Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20;
$sql = 'SELECT p.*, stock.out_of_stock,
stock.quantity as quantity,
pl.`description`,
pl.`description_short`,
pl.`link_rewrite`,
+76 -40
View File
@@ -109,7 +109,7 @@ class StockAvailableCore extends ObjectModel
if (!is_null($id_product_attribute))
$query->where('id_product_attribute = '.(int)$id_product_attribute);
$query = self::addSqlShopRestriction($query, $id_shop);
$query = StockAvailable::addSqlShopRestriction($query, $id_shop);
return (int)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($query);
}
@@ -134,7 +134,7 @@ class StockAvailableCore extends ObjectModel
foreach ($ids_warehouse as $id_shop => $warehouses)
{
// first, checks if the product depends on stock for the given shop $id_shop
if (self::dependsOnStock($id_product, $id_shop))
if (StockAvailable::dependsOnStock($id_product, $id_shop))
{
// init quantity
$product_quantity = 0;
@@ -153,7 +153,7 @@ class StockAvailableCore extends ObjectModel
'data' => array('quantity' => $quantity),
'type' => 'UPDATE',
'where' => 'id_product = '.(int)$id_product.' AND id_product_attribute = '.(int)$id_product_attribute.
self::addSqlShopRestriction(null, $id_shop)
StockAvailable::addSqlShopRestriction(null, $id_shop)
);
Db::getInstance()->autoExecute($query['table'], $query['data'], $query['type'], $query['where']);
@@ -167,7 +167,7 @@ class StockAvailableCore extends ObjectModel
'data' => array('quantity' => $product_quantity),
'type' => 'UPDATE',
'where' => 'id_product = '.(int)$id_product.' AND id_product_attribute = 0'.
self::addSqlShopRestriction(null, $id_shop)
StockAvailable::addSqlShopRestriction(null, $id_shop)
);
Db::getInstance()->autoExecute($query['table'], $query['data'], $query['type'], $query['where']);
}
@@ -186,7 +186,7 @@ class StockAvailableCore extends ObjectModel
if (is_null($id_shop))
$id_shop = Context::getContext()->shop->getID(true);
$existing_id = self::getStockAvailableIdByProductId((int)$id_product, 0, (int)$id_shop);
$existing_id = StockAvailable::getStockAvailableIdByProductId((int)$id_product, 0, (int)$id_shop);
if ($existing_id > 0)
{
@@ -195,7 +195,7 @@ class StockAvailableCore extends ObjectModel
array('depends_on_stock' => (int)(bool)$depends_on_stock),
'UPDATE',
'id_product = '.(int)$id_product.
self::addSqlShopRestriction(null, $id_shop)
StockAvailable::addSqlShopRestriction(null, $id_shop)
);
}
else
@@ -206,7 +206,7 @@ class StockAvailableCore extends ObjectModel
'id_product_attribute' => 0
);
self::addSqlShopParams($params, $id_shop);
StockAvailable::addSqlShopParams($params, $id_shop);
Db::getInstance()->autoExecute(
_DB_PREFIX_.'stock_available',
@@ -232,7 +232,7 @@ class StockAvailableCore extends ObjectModel
if (is_null($id_shop))
$id_shop = Context::getContext()->shop->getID(true);
$existing_id = self::getStockAvailableIdByProductId((int)$id_product, 0, (int)$id_shop);
$existing_id = StockAvailable::getStockAvailableIdByProductId((int)$id_product, 0, (int)$id_shop);
if ($existing_id > 0)
{
@@ -241,7 +241,7 @@ class StockAvailableCore extends ObjectModel
array('out_of_stock' => (int)$out_of_stock),
'UPDATE',
'id_product = '.(int)$id_product.
self::addSqlShopRestriction(null, $id_shop)
StockAvailable::addSqlShopRestriction(null, $id_shop)
);
}
else
@@ -252,7 +252,7 @@ class StockAvailableCore extends ObjectModel
'id_product_attribute' => 0
);
self::addSqlShopParams($params, $id_shop);
StockAvailable::addSqlShopParams($params, $id_shop);
Db::getInstance()->autoExecute(
_DB_PREFIX_.'stock_available',
@@ -270,7 +270,7 @@ class StockAvailableCore extends ObjectModel
* @param int $id_shop Optional : gets context by default
* @return int Quantity
*/
public static function getQuantityAvailableByProduct($id_product, $id_product_attribute = null, $id_shop = null)
public static function getQuantityAvailableByProduct($id_product = null, $id_product_attribute = null, $id_shop = null)
{
if (is_null($id_shop))
$id_shop = Context::getContext()->shop->getID(true);
@@ -282,10 +282,14 @@ class StockAvailableCore extends ObjectModel
$query = new DbQuery();
$query->select('quantity');
$query->from('stock_available');
$query->where('id_product = '.(int)$id_product);
// 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 = self::addSqlShopRestriction($query, $id_shop);
$query = StockAvailable::addSqlShopRestriction($query, $id_shop);
return (int)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($query);
}
@@ -331,7 +335,7 @@ class StockAvailableCore extends ObjectModel
FROM '._DB_PREFIX_.'stock_available
WHERE id_product = '.(int)$this->id_product.'
AND id_product_attribute <> 0 '.
self::addSqlShopRestriction(null, $this->id_shop).'
StockAvailable::addSqlShopRestriction(null, $this->id_shop).'
'
);
@@ -350,7 +354,7 @@ class StockAvailableCore extends ObjectModel
*/
public static function updateQuantity($id_product, $id_product_attribute, $delta_quantity, $id_shop = null)
{
$id_stock_available = self::getStockAvailableIdByProductId($id_product, $id_product_attribute, $id_shop);
$id_stock_available = StockAvailable::getStockAvailableIdByProductId($id_product, $id_product_attribute, $id_shop);
if (!$id_stock_available)
return false;
@@ -362,7 +366,7 @@ class StockAvailableCore extends ObjectModel
foreach ($products_pack as $product_pack)
{
$pack_id_product_attribute = Product::getDefaultAttribute($tab_product_pack['id_product'], 1);
self::updateQuantity($product_pack->id, $pack_id_product_attribute, $product_pack->pack_quantity * $delta_quantity, $id_shop);
StockAvailable::updateQuantity($product_pack->id, $pack_id_product_attribute, $product_pack->pack_quantity * $delta_quantity, $id_shop);
}
}
@@ -382,18 +386,18 @@ class StockAvailableCore extends ObjectModel
*/
public static function setQuantity($id_product, $id_product_attribute, $quantity, $id_shop = null)
{
$depends_on_stock = self::dependsOnStock($id_product);
$context = Context::getContext();
// if there is no $id_shop, gets the context one
if (is_null($id_shop))
$id_shop = (int)$context->shop->getID(true);
$depends_on_stock = StockAvailable::dependsOnStock($id_product);
//Try to set available quantitiy if product does not depend on physical stock
if (!$depends_on_stock)
{
$id_stock_available = (int)self::getStockAvailableIdByProductId($id_product, $id_product_attribute, $id_shop);
$context = Context::getContext();
// if there is no $id_shop, gets the context one
if (is_null($id_shop))
$id_shop = (int)$context->shop->getID(true);
$id_stock_available = (int)StockAvailable::getStockAvailableIdByProductId($id_product, $id_product_attribute, $id_shop);
if ($id_stock_available)
{
@@ -403,7 +407,7 @@ class StockAvailableCore extends ObjectModel
}
else
{
$out_of_stock = self::outOfStock($id_product, $id_shop);
$out_of_stock = StockAvailable::outOfStock($id_product, $id_shop);
$stock_available = new StockAvailable();
$stock_available->out_of_stock = (int)$out_of_stock;
@@ -443,14 +447,41 @@ class StockAvailableCore extends ObjectModel
*/
public static function removeProductFromStockAvailable($id_product, $id_product_attribute = null, $id_shop = null)
{
Db::getInstance()->execute('
return Db::getInstance()->execute('
DELETE FROM '._DB_PREFIX_.'stock_available
WHERE id_product = '.(int)$id_product.
($id_product_attribute ? ' AND id_product_attribute = '.(int)$id_product_attribute : '').
self::addSqlShopRestriction(null, $id_shop)
StockAvailable::addSqlShopRestriction(null, $id_shop)
);
}
/**
* Removes all product quantities from all a group of shops
* If stocks are shared, remoe all old available quantities for all shops of the group
* Else remove all available quantities for the current group
*
* @param GroupShop $group_shop the GroupShop object
*/
public static function resetProductFromStockAvailableByGroupShop($group_shop)
{
if ($group_shop->share_stock)
{
$id_shops_list = implode(', ', Shop::getIdShopsByIdGroupShop($group_shop->id));
return Db::getInstance()->execute('
DELETE FROM '._DB_PREFIX_.'stock_available
WHERE id_shop IN ('.$id_shops_list.')'
);
}
else
{
return Db::getInstance()->execute('
DELETE FROM '._DB_PREFIX_.'stock_available
WHERE id_group_shop = '.$group_shop->id
);
}
}
/**
* For a given product, tells if it depends on the physical (usable) stock
*
@@ -469,7 +500,7 @@ class StockAvailableCore extends ObjectModel
$query->where('id_product = '.(int)$id_product);
$query->where('id_product_attribute = 0');
$query = self::addSqlShopRestriction($query, $id_shop);
$query = StockAvailable::addSqlShopRestriction($query, $id_shop);
return (bool)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($query);
}
@@ -492,7 +523,7 @@ class StockAvailableCore extends ObjectModel
$query->where('id_product = '.(int)$id_product);
$query->where('id_product_attribute = 0');
$query = self::addSqlShopRestriction($query, $id_shop);
$query = StockAvailable::addSqlShopRestriction($query, $id_shop);
return (int)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($query);
}
@@ -506,14 +537,17 @@ class StockAvailableCore extends ObjectModel
*
* @return mixed the DbQuery object or the sql restriction string
*/
protected static function addSqlShopRestriction(DbQuery $sql = null, $id_shop = null, $alias = null)
public static function addSqlShopRestriction(DbQuery $sql = null, $id_shop = null, $alias = null)
{
$context = Context::getContext();
$group_ok = false;
if (!empty($alias))
$alias .= '.';
// if there is no $id_shop, gets the context one
if (is_null($id_shop))
$id_shop = $context->shop->getID(true);
$id_shop = $context->shop->getID();
// if we are in group_shop context
$group_shop = $context->shop->getGroup();
@@ -521,15 +555,15 @@ class StockAvailableCore extends ObjectModel
// if quantities are shared between shops of the group
if ($group_shop->share_stock)
{
if ($sql)
if (is_object($sql))
{
$sql->where($alias.'id_group_shop = '.(int)$group_shop->id);
$sql->where($alias.'id_shop = 0');
$sql->where(pSQL($alias).'id_group_shop = '.(int)$group_shop->id);
$sql->where(pSQL($alias).'id_shop = 0');
}
else
{
$sql = ' AND '.$alias.'id_group_shop = '.(int)$group_shop->id.' ';
$sql = ' AND '.$alias.'id_shop = 0 ';
$sql = ' AND '.pSQL($alias).'id_group_shop = '.(int)$group_shop->id.' ';
$sql .= ' AND '.pSQL($alias).'id_shop = 0 ';
}
$group_ok = true;
@@ -537,10 +571,12 @@ class StockAvailableCore extends ObjectModel
// if no group specific restriction, set simple shop restriction
if (!$group_ok)
if ($sql)
$sql->where($alias.'id_shop = '.(int)$id_shop);
{
if (is_object($sql))
$sql->where(pSQL($alias).'id_shop = '.(int)$id_shop);
else
$sql = ' AND '.$alias.'id_shop = '.(int)$id_shop.' ';
$sql = ' AND '.pSQL($alias).'id_shop = '.(int)$id_shop.' ';
}
return $sql;
}
@@ -552,7 +588,7 @@ class StockAvailableCore extends ObjectModel
* @param int $id_shop Optional : The shop ID
*
*/
protected static function addSqlShopParams(&$params, $id_shop = null)
public static function addSqlShopParams(&$params, $id_shop = null)
{
$context = Context::getContext();
$group_ok = false;
@@ -139,7 +139,8 @@ class AdminGroupShopControllerCore extends AdminController
'label' => $this->l('Disabled')
)
),
'desc' => $this->l('Share available quantities to sale between shops of this group')
'desc' => $this->l('Share available quantities to sale between shops of this group'),
'h' => $this->l('When changing this option, all product available quantities for the current groupof shop will be reseted to 0.')
),
array(
'type' => 'radio',
@@ -252,12 +253,18 @@ class AdminGroupShopControllerCore extends AdminController
{
if (Tools::getValue('useImportData') && ($import_data = Tools::getValue('importData')) && is_array($import_data))
$new_group_shop->copyGroupShopData(Tools::getValue('importFromShop'), $import_data);
//Reset available quantitites
StockAvailable::resetProductFromStockAvailableByGroupShop($new_group_shop);
}
public function afterUpdate($new_group_shop)
{
if (Tools::getValue('useImportData') && ($import_data = Tools::getValue('importData')) && is_array($import_data))
$new_group_shop->copyGroupShopData(Tools::getValue('importFromShop'), $import_data);
//Reset available quantitites
StockAvailable::resetProductFromStockAvailableByGroupShop($new_group_shop);
}
}
@@ -3422,9 +3422,7 @@ class AdminProductsControllerCore extends AdminController
if (Tools::getValue('id_product_attribute') === false)
return Tools::jsonEncode(array('error' => 'Undefined id product attribute'));
$id_shop = (int)Context::getContext()->shop->getID(true);
StockAvailable::setQuantity($product->id, (int)Tools::getValue('id_product_attribute'), (int)Tools::getValue('value'), $id_shop);
StockAvailable::setQuantity($product->id, (int)Tools::getValue('id_product_attribute'), (int)Tools::getValue('value'));
break;
}
die(Tools::jsonEncode(array('error' => false)));
+7 -1
View File
@@ -43,7 +43,13 @@ class NewProductsControllerCore extends FrontController
{
$this->productSort();
$nbProducts = (int)Product::getNewProducts($this->context->language->id, (isset($this->p) ? (int)($this->p) - 1 : null), (isset($this->n) ? (int)($this->n) : null), true);
$nbProducts = (int)Product::getNewProducts(
$this->context->language->id,
(isset($this->p) ? (int)($this->p) - 1 : null),
(isset($this->n) ? (int)($this->n) : null),
true
);
$this->pagination($nbProducts);
$this->context->smarty->assign(array(