From 211db12c3ee77ca24a7515fc6f262dea60bf0d7e Mon Sep 17 00:00:00 2001 From: VESSILLER Date: Fri, 22 Nov 2024 16:15:36 +0100 Subject: [PATCH] Add option to pre-select the batch with the earliest sell-by/eat-by date when creating a shipment --- htdocs/admin/expedition.php | 7 +++ htdocs/expedition/dispatch.php | 78 ++++++++++++++++++++------------ htdocs/langs/en_US/sendings.lang | 1 + 3 files changed, 57 insertions(+), 29 deletions(-) diff --git a/htdocs/admin/expedition.php b/htdocs/admin/expedition.php index 45c74c98523f2..ab7001ffd7138 100644 --- a/htdocs/admin/expedition.php +++ b/htdocs/admin/expedition.php @@ -456,6 +456,13 @@ print ajax_constantonoff('SHIPPING_DISPLAY_STOCK_ENTRY_DATE'); print ''; +print ''; +print ''.$langs->trans('SHIPPING_SELL_EAT_BY_DATE_PRE_SELECT_EARLIEST'); +print ''; +print ''; +print ajax_constantonoff('SHIPPING_SELL_EAT_BY_DATE_PRE_SELECT_EARLIEST'); +print ''; + $substitutionarray = pdf_getSubstitutionArray($langs, null, null, 2); $substitutionarray['__(AnyTranslationKey)__'] = $langs->trans("Translation"); $htmltext = ''.$langs->trans("AvailableVariables").':
'; diff --git a/htdocs/expedition/dispatch.php b/htdocs/expedition/dispatch.php index 1ac8ee123d68d..d73c7d802db2e 100644 --- a/htdocs/expedition/dispatch.php +++ b/htdocs/expedition/dispatch.php @@ -830,8 +830,8 @@ $child_product = $conf->cache['product'][$child_product_id]; } - // sub-product is a batch - $product_batch_first = null; + // sub-product is a batch and get selected batch from database or all batches for selected warehouse + $batch_list = array(); if ($is_mod_batch_enabled && $child_product->hasbatch()) { // search if batch is not exist in shipment lines $sql_line_batch_search = "SELECT eb.rowid, eb.qty, eb.batch, eb.sellby, eb.eatby"; @@ -840,44 +840,41 @@ $res_line_batch_search = $db->query($sql_line_batch_search); if ($res_line_batch_search) { while ($obj_batch = $db->fetch_object($res_line_batch_search)) { - $obj_batch->eatby = dol_print_date($obj_batch->eatby, "day"); - $obj_batch->sellby = dol_print_date($obj_batch->sellby, "day"); - - if ($product_batch_first === null) { - $product_batch_first = $obj_batch; - } else { - break; - } + $obj_batch->eatby = dol_print_date($obj_batch->eatby, 'day'); + $obj_batch->sellby = dol_print_date($obj_batch->sellby, 'day'); + $batch_list[] = $obj_batch; } $db->free($res_line_batch_search); } // no batch found for this sub-product so retrieve all batch numbers for this sub-product id and warehouse id - if ($product_batch_first === null) { - $product_batch_sort_field = 'pl.sellby,pl.eatby,pb.qty,pl.rowid'; // order by sell by (DLC), eat by (DLUO), qty and rowid - $product_batch_sort_order = 'ASC,ASC,ASC,ASC'; + if (empty($batch_list)) { + $batch_sort_field_arr = array(); + $batch_sort_order_arr = array(); + if ($is_sell_by_enabled) { + $batch_sort_field_arr[] = 'pl.sellby'; // order by sell by (DLC) + $batch_sort_order_arr[] = 'ASC'; + } + if ($is_eat_by_enabled) { + $batch_sort_field_arr[] = 'pl.eatby'; // order by eat by (DLUO) + $batch_sort_order_arr[] = 'ASC'; + } + $batch_sort_field_arr[] = 'pb.qty'; // order by qty + $batch_sort_order_arr[] = 'ASC'; + $batch_sort_field_arr[] = 'pl.rowid'; // order by rowid + $batch_sort_order_arr[] = 'ASC'; $product_batch = new Productbatch($db); - $product_batch_result = $product_batch->findAllForProduct($child_product_id, $line_obj->fk_warehouse, (getDolGlobalInt('STOCK_ALLOW_NEGATIVE_TRANSFER') ? null : 0), $product_batch_sort_field, $product_batch_sort_order); + $product_batch_result = $product_batch->findAllForProduct($child_product_id, $line_obj->fk_warehouse, (getDolGlobalInt('STOCK_ALLOW_NEGATIVE_TRANSFER') ? null : 0), implode(',', $batch_sort_field_arr), implode(',', $batch_sort_order_arr)); if (is_array($product_batch_result)) { foreach ($product_batch_result as $batch_current) { - $batch_current->eatby = dol_print_date($batch_current->eatby, "day"); - $batch_current->sellby = dol_print_date($batch_current->sellby, "day"); - - if ($product_batch_first === null) { - $product_batch_first = $batch_current; - } else { - break; - } + $batch_current->eatby = dol_print_date($batch_current->eatby, 'day'); + $batch_current->sellby = dol_print_date($batch_current->sellby, 'day'); + $batch_list[] = $batch_current; } } } } - if (is_object($product_batch_first)) { - // get first lot / serial of this warehouse - $line_obj->batch = $product_batch_first->batch; - $line_obj->sellby = $product_batch_first->sellby; - $line_obj->eatby = $product_batch_first->eatby; - } + $line_obj->batch_list = $batch_list; // determine if line is virtual product and stock is managed $line_obj->iskit = 0; @@ -920,7 +917,30 @@ $can_update_stock = empty($objd->iskit) && !empty($objd->incdec); $suffix = $child_line_id.$child_suffix; - if ($is_mod_batch_enabled && (!empty($objd->batch) || (is_null($objd->batch) && $tmpproduct->status_batch > 0))) { + // set default batch values for this dispatched line (lot/serial number of virtual product) + $dispatch_line_batch_current = null; + if (!empty($objd->batch_list)) { + $dispatch_line_batch_count = count($objd->batch_list); + // if only one batch found, this batch is pre-selected + if ($dispatch_line_batch_count >= 1) { + if ($dispatch_line_batch_count == 1 || getDolGlobalInt('SHIPPING_SELL_EAT_BY_DATE_PRE_SELECT_EARLIEST')) { + $dispatch_line_batch_current = current($objd->batch_list); + } + } + } + if (is_object($dispatch_line_batch_current)) { + $objd->batch = $dispatch_line_batch_current->batch; + $objd->eatby = $dispatch_line_batch_current->eatby; + $objd->sellby = $dispatch_line_batch_current->sellby; + } + + if ($is_mod_batch_enabled + && ( + !empty($objd->batch) + || (is_null($objd->batch) && $tmpproduct->status_batch > 0) + || !empty($objd->batch_list) + ) + ) { $type = 'batch'; // Enable hooks to append additional columns diff --git a/htdocs/langs/en_US/sendings.lang b/htdocs/langs/en_US/sendings.lang index 69fcb28e86f4e..fd0cef3d6e43f 100644 --- a/htdocs/langs/en_US/sendings.lang +++ b/htdocs/langs/en_US/sendings.lang @@ -85,3 +85,4 @@ ShipmentDistribution=Shipment distribution ErrorTooManyCombinationBatchcode=No dispatch for line %s as too many combinations of warehouse, product, batch code was found (%s). ErrorNoCombinationBatchcode=Could not save the line %s as the combination of warehouse-product-lot/serial (%s, %s, %s) was not found in stock. ErrorTooMuchShipped=Quantity shipped should not be greater than quantity ordered for line %s +SHIPPING_SELL_EAT_BY_DATE_PRE_SELECT_EARLIEST=Pre-select the batch/serial number with the earliest sell-by/eat-by date when creating a shipment