Skip to content

Commit

Permalink
NEW Can switch product batch management to no management. (#21691)
Browse files Browse the repository at this point in the history
* NEW : When an user unset the batch management of products, transformation of each batch stock mouvement in global stock mouvement

* FIX : Alert on deserialize product

* FIX : Correction of the trad

* Fixing style errors.

* FIX : PR returns

* FIX : using llx_product_batch table

* FIX : langs

* Fixing style errors.

* FIX : $value must be an absolute value

* FIX : init $inventorycode before while loop

* Fixing style errors.

* FIX : "Yes (unique serial number required)" choice must not be available on product edit if its current status batch is "Yes (lot required)"

* Fixing style errors.

* FIX : Just display a message when we change from batch to serial

* Fixing style errors.

* Update card.php

* Update card.php

* Update product.class.php

* Update product.class.php

---------

Co-authored-by: Adrien Raze <adrien.raze@atm-consulting.fr>
Co-authored-by: stickler-ci <support@stickler-ci.com>
Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
  • Loading branch information
4 people authored Oct 23, 2023
1 parent 5d6cf7c commit f46482a
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 5 deletions.
2 changes: 2 additions & 0 deletions htdocs/langs/en_US/products.lang
Original file line number Diff line number Diff line change
Expand Up @@ -432,3 +432,5 @@ ConfirmEditExtrafield = Select the extrafield you want modify
ConfirmEditExtrafieldQuestion = Are you sure you want to modify this extrafield?
ModifyValueExtrafields = Modify value of an extrafield
OrProductsWithCategories=Or products with tags/categories
WarningTransferBatchStockMouvToGlobal = If you want to deserialize this product, all its serialized stock will be transformed into global stock
WarningConvertFromBatchToSerial=If you currently have a quantity higher or equal to 2 for the product, switching to this choice means you will still have a product with different objects of the same batch (while you want a unique serial number). The duplicate will remain until an inventory or a manual stock movement to fix this is done.
4 changes: 4 additions & 0 deletions htdocs/langs/en_US/stocks.lang
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ qtyToTranferLotIsNotEnough=You don't have enough stock, for this lot number, fro
ShowWarehouse=Show warehouse
MovementCorrectStock=Stock correction for product %s
MovementTransferStock=Stock transfer of product %s into another warehouse
BatchStockMouvementAddInGlobal=Batch stock move into global stock (product doesn't use batch anymore)
InventoryCodeShort=Inv./Mov. code
NoPendingReceptionOnSupplierOrder=No pending reception due to open purchase order
ThisSerialAlreadyExistWithDifferentDate=This lot/serial number (<strong>%s</strong>) already exists but with different eatby or sellby date (found <strong>%s</strong> but you enter <strong>%s</strong>).
Expand Down Expand Up @@ -322,6 +323,8 @@ BatchNotFound=Lot / serial not found for this product
StockEntryDate=Date of <br>entry in stock
StockMovementWillBeRecorded=Stock movement will be recorded
StockMovementNotYetRecorded=Stock movement will not be affected by this step


WarningThisWIllAlsoDeleteStock=Warning, this will also destroy all quantities in stock in the warehouse
ValidateInventory=Inventory validation
IncludeSubWarehouse=Include sub-warehouse ?
Expand All @@ -331,3 +334,4 @@ ConfirmDeleteBatch=Are you sure you want to delete lot/serial ?
WarehouseUsage=Warehouse usage
InternalWarehouse=Internal warehouse
ExternalWarehouse=External warehouse

1 change: 1 addition & 0 deletions htdocs/langs/fr_FR/stocks.lang
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ qtyToTranferLotIsNotEnough=Vous n'avez pas assez de stock, pour ce numéro de lo
ShowWarehouse=Afficher entrepôt
MovementCorrectStock=Correction du stock pour le produit %s
MovementTransferStock=Transfert de stock du produit %s dans un autre entrepôt
BatchStockMouvementAddInGlobal=Batch stock move into global stock (product doesn't use batch anymore)
InventoryCodeShort=Code Inv./Mouv.
NoPendingReceptionOnSupplierOrder=Pas de réception en attente consécutive à des commandes fournisseurs
ThisSerialAlreadyExistWithDifferentDate=Ce lot/numéro de série (<strong>%s</strong>) existe déjà mais avec des dates de consommation ou péremption différente (trouvé <strong>%s</strong> mais vous avez entré <strong>%s</strong>).
Expand Down
40 changes: 39 additions & 1 deletion htdocs/product/card.php
Original file line number Diff line number Diff line change
Expand Up @@ -1944,7 +1944,45 @@
if ($object->isProduct() || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
print '<tr><td>'.$langs->trans("ManageLotSerial").'</td><td>';
$statutarray = array('0' => $langs->trans("ProductStatusNotOnBatch"), '1' => $langs->trans("ProductStatusOnBatch"), '2' => $langs->trans("ProductStatusOnSerial"));
print $form->selectarray('status_batch', $statutarray, (GETPOSTISSET('status_batch') ? GETPOST('status_batch') : $object->status_batch));

print $form->selectarray('status_batch', $statutarray, GETPOSTISSET('status_batch') ? GETPOST('status_batch') : $object->status_batch);

print '<span id="statusBatchWarning" class="warning" style="display: none;">';
print img_warning().'&nbsp;'.$langs->trans("WarningConvertFromBatchToSerial").'</span>';

print '<span id="statusBatchMouvToGlobal" class="warning" style="display: none;">';
print img_warning().'&nbsp;'.$langs->trans("WarningTransferBatchStockMouvToGlobal").'</span>';

if ($object->status_batch) {
// Display message to make user know that all batch will be move into global stock
print '<script type="text/javascript">
$(document).ready(function() {
console.log($("#statusBatchWarning"))
$("#status_batch").on("change", function() {
if ($("#status_batch")[0].value == 0){
$("#statusBatchMouvToGlobal").show()
} else {
$("#statusBatchMouvToGlobal").hide()
}
})
})</script>';

// Display message to explain that if the product currently have a quantity higher or equal to 2, switching to this choice means we will still have a product with different objects of the same batch (while we want a unique serial number)
if ($object->status_batch == 1) {
print '<script type="text/javascript">
$(document).ready(function() {
console.log($("#statusBatchWarning"))
$("#status_batch").on("change", function() {
if ($("#status_batch")[0].value == 2){
$("#statusBatchWarning").show()
} else {
$("#statusBatchWarning").hide()
}
})
})</script>';
}
}

print '</td></tr>';
if (!empty($object->status_batch) || !empty($conf->use_javascript_ajax)) {
$langs->load("admin");
Expand Down
41 changes: 39 additions & 2 deletions htdocs/product/class/product.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -1296,6 +1296,42 @@ public function update($id, $user, $notrigger = false, $action = 'update', $upda
}
}

if (!$this->hasbatch() && $this->oldcopy->hasbatch()) {
// Selection of all product stock mouvements that contains batchs
$sql = 'SELECT pb.qty, pb.fk_entrepot, pb.batch FROM '.MAIN_DB_PREFIX.'product_batch as pb';
$sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'product_stock as ps ON (ps.rowid = batch.fk_product_stock)';
$sql.= ' WHERE ps.fk_product = '.(int) $this->id;

$resql = $this->db->query($sql);
if ($resql) {
$inventorycode = dol_print_date(dol_now(), '%Y%m%d%H%M%S');

while ($obj = $this->db->fetch_object($resql)) {
$value = $obj->qty;
$fk_entrepot = $obj->fk_entrepot;
$price = 0;
$dlc = '';
$dluo = '';
$batch = $obj->batch;

// To know how to revert stockMouvement (add or remove)
$addOremove = $value > 0 ? 1 : 0; // 1 if remove, 0 if add
$label = $langs->trans('BatchStockMouvementAddInGlobal');
$res = $this->correct_stock_batch($user, $fk_entrepot, abs($value), $addOremove, $label, $price, $dlc, $dluo, $batch, $inventorycode, '', null, 0, null, true);

if ($res > 0) {
$label = $langs->trans('BatchStockMouvementAddInGlobal');
$res = $this->correct_stock($user, $fk_entrepot, abs($value), (int) empty($addOremove), $label, $price, $inventorycode, '', null, 0);
if ($res < 0) {
$error++;
}
} else {
$error++;
}
}
}
}

// Actions on extra fields
if (!$error) {
$result = $this->insertExtraFields();
Expand Down Expand Up @@ -5535,9 +5571,10 @@ public function correct_stock($user, $id_entrepot, $nbpiece, $movement, $label =
* @param int $origin_id Origin id of element
* @param int $disablestockchangeforsubproduct Disable stock change for sub-products of kit (usefull only if product is a subproduct)
* @param Extrafields $extrafields Array of extrafields
* @param boolean $force_update_batch Force update batch
* @return int <0 if KO, >0 if OK
*/
public function correct_stock_batch($user, $id_entrepot, $nbpiece, $movement, $label = '', $price = 0, $dlc = '', $dluo = '', $lot = '', $inventorycode = '', $origin_element = '', $origin_id = null, $disablestockchangeforsubproduct = 0, $extrafields = null)
public function correct_stock_batch($user, $id_entrepot, $nbpiece, $movement, $label = '', $price = 0, $dlc = '', $dluo = '', $lot = '', $inventorycode = '', $origin_element = '', $origin_id = null, $disablestockchangeforsubproduct = 0, $extrafields = null, $force_update_batch = false)
{
// phpcs:enable
if ($id_entrepot) {
Expand All @@ -5557,7 +5594,7 @@ public function correct_stock_batch($user, $id_entrepot, $nbpiece, $movement, $l

$movementstock = new MouvementStock($this->db);
$movementstock->setOrigin($origin_element, $origin_id); // Set ->origin_type and ->fk_origin
$result = $movementstock->_create($user, $this->id, $id_entrepot, $op[$movement], $movement, $price, $label, $inventorycode, '', $dlc, $dluo, $lot, false, 0, $disablestockchangeforsubproduct);
$result = $movementstock->_create($user, $this->id, $id_entrepot, $op[$movement], $movement, $price, $label, $inventorycode, '', $dlc, $dluo, $lot, false, 0, $disablestockchangeforsubproduct, 0, $force_update_batch);

if ($result >= 0) {
if ($extrafields) {
Expand Down
5 changes: 3 additions & 2 deletions htdocs/product/stock/class/mouvementstock.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,10 @@ public function __construct($db)
* @param int $id_product_batch Id product_batch (when skip_batch is false and we already know which record of product_batch to use)
* @param int $disablestockchangeforsubproduct Disable stock change for sub-products of kit (usefull only if product is a subproduct)
* @param int $donotcleanemptylines Do not clean lines in stock table with qty=0 (because we want to have this done by the caller)
* @param boolean $force_update_batch Allows to add batch stock movement even if $product doesn't use batch anymore
* @return int <0 if KO, 0 if fk_product is null or product id does not exists, >0 if OK
*/
public function _create($user, $fk_product, $entrepot_id, $qty, $type, $price = 0, $label = '', $inventorycode = '', $datem = '', $eatby = '', $sellby = '', $batch = '', $skip_batch = false, $id_product_batch = 0, $disablestockchangeforsubproduct = 0, $donotcleanemptylines = 0)
public function _create($user, $fk_product, $entrepot_id, $qty, $type, $price = 0, $label = '', $inventorycode = '', $datem = '', $eatby = '', $sellby = '', $batch = '', $skip_batch = false, $id_product_batch = 0, $disablestockchangeforsubproduct = 0, $donotcleanemptylines = 0, $force_update_batch = false)
{
// phpcs:enable
global $conf, $langs;
Expand Down Expand Up @@ -559,7 +560,7 @@ public function _create($user, $fk_product, $entrepot_id, $qty, $type, $price =
}

// Update detail of stock for the lot.
if (!$error && isModEnabled('productbatch') && $product->hasbatch() && !$skip_batch) {
if (!$error && isModEnabled('productbatch') && (($product->hasbatch() && !$skip_batch) || $force_update_batch)) {
if ($id_product_batch > 0) {
$result = $this->createBatch($id_product_batch, $qty);
if ($result == -2 && $fk_product_stock > 0) { // The entry for this product batch does not exists anymore, bu we already have a llx_product_stock, so we recreate the batch entry in product_batch
Expand Down

0 comments on commit f46482a

Please sign in to comment.