diff --git a/htdocs/admin/expensereport.php b/htdocs/admin/expensereport.php
index 97ce21ab585..1dd5166e1cb 100644
--- a/htdocs/admin/expensereport.php
+++ b/htdocs/admin/expensereport.php
@@ -207,24 +207,26 @@ $head=expensereport_admin_prepare_head();
dol_fiche_head($head, 'expensereport', $langs->trans("ExpenseReports"), -1, 'trip');
-// Interventions numbering model
/*
-print load_fiche_titre($langs->trans("FicheinterNumberingModules"),'','');
+ * Expense report numbering model
+ */
+
+print load_fiche_titre($langs->trans("ExpenseReportNumberingModules"),'','');
print '
';
print '';
-print '| '.$langs->trans("Name").' | ';
+print ''.$langs->trans("Name").' | ';
print ''.$langs->trans("Description").' | ';
-print ''.$langs->trans("Example").' | ';
+print ''.$langs->trans("Example").' | ';
print ''.$langs->trans("Status").' | ';
-print ''.$langs->trans("ShortInfo").' | ';
-print "
\n";
+print ''.$langs->trans("ShortInfo").' | ';
+print ''."\n";
clearstatcache();
foreach ($dirmodels as $reldir)
{
- $dir = dol_buildpath($reldir."core/modules/fichinter/");
+ $dir = dol_buildpath($reldir."core/modules/expensereport/");
if (is_dir($dir))
{
@@ -235,21 +237,20 @@ foreach ($dirmodels as $reldir)
while (($file = readdir($handle))!==false)
{
- if (preg_match('/^(mod_.*)\.php$/i',$file,$reg))
+ if (substr($file, 0, 18) == 'mod_expensereport_' && substr($file, dol_strlen($file)-3, 3) == 'php')
{
- $file = $reg[1];
- $classname = substr($file,4);
+ $file = substr($file, 0, dol_strlen($file)-4);
require_once $dir.$file.'.php';
- $module = new $file;
+ $module = new $file($db);
+
+ // Show modules according to features level
+ if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) continue;
+ if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) continue;
if ($module->isEnabled())
{
- // Show modules according to features level
- if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) continue;
- if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) continue;
-
print '| '.$module->nom." | \n";
print $module->info();
@@ -264,24 +265,26 @@ foreach ($dirmodels as $reldir)
print ' | '."\n";
print '';
- if ($conf->global->FICHEINTER_ADDON == $classname)
+ if ($conf->global->EXPENSEREPORT_ADDON == $file)
{
print img_picto($langs->trans("Activated"),'switch_on');
}
else
{
- print ''.img_picto($langs->trans("Disabled"),'switch_off').'';
+ print '';
+ print img_picto($langs->trans("Disabled"),'switch_off');
+ print '';
}
print ' | ';
- $ficheinter=new Fichinter($db);
- $ficheinter->initAsSpecimen();
+ $exp=new ExpenseReport($db);
+ $exp->initAsSpecimen();
// Info
$htmltooltip='';
$htmltooltip.=''.$langs->trans("Version").': '.$module->getVersion().'
';
- $nextval=$module->getNextValue($mysoc,$ficheinter);
- if ("$nextval" != $langs->trans("NotAvailable")) { // Keep " on nextval
+ $nextval=$module->getNextValue($exp);
+ if ("$nextval" != $langs->trans("NotAvailable")) { // Keep " on nextval
$htmltooltip.=''.$langs->trans("NextValue").': ';
if ($nextval) {
if (preg_match('/^Error/',$nextval) || $nextval=='NotConfigured')
@@ -291,11 +294,12 @@ foreach ($dirmodels as $reldir)
$htmltooltip.=$langs->trans($module->error).'
';
}
}
+
print '';
print $form->textwithpicto('',$htmltooltip,1,0);
print ' | ';
- print '
';
+ print "\n";
}
}
}
@@ -303,9 +307,7 @@ foreach ($dirmodels as $reldir)
}
}
}
-
-print '
';
-*/
+print "
\n";
/*
* Documents models for Interventions
diff --git a/htdocs/core/modules/expensereport/index.html b/htdocs/core/modules/expensereport/index.html
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/htdocs/core/modules/expensereport/mod_expensereport_jade.php b/htdocs/core/modules/expensereport/mod_expensereport_jade.php
new file mode 100644
index 00000000000..3ccfc8748cb
--- /dev/null
+++ b/htdocs/core/modules/expensereport/mod_expensereport_jade.php
@@ -0,0 +1,134 @@
+
+ *
+ * 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 .
+ * or see http://www.gnu.org/
+ */
+
+/**
+ * \file htdocs/core/modules/expensereport/mod_expensereport_jade.php
+ * \ingroup expensereport
+ * \brief File of class to manage customer order numbering rules Jade
+ */
+require_once DOL_DOCUMENT_ROOT .'/core/modules/expensereport/modules_expensereport.php';
+
+/**
+ * Class to manage customer order numbering rules Jade
+ */
+class mod_expensereport_jade extends ModeleNumRefExpenseReport
+{
+ var $version='dolibarr'; // 'development', 'experimental', 'dolibarr'
+ var $prefix='ER';
+ var $error='';
+ var $nom='Jade';
+
+
+ /**
+ * Return description of numbering module
+ *
+ * @return string Text with description
+ */
+ function info()
+ {
+ global $langs;
+ return $langs->trans("SimpleNumRefModelDesc",$this->prefix);
+ }
+
+
+ /**
+ * Renvoi un exemple de numerotation
+ *
+ * @return string Example
+ */
+ function getExample()
+ {
+ return $this->prefix."0501-0001";
+ }
+
+
+ /**
+ * Test si les numeros deje en vigueur dans la base ne provoquent pas de
+ * de conflits qui empechera cette numerotation de fonctionner.
+ *
+ * @return boolean false si conflit, true si ok
+ */
+ function canBeActivated()
+ {
+ global $conf,$langs,$db;
+
+ $coyymm=''; $max='';
+
+ $posindice=8;
+ $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max";
+ $sql.= " FROM ".MAIN_DB_PREFIX."expensereport";
+ $sql.= " WHERE ref LIKE '".$this->prefix."____-%'";
+ $sql.= " AND entity = ".$conf->entity;
+
+ $resql=$db->query($sql);
+ if ($resql)
+ {
+ $row = $db->fetch_row($resql);
+ if ($row) { $coyymm = substr($row[0],0,6); $max=$row[0]; }
+ }
+ if ($coyymm && ! preg_match('/'.$this->prefix.'[0-9][0-9][0-9][0-9]/i',$coyymm))
+ {
+ $langs->load("errors");
+ $this->error=$langs->trans('ErrorNumRefModel', $max);
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Return next free value
+ *
+ * @param Object $object Object we need next value for
+ * @return string Value if KO, <0 if KO
+ */
+ function getNextValue($object)
+ {
+ global $db,$conf;
+
+ // D'abord on recupere la valeur max
+ $posindice=8;
+ $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max";
+ $sql.= " FROM ".MAIN_DB_PREFIX."expensereport";
+ $sql.= " WHERE ref like '".$this->prefix."____-%'";
+ $sql.= " AND entity = ".$conf->entity;
+
+ $resql=$db->query($sql);
+ if ($resql)
+ {
+ $obj = $db->fetch_object($resql);
+ if ($obj) $max = intval($obj->max);
+ else $max=0;
+ }
+ else
+ {
+ dol_syslog("mod_expensereport_jade::getNextValue", LOG_DEBUG);
+ return -1;
+ }
+
+ //$date=time();
+ $date=$object->date;
+ $yymm = strftime("%y%m",$date);
+
+ if ($max >= (pow(10, 4) - 1)) $num=$max+1; // If counter > 9999, we do not format on 4 chars, we take number as it is
+ else $num = sprintf("%04s",$max+1);
+
+ dol_syslog("mod_expensereport_jade::getNextValue return ".$this->prefix.$yymm."-".$num);
+ return $this->prefix.$yymm."-".$num;
+ }
+}
diff --git a/htdocs/core/modules/expensereport/mod_expensereport_sand.php b/htdocs/core/modules/expensereport/mod_expensereport_sand.php
new file mode 100644
index 00000000000..9a638694665
--- /dev/null
+++ b/htdocs/core/modules/expensereport/mod_expensereport_sand.php
@@ -0,0 +1,126 @@
+
+ *
+ * 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 .
+ * or see http://www.gnu.org/
+ */
+
+/**
+ * \file htdocs/core/modules/expensereport/mod_expensereport_sand.php
+ * \ingroup expensereport
+ * \brief Fichier contenant la classe du modele de numerotation de reference de note de frais Sand
+ */
+
+require_once DOL_DOCUMENT_ROOT .'/core/modules/expensereport/modules_expensereport.php';
+
+
+/**
+ * Class to manage expense report numbering rules Sand
+ */
+class mod_expensereport_sand extends ModeleNumRefExpenseReport
+{
+ var $version='dolibarr'; // 'development', 'experimental', 'dolibarr'
+ var $error = '';
+ var $nom = 'Sand';
+
+
+ /**
+ * Renvoi la description du modele de numerotation
+ *
+ * @return string Texte descripif
+ */
+ function info()
+ {
+ global $conf,$langs;
+
+ $langs->load("bills");
+
+ $form = new Form($this->db);
+
+ $texte = $langs->trans('GenericNumRefModelDesc')."
\n";
+ $texte.= '';
+
+ return $texte;
+ }
+
+ /**
+ * Renvoi un exemple de numerotation
+ *
+ * @return string Example
+ */
+ function getExample()
+ {
+ global $conf,$langs,$mysoc;
+
+ $old_code_client=$mysoc->code_client;
+ $mysoc->code_client='CCCCCCCCCC';
+ $numExample = $this->getNextValue($mysoc,'');
+ $mysoc->code_client=$old_code_client;
+
+ if (! $numExample)
+ {
+ $numExample = $langs->trans('NotConfigured');
+ }
+ return $numExample;
+ }
+
+ /**
+ * Return next free value
+ *
+ * @param Societe $objsoc Object thirdparty
+ * @param Object $object Object we need next value for
+ * @return string Value if KO, <0 if KO
+ */
+ function getNextValue($objsoc,$object)
+ {
+ global $db,$conf;
+
+ require_once DOL_DOCUMENT_ROOT .'/core/lib/functions2.lib.php';
+
+ // We get cursor rule
+ $mask=$conf->global->EXPENSEREPORT_SAND_MASK;
+
+ if (! $mask)
+ {
+ $this->error='NotConfigured';
+ return 0;
+ }
+
+ $numFinal=get_next_value($db,$mask,'expensereport','ref','',$objsoc,$object->date);
+
+ return $numFinal;
+ }
+}
+
diff --git a/htdocs/core/modules/expensereport/modules_expensereport.php b/htdocs/core/modules/expensereport/modules_expensereport.php
index 153dfb37007..e0adf1fb47e 100644
--- a/htdocs/core/modules/expensereport/modules_expensereport.php
+++ b/htdocs/core/modules/expensereport/modules_expensereport.php
@@ -65,3 +65,87 @@ function expensereport_pdf_create(DoliDB $db, ExpenseReport $object, $message, $
{
return $object->generateDocument($modele, $outputlangs, $hidedetails, $hidedesc, $hideref);
}
+
+/**
+ * \class ModeleNumRefExpenseReport
+ * \brief Parent class for numbering masks of expense reports
+ */
+
+abstract class ModeleNumRefExpenseReport
+{
+ var $error='';
+
+ /**
+ * Return if a module can be used or not
+ *
+ * @return boolean true if module can be used
+ */
+ function isEnabled()
+ {
+ return true;
+ }
+
+ /**
+ * Renvoie la description par defaut du modele de numerotation
+ *
+ * @return string Texte descripif
+ */
+ function info()
+ {
+ global $langs;
+ $langs->load("orders");
+ return $langs->trans("NoDescription");
+ }
+
+ /**
+ * Renvoie un exemple de numerotation
+ *
+ * @return string Example
+ */
+ function getExample()
+ {
+ global $langs;
+ $langs->load("trips");
+ return $langs->trans("NoExample");
+ }
+
+ /**
+ * Test si les numeros deja en vigueur dans la base ne provoquent pas de conflits qui empecheraient cette numerotation de fonctionner.
+ *
+ * @return boolean false si conflit, true si ok
+ */
+ function canBeActivated()
+ {
+ return true;
+ }
+
+ /**
+ * Renvoie prochaine valeur attribuee
+ *
+ * @param Societe $objsoc Object thirdparty
+ * @param Object $object Object we need next value for
+ * @return string Valeur
+ */
+ function getNextValue($objsoc,$object)
+ {
+ global $langs;
+ return $langs->trans("NotAvailable");
+ }
+
+ /**
+ * Renvoie version du module numerotation
+ *
+ * @return string Valeur
+ */
+ function getVersion()
+ {
+ global $langs;
+ $langs->load("admin");
+
+ if ($this->version == 'development') return $langs->trans("VersionDevelopment");
+ if ($this->version == 'experimental') return $langs->trans("VersionExperimental");
+ if ($this->version == 'dolibarr') return DOL_VERSION;
+ if ($this->version) return $this->version;
+ return $langs->trans("NotAvailable");
+ }
+}
\ No newline at end of file
diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php
index cd3c104d98e..1e4d7e3bba1 100644
--- a/htdocs/expensereport/class/expensereport.class.php
+++ b/htdocs/expensereport/class/expensereport.class.php
@@ -1057,111 +1057,114 @@ class ExpenseReport extends CommonObject
*/
function setValidate($fuser, $notrigger=0)
{
- global $conf,$langs;
+ global $conf,$langs,$user;
$error = 0;
- $this->oldref = $this->ref;
- $expld_car = (empty($conf->global->NDF_EXPLODE_CHAR))?"-":$conf->global->NDF_EXPLODE_CHAR;
-
- // Sélection de la date de début de la NDF
- $sql = 'SELECT date_debut';
- $sql.= ' FROM '.MAIN_DB_PREFIX.$this->table_element;
- $sql.= ' WHERE rowid = '.$this->id;
- $result = $this->db->query($sql);
- $objp = $this->db->fetch_object($result);
- $this->date_debut = $this->db->jdate($objp->date_debut);
-
- $update_number_int = false;
-
- // Create next ref if ref is PROVxx
- // Rename directory if dir was a temporary ref
- if (preg_match('/^[\(]?PROV/i', $this->ref))
+
+ // Protection
+ if ($this->statut == self::STATUS_VALIDATED)
{
- // Sélection du numéro de ref suivant
- $ref_next = $this->getNextNumRef();
- $ref_number_int = ($this->ref+1)-1;
- $update_number_int = true;
- // Création du ref_number suivant
- if($ref_next)
- {
- $prefix="ER";
- if (! empty($conf->global->EXPENSE_REPORT_PREFIX)) $prefix=$conf->global->EXPENSE_REPORT_PREFIX;
- $this->ref = str_replace(' ','_', $this->user_author_infos).$expld_car.$prefix.$this->ref.$expld_car.dol_print_date($this->date_debut,'%y%m%d');
- }
- require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
- // We rename directory in order to avoid losing the attachments
- $oldref = dol_sanitizeFileName($this->oldref);
- $newref = dol_sanitizeFileName($this->ref);
- $dirsource = $conf->expensereport->dir_output.'/'.$oldref;
- $dirdest = $conf->expensereport->dir_output.'/'.$newref;
- if (file_exists($dirsource))
- {
- dol_syslog(get_class($this)."::setValidate() rename dir ".$dirsource." into ".$dirdest);
-
- if (@rename($dirsource, $dirdest))
- {
- dol_syslog("Rename ok");
- // Rename docs starting with $oldref with $newref
- $listoffiles=dol_dir_list($conf->expensereport->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref,'/'));
- foreach($listoffiles as $fileentry)
- {
- $dirsource=$fileentry['name'];
- $dirdest=preg_replace('/^'.preg_quote($oldref,'/').'/',$newref, $dirsource);
- $dirsource=$fileentry['path'].'/'.$dirsource;
- $dirdest=$fileentry['path'].'/'.$dirdest;
- @rename($dirsource, $dirdest);
- }
- }
- }
+ dol_syslog(get_class($this)."::valid action abandonned: already validated", LOG_WARNING);
+ return 0;
}
- if ($this->fk_statut != 2)
+
+ // Define new ref
+ if (! $error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) // empty should not happened, but when it occurs, the test save life
{
- $now = dol_now();
- $this->db->begin();
+ $num = $this->getNextNumRef();
+ }
+ else
+ {
+ $num = $this->ref;
+ }
+ $this->newref = $num;
+
+ $now = dol_now();
+ $this->db->begin();
- $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
- $sql.= " SET ref = '".$this->db->escape($this->ref)."', fk_statut = 2, fk_user_valid = ".$fuser->id.", date_valid='".$this->db->idate($now)."'";
- if ($update_number_int) {
- $sql.= ", ref_number_int = ".$ref_number_int;
- }
- $sql.= ' WHERE rowid = '.$this->id;
+ // Validate
+ $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
+ $sql.= " SET ref = '".$num."',";
+ $sql.= " fk_statut = ".self::STATUS_VALIDATED.",";
+ $sql.= " date_valid='".$this->db->idate($now)."',";
+ $sql.= " fk_user_valid = ".$user->id;
+ $sql.= " WHERE rowid = ".$this->id;
- $resql=$this->db->query($sql);
- if ($resql)
- {
- if (!$notrigger)
- {
- // Call trigger
- $result=$this->call_trigger('EXPENSE_REPORT_VALIDATE',$fuser);
+ $resql=$this->db->query($sql);
+ if ($resql)
+ {
+ if (!$notrigger)
+ {
+ // Call trigger
+ $result=$this->call_trigger('EXPENSE_REPORT_VALIDATE',$fuser);
- if ($result < 0) {
- $error++;
+ if ($result < 0) {
+ $error++;
+ }
+ // End call triggers
+ }
+
+ if (! $error)
+ {
+ $this->oldref = $this->ref;
+
+ // Rename directory if dir was a temporary ref
+ if (preg_match('/^[\(]?PROV/i', $this->ref))
+ {
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+
+ // On renomme repertoire ($this->ref = ancienne ref, $num = nouvelle ref)
+ // in order not to lose the attachments
+ $oldref = dol_sanitizeFileName($this->ref);
+ $newref = dol_sanitizeFileName($num);
+ $dirsource = $conf->expensereport->dir_output.'/'.$oldref;
+ $dirdest = $conf->expensereport->dir_output.'/'.$newref;
+ if (file_exists($dirsource))
+ {
+ dol_syslog(get_class($this)."::valid() rename dir ".$dirsource." into ".$dirdest);
+
+ if (@rename($dirsource, $dirdest))
+ {
+ dol_syslog("Rename ok");
+ // Rename docs starting with $oldref with $newref
+ $listoffiles=dol_dir_list($conf->expensereport->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref,'/'));
+ foreach($listoffiles as $fileentry)
+ {
+ $dirsource=$fileentry['name'];
+ $dirdest=preg_replace('/^'.preg_quote($oldref,'/').'/',$newref, $dirsource);
+ $dirsource=$fileentry['path'].'/'.$dirsource;
+ $dirdest=$fileentry['path'].'/'.$dirdest;
+ @rename($dirsource, $dirdest);
+ }
+ }
}
- // End call triggers
}
+ }
- if (empty($error))
- {
- $this->db->commit();
- return 1;
- }
- else
- {
- $this->db->rollback();
- $this->error=$this->db->error();
- return -2;
- }
- }
- else
- {
+ // Set new ref and current status
+ if (! $error)
+ {
+ $this->ref = $num;
+ $this->statut = self::STATUS_VALIDATED;
+ }
+
+ if (empty($error))
+ {
+ $this->db->commit();
+ return 1;
+ }
+ else
+ {
$this->db->rollback();
- $this->error=$this->db->lasterror();
- return -1;
- }
+ $this->error=$this->db->error();
+ return -2;
+ }
}
else
{
- dol_syslog(get_class($this)."::setValidate expensereport already with validated status", LOG_WARNING);
+ $this->db->rollback();
+ $this->error=$this->db->lasterror();
+ return -1;
}
return 0;
@@ -1466,36 +1469,51 @@ class ExpenseReport extends CommonObject
*/
function getNextNumRef()
{
- global $conf;
+ global $langs, $conf;
+ $langs->load("trips");
- $expld_car = (empty($conf->global->NDF_EXPLODE_CHAR))?"-":$conf->global->NDF_EXPLODE_CHAR;
- $num_car = (empty($conf->global->NDF_NUM_CAR_REF))?"5":$conf->global->NDF_NUM_CAR_REF;
+ if (! empty($conf->global->EXPENSEREPORT_ADDON))
+ {
+ $mybool=false;
- $sql = 'SELECT MAX(de.ref_number_int) as max';
- $sql.= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' de';
+ $file = $conf->global->EXPENSEREPORT_ADDON.".php";
+ $classname = $conf->global->EXPENSEREPORT_ADDON;
- $result = $this->db->query($sql);
+ // Include file with class
+ $dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']);
+ foreach ($dirmodels as $reldir)
+ {
+ $dir = dol_buildpath($reldir."core/modules/expensereport/");
- if($this->db->num_rows($result) > 0):
- $objp = $this->db->fetch_object($result);
- $this->ref = $objp->max;
- $this->ref++;
- while(strlen($this->ref) < $num_car):
- $this->ref = "0".$this->ref;
- endwhile;
- else:
- $this->ref = 1;
- while(strlen($this->ref) < $num_car):
- $this->ref = "0".$this->ref;
- endwhile;
- endif;
+ // Load file with numbering class (if found)
+ $mybool|=@include_once $dir.$file;
+ }
- if ($result):
- return 1;
- else:
- $this->error=$this->db->error();
- return -1;
- endif;
+ if (! $mybool)
+ {
+ dol_print_error('',"Failed to include file ".$file);
+ return '';
+ }
+
+ $obj = new $classname();
+ $numref = $obj->getNextValue($this);
+
+ if ($numref != "")
+ {
+ return $numref;
+ }
+ else
+ {
+ $this->error=$obj->error;
+ //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
+ return "";
+ }
+ }
+ else
+ {
+ print $langs->trans("Error")." ".$langs->trans("Error_COMMANDE_ADDON_NotDefined");
+ return "";
+ }
}
/**
diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang
index b4cce97957a..b8a6f3e0701 100644
--- a/htdocs/langs/en_US/admin.lang
+++ b/htdocs/langs/en_US/admin.lang
@@ -1632,6 +1632,7 @@ ExpenseReportsSetup=Setup of module Expense Reports
TemplatePDFExpenseReports=Document templates to generate expense report document
ExpenseReportsIkSetup=Setup of module Expense Reports - Milles index
ExpenseReportsRulesSetup=Setup of module Expense Reports - Rules
+ExpenseReportNumberingModules=Expense reports numbering module
NoModueToManageStockIncrease=No module able to manage automatic stock increase has been activated. Stock increase will be done on manual input only.
YouMayFindNotificationsFeaturesIntoModuleNotification=You may find options for EMail notifications by enabling and configuring the module "Notification".
ListOfNotificationsPerUser=List of notifications per user*