From 58c2b7893d92cafd90225a4b6878c7cc386135ff Mon Sep 17 00:00:00 2001
From: "florian.azizian" <florian.azizian@maarch.org>
Date: Fri, 2 Oct 2020 22:37:09 +0200
Subject: [PATCH] FEAT #13271 TIME 1:30 search list display

---
 .../controllers/ConfigurationController.php   |   1 -
 .../controllers/ResourceListController.php    |  83 +++++-----
 .../search/controllers/SearchController.php   | 147 +++++++-----------
 .../doctypes-administration.component.html    |   2 +-
 src/frontend/service/privileges.service.ts    |   4 +-
 src/lang/lang-en.json                         |   1 +
 src/lang/lang-fr.json                         |   3 +-
 7 files changed, 104 insertions(+), 137 deletions(-)

diff --git a/src/app/configuration/controllers/ConfigurationController.php b/src/app/configuration/controllers/ConfigurationController.php
index faa4baf991e..77f540ca0b0 100755
--- a/src/app/configuration/controllers/ConfigurationController.php
+++ b/src/app/configuration/controllers/ConfigurationController.php
@@ -93,7 +93,6 @@ class ConfigurationController
             }
 
             $data = ['listDisplay' => $data['listDisplay'], 'listEvent' => $data['listEvent']];
-
         }
 
         $data = json_encode($data);
diff --git a/src/app/resource/controllers/ResourceListController.php b/src/app/resource/controllers/ResourceListController.php
index 851c9a7e31b..37facbf48fa 100644
--- a/src/app/resource/controllers/ResourceListController.php
+++ b/src/app/resource/controllers/ResourceListController.php
@@ -91,9 +91,9 @@ class ResourceListController
         $allResources = array_column($rawResources, 'res_id');
 
         $formattedResources = [];
-        $defaultAction = [];
-        $displayFolderTags = false;
-        $templateColumns = 0;
+        $defaultAction      = [];
+        $displayFolderTags  = false;
+        $templateColumns    = 0;
         if (!empty($resIds)) {
             $excludeAttachmentTypes = ['signed_response'];
             $attachments = AttachmentModel::get([
@@ -103,40 +103,12 @@ class ResourceListController
                 'groupBy'   => ['res_id_master']
             ]);
 
-            $groupBasket = GroupBasketModel::get(['select' => ['list_display', 'list_event', 'list_event_data'], 'where' => ['basket_id = ?', 'group_id = ?'], 'data' => [$basket['basket_id'], $group['group_id']]]);
-            $listDisplay = json_decode($groupBasket[0]['list_display'], true);
+            $groupBasket     = GroupBasketModel::get(['select' => ['list_display', 'list_event', 'list_event_data'], 'where' => ['basket_id = ?', 'group_id = ?'], 'data' => [$basket['basket_id'], $group['group_id']]]);
+            $listDisplay     = json_decode($groupBasket[0]['list_display'], true);
             $templateColumns = $listDisplay['templateColumns'];
-            $listDisplay = $listDisplay['subInfos'];
+            $listDisplay     = $listDisplay['subInfos'];
 
-            $select = [
-                'res_letterbox.res_id', 'res_letterbox.subject', 'res_letterbox.barcode', 'res_letterbox.alt_identifier',
-                'status.label_status AS "status.label_status"', 'status.img_filename AS "status.img_filename"', 'priorities.color AS "priorities.color"',
-                'res_letterbox.closing_date', 'res_letterbox.locker_user_id', 'res_letterbox.locker_time', 'res_letterbox.confidentiality',
-                'res_letterbox.filename as res_filename', 'res_letterbox.integrations'
-            ];
-            $tableFunction = ['status', 'priorities'];
-            $leftJoinFunction = ['res_letterbox.status = status.id', 'res_letterbox.priority = priorities.id'];
-            foreach ($listDisplay as $value) {
-                $value = (array)$value;
-                if ($value['value'] == 'getPriority') {
-                    $select[] = 'priorities.label AS "priorities.label"';
-                } elseif ($value['value'] == 'getCategory') {
-                    $select[] = 'res_letterbox.category_id';
-                } elseif ($value['value'] == 'getDoctype') {
-                    $select[] = 'doctypes.description AS "doctypes.description"';
-                    $tableFunction[] = 'doctypes';
-                    $leftJoinFunction[] = 'res_letterbox.type_id = doctypes.type_id';
-                } elseif ($value['value'] == 'getCreationAndProcessLimitDates') {
-                    $select[] = 'res_letterbox.creation_date';
-                    $select[] = 'res_letterbox.process_limit_date';
-                } elseif ($value['value'] == 'getModificationDate') {
-                    $select[] = 'res_letterbox.modification_date';
-                } elseif ($value['value'] == 'getOpinionLimitDate') {
-                    $select[] = 'res_letterbox.opinion_limit_date';
-                } elseif (strpos($value['value'], 'indexingCustomField_') !== false && !in_array('res_letterbox.custom_fields', $select)) {
-                    $select[] = 'res_letterbox.custom_fields';
-                }
-            }
+            $selectData = ResourceListController::getSelectData(['listDisplay' => $listDisplay]);
 
             $order = 'CASE res_letterbox.res_id ';
             foreach ($resIds as $key => $resId) {
@@ -145,9 +117,9 @@ class ResourceListController
             $order .= 'END';
 
             $resources = ResourceListModel::getOnResource([
-                'select'    => $select,
-                'table'     => $tableFunction,
-                'leftJoin'  => $leftJoinFunction,
+                'select'    => $selectData['select'],
+                'table'     => $selectData['tableFunction'],
+                'leftJoin'  => $selectData['leftJoinFunction'],
                 'where'     => ['res_letterbox.res_id in (?)'],
                 'data'      => [$resIds],
                 'orderBy'   => [$order]
@@ -182,6 +154,41 @@ class ResourceListController
         ]);
     }
 
+    public static function getSelectData(array $args)
+    {
+        $select = [
+            'res_letterbox.res_id', 'res_letterbox.subject', 'res_letterbox.barcode', 'res_letterbox.alt_identifier',
+            'status.label_status AS "status.label_status"', 'status.img_filename AS "status.img_filename"', 'priorities.color AS "priorities.color"',
+            'res_letterbox.closing_date', 'res_letterbox.locker_user_id', 'res_letterbox.locker_time', 'res_letterbox.confidentiality',
+            'res_letterbox.filename as res_filename', 'res_letterbox.integrations'
+        ];
+        $tableFunction    = ['status', 'priorities'];
+        $leftJoinFunction = ['res_letterbox.status = status.id', 'res_letterbox.priority = priorities.id'];
+        foreach ($args['listDisplay'] as $value) {
+            $value = (array)$value;
+            if ($value['value'] == 'getPriority') {
+                $select[] = 'priorities.label AS "priorities.label"';
+            } elseif ($value['value'] == 'getCategory') {
+                $select[] = 'res_letterbox.category_id';
+            } elseif ($value['value'] == 'getDoctype') {
+                $select[] = 'doctypes.description AS "doctypes.description"';
+                $tableFunction[] = 'doctypes';
+                $leftJoinFunction[] = 'res_letterbox.type_id = doctypes.type_id';
+            } elseif ($value['value'] == 'getCreationAndProcessLimitDates') {
+                $select[] = 'res_letterbox.creation_date';
+                $select[] = 'res_letterbox.process_limit_date';
+            } elseif ($value['value'] == 'getModificationDate') {
+                $select[] = 'res_letterbox.modification_date';
+            } elseif ($value['value'] == 'getOpinionLimitDate') {
+                $select[] = 'res_letterbox.opinion_limit_date';
+            } elseif (strpos($value['value'], 'indexingCustomField_') !== false && !in_array('res_letterbox.custom_fields', $select)) {
+                $select[] = 'res_letterbox.custom_fields';
+            }
+        }
+
+        return ['select' => $select, 'tableFunction' => $tableFunction, 'leftJoinFunction' => $leftJoinFunction];
+    }
+
     public function getFilters(Request $request, Response $response, array $aArgs)
     {
         $errors = ResourceListController::listControl(['groupId' => $aArgs['groupId'], 'userId' => $aArgs['userId'], 'basketId' => $aArgs['basketId'], 'currentUserId' => $GLOBALS['id']]);
diff --git a/src/app/search/controllers/SearchController.php b/src/app/search/controllers/SearchController.php
index dec4a91d18b..0d2ebaea2b4 100644
--- a/src/app/search/controllers/SearchController.php
+++ b/src/app/search/controllers/SearchController.php
@@ -30,8 +30,11 @@ use Folder\models\ResourceFolderModel;
 use Note\models\NoteModel;
 use Priority\models\PriorityModel;
 use RegisteredMail\models\RegisteredMailModel;
+use Resource\controllers\ResourceListController;
 use Resource\models\ResModel;
 use Resource\models\ResourceContactModel;
+use Resource\models\ResourceListModel;
+use Resource\models\UserFollowedResourceModel;
 use Respect\Validation\Validator;
 use Slim\Http\Request;
 use Slim\Http\Response;
@@ -60,35 +63,35 @@ class SearchController
             return $response->withJson(['resources' => [], 'count' => 0, 'allResources' => []]);
         }
         $searchWhere = $searchClause['searchWhere'];
-        $searchData = $searchClause['searchData'];
+        $searchData  = $searchClause['searchData'];
 
         $searchClause = SearchController::getMainFieldsClause(['body' => $body, 'searchWhere' => $searchWhere, 'searchData' => $searchData]);
         if (empty($searchClause)) {
             return $response->withJson(['resources' => [], 'count' => 0, 'allResources' => []]);
         }
         $searchWhere = $searchClause['searchWhere'];
-        $searchData = $searchClause['searchData'];
+        $searchData  = $searchClause['searchData'];
 
         $searchClause = SearchController::getListFieldsClause(['body' => $body, 'searchWhere' => $searchWhere, 'searchData' => $searchData]);
         if (empty($searchClause)) {
             return $response->withJson(['resources' => [], 'count' => 0, 'allResources' => []]);
         }
         $searchWhere = $searchClause['searchWhere'];
-        $searchData = $searchClause['searchData'];
+        $searchData  = $searchClause['searchData'];
 
         $searchClause = SearchController::getCustomFieldsClause(['body' => $body, 'searchWhere' => $searchWhere, 'searchData' => $searchData]);
         if (empty($searchClause)) {
             return $response->withJson(['resources' => [], 'count' => 0, 'allResources' => []]);
         }
         $searchWhere = $searchClause['searchWhere'];
-        $searchData = $searchClause['searchData'];
+        $searchData  = $searchClause['searchData'];
 
         $searchClause = SearchController::getRegisteredMailsClause(['body' => $body, 'searchWhere' => $searchWhere, 'searchData' => $searchData]);
         if (empty($searchClause)) {
             return $response->withJson(['resources' => [], 'count' => 0, 'allResources' => []]);
         }
         $searchWhere = $searchClause['searchWhere'];
-        $searchData = $searchClause['searchData'];
+        $searchData  = $searchClause['searchData'];
 
         $searchClause = SearchController::getFulltextClause(['body' => $body, 'searchWhere' => $searchWhere, 'searchData' => $searchData]);
         if (empty($searchClause)) {
@@ -114,7 +117,7 @@ class SearchController
         if (!empty($queryParams['offset']) && is_numeric($queryParams['offset'])) {
             $offset = (int)$queryParams['offset'];
         }
-        $order = !in_array($queryParams['orderDir'], ['ASC', 'DESC']) ? '' : $queryParams['orderDir'];
+        $order   = !in_array($queryParams['orderDir'], ['ASC', 'DESC']) ? '' : $queryParams['orderDir'];
         $orderBy = str_replace(['chrono', 'typeLabel', 'creationDate', 'category', 'destUser', 'processLimitDate', 'entityLabel'], ['order_alphanum(alt_identifier)', 'type_label', 'creation_date', 'category_id', 'dest_user', 'process_limit_date', 'entity_label'], $queryParams['order']);
         $orderBy = !in_array($orderBy, ['order_alphanum(alt_identifier)', 'status', 'subject', 'type_label', 'creation_date', 'category_id', 'dest_user', 'process_limit_date', 'entity_label', 'priority']) ? ['creation_date'] : ["{$orderBy} {$order}"];
 
@@ -131,7 +134,7 @@ class SearchController
         $allResources = array_column($allResources, 'resId');
 
         $resIds = [];
-        $order = 'CASE res_id ';
+        $order  = 'CASE res_id ';
         for ($i = $offset; $i < ($offset + $limit); $i++) {
             if (empty($allResources[$i])) {
                 break;
@@ -141,101 +144,57 @@ class SearchController
         }
         $order .= 'END';
 
-        $resources = ResModel::get([
-            'select'    => [
-                'res_id as "resId"', 'category_id as "category"', 'alt_identifier as "chrono"', 'subject', 'barcode', 'filename', 'creation_date as "creationDate"',
-                'type_id as "type"', 'priority', 'status', 'dest_user as "destUser"'
-            ],
-            'where'   => ['res_id in (?)'],
-            'data'    => [$resIds],
-            'orderBy' => [$order]
+        $adminSearch   = ConfigurationModel::getByPrivilege(['privilege' => 'admin_search', 'select' => ['value']]);
+        $configuration = json_decode($adminSearch['value'], true);
+        $listDisplay   = $configuration['listDisplay']['subInfos'];
+
+        $selectData = ResourceListController::getSelectData(['listDisplay' => $listDisplay]);
+
+        $resources = ResourceListModel::getOnResource([
+            'select'    => $selectData['select'],
+            'table'     => $selectData['tableFunction'],
+            'leftJoin'  => $selectData['leftJoinFunction'],
+            'where'     => ['res_letterbox.res_id in (?)'],
+            'data'      => [$resIds],
+            'orderBy'   => [$order]
         ]);
         if (empty($resources)) {
             return $response->withJson(['resources' => [], 'count' => 0, 'allResources' => []]);
         }
 
-        $resourcesIds = array_column($resources, 'resId');
-        $attachments = AttachmentModel::get(['select' => ['count(1)', 'res_id_master'], 'where' => ['res_id_master in (?)', 'status not in (?)'], 'data' => [$resourcesIds, ['DEL']], 'groupBy' => ['res_id_master']]);
-
-        $prioritiesIds = array_column($resources, 'priority');
-        $priorities = PriorityModel::get(['select' => ['id', 'color'], 'where' => ['id in (?)'], 'data' => [$prioritiesIds]]);
-
-        $statusesIds = array_column($resources, 'status');
-        $statuses = StatusModel::get(['select' => ['id', 'label_status', 'img_filename'], 'where' => ['id in (?)'], 'data' => [$statusesIds]]);
-
-        $doctypesIds = array_column($resources, 'type');
-        $doctypes = DoctypeModel::get(['select' => ['type_id', 'description'], 'where' => ['type_id in (?)'], 'data' => [$doctypesIds]]);
-
-        $notes = NoteModel::countByResId(['resId' => $resourcesIds, 'userId' => $GLOBALS['id']]);
-
-        $correspondents = ResourceContactModel::get([
-            'select'    => ['item_id', 'type', 'mode', 'res_id'],
-            'where'     => ['res_id in (?)'],
-            'data'      => [$resourcesIds]
+        $excludeAttachmentTypes = ['signed_response'];
+        $attachments = AttachmentModel::get([
+            'select'    => ['COUNT(res_id)', 'res_id_master'],
+            'where'     => ['res_id_master in (?)', 'status not in (?)', 'attachment_type not in (?)', '((status = ? AND typist = ?) OR status != ?)'],
+            'data'      => [$resIds, ['DEL', 'OBS'], $excludeAttachmentTypes, 'TMP', $GLOBALS['id'], 'TMP'],
+            'groupBy'   => ['res_id_master']
         ]);
 
-        foreach ($resources as $key => $resource) {
-            if (!empty($resource['priority'])) {
-                foreach ($priorities as $priority) {
-                    if ($priority['id'] == $resource['priority']) {
-                        $resources[$key]['priorityColor'] = $priority['color'];
-                        break;
-                    }
-                }
-            }
-            $resources[$key]['statusLabel'] = null;
-            $resources[$key]['statusImage'] = null;
-            if (!empty($resource['status'])) {
-                foreach ($statuses as $status) {
-                    if ($status['id'] == $resource['status']) {
-                        $resources[$key]['statusLabel'] = $status['label_status'];
-                        $resources[$key]['statusImage'] = $status['img_filename'];
-                        break;
-                    }
-                }
-            }
-            foreach ($doctypes as $doctype) {
-                if ($doctype['type_id'] == $resource['type']) {
-                    $resources[$key]['typeLabel'] = $doctype['description'];
-                    break;
-                }
-            }
-            if (!empty($resource['destUser'])) {
-                $resources[$key]['destUserLabel'] = UserModel::getLabelledUserById(['id' => $resource['destUser']]);
-            }
-            $resources[$key]['hasDocument'] = !empty($resource['filename']);
-
-            $resources[$key]['senders'] = [];
-            $resources[$key]['recipients'] = [];
-            foreach ($correspondents as $correspondent) {
-                if ($correspondent['res_id'] == $resource['resId']) {
-                    if ($correspondent['type'] == 'contact') {
-                        $contactRaw = ContactModel::getById(['select' => ['firstname', 'lastname', 'company'], 'id' => $correspondent['item_id']]);
-                        $contactToDisplay = ContactController::getFormattedOnlyContact(['contact' => $contactRaw]);
-                        $formattedCorrespondent = $contactToDisplay['contact']['otherInfo'];
-                    } elseif ($correspondent['type'] == 'user') {
-                        $formattedCorrespondent = UserModel::getLabelledUserById(['id' => $correspondent['item_id']]);
-                    } else {
-                        $entity = EntityModel::getById(['id' => $correspondent['item_id'], 'select' => ['entity_label']]);
-                        $formattedCorrespondent = $entity['entity_label'];
-                    }
-
-                    $resources[$key]["{$correspondent['mode']}s"][] = $formattedCorrespondent;
-                }
-            }
-
-            $resources[$key]['countAttachments'] = 0;
-            foreach ($attachments as $attachment) {
-                if ($attachment['res_id_master'] == $resource['resId']) {
-                    $resources[$key]['countAttachments'] = $attachment['count'];
-                    break;
-                }
-            }
-
-            $resources[$key]['countNotes'] = $notes[$resource['resId']];
-        }
+        $followedDocuments = UserFollowedResourceModel::get([
+            'select' => ['res_id'],
+                'where'  => ['user_id = ?'],
+                'data'   => [$GLOBALS['id']],
+            ]);
+    
+        $trackedMails = array_column($followedDocuments, 'res_id');
+
+        $formattedResources = ResourceListController::getFormattedResources([
+            'resources'     => $resources,
+            'userId'        => $GLOBALS['id'],
+            'attachments'   => $attachments,
+            'checkLocked'   => false,
+            'listDisplay'   => $listDisplay,
+            'trackedMails'  => $trackedMails
+        ]);
 
-        return $response->withJson(['resources' => $resources, 'count' => count($allResources), 'allResources' => $allResources]);
+        return $response->withJson([
+            'resources'         => $formattedResources,
+            'count'             => count($allResources),
+            'allResources'      => $allResources,
+            'defaultTab'        => $configuration['listEvent']['defaultTab'],
+            'displayFolderTags' => in_array('getFolders', array_column($listDisplay, 'value')),
+            'templateColumns'   => $configuration['listDisplay']['templateColumns'],
+        ]);
     }
 
     public function getConfiguration(Request $request, Response $response)
diff --git a/src/frontend/app/administration/doctype/doctypes-administration.component.html b/src/frontend/app/administration/doctype/doctypes-administration.component.html
index c8ad5c66ef8..705c01fe801 100755
--- a/src/frontend/app/administration/doctype/doctypes-administration.component.html
+++ b/src/frontend/app/administration/doctype/doctypes-administration.component.html
@@ -53,7 +53,7 @@
 
                     <mat-form-field>
                         <input matInput id="jstree_search" name="jstree_search" type="text"
-                            placeholder="{{'lang.search' | translate}}">
+                            placeholder="{{'lang.searchDoctypes' | translate}}">
                     </mat-form-field>
                     <div id="jstree"></div>
                     <div class="mat-paginator"
diff --git a/src/frontend/service/privileges.service.ts b/src/frontend/service/privileges.service.ts
index f1cdf568288..9cca9952fd2 100755
--- a/src/frontend/service/privileges.service.ts
+++ b/src/frontend/service/privileges.service.ts
@@ -296,8 +296,8 @@ export class PrivilegeService {
             'hasParams': false
         },
         {
-            'id': 'search_administration',
-            'label': 'lang.searchAdministration',
+            'id': 'admin_search',
+            'label': 'lang.search',
             'comment': 'lang.searchAdministration',
             'route': '/administration/search',
             'unit': 'supervision',
diff --git a/src/lang/lang-en.json b/src/lang/lang-en.json
index e0b72c13415..210ea88a908 100644
--- a/src/lang/lang-en.json
+++ b/src/lang/lang-en.json
@@ -1340,6 +1340,7 @@
     "searchCommunicationMean": "Search a communication mean",
     "searchContact": "Search a contact",
     "searchDatas": "Search data",
+    "searchDoctypes": "Search doctypes",
     "searchEntities": "Search entity",
     "searchExternalIdM2M": "Search M2M Identifier",
     "searchFolder": "Search folder",
diff --git a/src/lang/lang-fr.json b/src/lang/lang-fr.json
index 7a7607d88c4..dd33009fa8c 100644
--- a/src/lang/lang-fr.json
+++ b/src/lang/lang-fr.json
@@ -1336,13 +1336,14 @@
     "sbSignatures": "Signatures de parapheur",
     "script": "Script",
     "scriptCreated": "Script créé",
-    "search": "Chercher",
+    "search": "Recherche",
     "searchAddressBan": "Recherchez une adresse",
     "searchAddressDb": "Rechercher dans la Base Adresse Nationale",
     "searchByAttachmentType": "Rechercher par type de pièce jointe",
     "searchCommunicationMean": "Recherchez un moyen de communication",
     "searchContact": "Recherchez un contact",
     "searchDatas": "Rechercher une donnée",
+    "searchDoctypes": "Rechercher une chemise/sous chemise ou type de courrier",
     "searchEntities": "Rechercher une entité",
     "searchExternalIdM2M": "Recherchez un identifiant M2M",
     "searchFolder": "Rechercher un dossier",
-- 
GitLab