From fb3ecd4cf7c7301e7c0b63e61ea2f04d24355271 Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Tue, 27 Apr 2021 19:42:16 +0300 Subject: [PATCH] field loading usage --- .../FieldProcessing/Campaign/StatsLoader.php | 242 ++++++++++++++++++ .../metadata/recordDefs/Campaign.json | 5 + .../Espo/Modules/Crm/Services/Campaign.php | 180 +------------ 3 files changed, 258 insertions(+), 169 deletions(-) create mode 100644 application/Espo/Modules/Crm/Classes/FieldProcessing/Campaign/StatsLoader.php create mode 100644 application/Espo/Modules/Crm/Resources/metadata/recordDefs/Campaign.json diff --git a/application/Espo/Modules/Crm/Classes/FieldProcessing/Campaign/StatsLoader.php b/application/Espo/Modules/Crm/Classes/FieldProcessing/Campaign/StatsLoader.php new file mode 100644 index 0000000000..84efd9adb8 --- /dev/null +++ b/application/Espo/Modules/Crm/Classes/FieldProcessing/Campaign/StatsLoader.php @@ -0,0 +1,242 @@ +entityManager = $entityManager; + $this->acl = $acl; + $this->currencyDataProvider = $currencyDataProvider; + } + + public function process(Entity $entity, LoaderParams $params): void + { + $sentCount = $this->entityManager + ->getRDBRepository('CampaignLogRecord') + ->where([ + 'campaignId' => $entity->getId(), + 'action' => 'Sent', + 'isTest' => false, + ]) + ->count(); + + if (!$sentCount) { + $sentCount = null; + } + + $entity->set('sentCount', $sentCount); + + $openedCount = $this->entityManager + ->getRDBRepository('CampaignLogRecord') + ->where([ + 'campaignId' => $entity->getId(), + 'action' => 'Opened', + 'isTest' => false, + ]) + ->count(); + + $entity->set('openedCount', $openedCount); + + $openedPercentage = null; + + if ($sentCount > 0) { + $openedPercentage = round( + $openedCount / $sentCount * 100, 2, + PHP_ROUND_HALF_EVEN + ); + } + + $entity->set('openedPercentage', $openedPercentage); + + $clickedCount = $this->entityManager + ->getRDBRepository('CampaignLogRecord') + ->where([ + 'campaignId' => $entity->getId(), + 'action' => 'Clicked', + 'isTest' => false, + 'id=s' => [ + 'entityType' => 'CampaignLogRecord', + 'selectParams' => [ + 'select' => ['MIN:id'], + 'whereClause' => [ + 'action' => 'Clicked', + 'isTest' => false, + 'campaignId' => $entity->getId(), + ], + 'groupBy' => ['queueItemId'], + ], + ], + ]) + ->count(); + + $entity->set('clickedCount', $clickedCount); + + $clickedPercentage = null; + + if ($sentCount > 0) { + $clickedPercentage = round( + $clickedCount / $sentCount * 100, 2, + PHP_ROUND_HALF_EVEN + ); + } + + $entity->set('clickedPercentage', $clickedPercentage); + + $optedInCount = $this->entityManager + ->getRDBRepository('CampaignLogRecord') + ->where([ + 'campaignId' => $entity->getId(), + 'action' => 'Opted In', + 'isTest' => false, + ]) + ->count(); + + if (!$optedInCount) { + $optedInCount = null; + } + + $entity->set('optedInCount', $optedInCount); + + $optedOutCount = $this->entityManager + ->getRDBRepository('CampaignLogRecord') + ->where([ + 'campaignId' => $entity->getId(), + 'action' => 'Opted Out', + 'isTest' => false, + ]) + ->count(); + + $entity->set('optedOutCount', $optedOutCount); + + $optedOutPercentage = null; + + if ($sentCount > 0) { + $optedOutPercentage = round( + $optedOutCount / $sentCount * 100, 2, + PHP_ROUND_HALF_EVEN + ); + } + + $entity->set('optedOutPercentage', $optedOutPercentage); + + $bouncedCount = $this->entityManager + ->getRDBRepository('CampaignLogRecord') + ->where([ + 'campaignId' => $entity->getId(), + 'action' => 'Bounced', + 'isTest' => false, + ]) + ->count(); + + $entity->set('bouncedCount', $bouncedCount); + + $bouncedPercentage = null; + + if ($sentCount && $sentCount > 0) { + $bouncedPercentage = round( + $bouncedCount / $sentCount * 100, 2, + PHP_ROUND_HALF_EVEN + ); + } + + $entity->set('bouncedPercentage', $bouncedPercentage); + + if ($this->acl->check('Lead')) { + $leadCreatedCount = $this->entityManager + ->getRDBRepository('Lead') + ->where([ + 'campaignId' => $entity->getId(), + ]) + ->count(); + + if (!$leadCreatedCount) { + $leadCreatedCount = null; + } + + $entity->set('leadCreatedCount', $leadCreatedCount); + } + + if ($this->acl->check('Opportunity')) { + $entity->set('revenueCurrency', $this->currencyDataProvider->getDefaultCurrency()); + + $query = $this->entityManager + ->getQueryBuilder() + ->select() + ->from('Opportunity') + ->select(['SUM:amountConverted']) + ->where([ + 'stage' => 'Closed Won', + 'campaignId' => $entity->getId(), + ]) + ->groupBy('opportunity.campaignId') + ->build(); + + $sth = $this->entityManager->getQueryExecutor()->execute($query); + + $revenue = null; + + $row = $sth->fetch(PDO::FETCH_ASSOC); + + if ($row) { + $revenue = floatval($row['SUM:amountConverted']); + } + + if (!$revenue) { + $revenue = null; + } + + $entity->set('revenue', $revenue); + } + } +} diff --git a/application/Espo/Modules/Crm/Resources/metadata/recordDefs/Campaign.json b/application/Espo/Modules/Crm/Resources/metadata/recordDefs/Campaign.json new file mode 100644 index 0000000000..9d942a2722 --- /dev/null +++ b/application/Espo/Modules/Crm/Resources/metadata/recordDefs/Campaign.json @@ -0,0 +1,5 @@ +{ + "readLoaderClassNameList": [ + "Espo\\Modules\\Crm\\Classes\\FieldProcessing\\Campaign\\StatsLoader" + ] +} diff --git a/application/Espo/Modules/Crm/Services/Campaign.php b/application/Espo/Modules/Crm/Services/Campaign.php index 8a06cdded8..f564655e00 100644 --- a/application/Espo/Modules/Crm/Services/Campaign.php +++ b/application/Espo/Modules/Crm/Services/Campaign.php @@ -31,7 +31,6 @@ namespace Espo\Modules\Crm\Services; use Espo\ORM\{ Entity, - QueryParams\Select, }; use Espo\Core\Exceptions\Error, @@ -53,178 +52,12 @@ class Campaign extends \Espo\Services\Record implements 'User' => [], ]; - public function loadAdditionalFields(Entity $entity) - { - parent::loadAdditionalFields($entity); - - $sentCount = $this->getEntityManager() - ->getRepository('CampaignLogRecord') - ->where([ - 'campaignId' => $entity->id, - 'action' => 'Sent', - 'isTest' => false - ]) - ->count(); - - if (!$sentCount) { - $sentCount = null; - } - - $entity->set('sentCount', $sentCount); - - $openedCount = $this->getEntityManager() - ->getRepository('CampaignLogRecord') - ->where([ - 'campaignId' => $entity->id, - 'action' => 'Opened', - 'isTest' => false - ]) - ->count(); - - $entity->set('openedCount', $openedCount); - - $openedPercentage = null; - if ($sentCount > 0) { - $openedPercentage = round($openedCount / $sentCount * 100, 2, \PHP_ROUND_HALF_EVEN); - } - $entity->set('openedPercentage', $openedPercentage); - - $clickedCount = $this->getEntityManager() - ->getRepository('CampaignLogRecord') - ->where([ - 'campaignId' => $entity->id, - 'action' => 'Clicked', - 'isTest' => false, - 'id=s' => [ - 'entityType' => 'CampaignLogRecord', - 'selectParams' => [ - 'select' => ['MIN:id'], - 'whereClause' => [ - 'action' => 'Clicked', - 'isTest' => false, - 'campaignId' => $entity->id, - ], - 'groupBy' => ['queueItemId'], - ], - ], - ]) - ->count(); - - $entity->set('clickedCount', $clickedCount); - - $clickedPercentage = null; - if ($sentCount > 0) { - $clickedPercentage = round($clickedCount / $sentCount * 100, 2, \PHP_ROUND_HALF_EVEN); - } - $entity->set('clickedPercentage', $clickedPercentage); - - $optedInCount = $this->getEntityManager() - ->getRepository('CampaignLogRecord') - ->where([ - 'campaignId' => $entity->id, - 'action' => 'Opted In', - 'isTest' => false, - ]) - ->count(); - - if (!$optedInCount) { - $optedInCount = null; - } - - $entity->set('optedInCount', $optedInCount); - - $optedOutCount = $this->getEntityManager() - ->getRepository('CampaignLogRecord') - ->where([ - 'campaignId' => $entity->id, - 'action' => 'Opted Out', - 'isTest' => false, - ]) - ->count(); - - $entity->set('optedOutCount', $optedOutCount); - - $optedOutPercentage = null; - - if ($sentCount > 0) { - $optedOutPercentage = round($optedOutCount / $sentCount * 100, 2, \PHP_ROUND_HALF_EVEN); - } - - $entity->set('optedOutPercentage', $optedOutPercentage); - - $bouncedCount = $this->getEntityManager() - ->getRepository('CampaignLogRecord') - ->where([ - 'campaignId' => $entity->id, - 'action' => 'Bounced', - 'isTest' => false, - ]) - ->count(); - - $entity->set('bouncedCount', $bouncedCount); - - $bouncedPercentage = null; - - if ($sentCount && $sentCount > 0) { - $bouncedPercentage = round($bouncedCount / $sentCount * 100, 2, \PHP_ROUND_HALF_EVEN); - } - - $entity->set('bouncedPercentage', $bouncedPercentage); - - if ($this->getAcl()->check('Lead')) { - $leadCreatedCount = $this->getEntityManager() - ->getRepository('Lead') - ->where([ - 'campaignId' => $entity->id, - ]) - ->count(); - - if (!$leadCreatedCount) { - $leadCreatedCount = null; - } - - $entity->set('leadCreatedCount', $leadCreatedCount); - } - - if ($this->getAcl()->check('Opportunity')) { - $entity->set('revenueCurrency', $this->getConfig()->get('defaultCurrency')); - - $params = [ - 'from' => 'Opportunity', - 'select' => ['SUM:amountConverted'], - 'whereClause' => [ - 'stage' => 'Closed Won', - 'campaignId' => $entity->id, - ], - 'groupBy' => ['opportunity.campaignId'], - ]; - - $sql = $this->getEntityManager()->getQueryComposer()->compose(Select::fromRaw($params)); - - $pdo = $this->getEntityManager()->getPDO(); - $sth = $pdo->prepare($sql); - - $sth->execute(); - - $revenue = null; - - if ($row = $sth->fetch(\PDO::FETCH_ASSOC)) { - $revenue = floatval($row['SUM:amountConverted']); - - if (!$revenue) { - $revenue = null; - } - } - - $entity->set('revenue', $revenue); - } - } - public function logLeadCreated($campaignId, Entity $target, $actionDate = null, $isTest = false) { if (empty($actionDate)) { $actionDate = date('Y-m-d H:i:s'); } + $logRecord = $this->getEntityManager()->getEntity('CampaignLogRecord'); $logRecord->set([ 'campaignId' => $campaignId, @@ -250,6 +83,7 @@ class Campaign extends \Espo\Services\Record implements if (empty($actionDate)) { $actionDate = date('Y-m-d H:i:s'); } + $logRecord = $this->getEntityManager()->getEntity('CampaignLogRecord'); $logRecord->set([ 'campaignId' => $campaignId, @@ -392,6 +226,7 @@ class Campaign extends \Espo\Services\Record implements } $logRecord = $this->getEntityManager()->getEntity('CampaignLogRecord'); + $logRecord->set(array( 'campaignId' => $campaignId, 'actionDate' => $actionDate, @@ -402,6 +237,7 @@ class Campaign extends \Espo\Services\Record implements 'queueItemId' => $queueItemId, 'isTest' => $isTest )); + $this->getEntityManager()->saveEntity($logRecord); } @@ -526,9 +362,11 @@ class Campaign extends \Espo\Services\Record implements } $template = $this->getEntityManager()->getEntity('Template', $campaign->get($link . 'TemplateId')); + if (!$template) { throw new Error("Template not found"); } + if ($template->get('entityType') !== $targetEntityType) { throw new Error("Template is not of proper entity type."); } @@ -620,7 +458,11 @@ class Campaign extends \Espo\Services\Record implements $this->getDefaultLanguage()->translate($targetEntityType, 'scopeNamesPlural'); return $this->getServiceFactory()->create('Pdf')->generateMailMerge( - $targetEntityType, $targetEntityList, $template, $filename, $campaign->id + $targetEntityType, + $targetEntityList, + $template, + $filename, + $campaign->id ); }