• Модуль: tasks
  • Путь к файлу: ~/bitrix/modules/tasks/lib/replicator/template/repetition/time/service/executionservice.php
  • Класс: BitrixTasksReplicatorTemplateRepetitionTimeServiceExecutionService
  • Вызов: ExecutionService::getTemplateNextExecutionTime
public function getTemplateNextExecutionTime(string $lastExecutionTime): Result
{
	$template = $this->repository->getTemplate();

	// get users and their time zone offsets
	$currentUserTimeZoneOffsetTS = User::getTimeZoneOffsetCurrentUser();

	$timeZoneOffsetTS = $this->replicateParameter->get('TIMEZONE_OFFSET');
	$creatorTimeZoneOffsetTS = $timeZoneOffsetTS ?? User::getTimeZoneOffset($template->getCreatedBy());

	// prepare time to be forced to
	$replicationTimeTS = strtotime($this->replicateParameter->get('TIME'));
	$creatorPreferredTimeTS = UI::parseTimeAmount(
		date("H:i", $replicationTimeTS - $creatorTimeZoneOffsetTS), 'HH:MI'
	);

	// prepare base time
	$baseExecutionTimeTS = time();

	if ($lastExecutionTime) // agent were found and had legal next_time
	{
		$lastExecutionTimeTS = (int)MakeTimeStamp($lastExecutionTime);
		if ($lastExecutionTimeTS > 0)
		{
			// $agentTime is in current user`s time, but we want server time here
			$lastExecutionTimeTS -= $currentUserTimeZoneOffsetTS;
			$baseExecutionTimeTS = $lastExecutionTimeTS;
		}
	}

	$replicationStartTimeTS = 0;
	$replicationStartTime = $this->replicateParameter->get('START_DATE');
	if ($replicationStartTime)
	{
		$replicationStartTimeTS = MakeTimeStamp($replicationStartTime);
		$replicationStartTimeTS -= $creatorTimeZoneOffsetTS;
	}

	$replicationEndTimeTS = PHP_INT_MAX; // never ending
	$replicationEndTime = $this->replicateParameter->get('END_DATE');
	if ($replicationEndTime)
	{
		$replicationEndTimeTS = MakeTimeStamp($replicationEndTime);
		$replicationEndTimeTS -= $creatorTimeZoneOffsetTS;
	}

	$baseExecutionTimeTS = max($baseExecutionTimeTS, $replicationStartTimeTS);

	$this->nextExecutionTimeTS = ExecutionTimeFactory::getNextExecutionTime(
		$baseExecutionTimeTS,
		$creatorPreferredTimeTS,
		$this->replicateParameter
	);

	if ($this->nextExecutionTimeTS <= 0)
	{
		$this->currentResult->addError(new Error(Loc::getMessage('TASKS_EXECUTION_ILLEGAL_NEXT_TIME')));
		return $this->stopReplication();
	}

	$repeatTill = $this->replicateParameter->get('REPEAT_TILL');

	if (!$repeatTill || $repeatTill === RepeatType::ENDLESS)
	{
		$this->nextExecutionTimeTS += $currentUserTimeZoneOffsetTS;
		return $this->continueReplication();
	}

	if (
		$repeatTill === RepeatType::DATE
		&& $replicationEndTimeTS > 0
		&& $this->nextExecutionTimeTS > $replicationEndTimeTS
	)
	{
		$this->currentResult->addError(new Error(Loc::getMessage('TASKS_EXECUTION_END_DATE_REACHED')));
		return $this->stopReplication();
	}

	if ($repeatTill === RepeatType::TIMES)
	{
		$neededReplicationCount = (int)$this->replicateParameter->get('TIMES');
		$currentReplicationCount = $template->getTparamReplicationCount();

		if ($currentReplicationCount >= $neededReplicationCount)
		{
			$this->currentResult->addError(new Error(Loc::getMessage('TASKS_EXECUTION_LIMIT_REACHED')));
			return $this->stopReplication();
		}
	}

	$this->nextExecutionTimeTS += $currentUserTimeZoneOffsetTS;

	return $this->continueReplication();
}