diff --git a/src/app/document/controllers/DocumentController.php b/src/app/document/controllers/DocumentController.php
index 994724ad32a62c5dd8517eb67491f5a5e5bf6382..4c2b0b6a0a59843273a81e93d4aea0da17b3fef1 100755
--- a/src/app/document/controllers/DocumentController.php
+++ b/src/app/document/controllers/DocumentController.php
@@ -129,7 +129,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']);
         }
 
@@ -204,9 +205,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'] = [];
@@ -246,7 +253,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']);
         }
 
@@ -941,7 +949,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']);
         }
 
@@ -1022,20 +1031,43 @@ class DocumentController
     {
         ValidatorModel::notEmpty($args, ['id', 'userId']);
         ValidatorModel::intVal($args, ['id', 'userId']);
+        ValidatorModel::boolType($args, ['readOnly']);
+
+        $readOnly = $args['readOnly'] ?? false;
+        $args['id'] = (int)$args['id'];
 
         $document = DocumentModel::getById(['select' => ['typist'], 'id' => $args['id']]);
         if ($document['typist'] == $GLOBALS['id']) {
             return true;
         }
 
-        $workflow = WorkflowModel::getCurrentStep(['select' => ['user_id'], 'documentId' => $args['id']]);
-        if (empty($workflow)) {
-            return false;
-        }
+        if (!$readOnly) {
+            $workflow = WorkflowModel::getCurrentStep(['select' => ['user_id'], 'documentId' => $args['id']]);
+            if (empty($workflow)) {
+                return false;
+            }
 
-        if ($workflow['user_id'] != $args['userId']) {
-            $user = UserModel::getById(['id' => $workflow['user_id'], 'select' => ['substitute']]);
-            if ($user['substitute'] != $args['userId']) {
+            if ($workflow['user_id'] != $args['userId']) {
+                $user = UserModel::getById(['id' => $workflow['user_id'], 'select' => ['substitute']]);
+                if ($user['substitute'] != $args['userId']) {
+                    return false;
+                }
+            }
+        } else {
+            $previousStepsUsers = array_column(WorkflowModel::get([
+                'select' => ['user_id'],
+                'where'  => ['main_document_id = ?', 'process_date is not null', 'status is not null'],
+                'data'   => [$args['id']]
+            ]), 'user_id');
+            if (!empty($previousStepsUsers)) {
+                $previousStepsSubstitutes = array_column(UserModel::get([
+                    'select' => ['substitute'],
+                    'where'  => ['id in (?)'],
+                    'data'   => [$previousStepsUsers]
+                ]), 'substitute');
+                $previousStepsUsers = array_unique(array_merge($previousStepsUsers, $previousStepsSubstitutes));
+            }
+            if (!empty($previousStepsUsers) && !in_array($args['userId'], $previousStepsUsers)) {
                 return false;
             }
         }