...Человеческий поиск в разработке...
- Модуль: crm
- Путь к файлу: ~/bitrix/modules/crm/lib/agent/duplicate/background/merge.php
- Класс: Bitrix\Crm\Agent\Duplicate\Background\Merge
- Вызов: Merge::onRunning
protected function onRunning(array $progressData): bool { if (!$this->checkStepInterval($progressData)) { return false; } $typeIds = $this->getTypeIds($progressData['TYPES']); if(empty($typeIds)) { return $this->setError($progressData, static::ERR_INDEX_TYPES); } if (!DuplicateIndexType::checkScopeValue($progressData['SCOPE'])) { return $this->setError($progressData, static::ERR_SCOPE); } $entityTypeId = $this->getEntityTypeId(); $scope = $progressData['SCOPE']; $userId = $this->getUserId(); $enablePermissionCheck = !Container::getInstance()->getUserPermissions($userId)->isAdmin(); $timeToMerge = (int)floor(static::STEP_TTL * static::STEP_INDEX_RATIO); $startTime = time(); $endTime = $startTime; $isFinal = false; $needNotify = false; $notifyPercentage = 0; while (!$isFinal && $endTime - $startTime <= $timeToMerge) { $list = new DuplicateList( DuplicateIndexType::joinType($typeIds), $this->getEntityTypeId(), $userId, $enablePermissionCheck ); $list->setScope($scope); $list->setStatusIDs([DuplicateStatus::PENDING]); $list->setSortTypeID( $entityTypeId === CCrmOwnerType::Company ? DuplicateIndexType::ORGANIZATION : DuplicateIndexType::PERSON ); $list->setSortOrder(SORT_ASC); $items = $list->getRootItems(0, 1); if(empty($items)) { $isFinal = true; $list->setStatusIDs([]); $progressData['TOTAL_ITEMS'] = $list->getRootItemCount(); $progressData['TOTAL_ENTITIES'] = DuplicateList::getTotalEntityCount( $userId, $entityTypeId, $typeIds, $scope ); $progressData['STATUS'] = static::STATUS_FINISHED; $progressData['TIMESTAMP_FINISH'] = time(); $progressData['TIMESTAMP'] = time(); if ($this->isNeedFullNotification($progressData)) { $notifyPercentage = static::PERCENT_FULL; $needNotify = true; } $this->setAgentResult(false); } else { $item = $items[0]; $rootEntityId = $item->getRootEntityID(); $criterion = $item->getCriterion(); $entityIds = $criterion->getEntityIDs( $entityTypeId, $rootEntityId, $userId, $enablePermissionCheck, ['limit' => 50] ); $entityIds = array_unique($entityIds); if(empty($entityIds)) { //Skip Junk item DuplicateIndexTable::deleteByFilter( array( 'USER_ID' => $userId, 'ENTITY_TYPE_ID' => $entityTypeId, 'TYPE_ID' => $criterion->getIndexTypeID(), 'MATCH_HASH' => $criterion->getMatchHash() ) ); } else { $isEntityMergerException = false; $merger = EntityMerger::create($entityTypeId, $userId, $enablePermissionCheck); $merger->setConflictResolutionMode(ConflictResolutionMode::ASK_USER); try { $merger->mergeBatch($entityIds, $rootEntityId, $criterion); } catch(EntityMergerException $e) { $isEntityMergerException = true; if($e->getCode() === EntityMergerException::CONFLICT_OCCURRED) { DuplicateIndexBuilder::setStatusID( $userId, $entityTypeId, $criterion->getIndexTypeID(), $criterion->getMatchHash(), $scope, DuplicateStatus::CONFLICT ); $progressData['CONFLICTED_ITEMS']++; } else { DuplicateIndexBuilder::setStatusID( $userId, $entityTypeId, $criterion->getIndexTypeID(), $criterion->getMatchHash(), $scope, DuplicateStatus::ERROR ); } } catch(Exception $e) { return $this->setError( $progressData, static::ERR_MERGE_UNHANDLED_EXCEPTION, ['MESSAGE' => $e->getMessage()] ); } $progressData['PROCESSED_ITEMS']++; // Recognize the need for progress notifications by 50% and 90%. if ($progressData['TIMESTAMP_START'] > 0 && $progressData['TOTAL_ITEMS'] > 0) { $percentage = (int)floor( static::PERCENT_FULL * $progressData['PROCESSED_ITEMS'] / $progressData['FOUND_ITEMS'] ); if ( $percentage >= static::PERCENT_HALF && $percentage < static::PERCENT_ALMOST && $progressData['TIMESTAMP_HALF'] === 0 ) { $progressData['TIMESTAMP_HALF'] = time(); if ($this->isNeedHalfNotification($progressData)) { $notifyPercentage = static::PERCENT_HALF; $needNotify = true; } } else if ($percentage >= static::PERCENT_ALMOST && $progressData['TIMESTAMP_ALMOST'] === 0) { $progressData['TIMESTAMP_ALMOST'] = time(); if ($this->isNeedAlmostNotification($progressData)) { $notifyPercentage = static::PERCENT_ALMOST; $needNotify = true; } } } if (!$isEntityMergerException) { $progressData['MERGED_ITEMS']++; } } } $currentProgressData = $this->getProgressData(); if ( isset($currentProgressData['TIMESTAMP']) && isset($currentProgressData['NEXT_STATUS']) && $currentProgressData['TIMESTAMP'] >= $progressData['TIMESTAMP'] && $currentProgressData['NEXT_STATUS'] !== static::STATUS_UNDEFINED && $currentProgressData['NEXT_STATUS'] !== $progressData['NEXT_STATUS'] ) { $progressData['NEXT_STATUS'] = $currentProgressData['NEXT_STATUS']; } $this->setProgressData($progressData); $endTime = time(); } // Progress notification, if needed. if ($needNotify) { $this->notifyPercentage($notifyPercentage); } return false; }