Reference: Espo custom assignment notification class

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • rabii
    Active Community Member
    • Jun 2016
    • 1250

    Reference: Espo custom assignment notification class

    Below is how you can implement a custom (assignmentNotificatorClassName) to enable notification for certain Lead entity based on certain conditions, follow steps below to achieve such behavior:

    1 - Create a file under custom\Espo\Custom\Classes\AssignmentNotificators\ Lead.php paste the code below:

    PHP Code:
    <?php
    
    namespace Espo\Custom\Classes\AssignmentNotificators;
    
    use Espo\Core\Field\LinkParent;
    use Espo\Core\Notification\AssignmentNotificator;
    use Espo\Core\Notification\AssignmentNotificator\Params;
    use Espo\Core\Notification\DefaultAssignmentNotificator;
    use Espo\Core\Notification\UserEnabledChecker;
    use Espo\Core\Utils\Metadata;
    use Espo\Entities\Notification;
    use Espo\Entities\User;
    use Espo\Modules\Crm\Entities\Lead as LeadEntity;
    use Espo\ORM\Entity;
    use Espo\ORM\EntityManager;
    
    /**
     * @implements AssignmentNotificator<LeadEntity>
     */
    class Lead implements AssignmentNotificator
    {
        private const ATTR_ASSIGNED_USERS_IDS = 'assignedUsersIds';
        private const TYPE_ASSIGN = 'Assign';
    
        public function __construct(
            private DefaultAssignmentNotificator $defaultAssignmentNotificator,
            private UserEnabledChecker $userEnabledChecker,
            private EntityManager $entityManager,
            private User $user,
            private Metadata $metadata
        ) {}
    
        /**
         * @param LeadEntity $entity
         */
        public function process(Entity $entity, Params $params): void
        {
            // Default assignment notifications not needed if stream is enabled.
            if (!$this->hasStream($entity->getEntityType())) {
                $this->defaultAssignmentNotificator->process($entity, $params);
            }
    
            if ($entity->getStatus() !== LeadEntity::STATUS_ASSIGNED) {
                return;
            }
    
            if (self::ATTR_ASSIGNED_USERS_IDS &&
                !$entity->isAttributeChanged(self::ATTR_ASSIGNED_USERS_IDS)
            ) {
                return;
            }
    
            /** @var string[] $prevIds */
            $prevIds = $entity->getFetched(self::ATTR_ASSIGNED_USERS_IDS) ?? [];
            $ids = $entity->get('assignedUsersIds');
    
            $newIds = array_filter($ids, fn ($id) => !in_array($id, $prevIds));
    
            $assignedUser = $entity->getAssignedUser();
    
            if ($assignedUser) {
                $newIds = array_filter($newIds, fn($id) => $id !== $assignedUser->getId());
            }
    
            $newIds = array_values($newIds);
    
            foreach ($newIds as $id) {
                $this->processForUser($entity, $id);
            }
        }
    
        /**
         * @param LeadEntity $entity
         */
        private function processForUser(Entity $entity, string $userId): void
        {
            if (!$this->userEnabledChecker->checkAssignment($entity->getEntityType(), $userId)) {
                return;
            }
    
            $createdBy = $entity->getCreatedBy();
            $modifiedBy = $entity->getModifiedBy();
    
            $isSelfAssignment = $entity->isNew() ?
                $createdBy && $userId ===  $createdBy->getId() :
                $modifiedBy && $userId === $modifiedBy->getId();
    
            if ($isSelfAssignment) {
                return;
            }
    
            /** @var Notification $notification */
            $notification = $this->entityManager->getRDBRepositoryByClass(Notification::class)->getNew();
    
            $notification
                ->setType(self::TYPE_ASSIGN)
                ->setUserId($userId)
                ->setRelated(
                    LinkParent::create($entity->getEntityType(), $entity->getId())
                )
                ->setData((object) [
                    'entityType' => $entity->getEntityType(),
                    'entityId' => $entity->getId(),
                    'entityName' => $entity->getName(),
                    'isNew' => $entity->isNew(),
                    'userId' => $this->user->getId(),
                    'userName' => $this->user->getName(),
                ]);
    
            $this->entityManager->saveEntity($notification);
        }
    
        private function hasStream(string $entityType): bool
        {
            return (bool) $this->metadata->get(['scopes', $entityType, 'stream']);
        }
    }

    The code above will only notify the user / users in case of multiple assignedusers is applied to the lead (which was the case for my use case) and only when the status of the lead is (assigned) then loop through the collection of the assignedusers and add the current assigneduser and process notification for each, by the way if the lead status is changed to something different and a new user is added it won't notify that user.

    2 - Create a file under this Path: metadata > notificationDefs > Lead.json. paste the code below

    PHP Code:
    {
        "assignmentNotificatorClassName": "Espo\\Custom\\Classes\\AssignmentNotificators\\Lead",
        "forceAssignmentNotificator": true
    }

    It is very useful class and allow a beautiful assignment implementation in different use case.

    I hope this helps ​​
    Rabii
    Web Dev
Working...