dolibarr 21.0.0-beta
contacts1.modules.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2005-2009 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005-2009 Regis Houssin <regis.houssin@inodbox.com>
5 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
6 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 * or see https://www.gnu.org/
21 */
22
29include_once DOL_DOCUMENT_ROOT.'/core/modules/mailings/modules_mailings.php';
30
31
36{
37 public $name = 'ContactCompanies'; // Identifiant du module mailing
38 // This label is used if no translation is found for key XXX neither MailingModuleDescXXX where XXX=name is found
39 public $desc = 'Contacts of thirdparties (prospects, customers, suppliers...)';
40 public $require_module = array("societe"); // Module mailing actif si modules require_module actifs
41 public $require_admin = 0; // Module mailing actif pour user admin ou non
42
46 public $enabled = 'isModEnabled("societe")';
47
51 public $picto = 'contact';
52
53
59 public function __construct($db)
60 {
61 $this->db = $db;
62 }
63
64
73 public function getSqlArrayForStats()
74 {
75 global $langs;
76
77 $langs->load("commercial");
78
79 $statssql = array();
80 $statssql[0] = "SELECT '".$this->db->escape($langs->trans("NbOfCompaniesContacts"))."' as label,";
81 $statssql[0] .= " count(distinct(c.email)) as nb";
82 $statssql[0] .= " FROM ".MAIN_DB_PREFIX."socpeople as c";
83 $statssql[0] .= " WHERE c.entity IN (".getEntity('contact').")";
84 $statssql[0] .= " AND c.email <> ''"; // Note that null != '' is false
85 $statssql[0] .= " AND c.statut = 1";
86
87 return $statssql;
88 }
89
90
99 public function getNbOfRecipients($sql = '')
100 {
101 global $conf;
102
103 $sql = "SELECT count(distinct(c.email)) as nb";
104 $sql .= " FROM ".MAIN_DB_PREFIX."socpeople as c";
105 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = c.fk_soc";
106 $sql .= " WHERE c.entity IN (".getEntity('contact').")";
107 $sql .= " AND c.email <> ''"; // Note that null != '' is false
108 if (empty($this->evenunsubscribe)) {
109 $sql .= " AND NOT EXISTS (SELECT rowid FROM ".MAIN_DB_PREFIX."mailing_unsubscribe as mu WHERE mu.email = c.email and mu.entity = ".((int) $conf->entity).")";
110 }
111 // exclude unsubscribed users
112 $sql .= " AND c.statut = 1";
113
114 // The request must return a field called "nb" to be understandable by parent::getNbOfRecipients
115 return parent::getNbOfRecipients($sql);
116 }
117
118
124 public function formFilter()
125 {
126 global $conf,$langs;
127
128 // Load translation files required by the page
129 $langs->loadLangs(array("commercial", "companies", "suppliers", "categories"));
130
131 $s = '';
132
133 // Add filter on job position
134 $sql = "SELECT sp.poste, count(distinct(sp.email)) AS nb";
135 $sql .= " FROM ".MAIN_DB_PREFIX."socpeople as sp";
136 $sql .= " WHERE sp.entity IN (".getEntity('contact').")";
137 $sql .= " AND sp.email <> ''"; // Note that null != '' is false
138 $sql .= " AND sp.statut = 1";
139 $sql .= " AND (sp.poste IS NOT NULL AND sp.poste <> '')";
140 $sql .= " GROUP BY sp.poste";
141 $sql .= " ORDER BY sp.poste";
142 $resql = $this->db->query($sql);
143
144 $s .= '<select id="filter_jobposition_contact" name="filter_jobposition" class="flat maxwidth200" placeholder="'.dol_escape_htmltag($langs->trans("PostOrFunction")).'">';
145 $s .= '<option value="-1">'.$langs->trans("PostOrFunction").'</option>';
146 if ($resql) {
147 $num = $this->db->num_rows($resql);
148 $i = 0;
149 if ($num > 0) {
150 while ($i < $num) {
151 $obj = $this->db->fetch_object($resql);
152 $s .= '<option value="'.dol_escape_htmltag($obj->poste).'">'.dol_escape_htmltag($obj->poste).' ('.$obj->nb.')</option>';
153 $i++;
154 }
155 } else {
156 $s .= '<option disabled="disabled" value="">'.$langs->trans("None").'</option>';
157 }
158 } else {
159 dol_print_error($this->db);
160 }
161 $s .= '</select>';
162 $s .= ajax_combobox("filter_jobposition_contact");
163 $s .= ' ';
164
165 // Filter on contact category
166 $sql = "SELECT c.label, count(distinct(sp.email)) AS nb";
167 $sql .= " FROM ";
168 $sql .= " ".MAIN_DB_PREFIX."socpeople as sp,";
169 $sql .= " ".MAIN_DB_PREFIX."categorie as c,";
170 $sql .= " ".MAIN_DB_PREFIX."categorie_contact as cs";
171 $sql .= " WHERE sp.entity IN (".getEntity('contact').")";
172 $sql .= " AND sp.email <> ''"; // Note that null != '' is false
173 $sql .= " AND sp.statut = 1";
174 $sql .= " AND cs.fk_categorie = c.rowid";
175 $sql .= " AND cs.fk_socpeople = sp.rowid";
176 $sql .= " GROUP BY c.label";
177 $sql .= " ORDER BY c.label";
178 $resql = $this->db->query($sql);
179
180 $s .= '<select id="filter_category_contact" name="filter_category" class="flat maxwidth200">';
181 $s .= '<option value="-1">'.$langs->trans("ContactCategoriesShort").'</option>';
182 if ($resql) {
183 $num = $this->db->num_rows($resql);
184 if ($num) {
185 $i = 0;
186 while ($i < $num) {
187 $obj = $this->db->fetch_object($resql);
188 $s .= '<option value="'.$obj->label.'">'.$obj->label.' ('.$obj->nb.')</option>';
189 $i++;
190 }
191 } else {
192 $s .= '<option value="-1" disabled="disabled">'.$langs->trans("NoContactWithCategoryFound").'</option>';
193 }
194 } else {
195 dol_print_error($this->db);
196 }
197 $s .= '</select>';
198 $s .= ajax_combobox("filter_category_contact");
199 $s .= '<br>';
200
201 // Add prospect of a particular level
202 $s .= '<select id="filter_contact" name="filter" class="flat maxwidth200">';
203 $sql = "SELECT code, label";
204 $sql .= " FROM ".MAIN_DB_PREFIX."c_prospectlevel";
205 $sql .= " WHERE active > 0";
206 $sql .= " ORDER BY label";
207 $resql = $this->db->query($sql);
208 if ($resql) {
209 $num = $this->db->num_rows($resql);
210 if ($num) {
211 $s .= '<option value="-1">'.$langs->trans("NatureOfThirdParty").'</option>';
212 } else {
213 $s .= '<option value="-1">'.$langs->trans("ContactsAllShort").'</option>';
214 }
215 $s .= '<option value="prospects">'.$langs->trans("ThirdPartyProspects").'</option>';
216
217 $i = 0;
218 while ($i < $num) {
219 $obj = $this->db->fetch_object($resql);
220 $level = $langs->trans($obj->code);
221 if ($level == $obj->code) {
222 $level = $langs->trans($obj->label);
223 }
224 $labeltoshow = $langs->trans("ThirdPartyProspects").' <span class="opacitymedium">('.$langs->trans("ProspectLevelShort").'='.$level.')</span>';
225 $s .= '<option value="prospectslevel'.$obj->code.'" data-html="'.dol_escape_htmltag($labeltoshow).'">'.$labeltoshow.'</option>';
226 $i++;
227 }
228 } else {
229 dol_print_error($this->db);
230 }
231 $s .= '<option value="customers">'.$langs->trans("ThirdPartyCustomers").'</option>';
232 //$s.='<option value="customersidprof">'.$langs->trans("ThirdPartyCustomersWithIdProf12",$langs->trans("ProfId1"),$langs->trans("ProfId2")).'</option>';
233 $s .= '<option value="suppliers">'.$langs->trans("ThirdPartySuppliers").'</option>';
234 $s .= '</select>';
235 $s .= ajax_combobox("filter_contact");
236
237 $s .= ' ';
238
239 // Filter on thirdparty category
240 $sql = "SELECT c.label, count(distinct(sp.email)) AS nb";
241 $sql .= " FROM ";
242 $sql .= " ".MAIN_DB_PREFIX."socpeople as sp,";
243 $sql .= " ".MAIN_DB_PREFIX."categorie as c,";
244 $sql .= " ".MAIN_DB_PREFIX."categorie_societe as cs";
245 $sql .= " WHERE sp.entity IN (".getEntity('contact').")";
246 $sql .= " AND sp.email <> ''"; // Note that null != '' is false
247 $sql .= " AND sp.statut = 1";
248 $sql .= " AND cs.fk_categorie = c.rowid";
249 $sql .= " AND cs.fk_soc = sp.fk_soc";
250 $sql .= " GROUP BY c.label";
251 $sql .= " ORDER BY c.label";
252 $resql = $this->db->query($sql);
253
254 $s .= '<select id="filter_category_customer_contact" name="filter_category_customer" class="flat maxwidth200">';
255 $s .= '<option value="-1">'.$langs->trans("CustomersProspectsCategoriesShort").'</option>';
256 if ($resql) {
257 $num = $this->db->num_rows($resql);
258 if ($num) {
259 $i = 0;
260 while ($i < $num) {
261 $obj = $this->db->fetch_object($resql);
262 $s .= '<option value="'.$obj->label.'">'.$obj->label.' ('.$obj->nb.')</option>';
263 $i++;
264 }
265 } else {
266 $s .= '<option value="-1" disabled="disabled">'.$langs->trans("NoContactLinkedToThirdpartieWithCategoryFound").'</option>';
267 }
268 } else {
269 dol_print_error($this->db);
270 }
271 $s .= '</select>';
272 $s .= ajax_combobox("filter_category_customer_contact");
273
274 $s .= ' ';
275
276 // Filter on thirdparty category
277 $sql = "SELECT c.label, count(distinct(sp.email)) AS nb";
278 $sql .= " FROM ";
279 $sql .= " ".MAIN_DB_PREFIX."socpeople as sp,";
280 $sql .= " ".MAIN_DB_PREFIX."categorie as c,";
281 $sql .= " ".MAIN_DB_PREFIX."categorie_fournisseur as cs";
282 $sql .= " WHERE sp.entity IN (".getEntity('contact').")";
283 $sql .= " AND sp.email <> ''"; // Note that null != '' is false
284 $sql .= " AND sp.statut = 1";
285 $sql .= " AND cs.fk_categorie = c.rowid";
286 $sql .= " AND cs.fk_soc = sp.fk_soc";
287 $sql .= " GROUP BY c.label";
288 $sql .= " ORDER BY c.label";
289 $resql = $this->db->query($sql);
290
291 $s .= '<select id="filter_category_supplier_contact" name="filter_category_supplier" class="flat maxwidth200">';
292 $s .= '<option value="-1">'.$langs->trans("SuppliersCategoriesShort").'</option>';
293 if ($resql) {
294 $num = $this->db->num_rows($resql);
295 if ($num) {
296 $i = 0;
297 while ($i < $num) {
298 $obj = $this->db->fetch_object($resql);
299 $s .= '<option value="'.$obj->label.'">'.$obj->label.' ('.$obj->nb.')</option>';
300 $i++;
301 }
302 } else {
303 $s .= '<option value="-1" disabled="disabled">'.$langs->trans("NoContactLinkedToThirdpartieWithCategoryFound").'</option>';
304 }
305 } else {
306 dol_print_error($this->db);
307 }
308 $s .= '</select>';
309
310 $s .= ajax_combobox("filter_category_supplier_contact");
311
312 // Choose language
313 if (getDolGlobalInt('MAIN_MULTILANGS')) {
314 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
315 $formadmin = new FormAdmin($this->db);
316 $s .= img_picto($langs->trans("DefaultLang"), 'language', 'class="pictofixedwidth"');
317 $s .= $formadmin->select_language(GETPOST('filter_lang', 'aZ09'), 'filter_lang', 0, null, $langs->trans("DefaultLang"), 0, 0, '', 0, 0, 0, null, 1);
318 }
319
320 return $s;
321 }
322
323
330 public function url($id)
331 {
332 return '<a href="'.DOL_URL_ROOT.'/contact/card.php?id='.$id.'">'.img_object('', "contact").'</a>';
333 }
334
335
336 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
343 public function add_to_target($mailing_id)
344 {
345 // phpcs:enable
346 global $conf, $langs;
347
348 $filter = GETPOST('filter', 'alpha');
349 $filter_jobposition = GETPOST('filter_jobposition', 'alpha');
350 $filter_category = GETPOST('filter_category', 'alpha');
351 $filter_category_customer = GETPOST('filter_category_customer', 'alpha');
352 $filter_category_supplier = GETPOST('filter_category_supplier', 'alpha');
353 $filter_lang = GETPOST('filter_lang', 'alpha');
354
355 $cibles = array();
356
357 // List prospects levels
358 $prospectlevel = array();
359 $sql = "SELECT code, label";
360 $sql .= " FROM ".MAIN_DB_PREFIX."c_prospectlevel";
361 $sql .= " WHERE active > 0";
362 $sql .= " ORDER BY label";
363 $resql = $this->db->query($sql);
364 if ($resql) {
365 $num = $this->db->num_rows($resql);
366 $i = 0;
367 while ($i < $num) {
368 $obj = $this->db->fetch_object($resql);
369 $prospectlevel[$obj->code] = $obj->label;
370 $i++;
371 }
372 } else {
373 dol_print_error($this->db);
374 }
375
376 // Request must return: id, email, fk_contact, lastname, firstname, other
377 $sql = "SELECT sp.rowid as id, sp.email as email, sp.rowid as fk_contact, sp.lastname, sp.firstname, sp.civility as civility_id, sp.poste as jobposition,";
378 $sql .= " s.nom as companyname";
379 $sql .= " FROM ".MAIN_DB_PREFIX."socpeople as sp";
380 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = sp.fk_soc";
381 if ($filter_category != 'all' && $filter_category != '-1') {
382 $sql .= ", ".MAIN_DB_PREFIX."categorie as c";
383 $sql .= ", ".MAIN_DB_PREFIX."categorie_contact as cs";
384 }
385 if ($filter_category_customer != 'all' && $filter_category_customer != '-1') {
386 $sql .= ", ".MAIN_DB_PREFIX."categorie as c2";
387 $sql .= ", ".MAIN_DB_PREFIX."categorie_societe as c2s";
388 }
389 if ($filter_category_supplier != 'all' && $filter_category_supplier != '-1') {
390 $sql .= ", ".MAIN_DB_PREFIX."categorie as c3";
391 $sql .= ", ".MAIN_DB_PREFIX."categorie_fournisseur as c3s";
392 }
393 $sql .= " WHERE sp.entity IN (".getEntity('contact').")";
394 $sql .= " AND sp.email <> ''";
395
396 if (empty($this->evenunsubscribe)) {
397 $sql .= " AND NOT EXISTS (SELECT rowid FROM ".MAIN_DB_PREFIX."mailing_unsubscribe as mu WHERE mu.email = sp.email and mu.entity = ".((int) $conf->entity).")";
398 }
399 // Exclude unsubscribed email addresses
400 $sql .= " AND sp.statut = 1";
401 $sql .= " AND sp.email NOT IN (SELECT email FROM ".MAIN_DB_PREFIX."mailing_cibles WHERE fk_mailing=".((int) $mailing_id).")";
402
403 // Filter on category
404 if ($filter_category != 'all' && $filter_category != '-1') {
405 $sql .= " AND cs.fk_categorie = c.rowid AND cs.fk_socpeople = sp.rowid";
406 $sql .= " AND c.label = '".$this->db->escape($filter_category)."'";
407 }
408 if ($filter_category_customer != 'all' && $filter_category_customer != '-1') {
409 $sql .= " AND c2s.fk_categorie = c2.rowid AND c2s.fk_soc = sp.fk_soc";
410 $sql .= " AND c2.label = '".$this->db->escape($filter_category_customer)."'";
411 }
412 if ($filter_category_supplier != 'all' && $filter_category_supplier != '-1') {
413 $sql .= " AND c3s.fk_categorie = c3.rowid AND c3s.fk_soc = sp.fk_soc";
414 $sql .= " AND c3.label = '".$this->db->escape($filter_category_supplier)."'";
415 }
416
417 // Filter on language
418 if (!empty($filter_lang) && $filter_lang != '-1') {
419 $sql .= " AND sp.default_lang LIKE '".$this->db->escape($filter_lang)."%'";
420 }
421
422 // Filter on nature
423 $key = $filter;
424
425 //print "xx".$key;
426 if ($key == 'prospects') {
427 $sql .= " AND s.client = 2";
428 }
429 foreach ($prospectlevel as $codelevel => $valuelevel) {
430 if ($key == 'prospectslevel'.$codelevel) {
431 $sql .= " AND s.fk_prospectlevel = '".$this->db->escape($codelevel)."'";
432 }
433 }
434 if ($key == 'customers') {
435 $sql .= " AND s.client = 1";
436 }
437 if ($key == 'suppliers') {
438 $sql .= " AND s.fournisseur = 1";
439 }
440
441 // Filter on job position
442 $key = $filter_jobposition;
443 if (!empty($key) && $key != 'all' && $key != '-1') {
444 $sql .= " AND sp.poste = '".$this->db->escape($key)."'";
445 }
446
447 $sql .= " ORDER BY sp.email";
448 //print "wwwwwwx".$sql;
449
450 // Store recipients in target tables
451 $result = $this->db->query($sql);
452 if ($result) {
453 $num = $this->db->num_rows($result);
454 $i = 0;
455 $j = 0;
456
457 dol_syslog(get_class($this)."::add_to_target mailing ".$num." targets found");
458
459 $old = '';
460 while ($i < $num) {
461 $obj = $this->db->fetch_object($result);
462 if ($old != $obj->email) {
463 $cibles[$j] = array(
464 'email' => $obj->email,
465 'fk_contact' => (int) $obj->fk_contact,
466 'lastname' => $obj->lastname,
467 'firstname' => $obj->firstname,
468 'other' =>
469 ($langs->transnoentities("ThirdParty").'='.$obj->companyname).';'.
470 ($langs->transnoentities("UserTitle").'='.($obj->civility_id ? $langs->transnoentities("Civility".$obj->civility_id) : '')).';'.
471 ($langs->transnoentities("PostOrFunction").'='.$obj->jobposition),
472 'source_url' => $this->url($obj->id),
473 'source_id' => (int) $obj->id,
474 'source_type' => 'contact'
475 );
476 $old = $obj->email;
477 $j++;
478 }
479
480 $i++;
481 }
482 } else {
483 dol_syslog($this->db->error());
484 $this->error = $this->db->error();
485 return -1;
486 }
487
488 return parent::addTargetsToDatabase($mailing_id, $cibles);
489 }
490}
$id
Definition account.php:48
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete='resolve', $idforemptyvalue='-1', $morecss='')
Convert a html select field into an ajax combobox.
Definition ajax.lib.php:459
Class to generate html code for admin pages.
Parent class of emailing target selectors modules.
Class to offer a selector of emailing targets from contacts.
add_to_target($mailing_id)
Add some recipients into target table.
formFilter()
Affiche formulaire de filtre qui apparait dans page de selection des destinataires de mailings.
url($id)
Provide the URL to the car of the source information of the recipient for the mailing.
getNbOfRecipients($sql='')
Return here number of distinct emails returned by your selector.
__construct($db)
Constructor.
getSqlArrayForStats()
On the main mailing area, there is a box with statistics.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79