diff --git a/htdocs/admin/emailsenderprofile_card.php b/htdocs/admin/emailsenderprofile_card.php
new file mode 100644
index 00000000000..547f810fa15
--- /dev/null
+++ b/htdocs/admin/emailsenderprofile_card.php
@@ -0,0 +1,622 @@
+
+ * Copyright (C) ---Put here your own copyright and developer email---
+ *
+ * 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 .
+ */
+
+/**
+ * \file emailsenderprofile_card.php
+ * \ingroup monmodule
+ * \brief Page to create/edit/view emailsenderprofile
+ */
+
+//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1');
+//if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1');
+//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1');
+//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1');
+//if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION','1'); // Do not check anti CSRF attack test
+//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check anti CSRF attack test
+//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check anti CSRF attack test done when option MAIN_SECURITY_CSRF_WITH_TOKEN is on.
+//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data
+//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not check anti POST attack test
+//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu
+//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); // If we don't need to load the html.form.class.php
+//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); // Do not load ajax.lib.php library
+//if (! defined("NOLOGIN")) define("NOLOGIN",'1'); // If this page is public (can be called outside logged session)
+
+// Load Dolibarr environment
+$res=0;
+// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
+if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include($_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php");
+// Try main.inc.php into web root detected using web root caluclated from SCRIPT_FILENAME
+$tmp=empty($_SERVER['SCRIPT_FILENAME'])?'':$_SERVER['SCRIPT_FILENAME'];$tmp2=realpath(__FILE__); $i=strlen($tmp)-1; $j=strlen($tmp2)-1;
+while($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i]==$tmp2[$j]) { $i--; $j--; }
+if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include(substr($tmp, 0, ($i+1))."/main.inc.php");
+if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php");
+// Try main.inc.php using relative path
+if (! $res && file_exists("../main.inc.php")) $res=@include("../main.inc.php");
+if (! $res && file_exists("../../main.inc.php")) $res=@include("../../main.inc.php");
+if (! $res && file_exists("../../../main.inc.php")) $res=@include("../../../main.inc.php");
+if (! $res) die("Include of main fails");
+
+include_once(DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php');
+include_once(DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php');
+dol_include_once('/monmodule/class/emailsenderprofile.class.php');
+dol_include_once('/monmodule/lib/emailsenderprofile.lib.php');
+
+// Load traductions files requiredby by page
+$langs->loadLangs(array("monmodule@monmodule","other"));
+
+// Get parameters
+$id = GETPOST('id', 'int');
+$ref = GETPOST('ref', 'alpha');
+$action = GETPOST('action', 'alpha');
+$cancel = GETPOST('cancel', 'aZ09');
+$backtopage = GETPOST('backtopage', 'alpha');
+
+// Initialize technical objects
+$object=new EmailSenderProfile($db);
+$extrafields = new ExtraFields($db);
+$diroutputmassaction=$conf->monmodule->dir_output . '/temp/massgeneration/'.$user->id;
+$hookmanager->initHooks(array('emailsenderprofilecard')); // Note that conf->hooks_modules contains array
+// Fetch optionals attributes and labels
+$extralabels = $extrafields->fetch_name_optionals_label('emailsenderprofile');
+$search_array_options=$extrafields->getOptionalsFromPost($extralabels,'','search_');
+
+// Initialize array of search criterias
+$search_all=trim(GETPOST("search_all",'alpha'));
+$search=array();
+foreach($object->fields as $key => $val)
+{
+ if (GETPOST('search_'.$key,'alpha')) $search[$key]=GETPOST('search_'.$key,'alpha');
+}
+
+if (empty($action) && empty($id) && empty($ref)) $action='view';
+
+// Security check - Protection if external user
+//if ($user->societe_id > 0) access_forbidden();
+//if ($user->societe_id > 0) $socid = $user->societe_id;
+//$result = restrictedArea($user, 'monmodule', $id);
+
+// fetch optionals attributes and labels
+$extralabels = $extrafields->fetch_name_optionals_label($object->table_element);
+
+// Load object
+include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals
+
+
+
+/*
+ * ACTIONS
+ *
+ * Put here all code to do according to value of "action" parameter
+ */
+
+$parameters=array();
+$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks
+if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
+
+if (empty($reshook))
+{
+ $error=0;
+
+ if ($cancel)
+ {
+ if (! empty($backtopage))
+ {
+ header("Location: ".$backtopage);
+ exit;
+ }
+ $action='';
+ }
+
+ // Action to add record
+ if ($action == 'add' && ! empty($user->rights->monmodule->create))
+ {
+ foreach ($object->fields as $key => $val)
+ {
+ if (in_array($key, array('rowid', 'entity', 'date_creation', 'tms', 'fk_user_creat', 'fk_user_modif', 'import_key'))) continue; // Ignore special fields
+
+ $object->$key=GETPOST($key,'alpha');
+ if ($val['notnull'] > 0 && $object->$key == '')
+ {
+ $error++;
+ setEventMessages($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv($val['label'])), null, 'errors');
+ }
+ }
+
+ if (! $error)
+ {
+ $result=$object->createCommon($user);
+ if ($result > 0)
+ {
+ // Creation OK
+ $urltogo=$backtopage?$backtopage:dol_buildpath('/monmodule/emailsenderprofile_list.php',1);
+ header("Location: ".$urltogo);
+ exit;
+ }
+ else
+ {
+ // Creation KO
+ if (! empty($object->errors)) setEventMessages(null, $object->errors, 'errors');
+ else setEventMessages($object->error, null, 'errors');
+ $action='create';
+ }
+ }
+ else
+ {
+ $action='create';
+ }
+ }
+
+ // Action to update record
+ if ($action == 'update' && ! empty($user->rights->monmodule->create))
+ {
+ foreach ($object->fields as $key => $val)
+ {
+ if (in_array($key, array('rowid', 'entity', 'date_creation', 'tms', 'fk_user_creat', 'fk_user_modif', 'import_key'))) continue; // Ignore special fields
+
+ $object->$key=GETPOST($key,'alpha');
+ if ($val['notnull'] > 0 && $object->$key == '')
+ {
+ $error++;
+ setEventMessages($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv($val['label'])), null, 'errors');
+ }
+ }
+
+ if (! $error)
+ {
+ $result=$object->updateCommon($user);
+ if ($result > 0)
+ {
+ $action='view';
+ }
+ else
+ {
+ // Creation KO
+ if (! empty($object->errors)) setEventMessages(null, $object->errors, 'errors');
+ else setEventMessages($object->error, null, 'errors');
+ $action='edit';
+ }
+ }
+ else
+ {
+ $action='edit';
+ }
+ }
+
+ // Action to delete
+ if ($action == 'confirm_delete' && ! empty($user->rights->monmodule->delete))
+ {
+ $result=$object->deleteCommon($user);
+ if ($result > 0)
+ {
+ // Delete OK
+ setEventMessages("RecordDeleted", null, 'mesgs');
+ header("Location: ".dol_buildpath('/monmodule/emailsenderprofile_list.php',1));
+ exit;
+ }
+ else
+ {
+ if (! empty($object->errors)) setEventMessages(null, $object->errors, 'errors');
+ else setEventMessages($object->error, null, 'errors');
+ }
+ }
+
+ // Actions when printing a doc from card
+ include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
+
+ // Actions to send emails
+ $trigger_name='MYOBJECT_SENTBYMAIL';
+ $autocopy='MAIN_MAIL_AUTOCOPY_MYOBJECT_TO';
+ $trackid='emailsenderprofile'.$object->id;
+ include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
+}
+
+
+
+
+/*
+ * VIEW
+ *
+ * Put here all code to build page
+ */
+
+$form=new Form($db);
+$formfile=new FormFile($db);
+
+llxHeader('','EmailSenderProfile','');
+
+// Example : Adding jquery code
+print '';
+
+
+// Part to create
+if ($action == 'create')
+{
+ print load_fiche_titre($langs->trans("NewObject", $langs->transnoentitiesnoconv("EmailSenderProfile")));
+
+ print '
'."\n";
+ $parameters=array();
+ $reshook=$hookmanager->executeHooks('addMoreActionsButtons',$parameters,$object,$action); // Note that $action and $object may have been modified by hook
+ if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
+
+ if (empty($reshook))
+ {
+ // Send
+ print '
';
+
+ $MAXEVENT = 10;
+
+ // List of actions on element
+ include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php';
+ $formactions = new FormActions($db);
+ $somethingshown = $formactions->showactions($object, 'emailsenderprofile', $socid, 1, '', $MAXEVENT);
+
+ print '
';
+ }
+
+ // Presend form
+ $modelmail='emailsenderprofile';
+ $defaulttopic='Information';
+ $diroutput = $conf->monmodule->dir_output;
+ $trackid = 'emailsenderprofile'.$object->id;
+
+ include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
+}
+
+
+// End of page
+llxFooter();
+$db->close();
diff --git a/htdocs/admin/emailsenderprofile_list.php b/htdocs/admin/emailsenderprofile_list.php
new file mode 100644
index 00000000000..dd2372443b3
--- /dev/null
+++ b/htdocs/admin/emailsenderprofile_list.php
@@ -0,0 +1,661 @@
+
+ * Copyright (C) ---Put here your own copyright and developer email---
+ *
+ * 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 .
+ */
+
+/**
+ * \file emailsenderprofile_list.php
+ * \ingroup monmodule
+ * \brief List page for emailsenderprofile
+ */
+
+//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1');
+//if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1');
+//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1');
+//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1');
+//if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION','1'); // Do not check anti CSRF attack test
+//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check anti CSRF attack test
+//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check anti CSRF attack test done when option MAIN_SECURITY_CSRF_WITH_TOKEN is on.
+//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data
+//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not check anti POST attack test
+//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu
+//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); // If we don't need to load the html.form.class.php
+//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); // Do not load ajax.lib.php library
+//if (! defined("NOLOGIN")) define("NOLOGIN",'1'); // If this page is public (can be called outside logged session)
+
+
+// Load Dolibarr environment
+$res=0;
+// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
+if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include($_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php");
+// Try main.inc.php into web root detected using web root caluclated from SCRIPT_FILENAME
+$tmp=empty($_SERVER['SCRIPT_FILENAME'])?'':$_SERVER['SCRIPT_FILENAME'];$tmp2=realpath(__FILE__); $i=strlen($tmp)-1; $j=strlen($tmp2)-1;
+while($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i]==$tmp2[$j]) { $i--; $j--; }
+if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include(substr($tmp, 0, ($i+1))."/main.inc.php");
+if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php");
+// Try main.inc.php using relative path
+if (! $res && file_exists("../main.inc.php")) $res=@include("../main.inc.php");
+if (! $res && file_exists("../../main.inc.php")) $res=@include("../../main.inc.php");
+if (! $res && file_exists("../../../main.inc.php")) $res=@include("../../../main.inc.php");
+if (! $res) die("Include of main fails");
+
+require_once(DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php');
+require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
+dol_include_once('/monmodule/class/emailsenderprofile.class.php');
+
+// Load traductions files requiredby by page
+$langs->loadLangs(array("monmodule@monmodule","other"));
+
+$action = GETPOST('action','alpha'); // The action 'add', 'create', 'edit', 'update', 'view', ...
+$massaction = GETPOST('massaction','alpha'); // The bulk action (combo box choice into lists)
+$show_files = GETPOST('show_files','int'); // Show files area generated by bulk actions ?
+$confirm = GETPOST('confirm','alpha'); // Result of a confirmation
+$cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button
+$toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected into a list
+$contextpage= GETPOST('contextpage','aZ')?GETPOST('contextpage','aZ'):'emailsenderprofilelist'; // To manage different context of search
+$backtopage = GETPOST('backtopage','alpha'); // Go back to a dedicated page
+$optioncss = GETPOST('optioncss','aZ'); // Option for the css output (always '' except when 'print')
+
+$id = GETPOST('id','int');
+
+// Load variable for pagination
+$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit;
+$sortfield = GETPOST('sortfield','alpha');
+$sortorder = GETPOST('sortorder','alpha');
+$page = GETPOST('page','int');
+if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
+$offset = $limit * $page;
+$pageprev = $page - 1;
+$pagenext = $page + 1;
+
+// Initialize technical objects
+$object=new EmailSenderProfile($db);
+$extrafields = new ExtraFields($db);
+$diroutputmassaction=$conf->monmodule->dir_output . '/temp/massgeneration/'.$user->id;
+$hookmanager->initHooks(array('emailsenderprofilelist')); // Note that conf->hooks_modules contains array
+// Fetch optionals attributes and labels
+$extralabels = $extrafields->fetch_name_optionals_label('emailsenderprofile');
+$search_array_options=$extrafields->getOptionalsFromPost($extralabels,'','search_');
+
+// Default sort order (if not yet defined by previous GETPOST)
+if (! $sortfield) $sortfield="t.".key($object->fields); // Set here default search field. By default 1st field in definition.
+if (! $sortorder) $sortorder="ASC";
+
+// Protection if external user
+$socid=0;
+if ($user->societe_id > 0)
+{
+ //$socid = $user->societe_id;
+ accessforbidden();
+}
+
+// Initialize array of search criterias
+$search_all=trim(GETPOST("search_all",'alpha'));
+$search=array();
+foreach($object->fields as $key => $val)
+{
+ if (GETPOST('search_'.$key,'alpha')) $search[$key]=GETPOST('search_'.$key,'alpha');
+}
+
+// List of fields to search into when doing a "search in all"
+$fieldstosearchall = array();
+foreach($object->fields as $key => $val)
+{
+ if ($val['searchall']) $fieldstosearchall['t.'.$key]=$val['label'];
+}
+
+// Definition of fields for list
+$arrayfields=array();
+foreach($object->fields as $key => $val)
+{
+ // If $val['visible']==0, then we never show the field
+ if (! empty($val['visible'])) $arrayfields['t.'.$key]=array('label'=>$val['label'], 'checked'=>(($val['visible']<0)?0:1), 'enabled'=>$val['enabled']);
+}
+// Extra fields
+if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label))
+{
+ foreach($extrafields->attribute_label as $key => $val)
+ {
+ if (! empty($extrafields->attribute_list[$key])) $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>(($extrafields->attribute_list[$key]<0)?0:1), 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]);
+ }
+}
+
+
+
+
+/*
+ * ACTIONS
+ *
+ * Put here all code to do according to value of "$action" parameter
+ */
+
+if (GETPOST('cancel','alpha')) { $action='list'; $massaction=''; }
+if (! GETPOST('confirmmassaction','alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { $massaction=''; }
+
+$parameters=array();
+$reshook=$hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
+if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
+
+if (empty($reshook))
+{
+ // Selection of new fields
+ include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
+
+ // Purge search criteria
+ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') ||GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers
+ {
+ foreach($object->fields as $key => $val)
+ {
+ $search[$key]='';
+ }
+ $toselect='';
+ $search_array_options=array();
+ }
+ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')
+ || GETPOST('button_search_x','alpha') || GETPOST('button_search.x','alpha') || GETPOST('button_search','alpha'))
+ {
+ $massaction=''; // Protection to avoid mass action if we force a new search during a mass action confirmation
+ }
+
+ // Mass actions
+ $objectclass='EmailSenderProfile';
+ $objectlabel='EmailSenderProfile';
+ $permtoread = $user->rights->monmodule->read;
+ $permtodelete = $user->rights->monmodule->delete;
+ $uploaddir = $conf->monmodule->dir_output;
+ include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
+}
+
+
+
+/*
+ * VIEW
+ *
+ * Put here all code to build page
+ */
+
+$form=new Form($db);
+
+$now=dol_now();
+
+//$help_url="EN:Module_EmailSenderProfile|FR:Module_EmailSenderProfile_FR|ES:Módulo_EmailSenderProfile";
+$help_url='';
+$title = $langs->trans('ListOf', $langs->transnoentitiesnoconv("EmailSenderProfiles"));
+
+
+// Build and execute select
+// --------------------------------------------------------------------
+$sql = 'SELECT ';
+foreach($object->fields as $key => $val)
+{
+ $sql.='t.'.$key.', ';
+}
+// Add fields from extrafields
+foreach ($extrafields->attribute_label as $key => $val) $sql.=($extrafields->attribute_type[$key] != 'separate' ? ", ef.".$key.' as options_'.$key : '');
+// Add fields from hooks
+$parameters=array();
+$reshook=$hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook
+$sql.=$hookmanager->resPrint;
+$sql=preg_replace('/, $/','', $sql);
+$sql.= " FROM ".MAIN_DB_PREFIX."emailsenderprofile as t";
+if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."emailsenderprofile_extrafields as ef on (t.rowid = ef.fk_object)";
+$sql.= " WHERE t.entity IN (".getEntity('emailsenderprofile').")";
+foreach($search as $key => $val)
+{
+ $mode_search=(($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key]))?1:0);
+ if ($search[$key] != '') $sql.=natural_search($key, $search[$key], (($key == 'status')?2:$mode_search));
+}
+if ($search_all) $sql.= natural_search(array_keys($fieldstosearchall), $search_all);
+// Add where from extra fields
+foreach ($search_array_options as $key => $val)
+{
+ $crit=$val;
+ $tmpkey=preg_replace('/search_options_/','',$key);
+ $typ=$extrafields->attribute_type[$tmpkey];
+ $mode_search=0;
+ if (in_array($typ, array('int','double','real'))) $mode_search=1; // Search on a numeric
+ if (in_array($typ, array('sellist')) && $crit != '0' && $crit != '-1') $mode_search=2; // Search on a foreign key int
+ if ($crit != '' && (! in_array($typ, array('select','sellist')) || $crit != '0'))
+ {
+ $sql .= natural_search('ef.'.$tmpkey, $crit, $mode_search);
+ }
+}
+// Add where from hooks
+$parameters=array();
+$reshook=$hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook
+$sql.=$hookmanager->resPrint;
+
+/* If a group by is required
+$sql.= " GROUP BY "
+foreach($object->fields as $key => $val)
+{
+ $sql.='t.'.$key.', ';
+}
+// Add fields from extrafields
+foreach ($extrafields->attribute_label as $key => $val) $sql.=($extrafields->attribute_type[$key] != 'separate' ? ",ef.".$key : '');
+// Add where from hooks
+$parameters=array();
+$reshook=$hookmanager->executeHooks('printFieldListGroupBy',$parameters); // Note that $action and $object may have been modified by hook
+$sql.=$hookmanager->resPrint;
+*/
+
+$sql.=$db->order($sortfield,$sortorder);
+
+// Count total nb of records
+$nbtotalofrecords = '';
+if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
+{
+ $result = $db->query($sql);
+ $nbtotalofrecords = $db->num_rows($result);
+}
+
+$sql.= $db->plimit($limit+1, $offset);
+
+dol_syslog($script_file, LOG_DEBUG);
+$resql=$db->query($sql);
+if (! $resql)
+{
+ dol_print_error($db);
+ exit;
+}
+
+$num = $db->num_rows($resql);
+
+// Direct jump if only one record found
+if ($num == 1 && ! empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all)
+{
+ $obj = $db->fetch_object($resql);
+ $id = $obj->rowid;
+ header("Location: ".DOL_URL_ROOT.'/monmodule/emailsenderprofile_card.php?id='.$id);
+ exit;
+}
+
+
+// Output page
+// --------------------------------------------------------------------
+
+llxHeader('', $title, $help_url);
+
+// Example : Adding jquery code
+print '';
+
+$arrayofselected=is_array($toselect)?$toselect:array();
+
+$param='';
+if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.urlencode($contextpage);
+if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.urlencode($limit);
+foreach($search as $key => $val)
+{
+ $param.= '&search_'.$key.'='.urlencode($search[$key]);
+}
+if ($optioncss != '') $param.='&optioncss='.urlencode($optioncss);
+// Add $param from extra fields
+foreach ($search_array_options as $key => $val)
+{
+ $crit=$val;
+ $tmpkey=preg_replace('/search_options_/','',$key);
+ if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val);
+}
+
+// List of mass actions available
+$arrayofmassactions = array(
+ //'presend'=>$langs->trans("SendByMail"),
+ //'builddoc'=>$langs->trans("PDFMerge"),
+);
+if ($user->rights->monmodule->delete) $arrayofmassactions['delete']=$langs->trans("Delete");
+if ($massaction == 'presend') $arrayofmassactions=array();
+$massactionbutton=$form->selectMassAction('', $arrayofmassactions);
+
+print ''."\n";
+
+if (in_array('builddoc',$arrayofmassactions) && ($nbtotalofrecords === '' || $nbtotalofrecords))
+{
+ if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files)
+ {
+ require_once(DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php');
+ $formfile = new FormFile($db);
+
+ // Show list of available documents
+ $urlsource=$_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder;
+ $urlsource.=str_replace('&','&',$param);
+
+ $filedir=$diroutputmassaction;
+ $genallowed=$user->rights->monmodule->read;
+ $delallowed=$user->rights->monmodule->read;
+
+ print $formfile->showdocuments('massfilesarea_monmodule','',$filedir,$urlsource,0,$delallowed,'',1,1,0,48,1,$param,$title,'');
+ }
+ else
+ {
+ print ' '.$langs->trans("ShowTempMassFilesArea").'';
+ }
+}
+
+// End of page
+llxFooter();
+$db->close();
diff --git a/htdocs/core/class/emailsenderprofile.class.php b/htdocs/core/class/emailsenderprofile.class.php
new file mode 100644
index 00000000000..f1e8332d116
--- /dev/null
+++ b/htdocs/core/class/emailsenderprofile.class.php
@@ -0,0 +1,445 @@
+
+ * Copyright (C) 2014-2016 Juanjo Menent
+ * Copyright (C) 2015 Florian Henry
+ * Copyright (C) 2015 Raphaël Doursenaud
+ * Copyright (C) ---Put here your own copyright and developer email---
+ *
+ * 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 .
+ */
+
+/**
+ * \file class/emailsenderprofile.class.php
+ * \ingroup monmodule
+ * \brief This file is a CRUD class file for EmailSenderProfile (Create/Read/Update/Delete)
+ */
+
+// Put here all includes required by your class file
+require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php';
+//require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
+//require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
+
+/**
+ * Class for EmailSenderProfile
+ */
+class EmailSenderProfile extends CommonObject
+{
+ /**
+ * @var string ID to identify managed object
+ */
+ public $element = 'emailsenderprofile';
+ /**
+ * @var string Name of table without prefix where object is stored
+ */
+ public $table_element = 'c_email_senderprofile';
+
+ /**
+ * @var array Does this field is linked to a thirdparty ?
+ */
+ protected $isnolinkedbythird = 1;
+ /**
+ * @var array Does emailsenderprofile support multicompany module ? 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
+ */
+ protected $ismultientitymanaged = 1;
+ /**
+ * @var string String with name of icon for emailsenderprofile
+ */
+ public $picto = 'emailsenderprofile@monmodule';
+
+
+ /**
+ * 'type' if the field format.
+ * 'label' the translation key.
+ * 'enabled' is a condition when the filed must be managed.
+ * 'visible' says if field is visible in list (-1 means not shown by default but can be added into list to be viewed).
+ * 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0).
+ * 'index' if we want an index in database.
+ * 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...).
+ * 'position' is the sort order of field.
+ * 'searchall' is 1 if we want to search in this field when making a search from the quick search button.
+ * 'isameasure' must be set to 1 if you want to have a total on list for this field. Field type must be summable like integer or double(24,8).
+ * 'help' is a string visible as a tooltip on field
+ * 'comment' is not used. You can store here any text of your choice.
+ */
+
+ // BEGIN MODULEBUILDER PROPERTIES
+ /**
+ * @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor.
+ */
+ public $fields=array(
+ 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'visible'=>-1, 'enabled'=>1, 'position'=>1, 'notnull'=>1, 'index'=>1, 'comment'=>'Id',),
+ 'entity' => array('type'=>'integer', 'label'=>'Entity', 'visible'=>-1, 'enabled'=>1, 'position'=>20, 'notnull'=>1, 'index'=>1,),
+ 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'visible'=>1, 'enabled'=>1, 'position'=>30, 'notnull'=>-1),
+ 'email' => array('type'=>'varchar(255)', 'label'=>'Email', 'visible'=>1, 'enabled'=>1, 'position'=>40, 'notnull'=>-1),
+ 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'visible'=>-1, 'enabled'=>1, 'position'=>500, 'notnull'=>1,),
+ 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'visible'=>-1, 'enabled'=>1, 'position'=>500, 'notnull'=>1,),
+ //'fk_user_creat' => array('type'=>'integer', 'label'=>'UserAuthor', 'visible'=>-1, 'enabled'=>1, 'position'=>500, 'notnull'=>1,),
+ //'fk_user_modif' => array('type'=>'integer', 'label'=>'UserModif', 'visible'=>-1, 'enabled'=>1, 'position'=>500, 'notnull'=>-1,),
+ 'signature' => array('type'=>'text', 'label'=>'Signature', 'visible'=>-1, 'enabled'=>1, 'position'=>1000, 'notnull'=>-1, 'index'=>1,),
+ 'position' => array('type'=>'integer', 'label'=>'Position', 'visible'=>-1, 'enabled'=>1, 'position'=>1000, 'notnull'=>-1, 'index'=>1,),
+ 'active' => array('type'=>'integer', 'label'=>'Active', 'visible'=>1, 'enabled'=>1, 'position'=>1000, 'notnull'=>-1, 'index'=>1),
+ );
+ public $rowid;
+ public $entity;
+ public $label;
+ public $email;
+ public $date_creation;
+ public $tms;
+ //public $fk_user_creat;
+ //public $fk_user_modif;
+ public $signature;
+ public $position;
+ public $active;
+ // END MODULEBUILDER PROPERTIES
+
+
+
+ // If this object has a subtable with lines
+
+ /**
+ * @var int Name of subtable line
+ */
+ //public $table_element_line = 'emailsenderprofiledet';
+ /**
+ * @var int Field with ID of parent key if this field has a parent
+ */
+ //public $fk_element = 'fk_emailsenderprofile';
+ /**
+ * @var int Name of subtable class that manage subtable lines
+ */
+ //public $class_element_line = 'EmailSenderProfileline';
+ /**
+ * @var array Array of child tables (child tables to delete before deleting a record)
+ */
+ //protected $childtables=array('emailsenderprofiledet');
+ /**
+ * @var EmailSenderProfileLine[] Array of subtable lines
+ */
+ //public $lines = array();
+
+
+
+ /**
+ * Constructor
+ *
+ * @param DoliDb $db Database handler
+ */
+ public function __construct(DoliDB $db)
+ {
+ global $conf;
+
+ $this->db = $db;
+
+ if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID)) $this->fields['rowid']['visible']=0;
+ }
+
+ /**
+ * Create object into database
+ *
+ * @param User $user User that creates
+ * @param bool $notrigger false=launch triggers after, true=disable triggers
+ * @return int <0 if KO, Id of created object if OK
+ */
+ public function create(User $user, $notrigger = false)
+ {
+ return $this->createCommon($user, $notrigger);
+ }
+
+ /**
+ * Clone and object into another one
+ *
+ * @param User $user User that creates
+ * @param int $fromid Id of object to clone
+ * @return mixed New object created, <0 if KO
+ */
+ public function createFromClone(User $user, $fromid)
+ {
+ global $hookmanager, $langs;
+ $error = 0;
+
+ dol_syslog(__METHOD__, LOG_DEBUG);
+
+ $object = new self($this->db);
+
+ $this->db->begin();
+
+ // Load source object
+ $object->fetchCommon($fromid);
+ // Reset some properties
+ unset($object->id);
+ unset($object->fk_user_creat);
+ unset($object->import_key);
+
+ // Clear fields
+ $object->ref = "copy_of_".$object->ref;
+ $object->title = $langs->trans("CopyOf")." ".$object->title;
+ // ...
+
+ // Create clone
+ $object->context['createfromclone'] = 'createfromclone';
+ $result = $object->createCommon($user);
+ if ($result < 0) {
+ $error++;
+ $this->error = $object->error;
+ $this->errors = $object->errors;
+ }
+
+ // End
+ if (!$error) {
+ $this->db->commit();
+ return $object;
+ } else {
+ $this->db->rollback();
+ return -1;
+ }
+ }
+
+ /**
+ * Load object in memory from the database
+ *
+ * @param int $id Id object
+ * @param string $ref Ref
+ * @return int <0 if KO, 0 if not found, >0 if OK
+ */
+ public function fetch($id, $ref = null)
+ {
+ $result = $this->fetchCommon($id, $ref);
+ if ($result > 0 && ! empty($this->table_element_line)) $this->fetchLines();
+ return $result;
+ }
+
+ /**
+ * Load object lines in memory from the database
+ *
+ * @param int $id Id object
+ * @param string $ref Ref
+ * @return int <0 if KO, 0 if not found, >0 if OK
+ */
+ public function fetchLines($id, $ref = null)
+ {
+ $this->lines=array();
+
+ // Load lines with object EmailSenderProfileLine
+
+ return count($this->lines)?1:0;
+ }
+
+ /**
+ * Update object into database
+ *
+ * @param User $user User that modifies
+ * @param bool $notrigger false=launch triggers after, true=disable triggers
+ * @return int <0 if KO, >0 if OK
+ */
+ public function update(User $user, $notrigger = false)
+ {
+ return $this->updateCommon($user, $notrigger);
+ }
+
+ /**
+ * Delete object in database
+ *
+ * @param User $user User that deletes
+ * @param bool $notrigger false=launch triggers after, true=disable triggers
+ * @return int <0 if KO, >0 if OK
+ */
+ public function delete(User $user, $notrigger = false)
+ {
+ return $this->deleteCommon($user, $trigger);
+ }
+
+ /**
+ * Return a link to the object card (with optionaly the picto)
+ *
+ * @param int $withpicto Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto)
+ * @return string String with URL
+ */
+ function getNomUrl($withpicto=0)
+ {
+ global $db, $conf, $langs;
+ global $dolibarr_main_authentication, $dolibarr_main_demo;
+ global $menumanager;
+
+ if (! empty($conf->dol_no_mouse_hover)) $notooltip=1; // Force disable tooltips
+
+ $result = '';
+ $companylink = '';
+
+ $url='';
+ //$url = dol_buildpath('/monmodule/emailsenderprofile_card.php',1).'?id='.$this->id;
+
+ $linkstart = '';
+ $linkend='';
+
+ if ($withpicto)
+ {
+ $result.=($linkstart.img_object(($notooltip?'':$label), 'label', ($notooltip?'':'class="classfortooltip"')).$linkend);
+ if ($withpicto != 2) $result.=' ';
+ }
+ $result.= $linkstart . $this->label . $linkend;
+ return $result;
+ }
+
+ /**
+ * Return link to download file from a direct external access
+ *
+ * @param int $withpicto Add download picto into link
+ * @return string HTML link to file
+ */
+ function getDirectExternalLink($withpicto=0)
+ {
+ return 'todo';
+ }
+
+ /**
+ * Retourne le libelle du status d'un user (actif, inactif)
+ *
+ * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
+ * @return string Label of status
+ */
+ function getLibStatut($mode=0)
+ {
+ return $this->LibStatut($this->status,$mode);
+ }
+
+ /**
+ * Return the status
+ *
+ * @param int $status Id status
+ * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto
+ * @return string Label of status
+ */
+ static function LibStatut($status,$mode=0)
+ {
+ global $langs;
+
+ if ($mode == 0)
+ {
+ $prefix='';
+ if ($status == 1) return $langs->trans('Enabled');
+ if ($status == 0) return $langs->trans('Disabled');
+ }
+ if ($mode == 1)
+ {
+ if ($status == 1) return $langs->trans('Enabled');
+ if ($status == 0) return $langs->trans('Disabled');
+ }
+ if ($mode == 2)
+ {
+ if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled');
+ if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled');
+ }
+ if ($mode == 3)
+ {
+ if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4');
+ if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5');
+ }
+ if ($mode == 4)
+ {
+ if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled');
+ if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled');
+ }
+ if ($mode == 5)
+ {
+ if ($status == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4');
+ if ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5');
+ }
+ if ($mode == 6)
+ {
+ if ($status == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4');
+ if ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5');
+ }
+ }
+
+ /**
+ * Charge les informations d'ordre info dans l'objet commande
+ *
+ * @param int $id Id of order
+ * @return void
+ */
+ function info($id)
+ {
+ $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
+ $sql.= ' fk_user_creat, fk_user_modif';
+ $sql.= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
+ $sql.= ' WHERE t.rowid = '.$id;
+ $result=$this->db->query($sql);
+ if ($result)
+ {
+ if ($this->db->num_rows($result))
+ {
+ $obj = $this->db->fetch_object($result);
+ $this->id = $obj->rowid;
+ if ($obj->fk_user_author)
+ {
+ $cuser = new User($this->db);
+ $cuser->fetch($obj->fk_user_author);
+ $this->user_creation = $cuser;
+ }
+
+ if ($obj->fk_user_valid)
+ {
+ $vuser = new User($this->db);
+ $vuser->fetch($obj->fk_user_valid);
+ $this->user_validation = $vuser;
+ }
+
+ if ($obj->fk_user_cloture)
+ {
+ $cluser = new User($this->db);
+ $cluser->fetch($obj->fk_user_cloture);
+ $this->user_cloture = $cluser;
+ }
+
+ $this->date_creation = $this->db->jdate($obj->datec);
+ $this->date_modification = $this->db->jdate($obj->datem);
+ $this->date_validation = $this->db->jdate($obj->datev);
+ }
+
+ $this->db->free($result);
+
+ }
+ else
+ {
+ dol_print_error($this->db);
+ }
+ }
+
+ /**
+ * Initialise object with example values
+ * Id must be 0 if object instance is a specimen
+ *
+ * @return void
+ */
+ public function initAsSpecimen()
+ {
+ $this->initAsSpecimenCommon();
+ }
+
+}
+
+/**
+ * Class EmailSenderProfileLine. You can also remove this and generate a CRUD class for lines objects.
+ */
+/*
+class EmailSenderProfileLine
+{
+ // @var int ID
+ public $id;
+ // @var mixed Sample line property 1
+ public $prop1;
+ // @var mixed Sample line property 2
+ public $prop2;
+}
+*/
\ No newline at end of file
diff --git a/htdocs/install/mysql/tables/llx_c_email_senderprofile.key.sql b/htdocs/install/mysql/tables/llx_c_email_senderprofile.key.sql
new file mode 100644
index 00000000000..a4896ea162c
--- /dev/null
+++ b/htdocs/install/mysql/tables/llx_c_email_senderprofile.key.sql
@@ -0,0 +1,21 @@
+-- ===================================================================
+-- Copyright (C) 2017 Laurent Destailleur
+--
+-- 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 .
+--
+-- Table with templates of emails
+-- ===================================================================
+
+ALTER TABLE llx_c_email_senderprofile ADD UNIQUE INDEX uk_c_email_senderprofile(entity, label, email);
+
diff --git a/htdocs/install/mysql/tables/llx_c_email_senderprofile.sql b/htdocs/install/mysql/tables/llx_c_email_senderprofile.sql
new file mode 100644
index 00000000000..24a050ca45a
--- /dev/null
+++ b/htdocs/install/mysql/tables/llx_c_email_senderprofile.sql
@@ -0,0 +1,32 @@
+-- ===================================================================
+-- Copyright (C) 2001-2017 Laurent Destailleur
+--
+-- 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 .
+--
+-- Table with templates of emails
+-- ===================================================================
+
+create table llx_c_email_senderprofile
+(
+ rowid integer AUTO_INCREMENT PRIMARY KEY,
+ entity integer DEFAULT 1 NOT NULL, -- multi company id
+ private smallint DEFAULT 0 NOT NULL, -- Template public or private
+ date_creation datetime,
+ tms timestamp,
+ label varchar(255), -- Label of predefined email
+ email varchar(255) NOT NULL, -- Email
+ signature text -- Predefined signature
+ position smallint DEFAULT 0, -- Position
+ active tinyint DEFAULT 1 NOT NULL,
+)ENGINE=innodb;