ref
This commit is contained in:
@@ -55,23 +55,14 @@ use DateTime;
|
||||
class Invitations
|
||||
{
|
||||
private $smtpParams;
|
||||
|
||||
private $entityManager;
|
||||
|
||||
private $emailSender;
|
||||
|
||||
private $config;
|
||||
|
||||
private $dateTime; /** @phpstan-ignore-line */
|
||||
|
||||
private $language;
|
||||
|
||||
private $number; /** @phpstan-ignore-line */
|
||||
|
||||
private $templateFileManager;
|
||||
|
||||
private $fileManager; /** @phpstan-ignore-line */
|
||||
|
||||
private $htmlizerFactory;
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,38 +31,34 @@ namespace Espo\Modules\Crm\Controllers;
|
||||
|
||||
use Espo\Core\Exceptions\Forbidden;
|
||||
use Espo\Core\Exceptions\BadRequest;
|
||||
use Espo\Core\Exceptions\ForbiddenSilent;
|
||||
use Espo\Core\Exceptions\NotFound;
|
||||
|
||||
use Espo\Core\Api\Request;
|
||||
|
||||
use Espo\Modules\Crm\Entities\Call as CallEntity;
|
||||
use Espo\Modules\Crm\Services\Call as Service;
|
||||
use Espo\Modules\Crm\Tools\Meeting\InvitationService;
|
||||
|
||||
class Call extends \Espo\Core\Controllers\Record
|
||||
{
|
||||
/**
|
||||
* @throws BadRequest
|
||||
* @throws Forbidden
|
||||
* @throws ForbiddenSilent
|
||||
* @throws NotFound
|
||||
*/
|
||||
public function postActionSendInvitations(Request $request): bool
|
||||
{
|
||||
$data = $request->getParsedBody();
|
||||
$id = $request->getParsedBody()->id ?? null;
|
||||
|
||||
if (empty($data->id)) {
|
||||
if (!$id) {
|
||||
throw new BadRequest();
|
||||
}
|
||||
|
||||
/** @var \Espo\Modules\Crm\Entities\Call|null $entity */
|
||||
$entity = $this->getCallService()->getEntity($data->id);
|
||||
$resultList = $this->injectableFactory
|
||||
->create(InvitationService::class)
|
||||
->send(CallEntity::ENTITY_TYPE, $id);
|
||||
|
||||
if (!$entity) {
|
||||
throw new NotFound();
|
||||
}
|
||||
|
||||
if (!$this->getAcl()->check($entity, 'edit')) {
|
||||
throw new Forbidden();
|
||||
}
|
||||
|
||||
if (!$this->getAcl()->checkScope('Email', 'create')) {
|
||||
throw new Forbidden();
|
||||
}
|
||||
|
||||
return $this->getCallService()->sendInvitations($entity);
|
||||
return $resultList !== 0;
|
||||
}
|
||||
|
||||
public function postActionMassSetHeld(Request $request): bool
|
||||
|
||||
@@ -29,40 +29,40 @@
|
||||
|
||||
namespace Espo\Modules\Crm\Controllers;
|
||||
|
||||
use Espo\Core\Acl\Table;
|
||||
use Espo\Core\Controllers\Record;
|
||||
use Espo\Core\Exceptions\Forbidden;
|
||||
use Espo\Core\Exceptions\BadRequest;
|
||||
use Espo\Core\Exceptions\ForbiddenSilent;
|
||||
use Espo\Core\Exceptions\NotFound;
|
||||
|
||||
use Espo\Core\Api\Request;
|
||||
|
||||
use Espo\Modules\Crm\Entities\Meeting as MeetingEntity;
|
||||
use Espo\Modules\Crm\Services\Meeting as Service;
|
||||
use Espo\Modules\Crm\Tools\Meeting\InvitationService;
|
||||
|
||||
class Meeting extends \Espo\Core\Controllers\Record
|
||||
class Meeting extends Record
|
||||
{
|
||||
/**
|
||||
* @throws BadRequest
|
||||
* @throws Forbidden
|
||||
* @throws ForbiddenSilent
|
||||
* @throws NotFound
|
||||
*/
|
||||
public function postActionSendInvitations(Request $request): bool
|
||||
{
|
||||
$data = $request->getParsedBody();
|
||||
$id = $request->getParsedBody()->id ?? null;
|
||||
|
||||
if (empty($data->id)) {
|
||||
if (!$id) {
|
||||
throw new BadRequest();
|
||||
}
|
||||
|
||||
/** @var \Espo\Modules\Crm\Entities\Meeting|null $entity */
|
||||
$entity = $this->getMeetingService()->getEntity($data->id);
|
||||
$resultList = $this->injectableFactory
|
||||
->create(InvitationService::class)
|
||||
->send(MeetingEntity::ENTITY_TYPE, $id);
|
||||
|
||||
if (!$entity) {
|
||||
throw new NotFound();
|
||||
}
|
||||
|
||||
if (!$this->getAcl()->check($entity, 'edit')) {
|
||||
throw new Forbidden();
|
||||
}
|
||||
|
||||
if (!$this->getAcl()->checkScope('Email', 'create')) {
|
||||
throw new Forbidden();
|
||||
}
|
||||
|
||||
return $this->getMeetingService()->sendInvitations($entity);
|
||||
return $resultList !== 0;
|
||||
}
|
||||
|
||||
public function postActionMassSetHeld(Request $request): bool
|
||||
|
||||
@@ -29,21 +29,15 @@
|
||||
|
||||
namespace Espo\Modules\Crm\Services;
|
||||
|
||||
use Espo\Core\Binding\BindingContainerBuilder;
|
||||
use Espo\Core\Mail\SmtpParams;
|
||||
use Espo\Entities\User;
|
||||
use Espo\Modules\Crm\Entities\Meeting as MeetingEntity;
|
||||
use Espo\ORM\Entity;
|
||||
use Espo\Modules\Crm\Business\Event\Invitations;
|
||||
use Espo\Services\Record;
|
||||
|
||||
use Espo\Core\ORM\Entity as CoreEntity;
|
||||
|
||||
use Espo\Core\Exceptions\NotFound;
|
||||
use Espo\Core\Exceptions\BadRequest;
|
||||
|
||||
use Espo\Core\Di;
|
||||
use Espo\Tools\Email\SendService;
|
||||
|
||||
/**
|
||||
* @extends Record<CoreEntity>
|
||||
@@ -114,7 +108,7 @@ class Meeting extends Record implements
|
||||
}
|
||||
|
||||
foreach ($newIdList as $userId) {
|
||||
if (!$this->getAcl()->checkAssignmentPermission($userId)) {
|
||||
if (!$this->acl->checkAssignmentPermission($userId)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -122,97 +116,6 @@ class Meeting extends Record implements
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function getInvitationManager(bool $useUserSmtp = true): Invitations
|
||||
{
|
||||
$smtpParams = null;
|
||||
|
||||
if ($useUserSmtp) {
|
||||
$smtpParams = $this->getEmailSendService()->getUserSmtpParams($this->user->getId());
|
||||
}
|
||||
|
||||
$builder = BindingContainerBuilder::create();
|
||||
|
||||
if ($smtpParams) {
|
||||
$builder->bindInstance(SmtpParams::class, $smtpParams);
|
||||
}
|
||||
|
||||
return $this->injectableFactory->createWithBinding(Invitations::class, $builder->build());
|
||||
}
|
||||
|
||||
public function sendInvitations(CoreEntity $entity, bool $useUserSmtp = true): bool
|
||||
{
|
||||
$invitationManager = $this->getInvitationManager($useUserSmtp);
|
||||
|
||||
$emailHash = [];
|
||||
|
||||
$sentCount = 0;
|
||||
|
||||
$users = $this->entityManager
|
||||
->getRDBRepository($entity->getEntityType())
|
||||
->getRelation($entity, 'users')
|
||||
->find();
|
||||
|
||||
foreach ($users as $user) {
|
||||
if (
|
||||
$user->getId() === $this->user->getId() &&
|
||||
$entity->getLinkMultipleColumn('users', 'status', $user->getId()) ===
|
||||
MeetingEntity::ATTENDEE_STATUS_ACCEPTED
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($user->get('emailAddress') && !array_key_exists($user->get('emailAddress'), $emailHash)) {
|
||||
$invitationManager->sendInvitation($entity, $user, 'users');
|
||||
|
||||
$emailHash[$user->get('emailAddress')] = true;
|
||||
|
||||
$sentCount ++;
|
||||
}
|
||||
}
|
||||
|
||||
$contacts = $this->entityManager
|
||||
->getRDBRepository($entity->getEntityType())
|
||||
->getRelation($entity, 'contacts')
|
||||
->find();
|
||||
|
||||
foreach ($contacts as $contact) {
|
||||
if (
|
||||
$contact->get('emailAddress') &&
|
||||
!array_key_exists($contact->get('emailAddress'), $emailHash)
|
||||
) {
|
||||
$invitationManager->sendInvitation($entity, $contact, 'contacts');
|
||||
|
||||
$emailHash[$contact->get('emailAddress')] = true;
|
||||
|
||||
$sentCount ++;
|
||||
}
|
||||
}
|
||||
|
||||
$leads = $this->entityManager
|
||||
->getRDBRepository($entity->getEntityType())
|
||||
->getRelation($entity, 'leads')
|
||||
->find();
|
||||
|
||||
foreach ($leads as $lead) {
|
||||
if (
|
||||
$lead->get('emailAddress') &&
|
||||
!array_key_exists($lead->get('emailAddress'), $emailHash)
|
||||
) {
|
||||
$invitationManager->sendInvitation($entity, $lead, 'leads');
|
||||
|
||||
$emailHash[$lead->get('emailAddress')] = true;
|
||||
|
||||
$sentCount ++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$sentCount) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $ids
|
||||
*/
|
||||
@@ -302,9 +205,4 @@ class Meeting extends Record implements
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function getEmailSendService(): SendService
|
||||
{
|
||||
return $this->injectableFactory->create(SendService::class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii 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.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Modules\Crm\Tools\Meeting;
|
||||
|
||||
use Espo\Core\Acl;
|
||||
use Espo\Core\Acl\Table;
|
||||
use Espo\Core\Binding\BindingContainerBuilder;
|
||||
use Espo\Core\Exceptions\Forbidden;
|
||||
use Espo\Core\Exceptions\NotFound;
|
||||
use Espo\Core\InjectableFactory;
|
||||
use Espo\Core\Mail\SmtpParams;
|
||||
use Espo\Core\Record\ServiceContainer as RecordServiceContainer;
|
||||
use Espo\Entities\Email;
|
||||
use Espo\Entities\User;
|
||||
use Espo\Modules\Crm\Business\Event\Invitations;
|
||||
use Espo\Modules\Crm\Entities\Contact;
|
||||
use Espo\Modules\Crm\Entities\Lead;
|
||||
use Espo\Modules\Crm\Entities\Meeting;
|
||||
use Espo\ORM\Collection;
|
||||
use Espo\ORM\Entity;
|
||||
use Espo\ORM\EntityManager;
|
||||
use Espo\Tools\Email\SendService;
|
||||
|
||||
|
||||
class InvitationService
|
||||
{
|
||||
private RecordServiceContainer $recordServiceContainer;
|
||||
private SendService $sendService;
|
||||
private User $user;
|
||||
private InjectableFactory $injectableFactory;
|
||||
private Acl $acl;
|
||||
private EntityManager $entityManager;
|
||||
|
||||
public function __construct(
|
||||
RecordServiceContainer $recordServiceContainer,
|
||||
SendService $sendService,
|
||||
User $user,
|
||||
InjectableFactory $injectableFactory,
|
||||
Acl $acl,
|
||||
EntityManager $entityManager
|
||||
) {
|
||||
$this->recordServiceContainer = $recordServiceContainer;
|
||||
$this->sendService = $sendService;
|
||||
$this->user = $user;
|
||||
$this->injectableFactory = $injectableFactory;
|
||||
$this->acl = $acl;
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send invitations for a meeting (or call). Checks access. Uses user's SMTP if available.
|
||||
*
|
||||
* @return Entity[] Entities an invitation was sent to.
|
||||
*
|
||||
* @throws Forbidden
|
||||
* @throws NotFound
|
||||
*/
|
||||
public function send(string $entityType, string $id): array
|
||||
{
|
||||
$entity = $this->recordServiceContainer
|
||||
->get($entityType)
|
||||
->getEntity($id);
|
||||
|
||||
if (!$entity) {
|
||||
throw new NotFound();
|
||||
}
|
||||
|
||||
if (!$this->acl->checkEntityEdit($entity)) {
|
||||
throw new Forbidden("No edit access.");
|
||||
}
|
||||
|
||||
if (!$this->acl->checkScope(Email::ENTITY_TYPE, Table::ACTION_CREATE)) {
|
||||
throw new Forbidden("No email create access.");
|
||||
}
|
||||
|
||||
$sender = $this->getSender();
|
||||
|
||||
$sentAddressList = [];
|
||||
$resultEntityList = [];
|
||||
|
||||
foreach ($this->getUsers($entity) as $user) {
|
||||
$emailAddress = $user->getEmailAddress();
|
||||
|
||||
if ($emailAddress) {
|
||||
$sender->sendInvitation($entity, $user, 'users');
|
||||
|
||||
$sentAddressList[] = $emailAddress;
|
||||
$resultEntityList[] = $user;
|
||||
}
|
||||
}
|
||||
|
||||
/** @var Collection<Contact> $contacts */
|
||||
$contacts = $this->entityManager
|
||||
->getRDBRepository($entity->getEntityType())
|
||||
->getRelation($entity, 'contacts')
|
||||
->find();
|
||||
|
||||
/** @var Collection<Lead> $leads */
|
||||
$leads = $this->entityManager
|
||||
->getRDBRepository($entity->getEntityType())
|
||||
->getRelation($entity, 'leads')
|
||||
->find();
|
||||
|
||||
foreach ($contacts as $contact) {
|
||||
$emailAddress = $contact->getEmailAddress();
|
||||
|
||||
if ($emailAddress && !in_array($emailAddress, $sentAddressList)) {
|
||||
$sender->sendInvitation($entity, $contact, 'contacts');
|
||||
|
||||
$sentAddressList[] = $emailAddress;
|
||||
$resultEntityList[] = $contact;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($leads as $lead) {
|
||||
$emailAddress = $lead->getEmailAddress();
|
||||
|
||||
if ($emailAddress && !in_array($emailAddress, $sentAddressList)) {
|
||||
$sender->sendInvitation($entity, $lead, 'leads');
|
||||
|
||||
$sentAddressList[] = $emailAddress;
|
||||
$resultEntityList[] = $lead;
|
||||
}
|
||||
}
|
||||
|
||||
return $resultEntityList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<User>
|
||||
*/
|
||||
private function getUsers(Entity $entity): Collection
|
||||
{
|
||||
/** @var Collection<User> */
|
||||
return $this->entityManager
|
||||
->getRDBRepository($entity->getEntityType())
|
||||
->getRelation($entity, 'users')
|
||||
->where([
|
||||
'OR' => [
|
||||
[
|
||||
'id=' => $this->user->getId(),
|
||||
'@relation.status!=' => Meeting::ATTENDEE_STATUS_ACCEPTED,
|
||||
],
|
||||
[
|
||||
'id!=' => $this->user->getId(),
|
||||
]
|
||||
]
|
||||
])
|
||||
->find();
|
||||
}
|
||||
|
||||
private function getSender(): Invitations
|
||||
{
|
||||
$smtpParams = $this->sendService->getUserSmtpParams($this->user->getId());
|
||||
|
||||
$builder = BindingContainerBuilder::create();
|
||||
|
||||
if ($smtpParams) {
|
||||
$builder->bindInstance(SmtpParams::class, $smtpParams);
|
||||
}
|
||||
|
||||
return $this->injectableFactory->createWithBinding(Invitations::class, $builder->build());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user