ref
This commit is contained in:
@@ -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(),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user