CAllCrmDeal::Update

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

	$ID = (int) $ID;
	if(!is_array($options))
	{
		$options = array();
	}
	$options['IS_COMPARE_ENABLED'] = $bCompare;
	$isSystemAction = isset($options['IS_SYSTEM_ACTION']) && $options['IS_SYSTEM_ACTION'];

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

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

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

	$arFilterTmp = array('ID' => $ID);
	if (!$this->bCheckPermission)
		$arFilterTmp['CHECK_PERMISSIONS'] = 'N';

	$obRes = self::GetListEx(array(), $arFilterTmp, false, false, array('*', 'UF_*'));
	if (!($arRow = $obRes->Fetch()))
		return false;

	unset(
		$arFields['DATE_CREATE'],
		$arFields['DATE_MODIFY'],
		$arFields['CATEGORY_ID'],
		$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'] = $userID;
		}
	}

	if(isset($arFields['TITLE']) && (!is_scalar($arFields['TITLE']) || trim($arFields['TITLE']) === ''))
	{
		unset($arFields['TITLE']);
	}

	//Scavenging
	if(isset($arFields['BEGINDATE']) && (!is_string($arFields['BEGINDATE']) || trim($arFields['BEGINDATE']) === ''))
	{
		unset($arFields['BEGINDATE']);
	}

	if(isset($arFields['CLOSEDATE']) && (!is_string($arFields['CLOSEDATE']) || trim($arFields['CLOSEDATE']) === ''))
	{
		unset($arFields['CLOSEDATE']);
	}

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

	$assignedByID = (int)(isset($arFields['ASSIGNED_BY_ID']) ? $arFields['ASSIGNED_BY_ID'] : $arRow['ASSIGNED_BY_ID']);

	$bResult = false;

	$options['CURRENT_FIELDS'] = $arRow;
	if (!$this->CheckFields($arFields, $ID, $options))
	{
		$arFields['RESULT_MESSAGE'] = &$this->LAST_ERROR;
	}
	else
	{
		//region Category, SemanticID and IsNew

		//Semantic ID depends on Stage ID and can't be assigned directly
		$syncStageSemantics = isset($options['SYNCHRONIZE_STAGE_SEMANTICS']) && $options['SYNCHRONIZE_STAGE_SEMANTICS'];
		if(isset($arFields['STAGE_ID']) && ($syncStageSemantics || $arFields['STAGE_ID'] !== $arRow['STAGE_ID']))
		{
			$arFields['STAGE_SEMANTIC_ID'] = self::IsStageExists($arFields['STAGE_ID'], $arRow['CATEGORY_ID'])
				? self::GetSemanticID($arFields['STAGE_ID'], $arRow['CATEGORY_ID'])
				: Bitrix\Crm\PhaseSemantics::UNDEFINED;
			$arFields['IS_NEW'] = $arFields['STAGE_ID'] === self::GetStartStageID($arRow['CATEGORY_ID']) ? 'Y' : 'N';

			if ($arFields['STAGE_ID'] !== $arRow['STAGE_ID'])
			{
				$arFields['MOVED_BY_ID'] = (int)$userID;
				$arFields['MOVED_TIME'] = (new \Bitrix\Main\Type\DateTime())->toString();
			}
		}
		else
		{
			unset($arFields['STAGE_SEMANTIC_ID'], $arFields['IS_NEW']);
		}
		//endregion

		$permissionEntityType = DealCategory::convertToPermissionEntityType($arRow['CATEGORY_ID']);
		if($this->bCheckPermission && !CCrmAuthorizationHelper::CheckUpdatePermission($permissionEntityType, $ID, $this->cPerms))
		{
			$this->LAST_ERROR = GetMessage('CRM_PERMISSION_DENIED');
			$arFields['RESULT_MESSAGE'] = &$this->LAST_ERROR;
			return false;
		}

		$updateOperationRestriction = Crm\Restriction\RestrictionManager::getUpdateOperationRestriction(new Crm\ItemIdentifier(
			\CCrmOwnerType::Deal,
			(int)$ID
		));
		if (!$isSystemAction && !$updateOperationRestriction->hasPermission())
		{
			$this->LAST_ERROR = $updateOperationRestriction->getErrorMessage();
			$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', 'OnBeforeCrmDealUpdate');
			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_DEAL_UPDATE_CANCELED', array('#NAME#' => $arEvent['TO_NAME']));
						$arFields['RESULT_MESSAGE'] = &$this->LAST_ERROR;
					}
					return false;
				}
			}
		}
		//endregion

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

		$originalObserverIDs = Crm\Observer\ObserverManager::getEntityObserverIDs(CCrmOwnerType::Deal, $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;
		}

		$arEntityAttr = self::BuildEntityAttr($assignedByID, $arAttr);
		if($this->bCheckPermission)
		{
			$sEntityPerm = $this->cPerms->GetPermType($permissionEntityType, 'WRITE', $arEntityAttr);
			//HACK: Ensure that entity accessible for user restricted by BX_CRM_PERM_OPEN
			self::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 !== $userID)
			{
				$arFields['OPENED'] = 'Y';
			}
		}

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

		//region Preparation of contacts
		$originalContactBindings = DealContactTable::getDealBindings($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 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)
		{
			$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'] = 'DEAL';
				$arEvent['ENTITY_ID'] = $ID;
				$arEvent['EVENT_TYPE'] = 1;

				if(!isset($arEvent['USER_ID']))
				{
					if($userID > 0)
					{
						$arEvent['USER_ID'] = $userID;
					}
					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'] !== 'CONTACT_ID' && $arEvent['ENTITY_FIELD'] !== '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 'STAGE_ID':
					{
						$sonetEventData[CCrmLiveFeedEvent::Progress] = array(
							'TYPE' => CCrmLiveFeedEvent::Progress,
							'FIELDS' => array(
								//'EVENT_ID' => $eventID,
								'TITLE' => GetMessage('CRM_DEAL_EVENT_UPDATE_STAGE'),
								'MESSAGE' => '',
								'PARAMS' => array(
									'START_STATUS_ID' => $arRow['STAGE_ID'],
									'FINAL_STATUS_ID' => $arFields['STAGE_ID'],
									'CATEGORY_ID' => intval($arRow['CATEGORY_ID'])
								)
							)
						);
					}
					break;
					case 'ASSIGNED_BY_ID':
					{
						$sonetEventData[CCrmLiveFeedEvent::Responsible] = array(
							'TYPE' => CCrmLiveFeedEvent::Responsible,
							'FIELDS' => array(
								//'EVENT_ID' => $eventID,
								'TITLE' => GetMessage('CRM_DEAL_EVENT_UPDATE_ASSIGNED_BY'),
								'MESSAGE' => '',
								'PARAMS' => array(
									'START_RESPONSIBLE_ID' => $arRow['ASSIGNED_BY_ID'],
									'FINAL_RESPONSIBLE_ID' => $arFields['ASSIGNED_BY_ID']
								)
							)
						);
					}
					break;
					case 'CONTACT_ID':
					case 'COMPANY_ID':
					{
						if(!isset($sonetEventData[CCrmLiveFeedEvent::Client]))
						{
							$oldCompanyID = isset($arRow['COMPANY_ID']) ? intval($arRow['COMPANY_ID']) : 0;
							$sonetEventData[CCrmLiveFeedEvent::Client] = array(
								'CODE'=> 'CLIENT',
								'TYPE' => CCrmLiveFeedEvent::Client,
								'FIELDS' => array(
									//'EVENT_ID' => $eventID,
									'TITLE' => GetMessage('CRM_DEAL_EVENT_UPDATE_CLIENT'),
									'MESSAGE' => '',
									'PARAMS' => array(
										'REMOVED_CLIENT_CONTACT_IDS' => is_array($removedContactIDs)
											? $removedContactIDs : array(),
										'ADDED_CLIENT_CONTACT_IDS' => is_array($addedContactIDs)
											? $addedContactIDs : array(),
										//Todo: Remove START_CLIENT_CONTACT_ID and FINAL_CLIENT_CONTACT_ID when log template will be ready
										'START_CLIENT_CONTACT_ID' => is_array($removedContactIDs)
											&& isset($removedContactIDs[0]) ? $removedContactIDs[0] : 0,
										'FINAL_CLIENT_CONTACT_ID' => is_array($addedContactIDs)
											&& isset($addedContactIDs[0]) ? $addedContactIDs[0] : 0,
										'START_CLIENT_COMPANY_ID' => $oldCompanyID,
										'FINAL_CLIENT_COMPANY_ID' => isset($arFields['COMPANY_ID']) ? intval($arFields['COMPANY_ID']) : $oldCompanyID
									)
								)
							);
						}
					}
					break;
					case 'TITLE':
					{
						$sonetEventData[CCrmLiveFeedEvent::Denomination] = array(
							'TYPE' => CCrmLiveFeedEvent::Denomination,
							'FIELDS' => array(
								//'EVENT_ID' => $eventID,
								'TITLE' => GetMessage('CRM_DEAL_EVENT_UPDATE_TITLE'),
								'MESSAGE' => '',
								'PARAMS' => array(
									'START_TITLE' => $arRow['TITLE'],
									'FINAL_TITLE' => $arFields['TITLE']
								)
							)
						);
					}
					break;
				}
			}
		}

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

		$currentDate = ConvertTimeStamp(time() + \CTimeZone::GetOffset(), 'SHORT', SITE_ID);
		$enableCloseDateSync = DealSettings::getCurrent()->isCloseDateSyncEnabled();
		if(isset($options['ENABLE_CLOSE_DATE_SYNC']) && is_bool($options['ENABLE_CLOSE_DATE_SYNC']))
		{
			$enableCloseDateSync = $options['ENABLE_CLOSE_DATE_SYNC'];
		}

		$categoryID = isset($arRow['CATEGORY_ID']) ? (int)$arRow['CATEGORY_ID'] : 0;
		if(isset($arFields['STAGE_ID']))
		{
			$isFinalStage = self::GetStageSemantics($arFields['STAGE_ID'], $categoryID) !== 'process';
			$isStageChanged = !isset($arRow['STAGE_ID']) || $arRow['STAGE_ID'] !== $arFields['STAGE_ID'];

			$arFields['CLOSED'] = $isFinalStage ? 'Y' : 'N';
			if($enableCloseDateSync && $isFinalStage && $isStageChanged)
			{
				$arFields['CLOSEDATE'] = $currentDate;
				$arFields['~CLOSEDATE'] = $DB->CharToDateFunction($currentDate, 'SHORT', false);
			}
			elseif(isset($arFields['CLOSEDATE']))
			{
				$arFields['~CLOSEDATE'] = $DB->CharToDateFunction($arFields['CLOSEDATE'], 'SHORT', false);
			}
		}
		elseif(isset($arFields['CLOSEDATE']))
		{
			$arFields['~CLOSEDATE'] = $DB->CharToDateFunction($arFields['CLOSEDATE'], 'SHORT', false);
		}

		if(isset($arFields['BEGINDATE']))
		{
			$arFields['~BEGINDATE'] = $DB->CharToDateFunction($arFields['BEGINDATE'], 'SHORT', false);
		}

		if(isset($arFields['BEGINDATE']))
		{
			$arFields['__BEGINDATE'] = $arFields['BEGINDATE'];
			unset($arFields['BEGINDATE']);
		}

		if(isset($arFields['CLOSEDATE']))
		{
			$arFields['__CLOSEDATE'] = $arFields['CLOSEDATE'];
			unset($arFields['CLOSEDATE']);
		}

		unset($arFields['ID']);

		$this->normalizeEntityFields($arFields);
		$sUpdate = $DB->PrepareUpdate(self::TABLE_NAME, $arFields);

		if ($sUpdate <> '')
		{
			$DB->Query("UPDATE b_crm_deal SET {$sUpdate} WHERE ID = {$ID}", false, 'FILE: '.__FILE__.'
LINE: '.__LINE__); $bResult = true; } //Restore BEGINDATE and CLOSEDATE if(isset($arFields['__BEGINDATE'])) { $arFields['BEGINDATE'] = $arFields['__BEGINDATE']; unset($arFields['__BEGINDATE']); } if(isset($arFields['__CLOSEDATE'])) { $arFields['CLOSEDATE'] = $arFields['__CLOSEDATE']; unset($arFields['__CLOSEDATE']); } 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::Deal."_".$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 = \CCrmDeal::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)) { DealContactTable::unbindContacts($ID, $removedContactBindings); } if(!empty($addedContactBindings)) { DealContactTable::bindContacts($ID, $addedContactBindings); } //endregion //region Save Observers if(!empty($addedObserverIDs)) { Crm\Observer\ObserverManager::registerBulk( $addedObserverIDs, \CCrmOwnerType::Deal, $ID, count($originalObserverIDs) ); } if(!empty($removedObserverIDs)) { Crm\Observer\ObserverManager::unregisterBulk( $removedObserverIDs, \CCrmOwnerType::Deal, $ID ); } //endregion //region Save access rights for owner and observers $securityRegisterOptions = (new \Bitrix\Crm\Security\Controller\RegisterOptions()) ->setEntityAttributes($arEntityAttr) ->setEntityFields($currentFields) ; Crm\Security\Manager::getEntityController(CCrmOwnerType::Deal) ->register($permissionEntityType, $ID, $securityRegisterOptions) ; //endregion self::SynchronizeCustomerData($ID, $arRow, array('ENABLE_SOURCE' => false)); self::SynchronizeCustomerData($ID, $currentFields); if (isset($GLOBALS['USER']) && isset($arFields['COMPANY_ID']) && $arFields['COMPANY_ID'] > 0) { CUserOptions::SetOption('crm', 'crm_company_search', array('last_selected' => $arFields['COMPANY_ID'])); } //region Complete activities if entity is closed if($arRow['STAGE_SEMANTIC_ID'] !== $currentFields['STAGE_SEMANTIC_ID'] && $currentFields['STAGE_SEMANTIC_ID'] !== Bitrix\Crm\PhaseSemantics::PROCESS) { CCrmActivity::SetAutoCompletedByOwner(CCrmOwnerType::Deal, $ID); } //endregion //region Statistics & History if(!isset($options['REGISTER_STATISTICS']) || $options['REGISTER_STATISTICS'] === true) { DealSumStatisticEntry::register($ID, $currentFields); DealStageHistoryEntry::synchronize($ID, $currentFields); DealInvoiceStatisticEntry::synchronize($ID, $currentFields); DealActivityStatisticEntry::synchronize($ID, $currentFields); DealChannelBinding::synchronize($ID, $currentFields); if(isset($arFields['STAGE_ID'])) { DealStageHistoryEntry::register($ID, $currentFields, array('IS_NEW' => false)); } $oldLeadID = isset($arRow['LEAD_ID']) ? (int)$arRow['LEAD_ID'] : 0; $curLeadID = isset($arFields['LEAD_ID']) ? (int)$arFields['LEAD_ID'] : $oldLeadID; if($oldLeadID != $curLeadID) { if($oldLeadID > 0) { LeadConversionStatisticsEntry::processBindingsChange($oldLeadID); } if($curLeadID > 0) { LeadConversionStatisticsEntry::processBindingsChange($curLeadID); } } } //endregion self::getCommentsAdapter() ->setPreviousFields((int)$ID, $arRow) ->performUpdate((int)$ID, $arFields, $options) ; if ($bResult) { \Bitrix\Crm\Counter\Monitor::getInstance()->onEntityUpdate(CCrmOwnerType::Deal, $arRow, $currentFields); } // update utm fields UtmTable::updateEntityUtmFromFields(CCrmOwnerType::Deal, $ID, $arFields); //region save parent relations Crm\Service\Container::getInstance()->getParentFieldManager()->saveParentRelationsForIdentifier( new Crm\ItemIdentifier(\CCrmOwnerType::Deal, $ID), $arFields ); //endregion if($bUpdateSearch) { $arFilterTmp = Array('ID' => $ID); if (!$this->bCheckPermission) $arFilterTmp['CHECK_PERMISSIONS'] = 'N'; CCrmSearch::UpdateSearch($arFilterTmp, 'DEAL', true); } //region Search content index Bitrix\Crm\Search\SearchContentBuilderFactory::create(CCrmOwnerType::Deal) ->build($ID, ['checkExist' => true]); //endregion Bitrix\Crm\Timeline\DealController::getInstance()->onModify( $ID, array( 'CURRENT_FIELDS' => $arFields, 'PREVIOUS_FIELDS' => $arRow, 'CONTACT_BINDINGS' => $contactBindings, 'ADDED_CONTACT_BINDINGS' => $addedContactBindings ) ); CCrmEntityHelper::registerAdditionalTimelineEvents([ 'entityTypeId' => \CCrmOwnerType::Deal, 'entityId' => $ID, 'fieldsInfo' => static::GetFieldsInfo(), 'previousFields' => $arRow, 'currentFields' => $arFields, 'previousStageSemantics' => $arRow['STAGE_SEMANTIC_ID'] ?? Crm\PhaseSemantics::UNDEFINED, 'currentStageSemantics' => $arFields['STAGE_SEMANTIC_ID'] ?? Crm\PhaseSemantics::UNDEFINED, 'options' => $options, 'bindings' => [ 'entityTypeId' => \CCrmOwnerType::Contact, 'previous' => $originalContactBindings, 'current' => $contactBindings, ] ]); Bitrix\Crm\Integration\Im\Chat::onEntityModification( CCrmOwnerType::Deal, $ID, array( 'CURRENT_FIELDS' => $arFields, 'PREVIOUS_FIELDS' => $arRow, 'ADDED_OBSERVER_IDS' => $addedObserverIDs, 'REMOVED_OBSERVER_IDS' => $removedObserverIDs ) ); $arFields['ID'] = $ID; if (isset($arFields['FM']) && is_array($arFields['FM'])) { $CCrmFieldMulti = new CCrmFieldMulti(); $CCrmFieldMulti->SetFields('DEAL', $ID, $arFields['FM']); } // Responsible user sync //CCrmActivity::Synchronize(CCrmOwnerType::Deal, $ID); $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::Deal, $ID, CCrmSonetSubscriptionType::Responsibility, $arFields['ASSIGNED_BY_ID'], $arRow['ASSIGNED_BY_ID'], $registerSonetEvent ); } if($bResult && $bCompare && $registerSonetEvent && !empty($sonetEventData)) { //region Preparation of Parent Contact IDs $parentContactIDs = is_array($contactIDs) ? $contactIDs : DealContactTable::getDealContactIDs($ID); //endregion //COMPANY $newCompanyID = isset($arFields['COMPANY_ID']) ? (int)$arFields['COMPANY_ID'] : 0; $oldCompanyID = isset($arRow['COMPANY_ID']) ? (int)$arRow['COMPANY_ID'] : 0; $companyID = $newCompanyID > 0 ? $newCompanyID : $oldCompanyID; $modifiedByID = (int)$arFields['MODIFY_BY_ID']; foreach($sonetEventData as &$sonetEvent) { $sonetEventType = $sonetEvent['TYPE']; $sonetEventFields = &$sonetEvent['FIELDS']; $sonetEventFields['ENTITY_TYPE_ID'] = CCrmOwnerType::Deal; $sonetEventFields['ENTITY_ID'] = $ID; $sonetEventFields['USER_ID'] = $modifiedByID; $parents = array(); //Register company relation if($companyID > 0) { CCrmLiveFeed::PrepareOwnershipRelations( CCrmOwnerType::Company, array($companyID), $parents ); } //Register contact relation CCrmLiveFeed::PrepareOwnershipRelations( CCrmOwnerType::Contact, $parentContactIDs, $parents ); if(!empty($parents)) { $sonetEventFields['PARENTS'] = array_values($parents); } $logEventID = CCrmLiveFeed::CreateLogEvent($sonetEventFields, $sonetEventType, ['CURRENT_USER' => $userID]); if ( $logEventID !== false && CModule::IncludeModule("im") ) { $title = CCrmOwnerType::GetCaption(CCrmOwnerType::Deal, $ID, false); $url = CCrmOwnerType::GetEntityShowPath(CCrmOwnerType::Deal, $ID); $serverName = (CMain::IsHTTPS() ? "https" : "http")."://".((defined("SITE_SERVER_NAME") && SITE_SERVER_NAME <> '') ? SITE_SERVER_NAME : COption::GetOptionString("main", "server_name", "")); if ( $sonetEvent['TYPE'] == CCrmLiveFeedEvent::Responsible && $sonetEventFields['PARAMS']['FINAL_RESPONSIBLE_ID'] != $modifiedByID ) { $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" => "deal_update", "NOTIFY_EVENT" => "changeAssignedBy", "NOTIFY_TAG" => "CRM|DEAL_RESPONSIBLE|".$ID, "NOTIFY_MESSAGE" => GetMessage("CRM_DEAL_RESPONSIBLE_IM_NOTIFY", Array("#title#" => "".htmlspecialcharsbx($title)."")), "NOTIFY_MESSAGE_OUT" => GetMessage("CRM_DEAL_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" => "deal_update", "NOTIFY_EVENT" => "changeAssignedBy", "NOTIFY_TAG" => "CRM|DEAL_RESPONSIBLE|".$ID, "NOTIFY_MESSAGE" => GetMessage("CRM_DEAL_NOT_RESPONSIBLE_IM_NOTIFY", Array("#title#" => "".htmlspecialcharsbx($title)."")), "NOTIFY_MESSAGE_OUT" => GetMessage("CRM_DEAL_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 = self::GetStages($categoryID); if ( $assignedByID != $modifiedByID && isset($infos[$sonetEventFields['PARAMS']['START_STATUS_ID']]) && isset($infos[$sonetEventFields['PARAMS']['FINAL_STATUS_ID']]) ) { $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" => "deal_update", "NOTIFY_EVENT" => "changeStage", "NOTIFY_TAG" => "CRM|DEAL_PROGRESS|".$ID, "NOTIFY_MESSAGE" => GetMessage("CRM_DEAL_PROGRESS_IM_NOTIFY_2", 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_DEAL_PROGRESS_IM_NOTIFY_2", 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); } //region After update event if($bResult && $enableSystemEvents) { $afterEvents = GetModuleEvents('crm', 'OnAfterCrmDealUpdate'); while ($arEvent = $afterEvents->Fetch()) ExecuteModuleEventEx($arEvent, array(&$arFields)); } //endregion self::PullChange('UPDATE', array('ID' => $ID)); if(!$isSystemAction) { $stageSemanticsId = ($arFields['STAGE_SEMANTIC_ID'] ?? null) ?: $arRow['STAGE_SEMANTIC_ID']; if(Crm\Ml\Scoring::isMlAvailable() && !Crm\PhaseSemantics::isFinal($stageSemanticsId)) { Crm\Ml\Scoring::queuePredictionUpdate(CCrmOwnerType::Deal, $ID, [ 'EVENT_TYPE' => Crm\Ml\Scoring::EVENT_ENTITY_UPDATE ]); } } if ($bResult && !$syncStageSemantics) { $item = Crm\Kanban\Entity::getInstance(self::$TYPE_NAME) ->createPullItem(array_merge($arRow, $arFields)); PullManager::getInstance()->sendItemUpdatedEvent( $item, [ 'TYPE' => self::$TYPE_NAME, 'CATEGORY_ID' => \CCrmDeal::GetCategoryID($ID), 'SKIP_CURRENT_USER' => ($userID !== 0), 'IGNORE_DELAY' => \CCrmBizProcHelper::isActiveDebugEntity(\CCrmOwnerType::Deal, $ID), ] ); } } return $bResult; }

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