RedPig Posted August 4, 2014 Share Posted August 4, 2014 Hi Guys, Ive looked around but can find a solution to a stock management problem. I have started to add stock to the warehouse I created in Prestashop. While adding stock we sold an item. Now when I go to remove that item I get an error "You don't have enough usable quantity. Cannot remove 1 out of 0." I had 2 of these items in stock and want to remove 1 leaving 1 left. Why would it say I cant remove 1 out of 0 items. Any help or advice would be useful Thanks 1 Link to comment Share on other sites More sharing options...
chris0241 Posted December 23, 2014 Share Posted December 23, 2014 Same issue... V1.6.0.9 BUMP! Link to comment Share on other sites More sharing options...
frank_jarle Posted December 24, 2014 Share Posted December 24, 2014 My best bet is that this is probably a bug that is handled in the upcoming 1.6.11 that will be released in near future (i guess January 2015). Link to comment Share on other sites More sharing options...
rexii2300 Posted January 10, 2015 Share Posted January 10, 2015 Just upgraded to 1.6.0.11 and I still have this problem. Stock Management screen shows qty = 1, instant stock status shows physical, usable, real qty all = 1. But when I try to remove stock, I get the error "You don't have enough usable quantity. Cannot remove 1 out of 0." Anyone else having this issue? If so I'll raise a bug Link to comment Share on other sites More sharing options...
frank_jarle Posted January 12, 2015 Share Posted January 12, 2015 I suggest you open a new bug for this and link it to this "old" bug. You might get some clue from this old bug, maybe some information there can help you to solve it yourself: Ref: http://forge.prestashop.com/browse/PSCFV-5632 Link to comment Share on other sites More sharing options...
chris0241 Posted February 2, 2015 Share Posted February 2, 2015 Still got this bug, the forge.prestashop bug tracker has closed this without a fix Link to comment Share on other sites More sharing options...
f00se Posted March 24, 2015 Share Posted March 24, 2015 (edited) I also have problem with this function ;] Edited March 24, 2015 by f00se (see edit history) Link to comment Share on other sites More sharing options...
fransjaeger Posted March 24, 2015 Share Posted March 24, 2015 Hi. I have this problem too. Please tell me how to reduce qty? Any ways to do it. Im running 1.6.0.9 and im not in mood for any larger updates. Any fix found? PLZ help Link to comment Share on other sites More sharing options...
fransjaeger Posted March 25, 2015 Share Posted March 25, 2015 (edited) Im trying to see if i can find the code bug I found the place in code where something is wrong file: StockManager.php // check quantity if we want to decrement unusable quantity if (!$is_usable){ $quantity_in_stock = $physical_quantity_in_stock - $usable_quantity_in_stock; PrestaShopLogger::addLog('removeProduct physical_quantity_in_stock='.$physical_quantity_in_stock.' usable_quantity_in_stock='.$usable_quantity_in_stock, 1, null, null, null, true); } else { $quantity_in_stock = $usable_quantity_in_stock; } As you can see i put PrestaShopLogger in there and that reveals that "removeProduct physical_quantity_in_stock=8 usable_quantity_in_stock=8"when im looking at stock prestahop tells me that i have 6 usable and 2 unusable.so i guess the correct should be:"removeProduct physical_quantity_in_stock=8 usable_quantity_in_stock=6" Edited March 25, 2015 by michaelhjulskov (see edit history) 1 Link to comment Share on other sites More sharing options...
chris0241 Posted May 19, 2015 Share Posted May 19, 2015 Is this bug still present on the latest stable releases? Link to comment Share on other sites More sharing options...
ragnabt Posted September 16, 2015 Share Posted September 16, 2015 (edited) It has something to with stockmvt tables in the db, if there is no data there it cant be done. I importet my stock so I think its the cause :/ Edited September 16, 2015 by ragnabt (see edit history) Link to comment Share on other sites More sharing options...
fransjaeger Posted September 16, 2015 Share Posted September 16, 2015 Yes i still have this issue present on my 1.6.0.9 and gladly receive advise or instructions how i can fix. I also experience issue with adv stock management when adding new products to order, it messes up the quantity. Help is more than welcome Link to comment Share on other sites More sharing options...
ragnabt Posted September 17, 2015 Share Posted September 17, 2015 (edited) Hi I cant say if this is a bug in 1.6.0.9 but in my 1.6.0.11 i just had to import the quantity data into the stock_mvt table. The problem was that I only imported data into tables stock and stock_available but not into stock_mvt. (I was upgrading my shop from 1.4.7 to 1.6.0.11, and imported all of the products etc), and if there is no "start" data in the stock_mvt table then the advanced stock system thinks there is 0 on stock when removing from stock, and of course you cant remove something you dont have Hope that explains it, just try with one product and see if that works. insert into YOURPREFIX_stock_mvt (id_stock, id_order, id_supply_order, id_stock_mvt_reason, id_employee, employee_lastname, employee_firstname,physical_quantity, date_add, sign, price_te, referer) values (id_stock, 0, 0, 1, 1, 'employee lastname', 'employee firstname', quantity, now(),1,price,0) Edited September 17, 2015 by ragnabt (see edit history) Link to comment Share on other sites More sharing options...
fransjaeger Posted December 8, 2015 Share Posted December 8, 2015 Hi I cant say if this is a bug in 1.6.0.9 but in my 1.6.0.11 i just had to import the quantity data into the stock_mvt table. The problem was that I only imported data into tables stock and stock_available but not into stock_mvt. (I was upgrading my shop from 1.4.7 to 1.6.0.11, and imported all of the products etc), and if there is no "start" data in the stock_mvt table then the advanced stock system thinks there is 0 on stock when removing from stock, and of course you cant remove something you dont have Hope that explains it, just try with one product and see if that works. insert into YOURPREFIX_stock_mvt (id_stock, id_order, id_supply_order, id_stock_mvt_reason, id_employee, employee_lastname, employee_firstname,physical_quantity, date_add, sign, price_te, referer) values (id_stock, 0, 0, 1, 1, 'employee lastname', 'employee firstname', quantity, now(),1,price,0) Hi there Is this a solution that actually works or is it a temp fix? Link to comment Share on other sites More sharing options...
fransjaeger Posted December 9, 2015 Share Posted December 9, 2015 (edited) I think I might have found the bug after spending many hours envestigating PS 1.6.0.9 replaced "break;" with "continue;" I made contrib here I made this override override/classes/stock/StockManager.php <?php /* * override Michael Hjulskov */ class StockManager extends StockManagerCore { public function removeProduct($id_product, $id_product_attribute = null, Warehouse $warehouse, $quantity, $id_stock_mvt_reason, $is_usable = true, $id_order = null) { $return = array(); if (!Validate::isLoadedObject($warehouse) || !$quantity || !$id_product) return $return; if (!StockMvtReason::exists($id_stock_mvt_reason)) $id_stock_mvt_reason = Configuration::get('PS_STOCK_MVT_DEC_REASON_DEFAULT'); $context = Context::getContext(); // Special case of a pack if (Pack::isPack((int)$id_product)) { // Gets items $products_pack = Pack::getItems((int)$id_product, (int)Configuration::get('PS_LANG_DEFAULT')); // Foreach item foreach ($products_pack as $product_pack) { $pack_id_product_attribute = Product::getDefaultAttribute($product_pack->id, 1); if ($product_pack->advanced_stock_management == 1) $this->removeProduct($product_pack->id, $pack_id_product_attribute, $warehouse, $product_pack->pack_quantity * $quantity, $id_stock_mvt_reason, $is_usable, $id_order); } } else { // gets total quantities in stock for the current product $physical_quantity_in_stock = (int)$this->getProductPhysicalQuantities($id_product, $id_product_attribute, array($warehouse->id), false); $usable_quantity_in_stock = (int)$this->getProductPhysicalQuantities($id_product, $id_product_attribute, array($warehouse->id), true); // check quantity if we want to decrement unusable quantity if (!$is_usable){ $quantity_in_stock = $physical_quantity_in_stock - $usable_quantity_in_stock; } else { $quantity_in_stock = $usable_quantity_in_stock; } // checks if it's possible to remove the given quantity if ($quantity_in_stock < $quantity) return $return; $stock_collection = $this->getStockCollection($id_product, $id_product_attribute, $warehouse->id); $stock_collection->getAll(); // check if the collection is loaded if (count($stock_collection) <= 0) return $return; $stock_history_qty_available = array(); $mvt_params = array(); $stock_params = array(); $quantity_to_decrement_by_stock = array(); $global_quantity_to_decrement = $quantity; // switch on MANAGEMENT_TYPE switch ($warehouse->management_type) { // case CUMP mode case 'WA': // There is one and only one stock for a given product in a warehouse in this mode $stock = $stock_collection->current(); $mvt_params = array( 'id_stock' => $stock->id, 'physical_quantity' => $quantity, 'id_stock_mvt_reason' => $id_stock_mvt_reason, 'id_order' => $id_order, 'price_te' => $stock->price_te, 'last_wa' => $stock->price_te, 'current_wa' => $stock->price_te, 'id_employee' => $context->employee->id, 'employee_firstname' => $context->employee->firstname, 'employee_lastname' => $context->employee->lastname, 'sign' => -1 ); $stock_params = array( 'physical_quantity' => ($stock->physical_quantity - $quantity), 'usable_quantity' => ($is_usable ? ($stock->usable_quantity - $quantity) : $stock->usable_quantity) ); // saves stock in warehouse $stock->hydrate($stock_params); $stock->update(); // saves stock mvt $stock_mvt = new StockMvt(); $stock_mvt->hydrate($mvt_params); $stock_mvt->save(); $return[$stock->id]['quantity'] = $quantity; $return[$stock->id]['price_te'] = $stock->price_te; break; case 'LIFO': case 'FIFO': // 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; if ($left_quantity_to_check <= 0) continue; $resource = Db::getInstance(_PS_USE_SQL_SLAVE_)->query(' SELECT sm.`id_stock_mvt`, sm.`date_add`, sm.`physical_quantity`, IF ((sm2.`physical_quantity` is null), sm.`physical_quantity`, (sm.`physical_quantity` - SUM(sm2.`physical_quantity`))) as qty FROM `'._DB_PREFIX_.'stock_mvt` sm LEFT JOIN `'._DB_PREFIX_.'stock_mvt` sm2 ON sm2.`referer` = sm.`id_stock_mvt` WHERE sm.`sign` = 1 AND sm.`id_stock` = '.(int)$stock->id.' GROUP BY sm.`id_stock_mvt` ORDER BY sm.`date_add` DESC' ); while ($row = Db::getInstance()->nextRow($resource)) { // 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'] == 0) continue; // Michael Hjulskov - here it was originally: break; // converts date to timestamp $date = new DateTime($row['date_add']); $timestamp = $date->format('U'); // history of the mvt $stock_history_qty_available[$timestamp] = array( 'id_stock' => $stock->id, 'id_stock_mvt' => (int)$row['id_stock_mvt'], 'qty' => (int)$row['qty'] ); // 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']; if ($left_quantity_to_check <= 0) break; } } } if ($warehouse->management_type == 'LIFO') // orders stock history by timestamp to get newest history first krsort($stock_history_qty_available); else // orders stock history by timestamp to get oldest history first ksort($stock_history_qty_available); // checks each stock to manage the real quantity to decrement for each of them foreach ($stock_history_qty_available as $entry) { if ($entry['qty'] >= $global_quantity_to_decrement) { $quantity_to_decrement_by_stock[$entry['id_stock']][$entry['id_stock_mvt']] = $global_quantity_to_decrement; $global_quantity_to_decrement = 0; } else { $quantity_to_decrement_by_stock[$entry['id_stock']][$entry['id_stock_mvt']] = $entry['qty']; $global_quantity_to_decrement -= $entry['qty']; } if ($global_quantity_to_decrement <= 0) break; } // for each stock, decrements it and logs the mvts foreach ($stock_collection as $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] as $id_mvt_referrer => $qte) { $mvt_params = array( '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, 'referer' => $id_mvt_referrer, 'id_employee' => $context->employee->id ); // saves stock mvt $stock_mvt = new StockMvt(); $stock_mvt->hydrate($mvt_params); $stock_mvt->save(); $total_quantity_for_current_stock += $qte; } $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]['quantity'] = $total_quantity_for_current_stock; $return[$stock->id]['price_te'] = $stock->price_te; // saves stock in warehouse $stock->hydrate($stock_params); $stock->update(); } } break; } } // if we remove a usable quantity, exec hook if ($is_usable) Hook::exec('actionProductCoverage', array( 'id_product' => $id_product, 'id_product_attribute' => $id_product_attribute, 'warehouse' => $warehouse ) ); return $return; } } Edited December 9, 2015 by fransjaeger (see edit history) Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now