This commit is contained in:
Laurent Destailleur 2015-08-14 23:53:59 +02:00
parent d408193657
commit 3bdd342df1
4 changed files with 131 additions and 67 deletions

View File

@ -76,7 +76,7 @@ $hideref = (GETPOST('hideref','int') ? GETPOST('hideref','int') : (! empty($co
$object = new Expedition($db);
// Load object
// Load object. Make an object->fetch
include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not includ_once
// Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array
@ -160,6 +160,7 @@ if (empty($reshook))
$num=count($objectsrc->lines);
$totalqty=0;
for ($i = 0; $i < $num; $i++)
{
$idl="idl".$i;
@ -178,11 +179,12 @@ if (empty($reshook))
while (isset($_POST[$batch]))
{
// save line of detail into sub_qty
$sub_qty[$j]['q']=GETPOST($qty,'int');
$sub_qty[$j]['id_batch']=GETPOST($batch,'int');
$sub_qty[$j]['q']=GETPOST($qty,'int'); // the qty we want to move for this stock record
$sub_qty[$j]['id_batch']=GETPOST($batch,'int'); // the id into llx_product_batch of stock record to move
$subtotalqty+=$sub_qty[$j]['q'];
//var_dump($qty);var_dump($batch);var_dump($sub_qty[$j]['q']);var_dump($sub_qty[$j]['id_batch']);
$j++;
$batch="batchl".$i."_".$j;
$qty = "qtyl".$i.'_'.$j;
@ -200,6 +202,8 @@ if (empty($reshook))
if (GETPOST($qty,'int') > 0) $totalqty+=GETPOST($qty,'int');
}
}
//var_dump($batch_line[2]);
if ($totalqty > 0) // There is at least one thing to ship
{
@ -208,7 +212,8 @@ if (empty($reshook))
{
$qty = "qtyl".$i;
if (! isset($batch_line[$i]))
{ // not batch mode
{
// not batch mode
if (GETPOST($qty,'int') > 0 || (GETPOST($qty,'int') == 0 && $conf->global->SHIPMENT_GETS_ALL_ORDER_PRODUCTS))
{
$ent = "entl".$i;
@ -225,7 +230,8 @@ if (empty($reshook))
}
}
else
{ // batch mode
{
// batch mode
if ($batch_line[$i]['qty']>0)
{
$ret=$object->addline_batch($batch_line[$i]);
@ -1257,8 +1263,8 @@ else if ($id || $ref)
print "</table>\n";
/*
* Lignes produits
*/
* Lines of products
*/
print '<br><table class="noborder" width="100%">';
print '<tr class="liste_titre">';
if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER))
@ -1417,12 +1423,19 @@ else if ($id || $ref)
if (isset($lines[$i]->detail_batch))
{
print '<td>';
$detail = '';
foreach ($lines[$i]->detail_batch as $dbatch)
if ($lines[$i]->product_tobatch)
{
$detail.= $langs->trans("DetailBatchFormat",$dbatch->batch,dol_print_date($dbatch->eatby,"day"),dol_print_date($dbatch->sellby,"day"),$dbatch->dluo_qty).'<br/>';
$detail = '';
foreach ($lines[$i]->detail_batch as $dbatch)
{
$detail.= $langs->trans("DetailBatchFormat",$dbatch->batch,dol_print_date($dbatch->eatby,"day"),dol_print_date($dbatch->sellby,"day"),$dbatch->dluo_qty).'<br/>';
}
print $form->textwithtooltip($langs->trans("DetailBatchNumber"),$detail);
}
else
{
print $langs->trans("NA");
}
print $form->textwithtooltip($langs->trans("DetailBatchNumber"),$detail);
print '</td>';
} else {
print '<td></td>';

View File

@ -391,7 +391,7 @@ class Expedition extends CommonObject
/**
* Create a expedition line with eat-by date
* Create the detail (eat-by date) of the expedition line
*
* @param object $line_ext full line informations
* @return int <0 if KO, >0 if OK
@ -626,9 +626,12 @@ class Expedition extends CommonObject
// Loop on each product line to add a stock movement
// TODO possibilite d'expedier a partir d'une propale ou autre origine
$sql = "SELECT cd.fk_product, cd.subprice, ed.qty, ed.fk_entrepot, ed.rowid";
$sql = "SELECT cd.fk_product, cd.subprice,";
$sql.= " ed.rowid, ed.qty, ed.fk_entrepot,";
$sql.= " edb.rowid as edbrowid, edb.eatby, edb.sellby, edb.batch, edb.qty, edb.fk_origin_stock";
$sql.= " FROM ".MAIN_DB_PREFIX."commandedet as cd,";
$sql.= " ".MAIN_DB_PREFIX."expeditiondet as ed";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."expeditiondet_batch as edb on edb.fk_expeditiondet = ed.rowid";
$sql.= " WHERE ed.fk_expedition = ".$this->id;
$sql.= " AND cd.rowid = ed.fk_origin_line";
@ -640,27 +643,38 @@ class Expedition extends CommonObject
for ($i = 0; $i < $cpt; $i++)
{
$obj = $this->db->fetch_object($resql);
if($obj->qty <= 0) continue;
dol_syslog(get_class($this)."::valid movement index ".$i);
if ($obj->qty <= 0) continue;
dol_syslog(get_class($this)."::valid movement index ".$i." ed.rowid=".$obj->rowid." edb.rowid=".$obj->edbrowid);
//var_dump($this->lines[$i]);
$mouvS = new MouvementStock($this->db);
$mouvS->origin = &$this;
// We decrement stock of product (and sub-products)
// We use warehouse selected for each line
$result=$mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $obj->qty, $obj->subprice, $langs->trans("ShipmentValidatedInDolibarr",$numref));
if ($result < 0) { $error++; break; }
if (! empty($conf->productbatch->enabled))
if (empty($obj->edbrowid))
{
$details=ExpeditionLineBatch::fetchAll($this->db,$obj->rowid);
if (! empty($details))
// line without batch detail
// We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record
$result=$mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $obj->qty, $obj->subprice, $langs->trans("ShipmentValidatedInDolibarr",$numref));
if ($result < 0) {
$error++; break;
}
}
else
{
// line with batch detail
// We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record
$result=$mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $obj->qty, $obj->subprice, $langs->trans("ShipmentValidatedInDolibarr",$numref), '', $obj->eatby, $obj->sellby, $obj->batch);
if ($result < 0) {
$error++; break;
}
// We update content of table llx_product_batch (will be rename into llx_product_stock_batch inantoher version)
if (! empty($conf->productbatch->enabled))
{
foreach ($details as $dbatch)
{
$result=$mouvS->livraison_batch($dbatch->fk_origin_stock,$dbatch->dluo_qty);
if ($result < 0) { $error++; $this->errors[]=$mouvS->$error; break 2; }
}
$result=$mouvS->livraison_batch($obj->fk_origin_stock, $obj->qty); // ->fk_origin_stock = id into table llx_product_batch (will be rename into llx_product_stock_batch in another version)
if ($result < 0) { $error++; $this->errors[]=$mouvS->error; break; }
}
}
}
@ -672,7 +686,7 @@ class Expedition extends CommonObject
return -2;
}
}
if (! $error && ! $notrigger)
{
// Call trigger
@ -843,6 +857,10 @@ class Expedition extends CommonObject
{
if ($value['q']>0)
{
// $value['q']=qty to move
// $value['id_batch']=id into llx_product_batch of record to move
//var_dump($value);
$linebatch = new ExpeditionLineBatch($this->db);
$ret=$linebatch->fetchFromStock($value['id_batch']); // load serial, sellby, eatby
if ($ret<0)
@ -857,13 +875,16 @@ class Expedition extends CommonObject
{
// TODO
}
//var_dump($linebatch);
}
}
$line->entrepot_id = $linebatch->entrepot_id;
$line->origin_line_id = $dbatch['ix_l'];
$line->qty = $dbatch['qty'];
$line->detail_batch=$tab;
//var_dump($line);
$this->lines[$num] = $line;
}
}
@ -1146,9 +1167,9 @@ class Expedition extends CommonObject
$sql = "SELECT cd.rowid, cd.fk_product, cd.label as custom_label, cd.description, cd.qty as qty_asked";
$sql.= ", cd.total_ht, cd.total_localtax1, cd.total_localtax2, cd.total_ttc, cd.total_tva";
$sql.= ", cd.tva_tx, cd.localtax1_tx, cd.localtax2_tx, cd.price, cd.subprice, cd.remise_percent";
$sql.= ", ed.qty as qty_shipped, ed.fk_origin_line, ed.fk_entrepot";
$sql.= ", ed.rowid as line_id, ed.qty as qty_shipped, ed.fk_origin_line, ed.fk_entrepot";
$sql.= ", p.ref as product_ref, p.label as product_label, p.fk_product_type";
$sql.= ", p.weight, p.weight_units, p.length, p.length_units, p.surface, p.surface_units, p.volume, p.volume_units, ed.rowid as line_id";
$sql.= ", p.weight, p.weight_units, p.length, p.length_units, p.surface, p.surface_units, p.volume, p.volume_units, p.tobatch as product_tobatch";
$sql.= " FROM (".MAIN_DB_PREFIX."expeditiondet as ed,";
$sql.= " ".MAIN_DB_PREFIX."commandedet as cd)";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = cd.fk_product";
@ -1202,6 +1223,7 @@ class Expedition extends CommonObject
$line->product_ref = $obj->product_ref;
$line->product_label = $obj->product_label;
$line->libelle = $obj->product_label; // TODO deprecated
$line->product_tobatch = $obj->product_tobatch;
$line->label = $obj->custom_label;
$line->description = $obj->description;
$line->qty_asked = $obj->qty_asked;

View File

@ -135,7 +135,7 @@ class Productbatch extends CommonObject
/**
* Load object in memory from the database
*
* @param int $id Id object
* @param int $id Id object
* @return int <0 if KO, >0 if OK
*/
function fetch($id)
@ -201,6 +201,12 @@ class Productbatch extends CommonObject
// Clean parameters
$this->clean_param();
// TODO Check qty is ok for stock move. Negative may not be allowed.
if ($this->qty < 0)
{
}
// Update request
$sql = "UPDATE ".MAIN_DB_PREFIX.self::$_table_element." SET";
$sql.= " fk_product_stock=".(isset($this->fk_product_stock)?$this->fk_product_stock:"null").",";
@ -389,11 +395,12 @@ class Productbatch extends CommonObject
}
/**
* Clean fields (triming)
* Clean fields (triming)
*
* @return void
*/
private function clean_param() {
private function clean_param()
{
if (isset($this->fk_product_stock)) $this->fk_product_stock=(int) trim($this->fk_product_stock);
if (isset($this->batch)) $this->batch=trim($this->batch);
if (isset($this->qty)) $this->qty=(float) trim($this->qty);
@ -403,11 +410,11 @@ 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
* @param date $sellby sell-by date for objet
* @param int $fk_product_stock id product_stock for objet
* @param date $eatby eat-by date for objet
* @param date $sellby sell-by date for objet
* @param string $batch_number batch number for objet
* @return int <0 if KO, >0 if OK
* @return int <0 if KO, >0 if OK
*/
function find($fk_product_stock=0, $eatby='',$sellby='',$batch_number='')
{

View File

@ -229,8 +229,8 @@ class MouvementStock extends CommonObject
$num = 0;
if (! $error)
{
$sql = "SELECT rowid, reel, pmp FROM ".MAIN_DB_PREFIX."product_stock";
$sql.= " WHERE fk_entrepot = ".$entrepot_id." AND fk_product = ".$fk_product;
$sql = "SELECT rowid, reel FROM ".MAIN_DB_PREFIX."product_stock";
$sql.= " WHERE fk_entrepot = ".$entrepot_id." AND fk_product = ".$fk_product; // This is a unique key
dol_syslog(get_class($this)."::_create", LOG_DEBUG);
$resql=$this->db->query($sql);
@ -327,7 +327,7 @@ class MouvementStock extends CommonObject
$this->errors[]=$this->db->lasterror();
$error = -3;
}
else if(empty($fk_product_stock))
else if (empty($fk_product_stock))
{
$fk_product_stock = $this->db->last_insert_id(MAIN_DB_PREFIX."product_stock");
}
@ -452,19 +452,22 @@ class MouvementStock extends CommonObject
* @param int $price Price
* @param string $label Label of stock movement
* @param string $datem Force date of movement
* @param date $eatby eat-by date
* @param date $sellby sell-by date
* @param string $batch batch number
* @return int <0 if KO, >0 if OK
*/
function livraison($user, $fk_product, $entrepot_id, $qty, $price=0, $label='', $datem='')
function livraison($user, $fk_product, $entrepot_id, $qty, $price=0, $label='', $datem='', $eatby='', $sellby='', $batch='')
{
return $this->_create($user, $fk_product, $entrepot_id, (0 - $qty), 2, $price, $label, '', $datem,'','','',true);
return $this->_create($user, $fk_product, $entrepot_id, (0 - $qty), 2, $price, $label, '', $datem, $eatby, $sellby, $batch, true);
}
/**
* Decrease stock for batch record
*
* @param int $id_stock_dluo Id product_dluo
* @param int $qty Quantity
* @return int <0 if KO, >0 if OK
* @param int $qty Quantity
* @return int <0 if KO, >0 if OK
*/
function livraison_batch($id_stock_dluo, $qty)
{
@ -543,10 +546,12 @@ class MouvementStock extends CommonObject
}
/**
* Create or update batch record
* Create or update batch record (update table llx_product_batch)
*
* @param variant $dluo Could be either int if id of product_batch or array with at leat fk_product_stock
* @param int $qty Quantity of product with batch number
* @param array|int $dluo Could be either
* - int if id of product_batch
* - or complete array('fk_product_stock'=>, 'eatby'=>, 'sellby'=> , 'batchnumber'=>)
* @param int $qty Quantity of product with batch number. May be a negative amount.
* @return int <0 if KO, else return productbatch id
*/
function _create_batch($dluo, $qty)
@ -555,44 +560,63 @@ class MouvementStock extends CommonObject
$result=0;
// Try to find an existing record with batch same batch number or id
if (is_numeric($dluo)) {
// Try to find an existing record with same batch number or id
if (is_numeric($dluo))
{
$result=$pdluo->fetch($dluo);
} else if (is_array($dluo)) {
if (isset($dluo['fk_product_stock'])) {
if (empty($pdluo->id))
{
// We didn't find the line. May be it was deleted before by a previous move in same transaction.
$this->error = 'Error. You ask a move on a record for a serial that does not exists anymore. May be you take the same serial on samewarehouse several times in same shipment or it was used by another shipment. Remove this shipment and prepare another one.';
$this->errors[] = $this->error;
$result = -2;
}
}
else if (is_array($dluo))
{
if (isset($dluo['fk_product_stock']))
{
$vfk_product_stock=$dluo['fk_product_stock'];
$veatby = $dluo['eatby'];
$vsellby = $dluo['sellby'];
$vbatchnumber = $dluo['batchnumber'];
$result = $pdluo->find($vfk_product_stock,$veatby,$vsellby,$vbatchnumber);
} else {
}
else
{
dol_syslog(get_class($this)."::_create_batch array param dluo must contain at least key fk_product_stock".$error, LOG_ERR);
$result = -1;
}
} else {
}
else
{
dol_syslog(get_class($this)."::_create_batch error invalid param dluo".$error, LOG_ERR);
$result = -1;
}
// Batch record found so we update it
if ($result>0)
if ($result >= 0)
{
if ($pdluo->id >0)
// No error
if ($pdluo->id > 0) // product_batch record found
{
$pdluo->qty +=$qty;
if ($pdluo->qty == 0) {
//print "Avant ".$pdluo->qty." Apres ".($pdluo->qty + $qty)."<br>";
$pdluo->qty += $qty;
if ($pdluo->qty == 0)
{
$result=$pdluo->delete(0,1);
} else {
$result=$pdluo->update(0,1);
}
}
else
else // product_batch record not found
{
$pdluo->fk_product_stock=$vfk_product_stock;
$pdluo->qty = $qty;
$pdluo->eatby = $veatby;
$pdluo->sellby = $vsellby;
$pdluo->batch = $vbatchnumber;
$result=$pdluo->create(0,1);
if ($result < 0)
{
@ -600,11 +624,9 @@ class MouvementStock extends CommonObject
$this->errors=$pdluo->errors;
}
}
return $result;
} else {
return -1;
}
return $result;
}
/**