• Модуль: imopenlines
  • Путь к файлу: ~/bitrix/modules/imopenlines/lib/session.php
  • Класс: BitrixImOpenLinesSession
  • Вызов: Session::createSession
protected function createSession($fields, $params)
{
	Debug::addSession($this, 'begin ' . __METHOD__, ['fields' => $fields, '$params' => $params]);

	$result = new Result();

	/* CRM BLOCK */
	if ($params['SKIP_CRM'] != 'Y')
	{
		$crmManager = new Crm($this);
		if ($crmManager->isLoaded())
		{
			$crmManager
				->getFields()
				->setSkipPhoneValidate($params['CRM_SKIP_PHONE_VALIDATE'] === 'Y')
				->setDataFromUser($fields['USER_ID'])
			;
			$crmManager->setModeCreate($this->config['CRM_CREATE']);

			if (Connector::isNeedCRMTracker($fields['SOURCE']))
			{
				$crmManager
					->setSkipCreate()
					->setIgnoreSearchPerson();
			}

			$fields['CRM_TRACE_DATA'] = CrmTracker::getTraceData($fields['USER_ID'], $params['CRM_TRACE_DATA']);
		}
	}

	if ($fields['MODE'] === self::MODE_OUTPUT)
	{
		$previousSessionBlock = ReplyBlock::getBlockFromPreviousSession($fields);
	}

	$fields['CHAT_ID'] = $this->chat->getData('ID');

	if ($this->chat->isNowCreated())
	{
		$fields['START_ID'] = 0;
		$fields['IS_FIRST'] = 'Y';
		$fields['LAST_SEND_MAIL_ID'] = 0;
	}
	else
	{
		$fields['START_ID'] = $this->chat->getData('LAST_MESSAGE_ID')+1;
		$fields['IS_FIRST'] = 'N';
		$fields['LAST_SEND_MAIL_ID'] = $this->chat->getData('LAST_MESSAGE_ID');

		$this->chat->join($fields['USER_ID']);
	}

	if ($fields['MODE'] == self::MODE_OUTPUT)
	{
		$fields['STATUS'] = self::STATUS_ANSWER;
	}

	$resultAdd = ModelSessionTable::add($fields);
	if ($resultAdd->isSuccess())
	{
		$this->isCreated = true;
		$fields['SESSION_ID'] = $resultAdd->getId();

		$resultAddSessionCheck = ModelSessionCheckTable::add([
			'SESSION_ID' => $fields['SESSION_ID'],
			'DATE_CLOSE' => (new DateTime())->add('180 SECONDS'),
			'DATE_QUEUE' => (new DateTime())->add('180 SECONDS'),
		]);

		if ($resultAddSessionCheck->isSuccess())
		{
			$this->session = $fields;
			$this->session['ID'] = $this->session['SESSION_ID'] = $fields['SESSION_ID'];

			$dateNoAnswer = null;

			$queueManager = Queue::initialization($this);

			$resultQueue = $queueManager->createSession($fields['OPERATOR_ID'], $crmManager, Connector::isEnableGroupByChat($fields['SOURCE']));

			$this->session['JOIN_BOT'] = $resultQueue['JOIN_BOT'];
			$this->session['OPERATOR_ID'] = $fields['OPERATOR_ID'] = $params['OPERATOR_ID'] = $resultQueue['OPERATOR_ID'];
			$fields['DATE_OPERATOR'] = $resultQueue['DATE_OPERATOR'];
			$fields['QUEUE_HISTORY'] = $this->session['QUEUE_HISTORY'] = $resultQueue['QUEUE_HISTORY'];
			$dateNoAnswer = $resultQueue['DATE_NO_ANSWER'];
			$undistributed = $resultQueue['UNDISTRIBUTED'] == true? 'Y' : 'N';
			$dateQueue = $resultQueue['DATE_QUEUE'];
			$this->joinUserList = $resultQueue['OPERATOR_LIST'];
			$fields['OPERATOR_FROM_CRM'] = $resultQueue['OPERATOR_CRM'] == true? 'Y' : 'N';

			//Send message
			if ($fields['PARENT_ID'] > 0)
			{
				$messageId = MessagesSession::sendMessageStartSessionByMessage(
					$fields['CHAT_ID'],
					$fields['SESSION_ID'],
					$fields['PARENT_ID']
				);
			}
			else
			{
				$messageId = MessagesSession::sendMessageStartSession($fields['CHAT_ID'], $fields['SESSION_ID']);
			}
			//END Send message

			if ($this->chat->isNowCreated())
			{
				if (intval($messageId) < 0)
				{
					$messageId = 0;
				}

				$fields['START_ID'] = $messageId;
			}

			$this->chat->updateFieldData([Chat::FIELD_SESSION => [
				'ID' => $fields['SESSION_ID'],
				'DATE_CREATE' => new DateTime()
			]]);

			if ($fields['MODE'] == self::MODE_INPUT)
			{
				/* CLOSED LINE */
				if ($this->config['ACTIVE'] == 'N')
				{
					$this->action = self::ACTION_CLOSED;
					$fields['WORKTIME'] = 'N';
					$fields['WAIT_ACTION'] = 'Y';
				}
				elseif (!(new AutomaticActionWorkTime($this))->isWorkTimeLine())
				{
					$fields['WORKTIME'] = 'N';
					if ($this->session['JOIN_BOT'])
					{
						$this->resetActionAll();
					}
					else
					{
						$fields['WAIT_ACTION'] = 'Y';
					}
				}
			}
			elseif ($fields['MODE'] == self::MODE_OUTPUT)
			{
				if ($this->config['ACTIVE'] == 'N')
				{
					$this->action = self::ACTION_CLOSED;
					$fields['WORKTIME'] = 'N';
					$fields['WAIT_ACTION'] = 'Y';
				}
				if ($fields['OPERATOR_ID'])
				{
					if ($this->chat->getData('AUTHOR_ID') == 0)
					{
						$this->chat->answer($fields['OPERATOR_ID'], true);
						$this->chat->join($fields['OPERATOR_ID']);
					}
				}
				$fields['WAIT_ANSWER'] = 'N';
			}

			$sessionId = $fields['SESSION_ID'];
			unset($fields['SESSION_ID']);
			ModelSessionTable::update($sessionId, $fields);
			$fields['SESSION_ID'] = $sessionId;

			if (
				$fields['MODE'] == self::MODE_INPUT
				&& !empty($this->joinUserList)
				&& $params['DEFERRED_JOIN'] == 'N'
			)
			{
				$this->chat->sendJoinMessage($this->joinUserList, $fields['OPERATOR_FROM_CRM']);
				$this->chat->join($this->joinUserList);
				$this->joinUserList = [];
			}

			$dateClose = new DateTime();

			if ($fields['MODE'] == self::MODE_INPUT)
			{
				$dateClose->add('1 MONTH');
			}
			else
			{
				$dateClose->add($this->config['AUTO_CLOSE_TIME'] . ' SECONDS');
			}

			ModelSessionCheckTable::update($fields['SESSION_ID'], [
				'DATE_CLOSE' => $dateClose,
				'DATE_QUEUE' => $dateQueue,
				'DATE_NO_ANSWER' => $dateNoAnswer,
				'UNDISTRIBUTED' => $undistributed,
			]);

			$sessionManager = ModelSessionTable::getByIdPerformance($fields['SESSION_ID']);
			$this->session = $sessionManager->fetch();
			$this->session['SESSION_ID'] = $this->session['ID'];

			$this->session['CHECK_DATE_CLOSE'] = $dateClose;
			$this->session['CHECK_DATE_QUEUE'] = $dateQueue;

			if (
				!empty($previousSessionBlock['BLOCK_DATE']) &&
				!empty($previousSessionBlock['BLOCK_REASON'])
			)
			{
				ReplyBlock::add($fields['SESSION_ID'], $this->chat, $previousSessionBlock);
			}
			elseif (Loader::includeModule('imconnector'))
			{
				$limit = BitrixImConnectorConnector::getReplyLimit($fields['SOURCE']);
				if ($limit)
				{
					if (!empty($limit['BLOCK_DATE']))
					{
						$limit['BLOCK_DATE'] = (new DateTime())->add($limit['BLOCK_DATE'] . ' SECONDS');

						ReplyBlock::add($fields['SESSION_ID'], $this->chat, $limit);
					}

					MessagesSession::sendMessageTimeLimit($fields['CHAT_ID'], $limit['BLOCK_REASON']);
				}
			}


			/* BLOCK STATISTIC*/
			ConfigStatistic::getInstance((int)$fields['CONFIG_ID'])->addInWork()->addSession();

			/* CRM BLOCK */
			if ($params['SKIP_CRM'] != 'Y')
			{
				if ($fields['MODE'] == self::MODE_INPUT)
				{
					if (
						!Connector::isEnableGroupByChat($fields['SOURCE'])
						&& $this->config['CRM'] == 'Y'
						&& $crmManager->isLoaded()
					)
					{
						$crmManager->getFields()->setTitle($this->chat->getData('TITLE'));

						$crmManager->setDefaultFlags();
						$crmManager->registrationChanges();
						$crmManager->sendCrmImMessages();
					}
					else
					{
						$crmManager->setDefaultFlags();
					}
				}
				elseif ($fields['MODE'] == self::MODE_OUTPUT)
				{
					if ($this->config['CRM'] == 'Y' && $crmManager->isLoaded())
					{
						$crmManager->getFields()->setTitle($this->chat->getData('TITLE'));

						if (
							$params['REOPEN'] === 'Y'
							|| $fields['IS_FIRST'] === 'N'
						)
						{
							$crmManager->setSkipAutomationTriggerFirstMessage();
						}

						$crmManager->registrationChanges();
						$crmManager->sendCrmImMessages();
					}
				}
			}

			/* Event */
			$eventData = [];
			$eventData['SESSION'] = $this->session;
			$eventData['RUNTIME_SESSION'] = $this;
			$eventData['CONFIG'] = $this->config;

			$event = new MainEvent('imopenlines', 'OnSessionStart', $eventData);
			$event->send();
			/* END Event */

			if (Connector::isLiveChat($this->session['SOURCE']))
			{
				$parsedUserCode = SessionCommon::parseUserCode($this->session['USER_CODE']);

				BitrixPullEvent::add($this->session['USER_ID'], [
					'module_id' => 'imopenlines',
					'command' => 'sessionStart',
					'params' => [
						'chatId' => (int)$parsedUserCode['EXTERNAL_CHAT_ID'],
						'sessionId' => (int)$this->session['ID'],
					]
				]);
			}
		}
		else
		{
			$result->addErrors($resultAddSessionCheck->getErrors());
		}

	}
	else
	{
		$result->addErrors($resultAdd->getErrors());
	}

	Debug::addSession($this, 'end ' . __METHOD__, ['SUCCESS' => $result->isSuccess(), 'ERRORS' => $result->getErrorMessages()]);

	return $result;
}