This repository has been archived on 2026-07-19. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
espocrm-base/application/Espo/Modules/Crm/Services/Activities.php
T
2015-02-20 16:33:49 +02:00

503 lines
17 KiB
PHP

<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2015 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
* Website: http://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/.
************************************************************************/
namespace Espo\Modules\Crm\Services;
use \Espo\Core\Exceptions\Error;
use \PDO;
class Activities extends \Espo\Core\Services\Base
{
protected $dependencies = array(
'entityManager',
'user',
'metadata',
'acl'
);
protected function getPDO()
{
return $this->getEntityManager()->getPDO();
}
protected function getEntityManager()
{
return $this->injections['entityManager'];
}
protected function getUser()
{
return $this->injections['user'];
}
protected function getAcl()
{
return $this->injections['acl'];
}
protected function getMetadata()
{
return $this->injections['metadata'];
}
protected function isPerson($scope)
{
return in_array($scope, array('Contact', 'Lead', 'User'));
}
protected function getMeetingQuery($scope, $id, $op = 'IN', $notIn = array())
{
$baseSql = "
SELECT meeting.id AS 'id', meeting.name AS 'name', meeting.date_start AS 'dateStart', meeting.date_end AS 'dateEnd', 'Meeting' AS '_scope',
meeting.assigned_user_id AS assignedUserId, TRIM(CONCAT(user.first_name, ' ', user.last_name)) AS assignedUserName,
meeting.parent_type AS 'parentType', meeting.parent_id AS 'parentId', meeting.status AS status, meeting.created_at AS createdAt
FROM `meeting`
LEFT JOIN `user` ON user.id = meeting.assigned_user_id
";
$sql = $baseSql;
$sql .= "
WHERE
meeting.deleted = 0 AND
";
if ($scope == 'Account') {
$sql .= "
(meeting.parent_type = ".$this->getPDO()->quote($scope)." AND meeting.parent_id = ".$this->getPDO()->quote($id)."
OR
meeting.account_id = ".$this->getPDO()->quote($id).")
";
} else {
$sql .= "
(meeting.parent_type = ".$this->getPDO()->quote($scope)." AND meeting.parent_id = ".$this->getPDO()->quote($id).")
";
}
if (!empty($notIn)) {
$sql .= "
AND meeting.status {$op} ('". implode("', '", $notIn) . "')
";
}
if ($this->isPerson($scope)) {
$sql = $sql . "
UNION
" . $baseSql;
switch ($scope) {
case 'Contact':
$joinTable = 'contact_meeting';
$key = 'contact_id';
break;
case 'Lead':
$joinTable = 'lead_meeting';
$key = 'lead_id';
break;
case 'User':
$joinTable = 'meeting_user';
$key = 'user_id';
break;
}
$sql .= "
JOIN `{$joinTable}` ON
meeting.id = {$joinTable}.meeting_id AND
{$joinTable}.deleted = 0 AND
{$joinTable}.{$key} = ".$this->getPDO()->quote($id)."
";
$sql .= "
WHERE
(
meeting.parent_type <> ".$this->getPDO()->quote($scope)." OR
meeting.parent_id <> ".$this->getPDO()->quote($id)." OR
meeting.parent_type IS NULL OR
meeting.parent_id IS NULL
) AND
meeting.deleted = 0
";
if (!empty($notIn)) {
$sql .= "
AND meeting.status {$op} ('". implode("', '", $notIn) . "')
";
}
}
return $sql;
}
protected function getCallQuery($scope, $id, $op = 'IN', $notIn = array())
{
$baseSql = "
SELECT call.id AS 'id', call.name AS 'name', call.date_start AS 'dateStart', call.date_end AS 'dateEnd', 'Call' AS '_scope',
call.assigned_user_id AS assignedUserId, TRIM(CONCAT(user.first_name, ' ', user.last_name)) AS assignedUserName,
call.parent_type AS 'parentType', call.parent_id AS 'parentId', call.status AS status, call.created_at AS createdAt
FROM `call`
LEFT JOIN `user` ON user.id = call.assigned_user_id
";
$sql = $baseSql;
$sql .= "
WHERE
call.deleted = 0 AND
";
if ($scope == 'Account') {
$sql .= "
(call.parent_type = ".$this->getPDO()->quote($scope)." AND call.parent_id = ".$this->getPDO()->quote($id)."
OR
call.account_id = ".$this->getPDO()->quote($id).")
";
} else {
$sql .= "
(call.parent_type = ".$this->getPDO()->quote($scope)." AND call.parent_id = ".$this->getPDO()->quote($id).")
";
}
if (!empty($notIn)) {
$sql .= "
AND call.status {$op} ('". implode("', '", $notIn) . "')
";
}
if ($this->isPerson($scope)) {
$sql = $sql . "
UNION
" . $baseSql;
switch ($scope) {
case 'Contact':
$joinTable = 'call_contact';
$key = 'contact_id';
break;
case 'Lead':
$joinTable = 'call_lead';
$key = 'lead_id';
break;
case 'User':
$joinTable = 'call_user';
$key = 'user_id';
break;
}
$sql .= "
JOIN `{$joinTable}` ON
call.id = {$joinTable}.call_id AND
{$joinTable}.deleted = 0 AND
{$joinTable}.{$key} = ".$this->getPDO()->quote($id)."
";
$sql .= "
WHERE
(
call.parent_type <> ".$this->getPDO()->quote($scope)." OR
call.parent_id <> ".$this->getPDO()->quote($id)." OR
call.parent_type IS NULL OR
call.parent_id IS NULL
) AND
call.deleted = 0
";
if (!empty($notIn)) {
$sql .= "
AND call.status {$op} ('". implode("', '", $notIn) . "')
";
}
}
return $sql;
}
protected function getEmailQuery($scope, $id, $op = 'IN', $notIn = array())
{
$baseSql = "
SELECT DISTINCT
email.id AS 'id', email.name AS 'name', email.date_sent AS 'dateStart', '' AS 'dateEnd', 'Email' AS '_scope',
email.assigned_user_id AS assignedUserId, TRIM(CONCAT(user.first_name, ' ', user.last_name)) AS assignedUserName,
email.parent_type AS 'parentType', email.parent_id AS 'parentId', email.status AS status, email.created_at AS createdAt
FROM `email`
LEFT JOIN `user` ON user.id = email.assigned_user_id
";
$sql = $baseSql;
$sql .= "
WHERE
email.deleted = 0 AND
";
if ($scope == 'Account') {
$sql .= "
(email.parent_type = ".$this->getPDO()->quote($scope)." AND email.parent_id = ".$this->getPDO()->quote($id)."
OR
email.account_id = ".$this->getPDO()->quote($id).")
";
} else {
$sql .= "
(email.parent_type = ".$this->getPDO()->quote($scope)." AND email.parent_id = ".$this->getPDO()->quote($id).")
";
}
if (!empty($notIn)) {
$sql .= "
AND email.status {$op} ('". implode("', '", $notIn) . "')
";
}
if ($this->isPerson($scope)) {
$sql = $sql . "
UNION
" . $baseSql;
$sql .= "
LEFT JOIN entity_email_address AS entity_email_address_2 ON
entity_email_address_2.email_address_id = email.from_email_address_id AND
entity_email_address_2.entity_type = " . $this->getPDO()->quote($scope) . " AND
entity_email_address_2.deleted = 0
LEFT JOIN email_email_address ON
email_email_address.email_id = email.id AND
email_email_address.deleted = 0
LEFT JOIN entity_email_address AS entity_email_address_1 ON
entity_email_address_1.email_address_id = email_email_address.email_address_id AND
entity_email_address_1.entity_type = " . $this->getPDO()->quote($scope) . " AND
entity_email_address_1.deleted = 0
";
$sql .= "
WHERE
email.deleted = 0 AND
(
email.parent_type <> ".$this->getPDO()->quote($scope)." OR
email.parent_id <> ".$this->getPDO()->quote($id)." OR
email.parent_type IS NULL OR
email.parent_id IS NULL
) AND
(entity_email_address_1.entity_id = ".$this->getPDO()->quote($id)." OR entity_email_address_2.entity_id = ".$this->getPDO()->quote($id).")
";
if (!empty($notIn)) {
$sql .= "
AND email.status {$op} ('". implode("', '", $notIn) . "')
";
}
}
return $sql;
}
protected function getResult($parts, $scope, $id, $params)
{
$pdo = $this->getEntityManager()->getPDO();
$onlyScope = false;
if (!empty($params['scope'])) {
$onlyScope = $params['scope'];
}
if (!$onlyScope) {
$qu = implode(" UNION ", $parts);
} else {
$qu = $parts[$onlyScope];
}
$countQu = "SELECT COUNT(*) AS 'count' FROM ({$qu}) AS c";
$sth = $pdo->prepare($countQu);
$sth->execute();
$row = $sth->fetch(PDO::FETCH_ASSOC);
$totalCount = $row['count'];
$qu .= "
ORDER BY dateStart DESC, createdAt DESC
";
if (!empty($params['maxSize'])) {
$qu .= "
LIMIT :offset, :maxSize
";
}
$sth = $pdo->prepare($qu);
if (!empty($params['maxSize'])) {
$offset = 0;
if (!empty($params['offset'])) {
$offset = $params['offset'];
}
$sth->bindParam(':offset', $offset, PDO::PARAM_INT);
$sth->bindParam(':maxSize', $params['maxSize'], PDO::PARAM_INT);
}
$sth->execute();
$rows = $sth->fetchAll(PDO::FETCH_ASSOC);
$list = array();
foreach ($rows as $row) {
$list[] = $row;
}
return array(
'list' => $rows,
'total' => $totalCount
);
}
public function getActivities($scope, $id, $params = array())
{
$fetchAll = empty($params['scope']);
$parts = array(
'Meeting' => ($fetchAll || $params['scope'] == 'Meeting') ? $this->getMeetingQuery($scope, $id, 'NOT IN', array('Held', 'Not Held')) : array(),
'Call' => ($fetchAll || $params['scope'] == 'Call') ? $this->getCallQuery($scope, $id, 'NOT IN', array('Held', 'Not Held')) : array(),
);
return $this->getResult($parts, $scope, $id, $params);
}
public function getHistory($scope, $id, $params)
{
$fetchAll = empty($params['scope']);
$parts = array(
'Meeting' => ($fetchAll || $params['scope'] == 'Meeting') ? $this->getMeetingQuery($scope, $id, 'IN', array('Held')) : array(),
'Call' => ($fetchAll || $params['scope'] == 'Call') ? $this->getCallQuery($scope, $id, 'IN', array('Held')) : array(),
'Email' => ($fetchAll || $params['scope'] == 'Email') ? $this->getEmailQuery($scope, $id, 'IN', array('Archived', 'Sent')) : array(),
);
$result = $this->getResult($parts, $scope, $id, $params);
foreach ($result['list'] as &$item) {
if ($item['_scope'] == 'Email') {
$item['dateSent'] = $item['dateStart'];
}
}
return $result;
}
public function getEvents($userId, $from, $to)
{
$pdo = $this->getPDO();
$sql = "
SELECT 'Meeting' AS scope, meeting.id AS id, meeting.name AS name, meeting.date_start AS dateStart, meeting.date_end AS dateEnd, meeting.status AS status
FROM `meeting`
JOIN meeting_user ON meeting_user.meeting_id = meeting.id AND meeting_user.deleted = 0
WHERE
meeting.deleted = 0 AND
meeting.date_start >= ".$pdo->quote($from)." AND
meeting.date_start < ".$pdo->quote($to)." AND
meeting_user.user_id =".$pdo->quote($userId)."
UNION
SELECT 'Call' AS scope, call.id AS id, call.name AS name, call.date_start AS dateStart, call.date_end AS dateEnd, call.status AS status
FROM `call`
JOIN call_user ON call_user.call_id = call.id AND call_user.deleted = 0
WHERE
call.deleted = 0 AND
call.date_start >= ".$pdo->quote($from)." AND
call.date_start < ".$pdo->quote($to)." AND
call_user.user_id = ".$pdo->quote($userId)."
UNION
SELECT 'Task' AS scope, task.id AS id, task.name AS name, task.date_start AS dateStart, task.date_end AS dateEnd, task.status AS status
FROM `task`
WHERE
task.deleted = 0 AND
(
(
task.date_start >= ".$pdo->quote($from)." AND
task.date_start < ".$pdo->quote($to)."
) OR (
(task.date_start IS NULL OR task.date_start = '') AND
task.date_end >= ".$pdo->quote($from)." AND
task.date_end < ".$pdo->quote($to)."
)
) AND
task.assigned_user_id = ".$pdo->quote($userId)."
";
$sth = $pdo->prepare($sql);
$sth->execute();
$rows = $sth->fetchAll(PDO::FETCH_ASSOC);
return $rows;
}
public function removeReminder($id)
{
$pdo = $this->getPDO();
$sql = "
DELETE FROM `reminder`
WHERE id = ".$pdo->quote($id)."
";
if (!$this->getUser()->isAdmin()) {
$sql .= " AND user_id = " . $pdo->quote($this->getUser()->id);
}
$pdo->query($sql);
return true;
}
public function getPopupNotifications($userId)
{
$pdo = $this->getPDO();
$dt = new \DateTime();
$now = $dt->format('Y-m-d H:i:s');
$nowShifted = $dt->sub(new \DateInterval('PT1H'))->format('Y-m-d H:i:s');
$sql = "
SELECT id, entity_type AS 'entityType', entity_id AS 'entityId'
FROM `reminder`
WHERE
`type` = 'Popup' AND
`user_id` = ".$pdo->quote($userId)." AND
`remind_at` <= '{$now}' AND
`start_at` > '{$nowShifted}' AND
`deleted` = 0
";
$sth = $pdo->prepare($sql);
$sth->execute();
$rows = $sth->fetchAll(PDO::FETCH_ASSOC);
$result = array();
foreach ($rows as $row) {
$entity = $this->getEntityManager()->getEntity($row['entityType'], $row['entityId']);
$data = null;
if ($entity) {
$data = array(
'id' => $entity->id,
'entityType' => $row['entityType'],
'dateStart' => $entity->get('dateStart'),
'name' => $entity->get('name')
);
}
$result[] = array(
'id' => $row['id'],
'data' => $data
);
}
return $result;
}
}