Merge pull request #18206 from Hystepik/develop#2
New : Inventory scanner tool implemented
This commit is contained in:
commit
9f293066ab
@ -63,7 +63,7 @@ class FormOther
|
|||||||
* @param string $jstoexecuteonadd Name of javascript function to call
|
* @param string $jstoexecuteonadd Name of javascript function to call
|
||||||
* @return string HTML component
|
* @return string HTML component
|
||||||
*/
|
*/
|
||||||
public function getHTMLScannerForm($jstoexecuteonadd = 'barcodscannerjs')
|
public function getHTMLScannerForm($jstoexecuteonadd = 'barcodescannerjs')
|
||||||
{
|
{
|
||||||
global $langs;
|
global $langs;
|
||||||
|
|
||||||
@ -73,9 +73,9 @@ class FormOther
|
|||||||
$out .= '<div class="div-for-modal-topright" style="padding: 15px">';
|
$out .= '<div class="div-for-modal-topright" style="padding: 15px">';
|
||||||
$out .= '<center><strong>Barcode scanner tool...</strong></center><br>';
|
$out .= '<center><strong>Barcode scanner tool...</strong></center><br>';
|
||||||
|
|
||||||
$out .= '<input type="checkbox" name="barcodeforautodetect" checked="checked"> Autodetect if we scan a product barcode or a lot/serial barcode<br>';
|
$out .= '<input type="radio" name="barcodemode" value="barcodeforautodetect" checked="checked"> Autodetect if we scan a product barcode or a lot/serial barcode<br>';
|
||||||
$out .= '<input type="checkbox" name="barcodeforproduct"> Scan a product barcode<br>';
|
$out .= '<input type="radio" name="barcodemode" value="barcodeforproduct"> Scan a product barcode<br>';
|
||||||
$out .= '<input type="checkbox" name="barcodeforlotserial"> Scan a product lot or serial number<br>';
|
$out .= '<input type="radio" name="barcodemode" value="barcodeforlotserial"> Scan a product lot or serial number<br>';
|
||||||
|
|
||||||
$out .= $langs->trans("QtyToAddAfterBarcodeScan").' <input type="text" name="barcodeproductqty" class="width50 right" value="1"><br>';
|
$out .= $langs->trans("QtyToAddAfterBarcodeScan").' <input type="text" name="barcodeproductqty" class="width50 right" value="1"><br>';
|
||||||
$out .= '<textarea type="text" name="barcodelist" class="centpercent" autofocus rows="'.ROWS_3.'"></textarea>';
|
$out .= '<textarea type="text" name="barcodelist" class="centpercent" autofocus rows="'.ROWS_3.'"></textarea>';
|
||||||
@ -88,13 +88,16 @@ class FormOther
|
|||||||
*/
|
*/
|
||||||
$out .= '<br>';
|
$out .= '<br>';
|
||||||
$out .= '<center>';
|
$out .= '<center>';
|
||||||
$out .= '<input type="submit" class="button marginleftonly marginrightonly" name="addscan" value="'.$langs->trans("Add").'">';
|
$out .= '<input type="submit" class="button marginleftonly marginrightonly" id ="exec'.dol_escape_js($jstoexecuteonadd).'" name="addscan" value="'.$langs->trans("Add").'">';
|
||||||
$out .= '<input type="submit" class="button marginleftonly marginrightonly" name="cancel" value="'.$langs->trans("Cancel").'">';
|
$out .= '<input type="submit" class="button marginleftonly marginrightonly" name="cancel" value="'.$langs->trans("Cancel").'">';
|
||||||
$out .= '<br>';
|
$out .= '<br>';
|
||||||
|
|
||||||
$out .= '<span class="opacitymedium">'.$langs->trans("FeatureNotYetAvailable").'</span>';
|
$out .= '<script>';
|
||||||
|
$out .= '$("#exec'.dol_escape_js($jstoexecuteonadd).'").click(function(){
|
||||||
// TODO Add call of javascript $jstoexecuteonadd so each scan will add qty into the inventory page + an ajax save.
|
console.log("We call js to execute '.dol_escape_js($jstoexecuteonadd).'");
|
||||||
|
'.dol_escape_js($jstoexecuteonadd).'();
|
||||||
|
})';
|
||||||
|
$out .= '</script>';
|
||||||
|
|
||||||
$out .= '</center>';
|
$out .= '</center>';
|
||||||
$out .= '</div>';
|
$out .= '</div>';
|
||||||
|
|||||||
@ -255,4 +255,9 @@ MakeMovementsAndClose=Generate movements and close
|
|||||||
AutofillWithExpected=Fill real quantity with expected quantity
|
AutofillWithExpected=Fill real quantity with expected quantity
|
||||||
ShowAllBatchByDefault=By default, show batch details on product "stock" tab
|
ShowAllBatchByDefault=By default, show batch details on product "stock" tab
|
||||||
CollapseBatchDetailHelp=You can set batch detail default display in stocks module configuration
|
CollapseBatchDetailHelp=You can set batch detail default display in stocks module configuration
|
||||||
FieldCannotBeNegative=Field "%s" cannot be negative
|
FieldCannotBeNegative=Field "%s" cannot be negative
|
||||||
|
ErrorWrongBarcodemode=Unknown Barcode mode
|
||||||
|
ProductDoesNotExist=Product does not exist
|
||||||
|
ErrorSameBatchNumber=Same batch number found in inventory list
|
||||||
|
ProductBatchDoesNotExist=Product with batch/serial does not exist
|
||||||
|
ProductBarcodeDoesNotExist=Product with barcode does not exist
|
||||||
|
|||||||
@ -449,7 +449,7 @@ if ($object->id > 0) {
|
|||||||
print dol_get_fiche_end();
|
print dol_get_fiche_end();
|
||||||
|
|
||||||
|
|
||||||
print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
|
print '<form name="formrecord" method="POST" action="'.$_SERVER["PHP_SELF"].'">';
|
||||||
print '<input type="hidden" name="token" value="'.newToken().'">';
|
print '<input type="hidden" name="token" value="'.newToken().'">';
|
||||||
print '<input type="hidden" name="action" value="updateinventorylines">';
|
print '<input type="hidden" name="action" value="updateinventorylines">';
|
||||||
print '<input type="hidden" name="id" value="'.$object->id.'">';
|
print '<input type="hidden" name="id" value="'.$object->id.'">';
|
||||||
@ -537,11 +537,116 @@ if ($object->id > 0) {
|
|||||||
|
|
||||||
// Popup for mass barcode scanning
|
// Popup for mass barcode scanning
|
||||||
if ($action == 'updatebyscaning') {
|
if ($action == 'updatebyscaning') {
|
||||||
|
if ($permissiontoadd) {
|
||||||
|
print '<script>';
|
||||||
|
print 'function barcodescannerjs(){
|
||||||
|
console.log("We catch inputs in sacnner box");
|
||||||
|
var barcodemode = $("input[name=barcodemode]:checked").val();
|
||||||
|
var barcodeproductqty = $("input[name=barcodeproductqty]").val();
|
||||||
|
var textarea = $("textarea[name=barcodelist]").val();
|
||||||
|
var textarray = textarea.split("\n");
|
||||||
|
if(textarray[0] != ""){
|
||||||
|
var tabproduct = [];
|
||||||
|
$(".expectedqty").each(function(){
|
||||||
|
id = this.id;
|
||||||
|
warehouse = $("#"+id+"_warehouse").children().first().text();
|
||||||
|
productbarcode = $("#"+id+"_product").children().first().attr("title");
|
||||||
|
productbarcode = productbarcode.split("<br>");
|
||||||
|
productbarcode = productbarcode.filter(barcode => barcode.includes("'.$langs->trans('BarCode').'"))[0];
|
||||||
|
productbarcode = productbarcode.slice(productbarcode.indexOf("</b> ")+5);
|
||||||
|
|
||||||
|
productbatchcode = $("#"+id+"_batch").text();
|
||||||
|
if(barcodemode != "barcodeforproduct"){
|
||||||
|
tabproduct.forEach(product=>{
|
||||||
|
if(product.Batch == productbatchcode){
|
||||||
|
alert("'.$langs->trans('ErrorSameBatchNumber').': "+productbatchcode);
|
||||||
|
throw"'.$langs->trans('ErrorSameBatchNumber').': "+productbatchcode;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
tabproduct.push({\'Id\':id,\'Warehouse\':warehouse,\'Barcode\':productbarcode,\'Batch\':productbatchcode,\'Qty\':0});
|
||||||
|
})
|
||||||
|
switch(barcodemode){
|
||||||
|
case "barcodeforautodetect":
|
||||||
|
textarray.forEach(function(element,index){
|
||||||
|
console.log("Product autodetect "+(index+=1)+": "+element);
|
||||||
|
BatchCodeDoesNotExist=0;
|
||||||
|
tabproduct.forEach(product => {
|
||||||
|
if(product.Batch == element || product.Barcode == element){
|
||||||
|
product.Qty+=1;
|
||||||
|
}else{
|
||||||
|
BatchCodeDoesNotExist+=1;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if(BatchCodeDoesNotExist >= tabproduct.length){
|
||||||
|
alert("'.$langs->trans('ProductDoesNotExist').': "+element);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
case "barcodeforproduct":
|
||||||
|
textarray.forEach(function(element,index){
|
||||||
|
console.log("Product "+(index+=1)+": "+element);
|
||||||
|
BarCodeDoesNotExist=0;
|
||||||
|
tabproduct.forEach(product => {
|
||||||
|
if(product.Barcode == element){
|
||||||
|
product.Qty+=1;
|
||||||
|
}else{
|
||||||
|
BarCodeDoesNotExist+=1;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if(BarCodeDoesNotExist >= tabproduct.length){
|
||||||
|
alert("'.$langs->trans('ProductBarcodeDoesNotExist').': "+element);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
case "barcodeforlotserial":
|
||||||
|
textarray.forEach(function(element,index){
|
||||||
|
console.log("Product batch/serial "+(index+=1)+": "+element);
|
||||||
|
BatchCodeDoesNotExist=0;
|
||||||
|
tabproduct.forEach(product => {
|
||||||
|
if(product.Batch == element){
|
||||||
|
product.Qty+=1;
|
||||||
|
}else{
|
||||||
|
BatchCodeDoesNotExist+=1;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if(BatchCodeDoesNotExist >= tabproduct.length){
|
||||||
|
alert("'.$langs->trans('ProductBatchDoesNotExist').': "+element);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
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");
|
||||||
|
$("#"+product.Id+"_input").val(product.Qty*barcodeproductqty);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
document.forms["formrecord"].submit();
|
||||||
|
}
|
||||||
|
}';
|
||||||
|
print '</script>';
|
||||||
|
}
|
||||||
include DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
|
include DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
|
||||||
$formother = new FormOther($db);
|
$formother = new FormOther($db);
|
||||||
print $formother->getHTMLScannerForm();
|
print $formother->getHTMLScannerForm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Call method to undo changes in real qty
|
||||||
|
print '<script>';
|
||||||
|
print 'jQuery(document).ready(function() {
|
||||||
|
$(".undochangesqty").on("click",function undochangesqty(){
|
||||||
|
id = this.id;
|
||||||
|
id = id.split("_")[1];
|
||||||
|
tmpvalue = $("#id_"+id+"_input_tmp").val()
|
||||||
|
$("#id_"+id+"_input")[0].value = tmpvalue;
|
||||||
|
document.forms["formrecord"].submit();
|
||||||
|
});
|
||||||
|
});';
|
||||||
|
print '</script>';
|
||||||
|
|
||||||
print '<div class="fichecenter">';
|
print '<div class="fichecenter">';
|
||||||
//print '<div class="fichehalfleft">';
|
//print '<div class="fichehalfleft">';
|
||||||
@ -639,15 +744,15 @@ if ($object->id > 0) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
print '<tr class="oddeven">';
|
print '<tr class="oddeven">';
|
||||||
print '<td>';
|
print '<td id="id_'.$obj->rowid.'_warehouse">';
|
||||||
print $warehouse_static->getNomUrl(1);
|
print $warehouse_static->getNomUrl(1);
|
||||||
print '</td>';
|
print '</td>';
|
||||||
print '<td>';
|
print '<td id="id_'.$obj->rowid.'_product">';
|
||||||
print $product_static->getNomUrl(1);
|
print $product_static->getNomUrl(1);
|
||||||
print '</td>';
|
print '</td>';
|
||||||
|
|
||||||
if ($conf->productbatch->enabled) {
|
if ($conf->productbatch->enabled) {
|
||||||
print '<td>';
|
print '<td id="id_'.$obj->rowid.'_batch">';
|
||||||
print $obj->batch;
|
print $obj->batch;
|
||||||
print '</td>';
|
print '</td>';
|
||||||
}
|
}
|
||||||
@ -665,8 +770,11 @@ if ($object->id > 0) {
|
|||||||
print '<input type="text" class="maxwidth75 right realqty" name="id_'.$obj->rowid.'" id="id_'.$obj->rowid.'_input" value="'.$qty_view.'">';
|
print '<input type="text" class="maxwidth75 right realqty" name="id_'.$obj->rowid.'" id="id_'.$obj->rowid.'_input" value="'.$qty_view.'">';
|
||||||
print '</td>';
|
print '</td>';
|
||||||
print '<td class="right">';
|
print '<td class="right">';
|
||||||
|
print '<a id="undochangesqty_'.$obj->rowid.'" href="#" class="undochangesqty"><span class="fas fa-undo pictoundo" ></span></a>  ';
|
||||||
print '<a class="reposition" href="'.DOL_URL_ROOT.'/product/inventory/inventory.php?id='.$object->id.'&lineid='.$obj->rowid.'&action=deleteline&token='.newToken().'">'.img_delete().'</a>';
|
print '<a class="reposition" href="'.DOL_URL_ROOT.'/product/inventory/inventory.php?id='.$object->id.'&lineid='.$obj->rowid.'&action=deleteline&token='.newToken().'">'.img_delete().'</a>';
|
||||||
print '</td>';
|
print '</td>';
|
||||||
|
$qty_tmp = price2num(GETPOST("id_".$obj->rowid."_input_tmp", 'MS')) >= 0 ? GETPOST("id_".$obj->rowid."_input_tmp") : $qty_view;
|
||||||
|
print '<input type="hidden" class="maxwidth75 right realqty" name="id_'.$obj->rowid.'_input_tmp" id="id_'.$obj->rowid.'_input_tmp" value="'.$qty_tmp.'">';
|
||||||
} else {
|
} else {
|
||||||
print $obj->qty_view;
|
print $obj->qty_view;
|
||||||
$totalfound += $obj->qty_view;
|
$totalfound += $obj->qty_view;
|
||||||
@ -685,7 +793,7 @@ if ($object->id > 0) {
|
|||||||
print '</div>';
|
print '</div>';
|
||||||
|
|
||||||
if ($object->status == $object::STATUS_VALIDATED) {
|
if ($object->status == $object::STATUS_VALIDATED) {
|
||||||
print '<center><input type="submit" class="button button-save" name="save" value="'.$langs->trans("Save").'"></center>';
|
print '<center><input id="submitrecord" type="submit" class="button button-save" name="save" value="'.$langs->trans("Save").'"></center>';
|
||||||
}
|
}
|
||||||
|
|
||||||
print '</div>';
|
print '</div>';
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user