diff --git a/apps/maarch_entreprise/indexing_searching/details.php b/apps/maarch_entreprise/indexing_searching/details.php
index f3077c23ecca04461ec9fa52d3d49c8ccd682d02..ae4206c33c914f77c702ba9bad5462010cb14bfb 100755
--- a/apps/maarch_entreprise/indexing_searching/details.php
+++ b/apps/maarch_entreprise/indexing_searching/details.php
@@ -164,7 +164,7 @@ if (isset($s_id) && !empty($s_id) && $_SESSION['history']['resview'] == 'true')
     );
 }
 
-$modify_doc = $core->test_service('edit_document_in_detail', 'apps', false);
+$modify_doc = $core->test_service('edit_resource', 'apps', false);
 
 //UPDATE DATAS (IF FIELDS CAN BE MODIFIED) OF DOC
 if (isset($_POST['submit_index_doc'])) {
diff --git a/migration/19.12/1912.sql b/migration/19.12/1912.sql
index 12f40465bc47bfca109c62c3e22e16a0be4dfd70..e9f6c52ed852b9e13d8edeb3797e473e78c7bd15 100644
--- a/migration/19.12/1912.sql
+++ b/migration/19.12/1912.sql
@@ -425,6 +425,7 @@ WHERE service_id = 'edit_recipient_outside_process' OR service_id = 'update_diff
 DELETE FROM usergroups_services WHERE service_id = 'edit_recipient_outside_process';
 DELETE FROM usergroups_services WHERE service_id = 'update_list_diff_in_details';
 DELETE FROM usergroups_services WHERE service_id = 'edit_recipient_in_process';
+UPDATE usergroups_services SET service_id = 'edit_resource' WHERE service_id = 'edit_document_in_detail';
 
 UPDATE usergroups_services SET service_id = 'manage_own_attachments_in_details' WHERE service_id = 'edit_attachments_from_detail';
 INSERT INTO usergroups_services (group_id, service_id)
diff --git a/rest/index.php b/rest/index.php
index 86f81e447acbef8e7dcdd189b92b9ee5af334cfe..2cf0c2f4172b3f18b37333440b1ab9a8894c7a9e 100755
--- a/rest/index.php
+++ b/rest/index.php
@@ -317,6 +317,7 @@ $app->put('/reports/groups/{groupId}', \Report\controllers\ReportController::cla
 //Resources
 $app->post('/resources', \Resource\controllers\ResController::class . ':create');
 $app->get('/resources/{resId}', \Resource\controllers\ResController::class . ':getById');
+$app->put('/resources/{resId}', \Resource\controllers\ResController::class . ':update');
 $app->get('/resources/{resId}/content', \Resource\controllers\ResController::class . ':getFileContent');
 $app->get('/resources/{resId}/originalContent', \Resource\controllers\ResController::class . ':getOriginalFileContent');
 $app->get('/resources/{resId}/thumbnail', \Resource\controllers\ResController::class . ':getThumbnailContent');
diff --git a/sql/data_en.sql b/sql/data_en.sql
index 5b4556490d31585fd8b2dcccca547642bbbbd045..eab4e9e7fd09c33357170714e4782d8f3074f2bc 100644
--- a/sql/data_en.sql
+++ b/sql/data_en.sql
@@ -50,7 +50,7 @@ INSERT INTO usergroups_services (group_id, service_id) VALUES ('COURRIER', 'view
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('COURRIER', 'view_full_history');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('COURRIER', 'add_links');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('COURRIER', 'delete_document_in_detail');
-INSERT INTO usergroups_services (group_id, service_id) VALUES ('COURRIER', 'edit_document_in_detail');
+INSERT INTO usergroups_services (group_id, service_id) VALUES ('COURRIER', 'edit_resource');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('COURRIER', 'entities_print_sep_mlb');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('COURRIER', 'update_diffusion_indexing');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('COURRIER', 'update_diffusion_details');
@@ -104,7 +104,7 @@ INSERT INTO usergroups_services (group_id, service_id) VALUES ('RESP_COURRIER',
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('RESP_COURRIER', 'view_full_history');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('RESP_COURRIER', 'add_links');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('RESP_COURRIER', 'delete_document_in_detail');
-INSERT INTO usergroups_services (group_id, service_id) VALUES ('RESP_COURRIER', 'edit_document_in_detail');
+INSERT INTO usergroups_services (group_id, service_id) VALUES ('RESP_COURRIER', 'edit_resource');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('RESP_COURRIER', 'edit_recipient_outside_process');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('RESP_COURRIER', 'update_list_diff_in_details');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('RESP_COURRIER', 'sendmail');
@@ -168,7 +168,7 @@ INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N1', 'admin_parameters');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N1', 'admin_priorities');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N1', 'delete_document_in_detail');
-INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N1', 'edit_document_in_detail');
+INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N1', 'edit_resource');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N1', 'admin_baskets');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N1', 'manage_entities');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N1', 'admin_difflist_types');
@@ -203,7 +203,7 @@ INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N2', 'admin');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N2', 'view_doc_history');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N2', 'view_full_history');
-INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N2', 'edit_document_in_detail');
+INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N2', 'edit_resource');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N2', 'admin_templates');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N2', 'admin_tag');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('ARCHIVISTE', 'adv_search_mlb');
diff --git a/sql/data_fr.sql b/sql/data_fr.sql
index 1c17fc53c34d36f97a3799616db7b4e589728b70..a043e53cd75f1c4142c20b39b80c892c817078f5 100755
--- a/sql/data_fr.sql
+++ b/sql/data_fr.sql
@@ -53,7 +53,7 @@ INSERT INTO usergroups_services (group_id, service_id) VALUES ('COURRIER', 'view
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('COURRIER', 'view_full_history');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('COURRIER', 'add_links');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('COURRIER', 'delete_document_in_detail');
-INSERT INTO usergroups_services (group_id, service_id) VALUES ('COURRIER', 'edit_document_in_detail');
+INSERT INTO usergroups_services (group_id, service_id) VALUES ('COURRIER', 'edit_resource');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('COURRIER', 'update_diffusion_indexing');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('COURRIER', 'update_diffusion_details');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('COURRIER', 'entities_print_sep_mlb');
@@ -108,7 +108,7 @@ INSERT INTO usergroups_services (group_id, service_id) VALUES ('RESP_COURRIER',
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('RESP_COURRIER', 'view_full_history');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('RESP_COURRIER', 'add_links');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('RESP_COURRIER', 'delete_document_in_detail');
-INSERT INTO usergroups_services (group_id, service_id) VALUES ('RESP_COURRIER', 'edit_document_in_detail');
+INSERT INTO usergroups_services (group_id, service_id) VALUES ('RESP_COURRIER', 'edit_resource');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('RESP_COURRIER', 'update_diffusion_indexing');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('RESP_COURRIER', 'update_diffusion_details');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('RESP_COURRIER', 'sendmail');
@@ -174,7 +174,7 @@ INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N1', 'admin_parameters');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N1', 'admin_priorities');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N1', 'delete_document_in_detail');
-INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N1', 'edit_document_in_detail');
+INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N1', 'edit_resource');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N1', 'admin_email_server');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N1', 'admin_shippings');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N1', 'admin_baskets');
@@ -212,7 +212,7 @@ INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N2', 'admin');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N2', 'view_doc_history');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N2', 'view_full_history');
-INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N2', 'edit_document_in_detail');
+INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N2', 'edit_resource');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N2', 'admin_templates');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('ADMINISTRATEUR_N2', 'admin_tag');
 INSERT INTO usergroups_services (group_id, service_id) VALUES ('ARCHIVISTE', 'adv_search_mlb');
diff --git a/src/app/attachment/controllers/AttachmentController.php b/src/app/attachment/controllers/AttachmentController.php
index e02d96b4fd5f633a1710c69a2f26d2167c90f4ab..6e137762f7d9cbf4f11795f88a98e9f8cb542499 100755
--- a/src/app/attachment/controllers/AttachmentController.php
+++ b/src/app/attachment/controllers/AttachmentController.php
@@ -86,7 +86,7 @@ class AttachmentController
         $attachment = AttachmentModel::getById([
             'id'        => $args['id'],
             'select'    => [
-                'res_id_master', 'status', 'title', 'identifier as chrono', 'relation', 'attachment_type as type',
+                'res_id as "resId"', 'res_id_master', 'status', 'title', 'identifier as chrono', 'relation', 'attachment_type as type',
                 'origin_id as "originId"', 'creation_date as "creationDate"', 'modification_date as "modificationDate"', 'validation_date as "validationDate"',
                 'fulltext_result as "fulltextResult"', 'in_signature_book as "inSignatureBook"', 'in_send_attach as "inSendAttach"'
             ]
diff --git a/src/app/entity/models/ListInstanceModelAbstract.php b/src/app/entity/models/ListInstanceModelAbstract.php
index 61225c8180c5be761716d1509165cfcf96825870..fdedf1aeecd705cbfa30228752a3606c18b98163 100755
--- a/src/app/entity/models/ListInstanceModelAbstract.php
+++ b/src/app/entity/models/ListInstanceModelAbstract.php
@@ -99,15 +99,15 @@ abstract class ListInstanceModelAbstract
         return true;
     }
 
-    public static function delete(array $aArgs)
+    public static function delete(array $args)
     {
-        ValidatorModel::notEmpty($aArgs, ['where', 'data']);
-        ValidatorModel::arrayType($aArgs, ['where', 'data']);
+        ValidatorModel::notEmpty($args, ['where', 'data']);
+        ValidatorModel::arrayType($args, ['where', 'data']);
 
         DatabaseModel::delete([
             'table' => 'listinstance',
-            'where' => $aArgs['where'],
-            'data'  => $aArgs['data']
+            'where' => $args['where'],
+            'data'  => $args['data']
         ]);
 
         return true;
diff --git a/src/app/resource/controllers/ResController.php b/src/app/resource/controllers/ResController.php
index 5c2d802578da3bd264531984897abd36bbf10202..9f44519a600dd8a24d2dbef0915140bd2b83058f 100755
--- a/src/app/resource/controllers/ResController.php
+++ b/src/app/resource/controllers/ResController.php
@@ -15,7 +15,6 @@
 namespace Resource\controllers;
 
 use AcknowledgementReceipt\models\AcknowledgementReceiptModel;
-use Attachment\models\AttachmentModel;
 use Basket\models\BasketModel;
 use Basket\models\RedirectBasketModel;
 use Convert\controllers\ConvertPdfController;
@@ -32,6 +31,7 @@ use Folder\controllers\FolderController;
 use Folder\models\FolderModel;
 use Folder\models\ResourceFolderModel;
 use Group\controllers\GroupController;
+use Group\controllers\PrivilegeController;
 use Group\models\PrivilegeModel;
 use History\controllers\HistoryController;
 use IndexingModel\models\IndexingModelFieldModel;
@@ -192,6 +192,53 @@ class ResController
         return $response->withJson($formattedData);
     }
 
+    public function update(Request $request, Response $response, array $args)
+    {
+        if (!Validator::intVal()->validate($args['resId']) || !ResController::hasRightByResId(['resId' => [$args['resId']], 'userId' => $GLOBALS['id']])) {
+            return $response->withStatus(403)->withJson(['errors' => 'Document out of perimeter']);
+        } elseif (!PrivilegeController::hasPrivilege(['privilegeId' => 'edit_resource', 'userId' => $GLOBALS['id']])) {
+            return $response->withStatus(403)->withJson(['errors' => 'Service forbidden']);
+        }
+
+        $body = $request->getParsedBody();
+
+        $control = ResController::controlUpdateResource(['body' => $body, 'resId' => $args['resId']]);
+        if (!empty($control['errors'])) {
+            return $response->withStatus(400)->withJson(['errors' => $control['errors']]);
+        }
+
+        $body['resId'] = $args['resId'];
+        $resId = StoreController::storeResource($body);
+        if (empty($resId) || !empty($resId['errors'])) {
+            return $response->withStatus(500)->withJson(['errors' => '[ResController update] ' . $resId['errors']]);
+        }
+
+        ResController::updateAdjacentData(['body' => $body, 'resId' => $args['resId']]);
+
+        if (!empty($body['encodedFile'])) {
+            AdrModel::deleteDocumentAdr(['where' => ['res_id = ?'], 'data' => [$args['resId']]]);
+            ConvertPdfController::convert([
+                'resId'     => $args['resId'],
+                'collId'    => 'letterbox_coll'
+            ]);
+
+            $customId = CoreConfigModel::getCustomId();
+            $customId = empty($customId) ? 'null' : $customId;
+            exec("php src/app/convert/scripts/FullTextScript.php --customId {$customId} --resId {$args['resId']} --collId letterbox_coll --userId {$GLOBALS['id']} > /dev/null &");
+        }
+
+        HistoryController::add([
+            'tableName' => 'res_letterbox',
+            'recordId'  => $args['resId'],
+            'eventType' => 'UP',
+            'info'      => _DOC_UPDATED,
+            'moduleId'  => 'resource',
+            'eventId'   => 'resourceModification',
+        ]);
+
+        return $response->withStatus(204);
+    }
+
     public function updateStatus(Request $request, Response $response)
     {
         $data = $request->getParams();
@@ -738,6 +785,53 @@ class ResController
         return true;
     }
 
+    private static function updateAdjacentData(array $args)
+    {
+        ValidatorModel::notEmpty($args, ['resId', 'body']);
+        ValidatorModel::intVal($args, ['resId']);
+        ValidatorModel::arrayType($args, ['body']);
+
+        $body = $args['body'];
+
+        if (!empty($body['diffusionList'])) {
+            ListInstanceModel::delete(['where' => ['res_id = ?', 'difflist_type = ?'], 'data' => [$args['resId'], 'entity_id']]);
+            foreach ($body['diffusionList'] as $diffusion) {
+                if ($diffusion['mode'] == 'dest') {
+                    ResModel::update(['set' => ['dest_user' => $diffusion['id']], 'where' => ['res_id = ?'], 'data' => [$args['resId']]]);
+                }
+                ListInstanceModel::create([
+                    'res_id'            => $args['resId'],
+                    'sequence'          => 0,
+                    'item_id'           => $diffusion['id'],
+                    'item_type'         => $diffusion['type'] == 'user' ? 'user_id' : 'entity_id',
+                    'item_mode'         => $diffusion['mode'],
+                    'added_by_user'     => $GLOBALS['userId'],
+                    'difflist_type'     => 'entity_id'
+                ]);
+            }
+        }
+        if (!empty($body['customFields'])) {
+            ResourceCustomFieldModel::delete(['where' => ['res_id = ?'], 'data' => [$args['resId']]]);
+            foreach ($body['customFields'] as $key => $value) {
+                ResourceCustomFieldModel::create(['res_id' => $args['resId'], 'custom_field_id' => $key, 'value' => json_encode($value)]);
+            }
+        }
+        if (!empty($body['folders'])) {
+            ResourceFolderModel::delete(['where' => ['res_id = ?'], 'data' => [$args['resId']]]);
+            foreach ($body['folders'] as $folder) {
+                ResourceFolderModel::create(['res_id' => $args['resId'], 'folder_id' => $folder]);
+            }
+        }
+        if (!empty($body['tags'])) {
+            TagResModel::delete(['where' => ['res_id = ?'], 'data' => [$args['resId']]]);
+            foreach ($body['tags'] as $tag) {
+                TagResModel::create(['res_id' => $args['resId'], 'tag_id' => $tag]);
+            }
+        }
+
+        return true;
+    }
+
     private static function controlResource(array $args)
     {
         $currentUser = UserModel::getById(['id' => $GLOBALS['id'], 'select' => ['loginmode']]);
@@ -813,6 +907,65 @@ class ResController
         return true;
     }
 
+    private static function controlUpdateResource(array $args)
+    {
+        $body = $args['body'];
+
+        $resource = ResModel::getById(['resId' => $args['resId'], 'select' => ['status']]);
+        if (empty($resource['status'])) {
+            return ['errors' => 'Resource status is empty. It can not be modified'];
+        }
+        $status = StatusModel::getById(['id' => $resource['status'], 'select' => ['can_be_modified']]);
+        if ($status['can_be_modified'] != 'Y') {
+            return ['errors' => 'Resource can not be modified because of status'];
+        }
+
+        if (empty($body)) {
+            return ['errors' => 'Body is not set or empty'];
+        } elseif (!Validator::intVal()->notEmpty()->validate($body['doctype'])) {
+            return ['errors' => 'Body doctype is empty or not an integer'];
+        }
+
+        $doctype = DoctypeModel::getById(['id' => $body['doctype'], 'select' => [1]]);
+        if (empty($doctype)) {
+            return ['errors' => 'Body doctype does not exist'];
+        }
+
+        $control = ResController::controlFileData(['body' => $body]);
+        if (!empty($control['errors'])) {
+            return ['errors' => $control['errors']];
+        }
+
+        $control = ResController::controlAdjacentData(['body' => $body, 'isWebServiceUser' => false]);
+        if (!empty($control['errors'])) {
+            return ['errors' => $control['errors']];
+        }
+
+        $control = ResController::controlIndexingModelFields(['body' => $body]);
+        if (!empty($control['errors'])) {
+            return ['errors' => $control['errors']];
+        }
+
+        if (!empty($body['initiator'])) {
+            $userEntities = UserModel::getEntitiesByLogin(['login' => $GLOBALS['userId']]);
+            $userEntities = array_column($userEntities, 'id');
+            if (!in_array($body['initiator'], $userEntities)) {
+                return ['errors' => "Body initiator does not belong to your entities"];
+            }
+        }
+
+        $control = ResController::controlDestination(['body' => $body]);
+        if (!empty($control['errors'])) {
+            return ['errors' => $control['errors']];
+        }
+        $control = ResController::controlDates(['body' => $body, 'resId' => $args['resId']]);
+        if (!empty($control['errors'])) {
+            return ['errors' => $control['errors']];
+        }
+
+        return true;
+    }
+
     private static function controlFileData(array $args)
     {
         $body = $args['body'];
@@ -979,11 +1132,19 @@ class ResController
                 return ['errors' => "Body processLimitDate is not a date"];
             }
 
+            if (!empty($args['resId'])) {
+                $resource = ResModel::getById(['resId' => $args['resId'], 'select' => ['process_limit_date']]);
+                if (!empty($resource['process_limit_date'])) {
+                    $originProcessLimitDate = new \DateTime($resource['process_limit_date']);
+                }
+            }
             $processLimitDate = new \DateTime($body['processLimitDate']);
-            $today = new \DateTime();
-            $today->setTime(00, 00, 00);
-            if ($processLimitDate < $today) {
-                return ['errors' => "Body processLimitDate is not a valid date"];
+            if (empty($originProcessLimitDate) || $originProcessLimitDate != $processLimitDate) {
+                $today = new \DateTime();
+                $today->setTime(00, 00, 00);
+                if ($processLimitDate < $today) {
+                    return ['errors' => "Body processLimitDate is not a valid date"];
+                }
             }
         } elseif (!empty($body['priority'])) {
             $priority = PriorityModel::getById(['id' => $body['priority'], 'select' => [1]]);
diff --git a/src/app/resource/controllers/StoreController.php b/src/app/resource/controllers/StoreController.php
index 7953e0053bd4649880f8bbca09eaebef198a79df..6ca9d21b9656105375c7f25762adf92965bbc2d9 100755
--- a/src/app/resource/controllers/StoreController.php
+++ b/src/app/resource/controllers/StoreController.php
@@ -30,20 +30,22 @@ class StoreController
 {
     public static function storeResource(array $args)
     {
-        ValidatorModel::notEmpty($args, ['doctype', 'modelId']);
-        ValidatorModel::intVal($args, ['doctype', 'modelId']);
-
         try {
-            $resId = DatabaseModel::getNextSequenceValue(['sequenceId' => 'res_id_mlb_seq']);
+            if (empty($args['resId'])) {
+                $resId = DatabaseModel::getNextSequenceValue(['sequenceId' => 'res_id_mlb_seq']);
 
-            $data = ['resId' => $resId];
-            $data = array_merge($args, $data);
-            $data = StoreController::prepareStorage($data);
+                $data = ['resId' => $resId];
+                $data = array_merge($args, $data);
+                $data = StoreController::prepareResourceStorage($data);
+            } else {
+                $resId = $args['resId'];
+                $data = StoreController::prepareUpdateResourceStorage($args);
+            }
 
             if (!empty($args['encodedFile'])) {
                 $fileContent = base64_decode(str_replace(['-', '_'], ['+', '/'], $args['encodedFile']));
 
-                if (in_array($args['format'], MergeController::OFFICE_EXTENSIONS)) {
+                if (empty($args['resId']) && in_array($args['format'], MergeController::OFFICE_EXTENSIONS)) {
                     $tmpPath = CoreConfigModel::getTmpPath();
                     $uniqueId = CoreConfigModel::uniqueId();
                     $tmpFilename = "storeTmp_{$GLOBALS['id']}_{$uniqueId}.{$args['format']}";
@@ -71,7 +73,11 @@ class StoreController
                 $data['format']         = $args['format'];
             }
 
-            ResModel::create($data);
+            if (empty($args['resId'])) {
+                ResModel::create($data);
+            } else {
+                ResModel::update(['set' => $data, 'where' => ['res_id = ?'], 'data' => [$args['resId']]]);
+            }
 
             return $resId;
         } catch (\Exception $e) {
@@ -122,7 +128,8 @@ class StoreController
             if (empty($args['id'])) {
                 $id = AttachmentModel::create($data);
             } else {
-                $id = AttachmentModel::update(['set' => $data, 'where' => ['res_id = ?'], 'data' => [$args['id']]]);
+                AttachmentModel::update(['set' => $data, 'where' => ['res_id = ?'], 'data' => [$args['id']]]);
+                $id = $args['id'];
             }
 
             return $id;
@@ -131,7 +138,7 @@ class StoreController
         }
     }
 
-    public static function prepareStorage(array $args)
+    public static function prepareResourceStorage(array $args)
     {
         ValidatorModel::notEmpty($args, ['resId', 'modelId']);
         ValidatorModel::intVal($args, ['resId', 'modelId']);
@@ -190,6 +197,59 @@ class StoreController
         return $preparedData;
     }
 
+    public static function prepareUpdateResourceStorage(array $args)
+    {
+        $preparedData = [
+            'modification_date' => 'CURRENT_TIMESTAMP'
+        ];
+
+        if (!empty($args['doctype'])) {
+            $preparedData['type_id'] = $args['doctype'];
+        }
+        if (isset($args['subject'])) {
+            $preparedData['subject'] = $args['subject'];
+        }
+        if (isset($args['confidentiality'])) {
+            $preparedData['confidentiality'] = empty($args['confidentiality']) ? 'N' : 'Y';
+        }
+        if (!empty($args['initiator'])) {
+            $entity = EntityModel::getById(['id' => $args['initiator'], 'select' => ['entity_id']]);
+            $preparedData['initiator'] = $entity['entity_id'];
+        }
+        if (!empty($args['destination'])) {
+            $entity = EntityModel::getById(['id' => $args['destination'], 'select' => ['entity_id']]);
+            $preparedData['destination'] = $entity['entity_id'];
+        }
+
+        if (isset($args['documentDate'])) {
+            $preparedData['doc_date'] = $args['documentDate'];
+        }
+        if (isset($args['arrivalDate'])) {
+            $preparedData['admission_date'] = $args['arrivalDate'];
+        }
+        if (isset($args['departureDate'])) {
+            $preparedData['departure_date'] = $args['departureDate'];
+        }
+        if (isset($args['processLimitDate'])) {
+            $preparedData['process_limit_date'] = $args['processLimitDate'];
+        }
+        if (isset($args['priority'])) {
+            $preparedData['priority'] = $args['priority'];
+        }
+        if (!empty($args['processLimitDate']) && !empty($args['priority'])) {
+            $preparedData['priority'] = IndexingController::calculatePriorityWithProcessLimitDate(['processLimitDate' => $args['processLimitDate']]);
+        }
+
+        if (!empty($args['externalId']) && is_array($args['externalId'])) {
+            $resource = ResModel::getById(['resId' => $args['id'], 'select' => ['external_id']]);
+            $externalId = array_merge(json_decode($resource['external_id'], true), $args['externalId']);
+            $externalId = json_encode($externalId);
+            $preparedData['external_id'] = $externalId;
+        }
+
+        return $preparedData;
+    }
+
     public static function prepareAttachmentStorage(array $args)
     {
         $attachmentsTypes = AttachmentModel::getAttachmentsTypesByXML();
diff --git a/src/core/lang/lang-en.php b/src/core/lang/lang-en.php
index 75d46231b64d5b72345a071077fb9987c20bb8b6..356a26b7d48d71bcce24728e7fbbd3ab6282fef0 100755
--- a/src/core/lang/lang-en.php
+++ b/src/core/lang/lang-en.php
@@ -139,10 +139,11 @@ define('_PATH_OF_DOCSERVER_UNAPPROACHABLE', 'Inaccessible Docserver path');
 define('_BACK_FROM_VACATION', 'back from vacation');
 define('_DOC_DISPLAYING', 'Displaying document');
 define('_DOC_ADDED', 'Document added');
+define('_DOC_UPDATED', 'Document updated');
+define('_DOC_DELETED', 'Document deleted');
 define('_ATTACHMENT_ADDED', 'Attachment added');
 define('_ATTACHMENT_UPDATED', 'Attachment updated');
 define('_ATTACH_DISPLAYING', 'Displaying attachment');
-define('_DOC_DELETED', 'Document deleted');
 define('_NOTE_ADDED', 'Note added');
 define('_NOTE_UPDATED', 'Note updated');
 define('_NOTE_DELETED', 'Note deleted');
diff --git a/src/core/lang/lang-fr.php b/src/core/lang/lang-fr.php
index 8377b9f7e4374a8ac3a454767180fb1c8a86c3d0..ff49c9bd02a11284a2909db9b58f8806016193ab 100755
--- a/src/core/lang/lang-fr.php
+++ b/src/core/lang/lang-fr.php
@@ -139,10 +139,11 @@ define('_PATH_OF_DOCSERVER_UNAPPROACHABLE', 'Chemin de la zone de stockage inacc
 define('_BACK_FROM_VACATION', 'de retour de son absence');
 define('_DOC_DISPLAYING', 'Visualisation du document');
 define('_DOC_ADDED', 'Document ajouté');
+define('_DOC_UPDATED', 'Document modifié');
+define('_DOC_DELETED', 'Document supprimé');
 define('_ATTACHMENT_ADDED', 'Pièce jointe ajoutée');
 define('_ATTACHMENT_UPDATED', 'Pièce jointe modifiée');
 define('_ATTACH_DISPLAYING', 'Visualisation de la pièce jointe');
-define('_DOC_DELETED', 'Document supprimé');
 define('_NOTE_ADDED', 'Annotation ajoutée');
 define('_NOTE_UPDATED', 'Annotation modifiée');
 define('_NOTE_DELETED', 'Annotation supprimée');
diff --git a/src/core/lang/lang-nl.php b/src/core/lang/lang-nl.php
index 16ca5e33535bc24330a4e3b68cf0651edaeee2a2..ca10cbd80176fc7e766f7ca36a59bd62839f27b4 100755
--- a/src/core/lang/lang-nl.php
+++ b/src/core/lang/lang-nl.php
@@ -139,10 +139,11 @@ define('_PATH_OF_DOCSERVER_UNAPPROACHABLE', 'Opslagruimtepad ontoegankelijk');
 define('_BACK_FROM_VACATION', 'bij terugkeer na afwezigheid');
 define('_DOC_DISPLAYING', 'Weergave van het document');
 define('_DOC_ADDED', 'Document toegevoegd');
+define('_DOC_UPDATED', 'Document updated');//translate
+define('_DOC_DELETED', 'Document deleted');//TRANSLATE
 define('_ATTACHMENT_ADDED', 'Attachment added');//TRANSLATE
 define('_ATTACHMENT_UPDATED', 'Attachment updated');//TRANSLATE
 define('_ATTACH_DISPLAYING', 'Weergave van de bijlage');
-define('_DOC_DELETED', 'Document deleted');//TRANSLATE
 define('_NOTE_ADDED', 'note added _TO_TRANSLATE');
 define('_NOTE_UPDATED', 'Note updated');//TRANSLATE
 define('_NOTE_DELETED', 'Note deleted');//TRANSLATE
diff --git a/src/frontend/lang/lang-en.ts b/src/frontend/lang/lang-en.ts
index 91cc699139d81b6e80ab9d944fc5369b8e38da5e..5326e8e09fd2360cc02ccb2fe92a4eaecab0b005 100755
--- a/src/frontend/lang/lang-en.ts
+++ b/src/frontend/lang/lang-en.ts
@@ -1187,8 +1187,8 @@ export const LANG_EN = {
     "viewHistoryDesc" : "Read the events history linked to the utilisation of Maarch.",
     "viewFullHistory" : "See Full document history",
     "viewFullHistoryDesc" : "Read the full events history linked to the utilisation of Maarch.",
-    "editDocumentInDetail" : "Edit a document in detail page",
-    "editDocumentInDetailDesc" : "Edit a document in detail page. Il will also depend on status setting (Index modification)",
+    "editResource" : "Edit a document",
+    "editResourceDesc" : "Edit a document. Il will also depend on status setting (Index modification)",
     "deleteDocumentInDetail" : "Delete a document in detail page",
     "manageTagsInApplication" : "Create tags",
     "manageTagsInApplicationDesc" : "Create tags while indexing, processing and in details",
diff --git a/src/frontend/lang/lang-fr.ts b/src/frontend/lang/lang-fr.ts
index eab376f4b3d2881a05ca5bd20c4a5e7383d2b214..cffcabf043e3e365e9f6258d8eb3c54982a64819 100755
--- a/src/frontend/lang/lang-fr.ts
+++ b/src/frontend/lang/lang-fr.ts
@@ -1224,8 +1224,8 @@ export const LANG_FR = {
     "viewHistoryDesc" : "Consulter l'historique des événements relatifs à l'utilisation de Maarch Courrier.",
     "viewFullHistory" : "Voir l'historique complet du courrier",
     "viewFullHistoryDesc" : "Consulter l'historique complet des événements relatifs à l'utilisation de la GED Maarch.",
-    "editDocumentInDetail" : "Modifier un document dans la fiche détaillée",
-    "editDocumentInDetailDesc" : "Modifier un document dans la fiche détaillée. Cela dépendra aussi du paramétrage du statut (Modification des index)",
+    "editResource" : "Modifier les données d'un courrier",
+    "editResourceDesc" : "Modifier les données d'un courrier. Cela dépendra aussi du paramétrage du statut (Modification des index)",
     "deleteDocumentInDetail" : "Supprimer un document dans la fiche détaillée",
     "manageTagsInApplication" : "Créer des mots-clés depuis les pages d'actions",
     "manageTagsInApplicationDesc" : "Créer des mots-clés depuis l'indexation, le traitement et la fiche détaillée",
diff --git a/src/frontend/lang/lang-nl.ts b/src/frontend/lang/lang-nl.ts
index fe7ef441da49482c5b7f790822ecdebd1c6e2892..5e0bd404116df738be0fc0c4b2c97e6189db7ae4 100755
--- a/src/frontend/lang/lang-nl.ts
+++ b/src/frontend/lang/lang-nl.ts
@@ -1213,8 +1213,8 @@ export const LANG_NL = {
     "viewHistoryDesc" : "De geschiedenis van de gebeurtenissen met betrekking tot het gebruik van Maarch Courrier raadplegen.",
     "viewFullHistory" : "De volledige geschiedenis van het document bekijken",
     "viewFullHistoryDesc" : "De volledige geschiedenis van de evenementen over het gebruik van GED Maarch raadplegen.",
-    "editDocumentInDetail" : "Een document in de gedetailleerde fiche wijzigen",
-    "editDocumentInDetailDesc" : "Een document in de gedetailleerde fiche wijzigen Dat zal ook van de instelling van de status afhangen (Wijziging van de indexen)",
+    "editResource" : "Een document in de gedetailleerde",
+    "editResourceDesc" : "Een document in de gedetailleerde. Dat zal ook van de instelling van de status afhangen (Wijziging van de indexen)",
     "deleteDocumentInDetail" : "Een document in de gedetailleerde fiche verwijderen",
     "manageTagsInApplication" : "Create tags", //_TO_TRANSLATE
     "manageTagsInApplicationDesc" : "Create tags while indexing, processing and in details", //_TO_TRANSLATE
diff --git a/src/frontend/service/privileges.service.ts b/src/frontend/service/privileges.service.ts
index 7e0cf6c804617ca2cccec7c429ad01bd69a5361b..468014b5bc2a6008fc430e92773f0856b28760bf 100644
--- a/src/frontend/service/privileges.service.ts
+++ b/src/frontend/service/privileges.service.ts
@@ -277,9 +277,9 @@ export class PrivilegeService {
             "unit": 'history'
         },
         {
-            "id": "edit_document_in_detail",
-            "label": this.lang.editDocumentInDetail,
-            "comment": this.lang.editDocumentInDetailDesc,
+            "id": "edit_resource",
+            "label": this.lang.editResource,
+            "comment": this.lang.editResourceDesc,
             "unit": 'application'
         },
         {