diff --git a/application/Espo/Modules/Crm/Services/MassEmail.php b/application/Espo/Modules/Crm/Services/MassEmail.php index 2f461caaff..cdbac55159 100644 --- a/application/Espo/Modules/Crm/Services/MassEmail.php +++ b/application/Espo/Modules/Crm/Services/MassEmail.php @@ -52,6 +52,8 @@ class MassEmail extends \Espo\Services\Record protected $mandatorySelectAttributeList = ['campaignId']; + protected $targetsLinkList = ['accounts', 'contacts', 'leads', 'users']; + protected function init() { parent::init(); @@ -80,10 +82,16 @@ class MassEmail extends \Espo\Services\Record protected function afterDeleteEntity(Entity $massEmail) { parent::afterDeleteEntity($massEmail); - $existingQueueItemList = $this->getEntityManager()->getRepository('EmailQueueItem')->where(array( + + $this->cleanupQueueItems($massEmail); + } + + protected function cleanupQueueItems(Entity $massEmail) + { + $existingQueueItemList = $this->getEntityManager()->getRepository('EmailQueueItem')->select(['id'])->where([ 'status' => ['Pending', 'Failed'], - 'massEmailId' => $massEmail->id - ))->find(); + 'massEmailId' => $massEmail->id, + ])->find(); foreach ($existingQueueItemList as $existingQueueItem) { $this->getEntityManager()->getMapper('RDB')->deleteFromDb('EmailQueueItem', $existingQueueItem->id); } @@ -95,27 +103,30 @@ class MassEmail extends \Espo\Services\Record throw new Error("Mass Email '".$massEmail->id."' should be 'Pending'."); } + $em = $this->getEntityManager(); + $pdo = $this->getEntityManager()->getPDO(); + if (!$isTest) { - $existingQueueItemList = $this->getEntityManager()->getRepository('EmailQueueItem')->where(array( - 'status' => ['Pending', 'Failed'], - 'massEmailId' => $massEmail->id - ))->find(); - foreach ($existingQueueItemList as $existingQueueItem) { - $this->getEntityManager()->getMapper('RDB')->deleteFromDb('EmailQueueItem', $existingQueueItem->id); - } + $this->cleanupQueueItems($massEmail); } - $metTargetHash = array(); - $metEmailAddressHash = array(); - $entityList = []; - - $pdo = $this->getEntityManager()->getPDO(); + $metTargetHash = []; + $metEmailAddressHash = []; + $itemList = []; if (!$isTest) { $excludingTargetListList = $massEmail->get('excludingTargetLists'); foreach ($excludingTargetListList as $excludingTargetList) { - foreach (['accounts', 'contacts', 'leads', 'users'] as $link) { - foreach ($excludingTargetList->get($link) as $excludingTarget) { + foreach ($this->targetsLinkList as $link) { + $excludingList = $em->getRepository('TargetList')->findRelated( + $excludingTargetList, + $link, + [ + 'select' => ['id', 'emailAddress'], + ] + ); + + foreach ($excludingList as $excludingTarget) { $hashId = $excludingTarget->getEntityType() . '-'. $excludingTarget->id; $metTargetHash[$hashId] = true; $emailAddress = $excludingTarget->get('emailAddress'); @@ -127,109 +138,50 @@ class MassEmail extends \Espo\Services\Record } $targetListCollection = $massEmail->get('targetLists'); + foreach ($targetListCollection as $targetList) { - $accountList = $targetList->get('accounts', array( - 'additionalColumnsConditions' => array( - 'optedOut' => false - ) - )); - foreach ($accountList as $account) { - $hashId = $account->getEntityType() . '-'. $account->id; - $emailAddress = $account->get('emailAddress'); - if (empty($emailAddress)) { - continue; - } - if (!empty($metEmailAddressHash[$emailAddress])) { - continue; - } - if (!empty($metTargetHash[$hashId])) { - continue; - } + foreach ($this->targetsLinkList as $link) { + $recordList = $em->getRepository('TargetList')->findRelated( + $targetList, + $link, + [ + 'additionalColumnsConditions' => ['optedOut' => false], + 'returnSthCollection' => true, + 'select' => ['id', 'emailAddress'], + ] + ); - $entityList[] = $account; - $metTargetHash[$hashId] = true; - $metEmailAddressHash[$emailAddress] = true; - } + foreach ($recordList as $record) { + $hashId = $record->getEntityType() . '-'. $record->id; + $emailAddress = $record->get('emailAddress'); - $contactList = $targetList->get('contacts', array( - 'additionalColumnsConditions' => array( - 'optedOut' => false - ) - )); - foreach ($contactList as $contact) { - $hashId = $contact->getEntityType() . '-'. $contact->id; - $emailAddress = $contact->get('emailAddress'); - if (empty($emailAddress)) { - continue; - } - if (!empty($metEmailAddressHash[$emailAddress])) { - continue; - } - if (!empty($metTargetHash[$hashId])) { - continue; - } + if (!$emailAddress) continue; + if (!empty($metEmailAddressHash[$emailAddress])) continue; + if (!empty($metTargetHash[$hashId])) continue; - $entityList[] = $contact; - $metTargetHash[$hashId] = true; - $metEmailAddressHash[$emailAddress] = true; - } + $item = $record->getValueMap(); + $item->entityType = $record->getEntityType(); - $leadList = $targetList->get('leads', array( - 'additionalColumnsConditions' => array( - 'optedOut' => false - ) - )); - foreach ($leadList as $lead) { - $hashId = $lead->getEntityType() . '-'. $lead->id; - $emailAddress = $lead->get('emailAddress'); - if (empty($emailAddress)) { - continue; - } - if (!empty($metEmailAddressHash[$emailAddress])) { - continue; - } - if (!empty($metTargetHash[$hashId])) { - continue; - } + $itemList[] = $item; - $entityList[] = $lead; - $metTargetHash[$hashId] = true; - $metEmailAddressHash[$emailAddress] = true; - } - - $userList = $targetList->get('users', array( - 'additionalColumnsConditions' => array( - 'optedOut' => false - ) - )); - foreach ($userList as $user) { - $hashId = $user->getEntityType() . '-'. $user->id; - $emailAddress = $user->get('emailAddress'); - if (empty($emailAddress)) { - continue; + $metTargetHash[$hashId] = true; + $metEmailAddressHash[$emailAddress] = true; } - if (!empty($metEmailAddressHash[$emailAddress])) { - continue; - } - if (!empty($metTargetHash[$hashId])) { - continue; - } - - $entityList[] = $user; - $metTargetHash[$hashId] = true; - $metEmailAddressHash[$emailAddress] = true; } } } - foreach ($additionalTargetList as $target) { - $entityList[] = $target; + foreach ($additionalTargetList as $record) { + $item = $record->getValueMap(); + $item->entityType = $record->getEntityType(); + $itemList[] = $item; } - foreach ($entityList as $target) { - $emailAddress = $target->get('emailAddress'); - if (!$target->get('emailAddress')) continue; + foreach ($itemList as $item) { + $emailAddress = $item->emailAddress ?? null; + if (!$emailAddress) continue; if (strpos($emailAddress, 'ERASED:') === 0) continue; + $emailAddressRecord = $this->getEntityManager()->getRepository('EmailAddress')->getByAddress($emailAddress); if ($emailAddressRecord) { if ($emailAddressRecord->get('invalid') || $emailAddressRecord->get('optOut')) { @@ -238,19 +190,19 @@ class MassEmail extends \Espo\Services\Record } $queueItem = $this->getEntityManager()->getEntity('EmailQueueItem'); - $queueItem->set(array( + $queueItem->set([ 'massEmailId' => $massEmail->id, 'status' => 'Pending', - 'targetId' => $target->id, - 'targetType' => $target->getEntityType(), - 'isTest' => $isTest - )); + 'targetId' => $item->id, + 'targetType' => $item->entityType, + 'isTest' => $isTest, + ]); $this->getEntityManager()->saveEntity($queueItem); } if (!$isTest) { $massEmail->set('status', 'In Process'); - if (empty($entityList)) { + if (empty($itemList)) { $massEmail->set('status', 'Complete'); } diff --git a/application/Espo/Modules/Crm/Services/TargetList.php b/application/Espo/Modules/Crm/Services/TargetList.php index 321eca8340..148b1b575a 100644 --- a/application/Espo/Modules/Crm/Services/TargetList.php +++ b/application/Espo/Modules/Crm/Services/TargetList.php @@ -41,11 +41,13 @@ class TargetList extends \Espo\Services\Record protected $duplicatingLinkList = ['accounts', 'contacts', 'leads', 'users']; + protected $targetsLinkList = ['accounts', 'contacts', 'leads', 'users']; + protected $entityTypeLinkMap = array( 'Lead' => 'leads', 'Account' => 'accounts', 'Contact' => 'contacts', - 'User' => 'users' + 'User' => 'users', ); protected $linkSelectParams = [ @@ -95,10 +97,9 @@ class TargetList extends \Espo\Services\Record protected function loadEntryCountField(Entity $entity) { $count = 0; - $count += $this->getEntityManager()->getRepository('TargetList')->countRelated($entity, 'contacts'); - $count += $this->getEntityManager()->getRepository('TargetList')->countRelated($entity, 'leads'); - $count += $this->getEntityManager()->getRepository('TargetList')->countRelated($entity, 'users'); - $count += $this->getEntityManager()->getRepository('TargetList')->countRelated($entity, 'accounts'); + foreach ($this->targetsLinkList as $link) { + $count += $this->getEntityManager()->getRepository('TargetList')->countRelated($entity, $link); + } $entity->set('entryCount', $count); } @@ -106,25 +107,13 @@ class TargetList extends \Espo\Services\Record { $count = 0; - $count += $this->getEntityManager()->getRepository('Contact')->join(['targetLists'])->where([ - 'targetListsMiddle.targetListId' => $entity->id, - 'targetListsMiddle.optedOut' => 1 - ])->count(); - - $count += $this->getEntityManager()->getRepository('Lead')->join(['targetLists'])->where([ - 'targetListsMiddle.targetListId' => $entity->id, - 'targetListsMiddle.optedOut' => 1 - ])->count(); - - $count += $this->getEntityManager()->getRepository('Account')->join(['targetLists'])->where([ - 'targetListsMiddle.targetListId' => $entity->id, - 'targetListsMiddle.optedOut' => 1 - ])->count(); - - $count += $this->getEntityManager()->getRepository('User')->join(['targetLists'])->where([ - 'targetListsMiddle.targetListId' => $entity->id, - 'targetListsMiddle.optedOut' => 1 - ])->count(); + foreach ($this->targetsLinkList as $link) { + $foreignEntityType = $entity->getRelationParam($link, 'entity'); + $count += $this->getEntityManager()->getRepository($foreignEntityType)->join(['targetLists'])->where([ + 'targetListsMiddle.targetListId' => $entity->id, + 'targetListsMiddle.optedOut' => 1, + ])->count(); + } $entity->set('optedOutCount', $count); } @@ -237,7 +226,7 @@ class TargetList extends \Espo\Services\Record } if ($sql) { if ($pdo->query($sql)) { - $this->getInjection('hookManager')->process('TargetList', 'afterUnlinkAll', $entity, array(), array('link' => $link)); + $this->getInjection('hookManager')->process('TargetList', 'afterUnlinkAll', $entity, [], ['link' => $link]); return true; } } @@ -324,12 +313,12 @@ class TargetList extends \Espo\Services\Record if (!$target) { throw new NotFound(); } - $map = array( + $map = [ 'Account' => 'accounts', 'Contact' => 'contacts', 'Lead' => 'leads', - 'User' => 'users' - ); + 'User' => 'users', + ]; if (empty($map[$targetType])) { throw new Error(); @@ -363,12 +352,12 @@ class TargetList extends \Espo\Services\Record if (!$target) { throw new NotFound(); } - $map = array( + $map = [ 'Account' => 'accounts', 'Contact' => 'contacts', 'Lead' => 'leads', - 'User' => 'users' - ); + 'User' => 'users', + ]; if (empty($map[$targetType])) { throw new Error(); 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 4b0bc7409a..d50dfe2527 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 @@ -73,7 +73,7 @@ define('crm:views/mass-email/fields/smtp-account', 'views/fields/enum', function }, getValueForDisplay: function () { - if (!this.model.has(this.name)) { + if (!this.model.has(this.name) && this.isReadMode()) { if (this.model.has('inboundEmailId')) { if (this.model.get('inboundEmailId')) { return 'inboundEmail:' + this.model.get('inboundEmailId'); diff --git a/frontend/less/espo/custom.less b/frontend/less/espo/custom.less index aec6d824b2..e4b21be89e 100644 --- a/frontend/less/espo/custom.less +++ b/frontend/less/espo/custom.less @@ -1696,6 +1696,7 @@ table.no-margin { .list-expanded > ul > li .list-row-buttons { margin-right: -12px; margin-top: -10px; + margin-bottom: -5px; } .show-more > .btn {