WIP : fix inventory scan
This commit is contained in:
parent
e8e63e85f1
commit
1f64b09430
@ -77,7 +77,10 @@ class FormOther
|
|||||||
$out .= '<input type="radio" name="barcodemode" value="barcodeforproduct"> Scan a product barcode<br>';
|
$out .= '<input type="radio" name="barcodemode" value="barcodeforproduct"> Scan a product barcode<br>';
|
||||||
$out .= '<input type="radio" name="barcodemode" value="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>';
|
$stringaddbarcode = $langs->trans("QtyToAddAfterBarcodeScan","tmphtml");
|
||||||
|
$htmltoreplaceby = '<select name="selectaddorreplace"><option selected value="add">'.$langs->trans("Add").'</option><option value="replace">'.$langs->trans("ToReplace").'</option></select>';
|
||||||
|
$stringaddbarcode = str_replace("tmphtml",$htmltoreplaceby,$stringaddbarcode);
|
||||||
|
$out .= $stringaddbarcode.' <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>';
|
||||||
|
|
||||||
/*print '<br>'.$langs->trans("or").'<br>';
|
/*print '<br>'.$langs->trans("or").'<br>';
|
||||||
|
|||||||
@ -30,7 +30,7 @@ ManageLotMask=Custom mask
|
|||||||
CustomMasks=Option to define a different numbering mask for each product
|
CustomMasks=Option to define a different numbering mask for each product
|
||||||
BatchLotNumberingModules=Numbering rule for automatic generation of lot number
|
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)
|
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)
|
LifeTime=Life span (in days)
|
||||||
EndOfLife=End of life
|
EndOfLife=End of life
|
||||||
ManufacturingDate=Manufacturing date
|
ManufacturingDate=Manufacturing date
|
||||||
@ -42,3 +42,4 @@ HideLots=Hide lots
|
|||||||
#Traceability - qc status
|
#Traceability - qc status
|
||||||
OutOfOrder=Out of order
|
OutOfOrder=Out of order
|
||||||
InWorkingOrder=In working order
|
InWorkingOrder=In working order
|
||||||
|
ToReplace=Replace
|
||||||
@ -30,7 +30,7 @@ ManageLotMask=Masque personnalisé
|
|||||||
CustomMasks=Option pour définir un masque de numérotation différent pour chaque produit
|
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
|
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)
|
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)
|
LifeTime=Durée de vie (en jours)
|
||||||
EndOfLife=Fin d'utilisation
|
EndOfLife=Fin d'utilisation
|
||||||
ManufacturingDate=Date de fabrication
|
ManufacturingDate=Date de fabrication
|
||||||
|
|||||||
@ -1,47 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require '../../../main.inc.php';
|
|
||||||
require_once DOL_DOCUMENT_ROOT.'/product/inventory/class/inventory.class.php';
|
|
||||||
|
|
||||||
$get = GETPOST('get', 'alpha');
|
|
||||||
$put = GETPOST('put', 'alpha');
|
|
||||||
|
|
||||||
switch ($put) {
|
|
||||||
case 'qty':
|
|
||||||
if (empty($user->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;
|
|
||||||
}
|
|
||||||
54
htdocs/product/inventory/ajax/searchfrombarcode.php
Normal file
54
htdocs/product/inventory/ajax/searchfrombarcode.php
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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';
|
||||||
|
|
||||||
@ -542,6 +542,7 @@ if ($object->id > 0) {
|
|||||||
print '<script>';
|
print '<script>';
|
||||||
print 'function barcodescannerjs(){
|
print 'function barcodescannerjs(){
|
||||||
console.log("We catch inputs in sacnner box");
|
console.log("We catch inputs in sacnner box");
|
||||||
|
var selectaddorreplace = $("select[name=selectaddorreplace]").val();
|
||||||
var barcodemode = $("input[name=barcodemode]:checked").val();
|
var barcodemode = $("input[name=barcodemode]:checked").val();
|
||||||
var barcodeproductqty = $("input[name=barcodeproductqty]").val();
|
var barcodeproductqty = $("input[name=barcodeproductqty]").val();
|
||||||
var textarea = $("textarea[name=barcodelist]").val();
|
var textarea = $("textarea[name=barcodelist]").val();
|
||||||
@ -565,56 +566,22 @@ if ($object->id > 0) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
tabproduct.push({\'Id\':id,\'Warehouse\':warehouse,\'Barcode\':productbarcode,\'Batch\':productbatchcode,\'Qty\':0});
|
productinput = $("#"+id+"_input").val();
|
||||||
|
if(productinput == ""){
|
||||||
|
productinput = 0
|
||||||
|
}
|
||||||
|
tabproduct.push({\'Id\':id,\'Warehouse\':warehouse,\'Barcode\':productbarcode,\'Batch\':productbatchcode,\'Qty\':productinput});
|
||||||
})
|
})
|
||||||
switch(barcodemode){
|
switch(barcodemode){
|
||||||
case "barcodeforautodetect":
|
case "barcodeforautodetect":
|
||||||
textarray.forEach(function(element,index){
|
barcodeserialforproduct(textarray,tabproduct,barcodeproductqty,selectaddorreplace,"barcode",true);
|
||||||
console.log("Product autodetect "+(index+=1)+": "+element);
|
barcodeserialforproduct(textarray,tabproduct,barcodeproductqty,selectaddorreplace,"lotserial",true);
|
||||||
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;
|
break;
|
||||||
case "barcodeforproduct":
|
case "barcodeforproduct": //TODO: create product !exist + ajout
|
||||||
textarray.forEach(function(element,index){
|
barcodeserialforproduct(textarray,tabproduct,barcodeproductqty,selectaddorreplace,"barcode");
|
||||||
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;
|
break;
|
||||||
case "barcodeforlotserial":
|
case "barcodeforlotserial":
|
||||||
textarray.forEach(function(element,index){
|
barcodeserialforproduct(textarray,tabproduct,barcodeproductqty,selectaddorreplace,"lotserial");
|
||||||
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;
|
break;
|
||||||
default:
|
default:
|
||||||
alert("'.$langs->trans("ErrorWrongBarcodemode").' \""+barcodemode+"\"");
|
alert("'.$langs->trans("ErrorWrongBarcodemode").' \""+barcodemode+"\"");
|
||||||
@ -623,17 +590,50 @@ if ($object->id > 0) {
|
|||||||
tabproduct.forEach(product => {
|
tabproduct.forEach(product => {
|
||||||
if(product.Qty!=0){
|
if(product.Qty!=0){
|
||||||
console.log("We change #"+product.Id+"_input to match input in scanner box");
|
console.log("We change #"+product.Id+"_input to match input in scanner box");
|
||||||
$("#"+product.Id+"_input").val(product.Qty*barcodeproductqty);
|
$("#"+product.Id+"_input").val(product.Qty);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
document.forms["formrecord"].submit();
|
document.forms["formrecord"].submit();
|
||||||
}
|
}
|
||||||
}';
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function barcodeserialforproduct(textarray,tabproduct,barcodeproductqty,selectaddorreplace,mode,autodetect=false){
|
||||||
|
textarray.forEach(function(element,index){
|
||||||
|
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(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;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
';
|
||||||
print '</script>';
|
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("barcodescannerjs");
|
||||||
}
|
}
|
||||||
|
|
||||||
//Call method to undo changes in real qty
|
//Call method to undo changes in real qty
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user