This commit is contained in:
Yuri Kuznetsov
2022-11-18 11:01:23 +02:00
parent 3fa83db99f
commit 99ca025ded
6 changed files with 106 additions and 121 deletions
@@ -31,18 +31,19 @@ namespace Espo\Classes\Cleanup;
use Espo\Core\Cleanup\Cleanup;
use Espo\Core\Utils\Config;
use Espo\Core\Utils\DateTime as DateTimeUtil;
use Espo\Modules\Crm\Entities\Reminder;
use Espo\ORM\EntityManager;
use DateTime;
class Reminders implements Cleanup
{
private $config;
private $entityManager;
private string $cleanupRemindersPeriod = '15 days';
private Config $config;
private EntityManager $entityManager;
public function __construct(Config $config, EntityManager $entityManager)
{
$this->config = $config;
@@ -60,9 +61,9 @@ class Reminders implements Cleanup
$delete = $this->entityManager
->getQueryBuilder()
->delete()
->from('Reminder')
->from(Reminder::ENTITY_TYPE)
->where([
'remindAt<' => $dt->format('Y-m-d'),
'remindAt<' => $dt->format(DateTimeUtil::SYSTEM_DATE_TIME_FORMAT),
])
->build();
@@ -29,13 +29,13 @@
namespace Espo\Core\FieldProcessing\Reminder;
use Espo\Modules\Crm\Entities\Reminder;
use Espo\ORM\Collection;
use Espo\ORM\Entity;
use Espo\Core\{
ORM\EntityManager,
FieldProcessing\Loader as LoaderInterface,
FieldProcessing\Loader\Params,
};
use Espo\Core\FieldProcessing\Loader as LoaderInterface;
use Espo\Core\FieldProcessing\Loader\Params;
use Espo\Core\ORM\EntityManager;
/**
* @internal This class should not be removed as it's used by custom entities.
@@ -43,12 +43,8 @@ use Espo\Core\{
*/
class Loader implements LoaderInterface
{
private $entityManager;
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
public function __construct(private EntityManager $entityManager)
{}
public function process(Entity $entity, Params $params): void
{
@@ -75,8 +71,9 @@ class Loader implements LoaderInterface
{
$list = [];
/** @var Collection<Reminder> $collection */
$collection = $this->entityManager
->getRDBRepository('Reminder')
->getRDBRepository(Reminder::ENTITY_TYPE)
->select(['seconds', 'type'])
->where([
'entityType' => $entity->getEntityType(),
@@ -88,8 +85,8 @@ class Loader implements LoaderInterface
foreach ($collection as $reminder) {
$list[] = (object) [
'seconds' => $reminder->get('seconds'),
'type' => $reminder->get('type'),
'seconds' => $reminder->getSeconds(),
'type' => $reminder->getType(),
];
}
+12 -13
View File
@@ -29,12 +29,12 @@
namespace Espo\Core\Repositories;
use Espo\Modules\Crm\Entities\Meeting;
use Espo\Modules\Crm\Entities\Reminder;
use Espo\ORM\Entity;
use Espo\Core\{
Di,
Utils\DateTime as DateTimeUtil,
};
use Espo\Core\Di;
use Espo\Core\Utils\DateTime as DateTimeUtil;
use DateTime;
use DateTimeZone;
@@ -55,7 +55,10 @@ class Event extends Database implements
/**
* @var string[]
*/
protected $reminderSkippingStatusList = ['Held', 'Not Held'];
protected $reminderSkippingStatusList = [
Meeting::STATUS_HELD,
Meeting::STATUS_NOT_HELD,
];
/**
* @param array<string,mixed> $options
@@ -93,13 +96,13 @@ class Event extends Database implements
$dt = new DateTime(
$this->convertDateTimeToDefaultTimezone($dateEndDate . ' 00:00:00')
);
} catch (Exception $e) {
} catch (Exception) {
throw new RuntimeException("Bad date-time.");
}
$dt->modify('+1 day');
$dateEnd = $dt->format('Y-m-d H:i:s');
$dateEnd = $dt->format(DateTimeUtil::SYSTEM_DATE_TIME_FORMAT);
$entity->set('dateEnd', $dateEnd);
}
else {
@@ -120,7 +123,7 @@ class Event extends Database implements
$delete = $this->entityManager->getQueryBuilder()
->delete()
->from('Reminder')
->from(Reminder::ENTITY_TYPE)
->where([
'entityId' => $entity->getId(),
'entityType' => $entity->getEntityType(),
@@ -140,11 +143,7 @@ class Event extends Database implements
$tz = new DateTimeZone($timeZone);
$dt = DateTime::createFromFormat(
DateTimeUtil::SYSTEM_DATE_TIME_FORMAT,
$string,
$tz
);
$dt = DateTime::createFromFormat(DateTimeUtil::SYSTEM_DATE_TIME_FORMAT, $string, $tz);
if ($dt === false) {
throw new RuntimeException("Could not parse date-time `{$string}`.");
@@ -29,7 +29,9 @@
namespace Espo\Modules\Crm\Entities;
class Reminder extends \Espo\Core\ORM\Entity
use Espo\Core\ORM\Entity;
class Reminder extends Entity
{
public const ENTITY_TYPE = 'Reminder';
@@ -50,4 +52,14 @@ class Reminder extends \Espo\Core\ORM\Entity
{
return $this->get('entityType');
}
public function getType(): ?string
{
return $this->get('type');
}
public function getSeconds(): int
{
return (int) $this->get('seconds');
}
}
@@ -29,16 +29,14 @@
namespace Espo\Modules\Crm\Jobs;
use Espo\Core\{
InjectableFactory,
ORM\EntityManager,
Utils\Config,
Job\JobDataLess,
Utils\Log,
};
use Espo\Core\InjectableFactory;
use Espo\Core\Job\JobDataLess;
use Espo\Core\ORM\EntityManager;
use Espo\Core\Utils\Config;
use Espo\Core\Utils\DateTime as DateTimeUtil;
use Espo\Core\Utils\Log;
use Espo\Modules\Crm\Business\Reminder\EmailReminder;
use Espo\Modules\Crm\Entities\Reminder;
use Throwable;
use DateTime;
use DateInterval;
@@ -47,40 +45,29 @@ class SendEmailReminders implements JobDataLess
{
private const MAX_PORTION_SIZE = 10;
private $injectableFactory;
private $entityManager;
private $config;
private $log;
public function __construct(
InjectableFactory $injectableFactory,
EntityManager $entityManager,
Config $config,
Log $log
) {
$this->injectableFactory = $injectableFactory;
$this->entityManager = $entityManager;
$this->config = $config;
$this->log = $log;
}
private InjectableFactory $injectableFactory,
private EntityManager $entityManager,
private Config $config,
private Log $log
) {}
public function run(): void
{
$dt = new DateTime();
$now = $dt->format('Y-m-d H:i:s');
$now = $dt->format(DateTimeUtil::SYSTEM_DATE_TIME_FORMAT);
$nowShifted = $dt->sub(new DateInterval('PT1H'))->format('Y-m-d H:i:s');
$nowShifted = $dt
->sub(new DateInterval('PT1H'))
->format(DateTimeUtil::SYSTEM_DATE_TIME_FORMAT);
$maxPortionSize = $this->config->get('emailReminderPortionSize') ?? self::MAX_PORTION_SIZE;
$collection = $this->entityManager
->getRDBRepository('Reminder')
->getRDBRepository(Reminder::ENTITY_TYPE)
->where([
'type' => 'Email',
'type' => Reminder::TYPE_EMAIL,
'remindAt<=' => $now,
'startAt>' => $nowShifted,
])
@@ -98,13 +85,11 @@ class SendEmailReminders implements JobDataLess
$emailReminder->send($entity);
}
catch (Throwable $e) {
$this->log->error(
"Email reminder '{$entity->getId()}': " . $e->getMessage()
);
$this->log->error("Email reminder '{$entity->getId()}': " . $e->getMessage());
}
$this->entityManager
->getRDBRepository('Reminder')
->getRDBRepository(Reminder::ENTITY_TYPE)
->deleteFromDb($entity->getId());
}
}
@@ -30,16 +30,14 @@
namespace Espo\Modules\Crm\Jobs;
use Espo\Core\ORM\Entity as CoreEntity;
use Espo\Modules\Crm\Entities\Meeting;
use Espo\Modules\Crm\Entities\Reminder;
use Espo\Core\{
ORM\EntityManager,
Utils\Config,
WebSocket\Submission as WebSocketSubmission,
Job\JobDataLess,
Utils\Log,
};
use Espo\Core\Job\JobDataLess;
use Espo\Core\ORM\EntityManager;
use Espo\Core\Utils\Config;
use Espo\Core\Utils\DateTime as DateTimeUtil;
use Espo\Core\Utils\Log;
use Espo\Core\WebSocket\Submission as WebSocketSubmission;
use Throwable;
use DateTime;
@@ -48,25 +46,12 @@ class SubmitPopupReminders implements JobDataLess
{
private const REMINDER_PAST_HOURS = 24;
private $entityManager;
private $config;
private $webSocketSubmission;
private $log;
public function __construct(
EntityManager $entityManager,
Config $config,
WebSocketSubmission $webSocketSubmission,
Log $log
) {
$this->entityManager = $entityManager;
$this->config = $config;
$this->webSocketSubmission = $webSocketSubmission;
$this->log = $log;
}
private EntityManager $entityManager,
private Config $config,
private WebSocketSubmission $webSocketSubmission,
private Log $log
) {}
public function run(): void
{
@@ -75,17 +60,18 @@ class SubmitPopupReminders implements JobDataLess
}
$dt = new DateTime();
$now = $dt->format('Y-m-d H:i:s');
$now = $dt->format(DateTimeUtil::SYSTEM_DATE_TIME_FORMAT);
$pastHours = $this->config->get('reminderPastHours', self::REMINDER_PAST_HOURS);
$nowShifted = $dt->modify('-' . $pastHours . ' hours')->format('Y-m-d H:i:s');
$nowShifted = $dt
->modify('-' . $pastHours . ' hours')
->format(DateTimeUtil::SYSTEM_DATE_TIME_FORMAT);
$reminderList = $this->entityManager
->getRDBRepository('Reminder')
->getRDBRepository(Reminder::ENTITY_TYPE)
->where([
'type' => 'Popup',
'type' => Reminder::TYPE_POPUP,
'remindAt<=' => $now,
'startAt>' => $nowShifted,
'isSubmitted' => false,
@@ -99,13 +85,18 @@ class SubmitPopupReminders implements JobDataLess
$entityType = $reminder->getTargetEntityType();
$entityId = $reminder->getTargetEntityId();
if (!$userId || !$entityType || !$entityId) {
if (
!$userId ||
!$entityType ||
!$entityId ||
!$this->entityManager->hasRepository($entityType)
) {
$this->deleteReminder($reminder);
continue;
}
$entity = $this->entityManager->getEntity($entityType, $entityId);
$entity = $this->entityManager->getEntityById($entityType, $entityId);
if (!$entity) {
$this->deleteReminder($reminder);
@@ -121,7 +112,7 @@ class SubmitPopupReminders implements JobDataLess
$status = $entity->getLinkMultipleColumn('users', 'status', $userId);
if ($status === 'Declined') {
if ($status === Meeting::ATTENDEE_STATUS_DECLINED) {
$this->deleteReminder($reminder);
continue;
@@ -130,36 +121,34 @@ class SubmitPopupReminders implements JobDataLess
$dateAttribute = 'dateStart';
if ($entityType === 'Task') {
$dateAttribute = 'dateEnd';
$entityDefs = $this->entityManager->getDefs()->getEntity($entityType);
if ($entityDefs->hasField('reminders')) {
$dateAttribute = $entityDefs
->getField('reminders')
->getParam('dateField') ?? $dateAttribute;
}
$data = [
$submitData[$userId] ??= [];
$submitData[$userId][] = [
'id' => $reminder->getId(),
'data' => [
'data' => (object) [
'id' => $entity->getId(),
'entityType' => $entityType,
$dateAttribute => $entity->get($dateAttribute),
'name' => $entity->get('name'),
],
];
if (!array_key_exists($userId, $submitData)) {
$submitData[$userId] = [];
}
$submitData[$userId][] = $data;
];;
$reminder->set('isSubmitted', true);
$this->entityManager->saveEntity($reminder);
}
foreach ($submitData as $userId => $list) {
try {
$this->webSocketSubmission->submit('popupNotifications.event', $userId, (object) [
'list' => $list
]);
$this->webSocketSubmission
->submit('popupNotifications.event', $userId, (object) ['list' => $list]);
}
catch (Throwable $e) {
$this->log->error('Job SubmitPopupReminders: [' . $e->getCode() . '] ' .$e->getMessage());
@@ -167,8 +156,10 @@ class SubmitPopupReminders implements JobDataLess
}
}
protected function deleteReminder(Reminder $reminder): void
private function deleteReminder(Reminder $reminder): void
{
$this->entityManager->getRDBRepository('Reminder')->deleteFromDb($reminder->getId());
$this->entityManager
->getRDBRepository(Reminder::ENTITY_TYPE)
->deleteFromDb($reminder->getId());
}
}