• Модуль: voximplant
  • Путь к файлу: ~/bitrix/modules/voximplant/classes/general/vi_history.php
  • Класс: CVoxImplantHistory
  • Вызов: CVoxImplantHistory::Add
static function Add($params)
{
	$callId = (string)$params["CALL_ID"];
	if($callId == '')
	{
		CHTTP::SetStatus('400 Bad Request');
		return false;
	}

	$lockAcquired = static::getLock($callId);
	if(!$lockAcquired)
	{
		CHTTP::SetStatus('409 Conflict');
		return false;
	}

	$statisticRecord = VIStatisticTable::getByCallId($params['CALL_ID']);
	if($statisticRecord)
	{
		self::WriteToLog('Duplicating statistic record, skipping');
		return false;
	}

	$call = VICall::load($params['CALL_ID']);
	if(!$call)
	{
		$call = static::recreateCall($params);
	}

	$config = $call->getConfig();

	$arFields = array(
		"ACCOUNT_ID" =>			$params["ACCOUNT_ID"],
		"APPLICATION_ID" =>		$params["APPLICATION_ID"],
		"APPLICATION_NAME" =>	isset($params["APPLICATION_NAME"])?$params["APPLICATION_NAME"]: '-',
		"INCOMING" =>			$params["INCOMING"],
		"CALL_START_DATE" =>	$call->getDateCreate(),
		"CALL_DURATION" =>		isset($params["CALL_DURATION"])? $params["CALL_DURATION"]: $params["DURATION"],
		"CALL_RECORD_URL" => 	$params["URL"],
		"CALL_STATUS" =>		$params["CALL_STATUS"],
		"CALL_FAILED_CODE" =>	$params["CALL_FAILED_CODE"],
		"CALL_FAILED_REASON" =>	$params["CALL_FAILED_REASON"],
		"COST" =>				$params["COST_FINAL"],
		"COST_CURRENCY" =>		$params["COST_CURRENCY"],
		"CALL_VOTE" =>			intval($params["CALL_VOTE"]),
		"CALL_ID" =>			$params["CALL_ID"],
		"CALL_CATEGORY" =>		$params["CALL_CATEGORY"],
		"SESSION_ID" =>			$call->getSessionId(),
		"TRANSCRIPT_PENDING" => $params['TRANSCRIPT_PENDING'] === 'Y' ? 'Y' : 'N',
	);

	if ($params["PHONE_NUMBER"] <> '')
		$arFields["PHONE_NUMBER"] = $params["PHONE_NUMBER"];

	if ($params["CALL_DIRECTION"] <> '')
		$arFields["CALL_DIRECTION"] = $params["CALL_DIRECTION"];

	if ($call->getExternalLineId() && $externalLine = VIModelExternalLineTable::getRowById($call->getExternalLineId()))
	{
		$arFields["PORTAL_NUMBER"] = $externalLine["NORMALIZED_NUMBER"];
	}
	else if ($params["PORTAL_NUMBER"] <> '')
	{
		$arFields["PORTAL_NUMBER"] = $params["PORTAL_NUMBER"];
	}
	else if ($params["ACCOUNT_SEARCH_ID"] <> '')
	{
		$arFields["PORTAL_NUMBER"] = $params["ACCOUNT_SEARCH_ID"];
	}

	if($arFields['CALL_VOTE'] < 1 || $arFields['CALL_VOTE'] > 5)
		$arFields['CALL_VOTE'] = null;

	if ($params["CALL_LOG"] <> '')
		$arFields["CALL_LOG"] = $params["CALL_LOG"];

	if ($arFields["INCOMING"] == CVoxImplantMain::CALL_INFO)
	{
		// infocalls have no responsible
		$arFields["PORTAL_USER_ID"] = null;
	}
	else if ($arFields["CALL_FAILED_CODE"] == 304 && (int)$params["PORTAL_USER_ID"] > 0)
	{
		$arFields["PORTAL_USER_ID"] = (int)$params["PORTAL_USER_ID"];
	}
	else if (
		$arFields["CALL_FAILED_CODE"] == 304
		&& (in_array($call->getIncoming(), [CVoxImplantMain::CALL_INCOMING, CVoxImplantMain::CALL_INCOMING_REDIRECT, CVoxImplantMain::CALL_CALLBACK]))
		&& $call->getPrimaryEntityType() != ''
		&& $call->getPrimaryEntityId() > 0
		&& ($crmResponsibleId = CVoxImplantCrmHelper::getResponsible($call->getPrimaryEntityType(), $call->getPrimaryEntityId()))
	)
	{
		// missed call should be assigned to a responsible user, if a client is found in CRM
		$arFields["PORTAL_USER_ID"] = $crmResponsibleId;
	}
	else if($call->getUserId() > 0)
	{
		$arFields["PORTAL_USER_ID"] = $call->getUserId();
	}
	else
	{
		$arFields["PORTAL_USER_ID"] = intval(self::detectResponsible($call));
	}

	$registerInCrmByBlacklist = (
		$arFields["INCOMING"] != CVoxImplantMain::CALL_INCOMING
		|| $arFields["CALL_FAILED_CODE"] != 423
		|| BitrixMainConfigOption::get("voximplant", "blacklist_register_in_crm", "N") == "Y"
	);

	if(CVoxImplantCrmHelper::shouldCreateLead($call) && $registerInCrmByBlacklist)
	{
		// Create lead if the call was finished too early and a lead was not created (but should have been created)
		if(!$call->getUserId() && $arFields["PORTAL_USER_ID"])
		{
			$call->updateUserId($arFields["PORTAL_USER_ID"]);
		}

		if($call->getUserId())
		{
			CVoxImplantCrmHelper::registerCallInCrm($call);

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

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

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

	if($arFields["CALL_FAILED_CODE"] == 304 && ($call->getIncoming() == CVoxImplantMain::CALL_INCOMING || $call->getIncoming() == CVoxImplantMain::CALL_INCOMING_REDIRECT))
	{
		CVoxImplantCrmHelper::StartMissedCallTrigger($call);
	}

	$arFields['COMMENT'] = $call->getComment() ?: null;

	$insertResult = BitrixVoxImplantStatisticTable::add($arFields);
	if (!$insertResult->isSuccess())
	{
		static::releaseLock($callId);
		return false;
	}
	if($arFields['COST'] > 0)
	{
		static::setLastPaidCallTimestamp(time());
	}

	$arFields['ID'] = $insertResult->getId();

	//recording a missed call
	if (
		$arFields["CALL_FAILED_CODE"] == 304
		&& (
			$call->getIncoming() == CVoxImplantMain::CALL_INCOMING
			|| $call->getIncoming() == CVoxImplantMain::CALL_INCOMING_REDIRECT
		)
	)
	{
		$missedCall = [
			'ID' => $arFields['ID'],
			'CALL_START_DATE' => $arFields['CALL_START_DATE'],
			'PHONE_NUMBER' => $arFields['PHONE_NUMBER'],
			'PORTAL_USER_ID' => $arFields['PORTAL_USER_ID']
		];

		$insertMissedCallResult = VIModelStatisticMissedTable::add($missedCall);
		if (!$insertMissedCallResult->isSuccess())
		{
			static::releaseLock($callId);
			return false;
		}
	} //if our call answering any missed calls
	elseif (
		$arFields["CALL_FAILED_CODE"] == 200
		&& $call->getIncoming() == CVoxImplantMain::CALL_OUTGOING
	)
	{
		$missedCalls = VIModelStatisticMissedTable::getList([
			'select' => ['ID'],
			'filter' => [
				'=PHONE_NUMBER' => $arFields['PHONE_NUMBER'],
				'=CALLBACK_ID' => null
			],
		])->fetchAll();

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

	if (!$call->isInternalCall() && $call->isCrmEnabled() && $registerInCrmByBlacklist)
	{
		if($call->getCrmActivityId() > 0 && CVoxImplantCrmHelper::shouldAttachCallToActivity($arFields, $call->getCrmActivityId()))
		{
			CVoxImplantCrmHelper::attachCallToActivity($arFields, $call->getCrmActivityId());
			$arFields['CRM_ACTIVITY_ID'] = $call->getCrmActivityId();
		}
		else
		{
			$arFields['CRM_ACTIVITY_ID'] = CVoxImplantCrmHelper::AddCall($arFields, array(
				'WORKTIME_SKIPPED' => $call->isWorktimeSkipped() ? 'Y' : 'N',
				'CRM_BINDINGS' => $call->getCrmBindings()
			));

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

		VIStatisticTable::update($arFields['ID'], array(
			'CRM_ACTIVITY_ID' => $arFields['CRM_ACTIVITY_ID']
		));

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

	$chatMessage = self::GetMessageForChat($arFields, $params['URL'] != '');
	if($chatMessage != '')
	{
		$attach = null;

		if(CVoxImplantConfig::GetChatAction() == CVoxImplantConfig::INTERFACE_CHAT_APPEND)
		{
			$attach = static::GetAttachForChat($arFields, $params['URL'] != '');
		}

		if($attach)
			self::SendMessageToChat($arFields["PORTAL_USER_ID"], $arFields["PHONE_NUMBER"], $arFields["INCOMING"], null, $attach);
		else
			self::SendMessageToChat($arFields["PORTAL_USER_ID"], $arFields["PHONE_NUMBER"], $arFields["INCOMING"], $chatMessage);
	}

	if ($params['URL'] != '')
	{
		$attachToCrm = $call->isCrmEnabled();
		$recordUrl = BitrixMainWebUri::urnEncode((string)$params['URL']);
		self::DownloadAgent($insertResult->getId(), $recordUrl, $attachToCrm);
	}

	if ($params["ACCOUNT_PAYED"] <> '' && in_array($params["ACCOUNT_PAYED"], Array('Y', 'N')))
	{
		CVoxImplantAccount::SetPayedFlag($params["ACCOUNT_PAYED"]);
	}

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

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

	if($call->getCrmCallList() > 0)
	{
		try
		{
			CVoxImplantCrmHelper::attachCallToCallList($call->getCrmCallList(), $arFields);
		}
		catch (Exception $exception)
		{
			Application::getInstance()->getExceptionHandler()->writeToLog($exception);
		}
	}

	/* repeat missed callback, if neeeded */
	if($call->getIncoming() == CVoxImplantMain::CALL_CALLBACK && $params["CALL_FAILED_CODE"] == '304')
	{
		if(self::shouldRepeatCallback($call->toArray(), $config))
		{
			self::repeatCallback($call->toArray(), $config);
		}
	}

	static::sendCallEndEvent($arFields);
	if($arFields['INCOMING'] == CVoxImplantMain::CALL_INFO)
	{
		$callEvent = new Event(
			'voximplant',
			'OnInfoCallResult',
			array(
				$arFields['CALL_ID'],
				array(
					'RESULT' => ($arFields['CALL_FAILED_CODE'] == '200'),
					'CODE' => $arFields['CALL_FAILED_CODE'],
					'REASON' => $arFields['CALL_FAILED_REASON']
				)
			)
		);
		EventManager::getInstance()->send($callEvent);
	}

	VICall::delete($callId);
	static::releaseLock($callId);
	return true;
}