diff --git a/htdocs/core/modules/mailings/thirdparties.modules.php b/htdocs/core/modules/mailings/thirdparties.modules.php
index 89bc2cf2b5e..1d7acf02c09 100644
--- a/htdocs/core/modules/mailings/thirdparties.modules.php
+++ b/htdocs/core/modules/mailings/thirdparties.modules.php
@@ -226,7 +226,7 @@ class mailing_thirdparties extends MailingTargets
$sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
$sql .= " WHERE s.email <> ''";
$sql .= " AND s.entity IN (".getEntity('societe').")";
-
+ $sql .= " AND NOT EXISTS (SELECT rowid FROM ".MAIN_DB_PREFIX."mailing_unsubscribe as mu WHERE mu.email = s.email and mu.entity = ".((int) $conf->entity).")";
// La requete doit retourner un champ "nb" pour etre comprise par parent::getNbOfRecipients
return parent::getNbOfRecipients($sql);
}
@@ -316,11 +316,13 @@ class mailing_thirdparties extends MailingTargets
$s .= '';
$s .= ajax_combobox("filter_status_thirdparties");
+ if (!empty($conf->global->MAIN_MULTILANGS)) {
// Choose language
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
$formadmin = new FormAdmin($this->db);
$s .= ''.$langs->trans("DefaultLang").': ';
$s .= $formadmin->select_language($langs->getDefaultLang(1), 'filter_lang_thirdparties', 0, null, 1, 0, 0, '', 0, 0, 0, null, 1);
+ }
return $s;
}
diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php
index c6ee771472f..4a145a15f87 100644
--- a/htdocs/societe/card.php
+++ b/htdocs/societe/card.php
@@ -262,6 +262,7 @@ if (empty($reshook)) {
// Update
$result = $object->update($object->id, $user, 0, 1, 1, 'merge');
+
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
$error++;
@@ -474,6 +475,7 @@ if (empty($reshook)) {
$object->phone = GETPOST('phone', 'alpha');
$object->fax = GETPOST('fax', 'alpha');
$object->email = trim(GETPOST('email', 'custom', 0, FILTER_SANITIZE_EMAIL));
+ $object->no_email = GETPOST("no_email", "int");
$object->url = trim(GETPOST('url', 'custom', 0, FILTER_SANITIZE_URL));
$object->idprof1 = trim(GETPOST('idprof1', 'alphanohtml'));
$object->idprof2 = trim(GETPOST('idprof2', 'alphanohtml'));
@@ -609,6 +611,16 @@ if (empty($reshook)) {
$result = $object->create($user);
+ if (empty($error) && !empty($conf->mailing->enabled) && !empty($object->email) && $object->no_email == 1) {
+ // Add mass emailing flag into table mailing_unsubscribe
+ $result = $object->setNoEmail($object->no_email);
+ if ($result < 0) {
+ $error++;
+ $errors = array_merge($errors, ($object->error ? array($object->error) : $object->errors));
+ $action = 'create';
+ }
+ }
+
if ($result >= 0) {
if ($object->particulier) {
dol_syslog("We ask to create a contact/address too", LOG_DEBUG);
@@ -766,6 +778,23 @@ if (empty($reshook)) {
$result = $object->update($socid, $user, 1, $object->oldcopy->codeclient_modifiable(), $object->oldcopy->codefournisseur_modifiable(), 'update', 0);
+ if ($result > 0) {
+ // Update mass emailing flag into table mailing_unsubscribe
+ if (GETPOSTISSET('no_email') && $object->email) {
+ $no_email = GETPOST('no_email', 'int');
+ $result = $object->setNoEmail($no_email);
+ if ($result < 0) {
+ setEventMessages($object->error, $object->errors, 'errors');
+ $action = 'edit';
+ }
+ }
+
+ $action = 'view';
+ } else {
+ setEventMessages($object->error, $object->errors, 'errors');
+ $action = 'edit';
+ }
+
if ($result <= 0) {
setEventMessages($object->error, $object->errors, 'errors');
$error++;
@@ -1599,6 +1628,35 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
print '
| '.$form->editfieldkey('Web', 'url', '', $object, 0).' | ';
print ''.img_picto('', 'globe', 'class="pictofixedwidth"').' |
';
+ // Unsubscribe
+ if (!empty($conf->mailing->enabled)) {
+ if ($conf->use_javascript_ajax && $conf->global->MAILING_CONTACT_DEFAULT_BULK_STATUS == 2) {
+ print "\n".''."\n";
+ }
+ if (!GETPOSTISSET("no_email") && !empty($object->email)) {
+ $result = $object->getNoEmail();
+ if ($result < 0) {
+ setEventMessages($object->error, $object->errors, 'errors');
+ }
+ }
+ print '';
+ print ' | ';
+ print '';
+ print $form->selectyesno('no_email', (GETPOSTISSET("no_email") ? GETPOST("no_email", 'int') : $conf->global->MAILING_CONTACT_DEFAULT_BULK_STATUS), 1, false, ($conf->global->MAILING_CONTACT_DEFAULT_BULK_STATUS == 2));
+ print ' | ';
+ print '
';
+ }
+
// Social networks
if (isModEnabled('socialnetworks')) {
foreach ($socialnetworks as $key => $value) {
@@ -1940,6 +1998,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
$object->phone = GETPOST('phone', 'alpha');
$object->fax = GETPOST('fax', 'alpha');
$object->email = GETPOST('email', 'custom', 0, FILTER_SANITIZE_EMAIL);
+ $object->no_email = GETPOST("no_email", "int");
$object->url = GETPOST('url', 'custom', 0, FILTER_SANITIZE_URL);
$object->capital = GETPOST('capital', 'alphanohtml');
$object->idprof1 = GETPOST('idprof1', 'alphanohtml');
@@ -2281,10 +2340,58 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
print ''.img_picto('', 'object_phoning_fax', 'class="pictofixedwidth"').' | ';
// EMail / Web
- print '| '.$form->editfieldkey('EMail', 'email', GETPOST('email', 'custom', 0, FILTER_SANITIZE_EMAIL), $object, 0, 'string', '', (!empty($conf->global->SOCIETE_EMAIL_MANDATORY))).' | ';
- print ''.img_picto('', 'object_email', 'class="pictofixedwidth"').' |
';
print '| '.$form->editfieldkey('Web', 'url', GETPOST('url', 'alpha'), $object, 0).' | ';
- print ''.img_picto('', 'globe', 'class="pictofixedwidth"').' |
';
+ print ''.img_picto('', 'globe', 'class="pictofixedwidth"').' | ';
+
+ // EMail
+ print '| '.$form->editfieldkey('EMail', 'email', GETPOST('email', 'alpha'), $object, 0, 'string', '', (!empty($conf->global->SOCIETE_EMAIL_MANDATORY))).' | ';
+ print '';
+ print img_picto('', 'object_email');
+ print ' | ';
+ if (!empty($conf->mailing->enabled)) {
+ $langs->load("mails");
+ print ''.$langs->trans("NbOfEMailingsSend").' | ';
+ print ''.$object->getNbOfEMailings().' | ';
+ } else {
+ print ' | ';
+ }
+ print '
';
+
+ // Unsubscribe
+ if (!empty($conf->mailing->enabled)) {
+ if ($conf->use_javascript_ajax && isset($conf->global->MAILING_CONTACT_DEFAULT_BULK_STATUS) && $conf->global->MAILING_CONTACT_DEFAULT_BULK_STATUS == 2) {
+ print "\n".''."\n";
+ }
+ if (!GETPOSTISSET("no_email") && !empty($object->email)) {
+ $result = $object->getNoEmail();
+ if ($result < 0) {
+ setEventMessages($object->error, $object->errors, 'errors');
+ }
+ }
+ print '';
+ print ' | ';
+ print '';
+ $useempty = (isset($conf->global->MAILING_CONTACT_DEFAULT_BULK_STATUS) && ($conf->global->MAILING_CONTACT_DEFAULT_BULK_STATUS == 2));
+ print $form->selectyesno('no_email', (GETPOSTISSET("no_email") ? GETPOST("no_email", 'int') : $object->no_email), 1, false, $useempty);
+ print ' | ';
+ print '
';
+ }
// Social network
if (isModEnabled('socialnetworks')) {
@@ -2940,6 +3047,28 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
}
print '';
+ // Email
+ if (!empty($conf->mailing->enabled)) {
+ $langs->load("mails");
+ print '| '.$langs->trans("NbOfEMailingsSend").' | ';
+ print ''.$object->getNbOfEMailings().' |
';
+ }
+
+ // Unsubscribe opt-out
+ if (!empty($conf->mailing->enabled)) {
+ $result = $object->getNoEmail();
+ if ($result < 0) {
+ setEventMessages($object->error, $object->errors, 'errors');
+ }
+ print '| '.$langs->trans("No_Email").' | ';
+ if ($object->email) {
+ print yn($object->no_email);
+ } else {
+ print ''.$langs->trans("EMailNotDefined").'';
+ }
+ print ' |
';
+ }
+
// Default language
if (!empty($conf->global->MAIN_MULTILANGS)) {
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
diff --git a/htdocs/societe/class/api_thirdparties.class.php b/htdocs/societe/class/api_thirdparties.class.php
index f2357c96a16..f197a1b7024 100644
--- a/htdocs/societe/class/api_thirdparties.class.php
+++ b/htdocs/societe/class/api_thirdparties.class.php
@@ -230,6 +230,9 @@ class Thirdparties extends DolibarrApi
$obj = $this->db->fetch_object($result);
$soc_static = new Societe($this->db);
if ($soc_static->fetch($obj->rowid)) {
+ if (isModEnabled('mailing')) {
+ $soc_static->getNoEmail();
+ }
$obj_ret[] = $this->_cleanObjectDatas($soc_static);
}
$i++;
@@ -263,6 +266,9 @@ class Thirdparties extends DolibarrApi
if ($this->company->create(DolibarrApiAccess::$user) < 0) {
throw new RestException(500, 'Error creating thirdparty', array_merge(array($this->company->error), $this->company->errors));
}
+ if (isModEnabled('mailing') && !empty($this->company->email) && isset($this->company->no_email)) {
+ $this->company->setNoEmail($this->company->no_email);
+ }
return $this->company->id;
}
@@ -296,7 +302,11 @@ class Thirdparties extends DolibarrApi
$this->company->$field = $value;
}
- if ($this->company->update($id, DolibarrApiAccess::$user, 1, '', '', 'update')) {
+ if (isModEnabled('mailing') && !empty($this->company->email) && isset($this->company->no_email)) {
+ $this->company->setNoEmail($this->company->no_email);
+ }
+
+ if ($this->company->update($id, DolibarrApiAccess::$user, 1, '', '', 'update', 1)) {
return $this->get($id);
}
@@ -1876,6 +1886,9 @@ class Thirdparties extends DolibarrApi
if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login.' on this thirdparty');
}
+ if (isModEnabled('mailing')) {
+ $this->company->getNoEmail();
+ }
if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
$filterabsolutediscount = "fk_facture_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php
index 6f735af6d37..5d7b9dfee90 100644
--- a/htdocs/societe/class/societe.class.php
+++ b/htdocs/societe/class/societe.class.php
@@ -4008,6 +4008,111 @@ class Societe extends CommonObject
return -1;
}
+ /**
+ * Return number of mass Emailing received by this contacts with its email
+ *
+ * @return int Number of EMailings
+ */
+ public function getNbOfEMailings()
+ {
+ $sql = "SELECT count(mc.email) as nb";
+ $sql .= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc, ".MAIN_DB_PREFIX."mailing as m";
+ $sql .= " WHERE mc.fk_mailing=m.rowid AND mc.email = '".$this->db->escape($this->email)."' ";
+ $sql .= " AND m.entity IN (".getEntity($this->element).") AND mc.statut NOT IN (-1,0)"; // -1 error, 0 not sent, 1 sent with success
+
+ $resql = $this->db->query($sql);
+ if ($resql) {
+ $obj = $this->db->fetch_object($resql);
+ $nb = $obj->nb;
+
+ $this->db->free($resql);
+ return $nb;
+ } else {
+ $this->error = $this->db->error();
+ return -1;
+ }
+ }
+
+ /**
+ * Set "blacklist" mailing status
+ *
+ * @param int $no_email 1=Do not send mailing, 0=Ok to recieve mailling
+ * @return int <0 if KO, >0 if OK
+ */
+ public function setNoEmail($no_email)
+ {
+ $error = 0;
+
+ // Update mass emailing flag into table mailing_unsubscribe
+ if ($this->email) {
+ $this->db->begin();
+
+ if ($no_email) {
+ $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."mailing_unsubscribe WHERE entity IN (".getEntity('mailing', 0).") AND email = '".$this->db->escape($this->email)."'";
+ $resql = $this->db->query($sql);
+ if ($resql) {
+ $obj = $this->db->fetch_object($resql);
+ $noemail = $obj->nb;
+ if (empty($noemail)) {
+ $sql = "INSERT INTO ".MAIN_DB_PREFIX."mailing_unsubscribe(email, entity, date_creat) VALUES ('".$this->db->escape($this->email)."', ".getEntity('mailing', 0).", '".$this->db->idate(dol_now())."')";
+ $resql = $this->db->query($sql);
+ if (!$resql) {
+ $error++;
+ $this->error = $this->db->lasterror();
+ $this->errors[] = $this->error;
+ }
+ }
+ } else {
+ $error++;
+ $this->error = $this->db->lasterror();
+ $this->errors[] = $this->error;
+ }
+ } else {
+ $sql = "DELETE FROM ".MAIN_DB_PREFIX."mailing_unsubscribe WHERE email = '".$this->db->escape($this->email)."' AND entity IN (".getEntity('mailing', 0).")";
+ $resql = $this->db->query($sql);
+ if (!$resql) {
+ $error++;
+ $this->error = $this->db->lasterror();
+ $this->errors[] = $this->error;
+ }
+ }
+
+ if (empty($error)) {
+ $this->no_email = $no_email;
+ $this->db->commit();
+ return 1;
+ } else {
+ $this->db->rollback();
+ return $error * -1;
+ }
+ }
+
+ return 0;
+ }
+
+ /**
+ * get "blacklist" mailing status
+ * set no_email attribut to 1 or 0
+ *
+ * @return int <0 if KO, >0 if OK
+ */
+ public function getNoEmail()
+ {
+ if ($this->email) {
+ $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."mailing_unsubscribe WHERE entity IN (".getEntity('mailing').") AND email = '".$this->db->escape($this->email)."'";
+ $resql = $this->db->query($sql);
+ if ($resql) {
+ $obj = $this->db->fetch_object($resql);
+ $this->no_email = $obj->nb;
+ return 1;
+ } else {
+ $this->error = $this->db->lasterror();
+ $this->errors[] = $this->error;
+ return -1;
+ }
+ }
+ return 0;
+ }
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**