CAllCrmLead::Update

  1. Bitrix24 API (v. 23.675.0)
  2. crm
  3. CAllCrmLead
  4. Update
  • Модуль: crm
  • Путь к файлу: ~/bitrix/modules/crm/classes/general/crm_lead.php
  • Класс: \CAllCrmLead
  • Вызов: CAllCrmLead::Update
public function Update($ID, array &$arFields, $bCompare = true, $bUpdateSearch = true, $options = array())
{
	global $DB;

	$this->LAST_ERROR = '';
	$this->checkExceptions = array();

	$ID = (int) $ID;
	if(!is_array($options))
	{
		$options = array();
	}

	$options['IS_COMPARE_ENABLED'] = $bCompare;

	if ($this->isUseOperation())
	{
		return $this->getCompatibilityAdapter()->performUpdate($ID, $arFields, $options);
	}

	$isSystemAction = isset($options['IS_SYSTEM_ACTION']) && $options['IS_SYSTEM_ACTION'];

	if(isset($options['CURRENT_USER']))
	{
		$iUserId = intval($options['CURRENT_USER']);
	}
	else
	{
		$iUserId = CCrmSecurityHelper::GetCurrentUserID();
	}

	$arRow = $this->getCurrentFields($ID);
	if ($arRow === false)
	{
		return false;
	}

	unset(
		$arFields['DATE_CREATE'],
		$arFields['DATE_MODIFY'],
		$arFields['DATE_CLOSED'],
		$arFields['IS_RETURN_CUSTOMER'],
		$arFields['MOVED_BY_ID'],
		$arFields['MOVED_TIME']
	);

	if(!$isSystemAction)
	{
		$arFields['~DATE_MODIFY'] = $DB->CurrentTimeFunction();
		if(!isset($arFields['MODIFY_BY_ID']) || $arFields['MODIFY_BY_ID'] <= 0)
		{
			$arFields['MODIFY_BY_ID'] = $iUserId;
		}
	}

	if (!empty($arFields['STATUS_ID']) && $arFields['STATUS_ID'] !== $arRow['STATUS_ID'])
	{
		self::EnsureStatusesLoaded();
		if (in_array($arFields['STATUS_ID'], self::$LEAD_STATUSES_BY_GROUP['FINISHED']))
			$arFields['~DATE_CLOSED'] = $DB->CurrentTimeFunction();
	}

	if(isset($arFields['ASSIGNED_BY_ID']) && $arFields['ASSIGNED_BY_ID'] <= 0)
	{
		unset($arFields['ASSIGNED_BY_ID']);
	}

	$companyID = isset($arFields['COMPANY_ID'])
		? (int)$arFields['COMPANY_ID'] : (isset($arRow['COMPANY_ID']) ? (int)$arRow['COMPANY_ID'] : 0);
	$assignedByID = (int)(isset($arFields['ASSIGNED_BY_ID']) ? $arFields['ASSIGNED_BY_ID'] : $arRow['ASSIGNED_BY_ID']);
	$statusID = isset($arFields['STATUS_ID']) ? $arFields['STATUS_ID'] : $arRow['STATUS_ID'];
	$customerType = isset($arRow['IS_RETURN_CUSTOMER']) && $arRow['IS_RETURN_CUSTOMER'] === 'Y'
		? CustomerType::RETURNING : CustomerType::GENERAL;

	$bResult = false;
	$options['CURRENT_FIELDS'] = $arRow;

	if(!$this->CheckFields($arFields, $ID, $options))
	{
		$arFields['RESULT_MESSAGE'] = &$this->LAST_ERROR;
	}
	else
	{
		if($this->bCheckPermission && !CCrmAuthorizationHelper::CheckUpdatePermission(self::$TYPE_NAME, $ID, $this->cPerms))
		{
			$this->LAST_ERROR = GetMessage('CRM_PERMISSION_DENIED');
			$arFields['RESULT_MESSAGE'] = &$this->LAST_ERROR;
			return false;
		}

		if(!isset($arFields['ID']))
		{
			$arFields['ID'] = $ID;
		}

		$enableSystemEvents = !isset($options['ENABLE_SYSTEM_EVENTS']) || $options['ENABLE_SYSTEM_EVENTS'] === true;
		//region Before update event
		if($enableSystemEvents)
		{
			$beforeEvents = GetModuleEvents('crm', 'OnBeforeCrmLeadUpdate');
			while ($arEvent = $beforeEvents->Fetch())
			{
				if(ExecuteModuleEventEx($arEvent, array(&$arFields)) === false)
				{
					if(isset($arFields['RESULT_MESSAGE']))
					{
						$this->LAST_ERROR = $arFields['RESULT_MESSAGE'];
					}
					else
					{
						$this->LAST_ERROR = GetMessage('CRM_LEAD_UPDATE_CANCELED', array('#NAME#' => $arEvent['TO_NAME']));
						$arFields['RESULT_MESSAGE'] = &$this->LAST_ERROR;
					}
					return false;
				}
			}
		}
		//endregion

		$arAttr = array();
		$arAttr['STATUS_ID'] = !empty($arFields['STATUS_ID']) ? $arFields['STATUS_ID'] : $arRow['STATUS_ID'];

		$originalObserverIDs = Crm\Observer\ObserverManager::getEntityObserverIDs(CCrmOwnerType::Lead, $ID);
		$observerIDs = isset($arFields['OBSERVER_IDS']) && is_array($arFields['OBSERVER_IDS'])
			? $arFields['OBSERVER_IDS'] : null;
		if($observerIDs !== null && count($observerIDs) > 0)
		{
			$arAttr['CONCERNED_USER_IDS'] = $observerIDs;
		}
		elseif($observerIDs === null && count($originalObserverIDs) > 0)
		{
			$arAttr['CONCERNED_USER_IDS'] = $originalObserverIDs;
		}

		//region Semantic ID depends on Status ID and can't be assigned directly
		$syncStatusSemantics = isset($options['SYNCHRONIZE_STATUS_SEMANTICS']) && $options['SYNCHRONIZE_STATUS_SEMANTICS'];
		if(isset($arFields['STATUS_ID']) && ($syncStatusSemantics || $arFields['STATUS_ID'] !== $arRow['STATUS_ID']))
		{
			$arFields['STATUS_SEMANTIC_ID'] = self::IsStatusExists($arFields['STATUS_ID'])
				? self::GetSemanticID($arFields['STATUS_ID'])
				: Bitrix\Crm\PhaseSemantics::UNDEFINED;

			if ($arFields['STATUS_ID'] !== $arRow['STATUS_ID'])
			{
				$arFields['MOVED_BY_ID'] = $iUserId;
				$arFields['MOVED_TIME'] = (new \Bitrix\Main\Type\DateTime())->toString();
			}
		}
		else
		{
			unset($arFields['STATUS_SEMANTIC_ID']);
		}
		//endregion

		$arAttr['OPENED'] = !empty($arFields['OPENED']) ? $arFields['OPENED'] : $arRow['OPENED'];
		$arEntityAttr = self::BuildEntityAttr($assignedByID, $arAttr);
		if($this->bCheckPermission)
		{
			$sEntityPerm = $this->cPerms->GetPermType(self::$TYPE_NAME, 'WRITE', $arEntityAttr);
			//HACK: Ensure that entity accessible for user restricted by BX_CRM_PERM_OPEN
			$this->PrepareEntityAttrs($arEntityAttr, $sEntityPerm);
			//HACK: Prevent 'OPENED' field change by user restricted by BX_CRM_PERM_OPEN permission
			if($sEntityPerm === BX_CRM_PERM_OPEN && isset($arFields['OPENED']) && $arFields['OPENED'] !== 'Y' && $assignedByID !== $iUserId)
			{
				$arFields['OPENED'] = 'Y';
			}
		}

		if (isset($arFields['ASSIGNED_BY_ID']) && $arRow['ASSIGNED_BY_ID'] != $arFields['ASSIGNED_BY_ID'])
		{
			CCrmEvent::SetAssignedByElement($arFields['ASSIGNED_BY_ID'], 'LEAD', $ID);
		}

		//region Preparation of contacts
		$originalContactBindings = LeadContactTable::getLeadBindings($ID);
		$originalContactIDs = EntityBinding::prepareEntityIDs(CCrmOwnerType::Contact, $originalContactBindings);
		$contactBindings = isset($arFields['CONTACT_BINDINGS']) && is_array($arFields['CONTACT_BINDINGS'])
			? $arFields['CONTACT_BINDINGS'] : null;
		$contactIDs = isset($arFields['CONTACT_IDS']) && is_array($arFields['CONTACT_IDS'])
			? $arFields['CONTACT_IDS'] : null;
		unset($arFields['CONTACT_IDS']);
		//region Backward compatibility
		$contactID = isset($arFields['CONTACT_ID']) ? max((int)$arFields['CONTACT_ID'], 0) : null;
		if($contactBindings === null &&
			$contactIDs === null &&
			$contactID !== null &&
			!in_array($contactID, $originalContactIDs, true))
		{
			//Compatibility mode. Trying to simulate single binding mode if contact is not found in bindings.
			$contactIDs = array();
			if($contactID > 0)
			{
				$contactIDs[] = $contactID;
			}
		}
		unset($arFields['CONTACT_ID']);
		//endregion

		$addedContactIDs = null;
		$removedContactIDs = null;

		$addedContactBindings = null;
		$removedContactBindings = null;

		if(is_array($contactIDs) && !is_array($contactBindings))
		{
			$contactBindings = EntityBinding::prepareEntityBindings(
				\CCrmOwnerType::Contact,
				$contactIDs
			);

			EntityBinding::markFirstAsPrimary($contactBindings);
		}
		elseif(is_array($contactBindings))
		{
			if(EntityBinding::findPrimaryBinding($contactBindings) === null)
			{
				EntityBinding::markFirstAsPrimary($contactBindings);
			}

			$contactIDs = EntityBinding::prepareEntityIDs(
				CCrmOwnerType::Contact,
				$contactBindings
			);
		}

		if(is_array($contactBindings))
		{
			$removedContactBindings = array();
			$addedContactBindings = array();

			EntityBinding::prepareBindingChanges(
				CCrmOwnerType::Contact,
				$originalContactBindings,
				$contactBindings,
				$addedContactBindings,
				$removedContactBindings
			);

			$addedContactIDs = EntityBinding::prepareEntityIDs(
				CCrmOwnerType::Contact,
				$addedContactBindings
			);

			$removedContactIDs = EntityBinding::prepareEntityIDs(
				CCrmOwnerType::Contact,
				$removedContactBindings
			);
		}
		//endregion

		//region Synchronize CustomerType
		if(self::GetSemanticID($statusID) !== Bitrix\Crm\PhaseSemantics::SUCCESS &&
			!Bitrix\Crm\History\LeadStatusHistoryEntry::checkStatus($ID, 'CONVERTED')
		)
		{
			$effectiveCustomerType = CustomerType::GENERAL;
			if($companyID > 0)
			{
				$effectiveCustomerType = CustomerType::RETURNING;
			}
			elseif((is_array($contactIDs) && !empty($contactIDs))
				|| !is_array($contactIDs) && !empty($originalContactIDs)
			)
			{
				$effectiveCustomerType = CustomerType::RETURNING;
			}

			if($customerType !== $effectiveCustomerType)
			{
				$arFields['IS_RETURN_CUSTOMER'] = $effectiveCustomerType === CustomerType::RETURNING ? 'Y' : 'N';
			}
		}
		//endregion

		//region Observers
		$addedObserverIDs = null;
		$removedObserverIDs = null;
		if(is_array($observerIDs))
		{
			$addedObserverIDs = array_diff($observerIDs, $originalObserverIDs);
			$removedObserverIDs = array_diff($originalObserverIDs, $observerIDs);
		}
		//endregion

		self::getLastActivityAdapter()->performUpdate((int)$ID, $arFields, $options);
		self::getCommentsAdapter()
			->setPreviousFields((int)$ID, $arRow)
			->normalizeFields((int)$ID, $arFields)
		;

		//
		$sonetEventData = array();
		if ($bCompare)
		{
			$res = CCrmFieldMulti::GetList(
				array('ID' => 'asc'),
				array('ENTITY_ID' => 'LEAD', 'ELEMENT_ID' => $ID)
			);
			$arRow['FM'] = array();
			while($ar = $res->Fetch())
				$arRow['FM'][$ar['TYPE_ID']][$ar['ID']] = array('VALUE' => $ar['VALUE'], 'VALUE_TYPE' => $ar['VALUE_TYPE']);

			$compareOptions = array();
			if(!empty($addedContactIDs) || !empty($removedContactIDs))
			{
				$compareOptions['CONTACTS'] = array('ADDED' => $addedContactIDs, 'REMOVED' => $removedContactIDs);
			}

			$arEvents = self::CompareFields($arRow, $arFields, $this->bCheckPermission, array_merge($compareOptions, $options));
			foreach($arEvents as $arEvent)
			{
				$arEvent['ENTITY_TYPE'] = 'LEAD';
				$arEvent['ENTITY_ID'] = $ID;
				$arEvent['EVENT_TYPE'] = 1;

				if(!isset($arEvent['USER_ID']))
				{
					if($iUserId > 0)
					{
						$arEvent['USER_ID'] = $iUserId;
					}
					else if(isset($arFields['MODIFY_BY_ID']) && $arFields['MODIFY_BY_ID'] > 0)
					{
						$arEvent['USER_ID'] = $arFields['MODIFY_BY_ID'];
					}
					else if(isset($options['CURRENT_USER']))
					{
						$arEvent['USER_ID'] = (int)$options['CURRENT_USER'];
					}
				}

				if (($arEvent['ENTITY_FIELD'] ?? null) !== 'CONTACT_ID' && ($arEvent['ENTITY_FIELD'] ?? null) !== 'COMPANY_ID')
				{
					$CCrmEvent = new CCrmEvent();
					$eventID = $CCrmEvent->Add($arEvent, $this->bCheckPermission);
				}

				$fieldID = isset($arEvent['ENTITY_FIELD']) ? $arEvent['ENTITY_FIELD'] : '';
				if($fieldID === '')
				{
					continue;
				}

				switch($fieldID)
				{
					case 'STATUS_ID':
						{
							$sonetEventData[] = array(
								'TYPE' => CCrmLiveFeedEvent::Progress,
								'FIELDS' => array(
									//'EVENT_ID' => $eventID,
									'TITLE' => GetMessage('CRM_LEAD_EVENT_UPDATE_STATUS'),
									'MESSAGE' => '',
									'PARAMS' => array(
										'START_STATUS_ID' => $arRow['STATUS_ID'],
										'FINAL_STATUS_ID' => $arFields['STATUS_ID']
									)
								)
							);
						}
						break;
					case 'ASSIGNED_BY_ID':
						{
							$sonetEventData[] = array(
								'TYPE' => CCrmLiveFeedEvent::Responsible,
								'FIELDS' => array(
									//'EVENT_ID' => $eventID,
									'TITLE' => GetMessage('CRM_LEAD_EVENT_UPDATE_ASSIGNED_BY'),
									'MESSAGE' => '',
									'PARAMS' => array(
										'START_RESPONSIBLE_ID' => $arRow['ASSIGNED_BY_ID'],
										'FINAL_RESPONSIBLE_ID' => $arFields['ASSIGNED_BY_ID']
									)
								)
							);
						}
						break;
					case 'TITLE':
						{
							$sonetEventData[] = array(
								'TYPE' => CCrmLiveFeedEvent::Denomination,
								'FIELDS' => array(
									//'EVENT_ID' => $eventID,
									'TITLE' => GetMessage('CRM_LEAD_EVENT_UPDATE_TITLE'),
									'MESSAGE' => '',
									'PARAMS' => array(
										'START_TITLE' => $arRow['TITLE'],
										'FINAL_TITLE' => $arFields['TITLE']
									)
								)
							);
						}
						break;
				}
			}
		}

		if((isset($arFields['NAME']) && $arFields['NAME'] !== $arRow['NAME'])
			|| (isset($arFields['SECOND_NAME']) && $arFields['SECOND_NAME'] !== $arRow['SECOND_NAME'])
			|| (isset($arFields['LAST_NAME']) && $arFields['LAST_NAME'] !== $arRow['LAST_NAME'])
			|| (isset($arFields['HONORIFIC']) && $arFields['HONORIFIC'] !== $arRow['HONORIFIC'])
			|| (isset($arFields['TITLE']) && $arFields['TITLE'] !== $arRow['TITLE'])
		)
		{
			CCrmActivity::ResetEntityCommunicationSettings(CCrmOwnerType::Lead, $ID);
		}

		if (isset($arFields['BIRTHDAY_SORT']))
		{
			unset($arFields['BIRTHDAY_SORT']);
		}

		if(isset($arFields['BIRTHDATE']))
		{
			if($arFields['BIRTHDATE'] !== '')
			{
				$birthDate = $arFields['BIRTHDATE'];
				$arFields['~BIRTHDATE'] = $DB->CharToDateFunction($birthDate, 'SHORT', false);
				$arFields['BIRTHDAY_SORT'] = \Bitrix\Crm\BirthdayReminder::prepareSorting($birthDate);
				unset($arFields['BIRTHDATE']);
			}
			else
			{
				$arFields['BIRTHDAY_SORT'] = \Bitrix\Crm\BirthdayReminder::prepareSorting('');
			}
		}

		$arFields = array_merge($arFields, \CCrmAccountingHelper::calculateAccountingData($arFields, $arRow));

		if (isset($arFields['NAME']) && isset($arFields['LAST_NAME']))
		{
			$arFields['FULL_NAME'] = trim($arFields['NAME'] . ' ' . $arFields['LAST_NAME']);
		}
		else
		{
			$dbRes = $DB->Query("SELECT NAME, LAST_NAME FROM b_crm_lead WHERE ID = {$ID}", false, 'FILE: '.__FILE__.'
LINE: '.__LINE__); $arRes = $dbRes->Fetch(); $arFields['FULL_NAME'] = trim((isset($arFields['NAME'])? $arFields['NAME']: $arRes['NAME']).' '.(isset($arFields['LAST_NAME'])? $arFields['LAST_NAME']: $arRes['LAST_NAME'])); } if(isset($arFields['HAS_EMAIL'])) { unset($arFields['HAS_EMAIL']); } if(isset($arFields['HAS_PHONE'])) { unset($arFields['HAS_PHONE']); } if(isset($arFields['HAS_IMOL'])) { unset($arFields['HAS_IMOL']); } unset($arFields['ID']); $this->normalizeEntityFields($arFields); $sUpdate = $DB->PrepareUpdate(self::TABLE_NAME, $arFields); if ($sUpdate <> '') { $DB->Query("UPDATE b_crm_lead SET {$sUpdate} WHERE ID = {$ID}", false, 'FILE: '.__FILE__.'
LINE: '.__LINE__); $bResult = true; } if(defined("BX_COMP_MANAGED_CACHE")) { static $arNameFields = array("TITLE"); $bClear = false; foreach($arNameFields as $val) { if(isset($arFields[$val])) { $bClear = true; break; } } if ($bClear) { $GLOBALS["CACHE_MANAGER"]->ClearByTag("crm_entity_name_".CCrmOwnerType::Lead."_".$ID); } } //region User Field CCrmEntityHelper::NormalizeUserFields($arFields, self::$sUFEntityID, $GLOBALS['USER_FIELD_MANAGER'], array('IS_NEW' => false)); $GLOBALS['USER_FIELD_MANAGER']->Update(self::$sUFEntityID, $ID, $arFields); //endregion //region Ensure entity has not been deleted yet by concurrent process $currentDbResult = \CCrmLead::GetListEx( array(), array('=ID' => $ID, 'CHECK_PERMISSIONS' => 'N'), false, false, array('*', 'UF_*') ); $currentFields = $currentDbResult->Fetch(); if(!is_array($currentFields)) { return false; } //endregion //region Save contacts if(!empty($removedContactBindings)) { LeadContactTable::unbindContacts($ID, $removedContactBindings); } if(!empty($addedContactBindings)) { LeadContactTable::bindContacts($ID, $addedContactBindings); } //endregion //region Save Observers if(!empty($addedObserverIDs)) { Crm\Observer\ObserverManager::registerBulk( $addedObserverIDs, \CCrmOwnerType::Lead, $ID, count($originalObserverIDs) ); } if(!empty($removedObserverIDs)) { Crm\Observer\ObserverManager::unregisterBulk( $removedObserverIDs, \CCrmOwnerType::Lead, $ID ); } //endregion //region Save access rights for owner and observers $securityRegisterOptions = (new \Bitrix\Crm\Security\Controller\RegisterOptions()) ->setEntityAttributes($arEntityAttr) ; Crm\Security\Manager::getEntityController(CCrmOwnerType::Lead) ->register(self::$TYPE_NAME, $ID, $securityRegisterOptions) ; //endregion //region Address if(isset($arFields['ADDRESS_DELETE']) && ($arFields['ADDRESS_DELETE'] === 'Y')) { \Bitrix\Crm\EntityAddress::unregister( CCrmOwnerType::Lead, $ID, EntityAddressType::Primary); } elseif(isset($arFields['ADDRESS']) || isset($arFields['ADDRESS_2']) || isset($arFields['ADDRESS_CITY']) || isset($arFields['ADDRESS_POSTAL_CODE']) || isset($arFields['ADDRESS_REGION']) || isset($arFields['ADDRESS_PROVINCE']) || isset($arFields['ADDRESS_COUNTRY']) || isset($arFields['ADDRESS_LOC_ADDR_ID']) || isset($arFields['ADDRESS_LOC_ADDR'])) { \Bitrix\Crm\EntityAddress::register( CCrmOwnerType::Lead, $ID, EntityAddressType::Primary, array( 'ADDRESS_1' => isset($arFields['ADDRESS']) ? $arFields['ADDRESS'] : (isset($arRow['ADDRESS']) ? $arRow['ADDRESS'] : null), 'ADDRESS_2' => isset($arFields['ADDRESS_2']) ? $arFields['ADDRESS_2'] : (isset($arRow['ADDRESS_2']) ? $arRow['ADDRESS_2'] : null), 'CITY' => isset($arFields['ADDRESS_CITY']) ? $arFields['ADDRESS_CITY'] : (isset($arRow['ADDRESS_CITY']) ? $arRow['ADDRESS_CITY'] : null), 'POSTAL_CODE' => isset($arFields['ADDRESS_POSTAL_CODE']) ? $arFields['ADDRESS_POSTAL_CODE'] : (isset($arRow['ADDRESS_POSTAL_CODE']) ? $arRow['ADDRESS_POSTAL_CODE'] : null), 'REGION' => isset($arFields['ADDRESS_REGION']) ? $arFields['ADDRESS_REGION'] : (isset($arRow['ADDRESS_REGION']) ? $arRow['ADDRESS_REGION'] : null), 'PROVINCE' => isset($arFields['ADDRESS_PROVINCE']) ? $arFields['ADDRESS_PROVINCE'] : (isset($arRow['ADDRESS_PROVINCE']) ? $arRow['ADDRESS_PROVINCE'] : null), 'COUNTRY' => isset($arFields['ADDRESS_COUNTRY']) ? $arFields['ADDRESS_COUNTRY'] : (isset($arRow['ADDRESS_COUNTRY']) ? $arRow['ADDRESS_COUNTRY'] : null), 'COUNTRY_CODE' => isset($arFields['ADDRESS_COUNTRY_CODE']) ? $arFields['ADDRESS_COUNTRY_CODE'] : (isset($arRow['ADDRESS_COUNTRY_CODE']) ? $arRow['ADDRESS_COUNTRY_CODE'] : null), 'LOC_ADDR_ID' => isset($arFields['ADDRESS_LOC_ADDR_ID']) ? (int)$arFields['ADDRESS_LOC_ADDR_ID'] : (isset($arRow['ADDRESS_LOC_ADDR_ID']) ? (int)$arRow['ADDRESS_LOC_ADDR_ID'] : 0), 'LOC_ADDR' => isset($arFields['ADDRESS_LOC_ADDR']) ? $arFields['ADDRESS_LOC_ADDR'] : null ), ); } //endregion //region Enrich associated company and primary contact of returning customer if(isset($arFields['IS_RETURN_CUSTOMER']) && $arFields['IS_RETURN_CUSTOMER'] === 'Y') { if($companyID > 0) { $merger = new \Bitrix\Crm\Merger\CompanyMerger(0,false); try { $merger->enrich( new \Bitrix\Crm\Merger\LeadMerger(0,false), $ID, $companyID ); } catch (\Bitrix\Crm\Merger\EntityMergerException $e) { } } if(!empty($contactIDs) && $contactIDs[0] > 0) { $merger = new \Bitrix\Crm\Merger\ContactMerger(0,false); try { $merger->enrich( new \Bitrix\Crm\Merger\LeadMerger(0,false), $ID, $contactIDs[0] ); } catch (\Bitrix\Crm\Merger\EntityMergerException $e) { } } } //endregion //region Complete activities if entity is closed if($arRow['STATUS_SEMANTIC_ID'] !== $currentFields['STATUS_SEMANTIC_ID'] && $currentFields['STATUS_SEMANTIC_ID'] !== Bitrix\Crm\PhaseSemantics::PROCESS && (!isset($options['ENABLE_ACTIVITY_COMPLETION']) || $options['ENABLE_ACTIVITY_COMPLETION'] === true) ) { $providerIDs = array(); $completionConfig = \Bitrix\Crm\Settings\LeadSettings::getCurrent()->getActivityCompletionConfig(); foreach(\Bitrix\Crm\Activity\Provider\ProviderManager::getCompletableProviderList() as $providerInfo) { $providerID = $providerInfo['ID']; if(!isset($completionConfig[$providerID]) || $completionConfig[$providerID]) { $providerIDs[] = $providerID; } } $providerQty = count($providerIDs); if($providerQty > 0) { $activityUserID = $iUserId; if($activityUserID <= 0 && isset($arFields['MODIFY_BY_ID'])) { $activityUserID = $arFields['MODIFY_BY_ID']; } \CCrmActivity::SetAutoCompletedByOwner( CCrmOwnerType::Lead, $ID, $providerQty < count($completionConfig) ? $providerIDs : array(), array('CURRENT_USER' => $activityUserID) ); } } //endregion //region Statistics & History Bitrix\Crm\Statistics\LeadSumStatisticEntry::register($ID, $currentFields); Bitrix\Crm\History\LeadStatusHistoryEntry::synchronize($ID, $currentFields); LeadChannelBinding::synchronize($ID, $currentFields); if(isset($arFields['STATUS_ID'])) { $currentSemanticID = self::GetSemanticID($arFields['STATUS_ID']); $previousSemanticID = self::GetSemanticID($arRow['STATUS_ID']); if($currentSemanticID !== Bitrix\Crm\PhaseSemantics::SUCCESS && $previousSemanticID === Bitrix\Crm\PhaseSemantics::SUCCESS ) { $converter = new Bitrix\Crm\Conversion\LeadConverter( new Bitrix\Crm\Conversion\LeadConversionConfig() ); $converter->setEntityID($ID); $converter->unbindChildEntities(); } Bitrix\Crm\History\LeadStatusHistoryEntry::register($ID, $currentFields, array('IS_NEW' => false)); if(($arFields['STATUS_ID'] === 'CONVERTED' && $arRow['STATUS_ID'] !== 'CONVERTED') || ($arFields['STATUS_ID'] !== 'CONVERTED' && $arRow['STATUS_ID'] === 'CONVERTED')) { Bitrix\Crm\Statistics\LeadConversionStatisticsEntry::register($ID, $currentFields, array('IS_NEW' => false)); } } //endregion if (isset($arFields['FM']) && is_array($arFields['FM'])) { $CCrmFieldMulti = new CCrmFieldMulti(); $CCrmFieldMulti->SetFields(CCrmOwnerType::LeadName, $ID, $arFields['FM']); $multifields = DuplicateCommunicationCriterion::prepareEntityMultifieldValues( CCrmOwnerType::Lead, $ID ); $hasEmail = CCrmFieldMulti::HasValues($multifields, CCrmFieldMulti::EMAIL) ? 'Y' : 'N'; $hasPhone = CCrmFieldMulti::HasValues($multifields, CCrmFieldMulti::PHONE) ? 'Y' : 'N'; $hasImol = CCrmFieldMulti::HasImolValues($multifields) ? 'Y' : 'N'; if( $hasEmail !== (isset($arRow['HAS_EMAIL']) ? $arRow['HAS_EMAIL'] : 'N') || $hasPhone !== (isset($arRow['HAS_PHONE']) ? $arRow['HAS_PHONE'] : 'N') || $hasImol !== (isset($arRow['HAS_IMOL']) ? $arRow['HAS_IMOL'] : 'N') ) { $DB->Query("UPDATE b_crm_lead SET HAS_EMAIL = '{$hasEmail}', HAS_PHONE = '{$hasPhone}', HAS_IMOL = '{$hasImol}' WHERE ID = {$ID}", false, 'FILE: '.__FILE__.'
LINE: '.__LINE__); $arFields['HAS_EMAIL'] = $hasEmail; $arFields['HAS_PHONE'] = $hasPhone; $arFields['HAS_IMOL'] = $hasImol; } } $duplicateCriterionRegistrar = DuplicateManager::getCriterionRegistrar(\CCrmOwnerType::Lead); $data = (new Crm\Integrity\CriterionRegistrar\Data()) ->setEntityTypeId(\CCrmOwnerType::Lead) ->setEntityId($ID) ->setCurrentFields($arFields) ->setPreviousFields($arRow) ; $duplicateCriterionRegistrar->update($data); $enableDupIndexInvalidation = (bool)($arOptions['ENABLE_DUP_INDEX_INVALIDATION'] ?? true); if(!$isSystemAction && $enableDupIndexInvalidation) { DuplicateManager::markDuplicateIndexAsDirty(CCrmOwnerType::Lead, $ID); } if($bResult && (isset($arFields['ASSIGNED_BY_ID']) || isset($arFields['STATUS_ID']))) { $previousAssignedByID = isset($arRow['ASSIGNED_BY_ID']) ? (int)$arRow['ASSIGNED_BY_ID'] : 0; if ($assignedByID !== $previousAssignedByID && $enableDupIndexInvalidation) { DuplicateManager::onChangeEntityAssignedBy(CCrmOwnerType::Lead, $ID); } } if ($bResult) { \Bitrix\Crm\Counter\Monitor::getInstance()->onEntityUpdate(CCrmOwnerType::Lead, $arRow, $currentFields); } self::getCommentsAdapter() ->setPreviousFields((int)$ID, $arRow) ->performUpdate((int)$ID, $arFields, $options) ; // update utm fields UtmTable::updateEntityUtmFromFields(CCrmOwnerType::Lead, $ID, $arFields); //region Search if($bUpdateSearch) { CCrmSearch::UpdateSearch(array('ID' => $ID, 'CHECK_PERMISSIONS' => 'N'), 'LEAD', true); } //endregion //region Search content index Bitrix\Crm\Search\SearchContentBuilderFactory::create(CCrmOwnerType::Lead) ->build($ID, ['checkExist' => true]); //endregion //region save parent relations Crm\Service\Container::getInstance()->getParentFieldManager()->saveParentRelationsForIdentifier( new Crm\ItemIdentifier(\CCrmOwnerType::Lead, $ID), $arFields ); //endregion Bitrix\Crm\Timeline\LeadController::getInstance()->onModify( $ID, array('CURRENT_FIELDS' => $arFields, 'PREVIOUS_FIELDS' => $arRow) ); CCrmEntityHelper::registerAdditionalTimelineEvents([ 'entityTypeId' => \CCrmOwnerType::Lead, 'entityId' => $ID, 'fieldsInfo' => static::GetFieldsInfo(), 'previousFields' => $arRow, 'currentFields' => $arFields, 'previousStageSemantics' => $arRow['STATUS_SEMANTIC_ID'] ?? Crm\PhaseSemantics::UNDEFINED, 'currentStageSemantics' => $arFields['STATUS_SEMANTIC_ID'] ?? Crm\PhaseSemantics::UNDEFINED, 'options' => $options, 'bindings' => [ 'entityTypeId' => \CCrmOwnerType::Contact, 'previous' => $originalContactBindings, 'current' => $contactBindings, ], 'isMarkEventRegistrationEnabled' => false, ]); Bitrix\Crm\Integration\Im\Chat::onEntityModification( CCrmOwnerType::Lead, $ID, array( 'CURRENT_FIELDS' => $arFields, 'PREVIOUS_FIELDS' => $arRow, 'ADDED_OBSERVER_IDS' => $addedObserverIDs, 'REMOVED_OBSERVER_IDS' => $removedObserverIDs ) ); $arFields['ID'] = $ID; //region Social network $registerSonetEvent = isset($options['REGISTER_SONET_EVENT']) && $options['REGISTER_SONET_EVENT'] === true; if ( $bResult && isset($arFields['ASSIGNED_BY_ID']) && Crm\Settings\Crm::isLiveFeedRecordsGenerationEnabled() ) { CCrmSonetSubscription::ReplaceSubscriptionByEntity( CCrmOwnerType::Lead, $ID, CCrmSonetSubscriptionType::Responsibility, $arFields['ASSIGNED_BY_ID'], $arRow['ASSIGNED_BY_ID'], $registerSonetEvent ); } if($bResult && $bCompare && $registerSonetEvent && !empty($sonetEventData)) { $modifiedByID = intval($arFields['MODIFY_BY_ID']); foreach($sonetEventData as &$sonetEvent) { $sonetEventFields = &$sonetEvent['FIELDS']; $sonetEventFields['ENTITY_TYPE_ID'] = CCrmOwnerType::Lead; $sonetEventFields['ENTITY_ID'] = $ID; $sonetEventFields['USER_ID'] = $modifiedByID; $logEventID = CCrmLiveFeed::CreateLogEvent($sonetEventFields, $sonetEvent['TYPE'], ['CURRENT_USER' => $iUserId]); if ( $logEventID !== false && CModule::IncludeModule("im") && \Bitrix\Crm\Settings\LeadSettings::isEnabled() ) { $title = CCrmOwnerType::GetCaption(CCrmOwnerType::Lead, $ID, false); $url = CCrmOwnerType::GetEntityShowPath(CCrmOwnerType::Lead, $ID); $serverName = (CMain::IsHTTPS() ? "https" : "http")."://".((defined("SITE_SERVER_NAME") && SITE_SERVER_NAME <> '') ? SITE_SERVER_NAME : COption::GetOptionString("main", "server_name", "")); if ( $sonetEventFields['PARAMS']['FINAL_RESPONSIBLE_ID'] != $modifiedByID && $sonetEvent['TYPE'] == CCrmLiveFeedEvent::Responsible ) { $arMessageFields = array( "MESSAGE_TYPE" => IM_MESSAGE_SYSTEM, "TO_USER_ID" => $sonetEventFields['PARAMS']['FINAL_RESPONSIBLE_ID'], "FROM_USER_ID" => $modifiedByID, "NOTIFY_TYPE" => IM_NOTIFY_FROM, "NOTIFY_MODULE" => "crm", "LOG_ID" => $logEventID, //"NOTIFY_EVENT" => "lead_update", "NOTIFY_EVENT" => "changeAssignedBy", "NOTIFY_TAG" => "CRM|LEAD_RESPONSIBLE|".$ID, "NOTIFY_MESSAGE" => GetMessage("CRM_LEAD_RESPONSIBLE_IM_NOTIFY", Array("#title#" => "".htmlspecialcharsbx($title)."")), "NOTIFY_MESSAGE_OUT" => GetMessage("CRM_LEAD_RESPONSIBLE_IM_NOTIFY", Array("#title#" => htmlspecialcharsbx($title)))." (".$serverName.$url.")" ); CIMNotify::Add($arMessageFields); } if ( $sonetEvent['TYPE'] == CCrmLiveFeedEvent::Responsible && $sonetEventFields['PARAMS']['START_RESPONSIBLE_ID'] != $modifiedByID ) { $arMessageFields = array( "MESSAGE_TYPE" => IM_MESSAGE_SYSTEM, "TO_USER_ID" => $sonetEventFields['PARAMS']['START_RESPONSIBLE_ID'], "FROM_USER_ID" => $modifiedByID, "NOTIFY_TYPE" => IM_NOTIFY_FROM, "NOTIFY_MODULE" => "crm", "LOG_ID" => $logEventID, //"NOTIFY_EVENT" => "lead_update", "NOTIFY_EVENT" => "changeAssignedBy", "NOTIFY_TAG" => "CRM|LEAD_RESPONSIBLE|".$ID, "NOTIFY_MESSAGE" => GetMessage("CRM_LEAD_NOT_RESPONSIBLE_IM_NOTIFY", Array("#title#" => "".htmlspecialcharsbx($title)."")), "NOTIFY_MESSAGE_OUT" => GetMessage("CRM_LEAD_NOT_RESPONSIBLE_IM_NOTIFY", Array("#title#" => htmlspecialcharsbx($title)))." (".$serverName.$url.")" ); CIMNotify::Add($arMessageFields); } if ( $sonetEvent['TYPE'] == CCrmLiveFeedEvent::Progress && $sonetEventFields['PARAMS']['START_STATUS_ID'] && $sonetEventFields['PARAMS']['FINAL_STATUS_ID'] ) { $assignedByID = (isset($arFields['ASSIGNED_BY_ID']) ? $arFields['ASSIGNED_BY_ID'] : $arRow['ASSIGNED_BY_ID']); $infos = CCrmStatus::GetStatus('STATUS'); if ( $assignedByID != $modifiedByID && array_key_exists($sonetEventFields['PARAMS']['START_STATUS_ID'], $infos) && array_key_exists($sonetEventFields['PARAMS']['FINAL_STATUS_ID'], $infos) ) { $arMessageFields = array( "MESSAGE_TYPE" => IM_MESSAGE_SYSTEM, "TO_USER_ID" => $assignedByID, "FROM_USER_ID" => $modifiedByID, "NOTIFY_TYPE" => IM_NOTIFY_FROM, "NOTIFY_MODULE" => "crm", "LOG_ID" => $logEventID, //"NOTIFY_EVENT" => "lead_update", "NOTIFY_EVENT" => "changeStage", "NOTIFY_TAG" => "CRM|LEAD_PROGRESS|".$ID, "NOTIFY_MESSAGE" => GetMessage("CRM_LEAD_PROGRESS_IM_NOTIFY_MSGVER_1", Array( "#title#" => "".htmlspecialcharsbx($title)."", "#start_status_title#" => htmlspecialcharsbx($infos[$sonetEventFields['PARAMS']['START_STATUS_ID']]['NAME']), "#final_status_title#" => htmlspecialcharsbx($infos[$sonetEventFields['PARAMS']['FINAL_STATUS_ID']]['NAME']) )), "NOTIFY_MESSAGE_OUT" => GetMessage("CRM_LEAD_PROGRESS_IM_NOTIFY_MSGVER_1", Array( "#title#" => htmlspecialcharsbx($title), "#start_status_title#" => htmlspecialcharsbx($infos[$sonetEventFields['PARAMS']['START_STATUS_ID']]['NAME']), "#final_status_title#" => htmlspecialcharsbx($infos[$sonetEventFields['PARAMS']['FINAL_STATUS_ID']]['NAME']) ))." (".$serverName.$url.")" ); CIMNotify::Add($arMessageFields); } } } unset($sonetEventFields); } unset($sonetEvent); } //endregion //region After update event if($bResult && $enableSystemEvents) { $afterEvents = GetModuleEvents('crm', 'OnAfterCrmLeadUpdate'); while ($arEvent = $afterEvents->Fetch()) ExecuteModuleEventEx($arEvent, array(&$arFields)); } //endregion $statusSemanticsId = $arFields['STATUS_SEMANTIC_ID'] ?? $arRow['STATUS_SEMANTIC_ID'] ?? \Bitrix\Crm\PhaseSemantics::PROCESS; if(Crm\Ml\Scoring::isMlAvailable() && !Crm\PhaseSemantics::isFinal($statusSemanticsId)) { Crm\Ml\Scoring::queuePredictionUpdate(CCrmOwnerType::Lead, $ID, [ 'EVENT_TYPE' => Crm\Ml\Scoring::EVENT_ENTITY_UPDATE ]); } if ($bResult && !$syncStatusSemantics) { $item = Crm\Kanban\Entity::getInstance(self::$TYPE_NAME) ->createPullItem(array_merge($arRow, $arFields)); PullManager::getInstance()->sendItemUpdatedEvent( $item, [ 'TYPE' => self::$TYPE_NAME, 'SKIP_CURRENT_USER' => ($iUserId !== 0), ] ); } } return $bResult; }

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