FIX Several problems into shipment management with lot enabled

This commit is contained in:
Laurent Destailleur 2016-11-14 13:40:41 +01:00
parent cc70b51ba3
commit ecbe719f23
8 changed files with 92 additions and 53 deletions

View File

@ -3310,8 +3310,7 @@ class Propal extends CommonObject
$sql.= ' pt.total_ht, pt.total_tva, pt.total_ttc, pt.fk_product_fournisseur_price as fk_fournprice, pt.buy_price_ht as pa_ht, pt.special_code, pt.localtax1_tx, pt.localtax2_tx,';
$sql.= ' pt.date_start, pt.date_end, pt.product_type, pt.rang, pt.fk_parent_line,';
$sql.= ' pt.fk_unit,';
$sql.= ' p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid,';
$sql.= ' p.description as product_desc,';
$sql.= ' p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid, p.description as product_desc, p.tobatch as product_tobatch,';
$sql.= ' p.entity,';
$sql.= ' pt.fk_multicurrency, pt.multicurrency_code, pt.multicurrency_subprice, pt.multicurrency_total_ht, pt.multicurrency_total_tva, pt.multicurrency_total_ttc';
$sql.= ' FROM '.MAIN_DB_PREFIX.'propaldet as pt';
@ -3342,6 +3341,7 @@ class Propal extends CommonObject
$this->lines[$i]->entity = $obj->entity; // Product entity
$this->lines[$i]->product_label = $obj->product_label;
$this->lines[$i]->product_desc = $obj->product_desc;
$this->lines[$i]->product_tobatch = $obj->product_tobatch;
$this->lines[$i]->fk_product_type = $obj->fk_product_type; // deprecated
$this->lines[$i]->product_type = $obj->product_type;
$this->lines[$i]->qty = $obj->qty;

View File

@ -1741,7 +1741,7 @@ class Commande extends CommonOrder
$sql.= ' l.total_ht, l.total_ttc, l.total_tva, l.total_localtax1, l.total_localtax2, l.date_start, l.date_end,';
$sql.= ' l.fk_unit,';
$sql.= ' l.fk_multicurrency, l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc,';
$sql.= ' p.ref as product_ref, p.description as product_desc, p.fk_product_type, p.label as product_label,';
$sql.= ' p.ref as product_ref, p.description as product_desc, p.fk_product_type, p.label as product_label, p.tobatch as product_tobatch,';
$sql.= ' p.weight, p.weight_units, p.volume, p.volume_units';
$sql.= ' FROM '.MAIN_DB_PREFIX.'commandedet as l';
$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON (p.rowid = l.fk_product)';
@ -1801,6 +1801,7 @@ class Commande extends CommonOrder
$line->libelle = $objp->product_label;
$line->product_label = $objp->product_label;
$line->product_desc = $objp->product_desc;
$line->product_tobatch = $objp->product_tobatch;
$line->fk_product_type = $objp->fk_product_type; // Produit ou service
$line->fk_unit = $objp->fk_unit;
@ -3765,7 +3766,7 @@ class OrderLine extends CommonOrderLine
$sql.= ' cd.info_bits, cd.total_ht, cd.total_tva, cd.total_localtax1, cd.total_localtax2, cd.total_ttc, cd.fk_product_fournisseur_price as fk_fournprice, cd.buy_price_ht as pa_ht, cd.rang, cd.special_code,';
$sql.= ' cd.fk_unit,';
$sql.= ' cd.fk_multicurrency, cd.multicurrency_code, cd.multicurrency_subprice, cd.multicurrency_total_ht, cd.multicurrency_total_tva, cd.multicurrency_total_ttc,';
$sql.= ' p.ref as product_ref, p.label as product_libelle, p.description as product_desc,';
$sql.= ' p.ref as product_ref, p.label as product_libelle, p.description as product_desc, p.tobatch as product_tobatch,';
$sql.= ' cd.date_start, cd.date_end';
$sql.= ' FROM '.MAIN_DB_PREFIX.'commandedet as cd';
$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON cd.fk_product = p.rowid';
@ -3810,7 +3811,8 @@ class OrderLine extends CommonOrderLine
$this->libelle = $objp->product_libelle; // deprecated
$this->product_label = $objp->product_libelle;
$this->product_desc = $objp->product_desc;
$this->fk_unit = $objp->fk_unit;
$this->product_tobatch = $objp->product_tobatch;
$this->fk_unit = $objp->fk_unit;
$this->date_start = $this->db->jdate($objp->date_start);
$this->date_end = $this->db->jdate($objp->date_end);
@ -3828,6 +3830,7 @@ class OrderLine extends CommonOrderLine
}
else
{
$this->error = $this->db->lasterror();
return -1;
}
}

View File

@ -176,7 +176,7 @@ function show_list_sending_receive($origin,$origin_id,$filter='')
$sql.= ", ed.qty as qty_shipped, ed.fk_expedition as expedition_id, ed.fk_origin_line, ed.fk_entrepot as warehouse_id";
$sql.= ", e.rowid as sendingid, e.ref as exp_ref, e.date_creation, e.date_delivery, e.date_expedition,";
//if ($conf->livraison_bon->enabled) $sql .= " l.rowid as livraison_id, l.ref as livraison_ref, l.date_delivery, ld.qty as qty_received,";
$sql.= ' p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid,';
$sql.= ' p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid, p.tobatch as product_tobatch,';
$sql.= ' p.description as product_desc';
$sql.= " FROM ".MAIN_DB_PREFIX."expeditiondet as ed";
$sql.= ", ".MAIN_DB_PREFIX."expedition as e";
@ -270,6 +270,7 @@ function show_list_sending_receive($origin,$origin_id,$filter='')
$product_static->type=$objp->fk_product_type;
$product_static->id=$objp->fk_product;
$product_static->ref=$objp->ref;
$product_static->status_batch=$objp->product_tobatch;
$text=$product_static->getNomUrl(1);
$text.= ' - '.$label;
$description=(! empty($conf->global->PRODUIT_DESC_IN_FORM)?'':dol_htmlentitiesbr($objp->description));

View File

@ -42,6 +42,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/modules/expedition/modules_expedition.php'
require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php';
if (! empty($conf->product->enabled) || ! empty($conf->service->enabled)) require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
if (! empty($conf->propal->enabled)) require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
if (! empty($conf->commande->enabled)) require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
@ -232,30 +233,39 @@ if (empty($reshook))
$batch="batchl".$i."_0";
$stockLocation="ent1".$i."_0";
$qty = "qtyl".$i;
if (isset($_POST[$batch]))
if ($objectsrc->lines[$i]->product_tobatch) // If product need a batch number
{
//shipment line with batch-enable product
$qty .= '_'.$j;
while (isset($_POST[$batch]))
{
// save line of detail into sub_qty
$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;
}
$batch_line[$i]['detail']=$sub_qty; // array of details
$batch_line[$i]['qty']=$subtotalqty;
$batch_line[$i]['ix_l']=GETPOST($idl,'int');
$totalqty+=$subtotalqty;
if (isset($_POST[$batch]))
{
//shipment line with batch-enable product
$qty .= '_'.$j;
while (isset($_POST[$batch]))
{
// save line of detail into sub_qty
$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;
}
$batch_line[$i]['detail']=$sub_qty; // array of details
$batch_line[$i]['qty']=$subtotalqty;
$batch_line[$i]['ix_l']=GETPOST($idl,'int');
$totalqty+=$subtotalqty;
}
else
{
// Case we dont use the list of available qty for each warehouse/lot
// GUI does not allow this yet
setEventMessage('StockRequiredToChooseWhichLotToUse', 'errors');
}
}
else if (isset($_POST[$stockLocation]))
{
@ -626,8 +636,6 @@ if ($action == 'create')
$object = new $classname($db);
if ($object->fetch($origin_id)) // This include the fetch_lines
{
//var_dump($object);
$soc = new Societe($db);
$soc->fetch($object->socid);
@ -652,7 +660,7 @@ if ($action == 'create')
print '<table class="border centpercent">';
// Ref
print '<tr><td class="fieldrequired">';
print '<tr><td class="titlefieldcreate fieldrequired">';
if ($origin == 'commande' && ! empty($conf->commande->enabled))
{
print $langs->trans("RefOrder").'</td><td colspan="3"><a href="'.DOL_URL_ROOT.'/commande/card.php?id='.$object->id.'">'.img_object($langs->trans("ShowOrder"),'order').' '.$object->ref;
@ -675,7 +683,7 @@ if ($action == 'create')
print '</tr>';
// Tiers
print '<tr><td class="fieldrequired">'.$langs->trans('Company').'</td>';
print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans('Company').'</td>';
print '<td colspan="3">'.$soc->getNomUrl(1).'</td>';
print '</tr>';
@ -691,7 +699,7 @@ if ($action == 'create')
// Note Public
print '<tr><td>'.$langs->trans("NotePublic").'</td>';
print '<td colspan="3">';
$doleditor = new DolEditor('note_public', $object->note_public, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70);
$doleditor = new DolEditor('note_public', $object->note_public, '', 60, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70);
print $doleditor->Create(1);
print "</td></tr>";
@ -700,7 +708,7 @@ if ($action == 'create')
{
print '<tr><td>'.$langs->trans("NotePrivate").'</td>';
print '<td colspan="3">';
$doleditor = new DolEditor('note_private', $object->note_private, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70);
$doleditor = new DolEditor('note_private', $object->note_private, '', 60, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70);
print $doleditor->Create(1);
print "</td></tr>";
}
@ -708,19 +716,18 @@ if ($action == 'create')
// Weight
print '<tr><td>';
print $langs->trans("Weight");
print '</td><td width="90px"><input name="weight" size="5" value="'.GETPOST('weight','int').'"></td><td>';
print '</td><td><input name="weight" size="4" value="'.GETPOST('weight','int').'"> ';
print $formproduct->select_measuring_units("weight_units","weight",GETPOST('weight_units','int'));
print '</td></tr><tr><td>';
print $langs->trans("Width");
print ' </td><td><input name="sizeW" size="5" value="'.GETPOST('sizeW','int').'"></td><td rowspan="3">';
print '</td></tr>';
// Dim
print '<tr><td>';
print $langs->trans("Width").' x '.$langs->trans("Height").' x '.$langs->trans("Depth");
print ' </td><td colspan="3"><input name="sizeW" size="4" value="'.GETPOST('sizeW','int').'">';
print ' x <input name="sizeH" size="4" value="'.GETPOST('sizeH','int').'">';
print ' x <input name="sizeS" size="4" value="'.GETPOST('sizeS','int').'">';
print ' ';
print $formproduct->select_measuring_units("size_units","size");
print '</td></tr><tr><td>';
print $langs->trans("Height");
print '</td><td><input name="sizeH" size="5" value="'.GETPOST('sizeH','int').'"></td>';
print '</tr><tr><td>';
print $langs->trans("Depth");
print '</td><td><input name="sizeS" size="5" value="'.GETPOST('sizeS','int').'"></td>';
print '</tr>';
print '</td></tr>';
// Delivery method
print "<tr><td>".$langs->trans("DeliveryMethod")."</td>";
@ -864,6 +871,7 @@ if ($action == 'create')
$product_static->type=$line->fk_product_type;
$product_static->id=$line->fk_product;
$product_static->ref=$line->ref;
$product_static->status_batch=$line->product_tobatch;
$text=$product_static->getNomUrl(1);
$text.= ' - '.(! empty($line->label)?$line->label:$line->product_label);
$description=($conf->global->PRODUIT_DESC_IN_FORM?'':dol_htmlentitiesbr($line->desc));
@ -1136,9 +1144,10 @@ if ($action == 'create')
$subj=0;
print '<input name="idl'.$indiceAsked.'" type="hidden" value="'.$line->id.'">';
$warehouseObject=new Entrepot($db);
$productlotObject=new Productlot($db);
foreach ($product->stock_warehouse as $warehouse_id=>$stock_warehouse)
{
$warehouseObject=new Entrepot($db);
$warehouseObject->fetch($warehouse_id);
if (($stock_warehouse->real > 0) && (count($stock_warehouse->detail_batch))) {
foreach ($stock_warehouse->detail_batch as $dbatch)
@ -1156,7 +1165,11 @@ if ($action == 'create')
print '<!-- Show details of lot -->';
print '<input name="batchl'.$indiceAsked.'_'.$subj.'" type="hidden" value="'.$dbatch->id.'">';
print $langs->trans("DetailBatchFormat", $dbatch->batch, dol_print_date($dbatch->eatby,"day"), dol_print_date($dbatch->sellby,"day"), $dbatch->qty);
//print $langs->trans("DetailBatchFormat", $dbatch->batch, dol_print_date($dbatch->eatby,"day"), dol_print_date($dbatch->sellby,"day"), $dbatch->qty);
$productlotObject->fetch(0, $line->fk_product, $dbatch->batch);
print $langs->trans("Batch").': '.$productlotObject->getNomUrl(1);
print ' ('.$dbatch->qty.')';
//print $langs->trans("DetailBatchFormat", 'ee'.$dbatch->batch, dol_print_date($dbatch->eatby,"day"), dol_print_date($dbatch->sellby,"day"), $dbatch->qty);
$quantityToBeDelivered -= $deliverableQty;
if ($quantityToBeDelivered < 0)
{
@ -1243,6 +1256,7 @@ else if ($id || $ref)
/* *************************************************************************** */
{
$lines = $object->lines;
$num_prod = count($lines);
if ($object->id > 0)
@ -1687,7 +1701,7 @@ else if ($id || $ref)
$sql.= ", ed.rowid as shipmentline_id, ed.qty as qty_shipped, ed.fk_expedition as expedition_id, ed.fk_origin_line, ed.fk_entrepot";
$sql.= ", e.rowid as shipment_id, e.ref as shipment_ref, e.date_creation, e.date_valid, e.date_delivery, e.date_expedition,";
//if ($conf->livraison_bon->enabled) $sql .= " l.rowid as livraison_id, l.ref as livraison_ref, l.date_delivery, ld.qty as qty_received,";
$sql.= ' p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid,';
$sql.= ' p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid, p.tobatch as product_tobatch';
$sql.= ' p.description as product_desc';
$sql.= " FROM ".MAIN_DB_PREFIX."expeditiondet as ed";
$sql.= ", ".MAIN_DB_PREFIX."expedition as e";
@ -1751,6 +1765,7 @@ else if ($id || $ref)
$product_static->type=$lines[$i]->fk_product_type;
$product_static->id=$lines[$i]->fk_product;
$product_static->ref=$lines[$i]->ref;
$product_static->status_batch=$lines[$i]->product_tobatch;
$text=$product_static->getNomUrl(1);
$text.= ' - '.$label;
$description=(! empty($conf->global->PRODUIT_DESC_IN_FORM)?'':dol_htmlentitiesbr($lines[$i]->description));

View File

@ -850,14 +850,14 @@ class Expedition extends CommonObject
}
/**
* Add a expedition line.
* Add an expedition line.
* If STOCK_WAREHOUSE_NOT_REQUIRED_FOR_SHIPMENTS is set, you can add a shipment line, with no stock source defined
* If STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT is not set, you can add a shipment line, even if not enough into stock
*
* @param int $entrepot_id Id of warehouse
* @param int $id Id of source line (order line)
* @param int $qty Quantity
* @param array $array_options extrafields array
* @param array $array_options extrafields array
* @return int <0 if KO, >0 if OK
*/
function addline($entrepot_id, $id, $qty,$array_options=0)
@ -909,6 +909,13 @@ class Expedition extends CommonObject
}
}
// If product need a batch number, we should not have called this function but addline_batch instead.
if (! empty($conf->productbatch->enabled) && ! empty($orderline->fk_product) && ! empty($orderline->product_tobatch))
{
$this->error='ADDLINE_WAS_CALLED_INSTEAD_OF_ADDLINEBATCH';
return -4;
}
// extrafields
if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && is_array($array_options) && count($array_options)>0) // For avoid conflicts if trigger used
$line->array_options = $array_options;

View File

@ -42,6 +42,7 @@ $langs->load("bills");
$langs->load('propal');
$langs->load('deliveries');
$langs->load('stocks');
$langs->load("productbatch");
$id=GETPOST('id','int'); // id of order
$ref= GETPOST('ref','alpha');

View File

@ -3198,7 +3198,11 @@ class Product extends CommonObject
{
//
}
if (! empty($this->entity)) $label .= '<br>' . $this->show_photos($conf->product->multidir_output[$this->entity],1,1,0,0,0,80);
if (! empty($this->entity))
{
$tmpphoto = $this->show_photos($conf->product->multidir_output[$this->entity],1,1,0,0,0,80);
if ($this->nbphoto > 0) $label .= '<br>' . $tmpphoto;
}
$linkclose='';

View File

@ -547,7 +547,15 @@ class Productlot extends CommonObject
$label = '<u>' . $langs->trans("Batch") . '</u>';
$label.= '<div width="100%">';
$label.= '<b>' . $langs->trans('Batch') . ':</b> ' . $this->batch;
if ($this->eatby)
{
$label.= '<br><b>' . $langs->trans('EatByDate') . ':</b> ' . dol_print_date($this->eatby, 'day');
}
if ($this->sellby)
{
$label.= '<br><b>' . $langs->trans('SellByDate') . ':</b> ' . dol_print_date($this->sellby, 'day');
}
$link = '<a href="'.DOL_URL_ROOT.'/product/stock/productlot_card.php?id='.$this->id.'"';
$link.= ($notooltip?'':' title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip'.($morecss?' '.$morecss:'').'"');
$link.= '>';