Skip to content

Commit

Permalink
Add option to pre-select the batch with the earliest sell-by/eat-by d…
Browse files Browse the repository at this point in the history
…ate when creating a shipment
  • Loading branch information
lvessiller-opendsi committed Nov 22, 2024
1 parent f763894 commit 211db12
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 29 deletions.
7 changes: 7 additions & 0 deletions htdocs/admin/expedition.php
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,13 @@
print ajax_constantonoff('SHIPPING_DISPLAY_STOCK_ENTRY_DATE');
print '</td></tr>';

print '<tr class="oddeven">';
print '<td>'.$langs->trans('SHIPPING_SELL_EAT_BY_DATE_PRE_SELECT_EARLIEST');
print '</td>';
print '<td>';
print ajax_constantonoff('SHIPPING_SELL_EAT_BY_DATE_PRE_SELECT_EARLIEST');
print '</td></tr>';

$substitutionarray = pdf_getSubstitutionArray($langs, null, null, 2);
$substitutionarray['__(AnyTranslationKey)__'] = $langs->trans("Translation");
$htmltext = '<i>'.$langs->trans("AvailableVariables").':<br>';
Expand Down
78 changes: 49 additions & 29 deletions htdocs/expedition/dispatch.php
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions htdocs/langs/en_US/sendings.lang
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 211db12

Please sign in to comment.