Debug serial/lot management

This commit is contained in:
Laurent Destailleur 2015-02-16 20:14:16 +01:00
parent 9a9a1f3983
commit 213c818204
7 changed files with 113 additions and 56 deletions

View File

@ -1232,14 +1232,16 @@ $formorder = new FormOrder($db);
* *
* ******************************************************************* * *******************************************************************
*/ */
if ($action == 'create' && $user->rights->commande->creer) { if ($action == 'create' && $user->rights->commande->creer)
{
print_fiche_titre($langs->trans('CreateOrder')); print_fiche_titre($langs->trans('CreateOrder'));
$soc = new Societe($db); $soc = new Societe($db);
if ($socid > 0) if ($socid > 0)
$res = $soc->fetch($socid); $res = $soc->fetch($socid);
if (! empty($origin) && ! empty($originid)) { if (! empty($origin) && ! empty($originid))
{
// Parse element/subelement (ex: project_task) // Parse element/subelement (ex: project_task)
$element = $subelement = $origin; $element = $subelement = $origin;
if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) { if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) {

View File

@ -2480,12 +2480,13 @@ abstract class CommonObject
$tplpath = 'comm/'.$element; $tplpath = 'comm/'.$element;
if (empty($conf->propal->enabled)) continue; // Do not show if module disabled if (empty($conf->propal->enabled)) continue; // Do not show if module disabled
} }
else if ($objecttype == 'shipping') { else if ($objecttype == 'shipping' || $objecttype == 'shipment') {
$tplpath = 'expedition'; $tplpath = 'expedition';
if (empty($conf->expedition->enabled)) continue; // Do not show if module disabled if (empty($conf->expedition->enabled)) continue; // Do not show if module disabled
} }
else if ($objecttype == 'delivery') { else if ($objecttype == 'delivery') {
$tplpath = 'livraison'; $tplpath = 'livraison';
if (empty($conf->expedition->enabled)) continue; // Do not show if module disabled
} }
else if ($objecttype == 'invoice_supplier') { else if ($objecttype == 'invoice_supplier') {
$tplpath = 'fourn/facture'; $tplpath = 'fourn/facture';

View File

@ -52,7 +52,7 @@ function commande_prepare_head($object)
|| ($conf->livraison_bon->enabled && $user->rights->expedition->livraison->lire)) || ($conf->livraison_bon->enabled && $user->rights->expedition->livraison->lire))
{ {
$head[$h][0] = DOL_URL_ROOT.'/expedition/shipment.php?id='.$object->id; $head[$h][0] = DOL_URL_ROOT.'/expedition/shipment.php?id='.$object->id;
if ($conf->expedition_bon->enabled) $text=$langs->trans("Shipment"); if ($conf->expedition_bon->enabled) $text=$langs->trans("Shipments");
if ($conf->expedition_bon->enabled && $conf->livraison_bon->enabled) $text.='/'; if ($conf->expedition_bon->enabled && $conf->livraison_bon->enabled) $text.='/';
if ($conf->livraison_bon->enabled) $text.=$langs->trans("Receivings"); if ($conf->livraison_bon->enabled) $text.=$langs->trans("Receivings");
$head[$h][1] = $text; $head[$h][1] = $text;

View File

@ -144,45 +144,59 @@ if (empty($reshook))
$object->note_private = GETPOST('note_private'); $object->note_private = GETPOST('note_private');
$object->note_public = GETPOST('note_public'); $object->note_public = GETPOST('note_public');
$batch_line = array();
$num=count($objectsrc->lines); $num=count($objectsrc->lines);
$totalqty=0; $totalqty=0;
for ($i = 0; $i < $num; $i++) for ($i = 0; $i < $num; $i++)
{ {
$qty = "qtyl".$i; $idl="idl".$i;
$j=0;
$sub_qty=array(); $sub_qty=array();
$subtotalqty=0; $subtotalqty=0;
$idl="idl".$i;
$j=0;
$batch="batchl".$i."_0"; $batch="batchl".$i."_0";
if (isset($_POST[$batch])) { $qty = "qtyl".$i;
if (isset($_POST[$batch]))
{
//shipment line with batch-enable product //shipment line with batch-enable product
$qty .= '_'.$j; $qty .= '_'.$j;
while (isset($_POST[$batch])) { while (isset($_POST[$batch]))
{
// save line of detail into sub_qty
$sub_qty[$j]['q']=GETPOST($qty,'int'); $sub_qty[$j]['q']=GETPOST($qty,'int');
$sub_qty[$j]['id_batch']=GETPOST($batch,'int'); $sub_qty[$j]['id_batch']=GETPOST($batch,'int');
$subtotalqty+=$sub_qty[$j]['q']; $subtotalqty+=$sub_qty[$j]['q'];
$j++; $j++;
$batch="batchl".$i."_".$j; $batch="batchl".$i."_".$j;
$qty = "qtyl".$i.'_'.$j; $qty = "qtyl".$i.'_'.$j;
} }
$batch_line[$i]['detail']=$sub_qty;
$batch_line[$i]['detail']=$sub_qty; // array of details
$batch_line[$i]['qty']=$subtotalqty; $batch_line[$i]['qty']=$subtotalqty;
$batch_line[$i]['ix_l']=GETPOST($idl,'int'); $batch_line[$i]['ix_l']=GETPOST($idl,'int');
$totalqty+=$subtotalqty; $totalqty+=$subtotalqty;
} else { }
//Standard product else
{
//shipment line for product with no batch management
if (GETPOST($qty,'int') > 0) $totalqty+=GETPOST($qty,'int'); if (GETPOST($qty,'int') > 0) $totalqty+=GETPOST($qty,'int');
} }
} }
if ($totalqty > 0) if ($totalqty > 0) // There is at least one thing to ship
{ {
//var_dump($_POST);exit; //var_dump($_POST);exit;
for ($i = 0; $i < $num; $i++) for ($i = 0; $i < $num; $i++)
{ {
$qty = "qtyl".$i; $qty = "qtyl".$i;
if (! isset($batch_line[$i])) { if (! isset($batch_line[$i]))
{ // not batch mode
if (GETPOST($qty,'int') > 0 || (GETPOST($qty,'int') == 0 && $conf->global->SHIPMENT_GETS_ALL_ORDER_PRODUCTS)) if (GETPOST($qty,'int') > 0 || (GETPOST($qty,'int') == 0 && $conf->global->SHIPMENT_GETS_ALL_ORDER_PRODUCTS))
{ {
$ent = "entl".$i; $ent = "entl".$i;
@ -197,8 +211,11 @@ if (empty($reshook))
$error++; $error++;
} }
} }
} else { }
if ($batch_line[$i]['qty']>0) { else
{ // batch mode
if ($batch_line[$i]['qty']>0)
{
$ret=$object->addline_batch($batch_line[$i]); $ret=$object->addline_batch($batch_line[$i]);
if ($ret < 0) if ($ret < 0)
{ {
@ -211,7 +228,7 @@ if (empty($reshook))
if (! $error) if (! $error)
{ {
$ret=$object->create($user); $ret=$object->create($user); // This create shipment (like Odoo picking) and line of shipments. Stock movement will when validating shipment.
if ($ret <= 0) if ($ret <= 0)
{ {
$mesg='<div class="error">'.$object->error.'</div>'; $mesg='<div class="error">'.$object->error.'</div>';

View File

@ -255,13 +255,16 @@ class Expedition extends CommonObject
$num=count($this->lines); $num=count($this->lines);
for ($i = 0; $i < $num; $i++) for ($i = 0; $i < $num; $i++)
{ {
if (! isset($this->lines[$i]->detail_batch)) { if (! isset($this->lines[$i]->detail_batch))
{ // no batch management
if (! $this->create_line($this->lines[$i]->entrepot_id, $this->lines[$i]->origin_line_id, $this->lines[$i]->qty) > 0) if (! $this->create_line($this->lines[$i]->entrepot_id, $this->lines[$i]->origin_line_id, $this->lines[$i]->qty) > 0)
{ {
$error++; $error++;
} }
} else { }
if (! $this->create_line_ext($this->lines[$i]) > 0) else
{ // with batch management
if (! $this->create_line_batch($this->lines[$i]) > 0)
{ {
$error++; $error++;
} }
@ -366,28 +369,37 @@ class Expedition extends CommonObject
if (! $error) return 1; if (! $error) return 1;
else return -1; else return -1;
} }
/** /**
* Create a expedition line with eat-by date * Create a expedition line with eat-by date
* *
* @param object $line_ext full line informations * @param object $line_ext full line informations
* @return int <0 if KO, >0 if OK * @return int <0 if KO, >0 if OK
*/ */
function create_line_ext($line_ext) function create_line_batch($line_ext)
{ {
$error = 0; $error = 0;
if ($this->create_line(($line_ext->entrepot_id?$line_ext->entrepot_id:'null'),$line_ext->origin_line_id,$line_ext->qty) < 0) if ($this->create_line(($line_ext->entrepot_id?$line_ext->entrepot_id:'null'),$line_ext->origin_line_id,$line_ext->qty) < 0)
{ {
$error++; $error++;
} else { }
if (! $error)
{
$line_id= $this->db->last_insert_id(MAIN_DB_PREFIX."expeditiondet"); $line_id= $this->db->last_insert_id(MAIN_DB_PREFIX."expeditiondet");
$tab=$line_ext->detail_batch; $tab=$line_ext->detail_batch;
foreach ($tab as $detbatch) { foreach ($tab as $detbatch)
if (! ($detbatch->create($line_id) >0)) { {
if (! ($detbatch->create($line_id) >0)) // Create an expeditionlinebatch
{
$error++; $error++;
} }
} }
} }
if (! $error) return 1; if (! $error) return 1;
else return -1; else return -1;
} }
@ -612,10 +624,13 @@ class Expedition extends CommonObject
$result=$mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $obj->qty, $obj->subprice, $langs->trans("ShipmentValidatedInDolibarr",$numref)); $result=$mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $obj->qty, $obj->subprice, $langs->trans("ShipmentValidatedInDolibarr",$numref));
if ($result < 0) { $error++; break; } if ($result < 0) { $error++; break; }
if (! empty($conf->productbatch->enabled)) { if (! empty($conf->productbatch->enabled))
$details=ExpeditionLigneBatch::fetchAll($this->db,$obj->rowid); {
if (! empty($details)) { $details=ExpeditionLineBatch::fetchAll($this->db,$obj->rowid);
foreach ($details as $dbatch) { if (! empty($details))
{
foreach ($details as $dbatch)
{
$result=$mouvS->livraison_batch($dbatch->fk_origin_stock,$dbatch->dluo_qty); $result=$mouvS->livraison_batch($dbatch->fk_origin_stock,$dbatch->dluo_qty);
if ($result < 0) { $error++; $this->errors[]=$mouvS->$error; break 2; } if ($result < 0) { $error++; $this->errors[]=$mouvS->$error; break 2; }
} }
@ -751,7 +766,8 @@ class Expedition extends CommonObject
$line->origin_line_id = $id; $line->origin_line_id = $id;
$line->qty = $qty; $line->qty = $qty;
if($conf->global->STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT) { if ($conf->global->STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT)
{
$orderline = new OrderLine($this->db); $orderline = new OrderLine($this->db);
$orderline->fetch($id); $orderline->fetch($id);
$fk_product = $orderline->fk_product; $fk_product = $orderline->fk_product;
@ -762,7 +778,8 @@ class Expedition extends CommonObject
$result=$product->fetch($fk_product); $result=$product->fetch($fk_product);
$product_type=$product->type; $product_type=$product->type;
if($product_type == 0 && $product->stock_reel < $qty) { if($product_type == 0 && $product->stock_reel < $qty)
{
$this->error=$langs->trans('ErrorStockIsNotEnough'); $this->error=$langs->trans('ErrorStockIsNotEnough');
$this->db->rollback(); $this->db->rollback();
return -3; return -3;
@ -782,14 +799,18 @@ class Expedition extends CommonObject
function addline_batch($dbatch) function addline_batch($dbatch)
{ {
$num = count($this->lines); $num = count($this->lines);
if ($dbatch['qty']>0) { if ($dbatch['qty']>0)
{
$line = new ExpeditionLigne($this->db); $line = new ExpeditionLigne($this->db);
$tab=array(); $tab=array();
foreach ($dbatch['detail'] as $key=>$value) { foreach ($dbatch['detail'] as $key=>$value)
if ($value['q']>0) { {
$linebatch = new ExpeditionLigneBatch($this->db); if ($value['q']>0)
$ret=$linebatch->fetchFromStock($value['id_batch']); {
if ($ret<0) { $linebatch = new ExpeditionLineBatch($this->db);
$ret=$linebatch->fetchFromStock($value['id_batch']); // load serial, sellby, eatby
if ($ret<0)
{
$this->error=$linebatch->error; $this->error=$linebatch->error;
return -1; return -1;
} }
@ -932,10 +953,13 @@ class Expedition extends CommonObject
$this->db->begin(); $this->db->begin();
if ($conf->productbatch->enabled) { if ($conf->productbatch->enabled)
{
require_once DOL_DOCUMENT_ROOT.'/expedition/class/expeditionbatch.class.php'; require_once DOL_DOCUMENT_ROOT.'/expedition/class/expeditionbatch.class.php';
if ( ExpeditionLigneBatch::deletefromexp($this->db,$this->id)<0) if (ExpeditionLineBatch::deletefromexp($this->db,$this->id) < 0)
{$error++;$this->errors[]="Error ".$this->db->lasterror();} {
$error++;$this->errors[]="Error ".$this->db->lasterror();
}
} }
// Stock control // Stock control
if ($conf->stock->enabled && $conf->global->STOCK_CALCULATE_ON_SHIPMENT && $this->statut > 0) if ($conf->stock->enabled && $conf->global->STOCK_CALCULATE_ON_SHIPMENT && $this->statut > 0)
@ -1174,10 +1198,11 @@ class Expedition extends CommonObject
* May be conf is not well initialized for dark reason * May be conf is not well initialized for dark reason
*/ */
require_once DOL_DOCUMENT_ROOT.'/expedition/class/expeditionbatch.class.php'; require_once DOL_DOCUMENT_ROOT.'/expedition/class/expeditionbatch.class.php';
if ($originline != $obj->fk_origin_line) { if ($originline != $obj->fk_origin_line)
$line->detail_batch = ExpeditionLigneBatch::fetchAll($this->db,$obj->line_id); {
$line->detail_batch = ExpeditionLineBatch::fetchAll($this->db,$obj->line_id);
} else { } else {
$line->detail_batch = array_merge($line->detail_batch,ExpeditionLigneBatch::fetchAll($this->db,$obj->line_id)); $line->detail_batch = array_merge($line->detail_batch,ExpeditionLineBatch::fetchAll($this->db,$obj->line_id));
} }
} }
if ($originline != $obj->fk_origin_line) { if ($originline != $obj->fk_origin_line) {

View File

@ -17,16 +17,16 @@
*/ */
/** /**
* \file expedition/class/productbatch.class.php * \file expedition/class/expeditionbatch.class.php
* \ingroup productbatch * \ingroup productbatch
* \brief This file implements CRUD method for managing product's shipment * \brief This file implements CRUD method for managing shipment batch lines
* with batch record * with batch record
*/ */
/** /**
* CRUD class for batch number management within shipment * CRUD class for batch number management within shipment
*/ */
class ExpeditionLigneBatch extends CommonObject class ExpeditionLineBatch extends CommonObject
{ {
var $element='expeditionlignebatch'; //!< Id that identify managed objects var $element='expeditionlignebatch'; //!< Id that identify managed objects
private static $_table_element='expeditiondet_batch'; //!< Name of table without prefix where object is stored private static $_table_element='expeditiondet_batch'; //!< Name of table without prefix where object is stored
@ -115,9 +115,9 @@ class ExpeditionLigneBatch extends CommonObject
$sql.= ", fk_origin_stock"; $sql.= ", fk_origin_stock";
$sql.= ") VALUES ("; $sql.= ") VALUES (";
$sql.= $id_line_expdet.","; $sql.= $id_line_expdet.",";
$sql.= " ".(! isset($this->sellby) || dol_strlen($this->sellby)==0?'NULL':"'".$this->db->idate($this->sellby))."',"; $sql.= " ".(! isset($this->sellby) || dol_strlen($this->sellby)==0?'NULL':("'".$this->db->idate($this->sellby))."'").",";
$sql.= " ".(! isset($this->eatby) || dol_strlen($this->eatby)==0?'NULL':"'".$this->db->idate($this->eatby))."',"; $sql.= " ".(! isset($this->eatby) || dol_strlen($this->eatby)==0?'NULL':("'".$this->db->idate($this->eatby))."'").",";
$sql.= " ".(! isset($this->batch)?'NULL':"'".$this->db->escape($this->batch)."'").","; $sql.= " ".(! isset($this->batch)?'NULL':("'".$this->db->escape($this->batch)."'")).",";
$sql.= " ".(! isset($this->dluo_qty)?'NULL':$this->dluo_qty).","; $sql.= " ".(! isset($this->dluo_qty)?'NULL':$this->dluo_qty).",";
$sql.= " ".(! isset($this->fk_origin_stock)?'NULL':$this->fk_origin_stock); $sql.= " ".(! isset($this->fk_origin_stock)?'NULL':$this->fk_origin_stock);
$sql.= ")"; $sql.= ")";
@ -174,7 +174,7 @@ class ExpeditionLigneBatch extends CommonObject
* *
* @param object $db Database object * @param object $db Database object
* @param int $id_line_expdet id of shipment line * @param int $id_line_expdet id of shipment line
* @return variant -1 if KO, array of ExpeditionLigneBatch if OK * @return variant -1 if KO, array of ExpeditionLineBatch if OK
*/ */
static function fetchAll($db,$id_line_expdet) static function fetchAll($db,$id_line_expdet)
{ {

View File

@ -73,6 +73,18 @@ delete from llx_livraisondet where fk_livraison not in (select fk_target from ll
delete from llx_livraison where rowid not in (select fk_target from llx_element_element where targettype = 'delivery') AND rowid not in (select fk_source from llx_element_element where sourcetype = 'delivery'); delete from llx_livraison where rowid not in (select fk_target from llx_element_element where targettype = 'delivery') AND rowid not in (select fk_source from llx_element_element where sourcetype = 'delivery');
-- Fix delete element_element orphelins (right side)
delete from llx_element_element where targettype='shipping' and fk_target not in (select rowid from llx_expedition);
delete from llx_element_element where targettype='propal' and fk_target not in (select rowid from llx_propal);
delete from llx_element_element where targettype='facture' and fk_target not in (select rowid from llx_facture);
delete from llx_element_element where targettype='commande' and fk_target not in (select rowid from llx_commande);
-- Fix delete element_element orphelins (left side)
delete from llx_element_element where sourcetype='shipping' and fk_source not in (select rowid from llx_expedition);
delete from llx_element_element where sourcetype='propal' and fk_source not in (select rowid from llx_propal);
delete from llx_element_element where sourcetype='facture' and fk_source not in (select rowid from llx_facture);
delete from llx_element_element where sourcetype='commande' and fk_source not in (select rowid from llx_commande);
UPDATE llx_product SET canvas = NULL where canvas = 'default@product'; UPDATE llx_product SET canvas = NULL where canvas = 'default@product';
UPDATE llx_product SET canvas = NULL where canvas = 'service@product'; UPDATE llx_product SET canvas = NULL where canvas = 'service@product';