diff --git a/ChangeLog b/ChangeLog
index c301ac59b58..48002248c4f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -165,6 +165,7 @@ NEW: Update ActionComm type_code on email message ticket
NEW: VAT - Admin - Add information on deadline day for submission of VAT declaration
NEW: expand/collapse permissions on user permission page
NEW: Show delivery mode on PDF for proposals
+NEW: Add the target to select attendees of event for emailings
For developers or integrators:
diff --git a/htdocs/comm/mailing/cibles.php b/htdocs/comm/mailing/cibles.php
index ed3cfce4163..fa2f3a3a83b 100644
--- a/htdocs/comm/mailing/cibles.php
+++ b/htdocs/comm/mailing/cibles.php
@@ -394,7 +394,7 @@ if ($object->fetch($id) >= 0) {
if (empty($obj->picto)) {
$obj->picto = 'generic';
}
- print img_object($langs->trans("EmailingTargetSelector").': '.get_class($obj), $obj->picto, 'class="valignmiddle pictomodule"');
+ print img_object($langs->trans("EmailingTargetSelector").': '.get_class($obj), $obj->picto, 'class="valignmiddle pictomodule pictofixedwidth"');
print ' ';
print $obj->getDesc();
print '';
@@ -633,10 +633,12 @@ if ($object->fetch($id) >= 0) {
include_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
include_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
include_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
+ include_once DOL_DOCUMENT_ROOT.'/eventorganization/class/conferenceorboothattendee.class.php';
$objectstaticmember = new Adherent($db);
$objectstaticuser = new User($db);
$objectstaticcompany = new Societe($db);
$objectstaticcontact = new Contact($db);
+ $objectstaticeventorganization = new ConferenceOrBoothAttendee($db);
while ($i < min($num, $limit)) {
$obj = $db->fetch_object($resql);
@@ -662,6 +664,9 @@ if ($object->fetch($id) >= 0) {
} elseif ($obj->source_type == 'contact') {
$objectstaticcontact->fetch($obj->source_id);
print $objectstaticcontact->getNomUrl(1);
+ } elseif ($obj->source_type == 'eventorganizationattendee') {
+ $objectstaticeventorganization->fetch($obj->source_id);
+ print $objectstaticeventorganization->getNomUrl(1);
} else {
print $obj->source_url;
}
diff --git a/htdocs/core/class/html.formprojet.class.php b/htdocs/core/class/html.formprojet.class.php
index 9c8928de718..aedff703a19 100644
--- a/htdocs/core/class/html.formprojet.class.php
+++ b/htdocs/core/class/html.formprojet.class.php
@@ -66,14 +66,15 @@ class FormProjets
* @param int $forcefocus Force focus on field (works with javascript only)
* @param int $disabled Disabled
* @param int $mode 0 for HTML mode and 1 for JSON mode
- * @param string $filterkey Key to filter
+ * @param string $filterkey Key to filter on ref or title
* @param int $nooutput No print output. Return it only.
* @param int $forceaddid Force to add project id in list, event if not qualified
* @param string $morecss More css
* @param int $htmlid Html id to use instead of htmlname
+ * @param string $morefilter More filters (Must be a sql sanitized string)
* @return string Return html content
*/
- public function select_projects($socid = -1, $selected = '', $htmlname = 'projectid', $maxlength = 16, $option_only = 0, $show_empty = 1, $discard_closed = 0, $forcefocus = 0, $disabled = 0, $mode = 0, $filterkey = '', $nooutput = 0, $forceaddid = 0, $morecss = '', $htmlid = '')
+ public function select_projects($socid = -1, $selected = '', $htmlname = 'projectid', $maxlength = 16, $option_only = 0, $show_empty = 1, $discard_closed = 0, $forcefocus = 0, $disabled = 0, $mode = 0, $filterkey = '', $nooutput = 0, $forceaddid = 0, $morecss = '', $htmlid = '', $morefilter = '')
{
// phpcs:enable
global $langs, $conf, $form;
@@ -96,16 +97,14 @@ class FormProjets
$selected_input_value = $project->ref;
}
$urloption = 'socid='.((int) $socid).'&htmlname='.urlencode($htmlname).'&discardclosed='.((int) $discard_closed);
-
+ if ($morefilter == 'usage_organize_event=1') {
+ $urloption .= '&usage_organize_event=1';
+ }
$out .= '';
- $out .= ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/projet/ajax/projects.php', $urloption, $conf->global->PROJECT_USE_SEARCH_TO_SELECT, 0, array(
- // 'update' => array(
- // 'projectid' => 'id'
- // )
- ));
+ $out .= ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/projet/ajax/projects.php', $urloption, $conf->global->PROJECT_USE_SEARCH_TO_SELECT, 0, array());
} else {
- $out .= $this->select_projects_list($socid, $selected, $htmlname, $maxlength, $option_only, $show_empty, abs($discard_closed), $forcefocus, $disabled, 0, $filterkey, 1, $forceaddid, $htmlid, $morecss);
+ $out .= $this->select_projects_list($socid, $selected, $htmlname, $maxlength, $option_only, $show_empty, abs($discard_closed), $forcefocus, $disabled, 0, $filterkey, 1, $forceaddid, $htmlid, $morecss, $morefilter);
}
if ($discard_closed > 0) {
if (!empty($form)) {
@@ -135,14 +134,15 @@ class FormProjets
* @param int $forcefocus Force focus on field (works with javascript only)
* @param int $disabled Disabled
* @param int $mode 0 for HTML mode and 1 for array return (to be used by json_encode for example)
- * @param string $filterkey Key to filter
+ * @param string $filterkey Key to filter on title or ref
* @param int $nooutput No print output. Return it only.
* @param int $forceaddid Force to add project id in list, event if not qualified
* @param int $htmlid Html id to use instead of htmlname
* @param string $morecss More CSS
+ * @param string $morefilter More filters (Must be a sql sanitized string)
* @return int Nb of project if OK, <0 if KO
*/
- public function select_projects_list($socid = -1, $selected = '', $htmlname = 'projectid', $maxlength = 24, $option_only = 0, $show_empty = 1, $discard_closed = 0, $forcefocus = 0, $disabled = 0, $mode = 0, $filterkey = '', $nooutput = 0, $forceaddid = 0, $htmlid = '', $morecss = 'maxwidth500')
+ public function select_projects_list($socid = -1, $selected = '', $htmlname = 'projectid', $maxlength = 24, $option_only = 0, $show_empty = 1, $discard_closed = 0, $forcefocus = 0, $disabled = 0, $mode = 0, $filterkey = '', $nooutput = 0, $forceaddid = 0, $htmlid = '', $morecss = 'maxwidth500', $morefilter = '')
{
// phpcs:enable
global $user, $conf, $langs;
@@ -187,6 +187,9 @@ class FormProjets
if (!empty($filterkey)) {
$sql .= natural_search(array('p.title', 'p.ref'), $filterkey);
}
+ if ($morefilter) {
+ $sql .= ' AND ('.$morefilter.')';
+ }
$sql .= " ORDER BY p.ref ASC";
$resql = $this->db->query($sql);
diff --git a/htdocs/core/modules/mailings/eventorganization.modules.php b/htdocs/core/modules/mailings/eventorganization.modules.php
new file mode 100644
index 00000000000..84c27c5f673
--- /dev/null
+++ b/htdocs/core/modules/mailings/eventorganization.modules.php
@@ -0,0 +1,212 @@
+
+ * Copyright (C) 2005-2010 Laurent Destailleur
+ * Copyright (C) 2005-2009 Regis Houssin
+ *
+ * This file is an example to follow to add your own email selector inside
+ * the Dolibarr email tool.
+ * Follow instructions given in README file to know what to change to build
+ * your own emailing list selector.
+ * Code that need to be changed in this file are marked by "CHANGE THIS" tag.
+ */
+
+/**
+ * \file htdocs/core/modules/mailings/eventorganization.modules.php
+ * \ingroup mailing
+ * \brief Example file to provide a list of recipients for mailing module
+ */
+
+
+// Load Dolibarr Environment
+include_once DOL_DOCUMENT_ROOT.'/core/modules/mailings/modules_mailings.php';
+
+
+/**
+ * Class to manage a list of personalised recipients for mailing feature
+ */
+class mailing_eventorganization extends MailingTargets
+{
+ // This label is used if no translation is found for key XXX neither MailingModuleDescXXX where XXX=name is found
+ public $name = 'AttendeesOfOrganizedEvent';
+ public $desc = "Attendees of an organized event";
+
+ public $require_admin = 0;
+
+ public $require_module = array(); // This module allows to select by categories must be also enabled if category module is not activated
+
+ /**
+ * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
+ */
+ public $picto = 'conferenceorbooth';
+
+ /**
+ * @var DoliDB Database handler.
+ */
+ public $db;
+
+ public $enabled = 'isModEnabled("eventorganization")';
+
+
+ /**
+ * Constructor
+ *
+ * @param DoliDB $db Database handler
+ */
+ public function __construct($db)
+ {
+ global $conf, $langs;
+ $langs->load('companies');
+
+ $this->db = $db;
+ }
+
+
+ // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
+ /**
+ * This is the main function that returns the array of emails
+ *
+ * @param int $mailing_id Id of mailing. No need to use it.
+ * @return int <0 if error, number of emails added if ok
+ */
+ public function add_to_target($mailing_id)
+ {
+ // phpcs:enable
+ global $conf, $langs;
+
+ $cibles = array();
+ $addDescription = '';
+
+ $sql = "SELECT p.ref, p.entity, e.rowid as id, e.fk_project, e.email as email, e.email_company as company_name, e.firstname as firstname, e.lastname as lastname,";
+ $sql .= " 'eventorganizationattendee' as source";
+ $sql .= " FROM ".MAIN_DB_PREFIX."eventorganization_conferenceorboothattendee as e,";
+ $sql .= " ".MAIN_DB_PREFIX."projet as p";
+ $sql .= " WHERE e.email <> ''";
+ $sql .= " AND e.fk_project = p.rowid";
+ $sql .= " AND p.entity IN (".getEntity('project').")";
+ $sql .= " AND e.email NOT IN (SELECT email FROM ".MAIN_DB_PREFIX."mailing_cibles WHERE fk_mailing=".((int) $mailing_id).")";
+ $sql .= " AND e.fk_project = ".((int) GETPOST('filter_eventorganization', 'int'));
+ $sql .= " ORDER BY e.email";
+
+ // Stock recipients emails into targets table
+ $result = $this->db->query($sql);
+ if ($result) {
+ $num = $this->db->num_rows($result);
+ $i = 0;
+ $j = 0;
+
+ dol_syslog(get_class($this)."::add_to_target mailing ".$num." targets found");
+
+ $old = '';
+ while ($i < $num) {
+ $obj = $this->db->fetch_object($result);
+ if ($old <> $obj->email) {
+ $otherTxt = ($obj->ref ? $langs->transnoentities("Project").'='.$obj->ref : '');
+ if (strlen($addDescription) > 0 && strlen($otherTxt) > 0) {
+ $otherTxt .= ";";
+ }
+ $otherTxt .= $addDescription;
+ $cibles[$j] = array(
+ 'email' => $obj->email,
+ 'fk_project' => $obj->fk_project,
+ 'lastname' => $obj->lastname,
+ 'firstname' => $obj->firstname,
+ 'other' => $otherTxt,
+ 'source_url' => $this->url($obj->id, $obj->source),
+ 'source_id' => $obj->id,
+ 'source_type' => $obj->source
+ );
+ $old = $obj->email;
+ $j++;
+ }
+
+ $i++;
+ }
+ } else {
+ dol_syslog($this->db->error());
+ $this->error = $this->db->error();
+ return -1;
+ }
+
+ return parent::addTargetsToDatabase($mailing_id, $cibles);
+ }
+
+
+ /**
+ * On the main mailing area, there is a box with statistics.
+ * If you want to add a line in this report you must provide an
+ * array of SQL request that returns two field:
+ * One called "label", One called "nb".
+ *
+ * @return array Array with SQL requests
+ */
+ public function getSqlArrayForStats()
+ {
+ // CHANGE THIS: Optionnal
+
+ //var $statssql=array();
+ //$this->statssql[0]="SELECT field1 as label, count(distinct(email)) as nb FROM mytable WHERE email IS NOT NULL";
+ return array();
+ }
+
+
+ /**
+ * Return here number of distinct emails returned by your selector.
+ * For example if this selector is used to extract 500 different
+ * emails from a text file, this function must return 500.
+ *
+ * @param string $sql Requete sql de comptage
+ * @return int|string Nb of recipient, or <0 if error, or '' if NA
+ */
+ public function getNbOfRecipients($sql = '')
+ {
+ global $conf;
+
+ $sql = "SELECT COUNT(DISTINCT(e.email)) as nb";
+ $sql .= " FROM ".MAIN_DB_PREFIX."eventorganization_conferenceorboothattendee as e, ";
+ $sql .= " ".MAIN_DB_PREFIX."projet as p";
+ $sql .= " WHERE e.email <> ''";
+ $sql .= " AND e.fk_project = p.rowid";
+ $sql .= " AND p.entity IN (".getEntity('project').")";
+
+ //print $sql;
+
+ // La requete doit retourner un champ "nb" pour etre comprise par parent::getNbOfRecipients
+ return parent::getNbOfRecipients($sql);
+ }
+
+ /**
+ * This is to add a form filter to provide variant of selector
+ * If used, the HTML select must be called "filter"
+ *
+ * @return string A html select zone
+ */
+ public function formFilter()
+ {
+ global $conf, $langs;
+
+ $langs->load("companies");
+
+ include_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
+ $formproject = new FormProjets($this->db);
+ $s .= $formproject->select_projects(-1, 0, "filter_eventorganization", 0, 0, 1, 1, 0, 0, 0, '', 1, 0, '', '', 'usage_organize_event=1');
+
+ return $s;
+ }
+
+
+ /**
+ * Can include an URL link on each record provided by selector shown on target page.
+ *
+ * @param int $id ID
+ * @param string $sourcetype Source type
+ * @return string Url link
+ */
+ public function url($id, $sourcetype = 'thirdparty')
+ {
+ if ($sourcetype == 'project') {
+ return ''.img_object('', "eventorganization").'';
+ }
+
+ return '';
+ }
+}
diff --git a/htdocs/core/modules/modEventOrganization.class.php b/htdocs/core/modules/modEventOrganization.class.php
index 437fa691713..f037f26176c 100644
--- a/htdocs/core/modules/modEventOrganization.class.php
+++ b/htdocs/core/modules/modEventOrganization.class.php
@@ -62,7 +62,7 @@ class modEventOrganization extends DolibarrModules
// Key used in llx_const table to save module status enabled/disabled (where EVENTORGANIZATION is value of property name of module in uppercase)
$this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
- $this->picto = 'action';
+ $this->picto = 'conferenceorbooth';
// Define some features supported by module (triggers, login, substitutions, menus, css, etc...)
$this->module_parts = array(
diff --git a/htdocs/install/mysql/migration/16.0.0-17.0.0.sql b/htdocs/install/mysql/migration/16.0.0-17.0.0.sql
index 0b4b773be40..8432bf252c3 100644
--- a/htdocs/install/mysql/migration/16.0.0-17.0.0.sql
+++ b/htdocs/install/mysql/migration/16.0.0-17.0.0.sql
@@ -55,6 +55,8 @@ ALTER TABLE llx_user DROP COLUMN idpers3;
-- v17
+ALTER TABLE llx_mailing_cibles MODIFY COLUMN source_type varchar(32);
+
ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_percent (percent);
UPDATE llx_c_paiement SET code = 'BANCON' WHERE code = 'BAN' AND libelle = 'Bancontact';
diff --git a/htdocs/install/mysql/tables/llx_mailing_cibles-mailing.sql b/htdocs/install/mysql/tables/llx_mailing_cibles-mailing.sql
index da0b6c1683a..3c38eedaaaf 100644
--- a/htdocs/install/mysql/tables/llx_mailing_cibles-mailing.sql
+++ b/htdocs/install/mysql/tables/llx_mailing_cibles-mailing.sql
@@ -32,7 +32,7 @@ create table llx_mailing_cibles
statut smallint NOT NULL DEFAULT 0, -- -1 = error, 0 = not sent, ...
source_url varchar(255),
source_id integer,
- source_type varchar(16),
+ source_type varchar(32),
date_envoi datetime,
tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
error_text varchar(255) -- text with error if statut is -1