diff --git a/dev/skeletons/build_class_from_table.php b/dev/skeletons/build_class_from_table.php
index 800bafe6318..ecdbbd09dc4 100755
--- a/dev/skeletons/build_class_from_table.php
+++ b/dev/skeletons/build_class_from_table.php
@@ -259,7 +259,7 @@ foreach($property as $key => $prop)
if ($addfield)
{
$varprop.="\t\t\$sql.= '".$prop['field'];
- if ($i <= count($property)-$no_output_field) $varprop.=",";
+ if ($i < (count($property)-$no_output_field)) $varprop.=",";
$varprop.="';";
$varprop.="\n";
}
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 93469ff5a8f..f34e52dafe6 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
@@ -54,6 +54,8 @@ CREATE TABLE llx_product_lot (
import_key integer
) ENGINE=InnoDB;
+ALTER TABLE llx_product_lot ADD UNIQUE INDEX uk_product_lot(fk_product, batch);
+
DROP TABLE llx_stock_serial;
ALTER TABLE llx_product ADD COLUMN note_public text;
@@ -460,6 +462,11 @@ CREATE TABLE llx_advtargetemailing
ALTER TABLE llx_advtargetemailing ADD UNIQUE INDEX uk_advtargetemailing_name (name);
+update llx_product_batch set batch = '000000' where batch = 'Non défini';
+update llx_product_batch set batch = '000000' where batch = 'Non défini';
+update llx_product_batch set batch = '000000' where batch = 'Undefined';
+update llx_product_lot set batch = '000000' where batch = 'Undefined';
+update llx_stock_mouvement set batch = '000000' where batch = 'Undefined';
-- At end
ALTER TABLE llx_product_batch ADD UNIQUE INDEX uk_product_batch (fk_product_stock, batch);
diff --git a/htdocs/langs/en_US/productbatch.lang b/htdocs/langs/en_US/productbatch.lang
index 37ceaa49b38..c3d78f7ff7f 100644
--- a/htdocs/langs/en_US/productbatch.lang
+++ b/htdocs/langs/en_US/productbatch.lang
@@ -17,6 +17,5 @@ printEatby=Eat-by: %s
printSellby=Sell-by: %s
printQty=Qty: %d
AddDispatchBatchLine=Add a line for Shelf Life dispatching
-BatchDefaultNumber=Undefined
WhenProductBatchModuleOnOptionAreForced=When module Lot/Serial is on, increase/decrease stock mode is forced to last choice and can't be edited. Other options can be defined as you want.
ProductDoesNotUseBatchSerial=This product does not use lot/serial number
diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
index e8b32f978cb..31aa35aba69 100644
--- a/htdocs/product/class/product.class.php
+++ b/htdocs/product/class/product.class.php
@@ -607,7 +607,8 @@ class Product extends CommonObject
}
/**
- * Update a record into database
+ * Update a record into database.
+ * If batch flag is set to on, we create records into llx_product_batch
*
* @param int $id Id of product
* @param User $user Object user making update
@@ -672,25 +673,46 @@ class Product extends CommonObject
$org->fetch($this->id);
$this->oldcopy=$org;
}
- // test if batch management is activated on existing product
+
+ // Test if batch management is activated on existing product
+ // If yes, we create missing entries into product_batch
if ($this->hasbatch() && !$this->oldcopy->hasbatch())
{
+ //$valueforundefinedlot = 'Undefined'; // In previous version, 39 and lower
+ $valueforundefinedlot = '000000';
+
+ dol_syslog("Flag batch of product id=".$this->id." is set to ON, so we will create missing records into product_batch");
+
$this->load_stock();
- foreach ($this->stock_warehouse as $idW => $ObjW)
+ foreach ($this->stock_warehouse as $idW => $ObjW) // For each warehouse where we have stocks defined for this product (for each lines in product_stock)
{
$qty_batch = 0;
- foreach ($ObjW->detail_batch as $detail)
+ foreach ($ObjW->detail_batch as $detail) // Each lines of detail in product_batch of the current $ObjW = product_stock
{
+ if ($detail->batch == $valueforundefinedlot || $detail->batch == 'Undefined')
+ {
+ // We discard this line, we will create it later
+ $sqlclean="DELETE FROM ".MAIN_DB_PREFIX."product_batch WHERE batch in('Undefined', '".$valueforundefinedlot."') AND fk_product_stock = ".$ObjW->id;
+ $result = $this->db->query($sqlclean);
+ if (! $result)
+ {
+ dol_print_error($this->db);
+ exit;
+ }
+ continue;
+ }
+
$qty_batch += $detail->qty;
}
- // Quantities in batch details are not same same as stock quantity
- // So we add a default batch record
+ // Quantities in batch details are not same as stock quantity,
+ // so we add a default batch record to complete and get same qty in parent and child table
if ($ObjW->real <> $qty_batch)
{
$ObjBatch = new Productbatch($this->db);
- $ObjBatch->batch = $langs->trans('BatchDefaultNumber');
- $ObjBatch->qty = $ObjW->real - $qty_batch;
+ $ObjBatch->batch = $valueforundefinedlot;
+ $ObjBatch->qty = ($ObjW->real - $qty_batch);
$ObjBatch->fk_product_stock = $ObjW->id;
+
if ($ObjBatch->create($user,1) < 0)
{
$error++;
@@ -699,6 +721,7 @@ class Product extends CommonObject
}
}
}
+
// For automatic creation
if ($this->barcode == -1) $this->barcode = $this->get_barcode($this,$this->barcode_type_code);
@@ -744,6 +767,7 @@ class Product extends CommonObject
$sql.= ", price_autogen = " . (!$this->price_autogen ? 0 : 1);
$sql.= ", fk_price_expression = ".($this->fk_price_expression != 0 ? $this->fk_price_expression : 'NULL');
$sql.= ", fk_user_modif = ".($user->id > 0 ? $user->id : 'NULL');
+ // stock field is not here because it is a denormalized value from product_stock.
$sql.= " WHERE rowid = " . $id;
dol_syslog(get_class($this)."::update", LOG_DEBUG);
@@ -1597,7 +1621,7 @@ class Product extends CommonObject
* @param int $ignore_expression Ignores the math expression for calculating price and uses the db value instead
* @return int <0 if KO, 0 if not found, >0 if OK
*/
- function fetch($id='', $ref='', $ref_ext='', $ignore_expression = 0)
+ function fetch($id='', $ref='', $ref_ext='', $ignore_expression=0)
{
include_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
diff --git a/htdocs/product/class/productbatch.class.php b/htdocs/product/class/productbatch.class.php
index d4440dac0f3..ed03c3e729e 100644
--- a/htdocs/product/class/productbatch.class.php
+++ b/htdocs/product/class/productbatch.class.php
@@ -40,7 +40,7 @@ class Productbatch extends CommonObject
var $batch='';
var $qty;
public $warehouseid;
-
+ public $fk_product;
@@ -75,7 +75,7 @@ class Productbatch extends CommonObject
// Put here code to add control on parameters values
// Insert request
- $sql = "INSERT INTO ".MAIN_DB_PREFIX.self::$_table_element." (";
+ $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_batch (";
$sql.= "fk_product_stock,";
$sql.= "sellby,";
$sql.= "eatby,";
@@ -143,15 +143,18 @@ class Productbatch extends CommonObject
$sql.= " t.tms,";
$sql.= " t.fk_product_stock,";
- $sql.= " t.sellby,";
- $sql.= " t.eatby,";
+ $sql.= " t.sellby as oldsellby,";
+ $sql.= " t.eatby as oldeatby,";
$sql.= " t.batch,";
$sql.= " t.qty,";
$sql.= " t.import_key,";
- $sql.= " w.fk_entrepot";
+ $sql.= " w.fk_entrepot,";
+ $sql.= " w.fk_product,";
+ $sql.= " pl.eatby,";
+ $sql.= " pl.sellby";
- $sql.= " FROM ".MAIN_DB_PREFIX.self::$_table_element." as t";
- $sql.= " INNER JOIN ".MAIN_DB_PREFIX."product_stock w on t.fk_product_stock=w.rowid";
+ $sql.= " FROM ".MAIN_DB_PREFIX."product_batch as t INNER JOIN ".MAIN_DB_PREFIX."product_stock w on t.fk_product_stock = w.rowid";
+ $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_lot as pl on pl.fk_product = w.fk_product and pl.batch = t.batch";
$sql.= " WHERE t.rowid = ".$id;
dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
@@ -165,12 +168,13 @@ class Productbatch extends CommonObject
$this->id = $obj->rowid;
$this->tms = $this->db->jdate($obj->tms);
$this->fk_product_stock = $obj->fk_product_stock;
- $this->sellby = $this->db->jdate($obj->sellby);
- $this->eatby = $this->db->jdate($obj->eatby);
+ $this->sellby = $this->db->jdate($obj->sellby?$obj->sellby:$obj->oldsellby);
+ $this->eatby = $this->db->jdate($obj->eatby?$obj->eatby:$obj->oldeatby);
$this->batch = $obj->batch;
$this->qty = $obj->qty;
$this->import_key = $obj->import_key;
$this->warehouseid= $obj->fk_entrepot;
+ $this->fk_product= $obj->fk_product;
}
$this->db->free($resql);
@@ -408,9 +412,9 @@ class Productbatch extends CommonObject
* Find first detail record that match eather eat-by or sell-by or batch within given warehouse
*
* @param int $fk_product_stock id product_stock for objet
- * @param date $eatby eat-by date for objet - deprecated: a search must be done on batch number
- * @param date $sellby sell-by date for objet - deprecated: a search must be done on batch number
- * @param string $batch_number batch number for objet
+ * @param date $eatby eat-by date for object - deprecated: a search must be done on batch number
+ * @param date $sellby sell-by date for object - deprecated: a search must be done on batch number
+ * @param string $batch_number batch number for object
* @return int <0 if KO, >0 if OK
*/
function find($fk_product_stock=0, $eatby='',$sellby='',$batch_number='')
@@ -421,8 +425,8 @@ class Productbatch extends CommonObject
$sql.= " t.rowid,";
$sql.= " t.tms,";
$sql.= " t.fk_product_stock,";
- $sql.= " t.sellby,";
- $sql.= " t.eatby,";
+ $sql.= " t.sellby,"; // deprecated
+ $sql.= " t.eatby,"; // deprecated
$sql.= " t.batch,";
$sql.= " t.qty,";
$sql.= " t.import_key";
@@ -431,6 +435,7 @@ class Productbatch extends CommonObject
if (! empty($eatby)) array_push($where," eatby = '".$this->db->idate($eatby)."'"); // deprecated
if (! empty($sellby)) array_push($where," sellby = '".$this->db->idate($sellby)."'"); // deprecated
+
if (! empty($batch_number)) $sql.= " AND batch = '".$this->db->escape($batch_number)."'";
if (! empty($where)) $sql.= " AND (".implode(" OR ",$where).")";
@@ -468,10 +473,11 @@ class Productbatch extends CommonObject
*
* @param DoliDB $db database object
* @param int $fk_product_stock id product_stock for objet
- * @param int $with_qty doesn't return line with 0 quantity
+ * @param int $with_qty 1 = doesn't return line with 0 quantity
+ * @param int $fk_product If set to a product id, get eatby and sellby from table llx_product_lot
* @return array <0 if KO, array of batch
*/
- public static function findAll($db,$fk_product_stock,$with_qty=0)
+ public static function findAll($db, $fk_product_stock, $with_qty=0, $fk_product=0)
{
global $langs;
$ret = array();
@@ -480,14 +486,22 @@ class Productbatch extends CommonObject
$sql.= " t.rowid,";
$sql.= " t.tms,";
$sql.= " t.fk_product_stock,";
- $sql.= " t.sellby,";
- $sql.= " t.eatby,";
+ $sql.= " t.sellby as oldsellby,"; // deprecated but may not be migrated into new table
+ $sql.= " t.eatby as oldeatby,"; // deprecated but may not be migrated into new table
$sql.= " t.batch,";
$sql.= " t.qty,";
$sql.= " t.import_key";
+ if ($fk_product > 0)
+ {
+ $sql.= ", pl.eatby as eatby, pl.sellby as sellby";
+ }
$sql.= " FROM ".MAIN_DB_PREFIX."product_batch as t";
+ if ($fk_product > 0)
+ {
+ $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_lot as pl ON pl.fk_product = ".$fk_product." AND pl.batch = t.batch";
+ }
$sql.= " WHERE fk_product_stock=".$fk_product_stock;
- if ($with_qty) $sql.= " AND qty<>0";
+ if ($with_qty) $sql.= " AND t.qty <> 0";
dol_syslog("productbatch::findAll", LOG_DEBUG);
$resql=$db->query($sql);
@@ -499,12 +513,12 @@ class Productbatch extends CommonObject
{
$obj = $db->fetch_object($resql);
- $tmp = new productbatch($db);
+ $tmp = new Productbatch($db);
$tmp->id = $obj->rowid;
$tmp->tms = $db->jdate($obj->tms);
$tmp->fk_product_stock = $obj->fk_product_stock;
- $tmp->sellby = $db->jdate($obj->sellby);
- $tmp->eatby = $db->jdate($obj->eatby);
+ $tmp->sellby = $db->jdate($obj->sellby ? $obj->sellby : $obj->oldsellby);
+ $tmp->eatby = $db->jdate($obj->eatby ? $obj->eatby : $obj->oldeatby);
$tmp->batch = $obj->batch;
$tmp->qty = $obj->qty;
$tmp->import_key = $obj->import_key;
diff --git a/htdocs/product/reassortlot.php b/htdocs/product/reassortlot.php
index b23a1cbf25c..f7d5e60ca72 100644
--- a/htdocs/product/reassortlot.php
+++ b/htdocs/product/reassortlot.php
@@ -105,15 +105,17 @@ $htmlother=new FormOther($db);
$title=$langs->trans("ProductsAndServices");
-$sql = 'SELECT p.rowid, p.ref, p.label, p.barcode, p.price, p.price_ttc, p.price_base_type,p.entity,';
+$sql = 'SELECT p.rowid, p.ref, p.label, p.barcode, p.price, p.price_ttc, p.price_base_type, p.entity,';
$sql.= ' p.fk_product_type, p.tms as datem,';
-$sql.= ' p.duration, p.tosell as statut, p.tobuy, p.seuil_stock_alerte, p.desiredstock,';
+$sql.= ' p.duration, p.tosell as statut, p.tobuy, p.seuil_stock_alerte, p.desiredstock, p.stock, p.tobatch,';
$sql.= ' s.fk_entrepot,';
-$sql.= ' pb.batch, pb.eatby, pb.sellby,';
-$sql.= ' SUM(pb.qty) as stock_physique';
+$sql.= ' pb.batch, pb.eatby as oldeatby, pb.sellby as oldsellby,';
+$sql.= ' pl.eatby, pl.sellby,';
+$sql.= ' SUM(pb.qty) as stock_physique, COUNT(pb.rowid) as nbinbatchtable';
$sql.= ' FROM '.MAIN_DB_PREFIX.'product as p';
$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_stock as s on p.rowid = s.fk_product';
$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_batch as pb on pb.fk_product_stock = s.rowid';
+$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_lot as pl on pl.fk_product = p.rowid AND pl.batch = pb.batch';
// We'll need this table joined to the select in order to filter by categ
if ($search_categ) $sql.= ", ".MAIN_DB_PREFIX."categorie_product as cp";
$sql.= " WHERE p.entity IN (".getEntity('product', 1).")";
@@ -166,10 +168,12 @@ if ($search_batch)
{
$sql .= " AND pb.batch LIKE '%".$db->escape($search_batch)."%'";
}
-$sql.= " GROUP BY p.rowid, p.ref, p.label, p.barcode, p.price, p.price_ttc, p.price_base_type,";
-$sql.= " p.fk_product_type, p.tms, p.duration, p.tosell, p.tobuy, p.seuil_stock_alerte, p.desiredstock,";
+$sql.= " GROUP BY p.rowid, p.ref, p.label, p.barcode, p.price, p.price_ttc, p.price_base_type, p.entity,";
+$sql.= " p.fk_product_type, p.tms,";
+$sql.= " p.duration, p.tosell, p.tobuy, p.seuil_stock_alerte, p.desiredstock, p.stock, p.tobatch,";
$sql.= " s.fk_entrepot,";
-$sql.= " pb.batch, pb.eatby, pb.sellby";
+$sql.= " pb.batch, pb.eatby, pb.sellby,";
+$sql.= " pl.eatby, pl.sellby";
if ($toolowstock) $sql.= " HAVING SUM(".$db->ifsql('s.reel IS NULL', '0', 's.reel').") < p.seuil_stock_alerte"; // Not used yet
$sql.= $db->order($sortfield,$sortorder);
$sql.= $db->plimit($limit + 1, $offset);
@@ -364,7 +368,7 @@ if ($resql)
//if ($objp->seuil_stock_alerte && ($objp->stock_physique < $objp->seuil_stock_alerte)) print img_warning($langs->trans("StockTooLow")).' ';
print $objp->stock_physique;
print '';
- print '
'.$langs->trans("Movements").' ';
+ print ''.$langs->trans("Movements").' ';
print ''.$product_static->LibStatut($objp->statut,5,0).' ';
print ''.$product_static->LibStatut($objp->tobuy,5,1).' ';
print "\n";
diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php
index 9b6db71be9e..b9859f9ec9b 100644
--- a/htdocs/product/stock/class/mouvementstock.class.php
+++ b/htdocs/product/stock/class/mouvementstock.class.php
@@ -117,7 +117,6 @@ class MouvementStock extends CommonObject
// Test if product require batch data. If yes, and there is not, we throw an error.
if (! empty($conf->productbatch->enabled) && $product->hasbatch() && ! $skip_batch)
{
- //if (empty($batch) && empty($eatby) && empty($sellby))
if (empty($batch))
{
$this->errors[]=$langs->trans("ErrorTryToMakeMoveOnProductRequiringBatchData", $product->name);
@@ -130,8 +129,9 @@ class MouvementStock extends CommonObject
// FIXME Code not complete to implement this
// Check table llx_product_lot from batchnumber for same product
// If found and eatby/sellby defined into table and provided and differs, return error
- // If found and eatby/sellby not defined into table and provided, we update table
// If found and eatby/sellby defined into table and not provided, we take value from table
+ // If found and eatby/sellby not defined into table and provided, we update table
+ // If found and eatby/sellby not defined into table and not provided, we do nothing
// If not found, we add record
$sql = "SELECT pb.rowid, pb.batch, pb.eatby, pb.sellby FROM ".MAIN_DB_PREFIX."product_lot as pb";
$sql.= " WHERE pb.fk_product = ".$fk_product." AND pb.batch = '".$this->db->escape($batch)."'";
@@ -158,6 +158,27 @@ class MouvementStock extends CommonObject
return -3;
}
}
+ else
+ {
+ $eatby = $obj->eatby; // If found and eatby/sellby defined into table and not provided, we take value from table
+ }
+ }
+ else
+ {
+ if ($eatby) // If found and eatby/sellby not defined into table and provided, we update table
+ {
+ $productlot = new Productlot($this->db);
+ $result = $productlot->fetch($obj->rowid);
+ $productlot->eatby = $eatby;
+ $result = $productlot->update($user);
+ if ($result <= 0)
+ {
+ $this->error = $productlot->error;
+ $this->errors = $productlot->errors;
+ $this->db->rollback();
+ return -5;
+ }
+ }
}
if ($obj->sellby)
{
@@ -171,8 +192,30 @@ class MouvementStock extends CommonObject
return -3;
}
}
+ else
+ {
+ $sellby = $obj->sellby; // If found and eatby/sellby defined into table and not provided, we take value from table
+ }
}
- $i++;
+ else
+ {
+ if ($sellby) // If found and eatby/sellby not defined into table and provided, we update table
+ {
+ $productlot = new Productlot($this->db);
+ $result = $productlot->fetch($obj->rowid);
+ $productlot->sellby = $sellby;
+ $result = $productlot->update($user);
+ if ($result <= 0)
+ {
+ $this->error = $productlot->error;
+ $this->errors = $productlot->errors;
+ $this->db->rollback();
+ return -5;
+ }
+ }
+ }
+
+ $i++;
}
}
else
@@ -181,7 +224,7 @@ class MouvementStock extends CommonObject
$productlot->fk_product = $fk_product;
$productlot->batch = $batch;
$result = $productlot->create($user);
- if (! $result)
+ if ($result <= 0)
{
$this->error = $productlot->error;
$this->errors = $productlot->errors;
@@ -367,7 +410,7 @@ class MouvementStock extends CommonObject
$sql = "UPDATE ".MAIN_DB_PREFIX."product as p SET p.pmp = ".$newpmp.", ";
$sql.= " stock=(SELECT SUM(ps.reel) FROM ".MAIN_DB_PREFIX."product_stock ps WHERE ps.fk_product = p.rowid)";
$sql.= " WHERE rowid = ".$fk_product;
- print $sql;
+
dol_syslog(get_class($this)."::_create", LOG_DEBUG);
$resql=$this->db->query($sql);
if (! $resql)
diff --git a/htdocs/product/stock/class/productlot.class.php b/htdocs/product/stock/class/productlot.class.php
index 26970a68e85..9b15ed31fcc 100644
--- a/htdocs/product/stock/class/productlot.class.php
+++ b/htdocs/product/stock/class/productlot.class.php
@@ -56,14 +56,15 @@ class Productlot extends CommonObject
/**
*/
- public $tms = '';
+ public $entity;
public $fk_product;
public $batch;
public $eatby = '';
public $sellby = '';
- public $note_public;
- public $note_private;
- public $qty;
+ public $datec = '';
+ public $tms = '';
+ public $fk_user_creat;
+ public $fk_user_modif;
public $import_key;
/**
@@ -96,20 +97,20 @@ class Productlot extends CommonObject
// Clean parameters
+ if (isset($this->entity)) {
+ $this->entity = trim($this->entity);
+ }
if (isset($this->fk_product)) {
$this->fk_product = trim($this->fk_product);
}
if (isset($this->batch)) {
$this->batch = trim($this->batch);
}
- if (isset($this->note_public)) {
- $this->note_public = trim($this->note_public);
+ if (isset($this->fk_user_creat)) {
+ $this->fk_user_creat = trim($this->fk_user_creat);
}
- if (isset($this->note_private)) {
- $this->note_private = trim($this->note_private);
- }
- if (isset($this->qty)) {
- $this->qty = trim($this->qty);
+ if (isset($this->fk_user_modif)) {
+ $this->fk_user_modif = trim($this->fk_user_modif);
}
if (isset($this->import_key)) {
$this->import_key = trim($this->import_key);
@@ -123,26 +124,28 @@ class Productlot extends CommonObject
// Insert request
$sql = 'INSERT INTO ' . MAIN_DB_PREFIX . $this->table_element . '(';
+ $sql.= 'entity,';
$sql.= 'fk_product,';
$sql.= 'batch,';
$sql.= 'eatby,';
$sql.= 'sellby,';
- $sql.= 'note_public,';
- $sql.= 'note_private,';
- $sql.= 'qty';
+ $sql.= 'datec,';
+ $sql.= 'fk_user_creat,';
+ $sql.= 'fk_user_modif,';
$sql.= 'import_key';
$sql .= ') VALUES (';
+ $sql .= ' '.(! isset($this->entity)?'NULL':$this->entity).',';
$sql .= ' '.(! isset($this->fk_product)?'NULL':$this->fk_product).',';
$sql .= ' '.(! isset($this->batch)?'NULL':"'".$this->db->escape($this->batch)."'").',';
$sql .= ' '.(! isset($this->eatby) || dol_strlen($this->eatby)==0?'NULL':"'".$this->db->idate($this->eatby)."'").',';
$sql .= ' '.(! isset($this->sellby) || dol_strlen($this->sellby)==0?'NULL':"'".$this->db->idate($this->sellby)."'").',';
- $sql .= ' '.(! isset($this->note_public)?'NULL':"'".$this->db->escape($this->note_public)."'").',';
- $sql .= ' '.(! isset($this->note_private)?'NULL':"'".$this->db->escape($this->note_private)."'").',';
- $sql .= ' '.(! isset($this->qty)?'NULL':"'".$this->qty."'").',';
- $sql .= ' '.(! isset($this->import_key)?'NULL':"'".$this->db->escape($this->import_key)."'");
+ $sql .= ' '."'".$this->db->idate(dol_now())."'".',';
+ $sql .= ' '.(! isset($this->fk_user_creat)?'NULL':$this->fk_user_creat).',';
+ $sql .= ' '.(! isset($this->fk_user_modif)?'NULL':$this->fk_user_modif).',';
+ $sql .= ' '.(! isset($this->import_key)?'NULL':$this->import_key);
$sql .= ')';
@@ -197,14 +200,15 @@ class Productlot extends CommonObject
$sql = 'SELECT';
$sql .= ' t.rowid,';
- $sql .= " t.tms,";
+ $sql .= " t.entity,";
$sql .= " t.fk_product,";
$sql .= " t.batch,";
$sql .= " t.eatby,";
$sql .= " t.sellby,";
- $sql .= " t.note_public,";
- $sql .= " t.note_private,";
- $sql .= " t.qty,";
+ $sql .= " t.datec,";
+ $sql .= " t.tms,";
+ $sql .= " t.fk_user_creat,";
+ $sql .= " t.fk_user_modif,";
$sql .= " t.import_key";
@@ -223,14 +227,15 @@ class Productlot extends CommonObject
$this->id = $obj->rowid;
- $this->tms = $this->db->jdate($obj->tms);
+ $this->entity = $obj->entity;
$this->fk_product = $obj->fk_product;
$this->batch = $obj->batch;
$this->eatby = $this->db->jdate($obj->eatby);
$this->sellby = $this->db->jdate($obj->sellby);
- $this->note_public = $obj->note_public;
- $this->note_private = $obj->note_private;
- $this->qty = $obj->qty;
+ $this->datec = $this->db->jdate($obj->datec);
+ $this->tms = $this->db->jdate($obj->tms);
+ $this->fk_user_creat = $obj->fk_user_creat;
+ $this->fk_user_modif = $obj->fk_user_modif;
$this->import_key = $obj->import_key;
@@ -269,14 +274,15 @@ class Productlot extends CommonObject
$sql = 'SELECT';
$sql .= ' t.rowid,';
- $sql .= " t.tms,";
+ $sql .= " t.entity,";
$sql .= " t.fk_product,";
$sql .= " t.batch,";
$sql .= " t.eatby,";
$sql .= " t.sellby,";
- $sql .= " t.note_public,";
- $sql .= " t.note_private,";
- $sql .= " t.qty,";
+ $sql .= " t.datec,";
+ $sql .= " t.tms,";
+ $sql .= " t.fk_user_creat,";
+ $sql .= " t.fk_user_modif,";
$sql .= " t.import_key";
@@ -310,14 +316,15 @@ class Productlot extends CommonObject
$line->id = $obj->rowid;
- $line->tms = $this->db->jdate($obj->tms);
+ $line->entity = $obj->entity;
$line->fk_product = $obj->fk_product;
$line->batch = $obj->batch;
$line->eatby = $this->db->jdate($obj->eatby);
$line->sellby = $this->db->jdate($obj->sellby);
- $line->note_public = $obj->note_public;
- $line->note_private = $obj->note_private;
- $line->qty = $obj->qty;
+ $line->datec = $this->db->jdate($obj->datec);
+ $line->tms = $this->db->jdate($obj->tms);
+ $line->fk_user_creat = $obj->fk_user_creat;
+ $line->fk_user_modif = $obj->fk_user_modif;
$line->import_key = $obj->import_key;
@@ -351,20 +358,20 @@ class Productlot extends CommonObject
// Clean parameters
+ if (isset($this->entity)) {
+ $this->entity = trim($this->entity);
+ }
if (isset($this->fk_product)) {
$this->fk_product = trim($this->fk_product);
}
if (isset($this->batch)) {
$this->batch = trim($this->batch);
}
- if (isset($this->note_public)) {
- $this->note_public = trim($this->note_public);
+ if (isset($this->fk_user_creat)) {
+ $this->fk_user_creat = trim($this->fk_user_creat);
}
- if (isset($this->note_private)) {
- $this->note_private = trim($this->note_private);
- }
- if (isset($this->qty)) {
- $this->qty = trim($this->qty);
+ if (isset($this->fk_user_modif)) {
+ $this->fk_user_modif = trim($this->fk_user_modif);
}
if (isset($this->import_key)) {
$this->import_key = trim($this->import_key);
@@ -378,15 +385,16 @@ class Productlot extends CommonObject
// Update request
$sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element . ' SET';
- $sql .= ' tms = '.(dol_strlen($this->tms) != 0 ? "'".$this->db->idate($this->tms)."'" : "'".$this->db->idate(dol_now())."'").',';
+ $sql .= ' entity = '.(isset($this->entity)?$this->entity:"null").',';
$sql .= ' fk_product = '.(isset($this->fk_product)?$this->fk_product:"null").',';
$sql .= ' batch = '.(isset($this->batch)?"'".$this->db->escape($this->batch)."'":"null").',';
$sql .= ' eatby = '.(! isset($this->eatby) || dol_strlen($this->eatby) != 0 ? "'".$this->db->idate($this->eatby)."'" : 'null').',';
$sql .= ' sellby = '.(! isset($this->sellby) || dol_strlen($this->sellby) != 0 ? "'".$this->db->idate($this->sellby)."'" : 'null').',';
- $sql .= ' note_public = '.(isset($this->note_public)?"'".$this->db->escape($this->note_public)."'":"null").',';
- $sql .= ' note_private = '.(isset($this->note_private)?"'".$this->db->escape($this->note_private)."'":"null").',';
- $sql .= ' qty = '.(isset($this->qty)?$this->qty:"null").',';
- $sql .= ' import_key = '.(isset($this->import_key)?"'".$this->db->escape($this->import_key)."'":"null");
+ $sql .= ' datec = '.(! isset($this->datec) || dol_strlen($this->datec) != 0 ? "'".$this->db->idate($this->datec)."'" : 'null').',';
+ $sql .= ' tms = '.(dol_strlen($this->tms) != 0 ? "'".$this->db->idate($this->tms)."'" : "'".$this->db->idate(dol_now())."'").',';
+ $sql .= ' fk_user_creat = '.(isset($this->fk_user_creat)?$this->fk_user_creat:"null").',';
+ $sql .= ' fk_user_modif = '.(isset($this->fk_user_modif)?$this->fk_user_modif:"null").',';
+ $sql .= ' import_key = '.(isset($this->import_key)?$this->import_key:"null");
$sql .= ' WHERE rowid=' . $this->id;
@@ -626,14 +634,15 @@ class Productlot extends CommonObject
{
$this->id = 0;
- $this->tms = '';
+ $this->entity = '';
$this->fk_product = '';
$this->batch = '';
$this->eatby = '';
$this->sellby = '';
- $this->note_public = '';
- $this->note_private = '';
- $this->qty = '';
+ $this->datec = '';
+ $this->tms = '';
+ $this->fk_user_creat = '';
+ $this->fk_user_modif = '';
$this->import_key = '';
@@ -654,14 +663,15 @@ class ProductlotLine
* @var mixed Sample line property 1
*/
- public $tms = '';
+ public $entity;
public $fk_product;
public $batch;
public $eatby = '';
public $sellby = '';
- public $note_public;
- public $note_private;
- public $qty;
+ public $datec = '';
+ public $tms = '';
+ public $fk_user_creat;
+ public $fk_user_modif;
public $import_key;
/**
diff --git a/htdocs/product/stock/mouvement.php b/htdocs/product/stock/mouvement.php
index 29ee33c56eb..b18ca146a25 100644
--- a/htdocs/product/stock/mouvement.php
+++ b/htdocs/product/stock/mouvement.php
@@ -367,7 +367,7 @@ if (! empty($search_movement)) $sql.= " AND m.label LIKE '%".$db->escape($s
if (! empty($search_inventorycode)) $sql.= " AND m.inventorycode LIKE '%".$db->escape($search_inventorycode)."%'";
if (! empty($search_product_ref)) $sql.= " AND p.ref LIKE '%".$db->escape($search_product_ref)."%'";
if (! empty($search_product)) $sql.= " AND p.label LIKE '%".$db->escape($search_product)."%'";
-if (! empty($search_warehouse)) $sql.= " AND e.label LIKE '%".$db->escape($search_warehouse)."%'";
+if (! empty($search_warehouse)) $sql.= " AND e.rowid = '".$db->escape($search_warehouse)."'";
if (! empty($search_user)) $sql.= " AND u.login LIKE '%".$db->escape($search_user)."%'";
if (! empty($search_batch)) $sql.= " AND m.batch LIKE '%".$db->escape($search_batch)."%'";
@@ -702,7 +702,8 @@ if ($resql)
if (! $id > 0)
{
print '';
- print ' ';
+ //print ' ';
+ print $formproduct->selectWarehouses($search_warehouse, 'search_warehouse', '', 1);
print ' ';
}
// Author
diff --git a/htdocs/product/stock/product.php b/htdocs/product/stock/product.php
index 499efd29847..1b4c159b1d6 100644
--- a/htdocs/product/stock/product.php
+++ b/htdocs/product/stock/product.php
@@ -273,6 +273,10 @@ if ($action == "transfert_stock" && ! $cancel)
$eatby,$sellby,$batch,
GETPOST('inventorycode')
);
+ if ($result1 < 0) $error++;
+ }
+ if (! $error)
+ {
// Add stock
$result2=$object->correct_stock_batch(
$user,
@@ -284,31 +288,39 @@ if ($action == "transfert_stock" && ! $cancel)
$eatby,$sellby,$batch,
GETPOST('inventorycode')
);
+ if ($result2 < 0) $error++;
}
}
else
{
- // Remove stock
- $result1=$object->correct_stock(
- $user,
- GETPOST("id_entrepot"),
- GETPOST("nbpiece"),
- 1,
- GETPOST("label"),
- $pricesrc,
- GETPOST('inventorycode')
- );
-
- // Add stock
- $result2=$object->correct_stock(
- $user,
- GETPOST("id_entrepot_destination"),
- GETPOST("nbpiece"),
- 0,
- GETPOST("label"),
- $pricedest,
- GETPOST('inventorycode')
- );
+ if (! $error)
+ {
+ // Remove stock
+ $result1=$object->correct_stock(
+ $user,
+ GETPOST("id_entrepot"),
+ GETPOST("nbpiece"),
+ 1,
+ GETPOST("label"),
+ $pricesrc,
+ GETPOST('inventorycode')
+ );
+ if ($result1 < 0) $error++;
+ }
+ if (! $error)
+ {
+ // Add stock
+ $result2=$object->correct_stock(
+ $user,
+ GETPOST("id_entrepot_destination"),
+ GETPOST("nbpiece"),
+ 0,
+ GETPOST("label"),
+ $pricedest,
+ GETPOST('inventorycode')
+ );
+ if ($result2 < 0) $error++;
+ }
}
if (! $error && $result1 >= 0 && $result2 >= 0)
{
@@ -589,7 +601,7 @@ if ($id > 0 || $ref)
if ($action == "correction")
{
include DOL_DOCUMENT_ROOT.'/product/stock/tpl/stockcorrection.tpl.php';
- print ' ';
+ print ' ';
}
/*
@@ -598,7 +610,7 @@ if ($id > 0 || $ref)
if ($action == "transfert")
{
include DOL_DOCUMENT_ROOT.'/product/stock/tpl/stocktransfer.tpl.php';
- print ' ';
+ print ' ';
}
/*
@@ -657,10 +669,10 @@ if (empty($action) && $object->id)
/*
- * Stock detail (by warehouse). Do not go down into batch.
+ * Stock detail (by warehouse). May go down into batch details.
*/
-print '';
+print '';
print ''.$langs->trans("Warehouse").' ';
print ''.$langs->trans("NumberOfUnit").' ';
print ''.$langs->trans("AverageUnitPricePMPShort").' ';
@@ -726,14 +738,14 @@ if ($resql)
if (price2num($object->pmp)) $totalwithpmp += $obj->reel;
$totalvalue = $totalvalue + ($object->pmp*$obj->reel);
$totalvaluesell = $totalvaluesell + ($object->price*$obj->reel);
- //Batch Detail
+ // Batch Detail
if ((! empty($conf->productbatch->enabled)) && $object->hasbatch())
{
- $details=Productbatch::findAll($db,$obj->product_stock_id);
+ $details=Productbatch::findAll($db, $obj->product_stock_id, 0, $object->id);
if ($details<0) dol_print_error($db);
foreach ($details as $pdluo)
{
- if ( $action == 'editline' && GETPOST('lineid','int')==$pdluo->id )
+ if ($action == 'editline' && GETPOST('lineid','int') == $pdluo->id)
{ //Current line edit
print "\n".'';
print '