entityManager = $entityManager; $this->reportService = $reportService; $this->entityType = $entityType; $this->reportHelper = $reportHelper; } /** * @param array|WhereItem|null $whereClause * @return array * @throws Forbidden * @throws Error */ public function getAssignmentAttributes( Entity $entity, string $targetTeamId, ?string $targetUserPosition, ?string $listReportId = null, $whereClause = null ): array { $team = $this->entityManager->getEntityById(Team::ENTITY_TYPE, $targetTeamId); if (!$team) { throw new Error("LeastBusy: No team $targetTeamId."); } $where = [ 'isActive' => true, ]; if ($targetUserPosition) { $where['@relation.role'] = $targetUserPosition; } $userList = $this->entityManager ->getRDBRepository(Team::ENTITY_TYPE) ->getRelation($team, 'users') ->select('id') ->order('userName') ->where($where) ->find(); if (is_countable($userList) && count($userList) === 0) { throw new Error("LeastBusy: No users in team $targetTeamId."); } $userIdList = []; foreach ($userList as $user) { $userIdList[] = $user->getId(); } $counts = []; foreach ($userIdList as $id) { $counts[$id] = 0; } $selectBuilder = SelectBuilder::create()->from($this->entityType); if ($listReportId) { /** @var ?Report $report */ $report = $this->entityManager->getEntityById(Report::ENTITY_TYPE, $listReportId); if (!$report) { throw new Error("No report $listReportId."); } $this->reportHelper->checkReportCanBeRun($report); $selectBuilder = $this->reportService->prepareSelectBuilder($report); } $selectBuilder ->where([ 'assignedUserId' => $userIdList, 'id!=' => $entity->hasId() ? $entity->getId() : null, ]) ->group('assignedUserId') ->select([ 'assignedUserId', ['COUNT:(id)', 'COUNT:id'], ]) ->order([]) ->order('assignedUserId') ->leftJoin('assignedUser', 'assignedUserAssignedRule') ->where(['assignedUserAssignedRule.isActive' => true]); if ($whereClause) { $selectBuilder->where($whereClause); } $sth = $this->entityManager ->getQueryExecutor() ->execute($selectBuilder->build()); $rowList = $sth->fetchAll(PDO::FETCH_ASSOC); foreach ($rowList as $row) { $id = $row['assignedUserId']; if (!$id) { continue; } $counts[$id] = $row['COUNT:id']; } $countValues = array_values($counts); if (!count($countValues)) { return []; } $minCount = min($countValues); $minCountIdList = []; foreach ($counts as $id => $count) { if ($count === $minCount) { $minCountIdList[] = $id; } } if (!count($minCountIdList)) { return []; } $attributes = []; $attributes['assignedUserId'] = $minCountIdList[array_rand($minCountIdList)]; /** @var ?User $user */ $user = $this->entityManager->getEntityById(User::ENTITY_TYPE, $attributes['assignedUserId']); if ($user) { $attributes['assignedUserName'] = $user->getName(); } return $attributes; } }