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:
commit
23c0edf854
@ -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">';
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user