Commit abf24340 authored by Stephane Bouvry's avatar Stephane Bouvry
Browse files

Modification du mapping en 'nested' pour les filtres sur une personne

parent 309b112d
Loading
Loading
Loading
Loading
+10 −12
Original line number Diff line number Diff line
@@ -2746,27 +2746,22 @@ class ProjectGrantController extends AbstractOscarController implements UseNotif
            "at" => [
                "key" => 'at',
                "label" => $this->oscarText("Type"),
                "raw" => 'at;;0'
                "raw" => 'at;;;'
            ],
            "ap" => [
                "key" => 'ap',
                "label" => $this->oscarText("Personne"),
                "raw" => 'ap;;'
                "raw" => 'ap;;;'
            ],
            "ao" => [
                "key" => 'ao',
                "label" => $this->oscarText("Organisation"),
                "raw" => 'ao;;'
                "raw" => 'ao;;;'
            ],
            "psa" => [
                "key" => 'psa',
                "label" => $this->oscarText("Projet sans activité"),
                "raw" => 'psa;;'
            ],
            "asp" => [
                "key" => 'asp',
                "label" => $this->oscarText("Activité sans projet"),
                "raw" => 'asp;;'
            "orp" => [
                "key" => 'orp',
                "label" => $this->oscarText("Orphelin"),
                "raw" => 'orp;;;'
            ]
        ];

@@ -2778,6 +2773,8 @@ class ProjectGrantController extends AbstractOscarController implements UseNotif
            'dateEnd' => 'Date de fin',
        ];

        $rolesPersons = $this->getOscarUserContextService()->getAllRoleIdPersonInActivity();

        $directions = [
            'desc' => 'Décroissant',
            'asc' => 'Croissant',
@@ -2802,6 +2799,7 @@ class ProjectGrantController extends AbstractOscarController implements UseNotif
        $filtersOptions = [
            'activityTypes' => $this->getActivityTypeService()->getActivityTypesTree(true),
            'activityDocumentTypes' => $this->getProjectGrantSearchService()->getFilterOptionsMilestones(),
            'rolesPersons' => $rolesPersons,
            'filters' => $filters,
            'sorts' => $sorts,
            'directions' => $directions,
+26 −0
Original line number Diff line number Diff line
@@ -238,6 +238,31 @@ class ActivityTypeService implements UseEntityManager, UseLoggerService
        return $out;
    }

    public function getIdsTreeByLast2(bool $returnLabel = false) :array {
        $output = [];
        $tree = $this->getActivityTypesTree(true);
        $tree = $tree[0];
        foreach ($tree['children'] as $child){
            $this->getIdsTreeByLast_recursive2($output, [], $child, $returnLabel);
        }
        echo json_encode($output, JSON_PRETTY_PRINT); die();
        return $output;
    }

    protected function getIdsTreeByLast_recursive2( array &$output, array $previous, array $child, bool $returnLabel = false ) :void {
        $data = $returnLabel ? $child['label'] : $child['id'];
        $output[$child['id']] = [$data];
        if(count($child['children'])){
            $previous[] = $data;
            foreach ($child['children'] as $subChild){
                $this->getIdsTreeByLast_recursive($output, $previous, $subChild, $returnLabel);
            }
        } else {
            $previous[] = $data;
            $output[$child['id']] = $previous;
        }
    }

    /**
     * Retourne l'enchainement des IDs/label pour chaque type.
     * ex: 507: [505,506]
@@ -256,6 +281,7 @@ class ActivityTypeService implements UseEntityManager, UseLoggerService

    protected function getIdsTreeByLast_recursive( array &$output, array $previous, array $child, bool $returnLabel = false ) :void {
        $data = $returnLabel ? $child['label'] : $child['id'];
        $output[$child['id']] = [$data];
        if(count($child['children'])){
            $previous[] = $data;
            foreach ($child['children'] as $subChild){
+24 −1
Original line number Diff line number Diff line
@@ -182,13 +182,36 @@ class PersonService implements UseOscarConfigurationService, UseEntityManager, U

    public function searchIds($what): array
    {
        $body = [
            "_source" => ["id"],
            "query" => [
                "bool" => []
            ]
        ];
        if (preg_match_all(self::SEARCH_ID_PATTERN, $what, $matches, PREG_SET_ORDER, 0)) {
            $idsStr = $matches[0][1];
            if ($idsStr) {
                return explode(',', $idsStr);
            }
        }
        return $this->getSearchEngineStrategy()->search($what);
        $result = $this->search2($what, $body);
        return array_column($result, 'id');
    }

    public function search2(string $what, ?array $body = null ) :array {
        if( $body === null ) {
            $body = [
                "query" => [
                    "bool" => []
                ]
            ];
        }
        $result = $this->getSearchEngineStrategy()->searchRaw($what,1000, $body);
        $response = [];
        foreach ($result["hits"]["hits"] as $hit) {
            $response[] = $hit["_source"];
        }
        return $response;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+159 −56
Original line number Diff line number Diff line
@@ -2147,6 +2147,10 @@ class ProjectGrantService implements UseGearmanJobLauncherService, UseOscarConfi
    }

    ////////////////////////////////////////////////// RECHERCHE v2
    public function getbaseFilters(): array
    {
        return [];
    }

    public function search2(array $params)
    {
@@ -2157,20 +2161,25 @@ class ProjectGrantService implements UseGearmanJobLauncherService, UseOscarConfi
            ],
            'query' => [
                'bool' => [
                    'filter' => []
                    'filter' => [],
                    'must_not' => []
                ]
            ]
        ];

        $modeProject = $params['project'] == 1;
        $notices = [];
        $filters = [];


        // Résultats par page
        if (array_key_exists('rbp', $params)) {
            if ($params['rbp'] <= 50) {
                $size = $params['rbp'];
            }
        }

        // Page affichée
        $page = $params['page'];
        if ($page > 1) {
            $from = ($size * ($page - 1));
@@ -2178,9 +2187,7 @@ class ProjectGrantService implements UseGearmanJobLauncherService, UseOscarConfi
            $from = 0;
        }

        $body['from'] = $from;
        $body['size'] = $size;

        // Trie
        if (array_key_exists('sort', $params) && $params['sort'] !== 'hit') {
            $direction = 'DESC';
            if ($params['direction'] && in_array($params['direction'], ['ASC', 'DESC'])) {
@@ -2190,33 +2197,128 @@ class ProjectGrantService implements UseGearmanJobLauncherService, UseOscarConfi

        }

        $body['from'] = $from;
        $body['size'] = $size;


        if (array_key_exists('filters', $params)) {
            $filterES = [];
            $filterNotES = [];
            foreach ($params['filters'] as $filter) {
                $filterDatas = explode(';', $filter);
                $type = $filterDatas[0];
                $value1 = $filterDatas[1];
                $value2 = $filterDatas[2];
                $value3 = $filterDatas[3];
                $value1Displayed = $value1;
                $value2Displayed = $value2;
                $value3Displayed = $value3;
                $error = "";

                switch ($type) {
                    case 'at':
                        if (!array_key_exists('at', $filterES)) {
                            $filterES['at'] = [
                                'field' => 'type_id',
                                'values' => []
                            ];
                        }
                        if( $value2 == 1 ){
                            $filterES['at']['field'] = 'type_chain_id';
                        }
                        if ($value1) {
                            $filterES['at']['values'][] = $value1;
                        } else {
                            $error = "Aucun type selectionné";
                        }
                        break;

                    case 'ap':
                        if (!array_key_exists('ap', $filterES)) {
                            $filterES['ap'] = [];
                        }

                        if ($value1) {
                            try {
                                $person = $this->getPersonService()->getPersonById($value1);
                                $value1 = $person->getId();
                                $value1Displayed = $person->getDisplayName();
                            } catch (OscarException $e) {
                                $error = "Impossible de trouver cette personne";
                            }

                            $currentFilter = [
                                "nested" => [
                                    "path" => "persons",
                                    "query" => [
                                        "bool" => [
                                    "should" => [],
                                    "minimum_should_match" => 1
                                ],
                                            "filter" => [
                                                ["term" => ["persons.id" => $value1]]
                                            ]
                                        ]
                                    ]
                                ]
                            ];
                            if ($value2) {
                                $currentFilter['nested']['query']['bool']['filter'][] = [
                                    "term" => ["persons.role_id" => $value2],
                                ];
                            }
                        $field = ($value2 == 1) ? "type_chain_id" : "type_id";
                        $filterES['at']['bool']['should'][] = [
                            "terms" => [$field => [$value1]],
                            $filterES['ap'][] = $currentFilter;
                        } else {
                            $error = "Aucune personne selectionnée";
                        }
                        break;

                    case 'orp':
                        if ($modeProject) {
                            $filterNotES[] = [
                                "exists" => [
                                    "field" => "activities"
                                ]
                            ];
                        } else {
                            $filterNotES[] = [
                                "exists" => [
                                    "field" => "project"
                                ]
                            ];
                        }
                        break;

                    default:

                        $error = "Introuvable";
                        $this->getLoggerService()->error("Le type de filtre '$type' n'est pas pris en charge");

                }
                $body['query']['bool']['filter'] = array_values($filterES);
                $filterOut = [
                    "type" => $type,
                    "raw" => $filter,
                    "value1" => $value1,
                    "value2" => $value2,
                    "value3" => $value3,
                    "value1Displayed" => $value1Displayed,
                    "value2Displayed" => $value2Displayed,
                    "value3Displayed" => $value3Displayed,
                    "error" => $error,
                ];

                $filters[] = $filterOut;
                foreach ($filterES as $key=>$value) {
                    if( $key == 'at' ){
                        $value = [
                            "terms" => [
                                $value['field'] => $value['values']
                            ]

                        ];
                    }
                    $body['query']['bool']['filter'] = array_merge($body['query']['bool']['filter'], $value);
                }

                //$body['query']['bool']['filter'] = array_values($filterES);
                $body['query']['bool']['must_not'] = $filterNotES;
            }
        }

@@ -2228,6 +2330,15 @@ class ProjectGrantService implements UseGearmanJobLauncherService, UseOscarConfi
            ];
        }

        $out = [
            'filters' => [],
            'page' => $page,
            'query' => $body,
            'activities' => [],
            'projects' => [],
        ];

        try {
            if ($params['project'] == '1') {

                $result = $this->getSearchEngineProjectStrategy()->searchRaw($params['q'], $limit = 1000, $body);
@@ -2236,11 +2347,6 @@ class ProjectGrantService implements UseGearmanJobLauncherService, UseOscarConfi
                $result = $this->getSearchEngineStrategy()->searchRaw($params['q'], $limit = 1000, $body);
            }

        $out = [
            'page' => $page,
            'query' => $body
        ];

            if ($params['project'] == 1) {
                $total = $result['hits']['total']['value'];
                $pages = ceil($total / $size);
@@ -2267,8 +2373,13 @@ class ProjectGrantService implements UseGearmanJobLauncherService, UseOscarConfi
                $out["activities"] = $datas;
            }

        } catch (\Exception $e) {
            $out['error'] = $e->getMessage();
        }

        $out['total'] = $total;
        $out['pages'] = $pages;
        $out['filters'] = $filters;

        return $out;
    }
@@ -2287,29 +2398,18 @@ class ProjectGrantService implements UseGearmanJobLauncherService, UseOscarConfi
    public function searchIndex_rebuild()
    {
        // PROJETS
        $projects = $this->getEntityManager()->getRepository(Project::class)->findBy(
            [],
            ['dateUpdated' => 'DESC'],
            50,
            0
        );
        $projects = $this->getEntityManager()->getRepository(Project::class)->findAll();

        $this->getLoggerService()->info('[elasic] Reindex ' . count($projects) . ' project(s)');
        $this->getSearchEngineProjectStrategy()->rebuildIndex($projects);

        //$activities = $this->getEntityManager()->getRepository(Activity::class)->findAll();
        $activities = $this->getEntityManager()->getRepository(Activity::class)->findBy(
            [],
            ['dateUpdated' => 'DESC'],
            1000,
            0
        );
        $activities = $this->getEntityManager()->getRepository(Activity::class)->findAll();

        $this->getLoggerService()->info('[elasic] Reindex ' . count($activities) . ' activitie(s)');
        $done = $this->getSearchEngineStrategy()->rebuildIndex($activities);



        return $done;
    }

@@ -2345,6 +2445,8 @@ class ProjectGrantService implements UseGearmanJobLauncherService, UseOscarConfi
            $params[] = $this->getLoggerService();
            $class = new \ReflectionClass(ProjectElasticSearch::class);
            $searchStrategy = $class->newInstanceArgs($params);


            $searchStrategy->staticDatas = [
                'typesChainIds' => $this->getActivityTypeService()->getIdsTreeByLast(),
                'typesChainlabels' => $this->getActivityTypeService()->getIdsTreeByLast(true),
@@ -2353,6 +2455,7 @@ class ProjectGrantService implements UseGearmanJobLauncherService, UseOscarConfi

        return $searchStrategy;
    }

    /**
     * @return IActivitySearchStrategy
     */
+18 −3
Original line number Diff line number Diff line
@@ -55,7 +55,7 @@ class ElasticActivitySearch extends ElasticSearchEngine implements IActivitySear
                    'label' => ['type' => 'text'],
                    'type' => ['type' => 'keyword'],
                    'type_id' => ['type' => 'integer'],
                    'type_chain_id' => ['type' => 'keyword'],
                    'type_chain_id' => ['type' => 'integer'],
                    'type_chain_labels' => ['type' => 'keyword'],
                    'eotp' => ['type' => 'keyword'],
                    'oscar' => ['type' => 'keyword'],
@@ -84,6 +84,16 @@ class ElasticActivitySearch extends ElasticSearchEngine implements IActivitySear
                            'date' => ['type' => 'date'],
                        ]
                    ],
                    'persons' => [
                        'type' => 'nested',
                        'properties' => [
                            'id' => ['type' => 'integer'],
                            'firstname' => ['type' => 'text'],
                            'lastname' => ['type' => 'text'],
                            'role_id' => ['type' => 'integer'],
                            'role' => ['type' => 'keyword'],
                        ]
                    ],
//                    'numerotation' => [ 'type' => 'text', 'analyzer' => 'folding_analyzer'],
//                    'numbers' => [ 'type' => 'nested' ],

@@ -115,8 +125,11 @@ class ElasticActivitySearch extends ElasticSearchEngine implements IActivitySear
        $type_chain_id = [];
        $type_chain_label = [];



        if ($activity->getActivityType()) {
            $typeId = $activity->getActivityType()->getId();

            $type_label = $activity->getActivityType()->getLabel();
            $type_id = $typeId;

@@ -150,6 +163,7 @@ class ElasticActivitySearch extends ElasticSearchEngine implements IActivitySear
                'id' => $personAffectation->getPerson()->getId(),
                'firstname' => $personAffectation->getPerson()->getFirstname(),
                'lastname' => $personAffectation->getPerson()->getLastname(),
                'role_id' => $personAffectation->getRoleObj()->getId(),
                'role' => $personAffectation->getRole(),
                'principal' => $personAffectation->isPrincipal(),
            ];
@@ -163,6 +177,7 @@ class ElasticActivitySearch extends ElasticSearchEngine implements IActivitySear
                'code' => $organizationAffectation->getOrganization()->getCode(),
                'shortname' => $organizationAffectation->getOrganization()->getShortName(),
                'longname' => $organizationAffectation->getOrganization()->getFullName(),
                'role_id' => $organizationAffectation->getRoleObj() ? $organizationAffectation->getRoleObj()->getId() : "",
                'role' => $organizationAffectation->getRole(),
                'principal' => $organizationAffectation->isPrincipal(),
            ];
@@ -183,8 +198,8 @@ class ElasticActivitySearch extends ElasticSearchEngine implements IActivitySear
        $datas = [
            'id' => $activity->getId(),
            'label' => $activity->getLabel(),
            'type' => $activity->getType(),
            'type_id' => $activity->getType() ? $activity->getType()->getId() : null,
            'type' => $type_label,
            'type_id' => $type_id,
            'type_chain_id' => $type_chain_id,
            'type_chain_labels' => $type_chain_label,
            'acronym' => $activity->getAcronym(),
Loading