diff --git a/application/Espo/Controllers/LeadCapture.php b/application/Espo/Controllers/LeadCapture.php index 0c3fdc7905..b96c09631d 100644 --- a/application/Espo/Controllers/LeadCapture.php +++ b/application/Espo/Controllers/LeadCapture.php @@ -69,4 +69,11 @@ class LeadCapture extends \Espo\Core\Controllers\Record return $this->getRecordService()->generateNewApiKeyForEntity($data->id)->getValueMap(); } + + public function getActionSmtpAccountDataList() + { + if (!$this->getUser()->isAdmin()) throw new Forbidden(); + + return $this->getServiceFactory()->create('LeadCapture')->getSmtpAccountDataList(); + } } diff --git a/application/Espo/Modules/Crm/Services/MassEmail.php b/application/Espo/Modules/Crm/Services/MassEmail.php index 740c077a04..e39a09a3ff 100644 --- a/application/Espo/Modules/Crm/Services/MassEmail.php +++ b/application/Espo/Modules/Crm/Services/MassEmail.php @@ -590,8 +590,8 @@ class MassEmail extends \Espo\Services\Record 'useSmtp' => true, 'status' => 'Active', 'smtpIsForMassEmail' => true, - 'emailAddress!=' => '', - 'emailAddress!=' => null + ['emailAddress!=' => ''], + ['emailAddress!=' => null], ])->find(); foreach ($inboundEmailList as $inboundEmail) { diff --git a/application/Espo/Resources/i18n/en_US/LeadCapture.json b/application/Espo/Resources/i18n/en_US/LeadCapture.json index 12c42e8715..203de98afd 100644 --- a/application/Espo/Resources/i18n/en_US/LeadCapture.json +++ b/application/Espo/Resources/i18n/en_US/LeadCapture.json @@ -18,6 +18,9 @@ "exampleRequestUrl": "URL", "exampleRequestPayload": "Payload", "createLeadBeforeOptInConfirmation": "Create Lead before confirmation", + "skipOptInConfirmationIfSubscribed": "Skip confirmation if lead is already in target list", + "smtpAccount": "SMTP Account", + "inboundEmail": "Group Email Account", "duplicateCheck": "Duplicate Check" }, "links": { @@ -25,6 +28,7 @@ "campaign": "Campaign", "optInConfirmationEmailTemplate": "Opt-in confirmation email template", "targetTeam": "Target Team", + "inboundEmail": "Group Email Account", "logRecords": "Log" }, "labels": { diff --git a/application/Espo/Resources/layouts/LeadCapture/detail.json b/application/Espo/Resources/layouts/LeadCapture/detail.json index 8e2b3b06ef..c072e6b246 100644 --- a/application/Espo/Resources/layouts/LeadCapture/detail.json +++ b/application/Espo/Resources/layouts/LeadCapture/detail.json @@ -15,8 +15,9 @@ "label": "", "rows": [ [{"name": "optInConfirmation", "inlineEditDisabled": true}, false], - [{"name": "createLeadBeforeOptInConfirmation"}, false], + [{"name": "createLeadBeforeOptInConfirmation"}, {"name": "skipOptInConfirmationIfSubscribed"}], [{"name": "optInConfirmationEmailTemplate"}, {"name": "optInConfirmationLifetime"}], + [{"name": "smtpAccount"}, false], [{"name": "optInConfirmationSuccessMessage", "fullWidth": true}] ] } diff --git a/application/Espo/Resources/metadata/clientDefs/LeadCapture.json b/application/Espo/Resources/metadata/clientDefs/LeadCapture.json index 725c3bfac5..3278d78a01 100644 --- a/application/Espo/Resources/metadata/clientDefs/LeadCapture.json +++ b/application/Espo/Resources/metadata/clientDefs/LeadCapture.json @@ -72,6 +72,38 @@ ] } }, + "smtpAccount": { + "visible": { + "conditionGroup": [ + { + "type": "isTrue", + "attribute": "optInConfirmation" + } + ] + } + }, + "skipOptInConfirmationIfSubscribed": { + "visible": { + "conditionGroup": [ + { + "type": "and", + "value": [ + { + "type": "isTrue", + "attribute": "optInConfirmation" + }, + { + "type": "isNotEmpty", + "attribute": "targetListId", + "data": { + "field": "targetList" + } + } + ] + } + ] + } + }, "optInConfirmationEmailTemplate": { "visible": { "conditionGroup": [ diff --git a/application/Espo/Resources/metadata/entityDefs/LeadCapture.json b/application/Espo/Resources/metadata/entityDefs/LeadCapture.json index 9d51d0fc75..92f083c0d1 100644 --- a/application/Espo/Resources/metadata/entityDefs/LeadCapture.json +++ b/application/Espo/Resources/metadata/entityDefs/LeadCapture.json @@ -63,6 +63,9 @@ "createLeadBeforeOptInConfirmation": { "type": "bool" }, + "skipOptInConfirmationIfSubscribed": { + "type": "bool" + }, "leadSource": { "type": "enum", "view": "crm:views/opportunity/fields/lead-source", @@ -94,6 +97,14 @@ "readOnly": true, "seeMoreDisabled": true }, + "inboundEmail": { + "type": "link" + }, + "smtpAccount": { + "type": "base", + "notStorable": true, + "view": "views/lead-capture/fields/smtp-account" + }, "createdAt": { "type": "datetime", "readOnly": true @@ -132,6 +143,10 @@ "type": "belongsTo", "entity": "Team" }, + "inboundEmail": { + "type": "belongsTo", + "entity": "InboundEmail" + }, "optInConfirmationEmailTemplate": { "type": "belongsTo", "entity": "EmailTemplate" diff --git a/application/Espo/Services/LeadCapture.php b/application/Espo/Services/LeadCapture.php index 2e9514474e..a9fcf6c8bf 100644 --- a/application/Espo/Services/LeadCapture.php +++ b/application/Espo/Services/LeadCapture.php @@ -164,6 +164,13 @@ class LeadCapture extends Record if ($hasDuplicate) { $this->logLeadCapture($leadCapture, $target, $data, false); $isLogged = true; + + if ($leadCapture->get('skipOptInConfirmationIfSubscribed') && $leadCapture->get('targetListId')) { + $isAlreadyOptedIn = $this->isTargetOptedIn($target, $leadCapture->get('targetListId')); + if ($isAlreadyOptedIn) { + return true; + } + } } if ($leadCapture->get('createLeadBeforeOptInConfirmation')) { @@ -552,7 +559,38 @@ class LeadCapture extends Record 'isHtml' => $isHtml, ]); - $this->getMailSender()->send($email); + $smtpParams = null; + + $inboundEmailId = $leadCapture->get('inboundEmailId'); + + if ($inboundEmailId) { + $inboundEmail = $this->getEntityManager()->getEntity('InboundEmail', $inboundEmailId); + if (!$inboundEmail) { + throw new Error("Lead Capture: Group Email Account {$inboundEmailId} is not available."); + } + + if ( + $inboundEmail->get('status') !== 'Active' + || + !$inboundEmail->get('useSmtp') + ) { + throw new Error("Lead Capture: Group Email Account {$inboundEmailId} can't be used for Lead Capture."); + } + + $inboundEmailService = $this->getServiceFactory()->create('InboundEmail'); + $smtpParams = $inboundEmailService->getSmtpParamsFromAccount($inboundEmail); + if (!$smtpParams) { + throw new Error("Lead Capture: Group Email Account {$inboundEmailId} has no SMTP params."); + } + } + + $sender = $this->getMailSender(); + + if ($smtpParams) { + $sender->useSmtp($smtpParams); + } + + $sender->send($email); return true; } @@ -598,4 +636,31 @@ class LeadCapture extends Record 'leadCaptureId' => $leadCapture->id, ]; } + + public function getSmtpAccountDataList() + { + if (!$this->getUser()->isAdmin()) throw new Forbidden(); + + $dataList = []; + + $inboundEmailList = $this->getEntityManager()->getRepository('InboundEmail')->where([ + 'useSmtp' => true, + 'status' => 'Active', + + ['emailAddress!=' => ''], + ['emailAddress!=' => null], + ])->find(); + + foreach ($inboundEmailList as $inboundEmail) { + $item = (object) []; + $key = 'inboundEmail:' . $inboundEmail->id; + $item->key = $key; + $item->emailAddress = $inboundEmail->get('emailAddress'); + $item->fromName = $inboundEmail->get('fromName'); + + $dataList[] = $item; + } + + return $dataList; + } } diff --git a/client/modules/crm/src/views/mass-email/fields/smtp-account.js b/client/modules/crm/src/views/mass-email/fields/smtp-account.js index b4a27eacf7..4562942fb9 100644 --- a/client/modules/crm/src/views/mass-email/fields/smtp-account.js +++ b/client/modules/crm/src/views/mass-email/fields/smtp-account.js @@ -30,6 +30,8 @@ Espo.define('crm:views/mass-email/fields/smtp-account', 'views/fields/enum', fun return Dep.extend({ + dataUrl: 'MassEmail/action/smtpAccountDataList', + getAttributeList: function () { return [this.name, 'inboundEmailId']; }, @@ -81,7 +83,7 @@ Espo.define('crm:views/mass-email/fields/smtp-account', 'views/fields/enum', fun Dep.prototype.setup.call(this); if (this.getAcl().checkScope('MassEmail', 'create') || this.getAcl().checkScope('MassEmail', 'edit')) { - this.ajaxGetRequest('MassEmail/action/smtpAccountDataList').then(function (dataList) { + this.ajaxGetRequest(this.dataUrl).then(function (dataList) { if (!dataList.length) return; this.loadedOptionList = []; this.loadedOptionTranslations = {}; diff --git a/client/src/views/lead-capture/fields/smtp-account.js b/client/src/views/lead-capture/fields/smtp-account.js new file mode 100644 index 0000000000..cd62491d35 --- /dev/null +++ b/client/src/views/lead-capture/fields/smtp-account.js @@ -0,0 +1,36 @@ +/************************************************************************ + * This file is part of EspoCRM. + * + * EspoCRM - Open Source CRM application. + * Copyright (C) 2014-2019 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko + * Website: https://www.espocrm.com + * + * EspoCRM 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. + * + * EspoCRM 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 EspoCRM. If not, see http://www.gnu.org/licenses/. + * + * The interactive user interfaces in modified source and object code versions + * of this program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU General Public License version 3. + * + * In accordance with Section 7(b) of the GNU General Public License version 3, + * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. + ************************************************************************/ + +define('views/lead-capture/fields/smtp-account', 'crm:views/mass-email/fields/smtp-account', function (Dep) { + + return Dep.extend({ + + dataUrl: 'LeadCapture/action/smtpAccountDataList', + + }); +});