// StockAvailable: updated synchronize() and updated its usage within the different stock controllers when necessary

This commit is contained in:
bMancone
2011-11-21 11:01:33 +00:00
parent 9426e5d883
commit 3c1fa76032
8 changed files with 165 additions and 124 deletions
+3 -3
View File
@@ -332,7 +332,7 @@ class ProductCore extends ObjectModel
} }
// By default, the product quantity correspond to the available quantity to sell in the current shop // By default, the product quantity correspond to the available quantity to sell in the current shop
$this->quantity = StockAvailable::getStockAvailableForProduct($id_product, 0, Context::getContext()->shop->getID()); $this->quantity = StockAvailable::getQuantityAvailableByProduct($id_product, 0, Context::getContext()->shop->getID());
$this->out_of_stock = $this->getOutOfStock(); $this->out_of_stock = $this->getOutOfStock();
$this->depends_on_stock = $this->getDependsOnStock(); $this->depends_on_stock = $this->getDependsOnStock();
@@ -2260,7 +2260,7 @@ class ProductCore extends ObjectModel
return 0; return 0;
// @since 1.5.0 // @since 1.5.0
return (StockAvailable::getStockAvailableForProduct($id_product, $id_product_attribute, Context::getContext()->shop->getID())); return (StockAvailable::getQuantityAvailableByProduct($id_product, $id_product_attribute, Context::getContext()->shop->getID()));
} }
/** /**
@@ -2463,7 +2463,7 @@ class ProductCore extends ObjectModel
else else
$id_product_attribute = 0; $id_product_attribute = 0;
return ($qty <= StockAvailable::getStockAvailableForProduct($this->id, $id_product_attribute, Context::getContext()->shop->getID())); return ($qty <= StockAvailable::getQuantityAvailableByProduct($this->id, $id_product_attribute, Context::getContext()->shop->getID()));
} }
/** /**
+64 -49
View File
@@ -89,7 +89,7 @@ class StockAvailableCore extends ObjectModel
} }
/** /**
* For a given {id_product, id_product_attribute and id_shop}, gets the stock id associated * For a given {id_product, id_product_attribute and id_shop}, gets the stock available id associated
* *
* @param int $id_product * @param int $id_product
* @param int $id_product_attribute Optional * @param int $id_product_attribute Optional
@@ -97,7 +97,7 @@ class StockAvailableCore extends ObjectModel
* @return int * @return int
*/ */
public static function getIdStockAvailableByProductId($id_product, $id_product_attribute = null, $id_shop = null) public static function getStockAvailableIdByProductId($id_product, $id_product_attribute = null, $id_shop = null)
{ {
// if there is no $id_shop, gets the context one // if there is no $id_shop, gets the context one
if (is_null($id_shop)) if (is_null($id_shop))
@@ -121,60 +121,54 @@ class StockAvailableCore extends ObjectModel
*/ */
public static function synchronize($id_product) public static function synchronize($id_product)
{ {
// inits the list of warehouse ids and product ids // gets warehouse ids grouped by shops
$ids_warehouse = array(); $ids_warehouse = Warehouse::getWarehousesGroupedByShops();
$ids_product_attribute = array();
// builds query to get every warehouses/shops
$query = new DbQuery();
$query->select('id_warehouse, id_shop');
$query->from('warehouse_shop');
$query->orderBy('id_shop');
// queries to get warehouse ids grouped by shops
foreach (Db::getInstance()->executeS($query) as $row)
$ids_warehouse[$row['id_shop']][] = $row['id_warehouse'];
// gets all product attributes ids // gets all product attributes ids
$ids_product_attribute = array();
foreach (Product::getProductAttributesIds($id_product) as $id_product_attribute) foreach (Product::getProductAttributesIds($id_product) as $id_product_attribute)
$ids_product_attribute[] = $id_product_attribute['id_product_attribute']; $ids_product_attribute[] = $id_product_attribute['id_product_attribute'];
$manager = StockManagerFactory::getManager(); $manager = StockManagerFactory::getManager();
// loops on ids_warehouse to synchronize // loops on $ids_warehouse to synchronize quantities
foreach ($ids_warehouse as $id_shop => $warehouses) foreach ($ids_warehouse as $id_shop => $warehouses)
{ {
$total_quantity = 0; // first, checks if the product depends on stock for the given shop $id_shop
if (self::dependsOnStock($id_product, $id_shop))
// if there are no product attributes
if (empty($ids_product_attribute))
$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 = $manager->getProductRealQuantities($id_product, $id_product_attribute, $warehouses, true); // inits quantity
$product_quantity = 0;
// if it's a simple product
if (empty($ids_product_attribute))
$product_quantity = $manager->getProductRealQuantities($id_product, null, $warehouses, true);
// else this product has attributes, hence loops on $ids_product_attribute
foreach ($ids_product_attribute as $id_product_attribute)
{
$quantity = $manager->getProductRealQuantities($id_product, $id_product_attribute, $warehouses, true);
$query = array(
'table' => _DB_PREFIX_.'stock_available',
'data' => array('quantity' => $quantity),
'type' => 'UPDATE',
'where' => 'id_product = '.(int)$id_product.' AND id_product_attribute = '.(int)$id_product_attribute.' AND id_shop = '.(int)$id_shop
);
Db::getInstance()->autoExecute($query['table'], $query['data'], $query['type'], $query['where']);
$product_quantity += $quantity;
}
// updates
// if $id_product has attributes, it also updates the sum for all attributes
$query = array( $query = array(
'table' => _DB_PREFIX_.'stock_available', 'table' => _DB_PREFIX_.'stock_available',
'data' => array('quantity' => $quantity), 'data' => array('quantity' => $product_quantity),
'type' => 'UPDATE', 'type' => 'UPDATE',
'where' => 'id_product = '.(int)$id_product.' AND id_product_attribute = '.(int)$id_product_attribute.' AND id_shop = '.(int)$id_shop 'where' => 'id_product = '.(int)$id_product.' AND id_product_attribute = 0 AND id_shop = '.(int)$id_shop
); );
Db::getInstance()->autoExecute($query['table'], $query['data'], $query['type'], $query['where']); Db::getInstance()->autoExecute($query['table'], $query['data'], $query['type'], $query['where']);
$total_quantity += $quantity;
} }
$query = array(
'table' => _DB_PREFIX_.'stock_available',
'data' => array('quantity' => $total_quantity),
'type' => 'UPDATE',
'where' => 'id_product = '.(int)$id_product.' AND id_product_attribute = 0 AND id_shop = '.(int)$id_shop
);
// saves quantities
Db::getInstance()->autoExecute($query['table'], $query['data'], $query['type'], $query['where']);
} }
} }
@@ -228,15 +222,15 @@ class StockAvailableCore extends ObjectModel
* @param int $id_product * @param int $id_product
* @param int $id_product_attribute Optional * @param int $id_product_attribute Optional
* @param int $id_shop Optional : gets context by default * @param int $id_shop Optional : gets context by default
* @return int * @return int Quantity
*/ */
public static function getStockAvailableForProduct($id_product, $id_product_attribute = null, $id_shop = null) public static function getQuantityAvailableByProduct($id_product, $id_product_attribute = null, $id_shop = null)
{ {
if (is_null($id_shop)) if (is_null($id_shop))
$id_shop = Context::getContext()->shop->getID(true); $id_shop = Context::getContext()->shop->getID(true);
// if null, it's a product without attributes // if null, it's a product without attributes
if (!$id_product_attribute) if (is_null($id_product_attribute))
$id_product_attribute = 0; $id_product_attribute = 0;
$query = new DbQuery(); $query = new DbQuery();
@@ -256,7 +250,7 @@ class StockAvailableCore extends ObjectModel
{ {
if (!parent::add($autodate, $null_values)) if (!parent::add($autodate, $null_values))
return false; return false;
$this->afterSave(); $this->postSave();
} }
/** /**
@@ -267,7 +261,7 @@ class StockAvailableCore extends ObjectModel
{ {
if (!parent::update($null_values)) if (!parent::update($null_values))
return false; return false;
$this->afterSave(); $this->postSave();
} }
/** /**
@@ -275,12 +269,12 @@ class StockAvailableCore extends ObjectModel
* @see StockAvailableCore::update() * @see StockAvailableCore::update()
* @see StockAvailableCore::add() * @see StockAvailableCore::add()
*/ */
public function afterSave() public function postSave()
{ {
if ($this->id_product_attribute == 0) if ($this->id_product_attribute == 0)
return true; return true;
$id_stock_available = StockAvailable::getIdStockAvailableByProductId($this->id_product, 0, $this->id_shop); $id_stock_available = StockAvailable::getStockAvailableIdByProductId($this->id_product, 0, $this->id_shop);
$total_quantity = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue(' $total_quantity = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('
SELECT SUM(quantity) SELECT SUM(quantity)
@@ -303,11 +297,11 @@ class StockAvailableCore extends ObjectModel
} }
/** /**
* For a given id_product and id_product_attribute update the quantity available * For a given id_product and id_product_attribute updates the quantity available
*/ */
public static function updateQuantity($id_product, $id_product_attribute, $delta_quantity, $id_shop = null) public static function updateQuantity($id_product, $id_product_attribute, $delta_quantity, $id_shop = null)
{ {
$id_stock = self::getIdStockAvailableByProductId($id_product, $id_product_attribute, $id_shop); $id_stock = self::getStockAvailableIdByProductId($id_product, $id_product_attribute, $id_shop);
if (!$id_stock) if (!$id_stock)
return false; return false;
@@ -343,4 +337,25 @@ class StockAvailableCore extends ObjectModel
($id_product_attribute ? ' AND id_product_attribute = '.(int)$id_product_attribute : ''). ($id_product_attribute ? ' AND id_product_attribute = '.(int)$id_product_attribute : '').
($id_shop ? ' AND id_shop = '.(int)$id_shop : '')); ($id_shop ? ' AND id_shop = '.(int)$id_shop : ''));
} }
/**
* For a given product, tells if it depends on the physical (usable) stock
*
* @param int $id_product
* @param int $id_shop Optional : gets context if null @see Context::getContext()
* @return bool : depends on stock @see $depends_on_stock
*/
public static function dependsOnStock($id_product, $id_shop = null)
{
if (is_null($id_shop))
$id_shop = Context::getContext()->shop->getID(true);
$query = new DbQuery();
$query->select('depends_on_stock');
$query->from('stock_available');
$query->where('id_product = '.(int)$id_product);
$query->where('id_shop = '.(int)$id_shop);
return (bool)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($query);
}
} }
+20
View File
@@ -317,6 +317,26 @@ class WarehouseCore extends ObjectModel
return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($query); return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($query);
} }
/**
* Gets ids of warehouses, grouped by ids of shops
*
* @return array
*/
public static function getWarehousesGroupedByShops()
{
$ids_warehouse = array();
$query = new DbQuery();
$query->select('id_warehouse, id_shop');
$query->from('warehouse_shop');
$query->orderBy('id_shop');
// queries to get warehouse ids grouped by shops
foreach (Db::getInstance()->executeS($query) as $row)
$ids_warehouse[$row['id_shop']][] = $row['id_warehouse'];
return $ids_warehouse;
}
/** /**
* Gets the number of products in the current warehouse * Gets the number of products in the current warehouse
* *
+1 -1
View File
@@ -152,7 +152,7 @@ class AdminCartsController extends AdminController
WHERE id_product = '.(int)($product['id_product']).' AND cover = 1'); WHERE id_product = '.(int)($product['id_product']).' AND cover = 1');
$productObj = new Product($product['id_product']); $productObj = new Product($product['id_product']);
$product['qty_in_stock'] = StockAvailable::getStockAvailableForProduct($product['id_product'], isset($product['id_product_attribute']) ? $product['id_product_attribute'] : null, (int)$order->id_shop); $product['qty_in_stock'] = StockAvailable::getQuantityAvailableByProduct($product['id_product'], isset($product['id_product_attribute']) ? $product['id_product_attribute'] : null, (int)$order->id_shop);
$imageProduct = new Image($image['id_image']); $imageProduct = new Image($image['id_image']);
$product['image'] = (isset($image['id_image']) ? cacheImage(_PS_IMG_DIR_.'p/'.$imageProduct->getExistingImgPath().'.jpg', 'product_mini_'.(int)($product['id_product']).(isset($product['id_product_attribute']) ? '_'.(int)($product['id_product_attribute']) : '').'.jpg', 45, 'jpg') : '--'); $product['image'] = (isset($image['id_image']) ? cacheImage(_PS_IMG_DIR_.'p/'.$imageProduct->getExistingImgPath().'.jpg', 'product_mini_'.(int)($product['id_product']).(isset($product['id_product_attribute']) ? '_'.(int)($product['id_product_attribute']) : '').'.jpg', 45, 'jpg') : '--');
+2 -2
View File
@@ -575,7 +575,7 @@ class AdminOrdersControllerCore extends AdminController
$productObj = new Product((int)$product['id_product'], false, (int)$this->context->language->id); $productObj = new Product((int)$product['id_product'], false, (int)$this->context->language->id);
$combinations = array(); $combinations = array();
$attributes = $productObj->getAttributesGroups((int)$this->context->language->id); $attributes = $productObj->getAttributesGroups((int)$this->context->language->id);
$product['qty_in_stock'] = StockAvailable::getStockAvailableForProduct((int)$product['id_product'], 0, (int)$this->context->shop->getID()); $product['qty_in_stock'] = StockAvailable::getQuantityAvailableByProduct((int)$product['id_product'], 0, (int)$this->context->shop->getID());
foreach($attributes AS $attribute) foreach($attributes AS $attribute)
{ {
if (!isset($combinations[$attribute['id_product_attribute']]['attributes'])) if (!isset($combinations[$attribute['id_product_attribute']]['attributes']))
@@ -586,7 +586,7 @@ class AdminOrdersControllerCore extends AdminController
if (!isset($combinations[$attribute['id_product_attribute']]['price'])) if (!isset($combinations[$attribute['id_product_attribute']]['price']))
$combinations[$attribute['id_product_attribute']]['price'] = Tools::displayPrice(Tools::convertPrice(Product::getPriceStatic((int)$product['id_product'], true, $attribute['id_product_attribute']), $currency), $currency); $combinations[$attribute['id_product_attribute']]['price'] = Tools::displayPrice(Tools::convertPrice(Product::getPriceStatic((int)$product['id_product'], true, $attribute['id_product_attribute']), $currency), $currency);
if (!isset($combinations[$attribute['id_product_attribute']]['qty_in_stock'])) if (!isset($combinations[$attribute['id_product_attribute']]['qty_in_stock']))
$combinations[$attribute['id_product_attribute']]['qty_in_stock']= StockAvailable::getStockAvailableForProduct((int)$product['id_product'], $attribute['id_product_attribute'], (int)$this->context->shop->getID()); $combinations[$attribute['id_product_attribute']]['qty_in_stock']= StockAvailable::getQuantityAvailableByProduct((int)$product['id_product'], $attribute['id_product_attribute'], (int)$this->context->shop->getID());
} }
foreach ($combinations AS &$combination) foreach ($combinations AS &$combination)
@@ -3048,10 +3048,8 @@ class AdminProductsControllerCore extends AdminController
$total_quantity += $physical_quantity[$attribute['id_product_attribute']]; $total_quantity += $physical_quantity[$attribute['id_product_attribute']];
// Get available quantity for the current product attribute in the current shop // Get available quantity for the current product attribute in the current shop
$available_quantity[$attribute['id_product_attribute']] = StockAvailable::getStockAvailableForProduct( $available_quantity[$attribute['id_product_attribute']] = StockAvailable::getQuantityAvailableByProduct((int)$obj->id,
(int)$obj->id, $attribute['id_product_attribute']);
$attribute['id_product_attribute']
);
// Get all product designation // Get all product designation
$product_designation[$attribute['id_product_attribute']] = rtrim($obj->name[$this->context->language->id].' - '.$attribute['attribute_designation'], ' - '); $product_designation[$attribute['id_product_attribute']] = rtrim($obj->name[$this->context->language->id].' - '.$attribute['attribute_designation'], ' - ');
@@ -3216,7 +3214,7 @@ class AdminProductsControllerCore extends AdminController
if (Tools::getValue('id_product_attribute') === false) if (Tools::getValue('id_product_attribute') === false)
return Tools::jsonEncode(array('error' => 'Undefined id product attribute')); return Tools::jsonEncode(array('error' => 'Undefined id product attribute'));
// @todo : Product class should handle that // @todo : Product class should handle that
$stock_available = new StockAvailable(StockAvailable::getIdStockAvailableByProductId($product->id, (int)Tools::getValue('id_product_attribute'))); $stock_available = new StockAvailable(StockAvailable::getStockAvailableIdByProductId($product->id, (int)Tools::getValue('id_product_attribute')));
if (!$stock_available->id) if (!$stock_available->id)
{ {
$stock_available->id_product = $product->id; $stock_available->id_product = $product->id;
@@ -618,7 +618,10 @@ class AdminStockManagementControllerCore extends AdminController
$stock_manager = StockManagerFactory::getManager(); $stock_manager = StockManagerFactory::getManager();
if ($stock_manager->addProduct($id_product, $id_product_attribute, $warehouse, $quantity, $id_stock_mvt_reason, $price, $usable)) if ($stock_manager->addProduct($id_product, $id_product_attribute, $warehouse, $quantity, $id_stock_mvt_reason, $price, $usable))
{
StockAvailable::synchronize($id_product);
Tools::redirectAdmin($redirect.'&conf=1'); Tools::redirectAdmin($redirect.'&conf=1');
}
else else
$this->_errors[] = Tools::displayError('An error occured. No stock was added.'); $this->_errors[] = Tools::displayError('An error occured. No stock was added.');
} }
@@ -636,7 +639,10 @@ class AdminStockManagementControllerCore extends AdminController
$removed_products = $stock_manager->removeProduct($id_product, $id_product_attribute, $warehouse, $quantity, $id_stock_mvt_reason, $usable); $removed_products = $stock_manager->removeProduct($id_product, $id_product_attribute, $warehouse, $quantity, $id_stock_mvt_reason, $usable);
if (count($removed_products) > 0) if (count($removed_products) > 0)
{
StockAvailable::synchronize($id_product);
Tools::redirectAdmin($redirect.'&conf=2'); Tools::redirectAdmin($redirect.'&conf=2');
}
else else
$this->_errors[] = Tools::displayError('It is not possible to remove the specified quantity or an error occured. No stock was removed.'); $this->_errors[] = Tools::displayError('It is not possible to remove the specified quantity or an error occured. No stock was removed.');
} }
@@ -1271,6 +1271,8 @@ class AdminSupplyOrdersControllerCore extends AdminController
$supplier_receipt_history->add(); $supplier_receipt_history->add();
$supply_order_detail->save(); $supply_order_detail->save();
$supply_order->save(); $supply_order->save();
// synchronizes
StockAvailable::synchronize($id_product);
} }
else else
$this->_errors[] = Tools::displayError($this->l('Something went wrong when adding products in warehouse')); $this->_errors[] = Tools::displayError($this->l('Something went wrong when adding products in warehouse'));