CAllCrmDeal::Add

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

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

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

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

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

	$userID = isset($options['CURRENT_USER'])
		? (int)$options['CURRENT_USER'] : CCrmSecurityHelper::GetCurrentUserID();

	if($userID <= 0 && $this->bCheckPermission)
	{
		$arFields['RESULT_MESSAGE'] = $this->LAST_ERROR = GetMessage('CRM_PERMISSION_USER_NOT_DEFINED');
		return false;
	}

	unset($arFields['ID']);

	if(!($isRestoration && isset($arFields['DATE_CREATE'])))
	{
		unset($arFields['DATE_CREATE']);
		$arFields['~DATE_CREATE'] = $DB->CurrentTimeFunction();
	}

	if(!($isRestoration && isset($arFields['DATE_MODIFY'])))
	{
		unset($arFields['DATE_MODIFY']);
		$arFields['~DATE_MODIFY'] = $DB->CurrentTimeFunction();
	}

	if(!($isRestoration && isset($arFields['MOVED_TIME'])))
	{
		unset($arFields['MOVED_TIME']);
	}
	if(!($isRestoration && isset($arFields['MOVED_BY_ID'])))
	{
		unset($arFields['MOVED_BY_ID']);
	}

	if($userID > 0)
	{
		if(!(isset($arFields['CREATED_BY_ID']) && $arFields['CREATED_BY_ID'] > 0))
		{
			$arFields['CREATED_BY_ID'] = $userID;
		}

		if(!(isset($arFields['MODIFY_BY_ID']) && $arFields['MODIFY_BY_ID'] > 0))
		{
			$arFields['MODIFY_BY_ID'] = $userID;
		}

		if(!(isset($arFields['ASSIGNED_BY_ID']) && $arFields['ASSIGNED_BY_ID'] > 0))
		{
			$arFields['ASSIGNED_BY_ID'] = $userID;
		}
	}

	if(!isset($arFields['TITLE']) || !is_string($arFields['TITLE']) || trim($arFields['TITLE']) === '')
	{
		$arFields['TITLE'] = self::GetDefaultTitle();
	}

	$fields = self::GetUserFields();
	$this->fillEmptyFieldValues($arFields, $fields);

	if (!$this->CheckFields($arFields, false, $options))
	{
		$result = false;
		$arFields['RESULT_MESSAGE'] = &$this->LAST_ERROR;
	}
	else
	{
		if (!isset($arFields['IS_RECURRING']))
		{
			$arFields['IS_RECURRING'] = 'N';
		}
		if (!isset($arFields['MOVED_BY_ID']))
		{
			$arFields['MOVED_BY_ID'] = (int)$userID;
		}
		if (!isset($arFields['MOVED_TIME']))
		{
			$arFields['MOVED_TIME'] = (new \Bitrix\Main\Type\DateTime())->toString();
		}

		self::getLastActivityAdapter()->performAdd($arFields, $options);
		self::getCommentsAdapter()->normalizeFields(null, $arFields);

		//region Category
		$categoryID = isset($arFields['CATEGORY_ID']) ? max((int)$arFields['CATEGORY_ID'], 0) : 0;
		if($categoryID > 0 && !DealCategory::isEnabled($categoryID))
		{
			$categoryID = 0;
		}
		$arFields['CATEGORY_ID'] = $categoryID;
		//endregion

		//region StageID, SemanticID and IsNew
		$permissionTypeId = (
			$this->bCheckPermission
				? Bitrix\Crm\Security\EntityPermissionType::CREATE
				: Bitrix\Crm\Security\EntityPermissionType::UNDEFINED
		);

		if (!isset($arFields['STAGE_ID']) || (string)$arFields['STAGE_ID'] === '')
		{
			$arFields['STAGE_ID'] = self::GetStartStageID($categoryID, $permissionTypeId);
		}

		$viewMode = ($options['ITEM_OPTIONS']['VIEW_MODE'] ?? null);

		$viewModeActivitiesStageId = null;
		if ($viewMode === ViewMode::MODE_ACTIVITIES)
		{
			$viewModeActivitiesStageId = $arFields['STAGE_ID'];
			$arFields['STAGE_ID'] = self::GetStartStageID($categoryID, $permissionTypeId);
		}

		$isStageExist = self::IsStageExists($arFields['STAGE_ID'], $categoryID);
		$arFields['STAGE_SEMANTIC_ID'] = $isStageExist
			? self::GetSemanticID($arFields['STAGE_ID'], $categoryID)
			: Bitrix\Crm\PhaseSemantics::UNDEFINED
		;

		$arFields['IS_NEW'] = $arFields['STAGE_ID'] === self::GetStartStageID($categoryID) ? 'Y' : 'N';
		//endregion

		$observerIDs = isset($arFields['OBSERVER_IDS']) && is_array($arFields['OBSERVER_IDS'])
			? $arFields['OBSERVER_IDS'] : null;
		unset($arFields['OBSERVER_IDS']);

		$arAttr = array();
		if (!empty($arFields['STAGE_ID']))
		{
			$arAttr['STAGE_ID'] = $arFields['STAGE_ID'];
		}
		if (!empty($arFields['OPENED']))
		{
			$arAttr['OPENED'] = $arFields['OPENED'];
		}
		if(!empty($observerIDs))
		{
			$arAttr['CONCERNED_USER_IDS'] = $observerIDs;
		}

		$permissionEntityType = DealCategory::convertToPermissionEntityType($arFields['CATEGORY_ID']);
		$sPermission = 'ADD';
		if (isset($arFields['PERMISSION']))
		{
			if ($arFields['PERMISSION'] == 'IMPORT')
				$sPermission = 'IMPORT';
			unset($arFields['PERMISSION']);
		}

		$assignedByID = (int)$arFields['ASSIGNED_BY_ID'];
		if($this->bCheckPermission)
		{
			$arEntityAttr = self::BuildEntityAttr($userID, $arAttr);
			$userPerms =  $userID == CCrmPerms::GetCurrentUserID() ? $this->cPerms : CCrmPerms::GetUserPermissions($userID);
			$sEntityPerm = $userPerms->GetPermType($permissionEntityType, $sPermission, $arEntityAttr);
			if ($sEntityPerm == BX_CRM_PERM_NONE)
			{
				$this->LAST_ERROR = GetMessage('CRM_PERMISSION_DENIED');
				$arFields['RESULT_MESSAGE'] = &$this->LAST_ERROR;
				return false;
			}

			if ($sEntityPerm == BX_CRM_PERM_SELF && $assignedByID != $userID)
			{
				$arFields['ASSIGNED_BY_ID'] = $assignedByID = $userID;
			}
			if ($sEntityPerm == BX_CRM_PERM_OPEN && $userID == $assignedByID)
			{
				$arFields['OPENED'] = 'Y';
			}
		}

		$assignedByID = (int)$arFields['ASSIGNED_BY_ID'];
		$arEntityAttr = self::BuildEntityAttr($assignedByID, $arAttr);
		$userPerms =  $assignedByID == CCrmPerms::GetCurrentUserID() ? $this->cPerms : CCrmPerms::GetUserPermissions($assignedByID);
		$sEntityPerm = $userPerms->GetPermType($permissionEntityType, $sPermission, $arEntityAttr);
		self::PrepareEntityAttrs($arEntityAttr, $sEntityPerm);

		//Prepare currency & exchange rate
		if(!isset($arFields['CURRENCY_ID']))
		{
			$arFields['CURRENCY_ID'] = CCrmCurrency::GetBaseCurrencyID();
		}

		if(!isset($arFields['EXCH_RATE']))
		{
			$arFields['EXCH_RATE'] = CCrmCurrency::GetExchangeRate($arFields['CURRENCY_ID']);
		}

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

		//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']);
		}

		$currentDate = ConvertTimeStamp(time() + \CTimeZone::GetOffset(), 'SHORT', SITE_ID);
		$arFields['~BEGINDATE'] = $DB->CharToDateFunction(
			isset($arFields['BEGINDATE']) ? $arFields['BEGINDATE'] : $currentDate,
			'SHORT',
			false
		);

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

		$isFinalStage = self::GetStageSemantics($arFields['STAGE_ID'], $categoryID) !== 'process';
		$enableCloseDateSync = DealSettings::getCurrent()->isCloseDateSyncEnabled();
		if(isset($options['ENABLE_CLOSE_DATE_SYNC']) && is_bool($options['ENABLE_CLOSE_DATE_SYNC']))
		{
			$enableCloseDateSync = $options['ENABLE_CLOSE_DATE_SYNC'];
		}

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

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

		//region Preparation of contacts
		$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']);
		//For backward compatibility only
		$contactID = isset($arFields['CONTACT_ID']) ? max((int)$arFields['CONTACT_ID'], 0) : null;
		if($contactID !== null && $contactIDs === null && $contactBindings === null)
		{
			$contactIDs = array();
			if($contactID > 0)
			{
				$contactIDs[] = $contactID;
			}
		}
		unset($arFields['CONTACT_ID']);

		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
			);
		}
		//endregion

		//region Rise BeforeAdd event
		$beforeEvents = GetModuleEvents('crm', 'OnBeforeCrmDealAdd');
		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_CREATION_CANCELED', array('#NAME#' => $arEvent['TO_NAME']));
					$arFields['RESULT_MESSAGE'] = &$this->LAST_ERROR;
				}
				return false;
			}
		}
		//endregion

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

		unset($arFields['ID']);

		$this->normalizeEntityFields($arFields);
		$ID = (int) $DB->Add(self::TABLE_NAME, $arFields, [], 'FILE: '.__FILE__.'
LINE: '.__LINE__); //Append ID to TITLE if required if($ID > 0 && $arFields['TITLE'] === self::GetDefaultTitle()) { $arFields['TITLE'] = self::GetDefaultTitle($ID); $sUpdate = $DB->PrepareUpdate('b_crm_deal', array('TITLE' => $arFields['TITLE'])); if($sUpdate <> '') { $DB->Query("UPDATE b_crm_deal SET {$sUpdate} WHERE ID = {$ID}", false, 'FILE: '.__FILE__.'
LINE: '.__LINE__); }; } if(defined('BX_COMP_MANAGED_CACHE')) { $GLOBALS['CACHE_MANAGER']->CleanDir('b_crm_deal'); } $result = $arFields['ID'] = $ID; //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']); } //region User Field CCrmEntityHelper::NormalizeUserFields($arFields, self::$sUFEntityID, $GLOBALS['USER_FIELD_MANAGER'], array('IS_NEW' => true)); $GLOBALS['USER_FIELD_MANAGER']->Update(self::$sUFEntityID, $ID, $arFields); //endregion //region Save Observers if(!empty($observerIDs)) { Crm\Observer\ObserverManager::registerBulk($observerIDs, \CCrmOwnerType::Deal, $ID); } //endregion $securityRegisterOptions = (new \Bitrix\Crm\Security\Controller\RegisterOptions()) ->setEntityAttributes($arEntityAttr) ; Crm\Security\Manager::getEntityController(CCrmOwnerType::Deal) ->register($permissionEntityType, $ID, $securityRegisterOptions) ; //region Save contacts if(!empty($contactBindings)) { DealContactTable::bindContacts($ID, $contactBindings); if (isset($GLOBALS['USER']) && !empty($contactIDs)) { CUserOptions::SetOption( 'crm', 'crm_contact_search', array('last_selected' => $contactIDs[count($contactIDs) - 1]) ); } } //endregion if(!empty($contactBindings)) { $arFields['CONTACT_ID'] = EntityBinding::getPrimaryEntityID(CCrmOwnerType::Contact, $contactBindings); } self::SynchronizeCustomerData($ID, $arFields); //Statistics & History --> if ($arFields['IS_RECURRING'] !== 'Y') { DealSumStatisticEntry::register($ID, $arFields); DealInvoiceStatisticEntry::synchronize($ID, $arFields); DealStageHistoryEntry::register($ID, $arFields, array('IS_NEW' => true)); } if(isset($arFields['LEAD_ID']) && $arFields['LEAD_ID'] > 0) { LeadConversionStatisticsEntry::processBindingsChange($arFields['LEAD_ID']); } //<-- Statistics & History if (($options['DISABLE_TIMELINE_CREATION'] ?? null) !== 'Y') { if($isRestoration) { Bitrix\Crm\Timeline\DealController::getInstance()->onRestore($ID, array('FIELDS' => $arFields)); } else { Bitrix\Crm\Timeline\DealController::getInstance()->onCreate( $ID, array( 'FIELDS' => $arFields, 'CONTACT_BINDINGS' => $contactBindings ) ); } } CCrmEntityHelper::registerAdditionalTimelineEvents([ 'entityTypeId' => \CCrmOwnerType::Deal, 'entityId' => $ID, 'fieldsInfo' => static::GetFieldsInfo(), 'previousFields' => [], 'currentFields' => $arFields, 'previousStageSemantics' => Crm\PhaseSemantics::UNDEFINED, 'currentStageSemantics' => $arFields['STAGE_SEMANTIC_ID'] ?? Crm\PhaseSemantics::UNDEFINED, 'options' => $options, 'bindings' => [ 'entityTypeId' => \CCrmOwnerType::Contact, 'previous' => [], 'current' => $contactBindings, ] ]); \Bitrix\Crm\Counter\Monitor::getInstance()->onEntityAdd(CCrmOwnerType::Deal, $arFields); // tracking of entity Tracking\Entity::onAfterAdd(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); } if (isset($GLOBALS['USER']) && isset($arFields['COMPANY_ID']) && intval($arFields['COMPANY_ID']) > 0) { CUserOptions::SetOption('crm', 'crm_company_search', array('last_selected' => $arFields['COMPANY_ID'])); } //region Search content index Bitrix\Crm\Search\SearchContentBuilderFactory::create( CCrmOwnerType::Deal )->build($ID, ['checkExist' => true]); //endregion self::getCommentsAdapter()->performAdd($arFields, $options); if(isset($options['REGISTER_SONET_EVENT']) && $options['REGISTER_SONET_EVENT'] === true) { $opportunity = round((isset($arFields['OPPORTUNITY']) ? doubleval($arFields['OPPORTUNITY']) : 0.0), 2); $currencyID = isset($arFields['CURRENCY_ID']) ? $arFields['CURRENCY_ID'] : ''; if($currencyID === '') { $currencyID = CCrmCurrency::GetBaseCurrencyID(); } $assignedByID = intval($arFields['ASSIGNED_BY_ID']); $createdByID = intval($arFields['CREATED_BY_ID']); $companyID = (int)$arFields['COMPANY_ID']; $liveFeedFields = array( 'USER_ID' => $createdByID, 'ENTITY_TYPE_ID' => CCrmOwnerType::Deal, 'ENTITY_ID' => $ID, 'TITLE' => GetMessage('CRM_DEAL_EVENT_ADD'), 'MESSAGE' => '', 'PARAMS' => array( 'TITLE' => isset($arFields['TITLE']) ? $arFields['TITLE'] : '', 'STAGE_ID' => isset($arFields['STAGE_ID']) ? $arFields['STAGE_ID'] : '', 'CATEGORY_ID' => isset($arFields['CATEGORY_ID']) ? $arFields['CATEGORY_ID'] : 0, 'OPPORTUNITY' => strval($opportunity), 'CURRENCY_ID' => $currencyID, 'COMPANY_ID' => $companyID, 'CONTACT_ID' => isset($arFields['CONTACT_ID']) ? intval($arFields['CONTACT_ID']) : 0, 'AUTHOR_ID' => intval($arFields['CREATED_BY_ID']), 'RESPONSIBLE_ID' => $assignedByID ) ); //Register contact & company relations $parents = array(); if($companyID > 0) { CCrmLiveFeed::PrepareOwnershipRelations( CCrmOwnerType::Company, array($companyID), $parents ); } if(is_array($contactIDs)) { CCrmLiveFeed::PrepareOwnershipRelations( CCrmOwnerType::Contact, $contactIDs, $parents ); } if(!empty($parents)) { $liveFeedFields['PARENTS'] = array_values($parents); } if (Crm\Settings\Crm::isLiveFeedRecordsGenerationEnabled()) { CCrmSonetSubscription::RegisterSubscription( CCrmOwnerType::Deal, $ID, CCrmSonetSubscriptionType::Responsibility, $assignedByID ); } $logEventID = CCrmLiveFeed::CreateLogEvent($liveFeedFields, CCrmLiveFeedEvent::Add, ['CURRENT_USER' => $userID]); if ( $logEventID !== false && $assignedByID != $createdByID && CModule::IncludeModule("im") ) { $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", "")); $arMessageFields = array( "MESSAGE_TYPE" => IM_MESSAGE_SYSTEM, "TO_USER_ID" => $assignedByID, "FROM_USER_ID" => $createdByID, "NOTIFY_TYPE" => IM_NOTIFY_FROM, "NOTIFY_MODULE" => "crm", "LOG_ID" => $logEventID, //"NOTIFY_EVENT" => "deal_add", "NOTIFY_EVENT" => "changeAssignedBy", "NOTIFY_TAG" => "CRM|DEAL_RESPONSIBLE|".$ID, "NOTIFY_MESSAGE" => GetMessage("CRM_DEAL_RESPONSIBLE_IM_NOTIFY", Array("#title#" => "".htmlspecialcharsbx($arFields['TITLE'])."")), "NOTIFY_MESSAGE_OUT" => GetMessage("CRM_DEAL_RESPONSIBLE_IM_NOTIFY", Array("#title#" => htmlspecialcharsbx($arFields['TITLE'])))." (".$serverName.$url.")" ); CIMNotify::Add($arMessageFields); } } //region Rise AfterAdd event $afterEvents = GetModuleEvents('crm', 'OnAfterCrmDealAdd'); while ($arEvent = $afterEvents->Fetch()) { ExecuteModuleEventEx($arEvent, array(&$arFields)); } //endregion if(isset($arFields['ORIGIN_ID']) && $arFields['ORIGIN_ID'] !== '') { $afterEvents = GetModuleEvents('crm', 'OnAfterExternalCrmDealAdd'); while ($arEvent = $afterEvents->Fetch()) { ExecuteModuleEventEx($arEvent, array(&$arFields)); } } if ($ID>0) { if ( $viewMode === ViewMode::MODE_ACTIVITIES && $viewModeActivitiesStageId ) { $deadline = (new Crm\Kanban\EntityActivityDeadline())->getDeadline($viewModeActivitiesStageId); if ($deadline) { \Bitrix\Crm\Activity\Entity\ToDo::createWithDefaultDescription( \CCrmOwnerType::Deal, $ID, $deadline ); } } $item = Crm\Kanban\Entity::getInstance(self::$TYPE_NAME) ->createPullItem($arFields); PullManager::getInstance()->sendItemAddedEvent( $item, [ 'TYPE' => self::$TYPE_NAME, 'CATEGORY_ID' => \CCrmDeal::GetCategoryID($ID), 'SKIP_CURRENT_USER' => ($userID !== 0), ] ); } } return $result; }

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