Merge pull request #17784 from atm-john/new_expedition_warehouse_auto_picking

NEW/FIX : Allow auto picking for child warehouse and taking into account of the quantities already affected in list
This commit is contained in:
Laurent Destailleur 2021-06-20 12:55:30 +02:00 committed by GitHub
commit 23c0edf854
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 86 additions and 12 deletions

View File

@ -1020,6 +1020,9 @@ if ($action == 'create') {
// Load shipments already done for same order
$object->loadExpeditions();
$alreadyQtyBatchSetted = $alreadyQtySetted = array();
if ($numAsked) {
print '<tr class="liste_titre">';
print '<td>'.$langs->trans("Description").'</td>';
@ -1044,6 +1047,15 @@ if ($action == 'create') {
print "</tr>\n";
}
$warehouse_id = GETPOST('entrepot_id', 'int');
$warehousePicking = array();
// get all warehouse children for picking
if ($warehouse_id > 0) {
$warehousePicking[] = $warehouse_id;
$warehouseObj = new Entrepot($db);
$warehouseObj->get_children_warehouses($warehouse_id, $warehousePicking);
}
$indiceAsked = 0;
while ($indiceAsked < $numAsked) {
$product = new Product($db);
@ -1142,10 +1154,9 @@ if ($action == 'create') {
} else {
$quantityToBeDelivered = $quantityAsked - $quantityDelivered;
}
$warehouse_id = GETPOST('entrepot_id', 'int');
$warehouseObject = null;
if ($warehouse_id > 0 || !($line->fk_product > 0) || empty($conf->stock->enabled)) { // If warehouse was already selected or if product is not a predefined, we go into this part with no multiwarehouse selection
if (count($warehousePicking) == 1 || !($line->fk_product > 0) || empty($conf->stock->enabled)) { // If warehouse was already selected or if product is not a predefined, we go into this part with no multiwarehouse selection
print '<!-- Case warehouse already known or product not a predefined product -->';
//ship from preselected location
$stock = + $product->stock_warehouse[$warehouse_id]->real; // Convert to number
@ -1293,6 +1304,7 @@ if ($action == 'create') {
$subj = 0;
// Define nb of lines suggested for this order line
$nbofsuggested = 0;
foreach ($product->stock_warehouse as $warehouse_id => $stock_warehouse) {
if ($stock_warehouse->real > 0) {
$nbofsuggested++;
@ -1300,6 +1312,11 @@ if ($action == 'create') {
}
$tmpwarehouseObject = new Entrepot($db);
foreach ($product->stock_warehouse as $warehouse_id => $stock_warehouse) { // $stock_warehouse is product_stock
if (!empty($warehousePicking) && !in_array($warehouse_id, $warehousePicking)) {
// if a warehouse was selected by user, picking is limited to this warehouse and his children
continue;
}
$tmpwarehouseObject->fetch($warehouse_id);
if ($stock_warehouse->real > 0) {
$stock = + $stock_warehouse->real; // Convert it to number
@ -1309,7 +1326,31 @@ if ($action == 'create') {
print '<!-- subj='.$subj.'/'.$nbofsuggested.' --><tr '.((($subj + 1) == $nbofsuggested) ? $bc[$var] : '').'>';
print '<td colspan="3" ></td><td class="center"><!-- qty to ship (no lot management for product line indiceAsked='.$indiceAsked.') -->';
if ($line->product_type == Product::TYPE_PRODUCT || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
print '<input name="qtyl'.$indiceAsked.'_'.$subj.'" id="qtyl'.$indiceAsked.'" type="text" size="4" value="'.$deliverableQty.'">';
if (isset($alreadyQtySetted[$line->fk_product][intval($warehouse_id)])) {
$deliverableQty = min($quantityToBeDelivered, $stock - $alreadyQtySetted[$line->fk_product][intval($warehouse_id)]);
} else {
if (!isset($alreadyQtySetted[$line->fk_product])) {
$alreadyQtySetted[$line->fk_product] = array();
}
$deliverableQty = min($quantityToBeDelivered, $stock);
}
if ($deliverableQty < 0) $deliverableQty = 0;
$tooltip = '';
if (!empty($alreadyQtySetted[$line->fk_product][intval($warehouse_id)])) {
$tooltip = ' class="classfortooltip" title="'.$langs->trans('StockQuantitiesAlreadyAllocatedOnPreviousLines').' : '.$alreadyQtySetted[$line->fk_product][intval($warehouse_id)].'" ';
}
$alreadyQtySetted[$line->fk_product][intval($warehouse_id)] = $deliverableQty + $alreadyQtySetted[$line->fk_product][intval($warehouse_id)];
$inputName = 'qtyl'.$indiceAsked.'_'.$subj;
if (GETPOSTISSET($inputName)) {
$deliverableQty = GETPOST($inputName, 'int');
}
print '<input '.$tooltip.' 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");
@ -1366,27 +1407,50 @@ if ($action == 'create') {
$tmpwarehouseObject = new Entrepot($db);
$productlotObject = new Productlot($db);
// Define nb of lines suggested for this order line
$nbofsuggested = 0;
foreach ($product->stock_warehouse as $warehouse_id => $stock_warehouse) {
if (($stock_warehouse->real > 0) && (count($stock_warehouse->detail_batch))) {
foreach ($stock_warehouse->detail_batch as $dbatch) {
$nbofsuggested++;
}
$nbofsuggested+=count($stock_warehouse->detail_batch);
}
}
foreach ($product->stock_warehouse as $warehouse_id => $stock_warehouse) {
$tmpwarehouseObject->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);
if ($deliverableQty < 0) {
$deliverableQty = 0;
if (isset($alreadyQtyBatchSetted[$line->fk_product][$dbatch->batch][intval($warehouse_id)])) {
$deliverableQty = min($quantityToBeDelivered, $batchStock - $alreadyQtyBatchSetted[$line->fk_product][$dbatch->batch][intval($warehouse_id)]);
} else {
if (!isset($alreadyQtyBatchSetted[$line->fk_product])) {
$alreadyQtyBatchSetted[$line->fk_product] = array();
}
if (!isset($alreadyQtyBatchSetted[$line->fk_product][$dbatch->batch])) {
$alreadyQtyBatchSetted[$line->fk_product][$dbatch->batch] = array();
}
$deliverableQty = min($quantityToBeDelivered, $batchStock);
}
if ($deliverableQty < 0) $deliverableQty = 0;
$inputName = 'qtyl'.$indiceAsked.'_'.$subj;
if (GETPOSTISSET($inputName)) {
$deliverableQty = GETPOST($inputName, 'int');
}
$tooltipClass = $tooltipTitle = '';
if (!empty($alreadyQtyBatchSetted[$line->fk_product][$dbatch->batch][intval($warehouse_id)])) {
$tooltipClass = ' classfortooltip';
$tooltipTitle = $langs->trans('StockQuantitiesAlreadyAllocatedOnPreviousLines').' : '.$alreadyQtyBatchSetted[$line->fk_product][$dbatch->batch][intval($warehouse_id)];
}
$alreadyQtyBatchSetted[$line->fk_product][$dbatch->batch][intval($warehouse_id)] = $deliverableQty + $alreadyQtyBatchSetted[$line->fk_product][$dbatch->batch][intval($warehouse_id)];
print '<!-- subj='.$subj.'/'.$nbofsuggested.' --><tr '.((($subj + 1) == $nbofsuggested) ? $bc[$var] : '').'><td colspan="3"></td><td class="center">';
print '<input class="qtyl" name="qtyl'.$indiceAsked.'_'.$subj.'" id="qtyl'.$indiceAsked.'_'.$subj.'" type="text" size="4" value="'.$deliverableQty.'">';
print '<input class="qtyl '.$tooltipClass.'" title="'.$tooltipTitle.'" name="'.$inputName.'" id="'.$inputName.'" type="text" size="4" value="'.$deliverableQty.'">';
print '</td>';
print '<td class="left">';

View File

@ -30,3 +30,4 @@ NonShippable=Not Shippable
ShowShippableStatus=Show shippable status
ShowReceiving=Show delivery receipt
NonExistentOrder=Nonexistent order
StockQuantitiesAlreadyAllocatedOnPreviousLines = Stock quantities already allocated on previous lines

View File

@ -30,3 +30,4 @@ NonShippable=Non expédiable
ShowShippableStatus=Afficher le statut Expédiable
ShowReceiving=Afficher le bon de réception
NonExistentOrder=Commande inexistante
StockQuantitiesAlreadyAllocatedOnPreviousLines = Qtés de stock déja attribuées sur une ou des lignes précédentes

View File

@ -5192,6 +5192,8 @@ class Product extends CommonObject
$sql .= " AND w.statut IN (".$this->db->sanitize(implode(',', $warehouseStatus)).")";
}
$sql .= " ORDER BY ps.reel ".(!empty($conf->global->DO_NOT_TRY_TO_DEFRAGMENT_STOCKS_WAREHOUSE)?'DESC':'ASC'); // Note : qty ASC is important for expedition card, to avoid stock fragmentation;
dol_syslog(get_class($this)."::load_stock", LOG_DEBUG);
$result = $this->db->query($sql);
if ($result) {

View File

@ -436,7 +436,7 @@ class Productbatch extends CommonObject
*/
public static function findAll($db, $fk_product_stock, $with_qty = 0, $fk_product = 0)
{
global $langs;
global $langs, $conf;
$ret = array();
$sql = "SELECT";
@ -462,6 +462,12 @@ class Productbatch extends CommonObject
$sql .= " AND t.qty <> 0";
}
$sql .= " ORDER BY ";
// TODO : use product lifo and fifo when product will implement it
if ($fk_product > 0) { $sql .= "pl.eatby ASC, pl.sellby ASC, "; }
$sql .= "t.eatby ASC, t.sellby ASC ";
$sql .= ", t.qty ".(!empty($conf->global->DO_NOT_TRY_TO_DEFRAGMENT_STOCKS_WAREHOUSE)?'DESC':'ASC'); // Note : qty ASC is important for expedition card, to avoid stock fragmentation
dol_syslog("productbatch::findAll", LOG_DEBUG);
$resql = $db->query($sql);
if ($resql) {