From 998741905be8d76d216a1b4b1867655a08971166 Mon Sep 17 00:00:00 2001 From: bMancone Date: Tue, 11 Oct 2011 14:12:40 +0000 Subject: [PATCH] // StockManager: Fixed --- classes/stock/StockManager.php | 186 +++++++++++++++------------------ 1 file changed, 84 insertions(+), 102 deletions(-) diff --git a/classes/stock/StockManager.php b/classes/stock/StockManager.php index cbc9c64bf..63e6a473f 100644 --- a/classes/stock/StockManager.php +++ b/classes/stock/StockManager.php @@ -1,29 +1,29 @@ - * @copyright 2007-2011 PrestaShop SA - * @version Release: $Revision: 8105 $ - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - * International Registered Trademark & Property of PrestaShop SA - */ +* 2007-2011 PrestaShop +* +* NOTICE OF LICENSE +* +* This source file is subject to the Open Software License (OSL 3.0) +* that is bundled with this package in the file LICENSE.txt. +* It is also available through the world-wide-web at this URL: +* http://opensource.org/licenses/osl-3.0.php +* If you did not receive a copy of the license and are unable to +* obtain it through the world-wide-web, please send an email +* to license@prestashop.com so we can send you a copy immediately. +* +* DISCLAIMER +* +* Do not edit or add to this file if you wish to upgrade PrestaShop to newer +* versions in the future. If you wish to customize PrestaShop for your +* needs please refer to http://www.prestashop.com for more information. +* +* @author PrestaShop SA +* @copyright 2007-2011 PrestaShop SA +* @version Release: $Revision: 9202 $ +* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ /** * StockManager : implementation of StockManagerInterface @@ -45,7 +45,7 @@ class StockManagerCore implements StockManagerInterface * @see StockManagerInterface::addProduct() */ public function addProduct($id_product, - $id_product_attribute = null, + $id_product_attribute = 0, $warehouse, $quantity, $id_stock_mvt_reason, @@ -53,102 +53,95 @@ class StockManagerCore implements StockManagerInterface $is_usable = true, $id_supplier_order = null) { - if (!is_object($warehouse) || !$price_te || !$quantity || (!$id_product || !$id_product_attribute)) + if (!Validate::isLoadedObject($warehouse) || !$price_te || !$quantity || !$id_product) return false; - if (!StockmvtReason::exists($id_stock_mvt_reason)) - $id_stock_mvt_reason = StockMvtReason::STOCK_MVT_DEFAULT_REASON; + if (!StockMvtReason::exists($id_stock_mvt_reason)) + $id_stock_mvt_reason = Configuration::get('PS_STOCK_MVT_INC_REASON_DEFAULT'); - // Get context to have employee informations $context = Context::getContext(); - // sets mvt params to save stock mvt (only one mvt possible when adding product quantities) $mvt_params = array( 'id_stock' => null, 'physical_quantity' => $quantity, 'id_stock_mvt_reason' => $id_stock_mvt_reason, 'id_supplier_order' => $id_supplier_order, - 'price_te' => $price_te, + 'price_te' => round($price_te, 6), 'last_wa' => null, 'current_wa' => null, - 'id_employee' => $context->employee->id_employee + 'id_employee' => $context->employee->id, + 'sign' => 1 ); - // Flag if an existing stock is available $stock_exists = false; - // switch on STOCK_MANAGEMENT_MODE - switch ($warehouse->stock_management) + // switch on MANAGEMENT_TYPE + switch ($warehouse->management_type) { // case CUMP mode case 'WA': - // gets stock collection for the given product - $stock_collection = $this->getStockCollection($id_product, $id_product_attribute, $warehouse->id_warehouse); + $stock_collection = $this->getStockCollection($id_product, $id_product_attribute, $warehouse->id); - // if the product is already in stock + // if this product is already in stock if (count($stock_collection) > 0) { $stock_exists = true; - // There is one and only one stock for a given product in a warehouse in this mode + // for a warehouse using WA, there is one and only one stock for a given product $stock = $stock_collection[0]; - // determine weigthed average price - $last_wa = $stock->price_te; - $current_wa = $this->calculateWA($stock, $quantity, $price_te); + // calculates WA price + $last_wa = round($stock->price_te, 6); + $current_wa = round($this->calculateWA($stock, $quantity, $price_te), 6); - // sets mvt_params - $mvt_params['id_stock'] = $stock->id_stock; + $mvt_params['id_stock'] = $stock->id; $mvt_params['last_wa'] = $last_wa; $mvt_params['current_wa'] = $current_wa; - // set new stock params $stock_params = array( 'physical_quantity' => ($stock->physical_quantity + $quantity), - 'price_te' => $current_cump, + 'price_te' => $current_wa, 'usable_quantity' => ($is_usable ? ($stock->usable_quantity + $quantity) : $stock->usable_quantity), - 'id_warehouse' => $warehouse->id_warehouse + 'id_warehouse' => $warehouse->id ); - // save stock in warehouse + // saves stock in warehouse $stock->hydrate($stock_params); $stock->update(); } else // else, the product is not in sock { - // sets mvt_params $mvt_params['last_wa'] = 0; - $mvt_params['current_wa'] = $price_te; + $mvt_params['current_wa'] = round($price_te, 6); } break; // case FIFO mode case 'FIFO': case 'LIFO': - // gets stock collection for the given product and the same unit price - $stock_collection = $this->getStockCollection($id_product, $id_product_attribute, $warehouse->id_warehouse, $price_te); - // if the product is already in stock + $stock_collection = $this->getStockCollection($id_product, $id_product_attribute, $warehouse->id, $price_te); + + // if this product is already in stock if (count($stock_collection) > 0) { $stock_exists = true; - // There is one and only one stock for a given product in a warehouse and at the curent unit price + // there is one and only one stock for a given product in a warehouse and at the current unit price $stock = $stock_collection[0]; - // set new stock params $stock_params = array( 'physical_quantity' => ($stock->physical_quantity + $quantity), 'usable_quantity' => ($is_usable ? ($stock->usable_quantity + $quantity) : $stock->usable_quantity), ); - // update stock in warehouse + // updates stock in warehouse $stock->hydrate($stock_params); $stock->update(); // sets mvt_params - $mvt_params['id_stock'] = $stock->id_stock; + $mvt_params['id_stock'] = $stock->id; } @@ -161,31 +154,28 @@ class StockManagerCore implements StockManagerInterface if (!$stock_exists) { - // creates a new stock for this product $stock = new Stock(); - // set stock params $stock_params = array( 'id_product_attribute' => $id_product_attribute, 'id_product' => $id_product, 'physical_quantity' => $quantity, - 'price_te' => $price_te, + 'price_te' => round($price_te, 6), 'usable_quantity' => ($is_usable ? $quantity : 0), - 'id_warehouse' => $warehouse->id_warehouse + 'id_warehouse' => $warehouse->id ); - // save stock in warehouse + // saves stock in warehouse $stock->hydrate($stock_params); $stock->add(); - // sets mvt_params - $mvt_params['id_stock'] = $stock->id_stock; + $mvt_params['id_stock'] = $stock->id; } // saves stock mvt $stock_mvt = new StockMvt(); $stock_mvt->hydrate($mvt_params); - $stock_mvt->save(); + $stock_mvt->add(); return true; } @@ -203,37 +193,34 @@ class StockManagerCore implements StockManagerInterface { $return = array(); - if (!is_object($warehouse) || !$price_te || !$quantity || (!$id_product || !$id_product_attribute)) + if (!Validate::isLoadedObject($warehouse) || !$quantity || !$id_product) return $return; - if (!StockmvtReason::exists($id_stock_mvt_reason)) - $id_stock_mvt_reason = StockMvtReason::STOCK_MVT_DEFAULT_REASON; + if (!StockMvtReason::exists($id_stock_mvt_reason)) + $id_stock_mvt_reason = Configuration::get('PS_STOCK_MVT_DEC_REASON_DEFAULT'); - // gets context to have the employee informations $context = Context::getContext(); - // gets total quantitiy in stock for the current product - $quantity_in_stock = $this->getProductPhysicalQuantities($id_product, $id_product_attribute, array($warehouse->id_warehouse), $usable); + // gets total quantities in stock for the current product + $quantity_in_stock = $this->getProductPhysicalQuantities($id_product, $id_product_attribute, array($warehouse->id), $is_usable); // checks if it's possible to remove the given quantity if ($quantity_in_stock < $quantity) return $return; - // gets stock collection for the given product - $stock_collection = $this->getStockCollection($id_product, $id_product_attribute, $warehouse->id_warehouse); + $stock_collection = $this->getStockCollection($id_product, $id_product_attribute, $warehouse->id); - // check if the collection is well loaded + // check if the collection is loaded if (count($stock_collection) <= 0) return $return; - // prepare utils variables $stock_history_qty_available = array(); $mvt_params = array(); $stock_params = array(); $quantity_to_decrement_by_stock = array(); $global_quantity_to_decrement = $quantity; - // switch on STOCK_MANAGEMENT_MODE + // switch on MANAGEMENT_TYPE switch ($warehouse->management_type) { // case CUMP mode @@ -241,17 +228,15 @@ class StockManagerCore implements StockManagerInterface // There is one and only one stock for a given product in a warehouse in this mode $stock = $stock_collection[0]; - // sets mvt params to save stock mvt (only one mvt is possible when removing product quantities in this mode) $mvt_params = array( - 'id_stock' => $stock->id_stock, + 'id_stock' => $stock->id, 'physical_quantity' => $quantity, 'id_stock_mvt_reason' => $id_stock_mvt_reason, 'id_order' => $id_order, 'price_te' => $stock->price_te, - 'id_employee' => $context->employee->id_employee + 'id_employee' => $context->employee->id, + 'sign' => -1 ); - - // sets new stock params $stock_params = array( 'physical_quantity' => ($stock->physical_quantity - $quantity), 'usable_quantity' => ($is_usable ? ($stock->usable_quantity - $quantity) : $stock->usable_quantity), @@ -270,8 +255,8 @@ class StockManagerCore implements StockManagerInterface case 'LIFO': case 'FIFO': - // for each stock, parse its mvts history to determine left quantities for each positive mvt, - // according to instant available quantities for this stock + // for each stock, parse its mvts history to calculate the quantities left for each positive mvt, + // according to the instant available quantities for this stock foreach ($stock_collection as $stock) { $left_quantity_to_check = $stock->physical_quantity; @@ -283,14 +268,14 @@ class StockManagerCore implements StockManagerInterface FROM `'._DB_PREFIX_.'stock_mvt` sm JOIN `'._DB_PREFIX_.'stock_mvt` sm2 ON sm2.`stock_mvt_referer` = sm.`id_stock_mvt` WHERE sm.`sign` = 1 - AND sm.`id_stock` = '.(int)$stock->id_stock.' + AND sm.`id_stock` = '.(int)$stock->id.' AND sm2.`sign` = -1 ORDER BY sm.`date_add` DESC' ); while ($row = Db::getInstance()->nextRow($resource)) { - // stop while - in FIFO mode, we have to retreive the oldest positive mvts for which there are left quantities + // break - in FIFO mode, we have to retreive the oldest positive mvts for which there are left quantities if ($warehouse->management_type == 'FIFO') if ($row['qty'] >= $row['physical_quantity']) break; @@ -301,12 +286,12 @@ class StockManagerCore implements StockManagerInterface // history of the mvt $stock_history_qty_available[$timestamp] = array( - 'id_stock' => $stock->id_stock, + 'id_stock' => $stock->id, 'id_stock_mvt' => (int)$row['id_stock_mvt'], 'qty' => (int)$row['qty'] ); - // stop while - in LIFO mode, checks only the necessary history to handle the global quantity for the current stock + // break - in LIFO mode, checks only the necessary history to handle the global quantity for the current stock if ($warehouse->management_type == 'LIFO') { $left_quantity_to_check -= (int)$row['physical_quantity']; @@ -343,22 +328,21 @@ class StockManagerCore implements StockManagerInterface // for each stock, decrements it and logs the mvts foreach ($stock_collection as $stock) { - if (array_key_exists($stock->id_stock, $quantity_to_decrement_by_stock) && is_array($quantity_to_decrement_by_stock[$stock->id_stock])) + if (array_key_exists($stock->id, $quantity_to_decrement_by_stock) && is_array($quantity_to_decrement_by_stock[$stock->id])) { $total_quantity_for_current_stock = 0; - foreach ($quantity_to_decrement_by_stock[$stock->id_stock] as $id_mvt_referrer => $qte) + foreach ($quantity_to_decrement_by_stock[$stock->id] as $id_mvt_referrer => $qte) { - // sets mvt params to save stock mvt $mvt_params = array( - 'id_stock' => $stock->id_stock, + 'id_stock' => $stock->id, 'physical_quantity' => $qte, 'id_stock_mvt_reason' => $id_stock_mvt_reason, 'id_order' => $id_order, 'price_te' => $stock->price_te, 'sign' => -1, 'stock_mvt_referer' => $id_mvt_referrer, - 'id_employee' => $context->employee->id_employee + 'id_employee' => $context->employee->id ); // saves stock mvt @@ -369,14 +353,13 @@ class StockManagerCore implements StockManagerInterface $total_quantity_for_current_stock += $qte; } - // sets new stock params $stock_params = array( 'physical_quantity' => ($stock->physical_quantity - $total_quantity_for_current_stock), 'usable_quantity' => ($is_usable ? ($stock->usable_quantity - $total_quantity_for_current_stock) : $stock->usable_quantity), ); - $return[$stock->id_stock]['quantity'] = $total_quantity_for_current_stock; - $return[$stock->id_stock]['price_te'] = $stock->price_te; + $return[$stock->id]['quantity'] = $total_quantity_for_current_stock; + $return[$stock->id]['price_te'] = $stock->price_te; // saves stock in warehouse $stock->hydrate($stock_params); @@ -385,7 +368,6 @@ class StockManagerCore implements StockManagerInterface } break; } - return $return; } @@ -432,7 +414,7 @@ class StockManagerCore implements StockManagerInterface public function transferBetweenWarehouses($id_product, $id_product_attribute, $quantity, - $id_stock_movement_reason, + $id_stock_mvt_reason, $id_warehouse_from, $id_warehouse_to, $usable_from = true, @@ -454,7 +436,7 @@ class StockManagerCore implements StockManagerInterface $id_product_attribute, $warehouse_from, $quantity, - $id_stock_movement_reason, + $id_stock_mvt_reason, $is_usable_from))) return false; // Adds in warehouse_to @@ -464,7 +446,7 @@ class StockManagerCore implements StockManagerInterface $id_product_attribute, $warehouse_to, $stock['quantity'], - $id_stock_movement_reason, + $id_stock_mvt_reason, $stock['price_te'], $usable_to)) return false; @@ -481,9 +463,9 @@ class StockManagerCore implements StockManagerInterface * @param float $price_te * @return int WA */ - protected function calculateWA(Stock $stock, $quantity, $price_te) + protected function calculateWA($stock, $quantity, $price_te) { - return ((($stock->physical_quantity * $stock->price_te) + ($quantity * $price_te)) / ($stock->$quantity + $quantity)); + return ((($stock->physical_quantity * $stock->price_te) + ($quantity * $price_te)) / ($stock->physical_quantity + $quantity)); } /** @@ -497,7 +479,7 @@ class StockManagerCore implements StockManagerInterface { // build query $query = new DbQuery(); - $query->select('s.id_stock, s.physical_quantity, s.usable_quantity, s.price_te'); + $query->select('s.id_stock, s.physical_quantity, s.usable_quantity, s.price_te, s.id_product, s.id_product_attribute, s.id_warehouse'); $query->from('stock s'); $query->where('s.id_product = '.(int)$id_product.' AND s.id_product_attribute = '.(int)$id_product_attribute); if ($id_warehouse)