diff --git a/lang/en.json b/lang/en.json
index c8e331ebaf809525b531a3a929b91b780a9f6a8d..443882308873910e684ad3965585abbc687d4fba 100755
--- a/lang/en.json
+++ b/lang/en.json
@@ -13,7 +13,7 @@
         "annotationAdded": "Annotation added",
         "annotationMode": "Annotation mode",
         "appleStylus": "Apple stylus",
-        "areYouSure": "Are you sure?",
+        "areYouSure": "Do you want to perform this action ?",
         "atRange": "at",
         "attachmentAdded": "Attachment added",
         "attachmentViewed": "Attachment viewed",
diff --git a/lang/fr.json b/lang/fr.json
index 2ff57f0027a27dbe5f574353be065f27886125ba..5d09b232045322b789fce5d83e17456dc63bd859 100755
--- a/lang/fr.json
+++ b/lang/fr.json
@@ -13,7 +13,7 @@
 		"annotationAdded"                    : "Annotation ajoutée",
 		"annotationMode"                     : "Mode de l'annotation",
 		"appleStylus"                        : "Stylet Apple",
-		"areYouSure"                         : "Êtes-vous sûr ?",
+		"areYouSure"                         : "Voulez-vous effectuer cette action ?",
 		"atRange"                            : "à",
 		"attachmentAdded"                    : "Pièce jointe ajoutée",
 		"attachmentViewed"                   : "Pièce jointe consulté",
diff --git a/src/app/document/controllers/DocumentController.php b/src/app/document/controllers/DocumentController.php
index a4a7df614533e3283423da57aff2cf06846c1f2a..a4f05f673d49fe324163166874d7f0c7b03b0db8 100755
--- a/src/app/document/controllers/DocumentController.php
+++ b/src/app/document/controllers/DocumentController.php
@@ -132,7 +132,8 @@ class DocumentController
 
     public function getById(Request $request, Response $response, array $args)
     {
-        if (!DocumentController::hasRightById(['id' => $args['id'], 'userId' => $GLOBALS['id']]) && !PrivilegeController::hasPrivilege(['userId' => $GLOBALS['id'], 'privilege' => 'manage_documents'])) {
+        $canManageDocuments = PrivilegeController::hasPrivilege(['userId' => $GLOBALS['id'], 'privilege' => 'manage_documents']);
+        if (!$canManageDocuments && !DocumentController::hasRightById(['id' => $args['id'], 'userId' => $GLOBALS['id'], 'readOnly' => true])) {
             return $response->withStatus(403)->withJson(['errors' => 'Document out of perimeter']);
         }
 
@@ -226,9 +227,15 @@ class DocumentController
             }
         }
 
-        if (!empty($currentId) && $currentId != $GLOBALS['id']) {
-            $substitute = UserModel::getById(['id' => $currentId, 'select' => ['substitute']]);
-            $formattedDocument['readOnly'] = $GLOBALS['id'] != $substitute['substitute'] && PrivilegeController::hasPrivilege(['userId' => $GLOBALS['id'], 'privilege' => 'manage_documents']);
+        $formattedDocument['readOnly'] = !$canManageDocuments;
+        if ($formattedDocument['readOnly'] && !empty($currentId)) {
+            if ($currentId == $GLOBALS['id']) {
+                $formattedDocument['readOnly'] = false;
+            } else {
+                $substitute = UserModel::getById(['id' => $currentId, 'select' => ['substitute']]);
+                $substitute = $substitute['substitute'] ?? null;
+                $formattedDocument['readOnly'] = $GLOBALS['id'] != $substitute;
+            }
         }
 
         $formattedDocument['attachments'] = [];
@@ -268,7 +275,8 @@ class DocumentController
 
     public function getContent(Request $request, Response $response, array $args)
     {
-        if (!DocumentController::hasRightById(['id' => $args['id'], 'userId' => $GLOBALS['id']]) && !PrivilegeController::hasPrivilege(['userId' => $GLOBALS['id'], 'privilege' => 'manage_documents'])) {
+        if (!PrivilegeController::hasPrivilege(['userId' => $GLOBALS['id'], 'privilege' => 'manage_documents'])
+            && !DocumentController::hasRightById(['id' => $args['id'], 'userId' => $GLOBALS['id'], 'readOnly' => true])) {
             return $response->withStatus(403)->withJson(['errors' => 'Document out of perimeter']);
         }
 
@@ -1042,7 +1050,8 @@ class DocumentController
 
     public function getThumbnailContent(Request $request, Response $response, array $args)
     {
-        if (!DocumentController::hasRightById(['id' => $args['id'], 'userId' => $GLOBALS['id']]) && !PrivilegeController::hasPrivilege(['userId' => $GLOBALS['id'], 'privilege' => 'manage_documents'])) {
+        if (!PrivilegeController::hasPrivilege(['userId' => $GLOBALS['id'], 'privilege' => 'manage_documents'])
+            && !DocumentController::hasRightById(['id' => $args['id'], 'userId' => $GLOBALS['id'], 'readOnly' => true])) {
             return $response->withStatus(403)->withJson(['errors' => 'Document out of perimeter']);
         }
 
@@ -1177,25 +1186,48 @@ class DocumentController
     {
         ValidatorModel::notEmpty($args, ['id', 'userId']);
         ValidatorModel::intVal($args, ['id', 'userId']);
+        ValidatorModel::boolType($args, ['readOnly']);
+
+        $args['readOnly'] = $args['readOnly'] ?? false;
+        $args['id']       = (int)$args['id'];
+        $args['userId']   = (int)$args['userId'];
 
         $document = DocumentModel::getById(['select' => ['typist'], 'id' => $args['id']]);
-        if ($document['typist'] == $GLOBALS['id']) {
+        if (!empty($document['typist']) && $document['typist'] == $GLOBALS['id']) {
             return true;
         }
 
-        $workflow = WorkflowModel::getCurrentStep(['select' => ['user_id'], 'documentId' => $args['id']]);
-        if (empty($workflow) || empty($workflow['user_id'])) {
-            return false;
-        }
-
-        if ($workflow['user_id'] != $args['userId']) {
-            $user = UserModel::getById(['id' => $workflow['user_id'], 'select' => ['substitute']]);
-            if ($user['substitute'] != $args['userId']) {
+        if (!$args['readOnly']) {
+            $currentStep = WorkflowModel::getCurrentStep(['select' => ['user_id'], 'documentId' => $args['id']]);
+            if (empty($currentStep) || empty($currentStep['user_id'])) {
                 return false;
             }
+
+            if ($currentStep['user_id'] == $args['userId']) {
+                return true;
+            } else {
+                $user = UserModel::getById(['id' => $args['userId'], 'select' => ['substitute']]);
+                return $currentStep['user_id'] == $user['substitute'];
+            }
         }
 
-        return true;
+        $canReadOnly = WorkflowModel::get([
+            'select' => [1],
+            'where'  => [
+                'main_document_id = ?',
+                '(process_date IS NOT NULL AND user_id = ?)
+                OR (
+                    user_id IN (
+                        SELECT (SELECT ?::int) UNION (SELECT id FROM users WHERE substitute = ?)
+                    )
+                    AND "order" = (
+                        SELECT min(ws2."order") FROM workflows ws2 WHERE ws2.process_date IS NULL AND ws2.main_document_id = main_document_id
+                    )
+                )'
+            ],
+            'data' => [$args['id'], $args['userId'], $args['userId'], $args['userId']]
+        ]);
+        return !empty($canReadOnly);
     }
 
     public static function getEncodedDocumentFromEncodedZip(array $args)
diff --git a/src/app/history/controllers/HistoryController.php b/src/app/history/controllers/HistoryController.php
index a7df7fa2e01c321ccf9e54a0bb2c55f8e36f2557..d18d15f0f24656b46cb5ede255639a0b9a0c027d 100644
--- a/src/app/history/controllers/HistoryController.php
+++ b/src/app/history/controllers/HistoryController.php
@@ -392,7 +392,8 @@ class HistoryController
             return $response->withStatus(400)->withJson(['errors' => 'Route id is not an integer']);
         }
 
-        if (!DocumentController::hasRightById(['id' => $args['id'], 'userId' => $GLOBALS['id']]) && !PrivilegeController::hasPrivilege(['userId' => $GLOBALS['id'], 'privilege' => 'manage_documents'])) {
+        if (!PrivilegeController::hasPrivilege(['userId' => $GLOBALS['id'], 'privilege' => 'manage_documents'])
+            && !DocumentController::hasRightById(['id' => $args['id'], 'userId' => $GLOBALS['id'], 'readOnly' => true])) {
             return $response->withStatus(403)->withJson(['errors' => 'Document out of perimeter']);
         }
 
diff --git a/src/app/search/controllers/SearchController.php b/src/app/search/controllers/SearchController.php
index d7e1a654039b7716e765d7a1e4da29271ea5c577..3df92ff62f0085c53315bbe8a155a0f83f96b5f5 100755
--- a/src/app/search/controllers/SearchController.php
+++ b/src/app/search/controllers/SearchController.php
@@ -38,16 +38,21 @@ class SearchController
         $data  = [];
         $hasFullRights = PrivilegeController::hasPrivilege(['userId' => $GLOBALS['id'], 'privilege' => 'manage_documents']);
         if (!$hasFullRights) {
-            $substitutedUsers = UserModel::get(['select' => ['id'], 'where' => ['substitute = ?'], 'data' => [$GLOBALS['id']]]);
-            $users = [$GLOBALS['id']];
-            foreach ($substitutedUsers as $value) {
-                $users[] = $value['id'];
-            }
-
-            $workflowSelect = "SELECT id FROM workflows ws WHERE workflows.main_document_id = main_document_id AND process_date IS NULL AND status IS NULL ORDER BY \"order\" LIMIT 1";
-            $workflowSelect = "SELECT main_document_id FROM workflows WHERE user_id in (?) AND id in ({$workflowSelect})";
-            $where          = ["(id in ({$workflowSelect}) OR typist = ?)"];
-            $data           = [$users, $GLOBALS['id']];
+            $where = ['id IN (
+                SELECT DISTINCT ws1.main_document_id
+                FROM workflows ws1
+                WHERE typist = ?
+                OR (ws1.process_date IS NOT NULL AND ws1.user_id = ?)
+                OR (
+                    ws1.user_id IN (
+                        SELECT (SELECT ?::int) UNION (SELECT id FROM users WHERE substitute = ?)
+                    )
+                    AND ws1."order" = (
+                        SELECT min(ws2."order") FROM workflows ws2 WHERE ws2.process_date IS NULL AND ws2.main_document_id = ws1.main_document_id
+                    )
+                )
+            )'];
+            $data = [$GLOBALS['id'], $GLOBALS['id'], $GLOBALS['id'], $GLOBALS['id']];
         }
 
         $whereWorkflow = [];