CAllCrmActivity::Add

  1. Bitrix24 API (v. 23.675.0)
  2. crm
  3. CAllCrmActivity
  4. Add
  • Модуль: crm
  • Путь к файлу: ~/bitrix/modules/crm/classes/general/crm_activity.php
  • Класс: \CAllCrmActivity
  • Вызов: CAllCrmActivity::Add
static function Add(&$arFields, $checkPerms = true, $regEvent = true, $options = array())
{
	global $DB, $USER_FIELD_MANAGER;
	if(!is_array($options))
	{
		$options = array();
	}

	$isRestoration = isset($options['IS_RESTORATION']) && $options['IS_RESTORATION'];

	// Setup ownership data if need
	if((empty($arFields['OWNER_ID']) || empty($arFields['OWNER_TYPE_ID']))
		&& isset($arFields['BINDINGS'])
		&& is_array($arFields['BINDINGS'])
		&& !empty($arFields['BINDINGS']))
	{
		$arFields['OWNER_ID'] = $arFields['BINDINGS'][0]['OWNER_ID'];
		$arFields['OWNER_TYPE_ID'] = $arFields['BINDINGS'][0]['OWNER_TYPE_ID'];
	}

	if(!isset($arFields['STORAGE_TYPE_ID']))
	{
		$arFields['STORAGE_TYPE_ID'] = StorageType::getDefaultTypeID();
	}

	$params = array();
	if(isset($options['PRESERVE_CREATION_TIME']))
	{
		$params['PRESERVE_CREATION_TIME'] = $options['PRESERVE_CREATION_TIME'];
	}
	if (!self::rebuildFieldsForDataBase('ADD', $arFields, 0, $params))
	{
		return false;
	}

	$storageElementIDs = isset($arFields['STORAGE_ELEMENT_IDS']) ? $arFields['STORAGE_ELEMENT_IDS'] : array();
	$storageElementsSerialized = false;
	if(is_array($storageElementIDs))
	{
		$storageElementIDs = self::NormalizeStorageElementIDs($storageElementIDs);
		$arFields['STORAGE_ELEMENT_IDS'] = serialize($storageElementIDs);
		$storageElementsSerialized = true;
	}

	if(isset($arFields['SETTINGS']) && is_array($arFields['SETTINGS']))
	{
		$arFields['SETTINGS'] = serialize($arFields['SETTINGS']);
	}

	if(isset($arFields['PROVIDER_PARAMS']))
	{
		$arFields['PROVIDER_PARAMS'] = serialize($arFields['PROVIDER_PARAMS']);
	}

	if (isset($arFields['PARENT_ID']) && $arFields['PARENT_ID'] > 0)
	{
		$parent = $DB->query(sprintf(
			'SELECT ID, THREAD_ID FROM %s WHERE ID = %u',
			\CCrmActivity::TABLE_NAME, $arFields['PARENT_ID']
		))->fetch();
	}

	if (!empty($parent))
	{
		$arFields['PARENT_ID'] = $parent['ID'];
		$arFields['THREAD_ID'] = $parent['THREAD_ID'];
	}
	else
	{
		$arFields['PARENT_ID'] = 0;
		$arFields['THREAD_ID'] = 0;
	}

	self::NormalizeDateTimeFields($arFields);

	$beforeEvents = GetModuleEvents('crm', 'OnBeforeCrmActivityAdd');
	while ($arEvent = $beforeEvents->Fetch())
	{
		ExecuteModuleEventEx($arEvent, array(&$arFields));
	}

	$originalSubject = null;
	if (isset($arFields['SUBJECT']))
	{
		$originalSubject = $arFields['SUBJECT'];
		$arFields['SUBJECT'] = \Bitrix\Main\Text\Emoji::encode($arFields['SUBJECT']);
	}
	$originalDescription = null;
	if (isset($arFields['DESCRIPTION']))
	{
		$originalDescription = $arFields['DESCRIPTION'];
		$arFields['DESCRIPTION'] = \Bitrix\Main\Text\Emoji::encode($arFields['DESCRIPTION']);
	}

	self::getInstance()->normalizeEntityFields($arFields);
	$ID = $DB->Add(
		CCrmActivity::TABLE_NAME,
		$arFields,
		['DESCRIPTION', 'STORAGE_ELEMENT_IDS', 'SETTINGS', 'PROVIDER_PARAMS', 'PROVIDER_DATA']
	);
	if(is_string($ID) && $ID !== '')
	{
		//MS SQL RETURNS STRING INSTEAD INT
		$ID = intval($ID);
	}

	if($ID === false)
	{
		self::RegisterError(array('text' => "DB connection was lost."));
		return false;
	}
	if (!is_null($originalSubject))
	{
		$arFields['SUBJECT'] = $originalSubject;
	}
	if (!is_null($originalDescription))
	{
		$arFields['DESCRIPTION'] = $originalDescription;
	}

	if ($arFields['PARENT_ID'] == 0)
	{
		$DB->query(sprintf(
			'UPDATE %s SET THREAD_ID = ID WHERE ID = %u',
			\CCrmActivity::TABLE_NAME, $ID
		));
	}

	$isIncomingChannel = (($arFields['IS_INCOMING_CHANNEL'] ?? null) === 'Y');
	if ($isIncomingChannel)
	{
		\Bitrix\Crm\Activity\IncomingChannel::getInstance()->register($ID, (int)$arFields['RESPONSIBLE_ID'], $arFields['COMPLETED'] === 'Y');
	}

	$arFields['ID'] = $ID;
	$arFields['SETTINGS'] = isset($arFields['SETTINGS']) ? unserialize($arFields['SETTINGS'], ['allowed_classes' => false]) : array();
	$arFields['PROVIDER_PARAMS'] = isset($arFields['PROVIDER_PARAMS']) ? unserialize($arFields['PROVIDER_PARAMS'], ['allowed_classes' => false]) : array();

	CCrmActivity::DoSaveElementIDs($ID, $arFields['STORAGE_TYPE_ID'], $storageElementIDs);

	$arBindings = isset($arFields['BINDINGS']) && is_array($arFields['BINDINGS']) ? $arFields['BINDINGS'] : array();

	$isOwnerInBindings = false;
	$ownerID = intval($arFields['OWNER_ID']);
	$ownerTypeID = intval($arFields['OWNER_TYPE_ID']);
	foreach($arBindings as $arBinding)
	{
		$curOwnerTypeID = isset($arBinding['OWNER_TYPE_ID']) ? intval($arBinding['OWNER_TYPE_ID']) : 0;
		$curOwnerID = isset($arBinding['OWNER_ID']) ? intval($arBinding['OWNER_ID']) : 0;

		if($curOwnerTypeID === $ownerTypeID && $curOwnerID === $ownerID)
		{
			$isOwnerInBindings = true;
			break;
		}
	}

	if(!$isOwnerInBindings)
	{
		$arBindings[] = array(
			'OWNER_TYPE_ID' => $ownerTypeID,
			'OWNER_ID' => $ownerID
		);
		$arFields['BINDINGS'][] = array(
			'OWNER_TYPE_ID' => $ownerTypeID,
			'OWNER_ID' => $ownerID
		);
	}

	self::SaveBindings($ID, $arBindings, false, false, false);
	if(isset($arFields['COMMUNICATIONS']) && is_array($arFields['COMMUNICATIONS']))
	{
		self::SaveCommunications($ID, $arFields['COMMUNICATIONS'], $arFields, false, false);
	}

	$needSynchronizePingQueue = false;
	$arPingOffsets = self::fetchActivityPingOffsets($arFields);
	if (!empty($arPingOffsets))
	{
		PingOffset::getInstance()->register($ID, $arPingOffsets);
		$needSynchronizePingQueue = true;
	}

	$completed = isset($arFields['COMPLETED']) && $arFields['COMPLETED'] === 'Y';
	if($completed && isset($arFields['STATUS']))
	{
		$completed = $arFields['STATUS'] == CCrmActivityStatus::Completed;
	}
	$deadline = isset($arFields['DEADLINE']) ? $arFields['DEADLINE'] : '';
	if($completed && $deadline !== '')
	{
		$deadline = \Bitrix\Main\Type\DateTime::createFromUserTime($deadline);
		$deadline->setTime(0, 0, 0);
		foreach($arBindings as $arBinding)
		{
			$curOwnerTypeID = isset($arBinding['OWNER_TYPE_ID']) ? intval($arBinding['OWNER_TYPE_ID']) : 0;
			$curOwnerID = isset($arBinding['OWNER_ID']) ? intval($arBinding['OWNER_ID']) : 0;
			if($curOwnerID > 0)
			{
				if($curOwnerTypeID === CCrmOwnerType::Deal)
				{
					Bitrix\Crm\Statistics\DealActivityStatisticEntry::register($curOwnerID, null, array('DATE' => $deadline));
				}
				elseif($curOwnerTypeID === CCrmOwnerType::Lead)
				{
					Bitrix\Crm\Statistics\LeadActivityStatisticEntry::register($curOwnerID, null, array('DATE' => $deadline));
				}
			}
		}
		unset($arBinding);
	}

	$lightTimeDate = (new FillActLightCounter())->onActAdd($arFields, $arPingOffsets);
	$arFields['LIGHT_COUNTER_AT'] = $lightTimeDate;

	if (!$completed)
	{
		\Bitrix\Crm\Activity\UncompletedActivity::synchronizeForUncompletedActivityChange(
			\Bitrix\Crm\Activity\UncompletedActivityChange::create(
				$ID,
				[],
				[],
				$arFields,
				$arBindings,
				null,
				$lightTimeDate
			)
		);

		if ($needSynchronizePingQueue)
		{
			PingQueue::getInstance()->register($ID, $completed, $arFields['DEADLINE']);
		}
	}

	\Bitrix\Crm\Activity\CommunicationStatistics::registerActivity($arFields);
	if ($deadline)
		\Bitrix\Crm\Statistics\ActivityStatisticEntry::register($ID, $arFields);

	if(!$isRestoration)
	{
		\Bitrix\Crm\Timeline\ActivityController::getInstance()->onCreate(
			$ID,
			array(
				'FIELDS' => $arFields,
				'PRESERVE_CREATION_TIME' => isset($options['PRESERVE_CREATION_TIME']) && $options['PRESERVE_CREATION_TIME'] === true,
				'CURRENT_USER' => $options['CURRENT_USER'] ?? null,
			)
		);
	}

	//region Search content index
	Bitrix\Crm\Search\SearchContentBuilderFactory::create(CCrmOwnerType::Activity)->build($ID);
	//endregion

	if(!$isRestoration && $regEvent)
	{
		foreach($arBindings as $arBinding)
		{
			self::RegisterAddEvent($arBinding['OWNER_TYPE_ID'], $arBinding['OWNER_ID'], $arFields, false);
		}
		unset($arBinding);
	}

	// Synchronize user activity -->
	$responsibleID = isset($arFields['RESPONSIBLE_ID']) ? intval($arFields['RESPONSIBLE_ID']) : 0;
	if($responsibleID > 0)
	{
		foreach($arBindings as $arBinding)
		{
			self::SynchronizeUserActivity($arBinding['OWNER_TYPE_ID'], $arBinding['OWNER_ID'], $responsibleID);
			self::SynchronizeUserActivity($arBinding['OWNER_TYPE_ID'], $arBinding['OWNER_ID'], 0);
		}
	}
	\Bitrix\Crm\Counter\Monitor::getInstance()->onActivityAdd($arFields, $arBindings, $lightTimeDate);
	// <-- Synchronize user activity

	$provider = self::GetActivityProvider($arFields);
	$providerTypeId = isset($arFields['PROVIDER_TYPE_ID']) ? (string) $arFields['PROVIDER_TYPE_ID'] : null;
	if (
		$provider !== null
		&& $provider::canUseCalendarEvents($providerTypeId)
		&& !$provider::skipCalendarSync($arFields, $options)
	)
	{
		$skipCalendarEvent = isset($options['SKIP_CALENDAR_EVENT']) ? (bool)$options['SKIP_CALENDAR_EVENT'] : null;
		$calendarEventId =  isset($arFields['CALENDAR_EVENT_ID']) ? (int)$arFields['CALENDAR_EVENT_ID'] : 0;
		$completed = isset($arFields['COMPLETED']) && $arFields['COMPLETED'] === 'Y';
		if (
			!$skipCalendarEvent
			&& $calendarEventId <= 0
			&& (!$completed || $provider::canKeepCompletedInCalendar($providerTypeId))
		)
		{
			$eventID = self::SaveCalendarEvent($arFields);
			if(is_int($eventID) && $eventID > 0)
			{
				self::SetCalendarEventId($eventID, $ID);
			}
		}
	}

	if($storageElementsSerialized)
	{
		$arFields['STORAGE_ELEMENT_IDS'] = $storageElementIDs;
	}

	if(is_int($ID) && $ID > 0)
	{
		/*
		 * Messages are linked by the owner of the mailbox
		 */
		if (isset($arFields['TYPE_ID']) && $arFields['TYPE_ID'] == CCrmActivityType::Email)
		{
			$USER_FIELD_MANAGER->update(static::UF_ENTITY_TYPE, $ID, $arFields, $arFields['AUTHOR_ID']);
		}
		else
		{
			$USER_FIELD_MANAGER->update(static::UF_ENTITY_TYPE, $ID, $arFields, $arFields['EDITOR_ID']);
		}

		if ($provider !== null && $provider::canUseLiveFeedEvents($providerTypeId) === false)
			$options['REGISTER_SONET_EVENT'] = false;

		if(isset($options['REGISTER_SONET_EVENT']) && $options['REGISTER_SONET_EVENT'] === true)
		{
			self::RegisterLiveFeedEvent($arFields);
			if ($responsibleID > 0 && Settings\Crm::isLiveFeedRecordsGenerationEnabled())
			{
				CCrmSonetSubscription::RegisterSubscription(
					CCrmOwnerType::Activity,
					$ID,
					CCrmSonetSubscriptionType::Responsibility,
					$responsibleID
				);
			}
		}

		if($provider !== null)
		{
			$provider::onAfterAdd(
				$arFields,
				[
					'IS_RESTORATION' => $isRestoration,
				],
			);
		}


		//Crm\Activity\Provider\ProviderManager::processRestorationFromRecycleBin(
		\Bitrix\Crm\Activity\Provider\ProviderManager::processCreation(
			$arFields,
			array('BINDINGS' => $arBindings, 'IS_RESTORATION' => $isRestoration)
		);

		\Bitrix\Crm\Pseudoactivity\WaitEntry::processActivityCreation(
			$arFields,
			array('BINDINGS' => $arBindings)
		);

		$rsEvents = GetModuleEvents('crm', 'OnActivityAdd');
		while ($arEvent = $rsEvents->Fetch())
		{
			ExecuteModuleEventEx($arEvent, array($ID, &$arFields));
		}

		if($arFields['COMPLETED'] === 'Y')
		{
			Crm\Ml\Scoring::queuePredictionUpdate($arFields['OWNER_TYPE_ID'], $arFields['OWNER_ID'], [
				'EVENT_TYPE' => Crm\Ml\Scoring::EVENT_ACTIVITY,
				'ASSOCIATED_ACTIVITY_ID'=> $ID
			]);
		}
	}

	return $ID;
}

Добавить комментарий