Example #1
0
 public function Update($ID, &$arFields, $bCompare = true, $bUpdateSearch = true, $options = array())
 {
     global $DB;
     $this->LAST_ERROR = '';
     $ID = (int) $ID;
     if (!is_array($options)) {
         $options = array();
     }
     $arFilterTmp = array('ID' => $ID);
     if (!$this->bCheckPermission) {
         $arFilterTmp['CHECK_PERMISSIONS'] = 'N';
     }
     $obRes = self::GetList(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']);
     }
     // number
     if (!isset($arFields['QUOTE_NUMBER']) || empty($arFields['QUOTE_NUMBER'])) {
         $arFields['QUOTE_NUMBER'] = isset($arRow['QUOTE_NUMBER']) ? $arRow['QUOTE_NUMBER'] : '';
         if (empty($arFields['QUOTE_NUMBER'])) {
             $arFields['QUOTE_NUMBER'] = strval($ID);
         }
     }
     // person type
     if (!isset($arFields['PERSON_TYPE_ID']) || intval($arFields['PERSON_TYPE_ID']) <= 0) {
         $companyId = isset($arFields['COMPANY_ID']) ? intval($arFields['COMPANY_ID']) : (isset($arRow['COMPANY_ID']) ? intval($arRow['COMPANY_ID']) : 0);
         $arFields['PERSON_TYPE_ID'] = intval($arRow['PERSON_TYPE_ID']);
         $arPersonTypes = CCrmPaySystem::getPersonTypeIDs();
         if (isset($arPersonTypes['CONTACT']) && isset($arPersonTypes['COMPANY'])) {
             if ($companyId <= 0) {
                 $arFields['PERSON_TYPE_ID'] = intval($arPersonTypes['CONTACT']);
             } else {
                 $arFields['PERSON_TYPE_ID'] = intval($arPersonTypes['COMPANY']);
             }
         }
         unset($companyId, $arPersonTypes);
     }
     // storage type id
     $storageTypeID = isset($arFields['STORAGE_TYPE_ID']) ? intval($arFields['STORAGE_TYPE_ID']) : CCrmQuoteStorageType::Undefined;
     if ($storageTypeID === CCrmQuoteStorageType::Undefined || !CCrmQuoteStorageType::IsDefined($storageTypeID)) {
         $storageTypeID = isset($arRow['STORAGE_TYPE_ID']) ? $arRow['STORAGE_TYPE_ID'] : CCrmQuoteStorageType::Undefined;
         if ($storageTypeID === CCrmQuoteStorageType::Undefined || !CCrmQuoteStorageType::IsDefined($storageTypeID)) {
             $storageTypeID = CCrmQuote::GetDefaultStorageTypeID();
         }
     }
     $arFields['STORAGE_TYPE_ID'] = $storageTypeID;
     // storage elements
     $storageElementIDs = isset($arFields['STORAGE_ELEMENT_IDS']) && is_array($arFields['STORAGE_ELEMENT_IDS']) ? $arFields['STORAGE_ELEMENT_IDS'] : null;
     $arFields['STORAGE_ELEMENT_IDS'] = null;
     if ($storageElementIDs !== null) {
         $storageElementIDs = self::NormalizeStorageElementIDs($storageElementIDs);
         $arFields['STORAGE_ELEMENT_IDS'] = serialize($storageElementIDs);
     }
     $assignedByID = (int) (isset($arFields['ASSIGNED_BY_ID']) ? $arFields['ASSIGNED_BY_ID'] : $arRow['ASSIGNED_BY_ID']);
     $bResult = false;
     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;
         }
         $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('QUOTE', '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'], 'QUOTE', $ID);
         }
         if ($bCompare) {
             $arEvents = self::CompareFields($arRow, $arFields, $this->bCheckPermission);
             foreach ($arEvents as $arEvent) {
                 $arEvent['ENTITY_TYPE'] = 'QUOTE';
                 $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);
             }
         }
         // 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'];
         }
         $accData = CCrmAccountingHelper::PrepareAccountingData(array('CURRENCY_ID' => isset($arFields['CURRENCY_ID']) ? $arFields['CURRENCY_ID'] : (isset($arRow['CURRENCY_ID']) ? $arRow['CURRENCY_ID'] : null), 'SUM' => isset($arFields['TAX_VALUE']) ? $arFields['TAX_VALUE'] : (isset($arRow['TAX_VALUE']) ? $arRow['TAX_VALUE'] : null), 'EXCH_RATE' => isset($arFields['EXCH_RATE']) ? $arFields['EXCH_RATE'] : (isset($arRow['EXCH_RATE']) ? $arRow['EXCH_RATE'] : null)));
         if (is_array($accData)) {
             $arFields['TAX_VALUE_ACCOUNT'] = $accData['ACCOUNT_SUM'];
         }
         if (isset($arFields['STATUS_ID'])) {
             $arFields['CLOSED'] = self::GetStatusSemantics($arFields['STATUS_ID']) === 'process' ? 'N' : 'Y';
         }
         if (isset($arFields['BEGINDATE']) && !isset($arFields['BEGINDATE'][0])) {
             unset($arFields['BEGINDATE']);
         }
         if (isset($arFields['CLOSED']) && $arFields['CLOSED'] === 'Y' && (!isset($arFields['CLOSEDATE']) || $arFields['CLOSEDATE'] === '')) {
             $arFields['CLOSEDATE'] = ConvertTimeStamp(time() + CTimeZone::GetOffset(), 'FULL', SITE_ID);
         }
         if (!isset($arFields['ID'])) {
             $arFields['ID'] = $ID;
         }
         foreach (GetModuleEvents('crm', 'OnBeforeCrmQuoteUpdate', true) as $arEvent) {
             if (ExecuteModuleEventEx($arEvent, array(&$arFields)) === false) {
                 if (isset($arFields['RESULT_MESSAGE'])) {
                     $this->LAST_ERROR = $arFields['RESULT_MESSAGE'];
                 } else {
                     $this->LAST_ERROR = GetMessage('CRM_QUOTE_UPDATE_CANCELED', array('#NAME#' => $arEvent['TO_NAME']));
                     $arFields['RESULT_MESSAGE'] =& $this->LAST_ERROR;
                 }
                 return false;
             }
         }
         unset($arFields['ID']);
         $sUpdate = $DB->PrepareUpdate('b_crm_quote', $arFields);
         if (strlen($sUpdate) > 0) {
             $clobFieldNames = array('COMMENTS', 'CONTENT', 'STORAGE_ELEMENT_IDS');
             $arBinds = array();
             foreach ($clobFieldNames as $fieldName) {
                 if (array_key_exists($fieldName, $arFields)) {
                     $arBinds[$fieldName] = $arFields[$fieldName];
                 }
             }
             unset($fieldName);
             $sql = "UPDATE b_crm_quote SET {$sUpdate} WHERE ID = {$ID}";
             if (!empty($arBinds)) {
                 $DB->QueryBind($sql, $arBinds, false);
             } else {
                 $DB->Query($sql, false, 'File: ' . __FILE__ . '<br>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::Quote . "_" . $ID);
             }
         }
         CCrmPerms::UpdateEntityAttr('QUOTE', $ID, $arEntityAttr);
         CCrmEntityHelper::NormalizeUserFields($arFields, self::$sUFEntityID, $GLOBALS['USER_FIELD_MANAGER'], array('IS_NEW' => false));
         $GLOBALS['USER_FIELD_MANAGER']->Update(self::$sUFEntityID, $ID, $arFields);
         if (is_array($storageElementIDs)) {
             CCrmQuote::DoSaveElementIDs($ID, $storageTypeID, $storageElementIDs);
         }
         unset($storageTypeID, $storageElementIDs);
         if ($bUpdateSearch) {
             $arFilterTmp = array('ID' => $ID);
             if (!$this->bCheckPermission) {
                 $arFilterTmp["CHECK_PERMISSIONS"] = "N";
             }
             CCrmSearch::UpdateSearch($arFilterTmp, 'QUOTE', true);
         }
         $arFields['ID'] = $ID;
         if (isset($arFields['FM']) && is_array($arFields['FM'])) {
             $CCrmFieldMulti = new CCrmFieldMulti();
             $CCrmFieldMulti->SetFields('QUOTE', $ID, $arFields['FM']);
         }
         // Responsible user sync
         //CCrmActivity::Synchronize(CCrmOwnerType::Quote, $ID);
         if ($bResult) {
             foreach (GetModuleEvents('crm', 'OnAfterCrmQuoteUpdate', true) as $arEvent) {
                 ExecuteModuleEventEx($arEvent, array(&$arFields));
             }
         }
     }
     return $bResult;
 }
Example #2
0
 public function Update($ID, array &$arFields, $bCompare = true, $bUpdateSearch = true, $options = array())
 {
     global $DB;
     $this->LAST_ERROR = '';
     $ID = (int) $ID;
     if (!is_array($options)) {
         $options = 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, $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;
         }
         $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;
             }
         }
         $arAttr = array();
         $arAttr['STAGE_ID'] = !empty($arFields['STAGE_ID']) ? $arFields['STAGE_ID'] : $arRow['STAGE_ID'];
         $arAttr['OPENED'] = !empty($arFields['OPENED']) ? $arFields['OPENED'] : $arRow['OPENED'];
         $arEntityAttr = self::BuildEntityAttr($assignedByID, $arAttr);
         $sEntityPerm = $this->cPerms->GetPermType('DEAL', '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'], 'DEAL', $ID);
         }
         $sonetEventData = array();
         if ($bCompare) {
             $arEvents = self::CompareFields($arRow, $arFields, $this->bCheckPermission);
             foreach ($arEvents as $arEvent) {
                 $arEvent['ENTITY_TYPE'] = 'DEAL';
                 $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 'STAGE_ID':
                             $sonetEventData[CCrmLiveFeedEvent::Progress] = array('TYPE' => CCrmLiveFeedEvent::Progress, 'FIELDS' => array('TITLE' => GetMessage('CRM_DEAL_EVENT_UPDATE_STAGE'), 'MESSAGE' => '', 'PARAMS' => array('START_STATUS_ID' => $arRow['STAGE_ID'], 'FINAL_STATUS_ID' => $arFields['STAGE_ID'])));
                             break;
                         case 'ASSIGNED_BY_ID':
                             $sonetEventData[CCrmLiveFeedEvent::Responsible] = array('TYPE' => CCrmLiveFeedEvent::Responsible, 'FIELDS' => array('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])) {
                                 $oldContactID = isset($arRow['CONTACT_ID']) ? intval($arRow['CONTACT_ID']) : 0;
                                 $oldCompanyID = isset($arRow['COMPANY_ID']) ? intval($arRow['COMPANY_ID']) : 0;
                                 $sonetEventData[CCrmLiveFeedEvent::Client] = array('CODE' => 'CLIENT', 'TYPE' => CCrmLiveFeedEvent::Client, 'FIELDS' => array('TITLE' => GetMessage('CRM_DEAL_EVENT_UPDATE_CLIENT'), 'MESSAGE' => '', 'PARAMS' => array('START_CLIENT_CONTACT_ID' => $oldContactID, 'FINAL_CLIENT_CONTACT_ID' => isset($arFields['CONTACT_ID']) ? intval($arFields['CONTACT_ID']) : $oldContactID, '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('TITLE' => GetMessage('CRM_DEAL_EVENT_UPDATE_TITLE'), 'MESSAGE' => '', 'PARAMS' => array('START_TITLE' => $arRow['TITLE'], 'FINAL_TITLE' => $arFields['TITLE'])));
                             break;
                     }
                 }
             }
             // CHECK IF COMPANY/CONTACT WAS ADDED/REMOVED
             if (!isset($sonetEventData[CCrmLiveFeedEvent::Client]) && (!isset($arRow['COMPANY_ID']) && isset($arFields['COMPANY_ID']) || isset($arRow['COMPANY_ID']) && !isset($arFields['COMPANY_ID']) || !isset($arRow['CONTACT_ID']) && isset($arFields['CONTACT_ID']) || isset($arRow['CONTACT_ID']) && !isset($arFields['CONTACT_ID']))) {
                 $sonetEventData[CCrmLiveFeedEvent::Client] = array('CODE' => 'CLIENT', 'TYPE' => CCrmLiveFeedEvent::Client, 'FIELDS' => array('TITLE' => GetMessage('CRM_DEAL_EVENT_UPDATE_CLIENT'), 'MESSAGE' => '', 'PARAMS' => array('START_CLIENT_CONTACT_ID' => isset($arRow['CONTACT_ID']) ? intval($arRow['CONTACT_ID']) : 0, 'FINAL_CLIENT_CONTACT_ID' => isset($arFields['CONTACT_ID']) ? intval($arFields['CONTACT_ID']) : 0, 'START_CLIENT_COMPANY_ID' => isset($arRow['COMPANY_ID']) ? intval($arRow['COMPANY_ID']) : 0, 'FINAL_CLIENT_COMPANY_ID' => isset($arFields['COMPANY_ID']) ? intval($arFields['COMPANY_ID']) : 0)));
             }
         }
         // 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'];
         }
         $accData = CCrmAccountingHelper::PrepareAccountingData(array('CURRENCY_ID' => isset($arFields['CURRENCY_ID']) ? $arFields['CURRENCY_ID'] : (isset($arRow['CURRENCY_ID']) ? $arRow['CURRENCY_ID'] : null), 'SUM' => isset($arFields['TAX_VALUE']) ? $arFields['TAX_VALUE'] : (isset($arRow['TAX_VALUE']) ? $arRow['TAX_VALUE'] : null), 'EXCH_RATE' => isset($arFields['EXCH_RATE']) ? $arFields['EXCH_RATE'] : (isset($arRow['EXCH_RATE']) ? $arRow['EXCH_RATE'] : null)));
         if (is_array($accData)) {
             $arFields['TAX_VALUE_ACCOUNT'] = $accData['ACCOUNT_SUM'];
         }
         $enableCloseDateSync = \Bitrix\Crm\Settings\DealSettings::isCloseDateSyncEnabled();
         if (isset($arFields['STAGE_ID'])) {
             $now = ConvertTimeStamp(time(), 'SHORT', SITE_ID);
             $isFinalStage = self::GetStageSemantics($arFields['STAGE_ID']) !== 'process';
             $isStageChanged = !isset($arRow['STAGE_ID']) || $arRow['STAGE_ID'] !== $arFields['STAGE_ID'];
             $arFields['CLOSED'] = $isFinalStage ? 'Y' : 'N';
             if ($enableCloseDateSync && $isFinalStage && $isStageChanged) {
                 $arFields['CLOSEDATE'] = $now;
                 $arFields['~CLOSEDATE'] = $DB->CharToDateFunction($now, 'SHORT', false);
             } elseif (isset($arFields['CLOSEDATE']) && $arFields['CLOSEDATE'] !== '') {
                 $arFields['~CLOSEDATE'] = $DB->CharToDateFunction($arFields['CLOSEDATE'], 'SHORT', false);
             }
         } elseif ($enableCloseDateSync && self::GetStageSemantics($arRow['STAGE_ID']) !== 'process' && isset($arFields['CLOSEDATE'])) {
             unset($arFields['CLOSEDATE']);
         }
         if (isset($arFields['BEGINDATE']) && $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']);
         $sUpdate = $DB->PrepareUpdate('b_crm_deal', $arFields);
         if (strlen($sUpdate) > 0) {
             $DB->Query("UPDATE b_crm_deal SET {$sUpdate} WHERE ID = {$ID}", false, 'FILE: ' . __FILE__ . '<br /> 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);
             }
         }
         CCrmPerms::UpdateEntityAttr('DEAL', $ID, $arEntityAttr);
         CCrmEntityHelper::NormalizeUserFields($arFields, self::$sUFEntityID, $GLOBALS['USER_FIELD_MANAGER'], array('IS_NEW' => false));
         $GLOBALS['USER_FIELD_MANAGER']->Update(self::$sUFEntityID, $ID, $arFields);
         //Statistics & History -->
         $currentDbResult = \CCrmDeal::GetListEx(array(), array('=ID' => $ID, 'CHECK_PERMISSIONS' => 'N'), false, false, array('*', 'UF_*'));
         $currentFields = $currentDbResult->Fetch();
         Bitrix\Crm\Statistics\DealSumStatisticEntry::register($ID, $currentFields);
         Bitrix\Crm\History\DealStageHistoryEntry::synchronize($ID, $currentFields);
         Bitrix\Crm\Statistics\DealInvoiceStatisticEntry::synchronize($ID, $currentFields);
         Bitrix\Crm\Statistics\DealActivityStatisticEntry::synchronize($ID, $currentFields);
         if (isset($arFields['STAGE_ID'])) {
             Bitrix\Crm\History\DealStageHistoryEntry::register($ID, $arFields, array('IS_NEW' => false));
         }
         //<-- Statistics & History
         if ($bUpdateSearch) {
             $arFilterTmp = array('ID' => $ID);
             if (!$this->bCheckPermission) {
                 $arFilterTmp['CHECK_PERMISSIONS'] = 'N';
             }
             CCrmSearch::UpdateSearch($arFilterTmp, 'DEAL', true);
         }
         $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'])) {
             CCrmSonetSubscription::ReplaceSubscriptionByEntity(CCrmOwnerType::Deal, $ID, CCrmSonetSubscriptionType::Responsibility, $arFields['ASSIGNED_BY_ID'], $arRow['ASSIGNED_BY_ID'], $registerSonetEvent);
         }
         if ($bResult && $bCompare && $registerSonetEvent && !empty($sonetEventData)) {
             //CONTACT
             $newContactID = isset($arFields['CONTACT_ID']) ? intval($arFields['CONTACT_ID']) : 0;
             $oldContactID = isset($arRow['CONTACT_ID']) ? intval($arRow['CONTACT_ID']) : 0;
             $contactID = $newContactID > 0 ? $newContactID : $oldContactID;
             //COMPANY
             $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;
             $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::Deal;
                 $sonetEventFields['ENTITY_ID'] = $ID;
                 $sonetEventFields['USER_ID'] = $modifiedByID;
                 //Register contact & company relations
                 if ($sonetEventCode === 'CLIENT') {
                     $sonetEventFields['PARENTS'] = array();
                     //If contact changed bind events to old and new contacts
                     if ($oldContactID !== $newContactID) {
                         if ($oldContactID > 0) {
                             $sonetEventFields['PARENTS'][] = array('ENTITY_TYPE_ID' => CCrmOwnerType::Contact, 'ENTITY_ID' => $oldContactID);
                         }
                         if ($newContactID > 0) {
                             $sonetEventFields['PARENTS'][] = array('ENTITY_TYPE_ID' => CCrmOwnerType::Contact, 'ENTITY_ID' => $newContactID);
                         }
                     }
                     //If company changed bind events to old and new companies
                     if ($oldCompanyID !== $newCompanyID) {
                         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 ($contactID > 0 || $companyID > 0) {
                     $sonetEventFields['PARENTS'] = array();
                     if ($contactID > 0) {
                         $sonetEventFields['PARENTS'][] = array('ENTITY_TYPE_ID' => CCrmOwnerType::Contact, 'ENTITY_ID' => $contactID);
                     }
                     if ($companyID > 0) {
                         $sonetEventFields['PARENTS'][] = array('ENTITY_TYPE_ID' => CCrmOwnerType::Company, 'ENTITY_ID' => $companyID);
                     }
                 }
                 $logEventID = CCrmLiveFeed::CreateLogEvent($sonetEventFields, $sonetEventType);
                 if ($logEventID && CModule::IncludeModule("im")) {
                     $url = CCrmOwnerType::GetShowUrl(CCrmOwnerType::Deal, $ID);
                     $serverName = (CMain::IsHTTPS() ? "https" : "http") . "://" . (defined("SITE_SERVER_NAME") && strlen(SITE_SERVER_NAME) > 0 ? 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_TAG" => "CRM|DEAL_RESPONSIBLE|" . $ID, "NOTIFY_MESSAGE" => GetMessage("CRM_DEAL_RESPONSIBLE_IM_NOTIFY", array("#title#" => "<a href=\"" . $url . "\" class=\"bx-notifier-item-action\">" . htmlspecialcharsbx($arFields['TITLE']) . "</a>")), "NOTIFY_MESSAGE_OUT" => GetMessage("CRM_DEAL_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" => "deal_update", "NOTIFY_TAG" => "CRM|DEAL_RESPONSIBLE|" . $ID, "NOTIFY_MESSAGE" => GetMessage("CRM_DEAL_NOT_RESPONSIBLE_IM_NOTIFY", array("#title#" => "<a href=\"" . $url . "\" class=\"bx-notifier-item-action\">" . htmlspecialcharsbx($arFields['TITLE']) . "</a>")), "NOTIFY_MESSAGE_OUT" => GetMessage("CRM_DEAL_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('DEAL_STAGE');
                         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" => "deal_update", "NOTIFY_TAG" => "CRM|DEAL_PROGRESS|" . $ID, "NOTIFY_MESSAGE" => GetMessage("CRM_DEAL_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_DEAL_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', 'OnAfterCrmDealUpdate');
             while ($arEvent = $afterEvents->Fetch()) {
                 ExecuteModuleEventEx($arEvent, array(&$arFields));
             }
         }
         self::PullChange('UPDATE', array('ID' => $ID));
     }
     return $bResult;
 }
Example #3
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;
 }
 /**
  * @return boolean
  */
 public static function synchronize($ownerID, array $entityFields = null)
 {
     if (!is_int($ownerID)) {
         $ownerID = (int) $ownerID;
     }
     if ($ownerID <= 0) {
         throw new Main\ArgumentException('Owner ID must be greater than zero.', 'ownerID');
     }
     if (!is_array($entityFields)) {
         $dbResult = \CCrmDeal::GetListEx(array(), array('=ID' => $ownerID, 'CHECK_PERMISSIONS' => 'N'), false, false, array('STAGE_ID', 'ASSIGNED_BY_ID', 'BEGINDATE', 'CLOSEDATE', 'OPPORTUNITY', 'CURRENCY_ID'));
         $entityFields = is_object($dbResult) ? $dbResult->Fetch() : null;
         if (!is_array($entityFields)) {
             return false;
         }
     }
     $stageID = isset($entityFields['STAGE_ID']) ? $entityFields['STAGE_ID'] : '';
     $semanticID = \CCrmDeal::GetSemanticID($stageID);
     $isLost = PhaseSemantics::isLost($semanticID);
     $responsibleID = isset($entityFields['ASSIGNED_BY_ID']) ? (int) $entityFields['ASSIGNED_BY_ID'] : 0;
     /** @var Date $startDate */
     $startDate = self::parseDateString(isset($entityFields['BEGINDATE']) ? $entityFields['BEGINDATE'] : '');
     if ($startDate === null) {
         $startDate = new Date();
     }
     /** @var Date $endDate */
     $endDate = self::parseDateString(isset($entityFields['CLOSEDATE']) ? $entityFields['CLOSEDATE'] : '');
     if ($endDate === null) {
         $endDate = new Date('9999-12-31', 'Y-m-d');
     }
     $sum = isset($entityFields['OPPORTUNITY']) ? (double) $entityFields['OPPORTUNITY'] : 0.0;
     $currencyID = isset($entityFields['CURRENCY_ID']) ? $entityFields['CURRENCY_ID'] : '';
     if ($currencyID === '') {
         $currencyID = \CCrmCurrency::GetBaseCurrencyID();
     }
     $accountCurrencyID = \CCrmCurrency::GetAccountCurrencyID();
     $sumData = \CCrmAccountingHelper::PrepareAccountingData(array('CURRENCY_ID' => $currencyID, 'SUM' => $sum));
     if (is_array($sumData)) {
         $sum = (double) $sumData['ACCOUNT_SUM'];
     }
     $latest = self::getLatest($ownerID);
     if (!is_array($latest)) {
         if ($semanticID === PhaseSemantics::SUCCESS) {
             //Creation of stub for successfully completed entity without invoices
             self::innerRegister(array('OWNER_ID' => $ownerID, 'CREATED_DATE' => new Date(), 'START_DATE' => $startDate, 'END_DATE' => $endDate, 'RESPONSIBLE_ID' => $responsibleID, 'STAGE_SEMANTIC_ID' => PhaseSemantics::SUCCESS, 'STAGE_ID' => $stageID, 'IS_LOST' => 'N', 'CURRENCY_ID' => $accountCurrencyID, 'INVOICE_SUM' => 0.0, 'INVOICE_QTY' => 0, 'TOTAL_INVOICE_SUM' => 0.0, 'TOTAL_INVOICE_QTY' => 0, 'TOTAL_SUM' => $sum));
         }
         return true;
     }
     if ($startDate->getTimestamp() === $latest['START_DATE']->getTimestamp() && $endDate->getTimestamp() === $latest['END_DATE']->getTimestamp() && $responsibleID === (int) $latest['RESPONSIBLE_ID'] && $stageID === $latest['STAGE_ID'] && $semanticID === $latest['STAGE_SEMANTIC_ID'] && $sum === (double) $latest['TOTAL_SUM']) {
         return false;
     }
     if ($semanticID !== $latest['STAGE_SEMANTIC_ID'] && $latest['STAGE_SEMANTIC_ID'] === PhaseSemantics::SUCCESS && (int) $latest['INVOICE_QTY'] === 0) {
         //Clean up stub for successfully completed entity without invoices
         DealInvoiceStatisticsTable::delete(array('OWNER_ID' => $ownerID, 'CREATED_DATE' => $latest['CREATED_DATE']));
     } else {
         DealInvoiceStatisticsTable::synchronize($ownerID, array('START_DATE' => $startDate, 'END_DATE' => $endDate, 'RESPONSIBLE_ID' => $responsibleID, 'STAGE_SEMANTIC_ID' => $semanticID, 'STAGE_ID' => $stageID, 'IS_LOST' => $isLost ? 'Y' : 'N', 'TOTAL_SUM' => $sum));
     }
     return true;
 }
Example #5
0
 public static function SaveRows($ownerType, $ownerID, $arRows, $accountContext = null, $checkPerms = true, $regEvent = true, $syncOwner = true, $totalInfo = array())
 {
     $ownerType = strval($ownerType);
     $ownerID = intval($ownerID);
     if (!isset($ownerType[0]) || $ownerID <= 0 || !is_array($arRows)) {
         self::RegisterError('Invalid arguments are supplied.');
         return false;
     }
     if (!is_array($totalInfo)) {
         $totalInfo = array();
     }
     $owner = null;
     if (!is_array($accountContext)) {
         if ($ownerType === 'D') {
             $owner = CCrmDeal::GetByID($ownerID, $checkPerms);
         } elseif ($ownerType === CCrmQuote::OWNER_TYPE) {
             $owner = CCrmQuote::GetByID($ownerID);
         } elseif ($ownerType === 'L') {
             $owner = CCrmLead::GetByID($ownerID);
         }
     }
     // Preparing accounting context -->
     if (!is_array($accountContext)) {
         $accountContext = array();
         if (is_array($owner)) {
             if (isset($owner['CURRENCY_ID'])) {
                 $accountContext['CURRENCY_ID'] = $owner['CURRENCY_ID'];
             }
             if (isset($owner['EXCH_RATE'])) {
                 $accountContext['EXCH_RATE'] = $owner['EXCH_RATE'];
             }
         }
     }
     $currencyID = isset($accountContext['CURRENCY_ID']) ? $accountContext['CURRENCY_ID'] : CCrmCurrency::GetBaseCurrencyID();
     $exchRate = isset($accountContext['EXCH_RATE']) ? $accountContext['EXCH_RATE'] : null;
     // <-- Preparing accounting context
     $productIDs = array();
     $products = array();
     foreach ($arRows as &$arRow) {
         $productID = isset($arRow['PRODUCT_ID']) ? intval($arRow['PRODUCT_ID']) : 0;
         if ($productID > 0 && !in_array($productID, $productIDs, true)) {
             $productIDs[] = $productID;
         }
     }
     unset($arRow);
     if (!empty($productIDs)) {
         $dbProduct = CCrmProduct::GetList(array(), array('ID' => $productIDs), array('ID', 'NAME'));
         if (is_object($dbProduct)) {
             while ($product = $dbProduct->Fetch()) {
                 $products[intval($product['ID'])] = $product;
             }
         }
     }
     $measurelessProductIDs = array();
     $arSafeRows = array();
     foreach ($arRows as &$arRow) {
         //$rowID = isset($arRow['ID']) ? intval($arRow['ID']) : 0;
         $productID = $arRow['PRODUCT_ID'] = isset($arRow['PRODUCT_ID']) ? intval($arRow['PRODUCT_ID']) : 0;
         $productName = $arRow['PRODUCT_NAME'] = isset($arRow['PRODUCT_NAME']) ? $arRow['PRODUCT_NAME'] : '';
         $arRow['PRICE'] = isset($arRow['PRICE']) ? round(doubleval($arRow['PRICE']), 2) : 0.0;
         $arRow['QUANTITY'] = isset($arRow['QUANTITY']) ? round(doubleval($arRow['QUANTITY']), 4) : 1;
         $arRow['TAX_RATE'] = isset($arRow['TAX_RATE']) ? round(doubleval($arRow['TAX_RATE']), 2) : 0.0;
         $arRow['TAX_INCLUDED'] = isset($arRow['TAX_INCLUDED']) ? $arRow['TAX_INCLUDED'] === 'Y' ? 'Y' : 'N' : 'N';
         $arRow['MEASURE_CODE'] = isset($arRow['MEASURE_CODE']) ? intval($arRow['MEASURE_CODE']) : 0;
         $arRow['MEASURE_NAME'] = isset($arRow['MEASURE_NAME']) ? $arRow['MEASURE_NAME'] : '';
         $arRow['CUSTOMIZED'] = isset($arRow['CUSTOMIZED']) && strtoupper($arRow['CUSTOMIZED']) === 'Y' ? 'Y' : 'N';
         $arRow['SORT'] = isset($arRow['SORT']) ? intval($arRow['SORT']) : 0;
         if ($productID > 0 && $productName !== '' && isset($products[$productID])) {
             //Skip save product name if it equal to original
             $product = $products[$productID];
             $originalProductName = isset($product['NAME']) ? trim($product['NAME']) : '';
             if ($productName === $originalProductName) {
                 $productName = '';
             }
         }
         $price = $arRow['PRICE'];
         $arRow['DISCOUNT_TYPE_ID'] = isset($arRow['DISCOUNT_TYPE_ID']) ? intval($arRow['DISCOUNT_TYPE_ID']) : 0;
         if (!\Bitrix\Crm\Discount::isDefined($arRow['DISCOUNT_TYPE_ID'])) {
             $arRow['DISCOUNT_TYPE_ID'] = \Bitrix\Crm\Discount::PERCENTAGE;
             $arRow['DISCOUNT_RATE'] = 0.0;
         }
         $discountTypeID = $arRow['DISCOUNT_TYPE_ID'];
         if ($discountTypeID === \Bitrix\Crm\Discount::PERCENTAGE) {
             if (!isset($arRow['DISCOUNT_RATE'])) {
                 self::RegisterError("Discount Rate (DISCOUNT_RATE) is required if Percentage Discount Type (DISCOUNT_TYPE_ID) is defined.");
                 return false;
             }
             $discountRate = round(doubleval($arRow['DISCOUNT_RATE']), 2);
             if (isset($arRow['DISCOUNT_SUM'])) {
                 $discountSum = round(doubleval($arRow['DISCOUNT_SUM']), 2);
             } else {
                 $exclusivePrice = self::CalculateExclusivePrice($price, $arRow['TAX_RATE']);
                 $discountSum = round(\Bitrix\Crm\Discount::calculateDiscountSum($exclusivePrice, $discountRate), 2);
             }
         } else {
             if (!isset($arRow['DISCOUNT_SUM'])) {
                 self::RegisterError("Discount Sum (DISCOUNT_SUM) is required if Monetary Discount Type (DISCOUNT_TYPE_ID) is defined.");
                 return false;
             }
             $discountSum = round(doubleval($arRow['DISCOUNT_SUM']), 2);
             if (isset($arRow['DISCOUNT_RATE'])) {
                 $discountRate = round(doubleval($arRow['DISCOUNT_RATE']), 2);
             } else {
                 $exclusivePrice = self::CalculateExclusivePrice($price, $arRow['TAX_RATE']);
                 $discountRate = \Bitrix\Crm\Discount::calculateDiscountRate($exclusivePrice + $discountSum, $exclusivePrice);
             }
         }
         $measureCode = $arRow['MEASURE_CODE'];
         if ($productID > 0 && $measureCode <= 0) {
             if (!in_array($productID, $measurelessProductIDs, true)) {
                 $measurelessProductIDs[] = $productID;
             }
         }
         $safeRow = array('OWNER_TYPE' => $ownerType, 'OWNER_ID' => $ownerID, 'PRODUCT_ID' => $productID, 'PRODUCT_NAME' => $productName, 'PRICE' => $price, 'QUANTITY' => $arRow['QUANTITY'], 'DISCOUNT_TYPE_ID' => $discountTypeID, 'DISCOUNT_SUM' => $discountSum, 'DISCOUNT_RATE' => $discountRate, 'TAX_RATE' => $arRow['TAX_RATE'], 'TAX_INCLUDED' => isset($arRow['TAX_INCLUDED']) ? $arRow['TAX_INCLUDED'] === 'Y' ? 'Y' : 'N' : 'N', 'MEASURE_CODE' => $measureCode, 'MEASURE_NAME' => $arRow['MEASURE_NAME'], 'CUSTOMIZED' => 'Y', 'SORT' => $arRow['SORT']);
         $accData = CCrmAccountingHelper::PrepareAccountingData(array('CURRENCY_ID' => $currencyID, 'SUM' => $safeRow['PRICE'], 'EXCH_RATE' => $exchRate));
         if (is_array($accData)) {
             $safeRow['PRICE_ACCOUNT'] = $accData['ACCOUNT_SUM'];
         }
         $arSafeRows[] =& $safeRow;
         unset($safeRow);
     }
     unset($arRow);
     if (!empty($measurelessProductIDs)) {
         $defaultMeasureInfo = \Bitrix\Crm\Measure::getDefaultMeasure();
         $measureInfos = \Bitrix\Crm\Measure::getProductMeasures($measurelessProductIDs);
         foreach ($arSafeRows as &$safeRow) {
             if ($safeRow['MEASURE_CODE'] > 0) {
                 continue;
             }
             $productID = $safeRow['PRODUCT_ID'];
             if (isset($measureInfos[$productID]) && !empty($measureInfos[$productID])) {
                 $measureInfo = $measureInfos[$productID][0];
                 $safeRow['MEASURE_CODE'] = $measureInfo['CODE'];
                 $safeRow['MEASURE_NAME'] = $measureInfo['SYMBOL'];
             } elseif ($defaultMeasureInfo !== null) {
                 $safeRow['MEASURE_CODE'] = $defaultMeasureInfo['CODE'];
                 $safeRow['MEASURE_NAME'] = $defaultMeasureInfo['SYMBOL'];
             }
         }
         unset($safeRow);
     }
     $arPresentRows = self::LoadRows($ownerType, $ownerID, true);
     // Registering events -->
     if ($regEvent) {
         $arRowIDs = array();
         foreach ($arRows as &$arRow) {
             if (isset($arRow['ID'])) {
                 $arRowIDs[] = intval($arRow['ID']);
             }
             $rowID = isset($arRow['ID']) ? intval($arRow['ID']) : 0;
             if ($rowID <= 0) {
                 // Row was added
                 self::RegisterAddEvent($ownerType, $ownerID, $arRow, $checkPerms);
                 continue;
             }
             $arPresentRow = isset($arPresentRows[$rowID]) ? $arPresentRows[$rowID] : null;
             if ($arPresentRow) {
                 // Row was modified
                 self::RegisterUpdateEvent($ownerType, $ownerID, $arRow, $arPresentRow, $checkPerms);
             }
         }
         unset($arRow);
         foreach ($arPresentRows as $rowID => &$arPresentRow) {
             if (!in_array($rowID, $arRowIDs, true)) {
                 // Product  was removed
                 self::RegisterRemoveEvent($ownerType, $ownerID, $arPresentRow, $checkPerms);
             }
         }
     }
     // <-- Registering events
     $result = CCrmProductRow::DoSaveRows($ownerType, $ownerID, $arSafeRows);
     // Update list of taxes
     if (!isset($totalInfo['CURRENCY_ID'])) {
         $totalInfo['CURRENCY_ID'] = $currencyID;
     }
     self::UpdateTotalInfo($ownerType, $ownerID, $totalInfo);
     // Disable sum synchronization if product rows are empty
     if ($result && $syncOwner && (count($arPresentRows) > 0 || count($arSafeRows) > 0)) {
         self::SynchronizeOwner($ownerType, $ownerID, $checkPerms, $totalInfo);
     }
     return $result;
 }
 /**
  * @return void
  */
 public static function register($ownerID, array $entityFields = null)
 {
     if (!is_int($ownerID)) {
         $ownerID = (int) $ownerID;
     }
     if ($ownerID <= 0) {
         throw new Main\ArgumentException('Owner ID must be greater than zero.', 'ownerID');
     }
     if (!is_array($entityFields)) {
         $dbResult = \CCrmDeal::GetListEx(array(), array('=ID' => $ownerID, 'CHECK_PERMISSIONS' => 'N'), false, false, array('STAGE_ID', 'ASSIGNED_BY_ID', 'BEGINDATE', 'CLOSEDATE', 'CURRENCY_ID', 'OPPORTUNITY', 'UF_*'));
         $entityFields = is_object($dbResult) ? $dbResult->Fetch() : null;
         if (!is_array($entityFields)) {
             return;
         }
     }
     $bindingMap = self::getSlotBindingMap();
     $stageID = isset($entityFields['STAGE_ID']) ? $entityFields['STAGE_ID'] : '';
     $semanticID = \CCrmDeal::GetSemanticID($stageID);
     $isLost = PhaseSemantics::isLost($semanticID);
     $isFinalized = PhaseSemantics::isFinal($semanticID);
     $responsibleID = isset($entityFields['ASSIGNED_BY_ID']) ? (int) $entityFields['ASSIGNED_BY_ID'] : 0;
     /** @var Date $startDate */
     $startDate = self::parseDateString(isset($entityFields['BEGINDATE']) ? $entityFields['BEGINDATE'] : '');
     if ($startDate === null || $startDate->getTimestamp() === false) {
         $startDate = isset($entityFields['DATE_CREATE']) ? self::parseDateString($entityFields['DATE_CREATE']) : null;
         if ($startDate === null || $startDate->getTimestamp() === false) {
             $startDate = new Date();
         }
     }
     /** @var Date $endDate */
     $endDate = self::parseDateString(isset($entityFields['CLOSEDATE']) ? $entityFields['CLOSEDATE'] : '');
     if ($endDate === null || $endDate->getTimestamp() === false) {
         $endDate = new Date('9999-12-31', 'Y-m-d');
     }
     $date = $isFinalized ? $endDate : $startDate;
     $day = (int) $date->format('d');
     $month = (int) $date->format('m');
     $quarter = $month <= 3 ? 1 : ($month <= 6 ? 2 : ($month <= 9 ? 3 : 4));
     $year = (int) $date->format('Y');
     $currencyID = isset($entityFields['CURRENCY_ID']) ? $entityFields['CURRENCY_ID'] : '';
     $accountingCurrencyID = \CCrmCurrency::GetAccountCurrencyID();
     $sum = isset($entityFields['OPPORTUNITY']) ? (double) $entityFields['OPPORTUNITY'] : 0.0;
     $binding = $bindingMap->get('SUM_TOTAL');
     if ($binding === null) {
         $total = isset($entityFields['OPPORTUNITY']) ? (double) $entityFields['OPPORTUNITY'] : 0.0;
     } else {
         $bindingFieldName = $binding->getFieldName();
         if ($bindingFieldName === '') {
             $bindingFieldName = 'OPPORTUNITY';
         }
         $total = isset($entityFields[$bindingFieldName]) ? (double) $entityFields[$bindingFieldName] : 0.0;
         if ($bindingFieldName !== 'OPPORTUNITY' && $binding->getOption('ADD_PRODUCT_ROW_SUM') === 'Y') {
             $total += $sum;
         }
     }
     if ($currencyID !== $accountingCurrencyID) {
         $accData = \CCrmAccountingHelper::PrepareAccountingData(array('CURRENCY_ID' => $currencyID, 'SUM' => $total, 'EXCH_RATE' => isset($entityFields['EXCH_RATE']) ? $entityFields['EXCH_RATE'] : null));
         if (is_array($accData)) {
             $total = (double) $accData['ACCOUNT_SUM'];
         }
     }
     $sumSlots = array();
     $sumSlotFields = DealSumStatisticsTable::getSumSlotFieldNames();
     foreach ($sumSlotFields as $fieldName) {
         $binding = $bindingMap->get($fieldName);
         if ($binding === null) {
             $slotSum = 0.0;
         } else {
             $bindingFieldName = $binding->getFieldName();
             $slotSum = $bindingFieldName !== '' && isset($entityFields[$bindingFieldName]) ? (double) $entityFields[$bindingFieldName] : 0.0;
             if ($binding->getOption('ADD_PRODUCT_ROW_SUM') === 'Y') {
                 $slotSum += $sum;
             }
         }
         if ($currencyID !== $accountingCurrencyID) {
             $accData = \CCrmAccountingHelper::PrepareAccountingData(array('CURRENCY_ID' => $currencyID, 'SUM' => $slotSum, 'EXCH_RATE' => isset($entityFields['EXCH_RATE']) ? $entityFields['EXCH_RATE'] : null));
             if (is_array($accData)) {
                 $slotSum = (double) $accData['ACCOUNT_SUM'];
             }
         }
         $sumSlots[$fieldName] = $slotSum;
     }
     $entities = self::getAll($ownerID);
     $final = null;
     $process = null;
     foreach ($entities as $entity) {
         if (PhaseSemantics::isFinal($entity['STAGE_SEMANTIC_ID'])) {
             $final = $entity;
         } else {
             $process = $entity;
         }
         if ($final && $process) {
             break;
         }
     }
     $latest = self::getLatest($ownerID);
     if (is_array($latest) && isset($latest['START_DATE']) && isset($latest['END_DATE'])) {
         if ($startDate->getTimestamp() === $latest['START_DATE']->getTimestamp() && $endDate->getTimestamp() === $latest['END_DATE']->getTimestamp() && $responsibleID === (int) $latest['RESPONSIBLE_ID'] && $stageID === $latest['STAGE_ID'] && $currencyID === $latest['CURRENCY_ID'] && $total === (double) $latest['SUM_TOTAL'] && $sumSlots['UF_SUM_1'] === (double) $latest['UF_SUM_1'] && $sumSlots['UF_SUM_2'] === (double) $latest['UF_SUM_2'] && $sumSlots['UF_SUM_3'] === (double) $latest['UF_SUM_3'] && $sumSlots['UF_SUM_4'] === (double) $latest['UF_SUM_4'] && $sumSlots['UF_SUM_5'] === (double) $latest['UF_SUM_5']) {
             return;
         }
         if ($startDate->getTimestamp() !== $latest['START_DATE']->getTimestamp() || $endDate->getTimestamp() !== $latest['END_DATE']->getTimestamp() || $responsibleID !== (int) $latest['RESPONSIBLE_ID']) {
             if (!$isFinalized) {
                 DealSumStatisticsTable::deleteByFilter(array('OWNER_ID' => $ownerID, 'SEMANTIC_ID' => PhaseSemantics::getFinalSemantis()));
                 DealSumStatisticsTable::synchronize($ownerID, array('CREATED_DATE' => $startDate, 'START_DATE' => $startDate, 'END_DATE' => $endDate, 'RESPONSIBLE_ID' => $responsibleID), PhaseSemantics::getProcessSemantis());
             } else {
                 if ($startDate->getTimestamp() === $endDate->getTimestamp()) {
                     DealSumStatisticsTable::deleteByFilter(array('OWNER_ID' => $ownerID, 'SEMANTIC_ID' => PhaseSemantics::getProcessSemantis()));
                     DealSumStatisticsTable::synchronize($ownerID, array('CREATED_DATE' => $endDate, 'START_DATE' => $startDate, 'END_DATE' => $endDate, 'RESPONSIBLE_ID' => $responsibleID), PhaseSemantics::getFinalSemantis());
                 } else {
                     //Diphasic update of "final" semantics (first update with forged date: "1970-01-01") for avoid possible primary key conflict with "process" semantics
                     DealSumStatisticsTable::synchronize($ownerID, array('CREATED_DATE' => new Date('1970-01-01', 'Y-m-d'), 'START_DATE' => $startDate, 'END_DATE' => $endDate, 'RESPONSIBLE_ID' => $responsibleID), PhaseSemantics::getFinalSemantis());
                     DealSumStatisticsTable::synchronize($ownerID, array('CREATED_DATE' => $startDate, 'START_DATE' => $startDate, 'END_DATE' => $endDate, 'RESPONSIBLE_ID' => $responsibleID), PhaseSemantics::getProcessSemantis());
                     DealSumStatisticsTable::synchronize($ownerID, array('CREATED_DATE' => $endDate, 'START_DATE' => $startDate, 'END_DATE' => $endDate, 'RESPONSIBLE_ID' => $responsibleID), PhaseSemantics::getFinalSemantis());
                 }
             }
         }
     }
     $data = array_merge(array('OWNER_ID' => $ownerID, 'CREATED_DATE' => $date, 'START_DATE' => $startDate, 'END_DATE' => $endDate, 'PERIOD_YEAR' => $year, 'PERIOD_QUARTER' => $quarter, 'PERIOD_MONTH' => $month, 'PERIOD_DAY' => $day, 'RESPONSIBLE_ID' => $responsibleID, 'STAGE_SEMANTIC_ID' => $semanticID, 'STAGE_ID' => $stageID, 'IS_LOST' => $isLost ? 'Y' : 'N', 'CURRENCY_ID' => $accountingCurrencyID, 'SUM_TOTAL' => $total), $sumSlots);
     DealSumStatisticsTable::upsert($data);
 }