forked from Wavyzz/dolibarr
New add shipping and dispatching from/to multiple warehouses
Add select2 to warehouse selectors Ship customer orderline from multiple warehouses Dispatch client orderline to multiple warehouses
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
|
||||
/**
|
||||
* addLineBatch
|
||||
* @deprecated replaced by addDispatchLine and moved to module folder and file fourn/js/lib_dispatch.js
|
||||
*
|
||||
* @param index int number of produt. 0 = first product line
|
||||
*/
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
|
||||
* Copyright (C) 2013 Marcos García <marcosgdf@gmail.com>
|
||||
* Copyright (C) 2014 Cedric GROSS <c.gross@kreiz-it.fr>
|
||||
* Copyright (C) 2014 Francis Appels <francis.appels@yahoo.com>
|
||||
* Copyright (C) 2014-2015 Francis Appels <francis.appels@yahoo.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -90,20 +90,6 @@ $permissiondellink=$user->rights->expedition->livraison->creer; // Used by the i
|
||||
* Actions
|
||||
*/
|
||||
|
||||
$warehousecanbeselectedlater=1;
|
||||
if (($action == 'create') || ($action == 'add'))
|
||||
{
|
||||
if (! empty($conf->productbatch->enabled))
|
||||
{
|
||||
if (! (GETPOST('entrepot_id','int') > 0))
|
||||
{
|
||||
$langs->load("errors");
|
||||
setEventMessages($langs->trans("WarehouseMustBeSelectedAtFirstStepWhenProductBatchModuleOn"), null, 'errors');
|
||||
header("Location: ".DOL_URL_ROOT.'/expedition/shipment.php?id='.$origin_id);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set incoterm
|
||||
if ($action == 'set_incoterms' && !empty($conf->incoterm->enabled))
|
||||
@@ -157,6 +143,7 @@ if (empty($reshook))
|
||||
$object->location_incoterms = GETPOST('location_incoterms', 'alpha');
|
||||
|
||||
$batch_line = array();
|
||||
$stockLine = array();
|
||||
|
||||
$num=count($objectsrc->lines);
|
||||
$totalqty=0;
|
||||
@@ -170,6 +157,7 @@ if (empty($reshook))
|
||||
|
||||
$j=0;
|
||||
$batch="batchl".$i."_0";
|
||||
$stockLocation="ent1".$i."_0";
|
||||
$qty = "qtyl".$i;
|
||||
|
||||
if (isset($_POST[$batch]))
|
||||
@@ -196,6 +184,22 @@ if (empty($reshook))
|
||||
|
||||
$totalqty+=$subtotalqty;
|
||||
}
|
||||
else if (isset($_POST[$stockLocation]))
|
||||
{
|
||||
//shipment line from multiple stock locations
|
||||
$qty .= '_'.$j;
|
||||
while (isset($_POST[$stockLocation]))
|
||||
{
|
||||
// save sub line of warehouse
|
||||
$stockLine[$i][$j]['qty']=GETPOST($qty,'int');
|
||||
$stockLine[$i][$j]['warehouse_id']=GETPOST($stockLocation,'int');
|
||||
$stockLine[$i][$j]['ix_l']=GETPOST($idl,'int');
|
||||
|
||||
$j++;
|
||||
$stockLocation="ent1".$i."_".$j;
|
||||
$qty = "qtyl".$i.'_'.$j;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//shipment line for product with no batch management
|
||||
@@ -214,6 +218,22 @@ if (empty($reshook))
|
||||
if (! isset($batch_line[$i]))
|
||||
{
|
||||
// not batch mode
|
||||
if (isset($stockLine[$i]))
|
||||
{
|
||||
//shipment from multiple stock locations
|
||||
for($j = 0; $j < count($stockLine[$i]); $j++)
|
||||
{
|
||||
if ($stockLine[$i][$j]['qty']>0)
|
||||
{
|
||||
$ret=$object->addline($stockLine[$i][$j]['warehouse_id'], $stockLine[$i][$j]['ix_l'], $stockLine[$i][$j]['qty']);
|
||||
if ($ret < 0)
|
||||
{
|
||||
setEventMessages($object->error, $object->errors, 'errors');
|
||||
$error++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (GETPOST($qty,'int') > 0 || (GETPOST($qty,'int') == 0 && $conf->global->SHIPMENT_GETS_ALL_ORDER_PRODUCTS))
|
||||
{
|
||||
$ent = "entl".$i;
|
||||
@@ -773,20 +793,22 @@ if ($action == 'create')
|
||||
print '</td>';
|
||||
|
||||
$quantityAsked = $line->qty;
|
||||
if ($line->product_type == 1 && empty($conf->global->STOCK_SUPPORTS_SERVICES))
|
||||
{
|
||||
$quantityToBeDelivered = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
$quantityToBeDelivered = $quantityAsked - $quantityDelivered;
|
||||
|
||||
}
|
||||
$warehouse_id = GETPOST('entrepot_id','int');
|
||||
|
||||
$defaultqty=0;
|
||||
$warehouseObject = null;
|
||||
if ($warehouse_id > 0)
|
||||
{
|
||||
//var_dump($product);
|
||||
$stock = $product->stock_warehouse[$warehouse_id]->real;
|
||||
$stock+=0; // Convertit en numerique
|
||||
$defaultqty=min($quantityToBeDelivered, $stock);
|
||||
if (($line->product_type == 1 && empty($conf->global->STOCK_SUPPORTS_SERVICES)) || $defaultqty < 0) $defaultqty=0;
|
||||
}
|
||||
|
||||
//ship from preselected location
|
||||
$stock = + $product->stock_warehouse[$warehouse_id]->real; // Convert to number
|
||||
$deliverableQty=min($quantityToBeDelivered, $stock);
|
||||
if (empty($conf->productbatch->enabled) || ! ($product->hasbatch() && is_object($product->stock_warehouse[$warehouse_id])))
|
||||
{
|
||||
// Quantity to send
|
||||
@@ -794,7 +816,7 @@ if ($action == 'create')
|
||||
if ($line->product_type == 0 || ! empty($conf->global->STOCK_SUPPORTS_SERVICES))
|
||||
{
|
||||
print '<input name="idl'.$indiceAsked.'" type="hidden" value="'.$line->id.'">';
|
||||
print '<input name="qtyl'.$indiceAsked.'" id="qtyl'.$indiceAsked.'" type="text" size="4" value="'.$defaultqty.'">';
|
||||
print '<input name="qtyl'.$indiceAsked.'" id="qtyl'.$indiceAsked.'" type="text" size="4" value="'.$deliverableQty.'">';
|
||||
}
|
||||
else print $langs->trans("NA");
|
||||
print '</td>';
|
||||
@@ -865,9 +887,10 @@ if ($action == 'create')
|
||||
foreach ($product->stock_warehouse[$warehouse_id]->detail_batch as $dbatch)
|
||||
{
|
||||
//var_dump($dbatch);
|
||||
$substock=$dbatch->qty +0 ; // To get a numeric
|
||||
$batchStock = + $dbatch->qty; // To get a numeric
|
||||
$deliverableQty = min($quantityToBeDelivered,$batchStock);
|
||||
print '<tr><td colspan="3" ></td><td align="center">';
|
||||
print '<input name="qtyl'.$indiceAsked.'_'.$subj.'" id="qtyl'.$indiceAsked.'_'.$subj.'" type="text" size="4" value="'.($substock > 0 ? min($defaultqty,$substock) : '0').'">';
|
||||
print '<input name="qtyl'.$indiceAsked.'_'.$subj.'" id="qtyl'.$indiceAsked.'_'.$subj.'" type="text" size="4" value="'.$deliverableQty.'">';
|
||||
print '</td>';
|
||||
|
||||
print '<td align="left">';
|
||||
@@ -877,10 +900,10 @@ 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);
|
||||
if ($defaultqty<=0) {
|
||||
$defaultqty=0;
|
||||
} else {
|
||||
$defaultqty -= min($defaultqty,$substock);
|
||||
$quantityToBeDelivered -= $deliverableQty;
|
||||
if ($quantityToBeDelivered < 0)
|
||||
{
|
||||
$quantityToBeDelivered = 0;
|
||||
}
|
||||
$subj++;
|
||||
}
|
||||
@@ -895,7 +918,136 @@ if ($action == 'create')
|
||||
print img_warning().' '.$langs->trans("NoProductToShipFoundIntoStock", $staticwarehouse->libelle);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// ship from multiple locations
|
||||
if (empty($conf->productbatch->enabled) || ! $product->hasbatch())
|
||||
{
|
||||
print '<td></td><td></td></tr>'; // end line and start a new one for each warehouse
|
||||
print '<input name="idl'.$indiceAsked.'" type="hidden" value="'.$line->id.'">';
|
||||
$subj=0;
|
||||
foreach ($product->stock_warehouse as $warehouse_id=>$stock_warehouse) {
|
||||
$warehouseObject=new Entrepot($db);
|
||||
$warehouseObject->fetch($warehouse_id);
|
||||
if ($stock_warehouse->real > 0) {
|
||||
$stock = + $stock_warehouse->real; // Convert it to number
|
||||
$deliverableQty = min($quantityToBeDelivered,$stock);
|
||||
// Quantity to send
|
||||
print '<tr><td colspan="3" ></td><td align="center">';
|
||||
if ($line->product_type == 0 || ! empty($conf->global->STOCK_SUPPORTS_SERVICES))
|
||||
{
|
||||
print '<input name="qtyl'.$indiceAsked.'_'.$subj.'" id="qtyl'.$indiceAsked.'" type="text" size="4" value="'.$deliverableQty.'">';
|
||||
print '<input name="ent1'.$indiceAsked.'_'.$subj.'" type="hidden" value="'.$warehouse_id.'">';
|
||||
}
|
||||
else print $langs->trans("NA");
|
||||
print '</td>';
|
||||
|
||||
// Stock
|
||||
if (! empty($conf->stock->enabled))
|
||||
{
|
||||
print '<td align="left">';
|
||||
if ($line->product_type == 0 || ! empty($conf->global->STOCK_SUPPORTS_SERVICES))
|
||||
{
|
||||
print $warehouseObject->getNomUrl(0).' / ';
|
||||
|
||||
print '<!-- Show details of stock -->';
|
||||
print $stock;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
print $langs->trans("Service");
|
||||
}
|
||||
print '</td>';
|
||||
}
|
||||
$quantityToBeDelivered -= $deliverableQty;
|
||||
if ($quantityToBeDelivered < 0)
|
||||
{
|
||||
$quantityToBeDelivered = 0;
|
||||
}
|
||||
$subj++;
|
||||
print "</tr>\n";
|
||||
}
|
||||
}
|
||||
// Show subproducts of product
|
||||
if (! empty($conf->global->PRODUIT_SOUSPRODUITS) && $line->fk_product > 0)
|
||||
{
|
||||
$product->get_sousproduits_arbo();
|
||||
$prods_arbo = $product->get_arbo_each_prod($qtyProdCom);
|
||||
if(count($prods_arbo) > 0)
|
||||
{
|
||||
foreach($prods_arbo as $key => $value)
|
||||
{
|
||||
//print $value[0];
|
||||
$img='';
|
||||
if ($value['stock'] < $value['stock_alert'])
|
||||
{
|
||||
$img=img_warning($langs->trans("StockTooLow"));
|
||||
}
|
||||
print "<tr ".$bc[$var]."><td> ->
|
||||
<a href=\"".DOL_URL_ROOT."/product/card.php?id=".$value['id']."\">".$value['fullpath']."
|
||||
</a> (".$value['nb'].")</td><td align=\"center\"> ".$value['nb_total']."</td><td> </td><td> </td>
|
||||
<td align=\"center\">".$value['stock']." ".$img."</td></tr>";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
print '<td></td><td></td></tr>'; // end line and start a new one for lot/serial
|
||||
|
||||
$subj=0;
|
||||
print '<input name="idl'.$indiceAsked.'" type="hidden" value="'.$line->id.'">';
|
||||
|
||||
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)
|
||||
{
|
||||
//var_dump($dbatch);
|
||||
$batchStock = + $dbatch->qty; // To get a numeric
|
||||
$deliverableQty = min($quantityToBeDelivered,$batchStock);
|
||||
print '<tr><td colspan="3" ></td><td align="center">';
|
||||
print '<input name="qtyl'.$indiceAsked.'_'.$subj.'" id="qtyl'.$indiceAsked.'_'.$subj.'" type="text" size="4" value="'.$deliverableQty.'">';
|
||||
print '</td>';
|
||||
|
||||
print '<td align="left">';
|
||||
|
||||
print $warehouseObject->getNomUrl(0).' / ';
|
||||
|
||||
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);
|
||||
$quantityToBeDelivered -= $deliverableQty;
|
||||
if ($quantityToBeDelivered < 0)
|
||||
{
|
||||
$quantityToBeDelivered = 0;
|
||||
}
|
||||
//dol_syslog('deliverableQty = '.$deliverableQty.' batchStock = '.$batchStock);
|
||||
$subj++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($subj == 0)
|
||||
{
|
||||
print '<tr><td colspan="3" ></td><td align="center">';
|
||||
print '<input name="qtyl'.$indiceAsked.'_'.$subj.'" id="qtyl'.$indiceAsked.'_'.$subj.'" type="text" size="4" value="0" disabled="disabled"> ';
|
||||
print '</td>';
|
||||
|
||||
print '<td align="left">';
|
||||
if ($warehouseObject)
|
||||
{
|
||||
print img_warning().' '.$langs->trans("NoProductToShipFoundIntoStock", $warehouseObject->libelle);
|
||||
}
|
||||
else
|
||||
{
|
||||
print img_warning().' '.$langs->trans("StockTooLow");
|
||||
}
|
||||
}
|
||||
}
|
||||
$indiceAsked++;
|
||||
}
|
||||
|
||||
|
||||
@@ -378,25 +378,39 @@ class Expedition extends CommonObject
|
||||
function create_line_batch($line_ext)
|
||||
{
|
||||
$error = 0;
|
||||
$stockLocationQty = array(); // associated array with batch qty in stock location
|
||||
|
||||
if ($this->create_line(($line_ext->entrepot_id?$line_ext->entrepot_id:'null'),$line_ext->origin_line_id,$line_ext->qty) < 0)
|
||||
$tab=$line_ext->detail_batch;
|
||||
// create stockLocation Qty array
|
||||
foreach ($tab as $detbatch)
|
||||
{
|
||||
if ($detbatch->entrepot_id)
|
||||
{
|
||||
$stockLocationQty[$detbatch->entrepot_id] += $detbatch->dluo_qty;
|
||||
}
|
||||
}
|
||||
// create shipment lines
|
||||
foreach ($stockLocationQty as $stockLocation => $qty)
|
||||
{
|
||||
if ($this->create_line($stockLocation,$line_ext->origin_line_id,$qty) < 0)
|
||||
{
|
||||
$error++;
|
||||
}
|
||||
|
||||
if (! $error)
|
||||
else
|
||||
{
|
||||
// create shipment batch lines for stockLocation
|
||||
$line_id= $this->db->last_insert_id(MAIN_DB_PREFIX."expeditiondet");
|
||||
$tab=$line_ext->detail_batch;
|
||||
foreach ($tab as $detbatch)
|
||||
{
|
||||
if ($detbatch->entrepot_id == $stockLocation){
|
||||
if (! ($detbatch->create($line_id) >0)) // Create an expeditionlinebatch
|
||||
{
|
||||
$error++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (! $error) return 1;
|
||||
else return -1;
|
||||
@@ -1278,8 +1292,10 @@ class Expedition extends CommonObject
|
||||
$this->total_localtax1+= $tabprice[9];
|
||||
$this->total_localtax2+= $tabprice[10];
|
||||
|
||||
if ($originline != $obj->fk_origin_line)
|
||||
{
|
||||
$line->detail_batch = array();
|
||||
|
||||
}
|
||||
// Eat-by date
|
||||
if (! empty($conf->productbatch->enabled) && $obj->line_id > 0)
|
||||
{
|
||||
|
||||
@@ -721,10 +721,7 @@ if ($id > 0 || ! empty($ref))
|
||||
|
||||
if (! empty($conf->stock->enabled))
|
||||
{
|
||||
$warehousecanbeselectedlater=1;
|
||||
if (! empty($conf->productbatch->enabled)) $warehousecanbeselectedlater=0;
|
||||
|
||||
print '<td'.($warehousecanbeselectedlater?'':' class="fieldrequired"').'>'.$langs->trans("WarehouseSource").'</td>';
|
||||
print '<td>'.$langs->trans("WarehouseSource").'</td>';
|
||||
print '<td>';
|
||||
print $formproduct->selectWarehouses(! empty($commande->warehouse_id)?$commande->warehouse_id:-1,'entrepot_id','',1);
|
||||
if (count($formproduct->cache_warehouses) <= 0)
|
||||
|
||||
@@ -33,6 +33,7 @@ require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/fourn.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.dispatch.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
|
||||
if (! empty($conf->projet->enabled)) require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
|
||||
|
||||
$langs->load('orders');
|
||||
@@ -130,17 +131,17 @@ if ($action == 'dispatch' && $user->rights->fournisseur->commande->receptionner)
|
||||
$pos=0;
|
||||
foreach($_POST as $key => $value)
|
||||
{
|
||||
if (preg_match('/^product_([0-9]+)$/i', $key, $reg)) // without batch module enabled
|
||||
if (preg_match('/^product_([0-9]+)_([0-9]+)$/i', $key, $reg)) // without batch module enabled
|
||||
{
|
||||
$pos++;
|
||||
|
||||
//$numline=$reg[1] + 1; // line of product
|
||||
//$numline=$reg[2] + 1; // line of product
|
||||
$numline=$pos;
|
||||
$prod = "product_".$reg[1];
|
||||
$qty = "qty_".$reg[1];
|
||||
$ent = "entrepot_".$reg[1];
|
||||
$pu = "pu_".$reg[1]; // This is unit price including discount
|
||||
$fk_commandefourndet = "fk_commandefourndet_".$reg[1];
|
||||
$prod = "product_".$reg[1].'_'.$reg[2];
|
||||
$qty = "qty_".$reg[1].'_'.$reg[2];
|
||||
$ent = "entrepot_".$reg[1].'_'.$reg[2];
|
||||
$pu = "pu_".$reg[1].'_'.$reg[2]; // This is unit price including discount
|
||||
$fk_commandefourndet = "fk_commandefourndet_".$reg[1].'_'.$reg[2];
|
||||
|
||||
if (GETPOST($qty) > 0) // We ask to move a qty
|
||||
{
|
||||
@@ -163,14 +164,14 @@ if ($action == 'dispatch' && $user->rights->fournisseur->commande->receptionner)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (preg_match('/^product_([0-9]+)_([0-9]+)$/i', $key, $reg)) // with batch module enabled
|
||||
if (preg_match('/^product_batch_([0-9]+)_([0-9]+)$/i', $key, $reg)) // with batch module enabled
|
||||
{
|
||||
$pos++;
|
||||
|
||||
//eat-by date dispatch
|
||||
//$numline=$reg[2] + 1; // line of product
|
||||
$numline=$pos;
|
||||
$prod = 'product_'.$reg[1].'_'.$reg[2];
|
||||
$prod = 'product_batch_'.$reg[1].'_'.$reg[2];
|
||||
$qty = 'qty_'.$reg[1].'_'.$reg[2];
|
||||
$ent = 'entrepot_'.$reg[1].'_'.$reg[2];
|
||||
$pu = 'pu_'.$reg[1].'_'.$reg[2];
|
||||
@@ -191,7 +192,7 @@ if ($action == 'dispatch' && $user->rights->fournisseur->commande->receptionner)
|
||||
$error++;
|
||||
}
|
||||
|
||||
if (! ($_POST[$lot] || $dDLUO || $dDLC))
|
||||
if (! (GETPOST($lot, 'alpha') || $dDLUO || $dDLC))
|
||||
{
|
||||
dol_syslog('No dispatch for line '.$key.' as serial/eat-by/sellby date are not set');
|
||||
$text = $langs->transnoentities('atleast1batchfield').', '.$langs->transnoentities('Line').' ' .($numline).'-'.($reg[1]+1);
|
||||
@@ -245,19 +246,13 @@ if ($action == 'dispatch' && $user->rights->fournisseur->commande->receptionner)
|
||||
*/
|
||||
|
||||
$form = new Form($db);
|
||||
$formproduct = new FormProduct($db);
|
||||
$warehouse_static = new Entrepot($db);
|
||||
$supplierorderdispatch = new CommandeFournisseurDispatch($db);
|
||||
|
||||
|
||||
$help_url='EN:CommandeFournisseur';
|
||||
if (!empty($conf->productbatch->enabled))
|
||||
{
|
||||
llxHeader('',$langs->trans("OrderCard"),$help_url,'',0,0,array('/core/js/lib_batch.js'));
|
||||
}
|
||||
else
|
||||
{
|
||||
llxHeader('',$langs->trans("OrderCard"),$help_url);
|
||||
}
|
||||
llxHeader('',$langs->trans("OrderCard"),$help_url,'',0,0,array('/fourn/js/lib_dispatch.js'));
|
||||
|
||||
$now=dol_now();
|
||||
|
||||
@@ -425,7 +420,7 @@ if ($id > 0 || ! empty($ref))
|
||||
$nbfreeproduct=0;
|
||||
$nbproduct=0;
|
||||
|
||||
$var=true;
|
||||
$var=false;
|
||||
while ($i < $num)
|
||||
{
|
||||
$objp = $db->fetch_object($resql);
|
||||
@@ -449,13 +444,7 @@ if ($id > 0 || ! empty($ref))
|
||||
// To show detail cref and description value, we must make calculation by cref
|
||||
//print ($objp->cref?' ('.$objp->cref.')':'');
|
||||
//if ($objp->description) print '<br>'.nl2br($objp->description);
|
||||
if ((empty($conf->productbatch->enabled)) || $objp->tobatch==0)
|
||||
{
|
||||
$suffix='_'.$i;
|
||||
} else {
|
||||
$suffix='_0_'.$i;
|
||||
}
|
||||
|
||||
|
||||
print "\n";
|
||||
print '<!-- Line '.$suffix.' -->'."\n";
|
||||
@@ -489,6 +478,7 @@ if ($id > 0 || ! empty($ref))
|
||||
print "</td>";
|
||||
}
|
||||
|
||||
$var=!$var;
|
||||
$up_ht_disc=$objp->subprice;
|
||||
if (! empty($objp->remise_percent) && empty($conf->global->STOCK_EXCLUDE_DISCOUNT_FOR_PMP)) $up_ht_disc=price2num($up_ht_disc * (100 - $objp->remise_percent) / 100, 'MU');
|
||||
|
||||
@@ -500,15 +490,19 @@ if ($id > 0 || ! empty($ref))
|
||||
|
||||
if (! empty($conf->productbatch->enabled) && $objp->tobatch==1)
|
||||
{
|
||||
print '<td align="right">'.img_picto($langs->trans('AddDispatchBatchLine'),'split.png','onClick="addLineBatch('.$i.')"').'</td>'; // Dispatch column
|
||||
$type = 'batch';
|
||||
print '<td align="right">'.img_picto($langs->trans('AddDispatchBatchLine'),'split.png','onClick="addDispatchLine('.$i.',\''.$type.'\')"').'</td>'; // Dispatch column
|
||||
print '<td></td>'; // Warehouse column
|
||||
print '</tr>';
|
||||
|
||||
print '<tr '.$bc[$var].' name="dluo'.$suffix.'">';
|
||||
print '<tr '.$bc[$var].' name="'.$type.$suffix.'">';
|
||||
print '<td>';
|
||||
print '<input name="fk_commandefourndet'.$suffix.'" type="hidden" value="'.$objp->rowid.'">';
|
||||
print '<input name="product'.$suffix.'" type="hidden" value="'.$objp->fk_product.'">';
|
||||
print '<input name="product_batch'.$suffix.'" type="hidden" value="'.$objp->fk_product.'">';
|
||||
print '<input name="pu'.$suffix.'" type="hidden" value="'.$up_ht_disc.'"><!-- This is a up including discount -->';
|
||||
// hidden fields for js function
|
||||
print '<input id="qty_ordered'.$suffix.'" type="hidden" value="'.$objp->qty.'">';
|
||||
print '<input id="qty_dispatched'.$suffix.'" type="hidden" value="'.(float) $products_dispatched[$objp->rowid].'">';
|
||||
print '</td>';
|
||||
|
||||
print '<td>';
|
||||
@@ -524,15 +518,24 @@ if ($id > 0 || ! empty($ref))
|
||||
print '</td>';
|
||||
print '<td colspan="2"> </td>'; // Qty ordered + qty already dispatached
|
||||
}
|
||||
|
||||
// Dispatch
|
||||
print '<td align="right">';
|
||||
if (empty($conf->productbatch->enabled) || $objp->tobatch!=1)
|
||||
else
|
||||
{
|
||||
$type = 'dispatch';
|
||||
print '<td align="right">'.img_picto($langs->trans('AddStockLocationLine'),'split.png','onClick="addDispatchLine('.$i.',\''.$type.'\')"').'</td>'; // Dispatch column
|
||||
print '<td></td>';
|
||||
print '</tr>';
|
||||
print '<tr '.$bc[$var].' name="'.$type.$suffix.'">';
|
||||
print '<td colspan="6">';
|
||||
print '<input name="fk_commandefourndet'.$suffix.'" type="hidden" value="'.$objp->rowid.'">';
|
||||
print '<input name="product'.$suffix.'" type="hidden" value="'.$objp->fk_product.'">';
|
||||
print '<input name="pu'.$suffix.'" type="hidden" value="'.$up_ht_disc.'"><!-- This is a up including discount -->';
|
||||
// hidden fields for js function
|
||||
print '<input id="qty_ordered'.$suffix.'" type="hidden" value="'.$objp->qty.'">';
|
||||
print '<input id="qty_dispatched'.$suffix.'" type="hidden" value="'.(float) $products_dispatched[$objp->rowid].'">';
|
||||
print '</td>';
|
||||
}
|
||||
// Dispatch
|
||||
print '<td align="right">';
|
||||
print '<input id="qty'.$suffix.'" name="qty'.$suffix.'" type="text" size="8" value="'.(GETPOST('qty'.$suffix)!='' ? GETPOST('qty'.$suffix) : $remaintodispatch).'">';
|
||||
print '</td>';
|
||||
|
||||
@@ -540,11 +543,11 @@ if ($id > 0 || ! empty($ref))
|
||||
print '<td align="right">';
|
||||
if (count($listwarehouses)>1)
|
||||
{
|
||||
print $form->selectarray("entrepot".$suffix, $listwarehouses, GETPOST("entrepot".$suffix), 1, 0, 0, '', 0, 0, $disabled);
|
||||
print $formproduct->selectWarehouses(GETPOST("entrepot".$suffix), "entrepot".$suffix,'',1,0,$objp->fk_product);
|
||||
}
|
||||
elseif (count($listwarehouses)==1)
|
||||
{
|
||||
print $form->selectarray("entrepot".$suffix, $listwarehouses, GETPOST("entrepot".$suffix), 0, 0, 0, '', 0, 0, $disabled);
|
||||
print $formproduct->selectWarehouses(GETPOST("entrepot".$suffix), "entrepot".$suffix,'',0,0,$objp->fk_product);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
77
htdocs/fourn/js/lib_dispatch.js
Normal file
77
htdocs/fourn/js/lib_dispatch.js
Normal file
@@ -0,0 +1,77 @@
|
||||
// Copyright (C) 2014 Cedric GROSS <c.gross@kreiz-it.fr>
|
||||
// Copyright (C) 2015 Francis Appels <francis.appels@z-application.com>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
// or see http://www.gnu.org/
|
||||
|
||||
//
|
||||
// \file htdocs/core/js/lib_dispatch.js
|
||||
// \brief File that include javascript functions used dispatch.php
|
||||
//
|
||||
|
||||
/**
|
||||
* addDispatchLine
|
||||
* Adds new table row for dispatching to multiple stock locations
|
||||
*
|
||||
* @param index int index of produt line. 0 = first product line
|
||||
* @param type string type of dispatch (batch = batch dispatch, dispatch = non batch dispatch)
|
||||
*/
|
||||
function addDispatchLine(index,type)
|
||||
{
|
||||
var $row = $("tr[name='"+type+'_0_'+index+"']").clone(true), // clone first batch line to jQuery object
|
||||
nbrTrs = $("tr[name^='"+type+"_'][name$='_"+index+"']").length, // position of line for batch
|
||||
qtyOrdered = parseFloat($("#qty_ordered_"+(nbrTrs - 1)+"_"+index).val()),
|
||||
qty = parseFloat($("#qty_"+(nbrTrs - 1)+"_"+index).val()),
|
||||
qtyDispatched;
|
||||
|
||||
if (type === 'batch')
|
||||
{
|
||||
qtyDispatched = parseFloat($("#qty_dispatched_"+(nbrTrs - 1)+"_"+index).val()) + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
qtyDispatched = parseFloat($("#qty_dispatched_"+(nbrTrs - 1)+"_"+index).val()) + qty;
|
||||
}
|
||||
|
||||
if (qtyDispatched < qtyOrdered)
|
||||
{
|
||||
//replace tr suffix nbr
|
||||
$row.html($row.html().replace(/_0_/g,"_"+nbrTrs+"_"));
|
||||
//create new select2 to avoid duplicate id of cloned one
|
||||
$row.find("select[name='"+'entrepot_'+nbrTrs+'_'+index+"']").select2();
|
||||
// TODO find solution to copy selected option to new select
|
||||
// TODO find solution to keep new tr's after page refresh
|
||||
//clear value
|
||||
$row.find("input[name^='qty']").val('');
|
||||
//change name of new row
|
||||
$row.attr('name',type+'_'+nbrTrs+'_'+index);
|
||||
//insert new row before last row
|
||||
$("tr[name^='"+type+"_'][name$='_"+index+"']:last").after($row);
|
||||
//remove cloned select2 with duplicate id.
|
||||
$("#s2id_entrepot_"+nbrTrs+'_'+index).detach();
|
||||
/* Suffix of lines are: _ trs.length _ index */
|
||||
$("#qty_"+nbrTrs+"_"+index).focus();
|
||||
$("#qty_dispatched_"+(nbrTrs)+"_"+index).val(qtyDispatched);
|
||||
if (type === 'batch')
|
||||
{
|
||||
$("#qty_"+(nbrTrs)+"_"+index).val(qty-1);
|
||||
$("#qty_"+(nbrTrs-1)+"_"+index).val(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
$("#qty_"+nbrTrs+"_"+index).val(qtyOrdered - qtyDispatched);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,24 +52,49 @@ class FormProduct
|
||||
* If fk_product is not 0, we do not use cache
|
||||
*
|
||||
* @param int $fk_product Add quantity of stock in label for product with id fk_product. Nothing if 0.
|
||||
* @param string $batch Add quantity of batch stock in label for product with batch name batch, batch name precedes batch_id. Nothing if ''.
|
||||
* @param int $fk_product_batch Add quantity of batch stock in label for product with batch id fk_product_batch. Nothing if 0.
|
||||
* @param boolean $sumStock sum total stock of a warehouse, default true
|
||||
* @return int Nb of loaded lines, 0 if already loaded, <0 if KO
|
||||
*/
|
||||
function loadWarehouses($fk_product=0)
|
||||
function loadWarehouses($fk_product=0, $batch = '', $fk_product_batch=0, $sumStock = true)
|
||||
{
|
||||
global $conf, $langs;
|
||||
|
||||
if (empty($fk_product) && count($this->cache_warehouses)) return 0; // Cache already loaded and we do not want a list with information specific to a product
|
||||
|
||||
$sql = "SELECT e.rowid, e.label";
|
||||
if ($fk_product) $sql.= ", ps.reel";
|
||||
$sql.= " FROM ".MAIN_DB_PREFIX."entrepot as e";
|
||||
if ($fk_product)
|
||||
if (!empty($fk_product))
|
||||
{
|
||||
if (!empty($fk_product_batch) || !empty($batch))
|
||||
{
|
||||
$sql.= ", pb.qty as stock";
|
||||
}
|
||||
else
|
||||
{
|
||||
$sql.= ", ps.reel as stock";
|
||||
}
|
||||
}
|
||||
else if ($sumStock)
|
||||
{
|
||||
$sql.= ", sum(ps.reel) as stock";
|
||||
}
|
||||
$sql.= " FROM ".MAIN_DB_PREFIX."entrepot as e";
|
||||
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_stock as ps on ps.fk_entrepot = e.rowid";
|
||||
if (!empty($fk_product))
|
||||
{
|
||||
$sql.= " AND ps.fk_product = '".$fk_product."'";
|
||||
if (!empty($batch))
|
||||
{
|
||||
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_batch as pb on pb.fk_product_stock = ps.rowid AND pb.batch = '".$batch."'";
|
||||
} else if (!empty($fk_product_batch))
|
||||
{
|
||||
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_batch as pb on pb.fk_product_stock = ps.rowid AND pb.rowid = '".$fk_product_batch."'";
|
||||
}
|
||||
}
|
||||
$sql.= " WHERE e.entity IN (".getEntity('stock', 1).")";
|
||||
$sql.= " AND e.statut = 1";
|
||||
if ($sumStock && empty($fk_product)) $sql.= " GROUP BY e.rowid, e.label, e.description";
|
||||
$sql.= " ORDER BY e.label";
|
||||
|
||||
dol_syslog(get_class($this).'::loadWarehouses', LOG_DEBUG);
|
||||
@@ -81,10 +106,11 @@ class FormProduct
|
||||
while ($i < $num)
|
||||
{
|
||||
$obj = $this->db->fetch_object($resql);
|
||||
|
||||
if ($sumStock) $obj->stock = price2num($obj->stock,5);
|
||||
$this->cache_warehouses[$obj->rowid]['id'] =$obj->rowid;
|
||||
$this->cache_warehouses[$obj->rowid]['label']=$obj->label;
|
||||
if ($fk_product) $this->cache_warehouses[$obj->rowid]['stock']=$obj->reel;
|
||||
$this->cache_warehouses[$obj->rowid]['description'] = $obj->description;
|
||||
$this->cache_warehouses[$obj->rowid]['stock'] = $obj->stock;
|
||||
$i++;
|
||||
}
|
||||
return $num;
|
||||
@@ -106,18 +132,31 @@ class FormProduct
|
||||
* @param int $disabled 1=Select is disabled
|
||||
* @param int $fk_product Add quantity of stock in label for product with id fk_product. Nothing if 0.
|
||||
* @param string $empty_label Empty label if needed (only if $empty=1)
|
||||
* @param int $showstock 1=show stock count
|
||||
* @param int $forcecombo force combo iso ajax select2
|
||||
* @param array $events events to add to select2
|
||||
* @return string HTML select
|
||||
*/
|
||||
function selectWarehouses($selected='',$htmlname='idwarehouse',$filtertype='',$empty=0,$disabled=0,$fk_product=0,$empty_label='')
|
||||
function selectWarehouses($selected='',$htmlname='idwarehouse',$filtertype='',$empty=0,$disabled=0,$fk_product=0,$empty_label='', $showstock=0, $forcecombo=0, $events=array())
|
||||
{
|
||||
global $langs,$user;
|
||||
global $conf,$langs,$user;
|
||||
|
||||
dol_syslog(get_class($this)."::selectWarehouses $selected, $htmlname, $filtertype, $empty, $disabled, $fk_product",LOG_DEBUG);
|
||||
|
||||
$out='';
|
||||
|
||||
$this->loadWarehouses($fk_product);
|
||||
$nbofwarehouses=count($this->cache_warehouses);
|
||||
|
||||
$out='<select class="flat"'.($disabled?' disabled':'').' id="'.$htmlname.'" name="'.($htmlname.($disabled?'_disabled':'')).'">';
|
||||
if ($conf->use_javascript_ajax && ! $forcecombo)
|
||||
{
|
||||
include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
|
||||
$comboenhancement = ajax_combobox($htmlname, $events);
|
||||
$out.= $comboenhancement;
|
||||
$nodatarole=($comboenhancement?' data-role="none"':'');
|
||||
}
|
||||
|
||||
$out.='<select class="flat"'.($disabled?' disabled':'').' id="'.$htmlname.'" name="'.($htmlname.($disabled?'_disabled':'')).'"'.$nodatarole.'>';
|
||||
if ($empty) $out.='<option value="-1">'.($empty_label?$empty_label:' ').'</option>';
|
||||
foreach($this->cache_warehouses as $id => $arraytypes)
|
||||
{
|
||||
@@ -125,7 +164,7 @@ class FormProduct
|
||||
if ($selected == $id || ($selected == 'ifone' && $nbofwarehouses == 1)) $out.=' selected';
|
||||
$out.='>';
|
||||
$out.=$arraytypes['label'];
|
||||
if ($fk_product) $out.=' ('.$langs->trans("Stock").': '.($arraytypes['stock']>0?$arraytypes['stock']:'?').')';
|
||||
if (($fk_product || ($showstock > 0)) && ($arraytypes['stock'] != 0)) $out.='('.$langs->trans("Stock").':'.$arraytypes['stock'].')';
|
||||
$out.='</option>';
|
||||
}
|
||||
$out.='</select>';
|
||||
|
||||
@@ -57,7 +57,7 @@ $form=new Form($db);
|
||||
$warehouse=new Entrepot($db);
|
||||
|
||||
$sql = "SELECT e.rowid, e.label as ref, e.statut, e.lieu, e.address, e.zip, e.town, e.fk_pays,";
|
||||
$sql.= " SUM(p.pmp * ps.reel) as estimatedvalue, SUM(p.price * ps.reel) as sellvalue";
|
||||
$sql.= " SUM(p.pmp * ps.reel) as estimatedvalue, SUM(p.price * ps.reel) as sellvalue, SUM(ps.reel) as stockqty";
|
||||
$sql.= " FROM ".MAIN_DB_PREFIX."entrepot as e";
|
||||
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_stock as ps ON e.rowid = ps.fk_entrepot";
|
||||
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON ps.fk_product = p.rowid";
|
||||
@@ -94,6 +94,7 @@ if ($result)
|
||||
print "<tr class=\"liste_titre\">";
|
||||
print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"], "e.label","","","",$sortfield,$sortorder);
|
||||
print_liste_field_titre($langs->trans("LocationSummary"),$_SERVER["PHP_SELF"], "e.lieu","","","",$sortfield,$sortorder);
|
||||
print_liste_field_titre($langs->trans("PhysicalStock"), $_SERVER["PHP_SELF"], "stockqty",'','','align="right"',$sortfield,$sortorder);
|
||||
print_liste_field_titre($langs->trans("EstimatedStockValue"), $_SERVER["PHP_SELF"], "e.valo_pmp",'','','align="right"',$sortfield,$sortorder);
|
||||
print_liste_field_titre($langs->trans("EstimatedStockValueSell"), $_SERVER["PHP_SELF"], "",'','','align="right"',$sortfield,$sortorder);
|
||||
print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"], "e.statut",'','','align="right"',$sortfield,$sortorder);
|
||||
@@ -111,7 +112,7 @@ if ($result)
|
||||
print '<input class="flat" type="text" name="search_label" size="10" value="'.dol_escape_htmltag($search_label).'">';
|
||||
print '</td>';
|
||||
|
||||
print '<td class="liste_titre" colspan="2">';
|
||||
print '<td class="liste_titre" colspan="3">';
|
||||
print '</td>';
|
||||
|
||||
print '<td class="liste_titre" align="right">';
|
||||
@@ -128,7 +129,7 @@ if ($result)
|
||||
if ($num)
|
||||
{
|
||||
$entrepot=new Entrepot($db);
|
||||
$total = $totalsell = 0;
|
||||
$total = $totalsell = $totalStock = 0;
|
||||
$var=false;
|
||||
while ($i < min($num,$limit))
|
||||
{
|
||||
@@ -140,6 +141,8 @@ if ($result)
|
||||
print '<td>' . $entrepot->getNomUrl(1) . '</td>';
|
||||
// Location
|
||||
print '<td>'.$objp->lieu.'</td>';
|
||||
// Stock qty
|
||||
print '<td align="right">'.price2num($objp->stockqty,5).'</td>';
|
||||
// PMP value
|
||||
print '<td align="right">';
|
||||
if (price2num($objp->estimatedvalue,'MT')) print price(price2num($objp->estimatedvalue,'MT'),1);
|
||||
@@ -163,6 +166,7 @@ if ($result)
|
||||
|
||||
$total += price2num($objp->estimatedvalue,'MU');
|
||||
$totalsell += price2num($objp->sellvalue,'MU');
|
||||
$totalStock += $objp->stockqty;
|
||||
|
||||
$var=!$var;
|
||||
$i++;
|
||||
@@ -170,6 +174,7 @@ if ($result)
|
||||
|
||||
print '<tr class="liste_total">';
|
||||
print '<td colspan="2" align="right">'.$langs->trans("Total").'</td>';
|
||||
print '<td align="right">'.price2num($totalStock,5).'</td>';
|
||||
print '<td align="right">'.price(price2num($total,'MT'),1,$langs,0,0,-1,$conf->currency).'</td>';
|
||||
print '<td align="right">';
|
||||
if (empty($conf->global->PRODUIT_MULTIPRICES)) print price(price2num($totalsell,'MT'),1,$langs,0,0,-1,$conf->currency);
|
||||
|
||||
Reference in New Issue
Block a user