예제 #1
0
 public function Update($ID, array &$arFields, $bCompare = true, $bUpdateSearch = true, $arOptions = array())
 {
     global $DB;
     $this->LAST_ERROR = '';
     $ID = (int) $ID;
     if (!is_array($arOptions)) {
         $arOptions = array();
     }
     $arFilterTmp = array('ID' => $ID);
     if (!$this->bCheckPermission) {
         $arFilterTmp['CHECK_PERMISSIONS'] = 'N';
     }
     $obRes = self::GetListEx(array(), $arFilterTmp);
     if (!($arRow = $obRes->Fetch())) {
         return false;
     }
     $iUserId = CCrmSecurityHelper::GetCurrentUserID();
     if (isset($arFields['DATE_CREATE'])) {
         unset($arFields['DATE_CREATE']);
     }
     if (isset($arFields['DATE_MODIFY'])) {
         unset($arFields['DATE_MODIFY']);
     }
     $arFields['~DATE_MODIFY'] = $DB->CurrentTimeFunction();
     if (isset($arFields['DATE_CLOSED'])) {
         unset($arFields['DATE_CLOSED']);
     }
     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['MODIFY_BY_ID']) || $arFields['MODIFY_BY_ID'] <= 0) {
         $arFields['MODIFY_BY_ID'] = $iUserId;
     }
     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;
     if (!$this->CheckFields($arFields, $ID, $arOptions)) {
         $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;
         }
         $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;
             }
         }
         $arAttr = array();
         $arAttr['STATUS_ID'] = !empty($arFields['STATUS_ID']) ? $arFields['STATUS_ID'] : $arRow['STATUS_ID'];
         $arAttr['OPENED'] = !empty($arFields['OPENED']) ? $arFields['OPENED'] : $arRow['OPENED'];
         $arEntityAttr = self::BuildEntityAttr($assignedByID, $arAttr);
         $sEntityPerm = $this->cPerms->GetPermType('LEAD', 'WRITE', $arEntityAttr);
         $this->PrepareEntityAttrs($arEntityAttr, $sEntityPerm);
         //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);
         }
         $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']);
             }
             $arEvents = self::CompareFields($arRow, $arFields);
             foreach ($arEvents as $arEvent) {
                 $arEvent['ENTITY_TYPE'] = 'LEAD';
                 $arEvent['ENTITY_ID'] = $ID;
                 $arEvent['EVENT_TYPE'] = 1;
                 $CCrmEvent = new CCrmEvent();
                 $eventID = $CCrmEvent->Add($arEvent);
                 if (is_int($eventID) && $eventID > 0) {
                     $fieldID = isset($arEvent['ENTITY_FIELD']) ? $arEvent['ENTITY_FIELD'] : '';
                     if ($fieldID === '') {
                         continue;
                     }
                     switch ($fieldID) {
                         case 'STATUS_ID':
                             $sonetEventData[] = array('TYPE' => CCrmLiveFeedEvent::Progress, 'FIELDS' => array('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('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('TITLE' => GetMessage('CRM_LEAD_EVENT_UPDATE_TITLE'), 'MESSAGE' => '', 'PARAMS' => array('START_TITLE' => $arRow['TITLE'], 'FINAL_TITLE' => $arFields['TITLE'])));
                             break;
                     }
                 }
             }
         }
         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('');
             }
         }
         // Calculation of Account Data
         $accData = CCrmAccountingHelper::PrepareAccountingData(array('CURRENCY_ID' => isset($arFields['CURRENCY_ID']) ? $arFields['CURRENCY_ID'] : (isset($arRow['CURRENCY_ID']) ? $arRow['CURRENCY_ID'] : null), 'SUM' => isset($arFields['OPPORTUNITY']) ? $arFields['OPPORTUNITY'] : (isset($arRow['OPPORTUNITY']) ? $arRow['OPPORTUNITY'] : null), 'EXCH_RATE' => isset($arFields['EXCH_RATE']) ? $arFields['EXCH_RATE'] : (isset($arRow['EXCH_RATE']) ? $arRow['EXCH_RATE'] : null)));
         if (is_array($accData)) {
             $arFields['ACCOUNT_CURRENCY_ID'] = $accData['ACCOUNT_CURRENCY_ID'];
             $arFields['OPPORTUNITY_ACCOUNT'] = $accData['ACCOUNT_SUM'];
         }
         unset($arFields['ID']);
         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__ . '<br /> 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']));
         }
         $sUpdate = $DB->PrepareUpdate('b_crm_lead', $arFields, 'FILE: ' . __FILE__ . '<br /> LINE: ' . __LINE__);
         if (strlen($sUpdate) > 0) {
             $DB->Query("UPDATE b_crm_lead SET {$sUpdate} WHERE ID = {$ID}", false, 'FILE: ' . __FILE__ . '<br /> LINE: ' . __LINE__);
             if (isset($arFields['COMPANY_TITLE'])) {
                 $newCompanyTitle = $arFields['COMPANY_TITLE'];
                 $oldCompanyTitle = isset($arRow['COMPANY_TITLE']) ? $arRow['COMPANY_TITLE'] : '';
                 if ($newCompanyTitle !== $oldCompanyTitle) {
                     \Bitrix\Crm\Integrity\DuplicateOrganizationCriterion::register(CCrmOwnerType::Lead, $ID, $newCompanyTitle);
                 }
             }
             if (isset($arFields['LAST_NAME']) || isset($arFields['NAME']) || isset($arFields['SECOND_NAME'])) {
                 $lastName = isset($arFields['LAST_NAME']) ? $arFields['LAST_NAME'] : (isset($arRow['LAST_NAME']) ? $arRow['LAST_NAME'] : '');
                 $name = isset($arFields['NAME']) ? $arFields['NAME'] : (isset($arRow['NAME']) ? $arRow['NAME'] : '');
                 $secondName = isset($arFields['SECOND_NAME']) ? $arFields['SECOND_NAME'] : (isset($arRow['SECOND_NAME']) ? $arRow['SECOND_NAME'] : '');
                 \Bitrix\Crm\Integrity\DuplicatePersonCriterion::register(CCrmOwnerType::Lead, $ID, $lastName, $name, $secondName);
             }
             $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);
             }
         }
         CCrmPerms::UpdateEntityAttr('LEAD', $ID, $arEntityAttr);
         if (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'])) {
             \Bitrix\Crm\EntityAddress::register(CCrmOwnerType::Lead, $ID, \Bitrix\Crm\EntityAddress::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)));
         }
         CCrmEntityHelper::NormalizeUserFields($arFields, self::$sUFEntityID, $GLOBALS['USER_FIELD_MANAGER'], array('IS_NEW' => false));
         $GLOBALS['USER_FIELD_MANAGER']->Update(self::$sUFEntityID, $ID, $arFields);
         if (isset($arFields['FM']) && is_array($arFields['FM'])) {
             $CCrmFieldMulti = new CCrmFieldMulti();
             $CCrmFieldMulti->SetFields(CCrmOwnerType::LeadName, $ID, $arFields['FM']);
             $multifields = \Bitrix\Crm\Integrity\DuplicateCommunicationCriterion::prepareEntityMultifieldsValues(CCrmOwnerType::Lead, $ID);
             \Bitrix\Crm\Integrity\DuplicateCommunicationCriterion::register(CCrmOwnerType::Lead, $ID, 'EMAIL', \Bitrix\Crm\Integrity\DuplicateCommunicationCriterion::extractMultifieldsValues($multifields, 'EMAIL'));
             \Bitrix\Crm\Integrity\DuplicateCommunicationCriterion::register(CCrmOwnerType::Lead, $ID, 'PHONE', \Bitrix\Crm\Integrity\DuplicateCommunicationCriterion::extractMultifieldsValues($multifields, 'PHONE'));
         }
         \Bitrix\Crm\Integrity\DuplicateEntityRanking::registerEntityStatistics(CCrmOwnerType::Lead, $ID, array_merge($arRow, $arFields));
         if ($bUpdateSearch) {
             CCrmSearch::UpdateSearch(array('ID' => $ID, 'CHECK_PERMISSIONS' => 'N'), 'LEAD', true);
         }
         $arFields['ID'] = $ID;
         // Responsible user sync
         //CCrmActivity::Synchronize(CCrmOwnerType::Lead, $ID);
         // Sonet events registration
         $registerSonetEvent = isset($arOptions['REGISTER_SONET_EVENT']) && $arOptions['REGISTER_SONET_EVENT'] === true;
         if ($bResult && isset($arFields['ASSIGNED_BY_ID'])) {
             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']);
                 if ($logEventID && CModule::IncludeModule("im")) {
                     $url = CCrmOwnerType::GetShowUrl(CCrmOwnerType::Lead, $ID);
                     $serverName = (CMain::IsHTTPS() ? "https" : "http") . "://" . (defined("SITE_SERVER_NAME") && strlen(SITE_SERVER_NAME) > 0 ? 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_TAG" => "CRM|LEAD_RESPONSIBLE|" . $ID, "NOTIFY_MESSAGE" => GetMessage("CRM_LEAD_RESPONSIBLE_IM_NOTIFY", array("#title#" => "<a href=\"" . $url . "\" class=\"bx-notifier-item-action\">" . htmlspecialcharsbx($arFields['TITLE']) . "</a>")), "NOTIFY_MESSAGE_OUT" => GetMessage("CRM_LEAD_RESPONSIBLE_IM_NOTIFY", array("#title#" => htmlspecialcharsbx($arFields['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_TAG" => "CRM|LEAD_RESPONSIBLE|" . $ID, "NOTIFY_MESSAGE" => GetMessage("CRM_LEAD_NOT_RESPONSIBLE_IM_NOTIFY", array("#title#" => "<a href=\"" . $url . "\" class=\"bx-notifier-item-action\">" . htmlspecialcharsbx($arFields['TITLE']) . "</a>")), "NOTIFY_MESSAGE_OUT" => GetMessage("CRM_LEAD_NOT_RESPONSIBLE_IM_NOTIFY", array("#title#" => htmlspecialcharsbx($arFields['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_TAG" => "CRM|LEAD_PROGRESS|" . $ID, "NOTIFY_MESSAGE" => GetMessage("CRM_LEAD_PROGRESS_IM_NOTIFY", array("#title#" => "<a href=\"" . $url . "\" class=\"bx-notifier-item-action\">" . htmlspecialcharsbx($arFields['TITLE']) . "</a>", "#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", array("#title#" => htmlspecialcharsbx($arFields['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);
         }
         if ($bResult) {
             $afterEvents = GetModuleEvents('crm', 'OnAfterCrmLeadUpdate');
             while ($arEvent = $afterEvents->Fetch()) {
                 ExecuteModuleEventEx($arEvent, array(&$arFields));
             }
         }
     }
     return $bResult;
 }
예제 #2
0
 public function Update($ID, array &$arFields, $bCompare = true, $bUpdateSearch = true, $arOptions = array())
 {
     global $DB;
     $this->LAST_ERROR = '';
     $ID = (int) $ID;
     if (!is_array($arOptions)) {
         $arOptions = array();
     }
     $arFilterTmp = array('ID' => $ID);
     if (!$this->bCheckPermission) {
         $arFilterTmp['CHECK_PERMISSIONS'] = 'N';
     }
     $obRes = self::GetListEx(array(), $arFilterTmp);
     if (!($arRow = $obRes->Fetch())) {
         return false;
     }
     $iUserId = CCrmSecurityHelper::GetCurrentUserID();
     if (isset($arFields['DATE_CREATE'])) {
         unset($arFields['DATE_CREATE']);
     }
     if (isset($arFields['DATE_MODIFY'])) {
         unset($arFields['DATE_MODIFY']);
     }
     $arFields['~DATE_MODIFY'] = $DB->CurrentTimeFunction();
     if (!isset($arFields['MODIFY_BY_ID']) || $arFields['MODIFY_BY_ID'] <= 0) {
         $arFields['MODIFY_BY_ID'] = $iUserId;
     }
     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;
     if (!$this->CheckFields($arFields, $ID, $arOptions)) {
         $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;
         }
         $beforeEvents = GetModuleEvents('crm', 'OnBeforeCrmContactUpdate');
         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_CONTACT_UPDATE_CANCELED', array('#NAME#' => $arEvent['TO_NAME']));
                     $arFields['RESULT_MESSAGE'] =& $this->LAST_ERROR;
                 }
                 return false;
             }
         }
         $arAttr = array();
         $arAttr['OPENED'] = !empty($arFields['OPENED']) ? $arFields['OPENED'] : $arRow['OPENED'];
         $arEntityAttr = self::BuildEntityAttr($assignedByID, $arAttr);
         $sEntityPerm = $this->cPerms->GetPermType('CONTACT', 'WRITE', $arEntityAttr);
         $this->PrepareEntityAttrs($arEntityAttr, $sEntityPerm);
         //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['PHOTO']) && is_array($arFields['PHOTO']) && strlen(CFile::CheckImageFile($arFields['PHOTO'])) === 0) {
             $arFields['PHOTO']['MODULE_ID'] = 'crm';
             if ($arFields['PHOTO_del'] == 'Y' && !empty($arRow['PHOTO'])) {
                 CFile::Delete($arRow['PHOTO']);
             }
             CFile::SaveForDB($arFields, 'PHOTO', 'crm');
             if ($arFields['PHOTO_del'] == 'Y' && !isset($arFields['PHOTO'])) {
                 $arFields['PHOTO'] = '';
             }
         }
         if (isset($arFields['ASSIGNED_BY_ID']) && intval($arRow['ASSIGNED_BY_ID']) !== intval($arFields['ASSIGNED_BY_ID'])) {
             CcrmEvent::SetAssignedByElement($arFields['ASSIGNED_BY_ID'], 'CONTACT', $ID);
         }
         $sonetEventData = array();
         if ($bCompare) {
             $res = CCrmFieldMulti::GetList(array('ID' => 'asc'), array('ENTITY_ID' => 'CONTACT', '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']);
             }
             $arEvents = self::CompareFields($arRow, $arFields, $arOptions);
             foreach ($arEvents as $arEvent) {
                 $arEvent['ENTITY_TYPE'] = 'CONTACT';
                 $arEvent['ENTITY_ID'] = $ID;
                 $arEvent['EVENT_TYPE'] = 1;
                 if (!isset($arEvent['USER_ID'])) {
                     $arEvent['USER_ID'] = $iUserId;
                 }
                 $CCrmEvent = new CCrmEvent();
                 $eventID = $CCrmEvent->Add($arEvent, $this->bCheckPermission);
                 if (is_int($eventID) && $eventID > 0) {
                     $fieldID = isset($arEvent['ENTITY_FIELD']) ? $arEvent['ENTITY_FIELD'] : '';
                     if ($fieldID === '') {
                         continue;
                     }
                     switch ($fieldID) {
                         case 'ASSIGNED_BY_ID':
                             $sonetEventData[] = array('TYPE' => CCrmLiveFeedEvent::Responsible, 'FIELDS' => array('TITLE' => GetMessage('CRM_CONTACT_EVENT_UPDATE_ASSIGNED_BY'), 'MESSAGE' => '', 'PARAMS' => array('START_RESPONSIBLE_ID' => $arRow['ASSIGNED_BY_ID'], 'FINAL_RESPONSIBLE_ID' => $arFields['ASSIGNED_BY_ID'])));
                             break;
                         case 'COMPANY_ID':
                             $sonetEventData[] = array('CODE' => 'COMPANY', 'TYPE' => CCrmLiveFeedEvent::Owner, 'FIELDS' => array('TITLE' => GetMessage('CRM_CONTACT_EVENT_UPDATE_COMPANY'), 'MESSAGE' => '', 'PARAMS' => array('START_OWNER_COMPANY_ID' => $arRow['COMPANY_ID'], 'FINAL_OWNER_COMPANY_ID' => $arFields['COMPANY_ID'])));
                             break;
                     }
                 }
             }
         }
         $newName = isset($arFields['NAME']) ? $arFields['NAME'] : '';
         $oldName = isset($arRow['NAME']) ? $arRow['NAME'] : '';
         $newSecondName = isset($arFields['SECOND_NAME']) ? $arFields['SECOND_NAME'] : '';
         $oldSecondName = isset($arRow['SECOND_NAME']) ? $arRow['SECOND_NAME'] : '';
         $newLastName = isset($arFields['LAST_NAME']) ? $arFields['LAST_NAME'] : '';
         $oldLastName = isset($arRow['LAST_NAME']) ? $arRow['LAST_NAME'] : '';
         $newHonorific = isset($arFields['HONORIFIC']) ? $arFields['HONORIFIC'] : '';
         $oldHonorific = isset($arRow['HONORIFIC']) ? $arRow['HONORIFIC'] : '';
         if ($newName !== $oldName || $newSecondName !== $oldSecondName || $newLastName !== $oldLastName || $newHonorific !== $oldHonorific) {
             CCrmActivity::ResetEntityCommunicationSettings(CCrmOwnerType::Contact, $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('');
             }
         }
         if (isset($arFields['NAME']) && isset($arFields['LAST_NAME'])) {
             $arFields['FULL_NAME'] = self::GetFullName($arFields);
         } else {
             $dbRes = $DB->Query("SELECT NAME, LAST_NAME FROM b_crm_contact WHERE ID = {$ID}", false, 'FILE: ' . __FILE__ . '<br /> LINE: ' . __LINE__);
             $arRes = $dbRes->Fetch();
             if (isset($arFields['NAME'])) {
                 $arRes['NAME'] = $arFields['NAME'];
             }
             if (isset($arFields['LAST_NAME'])) {
                 $arRes['LAST_NAME'] = $arFields['LAST_NAME'];
             }
             $arFields['FULL_NAME'] = self::GetFullName($arRes);
         }
         if (isset($arFields['HAS_EMAIL'])) {
             unset($arFields['HAS_EMAIL']);
         }
         if (isset($arFields['HAS_PHONE'])) {
             unset($arFields['HAS_PHONE']);
         }
         unset($arFields['ID']);
         $sUpdate = $DB->PrepareUpdate('b_crm_contact', $arFields, 'FILE: ' . __FILE__ . '<br /> LINE: ' . __LINE__);
         if (strlen($sUpdate) > 0) {
             $bResult = true;
             $DB->Query("UPDATE b_crm_contact SET {$sUpdate} WHERE ID = {$ID}", false, 'FILE: ' . __FILE__ . '<br /> LINE: ' . __LINE__);
             if (isset($arFields['LAST_NAME']) || isset($arFields['NAME']) || isset($arFields['SECOND_NAME'])) {
                 $lastName = isset($arFields['LAST_NAME']) ? $arFields['LAST_NAME'] : (isset($arRow['LAST_NAME']) ? $arRow['LAST_NAME'] : '');
                 $name = isset($arFields['NAME']) ? $arFields['NAME'] : (isset($arRow['NAME']) ? $arRow['NAME'] : '');
                 $secondName = isset($arFields['SECOND_NAME']) ? $arFields['SECOND_NAME'] : (isset($arRow['SECOND_NAME']) ? $arRow['SECOND_NAME'] : '');
                 \Bitrix\Crm\Integrity\DuplicatePersonCriterion::register(CCrmOwnerType::Contact, $ID, $lastName, $name, $secondName);
             }
         }
         CCrmPerms::UpdateEntityAttr('CONTACT', $ID, $arEntityAttr);
         if (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'])) {
             \Bitrix\Crm\EntityAddress::register(CCrmOwnerType::Contact, $ID, \Bitrix\Crm\EntityAddress::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)));
         }
         CCrmEntityHelper::NormalizeUserFields($arFields, self::$sUFEntityID, $GLOBALS['USER_FIELD_MANAGER'], array('IS_NEW' => false));
         $GLOBALS['USER_FIELD_MANAGER']->Update(self::$sUFEntityID, $ID, $arFields);
         if (defined("BX_COMP_MANAGED_CACHE")) {
             static $arNameFields = array("NAME", "LAST_NAME", "SECOND_NAME");
             $bClear = false;
             foreach ($arNameFields as $val) {
                 if (isset($arFields[$val])) {
                     $bClear = true;
                     break;
                 }
             }
             if ($bClear) {
                 $GLOBALS["CACHE_MANAGER"]->ClearByTag("crm_entity_name_" . CCrmOwnerType::Contact . "_" . $ID);
             }
         }
         if (isset($arFields['FM']) && is_array($arFields['FM'])) {
             $CCrmFieldMulti = new CCrmFieldMulti();
             $CCrmFieldMulti->SetFields(CCrmOwnerType::ContactName, $ID, $arFields['FM']);
             $multifields = \Bitrix\Crm\Integrity\DuplicateCommunicationCriterion::prepareEntityMultifieldsValues(CCrmOwnerType::Contact, $ID);
             $emails = \Bitrix\Crm\Integrity\DuplicateCommunicationCriterion::extractMultifieldsValues($multifields, 'EMAIL');
             \Bitrix\Crm\Integrity\DuplicateCommunicationCriterion::register(CCrmOwnerType::Contact, $ID, 'EMAIL', $emails);
             $phones = \Bitrix\Crm\Integrity\DuplicateCommunicationCriterion::extractMultifieldsValues($multifields, 'PHONE');
             \Bitrix\Crm\Integrity\DuplicateCommunicationCriterion::register(CCrmOwnerType::Contact, $ID, 'PHONE', $phones);
             $hasEmail = empty($emails) ? 'N' : 'Y';
             $hasPhone = empty($phones) ? 'N' : 'Y';
             if ($hasEmail !== (isset($arRow['HAS_EMAIL']) ? $arRow['HAS_EMAIL'] : 'N') || $hasPhone !== (isset($arRow['HAS_PHONE']) ? $arRow['HAS_PHONE'] : 'N')) {
                 $DB->Query("UPDATE b_crm_contact SET HAS_EMAIL = '{$hasEmail}', HAS_PHONE = '{$hasPhone}' WHERE ID = {$ID}", false, 'FILE: ' . __FILE__ . '<br /> LINE: ' . __LINE__);
                 $arFields['HAS_EMAIL'] = $hasEmail;
                 $arFields['HAS_PHONE'] = $hasPhone;
             }
         }
         \Bitrix\Crm\Integrity\DuplicateEntityRanking::registerEntityStatistics(CCrmOwnerType::Contact, $ID, array_merge($arRow, $arFields));
         if ($bUpdateSearch) {
             CCrmSearch::UpdateSearch(array('ID' => $ID, 'CHECK_PERMISSIONS' => 'N'), 'CONTACT', true);
         }
         if (isset($GLOBALS["USER"]) && isset($arFields['COMPANY_ID']) && intval($arFields['COMPANY_ID']) > 0) {
             if (!class_exists('CUserOptions')) {
                 include_once $_SERVER['DOCUMENT_ROOT'] . "/bitrix/modules/main/classes/" . $GLOBALS['DBType'] . "/favorites.php";
             }
             CUserOptions::SetOption("crm", "crm_company_search", array('last_selected' => $arFields['COMPANY_ID']));
         }
         $arFields['ID'] = $ID;
         $newCompanyID = isset($arFields['COMPANY_ID']) ? intval($arFields['COMPANY_ID']) : 0;
         $oldCompanyID = isset($arRow['COMPANY_ID']) ? intval($arRow['COMPANY_ID']) : 0;
         $companyID = $newCompanyID > 0 ? $newCompanyID : $oldCompanyID;
         $registerSonetEvent = isset($arOptions['REGISTER_SONET_EVENT']) && $arOptions['REGISTER_SONET_EVENT'] === true;
         if ($bResult && isset($arFields['ASSIGNED_BY_ID'])) {
             CCrmSonetSubscription::ReplaceSubscriptionByEntity(CCrmOwnerType::Contact, $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) {
                 $sonetEventType = $sonetEvent['TYPE'];
                 $sonetEventCode = isset($sonetEvent['CODE']) ? $sonetEvent['CODE'] : '';
                 $sonetEventFields =& $sonetEvent['FIELDS'];
                 $sonetEventFields['ENTITY_TYPE_ID'] = CCrmOwnerType::Contact;
                 $sonetEventFields['ENTITY_ID'] = $ID;
                 $sonetEventFields['USER_ID'] = $modifiedByID;
                 //Register company relation
                 if ($sonetEventCode === 'COMPANY') {
                     //If company changed bind events to old and new companies
                     $sonetEventFields['PARENTS'] = array();
                     if ($oldCompanyID > 0) {
                         $sonetEventFields['PARENTS'][] = array('ENTITY_TYPE_ID' => CCrmOwnerType::Company, 'ENTITY_ID' => $oldCompanyID);
                     }
                     if ($newCompanyID > 0) {
                         $sonetEventFields['PARENTS'][] = array('ENTITY_TYPE_ID' => CCrmOwnerType::Company, 'ENTITY_ID' => $newCompanyID);
                     }
                 } elseif ($companyID > 0) {
                     $sonetEventFields['PARENT_ENTITY_TYPE_ID'] = CCrmOwnerType::Company;
                     $sonetEventFields['PARENT_ENTITY_ID'] = $companyID;
                 }
                 $logEventID = CCrmLiveFeed::CreateLogEvent($sonetEventFields, $sonetEventType);
                 if ($logEventID && $sonetEvent['TYPE'] == CCrmLiveFeedEvent::Responsible && CModule::IncludeModule("im")) {
                     $url = CCrmOwnerType::GetShowUrl(CCrmOwnerType::Contact, $ID);
                     $serverName = (CMain::IsHTTPS() ? "https" : "http") . "://" . (defined("SITE_SERVER_NAME") && strlen(SITE_SERVER_NAME) > 0 ? SITE_SERVER_NAME : COption::GetOptionString("main", "server_name", ""));
                     if ($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" => "contact_update", "NOTIFY_TAG" => "CRM|CONTACT_RESPONSIBLE|" . $ID, "NOTIFY_MESSAGE" => GetMessage("CRM_CONTACT_RESPONSIBLE_IM_NOTIFY", array("#title#" => "<a href=\"" . $url . "\" class=\"bx-notifier-item-action\">" . htmlspecialcharsbx($arFields['FULL_NAME']) . "</a>")), "NOTIFY_MESSAGE_OUT" => GetMessage("CRM_CONTACT_RESPONSIBLE_IM_NOTIFY", array("#title#" => htmlspecialcharsbx($arFields['FULL_NAME']))) . " (" . $serverName . $url . ")");
                         CIMNotify::Add($arMessageFields);
                     }
                     if ($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" => "contact_update", "NOTIFY_TAG" => "CRM|CONTACT_RESPONSIBLE|" . $ID, "NOTIFY_MESSAGE" => GetMessage("CRM_CONTACT_NOT_RESPONSIBLE_IM_NOTIFY", array("#title#" => "<a href=\"" . $url . "\" class=\"bx-notifier-item-action\">" . htmlspecialcharsbx($arFields['FULL_NAME']) . "</a>")), "NOTIFY_MESSAGE_OUT" => GetMessage("CRM_CONTACT_NOT_RESPONSIBLE_IM_NOTIFY", array("#title#" => htmlspecialcharsbx($arFields['FULL_NAME']))) . " (" . $serverName . $url . ")");
                         CIMNotify::Add($arMessageFields);
                     }
                 }
                 unset($sonetEventFields);
             }
             unset($sonetEvent);
         }
         if ($bResult) {
             $afterEvents = GetModuleEvents('crm', 'OnAfterCrmContactUpdate');
             while ($arEvent = $afterEvents->Fetch()) {
                 ExecuteModuleEventEx($arEvent, array(&$arFields));
             }
         }
     }
     return $bResult;
 }