Commit 2a9591c3 authored by Stephane Bouvry's avatar Stephane Bouvry
Browse files

Recherche avancées OK

 - Testé pour le profil Gestionnaire
 - Tri à affiner (en mode projet)
 - Filtres (fait, mais à revérifier)
 - Vue GANT KO
 - Export OK
parent 9f2c5922
Loading
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -451,6 +451,7 @@ class ProjectController extends AbstractOscarController

    public function currentUserStructureProjectsAction(): array
    {
        die("ICI");
        /** @var Person|null $currentPerson */
        $currentPerson = $this->getOscarUserContextService()->getCurrentPerson();

+4 −732

File changed.

Preview size limit exceeded, changes collapsed.

+68 −34
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ namespace Oscar\Entity;
use \DateTime;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;
use Exception;
use Oscar\Exception\OscarException;
use Oscar\Utils\DateTimeUtils;

@@ -387,9 +388,8 @@ class ActivityRepository extends EntityRepository
    public function getActivityByNumOscar($numOscar, $throw = false)
    {
        try {
            $activity = $this->findOneBy(['oscarNum' => $numOscar]);
            return $activity;
        } catch (\Exception $exception) {
            return $this->findOneBy(['oscarNum' => $numOscar]);
        } catch (Exception $exception) {
            $error = "Impossible de charger l'activité $numOscar : " . $exception->getMessage();
            if ($throw) {
                throw new OscarException($error);
@@ -401,13 +401,12 @@ class ActivityRepository extends EntityRepository
    }

    /**
     * @return \Doctrine\ORM\QueryBuilder
     * @return QueryBuilder
     */
    protected function qbActivityWithWorkPackage()
    protected function qbActivityWithWorkPackage(): QueryBuilder
    {
        $qb = $this->createQueryBuilder('a')
        return $this->createQueryBuilder('a')
            ->innerJoin('a.workPackages', 'wp');
        return $qb;
    }

    /**
@@ -424,18 +423,6 @@ class ActivityRepository extends EntityRepository
    {
        return $this->createQueryBuilder('c')
            ->leftJoin('c.project', 'p');
//            ->leftJoin('c.persons', 'm1')
//            ->leftJoin('m1.person', 'pers1')
//            ->leftJoin('c.disciplines', 'dis')
//            ->leftJoin('c.activityType', 't1')
//            ->leftJoin('c.organizations', 'p1')
//            ->leftJoin('p1.organization', 'orga1')
//            ->leftJoin('c.documents', 'd1')
//            ->leftJoin('c.project', 'pr')
//            ->leftJoin('pr.members', 'm2')
//            ->leftJoin('pr.partners', 'p2')
//            ->leftJoin('m2.person', 'pers2')
//            ->leftJoin('p2.organization', 'orga2');
    }

    public function getBaseQueryBuilderByIdsPaged(array $ids, int $page = 1, int $resultByPage = 50): QueryBuilder
@@ -910,22 +897,28 @@ class ActivityRepository extends EntityRepository
     * @param array|null $ids
     * @return array
     */
    public function getIdsProjectsForActivity(?array $ids): array
    public function getIdsProjectsForActivity(?array $ids, string $orderBy = "", string $direction = 'desc'): array
    {
        if ($ids) {
            $qb = $this->getEntityManager()->createQueryBuilder()
                ->select('DISTINCT p.id')
                ->select('DISTINCT p.id, 
                    MIN(a.dateCreated) as dateCreated, 
                    MAX(a.dateUpdated) as dateUpdated,
                    MAX(a.dateEnd) as dateEnd')
                ->from(Project::class, 'p')
                ->innerJoin('p.grants', 'a')
                ->where('a.id IN(:ids)')
                ->groupBy('p.id')
                ->setParameter('ids', $ids);

            return array_map(
                'current',
                $qb
                    ->getQuery()
                    ->getResult()
            );
            $orderable = ['dateCreated', 'dateUpdated', 'dateEnd'];
            if ($orderBy && in_array($orderBy, $orderable)) {
                $qb->orderBy($orderBy, $direction);
            }

            $results = $qb->getQuery()->getResult();

            return array_map('current', $results);
        }
        else {
            return [];
@@ -1021,12 +1014,12 @@ class ActivityRepository extends EntityRepository
     * @param mixed $value1
     * @param mixed $value2
     * @return integer[]
     * @throws \Exception
     * @throws Exception
     */
    public function getIdsByDate(string $field, mixed $value1, mixed $value2): array
    {
        if (!$value1 && !$value2) {
            throw new \Exception("Aucune date à filtrer");
            throw new Exception("Aucune date à filtrer");
        }
        $q = $this->createQueryBuilder('c')
            ->select('c.id');
@@ -1049,18 +1042,25 @@ class ActivityRepository extends EntityRepository
        return array_map('current', $activities);
    }

    public function getIdsFinancialImpact(mixed $value1, bool $inversed = false): array
    /**
     * Retourne les IDS des activités en fonction de l'impact financier.
     * @param mixed $indexImpact Index dans la liste des impacts possibles
     * @param bool $inverse
     * @return array
     * @throws Exception
     */
    public function getIdsFinancialImpact(mixed $indexImpact, bool $inverse = false): array
    {
        if (!array_key_exists($value1, Activity::getFinancialImpactValues())) {
            throw new \Exception("Ce type d'incidence financière n'existe pas");
        if (!array_key_exists($indexImpact, Activity::getFinancialImpactValues())) {
            throw new Exception("Ce type d'incidence financière n'existe pas");
        }

        $param = Activity::getFinancialImpactValues()[$value1];
        $param = Activity::getFinancialImpactValues()[$indexImpact];

        $q = $this->createQueryBuilder('c')
            ->select('c.id');

        if ($inversed) {
        if ($inverse) {
            $q->andWhere('c.financialImpact != :param');
        }
        else {
@@ -1071,4 +1071,38 @@ class ActivityRepository extends EntityRepository

        return array_map('current', $q->getQuery()->getResult());
    }

    /**
     * Retourne les IDS des activités sans projet.
     * @return integer[]
     */
    public function getIdsWithoutProject(): array
    {
        $qb = $this->createQueryBuilder('c')
            ->select('c.id')
            ->leftJoin('c.project', 'p')
            ->where('c.project IS NULL');;
        return array_map('current', $qb->getQuery()->getResult());
    }

    /**
     * Retourne les IDS des activités d'un des types.
     * @param array $types
     * @param bool $inverse
     * @return array
     */
    public function getIdsWithTypes(array $types, bool $inverse = false): array
    {
        $qb = $this->createQueryBuilder('c')
            ->select('c.id')
            ->leftJoin('c.activityType', 't');

        if ($inverse === false) {
            $qb->where('c.activityType IN(:types)');
        }
        else {
            $qb->where('c.activityType NOT IN (:types)');;
        }
        return array_map('current', $qb->setParameter('types', $types)->getQuery()->getResult());
    }
}
 No newline at end of file
+102 −112
Original line number Diff line number Diff line
@@ -189,22 +189,14 @@ class ProjectGrantSearchService implements UseEntityManager, UsePersonService, U
        $params['include'] = $request->getQuery('include', null);

        // Champ de tri
        $params[self::QUERY_PARAM_SORT] = $this->extractValueInArrayKey(
            $request->getQuery(self::QUERY_PARAM_SORT),
            $this->getSortOptions(),
            $search ? self::SORT_HIT : self::SORT_DATE_UPDATED
        );
        $params[self::QUERY_PARAM_SORT] = $request->getQuery(self::QUERY_PARAM_SORT);

        // Ignorer les valeurs nulles
        $params[self::QUERY_PARAM_SORT_IGNORE_NULL] =
            (bool)$request->getQuery(self::QUERY_PARAM_SORT_IGNORE_NULL, false);

        // Sens du tri
        $params[self::QUERY_PARAM_SORT_DIRECTION] = $this->extractValueInArrayKey(
            $request->getQuery(self::QUERY_PARAM_SORT_DIRECTION),
            $this->getSortDirections(),
            self::SORT_DIRECTION_DESC
        );
        $params[self::QUERY_PARAM_SORT_DIRECTION] = $request->getQuery(self::QUERY_PARAM_SORT_DIRECTION);

        // Mode PROJET
        $params[self::QUERY_PARAM_PROJECTVIEW] =
@@ -235,6 +227,11 @@ class ProjectGrantSearchService implements UseEntityManager, UsePersonService, U
            ];

            switch ($type) {
                case 'pp' :
                    $crit['val1'] = '';
                    $crit['val2'] = '';
                    break;

                case 'mp':
                    if (!$value1 && !$value2) {
                        $filtersError = true;
@@ -388,9 +385,36 @@ class ProjectGrantSearchService implements UseEntityManager, UsePersonService, U

        // --- Périmètre (Organization)
        if ($organizationsPerimeter !== null) {
            die("Calculer le périmètre organisation");
            // TODO IDs des activités réservées
            // TODO IDs des projets réservés
            $include = $params['include'];
            if ($include) {
                $includeClear = [];
                foreach ($include as $index => $value) {
                    if ($value > 0) {
                        $includeClear[] = intval($value);
                    }
                }
                $include = array_intersect(
                    $includeClear,
                    $organizationsPerimeter
                );
            }
            else {
                $include = $params['organizationsPerimeter'];
            }

            // IDS concernés
            $organizationsIdsPerimeter = $this->getProjectGrantService()
                ->getActivityRepository()
                ->getIdsWithOrganizations($include);

            // FIX
            if (count($organizationsIdsPerimeter) == 0) {
                $organizationsIdsPerimeter = [0];
                $activitiesIds = [];
            }
            else {
                $activitiesIds = $organizationsIdsPerimeter;
            }
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -749,13 +773,13 @@ class ProjectGrantSearchService implements UseEntityManager, UsePersonService, U
                        }
                        break;

                    ///////////////////////////////// ACTIVITE / FEUILLE de TEMPS
                    ///////////////////////////////// ACTIVITY / FEUILLE de TEMPS
                    case 'fdt' :
                        $filteredIds = $this->getProjectGrantService()
                            ->getActivityRepository()->getActivityIdsWithWorkpackage();
                        break;

                    ///////////////////////////////// ACTIVITE / DATES
                    ///////////////////////////////// ACTIVITY / DATES
                    case 'add' :
                    case 'adf' :
                    case 'adm' :
@@ -777,7 +801,7 @@ class ProjectGrantSearchService implements UseEntityManager, UsePersonService, U
                        break;


                    ///////////////////////////////// ACTIVITE / NUMEROTATION
                    ///////////////////////////////// ACTIVITY / NUMERATION
                    case 'num' :
                        try {
                            $filteredIds = $this->getProjectGrantService()->getActivityRepository(
@@ -788,7 +812,7 @@ class ProjectGrantSearchService implements UseEntityManager, UsePersonService, U
                        }
                        break;

                    ///////////////////////////////// ACTIVITE / INCIDENCE FINANCIERE
                    ///////////////////////////////// ACTIVITY / INCIDENCE FINANCIERS
                    case 'af' :
                    case 'sf' :
                        try {
@@ -796,13 +820,12 @@ class ProjectGrantSearchService implements UseEntityManager, UsePersonService, U
                            )->getIdsFinancialImpact($value1, $type == 'sf');
                        } catch (Exception $exception) {
                            $this->getLoggerService()->warning($exception->getMessage());
                            $filter['error'] = "Un problème est survenu en filtrant sur l'incidence financiere'";
                            $filter['error'] = "Un problème est survenu en filtrant sur l'incidence financière'";
                        }
                        break;

                    ///////////////////////////////// ACTIVITE / COMPTE
                    ///////////////////////////////// ACTIVITY / COMPTE
                    case 'cb':

                        try {
                            $accountsInfos = $this->getSpentService()->getAccountsInfosUsed();
                            $compteGeneralList = $accountsInfos->getCompteGeneralListByAccountIds($value1);
@@ -812,6 +835,47 @@ class ProjectGrantSearchService implements UseEntityManager, UsePersonService, U
                            throw new Exception("Impossible de filtrer sur le compte");
                        }
                        break;

                    ///////////////////////////////// ACTIVITY / PAS de PROJET
                    case 'pp' :
                        try {
                            $filteredIds = $this->getProjectGrantService()->getActivityRepository(
                            )->getIdsWithoutProject();
                        } catch (Exception $e) {
                            $this->getLoggerService()->warning($e->getMessage());
                            $filter['error'] = "Impossible de filtrer les activités sans projet";
                        }
                        break;

                    ///////////////////////////////// ACTIVITY / TYPE
                    case 'at' :
                    case 'st' :

                        if ($value2 == 1) {
                            $types = [$value1];
                        }
                        else {
                            $types = $this->getProjectGrantService()->getActivityTypeService()->getTypeIdsInside(
                                $value1
                            );
                        }

                        $filteredIds = $this->getProjectGrantService()->getActivityRepository()
                            ->getIdsWithTypes($types, $type === 'st');

                        break;

                    ///////////////////////////////// ACTIVITY / COMPTE STRICT
                    /// (Note : Accessible depuis l'interface d'administration uniquement)
                    case 'cb2':

                        try {
                            $filteredIds = $this->getSpentService()->getIdsActivitiesForCompteGeneral($value1);
                        } catch (Exception $e) {
                            $this->getLoggerService()->warning($e->getMessage());
                            throw new OscarException("Impossible de filtrer sur le compte");
                        }
                        break;
                }

                if ($filteredIds !== null) {
@@ -825,7 +889,7 @@ class ProjectGrantSearchService implements UseEntityManager, UsePersonService, U
                    $filter['filtered'] = count($filteredIds);
                }
                else {
                    $filter['error'] = "Filtre non-appliqué";
                    $filter['error'] = $filter['error'] ?: "Filtre non-appliqué";
                }

                $filter['took'] = (int)((microtime(true) - $time_start) * 1000);
@@ -835,85 +899,6 @@ class ProjectGrantSearchService implements UseEntityManager, UsePersonService, U
            }
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // --- FILTRES
//        switch ($type) {
//

//
//            case 'pp' :
//                $qb->andWhere('c.project IS NULL');
//                break;
//



//
//
//            // --- Compte général
//            case 'cb2':
//                $value1 = $crit['val1'] = explode(',', $params[1]);
//
//                try {
//                    $idsActivity = $this->getSpentService()->getIdsActivitiesForCompteGeneral($value1);
//                    $idsProject = $this->getActivityService()->getActivityRepository(
//                    )->getIdsProjectsForActivity($idsActivity);
//                    $idsActivityRestricted = array_intersect($idsActivityRestricted, $idsActivity);
//                    $idsProjectRestricted = array_intersect($idsProjectRestricted, $idsProject);
//                } catch (Exception $e) {
//                    throw new OscarException($e->getMessage());
//                }
//                break;
//

//

//


//
//            case 'at' :
//
//                if (!isset($parameters['withtype'])) {
//                    $parameters['withtype'] = [];
//                    $qb->andWhere('c.activityType IN (:withtype)');
//                }
//
//                if ($value2 == 1) {
//                    $types = [$value1];
//                }
//                else {
//                    $types = $this->getActivityTypeService()->getTypeIdsInside($value1);
//                }
//
//                $parameters['withtype'] = array_merge(
//                    $parameters['withtype'],
//                    $types
//                );
//                $result = $qb->setParameters($parameters)->getQuery()->getResult();
//                break;
//
//            case 'st' :
//                if (!isset($parameters['withouttype'])) {
//                    $parameters['withouttype'] = [];
//                    $qb->andWhere('c.activityType NOT IN (:withouttype)');
//                }
//                $parameters['withouttype'] = array_merge(
//                    $parameters['withouttype'],
//                    $this->getActivityTypeService()->getTypeIdsInside($value1)
//                );
//                break;
//

//
//            case 'sf' :

//

//

//        }

        /////////////////////////////
        $totalResult = 0;
        $totalPages = 0;
@@ -922,10 +907,7 @@ class ProjectGrantSearchService implements UseEntityManager, UsePersonService, U
        // lors d'une recherche vide.
        if ($startEmpty === false) {
            if (!$search && count($criterias) == 0) {
                if ($activitiesIds !== null) {
                    die("START EMPTY : TRUE");
                }
                else {
                if ($activitiesIds === null) {
                    // AFFICHER TOUS
                    $allIds = $this->getEntityManager()->createQueryBuilder()
                        ->select('c.id')
@@ -935,8 +917,6 @@ class ProjectGrantSearchService implements UseEntityManager, UsePersonService, U
                    $activitiesIds = array_map('current', $allIds);
                }
            }
            else {
            }
        }

        if ($activitiesIds === null) {
@@ -945,8 +925,12 @@ class ProjectGrantSearchService implements UseEntityManager, UsePersonService, U

        $idsRef = $activitiesIds;
        if ($projectview) {
            $idsRef = $projectsIds;
            die("VUE PROJET");
            if ($search) {
                // TODO Ajouter les projets vides aux résultats
            }
            $idsProject = $this->getProjectGrantService()->getActivityRepository()
                ->getIdsProjectsForActivity($activitiesIds, $params['sort'], $params['sortDirection']);
            $idsRef = $idsProject;
        }

        $totalResult = count($idsRef);
@@ -956,11 +940,13 @@ class ProjectGrantSearchService implements UseEntityManager, UsePersonService, U
        $orderedIds = array_slice($idsRef, $offset, $limit);

        if ($projectview) {
            $projectsIds = $idsRef;
            $qb = $this->getEntityManager()->createQueryBuilder()
                ->select('c')
                ->from(Project::class, 'c')
                ->where('c.id IN(:ids)')
                ->setParameter('ids', $idsProjectRestricted);
                ->select('p, c')
                ->from(Project::class, 'p')
                ->leftJoin('p.grants', 'c')
                ->where('p.id IN(:ids)')
                ->setParameter('ids', $orderedIds);
        }
        else {
            $qb = $this->getEntityManager()->createQueryBuilder()
@@ -982,6 +968,10 @@ class ProjectGrantSearchService implements UseEntityManager, UsePersonService, U
                ->setParameter('ids', $orderedIds);
        }

        if ($params['sort']) {
            // $qb->orderBy('c.'.$params['sort'], $params['sortDirection']);
        }

        $activities = $qb->getQuery()->getResult();

        $output = [
+3 −4
Original line number Diff line number Diff line
@@ -470,7 +470,7 @@
                    </span>
                <?php endforeach; ?>

                <?php /* foreach($this->grant()->getCurrentPerson()->getOrganizations() as $affectation ): ?>
                <?php foreach($this->grant()->getCurrentPerson()->getOrganizations() as $affectation ): ?>
                    <?php if( $affectation->isPrincipal() ): ?>
                    <span class="cartouche <?= $affectation->isPrincipal() ? 'primary' : '' ?>">
                        <input name="include[]" class="inline-checkbox" value="<?= $affectation->getOrganization()->getId() ?>" type="checkbox" <?= in_array($affectation->getOrganization()->getId(), $include) ? ' checked="checked"' : '' ?>>
@@ -480,7 +480,7 @@
                        </span>
                    </span>
                    <?php endif; ?>
                <?php endforeach;*/ ?>
                <?php endforeach; ?>
            </p>
            <hr>
            <nav>
@@ -602,8 +602,7 @@
            </small>
        </div>
    </h3>
        <h2>CRITERES</h2>
        <pre><?php var_dump($criteria) ?></pre>

    <?php if($activities && $totalResult > 0): ?>
        <div>
            <?php echo $this->pagerSimple($totalResult, $page) ?>