Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop
This commit is contained in:
commit
72dc560ce8
@ -144,6 +144,9 @@ Following changes may create regressions for some external modules, but were nec
|
||||
* Method getDictvalue has been renamed into getDictionaryValue to match camel case rule.
|
||||
* To execute shell or command line command, your code must never use method like exec, shell_exec, popen, .. but must use the built-in
|
||||
method executeCLI() available into core/class/utils.class.php
|
||||
* Class file expeditionbatch.class.php renamed to expeditionlinebatch.class.php
|
||||
* ExpeditionLineBatch::fetchAll is not static anymore and first parameter $db is removed
|
||||
* ExtraFields->showOutputField parameter 4 'extrafieldsobjectkey' is now required
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1488,7 +1488,7 @@ class ExtraFields
|
||||
* @param string $key Key of attribute
|
||||
* @param string $value Value to show
|
||||
* @param string $moreparam To add more parameters on html input tag (only checkbox use html input for output rendering)
|
||||
* @param string $extrafieldsobjectkey If defined (for example $object->table_element), function uses the new method to get extrafields data
|
||||
* @param string $extrafieldsobjectkey Required (for example $object->table_element).
|
||||
* @return string Formated value
|
||||
*/
|
||||
public function showOutputField($key, $value, $moreparam = '', $extrafieldsobjectkey = '')
|
||||
@ -1510,11 +1510,9 @@ class ExtraFields
|
||||
$help = $this->attributes[$extrafieldsobjectkey]['help'][$key];
|
||||
$hidden = (empty($list) ? 1 : 0); // If $list empty, we are sure it is hidden, otherwise we show. If it depends on mode (view/create/edit form or list, this must be filtered by caller)
|
||||
} else {
|
||||
// Old usage
|
||||
$label = $this->attribute_label[$key];
|
||||
$type = $this->attribute_type[$key];
|
||||
$help = ''; // Not supported with old syntax
|
||||
$hidden = (empty($list) ? 1 : 0); // If $list empty, we are sure it is hidden, otherwise we show. If it depends on mode (view/create/edit form or list, this must be filtered by caller)
|
||||
// Old usage not allowed anymore
|
||||
dol_syslog(get_class($this).'::showOutputField extrafieldsobjectkey required', LOG_WARNING);
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($hidden) {
|
||||
|
||||
@ -5042,7 +5042,7 @@ class Form
|
||||
}
|
||||
$formconfirm .= '<br>';
|
||||
|
||||
if (empty($conf->use_javascript_ajax)) {
|
||||
if (!empty($conf->use_javascript_ajax)) {
|
||||
$formconfirm .= '<!-- code to disable button to avoid double clic -->';
|
||||
$formconfirm .= '<script type="text/javascript">'."\n";
|
||||
$formconfirm .= '
|
||||
|
||||
@ -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="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>';
|
||||
|
||||
/*print '<br>'.$langs->trans("or").'<br>';
|
||||
|
||||
@ -1403,6 +1403,9 @@ class Expedition extends CommonObject
|
||||
|
||||
$langs->load("agenda");
|
||||
|
||||
// we try deletion of batch line even if module batch not enabled in case of the module were enabled and disabled previously
|
||||
$shipmentlinebatch = new ExpeditionLineBatch($this->db);
|
||||
|
||||
// Loop on each product line to add a stock movement
|
||||
$sql = "SELECT cd.fk_product, cd.subprice, ed.qty, ed.fk_entrepot, ed.rowid as expeditiondet_id";
|
||||
$sql .= " FROM ".MAIN_DB_PREFIX."commandedet as cd,";
|
||||
@ -1422,12 +1425,9 @@ class Expedition extends CommonObject
|
||||
// we do not log origin because it will be deleted
|
||||
$mouvS->origin = null;
|
||||
// get lot/serial
|
||||
$lotArray = null;
|
||||
if ($conf->productbatch->enabled) {
|
||||
$lotArray = ExpeditionLineBatch::fetchAll($this->db, $obj->expeditiondet_id);
|
||||
if (!is_array($lotArray)) {
|
||||
$error++; $this->errors[] = "Error ".$this->db->lasterror();
|
||||
}
|
||||
$lotArray = $shipmentlinebatch->fetchAll($obj->expeditiondet_id);
|
||||
if (!is_array($lotArray)) {
|
||||
$error++; $this->errors[] = "Error ".$this->db->lasterror();
|
||||
}
|
||||
if (empty($lotArray)) {
|
||||
// no lot/serial
|
||||
@ -1458,9 +1458,8 @@ class Expedition extends CommonObject
|
||||
}
|
||||
}
|
||||
|
||||
// delete batch expedition line (we try deletion even if module not enabled in case of the module were enabled and disabled previously)
|
||||
// delete batch expedition line
|
||||
if (!$error) {
|
||||
$shipmentlinebatch = ExpeditionLineBatch($this->db);
|
||||
if ($shipmentlinebatch->deleteFromShipment($this->id) < 0) {
|
||||
$error++; $this->errors[] = "Error ".$this->db->lasterror();
|
||||
}
|
||||
|
||||
@ -1098,6 +1098,7 @@ if (empty($reshook)) {
|
||||
$arrayoffiles = GETPOST('attachfile', 'array');
|
||||
if (is_array($arrayoffiles) && !empty($arrayoffiles[0])) {
|
||||
include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php';
|
||||
$entityprefix = ($conf->entity != '1') ? $conf->entity.'/' : '';
|
||||
$relativepath = 'expensereport/'.$object->ref.'/'.$arrayoffiles[0];
|
||||
$ecmfiles = new EcmFiles($db);
|
||||
$ecmfiles->fetch(0, '', $relativepath);
|
||||
|
||||
@ -410,7 +410,13 @@ class Skill extends CommonObject
|
||||
$skilldet = new Skilldet($this->db);
|
||||
$this->lines = $skilldet->fetchAll('ASC', '', '', '', array('fk_skill' => $this->id), '');
|
||||
|
||||
return (count($this->lines) > 0 ) ? $this->lines : array();
|
||||
if (is_array($this->lines)) {
|
||||
return (count($this->lines) > 0) ? $this->lines : array();
|
||||
} elseif ($this->lines < 0) {
|
||||
$this->errors = array_merge($this->errors, $skilldet->errors);
|
||||
$this->error = $skilldet->error;
|
||||
return $this->lines;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -113,46 +113,50 @@ function displayRankInfos($selected_rank, $fk_skill, $inputname = 'TNote', $mode
|
||||
|
||||
// On charge les différentes notes possibles pour la compétence $fk_skill
|
||||
$skilldet = new Skilldet($db);
|
||||
$Lines = $skilldet->fetchAll('ASC', 'rank', 0, 0, array('customsql'=>'fk_skill = '.$fk_skill));
|
||||
$Lines = $skilldet->fetchAll('ASC', 'rankorder', 0, 0, array('customsql'=>'fk_skill = '.$fk_skill));
|
||||
|
||||
if (!is_array($Lines) && $Lines<0) {
|
||||
setEventMessages($skilldet->error, $skilldet->errors, 'errors');
|
||||
}
|
||||
if (empty($Lines)) return $langs->trans('SkillHasNoLines');
|
||||
|
||||
$ret = '<!-- field jquery --><span title="'.$langs->trans('NA').'" class="radio_js_bloc_number '.$inputname.'_'.$fk_skill.(empty($selected_rank) ? ' selected' : '').'">0</span>';
|
||||
if (is_array($Lines) && !empty($Lines)) {
|
||||
foreach ($Lines as $line) {
|
||||
$MaxNumberSkill = isset($conf->global->HRM_MAXRANK) ? $conf->global->HRM_MAXRANK : Skill::DEFAULT_MAX_RANK_PER_SKILL;
|
||||
if ($line->rank > $MaxNumberSkill) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($Lines as $line) {
|
||||
$MaxNumberSkill = isset($conf->global->HRM_MAXRANK) ? $conf->global->HRM_MAXRANK : Skill::DEFAULT_MAX_RANK_PER_SKILL;
|
||||
if ($line->rank > $MaxNumberSkill) {
|
||||
continue;
|
||||
$ret .= '<span title="' . $line->description . '" class="radio_js_bloc_number ' . $inputname . '_' . $line->fk_skill;
|
||||
$ret .= $line->rank == $selected_rank ? ' selected' : '';
|
||||
$ret .= '">' . $line->rank . '</span>';
|
||||
}
|
||||
|
||||
$ret.= '<span title="'.$line->description.'" class="radio_js_bloc_number '.$inputname.'_'.$line->fk_skill;
|
||||
$ret.= $line->rank == $selected_rank ? ' selected' : '';
|
||||
$ret.= '">'.$line->rank.'</span>';
|
||||
}
|
||||
|
||||
if ($mode == 'edit') {
|
||||
$ret.= '
|
||||
<input type="hidden" id="'.$inputname.'_'.$fk_skill.'" name="'.$inputname.'['.$fk_skill.']" value="'.$selected_rank.'">
|
||||
if ($mode == 'edit') {
|
||||
$ret .= '
|
||||
<input type="hidden" id="' . $inputname . '_' . $fk_skill . '" name="' . $inputname . '[' . $fk_skill . ']" value="' . $selected_rank . '">
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
$(".radio_js_bloc_number").tooltip();
|
||||
var error,same;
|
||||
$(".'.$inputname.'_'.$fk_skill.'").on("click",function(){
|
||||
$(".' . $inputname . '_' . $fk_skill . '").on("click",function(){
|
||||
same=false;
|
||||
val = $(this).html();
|
||||
if($(this).hasClass("selected"))same=true;
|
||||
$(".'.$inputname.'_'.$fk_skill.'").removeClass("selected");
|
||||
$(".' . $inputname . '_' . $fk_skill . '").removeClass("selected");
|
||||
if(same)
|
||||
{
|
||||
$("#'.$inputname.'_'.$fk_skill.'").val("");
|
||||
$("#' . $inputname . '_' . $fk_skill . '").val("");
|
||||
}else {
|
||||
$(this).addClass("selected");
|
||||
$("#'.$inputname.'_'.$fk_skill.'").val(val);
|
||||
$("#' . $inputname . '_' . $fk_skill . '").val(val);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
</script>';
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
InventoryStartedShort=Started
|
||||
ErrorOnElementsInventory=Scan was aborted due to following barcode or batch number on error
|
||||
@ -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
|
||||
|
||||
@ -92,8 +92,8 @@ class mymodulewidget1 extends ModeleBoxes
|
||||
public function __construct(DoliDB $db, $param = '')
|
||||
{
|
||||
global $user, $conf, $langs;
|
||||
$langs->load("boxes");
|
||||
$langs->load('mymodule@mymodule');
|
||||
// Translations
|
||||
$langs->loadLangs(array("boxes", "mymodule@mymodule"));
|
||||
|
||||
parent::__construct($db, $param);
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
135
htdocs/product/inventory/ajax/searchfrombarcode.php
Normal file
135
htdocs/product/inventory/ajax/searchfrombarcode.php
Normal file
@ -0,0 +1,135 @@
|
||||
<?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('NOREQUIREMENU')) {
|
||||
define('NOREQUIREMENU', '1');
|
||||
}
|
||||
if (!defined('NOREQUIREHTML')) {
|
||||
define('NOREQUIREHTML', '1');
|
||||
}
|
||||
if (!defined('NOREQUIREAJAX')) {
|
||||
define('NOREQUIREAJAX', '1');
|
||||
}
|
||||
if (!defined('NOREQUIRESOC')) {
|
||||
define('NOREQUIRESOC', '1');
|
||||
}
|
||||
if (!defined('NOCSRFCHECK')) {
|
||||
define('NOCSRFCHECK', '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");
|
||||
$batch = GETPOST("batch", "int");
|
||||
$mode = GETPOST("mode", "aZ");
|
||||
|
||||
$warehousefound = 0;
|
||||
$warehouseid = 0;
|
||||
$objectreturn = array();
|
||||
|
||||
if ($action == "existbarcode" && !empty($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)."'";
|
||||
}
|
||||
if (!empty($fk_product)) {
|
||||
$sql .= " AND ps.fk_product = '".$db->escape($fk_product)."'";
|
||||
}
|
||||
$result = $db->query($sql);
|
||||
if ($result) {
|
||||
$nbline = $db->num_rows($result);
|
||||
for ($i=0; $i < $nbline; $i++) {
|
||||
$object = $db->fetch_object($result);
|
||||
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++;
|
||||
$warehouseid = $object->fk_entrepot;
|
||||
$fk_product = $object->fk_product;
|
||||
$reelqty = $object->reel;
|
||||
|
||||
$objectreturn = array('fk_warehouse'=>$warehouseid,'fk_product'=>$fk_product,'reelqty'=>$reelqty);
|
||||
}
|
||||
}
|
||||
}
|
||||
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','object'=>$objectreturn);
|
||||
}
|
||||
} else {
|
||||
$response = array('status'=>'error','errorcode'=>'NotFound','message'=>"No results found for 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;
|
||||
if (!empty($batch)) {
|
||||
$inventoryline->batch = $batch;
|
||||
}
|
||||
$inventoryline->datec = dol_now();
|
||||
|
||||
$result = $inventoryline->create($user);
|
||||
if ($result > 0) {
|
||||
$response = array('status'=>'success','message'=>'Success on creating line','id_line'=>$result);
|
||||
} 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;
|
||||
@ -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';
|
||||
|
||||
|
||||
@ -452,7 +452,7 @@ if ($object->id > 0) {
|
||||
print dol_get_fiche_end();
|
||||
|
||||
|
||||
print '<form name="formrecord" method="POST" action="'.$_SERVER["PHP_SELF"].'">';
|
||||
print '<form id="formrecord" name="formrecord" method="POST" action="'.$_SERVER["PHP_SELF"].'">';
|
||||
print '<input type="hidden" name="token" value="'.newToken().'">';
|
||||
print '<input type="hidden" name="action" value="updateinventorylines">';
|
||||
print '<input type="hidden" name="id" value="'.$object->id.'">';
|
||||
@ -541,14 +541,18 @@ if ($object->id > 0) {
|
||||
if ($action == 'updatebyscaning') {
|
||||
if ($permissiontoadd) {
|
||||
print '<script>';
|
||||
print 'function barcodescannerjs(){
|
||||
|
||||
print '
|
||||
var errortab = [];
|
||||
function barcodescannerjs(){
|
||||
console.log("We catch inputs in sacnner box");
|
||||
var selectaddorreplace = $("select[name=selectaddorreplace]").val();
|
||||
var barcodemode = $("input[name=barcodemode]:checked").val();
|
||||
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();
|
||||
@ -560,81 +564,147 @@ if ($object->id > 0) {
|
||||
productbatchcode = $("#"+id+"_batch").text();
|
||||
if(barcodemode != "barcodeforproduct"){
|
||||
tabproduct.forEach(product=>{
|
||||
if(product.Batch == productbatchcode){
|
||||
alert("'.$langs->trans('ErrorSameBatchNumber').': "+productbatchcode);
|
||||
throw"'.$langs->trans('ErrorSameBatchNumber').': "+productbatchcode;
|
||||
if(product.Batch != "" && product.Batch == productbatchcode){
|
||||
alert("'.$langs->transnoentities('ErrorSameBatchNumber').': "+productbatchcode);
|
||||
throw"'.$langs->transnoentities('ErrorSameBatchNumber').': "+productbatchcode;
|
||||
}
|
||||
})
|
||||
}
|
||||
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,\'fetched\':false});
|
||||
})
|
||||
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);
|
||||
textarray.forEach(function(element,index){
|
||||
var verify_batch = false;
|
||||
var verify_barcode = false;
|
||||
switch(barcodemode){
|
||||
case "barcodeforautodetect":
|
||||
verify_barcode = barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,selectaddorreplace,"barcode",true);
|
||||
verify_batch = barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,selectaddorreplace,"lotserial",true);
|
||||
break;
|
||||
case "barcodeforproduct":
|
||||
barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,selectaddorreplace,"barcode");
|
||||
break;
|
||||
case "barcodeforlotserial":
|
||||
barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,selectaddorreplace,"lotserial");
|
||||
break;
|
||||
default:
|
||||
alert("'.$langs->trans("ErrorWrongBarcodemode").' \""+barcodemode+"\"");
|
||||
throw "'.$langs->trans('ErrorWrongBarcodemode').' \""+barcodemode+"\"";
|
||||
}
|
||||
if(verify_batch == true && verify_barcode == true){
|
||||
errortab.push(element);
|
||||
}
|
||||
});
|
||||
if (Object.keys(errortab).length < 1){
|
||||
tabproduct.forEach(product => {
|
||||
if(product.Qty!=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":product.Batch,"fk_inventory":'.dol_escape_js($object->id).',"fk_product":product.fk_product,"reelqty":product.reelqty},
|
||||
type: \'POST\',
|
||||
async: false,
|
||||
success: function(response) {
|
||||
response = JSON.parse(response);
|
||||
if(response.status == "success"){
|
||||
console.log(response.message);
|
||||
$("<input type=\'text\' value=\'"+product.Qty+"\' />")
|
||||
.attr("id", "id_"+response.id_line+"_input")
|
||||
.attr("name", "id_"+response.id_line)
|
||||
.appendTo("#formrecord");
|
||||
}else{
|
||||
console.error(response.message);
|
||||
}
|
||||
},
|
||||
error : function(output) {
|
||||
console.error("Error on line creation function");
|
||||
},
|
||||
});
|
||||
} else {
|
||||
$("#"+product.Id+"_input").val(product.Qty);
|
||||
}
|
||||
})
|
||||
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+"\"";
|
||||
}
|
||||
})
|
||||
document.forms["formrecord"].submit();
|
||||
}else{
|
||||
let stringerror = "";
|
||||
errortab.forEach(element => {
|
||||
stringerror += (element + ",")
|
||||
});
|
||||
stringerror = stringerror.slice(0, -1);
|
||||
alert("'.$langs->trans("ErrorOnElementsInventory").' :\n" + stringerror);
|
||||
}
|
||||
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();
|
||||
}
|
||||
}';
|
||||
|
||||
}
|
||||
|
||||
function barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,selectaddorreplace,mode,autodetect=false){
|
||||
BarcodeIsInProduct=0;
|
||||
newproductrow=0
|
||||
result=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.',':'').(!empty($object->fk_product)?'"fk_product":'.$object->fk_product.',':'').'"barcode":element,"product":product,"mode":mode},
|
||||
type: \'POST\',
|
||||
async: false,
|
||||
success: function(response) {
|
||||
response = JSON.parse(response);
|
||||
if(response.status == "success"){
|
||||
console.log(response.message);
|
||||
if(!newproductrow){
|
||||
newproductrow = response.object;
|
||||
}
|
||||
}else{
|
||||
if (mode!="lotserial" && autodetect==false && !errortab.includes(element)){
|
||||
errortab.push(element);
|
||||
console.error(response.message);
|
||||
}
|
||||
}
|
||||
},
|
||||
error : function(output) {
|
||||
console.error("Error on barcodeserialforproduct function");
|
||||
},
|
||||
});
|
||||
console.log("Product "+(index+=1)+": "+element);
|
||||
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 + parseInt(barcodeproductqty,10);
|
||||
}else if(selectaddorreplace == "replace"){
|
||||
if(product.fetched == false){
|
||||
product.Qty = barcodeproductqty
|
||||
product.fetched=true
|
||||
}else{
|
||||
productqty = parseInt(product.Qty,10);
|
||||
product.Qty = productqty + parseInt(barcodeproductqty,10);
|
||||
}
|
||||
}
|
||||
BarcodeIsInProduct+=1;
|
||||
}
|
||||
})
|
||||
if(BarcodeIsInProduct==0 && newproductrow!=0){
|
||||
tabproduct.push({\'Id\':tabproduct.length-1,\'Warehouse\':newproductrow.fk_warehouse,\'Barcode\':mode=="barcode"?element:null,\'Batch\':mode=="lotserial"?element:null,\'Qty\':barcodeproductqty,\'fetched\':true,\'reelqty\':newproductrow.reelqty,\'fk_product\':newproductrow.fk_product,\'mode\':mode});
|
||||
result = true;
|
||||
}
|
||||
if(BarcodeIsInProduct > 0){
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
';
|
||||
print '</script>';
|
||||
}
|
||||
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
|
||||
|
||||
@ -125,15 +125,17 @@ if (GETPOST('newcompany') || GETPOST('socid', 'int') || GETPOST('id_fourn', 'int
|
||||
if ($resql) {
|
||||
while ($row = $db->fetch_array($resql)) {
|
||||
$label = '';
|
||||
if ($conf->global->SOCIETE_ADD_REF_IN_LIST) {
|
||||
if (! empty($conf->global->SOCIETE_ADD_REF_IN_LIST)) {
|
||||
if (($row['client']) && (!empty($row['code_client']))) {
|
||||
$label = $row['code_client'].' - ';
|
||||
}
|
||||
if (($row['fournisseur']) && (!empty($row['code_fournisseur']))) {
|
||||
$label .= $row['code_fournisseur'].' - ';
|
||||
}
|
||||
$label .= ' '.$row['name'];
|
||||
}
|
||||
|
||||
$label .= $row['nom'];
|
||||
|
||||
if (!empty($conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST)) {
|
||||
$label .= ($row['address'] ? ' - '.$row['address'] : '').($row['zip'] ? ' - '.$row['zip'] : '').($row['town'] ? ' '.$row['town'] : '');
|
||||
if (!empty($row['country_code'])) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user