From 1f64b09430aadb5e7670bc5c8973b1b77b33519d Mon Sep 17 00:00:00 2001 From: Lucas Marcouiller Date: Thu, 21 Oct 2021 18:07:54 +0200 Subject: [PATCH 01/12] WIP : fix inventory scan --- htdocs/core/class/html.formother.class.php | 5 +- htdocs/langs/en_US/productbatch.lang | 3 +- htdocs/langs/fr_FR/productbatch.lang | 2 +- .../product/inventory/ajax/ajax.inventory.php | 47 ---------- .../inventory/ajax/searchfrombarcode.php | 54 +++++++++++ htdocs/product/inventory/inventory.php | 94 +++++++++---------- 6 files changed, 108 insertions(+), 97 deletions(-) delete mode 100644 htdocs/product/inventory/ajax/ajax.inventory.php create mode 100644 htdocs/product/inventory/ajax/searchfrombarcode.php diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index 99ee1b6af9b..1d8dd1db08e 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -77,7 +77,10 @@ class FormOther $out .= ' Scan a product barcode
'; $out .= ' Scan a product lot or serial number
'; - $out .= $langs->trans("QtyToAddAfterBarcodeScan").'
'; + $stringaddbarcode = $langs->trans("QtyToAddAfterBarcodeScan","tmphtml"); + $htmltoreplaceby = ''; + $stringaddbarcode = str_replace("tmphtml",$htmltoreplaceby,$stringaddbarcode); + $out .= $stringaddbarcode.'
'; $out .= ''; /*print '
'.$langs->trans("or").'
'; diff --git a/htdocs/langs/en_US/productbatch.lang b/htdocs/langs/en_US/productbatch.lang index 71e44e8f281..dd1e0ea4027 100644 --- a/htdocs/langs/en_US/productbatch.lang +++ b/htdocs/langs/en_US/productbatch.lang @@ -30,7 +30,7 @@ ManageLotMask=Custom mask CustomMasks=Option to define a different numbering mask for each product BatchLotNumberingModules=Numbering rule for automatic generation of lot number BatchSerialNumberingModules=Numbering rule for automatic generation of serial number (for products with property 1 unique lot/serial for each product) -QtyToAddAfterBarcodeScan=Qty to add for each barcode/lot/serial scanned +QtyToAddAfterBarcodeScan=Qty to %s for each barcode/lot/serial scanned LifeTime=Life span (in days) EndOfLife=End of life ManufacturingDate=Manufacturing date @@ -42,3 +42,4 @@ HideLots=Hide lots #Traceability - qc status OutOfOrder=Out of order InWorkingOrder=In working order +ToReplace=Replace \ No newline at end of file diff --git a/htdocs/langs/fr_FR/productbatch.lang b/htdocs/langs/fr_FR/productbatch.lang index ccd5e43d3d7..bcef04e75ed 100644 --- a/htdocs/langs/fr_FR/productbatch.lang +++ b/htdocs/langs/fr_FR/productbatch.lang @@ -30,7 +30,7 @@ ManageLotMask=Masque personnalisé CustomMasks=Option pour définir un masque de numérotation différent pour chaque produit BatchLotNumberingModules=Règle de numérotation pour la génération automatique de numéro de lot BatchSerialNumberingModules=Règle de numérotation pour la génération automatique de numéro de série (pour les produits avec propriété 1 lot/série unique pour chaque produit) -QtyToAddAfterBarcodeScan=Quantité à ajouter pour chaque code à barres/lot/série scanné +QtyToAddAfterBarcodeScan=Quantité à %s pour chaque code à barres/lot/série scanné LifeTime=Durée de vie (en jours) EndOfLife=Fin d'utilisation ManufacturingDate=Date de fabrication diff --git a/htdocs/product/inventory/ajax/ajax.inventory.php b/htdocs/product/inventory/ajax/ajax.inventory.php deleted file mode 100644 index 920607f4c1e..00000000000 --- a/htdocs/product/inventory/ajax/ajax.inventory.php +++ /dev/null @@ -1,47 +0,0 @@ -rights->stock->creer)) { - echo -1; exit; - } - - $fk_det_inventory = GETPOST('fk_det_inventory'); - - $det = new InventoryLine($db); - if ($det->fetch($fk_det_inventory)) { - $det->qty_view += GETPOST('qty'); - $res = $det->update($user); - - echo $det->qty_view; - } else { - echo -2; - } - - break; - - case 'pmp': - if (empty($user->rights->stock->creer) || empty($user->rights->stock->changePMP)) { - echo -1; exit; - } - - $fk_det_inventory = GETPOST('fk_det_inventory'); - - $det = new InventoryLine($db); - if ($det->fetch($fk_det_inventory)) { - $det->new_pmp = price2num(GETPOST('pmp')); - $det->update($user); - - echo $det->new_pmp; - } else { - echo -2; - } - - break; -} diff --git a/htdocs/product/inventory/ajax/searchfrombarcode.php b/htdocs/product/inventory/ajax/searchfrombarcode.php new file mode 100644 index 00000000000..259aa5999f6 --- /dev/null +++ b/htdocs/product/inventory/ajax/searchfrombarcode.php @@ -0,0 +1,54 @@ +. + */ + +/** + * \file /htdocs/product/inventory/ajax/searchfrombarcode.php + * \brief File to make Ajax action on product and stock + */ + +if (!defined('NOTOKENRENEWAL')) { + define('NOTOKENRENEWAL', '1'); // Disables token renewal +} +if (!defined('NOREQUIREHTML')) { + define('NOREQUIREHTML', '1'); +} +if (!defined('NOREQUIREAJAX')) { + define('NOREQUIREAJAX', '1'); +} +if (!defined('NOREQUIRESOC')) { + define('NOREQUIRESOC', '1'); +} +if (!defined('NOCSRFCHECK')) { + define('NOCSRFCHECK', '1'); +} +// Do not check anti CSRF attack test +if (!defined('NOREQUIREMENU')) { + define('NOREQUIREMENU', '1'); +} +// If there is no need to load and show top and left menu +if (!defined("NOLOGIN")) { + define("NOLOGIN", '1'); +} +if (!defined('NOIPCHECK')) { + define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip +} +if (!defined('NOBROWSERNOTIF')) { + define('NOBROWSERNOTIF', '1'); +} +require '../../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/product/inventory/class/inventory.class.php'; + diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index 9a4d61209ba..9445e7896c6 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -542,6 +542,7 @@ if ($object->id > 0) { print ''; } include DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; $formother = new FormOther($db); - print $formother->getHTMLScannerForm(); + print $formother->getHTMLScannerForm("barcodescannerjs"); } //Call method to undo changes in real qty From 4d2b96d0294cf9fbf36fb08df277368f22762e13 Mon Sep 17 00:00:00 2001 From: Lucas Marcouiller Date: Thu, 21 Oct 2021 18:08:20 +0200 Subject: [PATCH 02/12] fix inventory scan --- htdocs/core/class/html.formother.class.php | 4 ++-- htdocs/product/inventory/ajax/searchfrombarcode.php | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index 1d8dd1db08e..d1f50889182 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -77,9 +77,9 @@ class FormOther $out .= ' Scan a product barcode
'; $out .= ' Scan a product lot or serial number
'; - $stringaddbarcode = $langs->trans("QtyToAddAfterBarcodeScan","tmphtml"); + $stringaddbarcode = $langs->trans("QtyToAddAfterBarcodeScan", "tmphtml"); $htmltoreplaceby = ''; - $stringaddbarcode = str_replace("tmphtml",$htmltoreplaceby,$stringaddbarcode); + $stringaddbarcode = str_replace("tmphtml", $htmltoreplaceby, $stringaddbarcode); $out .= $stringaddbarcode.'
'; $out .= ''; diff --git a/htdocs/product/inventory/ajax/searchfrombarcode.php b/htdocs/product/inventory/ajax/searchfrombarcode.php index 259aa5999f6..7ee9d2b6be9 100644 --- a/htdocs/product/inventory/ajax/searchfrombarcode.php +++ b/htdocs/product/inventory/ajax/searchfrombarcode.php @@ -51,4 +51,3 @@ if (!defined('NOBROWSERNOTIF')) { } require '../../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/product/inventory/class/inventory.class.php'; - From 56ff2412c1712c39d3ecee14b2fd22ed107eb46c Mon Sep 17 00:00:00 2001 From: Lucas Marcouiller Date: Fri, 22 Oct 2021 16:39:42 +0200 Subject: [PATCH 03/12] start code to searchfrmbarcode --- .../inventory/ajax/searchfrombarcode.php | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/htdocs/product/inventory/ajax/searchfrombarcode.php b/htdocs/product/inventory/ajax/searchfrombarcode.php index 7ee9d2b6be9..73b1943f4c7 100644 --- a/htdocs/product/inventory/ajax/searchfrombarcode.php +++ b/htdocs/product/inventory/ajax/searchfrombarcode.php @@ -51,3 +51,29 @@ if (!defined('NOBROWSERNOTIF')) { } require '../../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/product/inventory/class/inventory.class.php'; + +$action = GETPOST("action", "alpha"); +$barcode = GETPOST("barcode", "aZ09"); +$response = ""; +$fk_entrepot = -1; +if ($action == "existbarcode" && !empty($barcode)) { + $sql = "SELECT *"; + $sql .= " FROM ".MAIN_DB_PREFIX."product_stock as ps JOIN ".MAIN_DB_PREFIX."product as p ON ps.fk_product = p.rowid"; + " WHERE p.barcode = '".$db->escape($barcode)."'"; + $result = $db->query($sql); + if ($result) { + $objecttab = $db->fetch_row($resql); + $nbline = $db->num_rows($resql); + for ($i=0; $i < $nbline; $i++) { + if ($fk_entrepot != $objecttab[$i]) { + // code... + } + } + } else { + $response = "No results found for barcode"; + } +} else { + $response = "Error on action"; +} + +echo $response; From ae78bed41d6ca6de523859676a6eaba37fb6fce6 Mon Sep 17 00:00:00 2001 From: Lucas Marcouiller Date: Sat, 23 Oct 2021 14:36:31 +0200 Subject: [PATCH 04/12] call to ajax file --- htdocs/product/inventory/inventory.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index 9445e7896c6..f2702fbc0db 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -600,6 +600,16 @@ if ($object->id > 0) { function barcodeserialforproduct(textarray,tabproduct,barcodeproductqty,selectaddorreplace,mode,autodetect=false){ textarray.forEach(function(element,index){ + $.ajax({ url: \''.DOL_URL_ROOT.'/product/inventory/ajax/searchfrombarcode.php\', + data: { "action":"existbarcode","barcode":element}, + type: \'POST\', + success: function(response) { + console.log("test+1"); + }, + error : function(output) { + console.error("Error on Fetch of KM articles"); + }, + }); console.log("Product "+(index+=1)+": "+element); BarCodeDoesNotExist=0; tabproduct.forEach(product => { From 694ce9be17f09697d6eb9aa604ac55933682cd07 Mon Sep 17 00:00:00 2001 From: lmarcouiller Date: Mon, 15 Nov 2021 14:23:52 +0100 Subject: [PATCH 05/12] update inventory --- .../inventory/ajax/searchfrombarcode.php | 20 ++++-- htdocs/product/inventory/inventory.php | 67 ++++++++++--------- 2 files changed, 47 insertions(+), 40 deletions(-) diff --git a/htdocs/product/inventory/ajax/searchfrombarcode.php b/htdocs/product/inventory/ajax/searchfrombarcode.php index 73b1943f4c7..559bf8b72da 100644 --- a/htdocs/product/inventory/ajax/searchfrombarcode.php +++ b/htdocs/product/inventory/ajax/searchfrombarcode.php @@ -50,23 +50,29 @@ if (!defined('NOBROWSERNOTIF')) { define('NOBROWSERNOTIF', '1'); } require '../../../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/product/inventory/class/inventory.class.php'; +//require_once DOL_DOCUMENT_ROOT.'/product/inventory/class/inventory.class.php'; $action = GETPOST("action", "alpha"); $barcode = GETPOST("barcode", "aZ09"); +$product = GETPOST("product"); $response = ""; -$fk_entrepot = -1; +$fk_entrepot = GETPOST("fk_entrepot", "int"); if ($action == "existbarcode" && !empty($barcode)) { - $sql = "SELECT *"; + $sql = "SELECT ps.fk_entrepot, ps.fk_product, p.barcode"; $sql .= " FROM ".MAIN_DB_PREFIX."product_stock as ps JOIN ".MAIN_DB_PREFIX."product as p ON ps.fk_product = p.rowid"; - " WHERE p.barcode = '".$db->escape($barcode)."'"; + $sql .= " WHERE p.barcode = '".$db->escape($barcode)."'"; + if (!empty($fk_entrepot)) { + $sql .= "AND ps.fk_entrepot = '".$db->escape($fk_entrepot)."'"; + } $result = $db->query($sql); if ($result) { - $objecttab = $db->fetch_row($resql); $nbline = $db->num_rows($resql); for ($i=0; $i < $nbline; $i++) { - if ($fk_entrepot != $objecttab[$i]) { - // code... + $object = $db->fetch_object($resql); + if ($barcode == $object->barcode) { + if (!empty($object->fk_entrepot) && $product["Warehouse"] == $object->fk_entrepot) { + //si warehouse !=$object->fk_entrepot erreur + } } } } else { diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index f2702fbc0db..8adf1ebc67c 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -572,21 +572,23 @@ if ($object->id > 0) { } tabproduct.push({\'Id\':id,\'Warehouse\':warehouse,\'Barcode\':productbarcode,\'Batch\':productbatchcode,\'Qty\':productinput}); }) - switch(barcodemode){ - case "barcodeforautodetect": - barcodeserialforproduct(textarray,tabproduct,barcodeproductqty,selectaddorreplace,"barcode",true); - barcodeserialforproduct(textarray,tabproduct,barcodeproductqty,selectaddorreplace,"lotserial",true); - break; - case "barcodeforproduct": //TODO: create product !exist + ajout - barcodeserialforproduct(textarray,tabproduct,barcodeproductqty,selectaddorreplace,"barcode"); - break; - case "barcodeforlotserial": - barcodeserialforproduct(textarray,tabproduct,barcodeproductqty,selectaddorreplace,"lotserial"); - break; - default: - alert("'.$langs->trans("ErrorWrongBarcodemode").' \""+barcodemode+"\""); - throw"'.$langs->trans('ErrorWrongBarcodemode').' \""+barcodemode+"\""; - } + tabproduct.forEach(product => { + switch(barcodemode){ + case "barcodeforautodetect": + barcodeserialforproduct(textarray,product,barcodeproductqty,selectaddorreplace,"barcode",true); + barcodeserialforproduct(textarray,product,barcodeproductqty,selectaddorreplace,"lotserial",true); + break; + case "barcodeforproduct": //TODO: create product !exist + ajout + barcodeserialforproduct(textarray,product,barcodeproductqty,selectaddorreplace,"barcode"); + break; + case "barcodeforlotserial": + barcodeserialforproduct(textarray,product,barcodeproductqty,selectaddorreplace,"lotserial"); + break; + default: + alert("'.$langs->trans("ErrorWrongBarcodemode").' \""+barcodemode+"\""); + throw"'.$langs->trans('ErrorWrongBarcodemode').' \""+barcodemode+"\""; + } + )} tabproduct.forEach(product => { if(product.Qty!=0){ console.log("We change #"+product.Id+"_input to match input in scanner box"); @@ -598,13 +600,14 @@ if ($object->id > 0) { } - function barcodeserialforproduct(textarray,tabproduct,barcodeproductqty,selectaddorreplace,mode,autodetect=false){ + function barcodeserialforproduct(textarray,product,barcodeproductqty,selectaddorreplace,mode,autodetect=false){ textarray.forEach(function(element,index){ $.ajax({ url: \''.DOL_URL_ROOT.'/product/inventory/ajax/searchfrombarcode.php\', - data: { "action":"existbarcode","barcode":element}, + data: { "action":"existbarcode",'.(!empty($object->fk_warehouse)?'"fk_entrepot":'.$object->fk_warehouse.',':'').'"barcode":element,"product":product}, type: \'POST\', success: function(response) { console.log("test+1"); + //gerer erreur si entrepot different }, error : function(output) { console.error("Error on Fetch of KM articles"); @@ -612,23 +615,21 @@ if ($object->id > 0) { }); console.log("Product "+(index+=1)+": "+element); BarCodeDoesNotExist=0; - tabproduct.forEach(product => { - if(mode == "barcode"){ - testonproduct = product.Barcode - }else if (mode == "lotserial"){ - testonproduct = product.Batch + if(mode == "barcode"){ + testonproduct = product.Barcode + }else if (mode == "lotserial"){ + testonproduct = product.Batch + } + if(testonproduct == element){ + if(selectaddorreplace == "add"){ + productqty = parseInt(product.Qty,10) + product.Qty = productqty + (1*barcodeproductqty) + }else if(selectaddorreplace == "replace"){ + product.Qty = (1*barcodeproductqty) } - if(testonproduct == element){ - if(selectaddorreplace == "add"){ - productqty = parseInt(product.Qty,10) - product.Qty = productqty + (1*barcodeproductqty) - }else if(selectaddorreplace == "replace"){ - product.Qty = (1*barcodeproductqty) - } - }else{ - BarCodeDoesNotExist+=1; - } - }) + }else{ + BarCodeDoesNotExist+=1; + } if(autodetect == false){ if(BarCodeDoesNotExist >= tabproduct.length && mode == "barcode"){ alert("'.$langs->trans('ProductBarcodeDoesNotExist').': "+element); From 5b1028611aacd583fa9d7bde4f225e50770a65df Mon Sep 17 00:00:00 2001 From: lmarcouiller Date: Fri, 19 Nov 2021 13:55:59 +0100 Subject: [PATCH 06/12] update inventory 19 11 --- .../inventory/ajax/searchfrombarcode.php | 17 +++++++++++-- htdocs/product/inventory/inventory.php | 24 +++++++++---------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/htdocs/product/inventory/ajax/searchfrombarcode.php b/htdocs/product/inventory/ajax/searchfrombarcode.php index 559bf8b72da..884aff9ec12 100644 --- a/htdocs/product/inventory/ajax/searchfrombarcode.php +++ b/htdocs/product/inventory/ajax/searchfrombarcode.php @@ -50,13 +50,17 @@ if (!defined('NOBROWSERNOTIF')) { define('NOBROWSERNOTIF', '1'); } require '../../../main.inc.php'; -//require_once DOL_DOCUMENT_ROOT.'/product/inventory/class/inventory.class.php'; +//include_once DOL_DOCUMENT_ROOT.'/product/inventory/class/inventory.class.php'; +$object = new Inventory($db); + $action = GETPOST("action", "alpha"); $barcode = GETPOST("barcode", "aZ09"); $product = GETPOST("product"); $response = ""; $fk_entrepot = GETPOST("fk_entrepot", "int"); +$warehousefound = 0; +$warehouseid = 0; if ($action == "existbarcode" && !empty($barcode)) { $sql = "SELECT ps.fk_entrepot, ps.fk_product, p.barcode"; $sql .= " FROM ".MAIN_DB_PREFIX."product_stock as ps JOIN ".MAIN_DB_PREFIX."product as p ON ps.fk_product = p.rowid"; @@ -71,10 +75,19 @@ if ($action == "existbarcode" && !empty($barcode)) { $object = $db->fetch_object($resql); if ($barcode == $object->barcode) { if (!empty($object->fk_entrepot) && $product["Warehouse"] == $object->fk_entrepot) { - //si warehouse !=$object->fk_entrepot erreur + $warehousefound++; + $warehouseid = $object->fk_entrepot; } } } + if ($warehousefound < 1) { + $response = array('status'=>'error','errorcode'=>'NotFound','message'=>'No warehouse found for barcode'.$barcode); + } elseif ($warehousefound > 1) { + $response = array('status'=>'error','errorcode'=>'TooManyWarehouse','message'=>'Too many warehouse found'); + } else { + $response = array('status'=>'success','message'=>'Warehouse found','warehouse'=>$warehouseid); + } + $response = json_encode($response); } else { $response = "No results found for barcode"; } diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index 8adf1ebc67c..76e3d53de2f 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -588,7 +588,7 @@ if ($object->id > 0) { alert("'.$langs->trans("ErrorWrongBarcodemode").' \""+barcodemode+"\""); throw"'.$langs->trans('ErrorWrongBarcodemode').' \""+barcodemode+"\""; } - )} + }); tabproduct.forEach(product => { if(product.Qty!=0){ console.log("We change #"+product.Id+"_input to match input in scanner box"); @@ -605,12 +605,17 @@ if ($object->id > 0) { $.ajax({ url: \''.DOL_URL_ROOT.'/product/inventory/ajax/searchfrombarcode.php\', data: { "action":"existbarcode",'.(!empty($object->fk_warehouse)?'"fk_entrepot":'.$object->fk_warehouse.',':'').'"barcode":element,"product":product}, type: \'POST\', + async: false, success: function(response) { - console.log("test+1"); - //gerer erreur si entrepot different + response = JSON.parse(response); + if(response.status == "success"){ + console.log(response.message); + }else{ + console.error(response.message); + } }, error : function(output) { - console.error("Error on Fetch of KM articles"); + console.error("Error on barcodeserialforproduct function"); }, }); console.log("Product "+(index+=1)+": "+element); @@ -623,20 +628,13 @@ if ($object->id > 0) { if(testonproduct == element){ if(selectaddorreplace == "add"){ productqty = parseInt(product.Qty,10) - product.Qty = productqty + (1*barcodeproductqty) + product.Qty = productqty + barcodeproductqty }else if(selectaddorreplace == "replace"){ - product.Qty = (1*barcodeproductqty) + product.Qty = barcodeproductqty } }else{ BarCodeDoesNotExist+=1; } - if(autodetect == false){ - if(BarCodeDoesNotExist >= tabproduct.length && mode == "barcode"){ - alert("'.$langs->trans('ProductBarcodeDoesNotExist').': "+element); - }else if(BarCodeDoesNotExist >= tabproduct.length && mode == "lotserial"){ - alert("'.$langs->trans('ProductBatchDoesNotExist').': "+element); - } - } }) } '; From c529d1a928aef79b1a8c6518761b1f048d35b408 Mon Sep 17 00:00:00 2001 From: lmarcouiller Date: Mon, 29 Nov 2021 15:00:23 +0100 Subject: [PATCH 07/12] update inventory add replace work --- .../inventory/ajax/searchfrombarcode.php | 9 ++--- .../inventory/class/inventory.class.php | 1 + htdocs/product/inventory/inventory.php | 40 ++++++++++++------- 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/htdocs/product/inventory/ajax/searchfrombarcode.php b/htdocs/product/inventory/ajax/searchfrombarcode.php index 884aff9ec12..1a613c7a837 100644 --- a/htdocs/product/inventory/ajax/searchfrombarcode.php +++ b/htdocs/product/inventory/ajax/searchfrombarcode.php @@ -50,8 +50,6 @@ if (!defined('NOBROWSERNOTIF')) { define('NOBROWSERNOTIF', '1'); } require '../../../main.inc.php'; -//include_once DOL_DOCUMENT_ROOT.'/product/inventory/class/inventory.class.php'; -$object = new Inventory($db); $action = GETPOST("action", "alpha"); @@ -87,12 +85,11 @@ if ($action == "existbarcode" && !empty($barcode)) { } else { $response = array('status'=>'success','message'=>'Warehouse found','warehouse'=>$warehouseid); } - $response = json_encode($response); } else { - $response = "No results found for barcode"; + $response = array('status'=>'error','errorcode'=>'NotFound','message'=>"No results found for barcode"); } } else { - $response = "Error on action"; + $response = array('status'=>'error','errorcode'=>'ActionError','message'=>"Error on action"); } - +$response = json_encode($response); echo $response; diff --git a/htdocs/product/inventory/class/inventory.class.php b/htdocs/product/inventory/class/inventory.class.php index b972e44245b..092d98ea854 100644 --- a/htdocs/product/inventory/class/inventory.class.php +++ b/htdocs/product/inventory/class/inventory.class.php @@ -26,6 +26,7 @@ // Put here all includes required by your class file require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php'; //require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php'; //require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index 4dcda1bba41..910084c12fe 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -571,19 +571,19 @@ if ($object->id > 0) { if(productinput == ""){ productinput = 0 } - tabproduct.push({\'Id\':id,\'Warehouse\':warehouse,\'Barcode\':productbarcode,\'Batch\':productbatchcode,\'Qty\':productinput}); + tabproduct.push({\'Id\':id,\'Warehouse\':warehouse,\'Barcode\':productbarcode,\'Batch\':productbatchcode,\'Qty\':productinput,\'fetched\':false}); }) - tabproduct.forEach(product => { + textarray.forEach(function(element,index){ switch(barcodemode){ case "barcodeforautodetect": - barcodeserialforproduct(textarray,product,barcodeproductqty,selectaddorreplace,"barcode",true); - barcodeserialforproduct(textarray,product,barcodeproductqty,selectaddorreplace,"lotserial",true); + barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,selectaddorreplace,"barcode",true); + barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,selectaddorreplace,"lotserial",true); break; case "barcodeforproduct": //TODO: create product !exist + ajout - barcodeserialforproduct(textarray,product,barcodeproductqty,selectaddorreplace,"barcode"); + barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,selectaddorreplace,"barcode"); break; case "barcodeforlotserial": - barcodeserialforproduct(textarray,product,barcodeproductqty,selectaddorreplace,"lotserial"); + barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,selectaddorreplace,"lotserial"); break; default: alert("'.$langs->trans("ErrorWrongBarcodemode").' \""+barcodemode+"\""); @@ -601,8 +601,10 @@ if ($object->id > 0) { } - function barcodeserialforproduct(textarray,product,barcodeproductqty,selectaddorreplace,mode,autodetect=false){ - textarray.forEach(function(element,index){ + function barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,selectaddorreplace,mode,autodetect=false){ + BarcodeIsInProduct=0; + BarcodeSuccess=false; + tabproduct.forEach(product => { $.ajax({ url: \''.DOL_URL_ROOT.'/product/inventory/ajax/searchfrombarcode.php\', data: { "action":"existbarcode",'.(!empty($object->fk_warehouse)?'"fk_entrepot":'.$object->fk_warehouse.',':'').'"barcode":element,"product":product}, type: \'POST\', @@ -611,6 +613,7 @@ if ($object->id > 0) { response = JSON.parse(response); if(response.status == "success"){ console.log(response.message); + BarcodeSucess=true; }else{ console.error(response.message); } @@ -618,9 +621,8 @@ if ($object->id > 0) { error : function(output) { console.error("Error on barcodeserialforproduct function"); }, - }); + }); console.log("Product "+(index+=1)+": "+element); - BarCodeDoesNotExist=0; if(mode == "barcode"){ testonproduct = product.Barcode }else if (mode == "lotserial"){ @@ -628,15 +630,23 @@ if ($object->id > 0) { } if(testonproduct == element){ if(selectaddorreplace == "add"){ - productqty = parseInt(product.Qty,10) - product.Qty = productqty + barcodeproductqty + productqty = parseInt(product.Qty,10); + product.Qty = productqty + parseInt(barcodeproductqty,10); }else if(selectaddorreplace == "replace"){ - product.Qty = barcodeproductqty + if(product.fetched == false){ + product.Qty = barcodeproductqty + product.fetched=true + }else{ + productqty = parseInt(product.Qty,10); + product.Qty = productqty + parseInt(barcodeproductqty,10); + } } - }else{ - BarCodeDoesNotExist+=1; + BarcodeIsInProduct+=1; } }) + if(BarcodeIsInProduct==0 && BarcodeSuccess){ + //addproduct to db and tabproduct + } } '; print ''; From ae56619253059ef533f17e18f29255abb0e3df57 Mon Sep 17 00:00:00 2001 From: Lucas Marcouiller Date: Tue, 30 Nov 2021 15:38:27 +0100 Subject: [PATCH 08/12] add productadd function but error on tabproduct --- .../inventory/ajax/searchfrombarcode.php | 71 +++++++++++++------ htdocs/product/inventory/inventory.php | 35 +++++++-- 2 files changed, 79 insertions(+), 27 deletions(-) diff --git a/htdocs/product/inventory/ajax/searchfrombarcode.php b/htdocs/product/inventory/ajax/searchfrombarcode.php index 1a613c7a837..32cba249896 100644 --- a/htdocs/product/inventory/ajax/searchfrombarcode.php +++ b/htdocs/product/inventory/ajax/searchfrombarcode.php @@ -21,7 +21,10 @@ */ if (!defined('NOTOKENRENEWAL')) { - define('NOTOKENRENEWAL', '1'); // Disables token renewal + define('NOTOKENRENEWAL', 1); // Disables token renewal +} +if (!defined('NOREQUIREMENU')) { + define('NOREQUIREMENU', '1'); } if (!defined('NOREQUIREHTML')) { define('NOREQUIREHTML', '1'); @@ -35,32 +38,28 @@ if (!defined('NOREQUIRESOC')) { if (!defined('NOCSRFCHECK')) { define('NOCSRFCHECK', '1'); } -// Do not check anti CSRF attack test -if (!defined('NOREQUIREMENU')) { - define('NOREQUIREMENU', '1'); -} -// If there is no need to load and show top and left menu -if (!defined("NOLOGIN")) { - define("NOLOGIN", '1'); -} -if (!defined('NOIPCHECK')) { - define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip -} -if (!defined('NOBROWSERNOTIF')) { - define('NOBROWSERNOTIF', '1'); -} require '../../../main.inc.php'; - +require_once DOL_DOCUMENT_ROOT."/product/stock/class/entrepot.class.php"; +$warehouse = new Entrepot($db); $action = GETPOST("action", "alpha"); $barcode = GETPOST("barcode", "aZ09"); $product = GETPOST("product"); $response = ""; + $fk_entrepot = GETPOST("fk_entrepot", "int"); +$fk_inventory = GETPOST("fk_inventory", "int"); +$fk_product = GETPOST("fk_product", "int"); +$reelqty = GETPOST("reelqty", "int"); +$qtyview = GETPOST("Qty", "int"); +$batch = GETPOST("batch","int"); + $warehousefound = 0; $warehouseid = 0; +$objectreturn = array(); + if ($action == "existbarcode" && !empty($barcode)) { - $sql = "SELECT ps.fk_entrepot, ps.fk_product, p.barcode"; + $sql = "SELECT ps.fk_entrepot, ps.fk_product, p.barcode,ps.reel"; $sql .= " FROM ".MAIN_DB_PREFIX."product_stock as ps JOIN ".MAIN_DB_PREFIX."product as p ON ps.fk_product = p.rowid"; $sql .= " WHERE p.barcode = '".$db->escape($barcode)."'"; if (!empty($fk_entrepot)) { @@ -68,13 +67,18 @@ if ($action == "existbarcode" && !empty($barcode)) { } $result = $db->query($sql); if ($result) { - $nbline = $db->num_rows($resql); + $nbline = $db->num_rows($result); for ($i=0; $i < $nbline; $i++) { - $object = $db->fetch_object($resql); + $object = $db->fetch_object($result); if ($barcode == $object->barcode) { - if (!empty($object->fk_entrepot) && $product["Warehouse"] == $object->fk_entrepot) { + $warehouse->fetch(0,$product["Warehouse"]); + if (!empty($object->fk_entrepot) && $warehouse->id == $object->fk_entrepot) { $warehousefound++; $warehouseid = $object->fk_entrepot; + $fk_product = $object->fk_product; + $reelqty = $object->reel; + + $objectreturn = array('fk_warehouse'=>$warehouseid,'fk_product'=>$fk_product,'reelqty'=>$reelqty); } } } @@ -83,7 +87,7 @@ if ($action == "existbarcode" && !empty($barcode)) { } elseif ($warehousefound > 1) { $response = array('status'=>'error','errorcode'=>'TooManyWarehouse','message'=>'Too many warehouse found'); } else { - $response = array('status'=>'success','message'=>'Warehouse found','warehouse'=>$warehouseid); + $response = array('status'=>'success','message'=>'Warehouse found','object'=>$objectreturn); } } else { $response = array('status'=>'error','errorcode'=>'NotFound','message'=>"No results found for barcode"); @@ -91,5 +95,30 @@ if ($action == "existbarcode" && !empty($barcode)) { } else { $response = array('status'=>'error','errorcode'=>'ActionError','message'=>"Error on action"); } + +if ($action == "addnewlineproduct") { + require_once DOL_DOCUMENT_ROOT."/product/inventory/class/inventory.class.php"; + $inventoryline = new InventoryLine($db); + if (!empty($fk_inventory)) { + $inventoryline->fk_inventory = $fk_inventory; + + $inventoryline->fk_warehouse = $fk_entrepot; + $inventoryline->fk_product = $fk_product; + $inventoryline->qty_stock = $reelqty; + $inventoryline->qty_view = $qtyview; + $inventoryline->batch = $batch; + $inventoryline->datec = dol_now(); + + $result = $inventoryline->create($user); + if ($result > 0) { + $response = array('status'=>'success','message'=>'Success on creating line'); + }else { + $response = array('status'=>'error','errorcode'=>'ErrorCreation','message'=>"Error on line creation"); + } + }else { + $response = array('status'=>'error','errorcode'=>'NoIdForInventory','message'=>"No id for inventory"); + } +} + $response = json_encode($response); echo $response; diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index 910084c12fe..58bdcbc0022 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -587,13 +587,32 @@ if ($object->id > 0) { break; default: alert("'.$langs->trans("ErrorWrongBarcodemode").' \""+barcodemode+"\""); - throw"'.$langs->trans('ErrorWrongBarcodemode').' \""+barcodemode+"\""; + throw "'.$langs->trans('ErrorWrongBarcodemode').' \""+barcodemode+"\""; } }); tabproduct.forEach(product => { if(product.Qty!=0){ console.log("We change #"+product.Id+"_input to match input in scanner box"); - $("#"+product.Id+"_input").val(product.Qty); + if(product.hasOwnProperty("reelqty")){ + $.ajax({ url: \''.DOL_URL_ROOT.'/product/inventory/ajax/searchfrombarcode.php\', + data: { "action":"addnewlineproduct","fk_entrepot":product.Warehouse,"batch":Batch,"fk_inventory":'.dol_escape_js($object->id).',"fk_product":product.fk_product,"reelqty":product.reelqty,"qty":product.Qty}, + type: \'POST\', + async: false, + success: function(response) { + response = JSON.parse(response); + if(response.status == "success"){ + console.log(response.message); + }else{ + console.error(response.message); + } + }, + error : function(output) { + console.error("Error on barcodeserialforproduct function"); + }, + }); + } else { + $("#"+product.Id+"_input").val(product.Qty); + } } }) document.forms["formrecord"].submit(); @@ -603,7 +622,7 @@ if ($object->id > 0) { function barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,selectaddorreplace,mode,autodetect=false){ BarcodeIsInProduct=0; - BarcodeSuccess=false; + newproductrow=0 tabproduct.forEach(product => { $.ajax({ url: \''.DOL_URL_ROOT.'/product/inventory/ajax/searchfrombarcode.php\', data: { "action":"existbarcode",'.(!empty($object->fk_warehouse)?'"fk_entrepot":'.$object->fk_warehouse.',':'').'"barcode":element,"product":product}, @@ -613,7 +632,9 @@ if ($object->id > 0) { response = JSON.parse(response); if(response.status == "success"){ console.log(response.message); - BarcodeSucess=true; + if(!newproductrow){ + newproductrow = response.object; + } }else{ console.error(response.message); } @@ -644,9 +665,11 @@ if ($object->id > 0) { BarcodeIsInProduct+=1; } }) - if(BarcodeIsInProduct==0 && BarcodeSuccess){ - //addproduct to db and tabproduct + if(BarcodeIsInProduct==0 && newproductrow){ + //addproduct to tabproduct + tabproduct.push({\'Id\':tabproduct.length-1,\'Warehouse\':newproductrow.fk_warehouse,\'Barcode\':element,\'Batch\':"",\'Qty\':1,\'fetched\':true,\'reelqty\':object.reelqty}); } + return tabproduct; } '; print ''; From f39dd30a7f49b6cd9a542eb291e3c742090caf40 Mon Sep 17 00:00:00 2001 From: Lucas Marcouiller Date: Tue, 30 Nov 2021 15:38:48 +0100 Subject: [PATCH 09/12] fix precommit --- htdocs/product/inventory/ajax/searchfrombarcode.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/product/inventory/ajax/searchfrombarcode.php b/htdocs/product/inventory/ajax/searchfrombarcode.php index 32cba249896..947a9904bf0 100644 --- a/htdocs/product/inventory/ajax/searchfrombarcode.php +++ b/htdocs/product/inventory/ajax/searchfrombarcode.php @@ -52,7 +52,7 @@ $fk_inventory = GETPOST("fk_inventory", "int"); $fk_product = GETPOST("fk_product", "int"); $reelqty = GETPOST("reelqty", "int"); $qtyview = GETPOST("Qty", "int"); -$batch = GETPOST("batch","int"); +$batch = GETPOST("batch", "int"); $warehousefound = 0; $warehouseid = 0; @@ -71,7 +71,7 @@ if ($action == "existbarcode" && !empty($barcode)) { for ($i=0; $i < $nbline; $i++) { $object = $db->fetch_object($result); if ($barcode == $object->barcode) { - $warehouse->fetch(0,$product["Warehouse"]); + $warehouse->fetch(0, $product["Warehouse"]); if (!empty($object->fk_entrepot) && $warehouse->id == $object->fk_entrepot) { $warehousefound++; $warehouseid = $object->fk_entrepot; @@ -112,10 +112,10 @@ if ($action == "addnewlineproduct") { $result = $inventoryline->create($user); if ($result > 0) { $response = array('status'=>'success','message'=>'Success on creating line'); - }else { + } else { $response = array('status'=>'error','errorcode'=>'ErrorCreation','message'=>"Error on line creation"); } - }else { + } else { $response = array('status'=>'error','errorcode'=>'NoIdForInventory','message'=>"No id for inventory"); } } From 7512305b449e0718513cc302c3117eed2215dba3 Mon Sep 17 00:00:00 2001 From: lmarcouiller Date: Wed, 1 Dec 2021 12:10:57 +0100 Subject: [PATCH 10/12] add porduct inventory but qty_view bug --- htdocs/product/inventory/ajax/searchfrombarcode.php | 7 +++++-- htdocs/product/inventory/inventory.php | 10 ++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/htdocs/product/inventory/ajax/searchfrombarcode.php b/htdocs/product/inventory/ajax/searchfrombarcode.php index 947a9904bf0..c4d53719d65 100644 --- a/htdocs/product/inventory/ajax/searchfrombarcode.php +++ b/htdocs/product/inventory/ajax/searchfrombarcode.php @@ -51,8 +51,9 @@ $fk_entrepot = GETPOST("fk_entrepot", "int"); $fk_inventory = GETPOST("fk_inventory", "int"); $fk_product = GETPOST("fk_product", "int"); $reelqty = GETPOST("reelqty", "int"); -$qtyview = GETPOST("Qty", "int"); +$qtyview = GETPOST("qty", "int"); $batch = GETPOST("batch", "int"); +$mode = GETPOST("mode", "aZ"); $warehousefound = 0; $warehouseid = 0; @@ -106,7 +107,9 @@ if ($action == "addnewlineproduct") { $inventoryline->fk_product = $fk_product; $inventoryline->qty_stock = $reelqty; $inventoryline->qty_view = $qtyview; - $inventoryline->batch = $batch; + if ($mode == "lotserial") { + $inventoryline->batch = $batch; + } $inventoryline->datec = dol_now(); $result = $inventoryline->create($user); diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index 58bdcbc0022..9376d583ad4 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -548,8 +548,8 @@ if ($object->id > 0) { var barcodeproductqty = $("input[name=barcodeproductqty]").val(); var textarea = $("textarea[name=barcodelist]").val(); var textarray = textarea.split("\n"); + var tabproduct = []; if(textarray[0] != ""){ - var tabproduct = []; $(".expectedqty").each(function(){ id = this.id; warehouse = $("#"+id+"_warehouse").children().first().text(); @@ -579,7 +579,7 @@ if ($object->id > 0) { barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,selectaddorreplace,"barcode",true); barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,selectaddorreplace,"lotserial",true); break; - case "barcodeforproduct": //TODO: create product !exist + ajout + case "barcodeforproduct": barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,selectaddorreplace,"barcode"); break; case "barcodeforlotserial": @@ -595,7 +595,7 @@ if ($object->id > 0) { console.log("We change #"+product.Id+"_input to match input in scanner box"); if(product.hasOwnProperty("reelqty")){ $.ajax({ url: \''.DOL_URL_ROOT.'/product/inventory/ajax/searchfrombarcode.php\', - data: { "action":"addnewlineproduct","fk_entrepot":product.Warehouse,"batch":Batch,"fk_inventory":'.dol_escape_js($object->id).',"fk_product":product.fk_product,"reelqty":product.reelqty,"qty":product.Qty}, + data: { "action":"addnewlineproduct","fk_entrepot":product.Warehouse,"batch":product.Batch,"fk_inventory":'.dol_escape_js($object->id).',"fk_product":product.fk_product,"reelqty":product.reelqty,"qty":product.Qty}, type: \'POST\', async: false, success: function(response) { @@ -666,10 +666,8 @@ if ($object->id > 0) { } }) if(BarcodeIsInProduct==0 && newproductrow){ - //addproduct to tabproduct - tabproduct.push({\'Id\':tabproduct.length-1,\'Warehouse\':newproductrow.fk_warehouse,\'Barcode\':element,\'Batch\':"",\'Qty\':1,\'fetched\':true,\'reelqty\':object.reelqty}); + tabproduct.push({\'Id\':tabproduct.length-1,\'Warehouse\':newproductrow.fk_warehouse,\'Barcode\':element,\'Batch\':element,\'Qty\':barcodeproductqty,\'fetched\':true,\'reelqty\':newproductrow.reelqty,\'fk_product\':newproductrow.fk_product,\'mode\':mode}); } - return tabproduct; } '; print ''; From 325ad45bca794a69f12c0d45e5ad9954f3328529 Mon Sep 17 00:00:00 2001 From: lmarcouiller Date: Fri, 3 Dec 2021 16:04:23 +0100 Subject: [PATCH 11/12] update scan inventory error gestion --- htdocs/langs/en_US/stocks.lang | 3 +- .../inventory/ajax/searchfrombarcode.php | 17 ++-- htdocs/product/inventory/inventory.php | 77 +++++++++++-------- 3 files changed, 60 insertions(+), 37 deletions(-) diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index 75b6ea1bd4e..c26a8819a1d 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -265,4 +265,5 @@ ProductBarcodeDoesNotExist=Product with barcode does not exist WarehouseId=Warehouse ID WarehouseRef=Warehouse Ref SaveQtyFirst=Save the real inventoried quantities first, before asking creation of the stock movement. -InventoryStartedShort=Started \ No newline at end of file +InventoryStartedShort=Started +ErrorOnElementsInventory=Scan was aborted due to following barcode or batch number on error \ No newline at end of file diff --git a/htdocs/product/inventory/ajax/searchfrombarcode.php b/htdocs/product/inventory/ajax/searchfrombarcode.php index c4d53719d65..8dfac96c32b 100644 --- a/htdocs/product/inventory/ajax/searchfrombarcode.php +++ b/htdocs/product/inventory/ajax/searchfrombarcode.php @@ -60,18 +60,25 @@ $warehouseid = 0; $objectreturn = array(); if ($action == "existbarcode" && !empty($barcode)) { - $sql = "SELECT ps.fk_entrepot, ps.fk_product, p.barcode,ps.reel"; - $sql .= " FROM ".MAIN_DB_PREFIX."product_stock as ps JOIN ".MAIN_DB_PREFIX."product as p ON ps.fk_product = p.rowid"; - $sql .= " WHERE p.barcode = '".$db->escape($barcode)."'"; + if (!empty($mode) && $mode == "lotserial") { + $sql = "SELECT ps.fk_entrepot, ps.fk_product, p.barcode, ps.reel, pb.batch"; + $sql .= " FROM ".MAIN_DB_PREFIX."product_batch as pb"; + $sql .= " JOIN ".MAIN_DB_PREFIX."product_stock as ps ON pb.fk_product_stock = ps.rowid JOIN ".MAIN_DB_PREFIX."product as p ON ps.fk_product = p.rowid"; + $sql .= " WHERE pb.batch = '".$db->escape($barcode)."'"; + } else { + $sql = "SELECT ps.fk_entrepot, ps.fk_product, p.barcode,ps.reel"; + $sql .= " FROM ".MAIN_DB_PREFIX."product_stock as ps JOIN ".MAIN_DB_PREFIX."product as p ON ps.fk_product = p.rowid"; + $sql .= " WHERE p.barcode = '".$db->escape($barcode)."'"; + } if (!empty($fk_entrepot)) { - $sql .= "AND ps.fk_entrepot = '".$db->escape($fk_entrepot)."'"; + $sql .= " AND ps.fk_entrepot = '".$db->escape($fk_entrepot)."'"; } $result = $db->query($sql); if ($result) { $nbline = $db->num_rows($result); for ($i=0; $i < $nbline; $i++) { $object = $db->fetch_object($result); - if ($barcode == $object->barcode) { + if (($mode == "barcode" && $barcode == $object->barcode) || ($mode == "lotserial" && $barcode == $object->batch)) { $warehouse->fetch(0, $product["Warehouse"]); if (!empty($object->fk_entrepot) && $warehouse->id == $object->fk_entrepot) { $warehousefound++; diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index 9376d583ad4..51c2e9d2bc5 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -541,7 +541,10 @@ if ($object->id > 0) { if ($action == 'updatebyscaning') { if ($permissiontoadd) { print '';