• Модуль: voximplant
  • Путь к файлу: ~/bitrix/modules/voximplant/lib/rest/helper.php
  • Класс: BitrixVoximplantRestHelper
  • Вызов: Helper::finishExternalCall
static function finishExternalCall(array $fields)
{
	$result = new Result();

	if (!is_string($fields['CALL_ID']))
	{
		$result->addError(new Error('CALL_ID must be a string'));

		return $result;
	}

	$call = Call::load($fields['CALL_ID']);

	/*$call = CallTable::getRow(array(
		'select' => array(
			'*',
			'EXTERNAL_LINE_NUMBER' => 'EXTERNAL_LINE.NUMBER',
			'EXTERNAL_LINE_NAME' => 'EXTERNAL_LINE.NAME'
		),
		'filter' => array(
			'=CALL_ID' => $fields['CALL_ID']
		)
	));*/

	if (!$call)
	{
		$result->addError(new Error('Call is not found (call should be registered prior to finishing'));
		return $result;
	}

	if (isset($fields['USER_ID']))
	{
		$userCheck = BitrixMainUserTable::getRow([
			'select' => ['ID'],
			'filter' => ['=ID' => $fields['USER_ID'], '=ACTIVE' => 'Y', '=IS_REAL_USER' => 'Y']
		]);
		if (!$userCheck)
		{
			$result->addError(new Error('User is not found or is not active'));
			return $result;
		}
	}

	self::hideExternalCall([
		'CALL_ID' => $call->getCallId(),
		'USER_ID' => isset($fields['USER_ID']) ? (int)$fields['USER_ID'] : $call->getUserId()
	]);

	$fields['DURATION'] = (int)$fields['DURATION'];
	$fields['STATUS_CODE'] = $fields['STATUS_CODE'] ?: ($fields['DURATION'] > 0 ? '200' : '304');
	$fields['ADD_TO_CHAT'] = isset($fields['ADD_TO_CHAT']) ? (bool)$fields['ADD_TO_CHAT'] : true;

	$statisticRecord = [
		'CALL_ID' => $call->getCallId(),
		'EXTERNAL_CALL_ID' => $call->getExternalCallId(),
		'PORTAL_USER_ID' => isset($fields['USER_ID']) ? (int)$fields['USER_ID'] : $call->getUserId(),
		'PHONE_NUMBER' => $call->getCallerId(),
		'PORTAL_NUMBER' => $call->getPortalNumber(),
		'INCOMING' => $call->getIncoming(),
		'CALL_DURATION' => $fields['DURATION'] ?: 0,
		'CALL_START_DATE' => $call->getDateCreate(),
		'CALL_STATUS' => $fields['DURATION'] > 0 ? 1 : 0,
		'CALL_VOTE' => $fields['VOTE'],
		'COST' => $fields['COST'],
		'COST_CURRENCY' => $fields['COST_CURRENCY'],
		'CALL_FAILED_CODE' => $fields['STATUS_CODE'],
		'CALL_FAILED_REASON' => $fields['FAILED_REASON'],
		'REST_APP_ID' => $call->getRestAppId(),
		'REST_APP_NAME' => self::getRestAppName($call->getRestAppId()),
		'CRM_ACTIVITY_ID' => (int)$call->getCrmActivityId() ?: null,
		'COMMENT' => $call->getComment(),
	];

	CVoxImplantCrmHelper::updateCrmEntities(
		$call->getCreatedCrmEntities(),
		[
			'ASSIGNED_BY_ID' => $statisticRecord['PORTAL_USER_ID']
		],
		$statisticRecord['PORTAL_USER_ID']
	);

	if ($call->getPrimaryEntityType() != '' && $call->getPrimaryEntityId() > 0)
	{
		$statisticRecord['CRM_ENTITY_TYPE'] = $call->getPrimaryEntityType();
		$statisticRecord['CRM_ENTITY_ID'] = $call->getPrimaryEntityId();

		$viMain = new CVoxImplantMain($statisticRecord["PORTAL_USER_ID"]);
		$dialogData = $viMain->GetDialogInfo($statisticRecord['PHONE_NUMBER'], '', false);
		if (!$dialogData['UNIFIED'])
		{
			CVoxImplantMain::UpdateChatInfo(
				$dialogData['DIALOG_ID'],
				[
					'CRM' => $call->isCrmEnabled() ? 'Y' : 'N',
					'CRM_ENTITY_TYPE' => $call->getPrimaryEntityType(),
					'CRM_ENTITY_ID' => $call->getPrimaryEntityId()
				]
			);
		}
	}

	if (
		$call->getCrmActivityId()
		&& CVoxImplantCrmHelper::shouldAttachCallToActivity($statisticRecord, $call->getCrmActivityId())
	)
	{
		CVoxImplantCrmHelper::attachCallToActivity($statisticRecord, $call->getCrmActivityId());
		$statisticRecord['CRM_ACTIVITY_ID'] = $call->getCrmActivityId();
	}
	else
	{
		$statisticRecord['CRM_ACTIVITY_ID'] = CVoxImplantCrmHelper::AddCall($statisticRecord, array(
			'CRM_BINDINGS' => $call->getCrmBindings()
		));
		if (!$statisticRecord['CRM_ACTIVITY_ID'])
		{
			$activityCreationError = CVoxImplantCrmHelper::$lastError;
		}

		if ($call->getCrmActivityId() && CVoxImplantCrmHelper::shouldCompleteActivity($statisticRecord))
		{
			CVoxImplantCrmHelper::completeActivity($call->getCrmActivityId());
		}
	}

	if (CVoxImplantConfig::GetLeadWorkflowExecution() == CVoxImplantConfig::WORKFLOW_START_DEFERRED)
	{
		CVoxImplantCrmHelper::StartCallTrigger($call);
	}

	if ($statisticRecord["CALL_FAILED_CODE"] == 304 && self::isIncomingCall($call))
	{
		CVoxImplantCrmHelper::StartMissedCallTrigger($call);
	}

	$insertResult = StatisticTable::add($statisticRecord);
	if (!$insertResult->isSuccess())
	{
		$result->addError(new Error('Unexpected database error'));
		$result->addErrors($insertResult->getErrors());
		return $result;
	}
	$statisticRecord['ID'] = $insertResult->getId();

	//recording a missed call
	if (
		$statisticRecord["CALL_FAILED_CODE"] == 304
		&& self::isIncomingCall($call)
	)
	{
		$missedCall = [
			'ID' => $statisticRecord['ID'],
			'CALL_START_DATE' => $statisticRecord['CALL_START_DATE'],
			'PHONE_NUMBER' => $statisticRecord['PHONE_NUMBER'],
			'PORTAL_USER_ID' => $statisticRecord['PORTAL_USER_ID']
		];

		$insertMissedCallResult = StatisticMissedTable::add($missedCall);
		if (!$insertMissedCallResult->isSuccess())
		{
			$result->addError(new Error('Unexpected database error'));
			$result->addErrors($insertMissedCallResult->getErrors());
			return $result;
		}
	} //if our call answering any missed calls
	elseif (
		$statisticRecord["CALL_FAILED_CODE"] == 200
		&& $call->getIncoming() == CVoxImplantMain::CALL_OUTGOING
	)
	{
		$missedCalls = StatisticMissedTable::getList([
			'select' => ['ID'],
			'filter' => [
				'=PHONE_NUMBER' => $statisticRecord['PHONE_NUMBER'],
				'=CALLBACK_ID' => null
			],
		])->fetchAll();

		if ($missedCalls)
		{
			foreach ($missedCalls as $missedCall)
			{
				StatisticMissedTable::update($missedCall['ID'], [
						'CALLBACK_ID' => $statisticRecord['ID'],
						'CALLBACK_CALL_START_DATE' => $statisticRecord['CALL_START_DATE']
					]
				);
			}
		}
	}

	$hasRecord = ($fields['RECORD_URL'] != '');
	if ($hasRecord)
	{
		if (defined('BX_UTF') && !mb_check_encoding($fields['RECORD_URL'], 'UTF-8'))
		{
			$result->addError(new Error('RECORD_URL contains invalid symbols for UTF-8 encoding'));
			return $result;
		}
		$recordUrl = Uri::urnEncode($fields['RECORD_URL']);
		CVoxImplantHistory::DownloadAgent($insertResult->getId(), $recordUrl, $call->isCrmEnabled());
	}

	if ($fields['ADD_TO_CHAT'])
	{
		$chatMessage = CVoxImplantHistory::GetMessageForChat($statisticRecord, $hasRecord);
		if ($chatMessage != '')
		{
			$attach = null;

			if (CVoxImplantConfig::GetChatAction() == CVoxImplantConfig::INTERFACE_CHAT_APPEND)
			{
				$attach = CVoxImplantHistory::GetAttachForChat($statisticRecord, $hasRecord);
			}

			if ($attach)
			{
				CVoxImplantHistory::SendMessageToChat($statisticRecord["PORTAL_USER_ID"], $statisticRecord["PHONE_NUMBER"], $statisticRecord["INCOMING"], null, $attach);
			}
			else
			{
				CVoxImplantHistory::SendMessageToChat($statisticRecord["PORTAL_USER_ID"], $statisticRecord["PHONE_NUMBER"], $statisticRecord["INCOMING"], $chatMessage);
			}
		}
	}

	if (CVoxImplantConfig::GetLeadWorkflowExecution() == CVoxImplantConfig::WORKFLOW_START_DEFERRED)
	{
		$createdCrmEntities = $call->getCreatedCrmEntities();

		foreach ($createdCrmEntities as $entity)
		{
			if ($entity['ENTITY_TYPE'] === 'LEAD')
			{
				CVoxImplantCrmHelper::StartLeadWorkflow($entity['ENTITY_ID']);
			}
		}
	}

	Call::delete($fields['CALL_ID']);

	CVoxImplantHistory::sendCallEndEvent($statisticRecord);
	$resultData = $statisticRecord;
	if (isset($activityCreationError))
	{
		$resultData['ERRORS']['ACTIVITY_CREATION'] = $activityCreationError;
	}

	$result->setData($resultData);
	return $result;
}