diff --git a/src/module_vmap/web_service/ws/Querys.class.inc b/src/module_vmap/web_service/ws/Querys.class.inc
index 83c9db4f1920fca235af51b6ea3c67cb4c804b62..41656427c4bfaae5f067386cae79fe4eceff5579 100644
--- a/src/module_vmap/web_service/ws/Querys.class.inc
+++ b/src/module_vmap/web_service/ws/Querys.class.inc
@@ -1445,53 +1445,8 @@ class Querys extends Vmap {
 
         $this->aValues['my_vitis_id'] = $this->aValues[$bo_id_field];
 
-        // Fichiers inchangés à ne pas supprimer
-        if (!empty($this->aValues['vitis_unchanged_files'])) {
-            $aUnchangedFiles = json_decode($this->aValues['vitis_unchanged_files'], true);
-        }
-
-        // Fichiers à supprimer ?
-        if (!empty($this->aValues['vitis_deleted_files'])) {
-            $aDeletedFiles = json_decode($this->aValues['vitis_deleted_files'], true);
-            foreach ($aDeletedFiles as $sName => $aFile) {
-                // Supprime les fichiers
-                $this->oFilesManager->cleanWsDataDir('vitis', $sBusinessObjectId, $this->aValues['my_vitis_id'], $sName, 'documents', $aDeletedFiles[$sName], false);
-                // Set aValues avec les fichiers restants
-                $this->aValues[$sName] = null;
-                if (!empty($aUnchangedFiles[$sName])) {
-                    $this->aValues[$sName] = implode('|', $aUnchangedFiles[$sName]);
-                }
-            }
-        }
-
-        // Fichiers à uploader ?
-        if (!empty($_FILES) && !empty($this->aValues['my_vitis_id'])) {
-            foreach ($_FILES as $sName => $aFile) {
-
-                // Fichiers à ne pas supprimer
-                $aExceptions = [];
-                if (!empty($aUnchangedFiles[$sName])) {
-                    $aExceptions = $aUnchangedFiles[$sName];
-                }
-
-                // Nettoyage de l'espace ws_data
-                $this->oFilesManager->cleanWsDataDir('vitis', $sBusinessObjectId, $this->aValues['my_vitis_id'], $sName, 'documents', false, $aExceptions);
-
-                // Écriture des fichiers
-                $aUploadReturn = $this->oFilesManager->uploadInWsDataDir('vitis', $sBusinessObjectId, $this->aValues['my_vitis_id'], $sName, 'documents', -1, "all", null, true);
-                $this->aValues[$sName] = $aUploadReturn['field_value'];
-
-                // Re-inscrit en base les fichiers à ne pas supprimer
-                $aFiles = explode('|', $this->aValues[$sName]);
-                for ($i=0; $i < count($aExceptions); $i++) {
-                    array_unshift($aFiles, $aExceptions[$i]);
-                }
-                $this->aValues[$sName] = implode('|', $aFiles);
-            }
-        }
-
         // Maj en base
-        $aReturn = $this->genericPut($bo_schema, $bo_table, $bo_id_field);
+        $aReturn = $this->genericPut($bo_schema, $bo_table, $bo_id_field, '*', $sBusinessObjectId, "vitis", "documents");
 
         // Lance l'évènement webSocket
         if (!empty($bo_event)) {
@@ -1658,19 +1613,7 @@ class Querys extends Vmap {
         // $this->aValues['my_vitis_id'] = $this->aValues[$bo_id_field];
         unset($this->aValues['my_vitis_id']);
 
-        $aReturn = $this->genericPost($bo_schema, $bo_table, '', $bo_id_field);
-
-        // Fichiers à uploader ?
-        if (!empty($_FILES) && !empty($this->aValues['my_vitis_id'])) {
-
-            // Écriture du fichier
-            foreach ($_FILES as $sName => $aFile) {
-                $aUploadReturn = $this->oFilesManager->uploadInWsDataDir('vitis', $sBusinessObjectId, $this->aValues['my_vitis_id'], $sName, 'documents');
-                $this->aValues[$sName] = $aUploadReturn['field_value'];
-            }
-
-            $this->genericPut($bo_schema, $bo_table, $bo_id_field);
-        }
+        $aReturn = $this->genericPost($bo_schema, $bo_table, '', $bo_id_field, '*', $sBusinessObjectId, "vitis", "documents");
 
         // Lance l'évènement webSocket
         if (!empty($bo_event)) {
diff --git a/src/vitis/vas/rest/ws/vitis/Vitis.class.inc b/src/vitis/vas/rest/ws/vitis/Vitis.class.inc
index 8a5c4da59651c0c09d1dd64ad8a91f9d2926a22a..4b58b7fc1ef463d36c79674be01d31a3e009d7a6 100644
--- a/src/vitis/vas/rest/ws/vitis/Vitis.class.inc
+++ b/src/vitis/vas/rest/ws/vitis/Vitis.class.inc
@@ -527,15 +527,18 @@ class Vitis extends DbClass {
     }
 
     /**
-     *
-     * @param type $sSchema schema containing the table
-     * @param type $sTable table to update
-     * @param type $sSequence  used sequence to get the id
-     * @param type $sIdField id field name
-     * @param type $sPrivilegeParent privilege to do the insertion
+     * Generic function to insert data using $this->aValues
+     * @param $sSchema schema containing the table
+     * @param $sTable table to update
+     * @param $sSequence  used sequence to get the id
+     * @param $sIdField id field name
+     * @param $aUploadFiles : uploaded files array (more info on function genericPutFiles)
+     * @param $sVitisObjectName for upload files : object name
+     * @param $sVitisModuleName for upload files : module name
+     * @param $sVitisPathComplement for upload files : complement folder on put files (ws_data/vitis/.../documents/...)
      * @return array containing the status and the message
      */
-    function genericPost($sSchema, $sTable, $sSequence, $sIdField) {
+    function genericPost($sSchema, $sTable, $sSequence, $sIdField, $aUploadFiles = false, $sVitisObjectName = "", $sVitisModuleName = "vitis", $sVitisPathComplement = "documents") {
         if (isset($this->aValues['sEncoding']))
             $sEncoding = $this->aValues['sEncoding'];
         else
@@ -550,10 +553,10 @@ class Vitis extends DbClass {
             $aXmlRacineAttribute['status'] = 0;
             $sMessage = $oError->asDocument('', 'vitis', $sEncoding, True, $aXmlRacineAttribute, $sSourceEncoding, $this->aValues['output']);
         } else {
-            // verify if the user is framework_admin
+            // verify if the user privileges
             $this->getTablePrivileges($sSchema, $sTable);
-            //$aPrivileges = array_intersect($this->oConnection->aPrivileges, $this->aTablePrivileges) ;
             if (in_array('INSERT', $this->aTablePrivileges)) {
+
                 // insert user in table
                 $iId = $this->oConnection->oBd->insert($sSchema, $sTable, $this->aValues, $sSequence, $sIdField);
                 if ($this->oConnection->oBd->enErreur()) {
@@ -564,6 +567,13 @@ class Vitis extends DbClass {
                     $this->aFields[$sIdField] = $iId;
                     $this->aValues['my_vitis_id'] = $iId;
 
+                    // Upload de fichiers
+                    if (($aUploadFiles !== false) && ($sVitisObjectName != "")) {
+                        // Upload the files in $_FILES and $aUploadFiles
+                        // Updade $this->aValues
+                        $this->genericPut($sSchema, $sTable, $sIdField, $aUploadFiles, $sVitisObjectName, $sVitisModuleName, $sVitisPathComplement);
+                    }
+
                     $aXmlRacineAttribute['status'] = 1;
                     $sMessage = $this->asDocument('', 'vitis', $sEncoding, True, $aXmlRacineAttribute, $sSourceEncoding, $this->aValues['output']);
                 }
@@ -578,14 +588,17 @@ class Vitis extends DbClass {
     }
 
     /**
-     *
-     * @param type $sSchema schema containing the table
-     * @param type $sTable table to update
-     * @param type $sIdField id field name
-     * @param type $sPrivilegeParent privilege to do the insertion
+     * Generic function to update data using $this->aValues
+     * @param $sSchema schema containing the table
+     * @param $sTable table to update
+     * @param $sIdField id field name
+     * @param $aUploadFiles : uploaded files array (more info on function genericPutFiles)
+     * @param $sVitisObjectName for upload files : object name
+     * @param $sVitisModuleName for upload files : module name
+     * @param $sVitisPathComplement for upload files : complement folder on put files (ws_data/vitis/.../documents/...)
      * @return array containing the status and the message
      */
-    function genericPut($sSchema, $sTable, $sIdField) {
+    function genericPut($sSchema, $sTable, $sIdField, $aUploadFiles = false, $sVitisObjectName = "", $sVitisModuleName = "vitis", $sVitisPathComplement = "documents") {
         if (isset($this->aValues['sEncoding']))
             $sEncoding = $this->aValues['sEncoding'];
         else
@@ -594,14 +607,26 @@ class Vitis extends DbClass {
             $sSourceEncoding = $this->aValues['sSourceEncoding'];
         else
             $sSourceEncoding = null;
+
+        // Test connection
         if ($this->oConnection->oError != null) {
             $oError = $this->oConnection->oError;
             $aXmlRacineAttribute['status'] = 0;
             $sMessage = $oError->asDocument('', 'vitis', $sEncoding, True, $aXmlRacineAttribute, $sSourceEncoding, $this->aValues['output']);
         } else {
+
+            // Test privilèges
             $this->getTablePrivileges($sSchema, $sTable);
-            //$aPrivileges = array_intersect($this->oConnection->aPrivileges, $this->aTablePrivileges) ;
             if (in_array('UPDATE', $this->aTablePrivileges)) {
+
+                // Upload de fichiers
+                if (($aUploadFiles !== false) && ($sVitisObjectName != "")) {
+                    // Upload the files in $_FILES and $aUploadFiles
+                    // Updade $this->aValues
+                    $this->genericPutFiles($aUploadFiles, $sVitisObjectName, $sVitisModuleName, $sVitisPathComplement);
+                }
+
+                // Upload DBB
                 $iId = $this->oConnection->oBd->update($sSchema, $sTable, $this->aValues, $sIdField, $this->aValues['my_vitis_id'], "text");
                 if ($this->oConnection->oBd->enErreur()) {
                     $oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
@@ -1431,5 +1456,106 @@ class Vitis extends DbClass {
         else
             return $sField;
     }
+
+    /**
+     * Put the files present on $_FILES and aValues on the specified dir (ws_data, S3 ...)
+     * @param $aUploadFiles for upload files : two dimensional array of uploaded files columns or * to allow everyting
+     * ex : $aUploadFiles = [
+     *      'image_col' => [
+     *          'width' => 800
+     *          'height' => 600
+     *      ],
+     *      'doc_col' => []
+     * ]
+     * @param $sVitisObjectName for upload files : object name (ex : user)
+     * @param $sVitisModuleName for upload files : module name (ex : vitis)
+     * @param $sVitisPathComplement for upload files : complement folder on put files (ws_data/vitis/.../documents/...)
+     */
+    function genericPutFiles($aUploadFiles, $sVitisObjectName, $sVitisModuleName = 'vitis', $sVitisPathComplement = 'documents') {
+
+        if ($sVitisObjectName == "" || $aUploadFiles == false || empty($this->aValues['my_vitis_id'])) {
+            return false;
+        }
+
+        // Noms des colonnes à uploader
+        $aUploadFilesCols = [];
+        if (is_array($aUploadFiles)) {
+            $aUploadFilesCols = array_keys($aUploadFiles);
+        }
+
+        // Fichiers inchangés à ne pas supprimer
+        if (!empty($this->aValues['vitis_unchanged_files'])) {
+            $aUnchangedFiles = json_decode($this->aValues['vitis_unchanged_files'], true);
+        }
+
+        // Fichiers à supprimer ?
+        if (!empty($this->aValues['vitis_deleted_files'])) {
+            $aDeletedFiles = json_decode($this->aValues['vitis_deleted_files'], true);
+            foreach ($aDeletedFiles as $sFieldName => $aFile) {
+
+                // Vérifie la présence du champ
+                if (in_array($sFieldName, $aUploadFilesCols) || $aUploadFiles === '*') {
+
+                    // Supprime les fichiers
+                    $this->oFilesManager->cleanWsDataDir($sVitisModuleName, $sVitisObjectName, $this->aValues['my_vitis_id'], $sFieldName, $sVitisPathComplement, $aDeletedFiles[$sFieldName], false);
+
+                    // Set aValues avec les fichiers restants
+                    $this->aValues[$sFieldName] = null;
+                    if (!empty($aUnchangedFiles[$sFieldName])) {
+                        $this->aValues[$sFieldName] = implode('|', $aUnchangedFiles[$sFieldName]);
+                    }
+                }
+            }
+        }
+
+        // Fichiers à uploader ?
+        if (!empty($_FILES) && !empty($this->aValues['my_vitis_id'])) {
+            foreach ($_FILES as $sFieldName => $aFile) {
+
+                // Vérifie la présence du champ
+                if (in_array($sFieldName, $aUploadFilesCols) || $aUploadFiles === '*') {
+
+                    // width / height
+                    if (!empty($aUploadFilesCols[$sFieldName]['width']) &&
+                        !empty($aUploadFilesCols[$sFieldName]['height'])) {
+
+                        // Fichier unique
+                        if (!empty($_FILES[$sFieldName]['name'])) {
+                            $_FILES[$sFieldName]['width'] = $aUploadFilesCols[$sFieldName]['width'];
+                            $_FILES[$sFieldName]['height'] = $aUploadFilesCols[$sFieldName]['height'];
+                        }
+
+                        // Fichiers multiples
+                        if (!empty($_FILES[$sFieldName][0]['name'])) {
+                            for ($i=0; $i < count($_FILES[$sFieldName]); $i++) {
+                                $_FILES[$sFieldName][$i]['width'] = $aUploadFilesCols[$sFieldName]['width'];
+                                $_FILES[$sFieldName][$i]['height'] = $aUploadFilesCols[$sFieldName]['height'];
+                            }
+                        }
+                    }
+
+                    // Fichiers à ne pas supprimer
+                    $aExceptions = [];
+                    if (!empty($aUnchangedFiles[$sFieldName])) {
+                        $aExceptions = $aUnchangedFiles[$sFieldName];
+                    }
+
+                    // Nettoyage de l'espace ws_data
+                    $this->oFilesManager->cleanWsDataDir($sVitisModuleName, $sVitisObjectName, $this->aValues['my_vitis_id'], $sFieldName, $sVitisPathComplement, false, $aExceptions);
+
+                    // Écriture des fichiers
+                    $aUploadReturn = $this->oFilesManager->uploadInWsDataDir($sVitisModuleName, $sVitisObjectName, $this->aValues['my_vitis_id'], $sFieldName, $sVitisPathComplement, -1, "all", null, true);
+                    $this->aValues[$sFieldName] = $aUploadReturn['field_value'];
+
+                    // Re-inscrit en base les fichiers à ne pas supprimer
+                    $aFiles = explode('|', $this->aValues[$sFieldName]);
+                    for ($i=0; $i < count($aExceptions); $i++) {
+                        array_unshift($aFiles, $aExceptions[$i]);
+                    }
+                    $this->aValues[$sFieldName] = implode('|', $aFiles);
+                }
+            }
+        }
+    }
 }
 ?>