diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php
index 26c8a5beef9..0e4cd66e323 100644
--- a/htdocs/commande/list.php
+++ b/htdocs/commande/list.php
@@ -715,7 +715,7 @@ if ($resql)
// Get local and virtual stock and store it into cache
if (empty($productstat_cache[$generic_commande->lines[$lig]->fk_product])) {
- $generic_product->load_stock();
+ $generic_product->load_stock('nobatch');
//$generic_product->load_virtual_stock(); Already included into load_stock
$productstat_cache[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_reel;
$productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_theorique;
@@ -723,7 +723,7 @@ if ($resql)
$generic_product->stock_reel = $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stock_reel'];
$generic_product->stock_theorique = $productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_theorique;
}
-
+
if (empty($conf->global->SHIPPABLE_ORDER_ICON_IN_LIST)) // Default code. Default is when this option is not set, setting it create strange result
{
$text_info .= $generic_commande->lines[$lig]->qty.' X '.$generic_commande->lines[$lig]->ref.' '.dol_trunc($generic_commande->lines[$lig]->product_label, 25);
diff --git a/htdocs/install/mysql/migration/3.9.0-4.0.0.sql b/htdocs/install/mysql/migration/3.9.0-4.0.0.sql
index 832107e7f6f..fffca45c77e 100644
--- a/htdocs/install/mysql/migration/3.9.0-4.0.0.sql
+++ b/htdocs/install/mysql/migration/3.9.0-4.0.0.sql
@@ -66,6 +66,8 @@ ALTER TABLE llx_product ADD COLUMN height_units tinyint DEFAULT NULL;
ALTER TABLE llx_product ADD COLUMN default_vat_code varchar(10) after cost_price;
+ALTER TABLE llx_product MODIFY COLUMN stock real;
+
CREATE TABLE llx_categorie_user
(
fk_categorie integer NOT NULL,
diff --git a/htdocs/install/mysql/tables/llx_product.sql b/htdocs/install/mysql/tables/llx_product.sql
index 9d3446d696d..8b43844498e 100755
--- a/htdocs/install/mysql/tables/llx_product.sql
+++ b/htdocs/install/mysql/tables/llx_product.sql
@@ -79,7 +79,7 @@ create table llx_product
surface_units tinyint DEFAULT NULL,
volume float DEFAULT NULL,
volume_units tinyint DEFAULT NULL,
- stock integer, -- Current physical stock (dernormalized field)
+ stock real, -- Current physical stock (dernormalized field)
pmp double(24,8) DEFAULT 0 NOT NULL, -- To store valuation of stock calculated using average price method, for this product
fifo double(24,8), -- To store valuation of stock calculated using fifo method, for this product
lifo double(24,8), -- To store valuation of stock calculated using lifo method, for this product
diff --git a/htdocs/install/mysql/tables/llx_stock_mouvement.sql b/htdocs/install/mysql/tables/llx_stock_mouvement.sql
index 3db9a4475cd..3ac42c0c852 100644
--- a/htdocs/install/mysql/tables/llx_stock_mouvement.sql
+++ b/htdocs/install/mysql/tables/llx_stock_mouvement.sql
@@ -24,8 +24,8 @@ create table llx_stock_mouvement
datem datetime, -- Date and hour of movement
fk_product integer NOT NULL, -- Id of product
batch varchar(30) DEFAULT NULL, -- Lot or serial number
- eatby date DEFAULT NULL, -- Eatby date
- sellby date DEFAULT NULL, -- Sellby date
+ eatby date DEFAULT NULL, -- Eatby date (deprecated, we should get value from batch number in table llx_product_lot)
+ sellby date DEFAULT NULL, -- Sellby date (deprecated, we should get value from batch number in table llx_product_lot)
fk_entrepot integer NOT NULL, -- Id warehouse
value real, -- Qty of movement
price double(24,8) DEFAULT 0, -- Entry price (used to calculate PMP, FIFO or LIFO value)
diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
index 685a29cb8e1..f93e5254ce0 100644
--- a/htdocs/product/class/product.class.php
+++ b/htdocs/product/class/product.class.php
@@ -1850,7 +1850,7 @@ class Product extends CommonObject
}
}
- // We should not load stock at each fetch. If someone need stock, he must call load_stock after fetch.
+ // We should not load stock during the fetch. If someone need stock of product, he must call load_stock after fetching product.
//$res=$this->load_stock();
// instead we just init the stock_warehouse array
$this->stock_warehouse = array();
@@ -2847,7 +2847,7 @@ class Product extends CommonObject
//print "XXX We add id=".$id." - label=".$label." - nb=".$nb." - multiply=".$multiply." fullpath=".$compl_path.$label."\n";
$this->fetch($id); // Load product
- $this->load_stock(); // Load stock
+ $this->load_stock('nobatch,novirtual'); // Load stock to get true this->stock_reel
$this->res[]= array(
'id'=>$id, // Id product
'id_parent'=>$id_parent,
diff --git a/htdocs/product/list.php b/htdocs/product/list.php
index 1df8e667569..3ed4673a95d 100644
--- a/htdocs/product/list.php
+++ b/htdocs/product/list.php
@@ -142,8 +142,8 @@ $arrayfields=array(
'p.minbuyprice'=>array('label'=>$langs->trans("BuyingPriceMinShort"), 'checked'=>1, 'enabled'=>(! empty($user->rights->fournisseur->lire))),
'p.seuil_stock_alerte'=>array('label'=>$langs->trans("StockLimit"), 'checked'=>0, 'enabled'=>(! empty($conf->stock->enabled) && $user->rights->stock->lire && $contextpage != 'service')),
'p.desiredstock'=>array('label'=>$langs->trans("DesiredStock"), 'checked'=>1, 'enabled'=>(! empty($conf->stock->enabled) && $user->rights->stock->lire && $contextpage != 'service')),
- 'p.tobatch'=>array('label'=>$langs->trans("ManageLotSerial"), 'checked'=>0, 'enabled'=>(! empty($conf->productbatch->enabled))),
'p.stock'=>array('label'=>$langs->trans("PhysicalStock"), 'checked'=>1, 'enabled'=>(! empty($conf->stock->enabled) && $user->rights->stock->lire && $contextpage != 'service')),
+ 'p.tobatch'=>array('label'=>$langs->trans("ManageLotSerial"), 'checked'=>0, 'enabled'=>(! empty($conf->productbatch->enabled))),
'p.accountancy_code_sell'=>array('label'=>$langs->trans("ProductAccountancySellCode"), 'checked'=>0),
'p.accountancy_code_buy'=>array('label'=>$langs->trans("ProductAccountancyBuyCode"), 'checked'=>0),
'p.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500),
@@ -428,8 +428,8 @@ else
if (! empty($arrayfields['p.minbuyprice']['checked'])) print_liste_field_titre($arrayfields['p.minbuyprice']['label'], $_SERVER["PHP_SELF"],"","",$param,'align="right"',$sortfield,$sortorder);
if (! empty($arrayfields['p.seuil_stock_alerte']['checked'])) print_liste_field_titre($arrayfields['p.seuil_stock_alerte']['label'], $_SERVER["PHP_SELF"],"p.seuil_stock_alerte","",$param,'align="right"',$sortfield,$sortorder);
if (! empty($arrayfields['p.desiredstock']['checked'])) print_liste_field_titre($arrayfields['p.desiredstock']['label'], $_SERVER["PHP_SELF"],"p.desiredstock","",$param,'align="right"',$sortfield,$sortorder);
- if (! empty($arrayfields['p.tobatch']['checked'])) print_liste_field_titre($arrayfields['p.tobatch']['label'], $_SERVER["PHP_SELF"],"p.tobatch","",$param,'align="center"',$sortfield,$sortorder);
if (! empty($arrayfields['p.stock']['checked'])) print_liste_field_titre($arrayfields['p.stock']['label'], $_SERVER["PHP_SELF"],"p.stock","",$param,'align="right"',$sortfield,$sortorder);
+ if (! empty($arrayfields['p.tobatch']['checked'])) print_liste_field_titre($arrayfields['p.tobatch']['label'], $_SERVER["PHP_SELF"],"p.tobatch","",$param,'align="center"',$sortfield,$sortorder);
if (! empty($arrayfields['p.accountancy_code_sell']['checked'])) print_liste_field_titre($arrayfields['p.accountancy_code_sell']['label'], $_SERVER["PHP_SELF"],"p.accountancy_code_sell","",$param,'',$sortfield,$sortorder);
if (! empty($arrayfields['p.accountancy_code_buy']['checked'])) print_liste_field_titre($arrayfields['p.accountancy_code_buy']['label'], $_SERVER["PHP_SELF"],"p.accountancy_code_buy","",$param,'',$sortfield,$sortorder);
if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label))
@@ -515,11 +515,11 @@ else
print ' ';
print '';
}
- // To batch
- if (! empty($arrayfields['p.tobatch']['checked'])) print '