diff --git a/src/vitis/vas/rest/class/vmlib/files/Files_manager.class.inc b/src/vitis/vas/rest/class/vmlib/files/Files_manager.class.inc
index 2b9321e1ec953f579336cac6f8a30b91fa499905..d729464854e243454be5a6cee5eacb087678a466 100644
--- a/src/vitis/vas/rest/class/vmlib/files/Files_manager.class.inc
+++ b/src/vitis/vas/rest/class/vmlib/files/Files_manager.class.inc
@@ -50,117 +50,116 @@ class Files_manager{
      *@param $aFileValues File structure generated by extractFileStruct.
      *@return $sErrorMsg The error message or the final file path on success.
      */
-    private function upload_file($sNomObjet, $sFileType, $sServerPath, $sMaxSize, $aFileValues){
-             loadLang($this->sFolderLib, $this->oProperties["language"], $this->sFolderLib . "/");
-
-             $aExtension = array(
-                 "image" => array('gif', 'jpg', 'jpeg', 'png'),
-                 "image-pdf" => array('gif', 'jpg', 'jpeg', 'png', 'pdf'),
-                 "document" => array('pdf', 'gif', 'jpg', 'jpeg', 'png', 'txt'),
-                 "pdf" => array('pdf'),
-                 "zip" => array('zip', 'gex'),
-                 "fmw" => array('fmw')
-             );
-             $aForbiddenExtension = explode('|', str_replace("*.", "", $this->oProperties['forbidden_extension']));
-             $sTmpFile = "";
-             $sErrorMsg = "";
-             // si pas de aValues il y a eu une erreur pendant l'upload dans tmp du PUT
-             if (!empty($aFileValues)){
-                 $sTmpFile = $aFileValues['tmp_name'];
-
-                 // Si l'utilisateur n'a indiqué aucun fichier à uploader, il ne se passe rien
-                 if ($sTmpFile == '') {
-                     if ($aFileValues['name'] != "") {
-                         switch ($aFileValues['error']) {
-                             case "1" :
-                                 $sErrorMsg = ERROR_DOWNLOAD_FILE . $aFileValues['name'] . " : " . ERROR_UPLOAD_MAX_FILE_SIZE;
-                                 break;
-                             case "2" :
-                                 $sErrorMsg = ERROR_DOWNLOAD_FILE . $aFileValues['name'] . " : " . ERROR_MAX_FILE_SIZE;
-                                 break;
-                             case "3" :
-                                 $sErrorMsg = ERROR_DOWNLOAD_FILE . $aFileValues['name'] . " : " . ERROR_PARTIAL_DOWNLOAD;
-                                 break;
-                             case "4" :
-                                 $sErrorMsg = ERROR_NO_FILE_DOWNLOADED;
-                                 break;
-                             case "6" :
-                                 $sErrorMsg = ERROR_DOWNLOAD_FILE . $aFileValues['name'] . " : " . ERROR_MISSING_TEMP_FOLDER;
-                                 break;
-                             case "7" :
-                                 $sErrorMsg = ERROR_DOWNLOAD_FILE . $aFileValues['name'] . " : " . ERROR_WRITING_DISK;
-                                 break;
-                             case "8" :
-                                 $sErrorMsg = ERROR_DOWNLOAD_FILE . $aFileValues['name'] . " : " . ERROR_PHP_EXT_SEND;
-                                 break;
-                         }
-                         writeToErrorLog($sErrorMsg);
-                     }
-                     return $sErrorMsg;
-                 }
-
-                 $aTemp = explode("/", $sServerPath);
-
-                 $sFileName = end($aTemp);
-                 $sFileExtension = $this->extension($sFileName);
-
-                 if (!in_array($sFileExtension, $aForbiddenExtension)) {
-                     //Teste si le fichier correspont au format voulu.
-                     $bAllowUpload = false;
-                     $sFormat = "";
-
-                     if (in_array($sFileType, array_keys($aExtension))){
-                         if (in_array($sFileExtension, $aExtension[$sFileType])) {
-                             $bAllowUpload = true;
-                         } else {
-                             foreach ($aExtensionPicture as $sValue) {
-                                 $sFormat .= " " . $sValue;
-                             }
-                             writeToErrorLog(ERROR_FILE . $aFileValues['name']  . ERROR_NOT_FILE . $sFileType);
-                             $sErrorMsg = FILE_LABEL_PHPUTIL . $aFileValues['name']  . ERROR_NOT_FILE . $sFileType . ERROR_VALID_FILE . $sFormat . '.';
-                         }
-                     } else {
-                         $bAllowUpload = true;
-                     }
-
-                     //Teste si le fichier n'est pas de trop grande taille.
-                     if ($aFileValues['size'] > $sMaxSize || $aFileValues['error'] == 1) {
-                         $bAllowUpload = false;
-                         if ($aFileValues['size'] > $sMaxSize)
-                             $sErrorMsg .= FILE_LABEL_PHPUTIL . $aFileValues['name'] . OF_LABEL_PHPUTIL . $aFileValues['size'] . ERROR_EXCEED_MAX_SIZE . ' (' . $sMaxSize . LABEL_BYTES_PHPUTIL . ').';
-                         if ($aFileValues['error'] > $sMaxSize)
-                             $sErrorMsg .= FILE_LABEL_PHPUTIL . $aFileValues['name'] . ERROR_EXCEED_MAX_SIZE_PHP . ' (' . $sMaxSize . LABEL_BYTES_PHPUTIL . ').';
-                     }
-
-                     // si c'est une image avec les infos de taille final on resample
-                     if($sFileType === "image" && (isset($aFileValues["width"]) && isset($aFileValues["height"]))){
-                       $sTmpFile = pictureResampler($sTmpFile, $aFileValues["width"], $aFileValues["height"], 0, 0, 0, 0, $sFileExtension);
-                       if(!$sTmpFile){
-                         $bAllowUpload = false;
-                         writeToErrorLog(ERROR_COPYING_FILE . $aFileValues['name'] . ON_SERVER_PHPUTIL . ', while resampling picture, ' . $sServerPath);
-                         $sErrorMsg = ERROR_COPYING_FILE . $aFileValues['name'] . ON_SERVER_PHPUTIL . '.';
-                       }
-                     }
-
-                     //Lance l'upload.
-                     if ($bAllowUpload) {
-                         $sFileContent =  file_get_contents($sTmpFile);
-                         $this->oFileInterface->file_put_contents($sServerPath, $sFileContent);
-                         unlink($sTmpFile);
-                         $sErrorMsg = $sServerPath;
-                     }
-                 } else {
-                     writeToErrorLog(ERROR_FILE . $aFileValues['name'] . ERROR_NOT_FILE . $sFileType);
-                     $sErrorMsg = FILE_LABEL_PHPUTIL . $aFileValues['name'] . ERROR_NOT_FILE . $sFileType . ERROR_VALID_FILE . $sFormat . '.';
-                 }
-             } else {
-                 writeToErrorLog(ERROR_FILE . "File" . ERROR_DOWNLOAD_SERVER);
-                 $sErrorMsg = FILE_LABEL_PHPUTIL . "File" . ERROR_DOWNLOAD_SERVER . '.';
-             }
-
-             return $sErrorMsg;
-         }
-    //}
+    private function uploadFile($sNomObjet, $sFileType, $sServerPath, $sMaxSize, $aFileValues) {
+        loadLang($this->sFolderLib, $this->oProperties["language"], $this->sFolderLib . "/");
+
+        $aExtension = array(
+            "image" => array('gif', 'jpg', 'jpeg', 'png'),
+            "image-pdf" => array('gif', 'jpg', 'jpeg', 'png', 'pdf'),
+            "document" => array('pdf', 'gif', 'jpg', 'jpeg', 'png', 'txt'),
+            "pdf" => array('pdf'),
+            "zip" => array('zip', 'gex'),
+            "fmw" => array('fmw')
+        );
+        $aForbiddenExtension = explode('|', str_replace("*.", "", $this->oProperties['forbidden_extension']));
+        $sTmpFile = "";
+        $sErrorMsg = "";
+        // si pas de aValues il y a eu une erreur pendant l'upload dans tmp du PUT
+        if (!empty($aFileValues)){
+            $sTmpFile = $aFileValues['tmp_name'];
+
+            // Si l'utilisateur n'a indiqué aucun fichier à uploader, il ne se passe rien
+            if ($sTmpFile == '') {
+                if ($aFileValues['name'] != "") {
+                    switch ($aFileValues['error']) {
+                        case "1" :
+                        $sErrorMsg = ERROR_DOWNLOAD_FILE . $aFileValues['name'] . " : " . ERROR_UPLOAD_MAX_FILE_SIZE;
+                        break;
+                        case "2" :
+                        $sErrorMsg = ERROR_DOWNLOAD_FILE . $aFileValues['name'] . " : " . ERROR_MAX_FILE_SIZE;
+                        break;
+                        case "3" :
+                        $sErrorMsg = ERROR_DOWNLOAD_FILE . $aFileValues['name'] . " : " . ERROR_PARTIAL_DOWNLOAD;
+                        break;
+                        case "4" :
+                        $sErrorMsg = ERROR_NO_FILE_DOWNLOADED;
+                        break;
+                        case "6" :
+                        $sErrorMsg = ERROR_DOWNLOAD_FILE . $aFileValues['name'] . " : " . ERROR_MISSING_TEMP_FOLDER;
+                        break;
+                        case "7" :
+                        $sErrorMsg = ERROR_DOWNLOAD_FILE . $aFileValues['name'] . " : " . ERROR_WRITING_DISK;
+                        break;
+                        case "8" :
+                        $sErrorMsg = ERROR_DOWNLOAD_FILE . $aFileValues['name'] . " : " . ERROR_PHP_EXT_SEND;
+                        break;
+                    }
+                    writeToErrorLog($sErrorMsg);
+                }
+                return $sErrorMsg;
+            }
+
+            $aTemp = explode("/", $sServerPath);
+
+            $sFileName = end($aTemp);
+            $sFileExtension = $this->extension($sFileName);
+
+            if (!in_array($sFileExtension, $aForbiddenExtension)) {
+                //Teste si le fichier correspont au format voulu.
+                $bAllowUpload = false;
+                $sFormat = "";
+
+                if (in_array($sFileType, array_keys($aExtension))){
+                    if (in_array($sFileExtension, $aExtension[$sFileType])) {
+                        $bAllowUpload = true;
+                    } else {
+                        foreach ($aExtensionPicture as $sValue) {
+                            $sFormat .= " " . $sValue;
+                        }
+                        writeToErrorLog(ERROR_FILE . $aFileValues['name']  . ERROR_NOT_FILE . $sFileType);
+                        $sErrorMsg = FILE_LABEL_PHPUTIL . $aFileValues['name']  . ERROR_NOT_FILE . $sFileType . ERROR_VALID_FILE . $sFormat . '.';
+                    }
+                } else {
+                    $bAllowUpload = true;
+                }
+
+                //Teste si le fichier n'est pas de trop grande taille.
+                if ($aFileValues['size'] > $sMaxSize || $aFileValues['error'] == 1) {
+                    $bAllowUpload = false;
+                    if ($aFileValues['size'] > $sMaxSize)
+                    $sErrorMsg .= FILE_LABEL_PHPUTIL . $aFileValues['name'] . OF_LABEL_PHPUTIL . $aFileValues['size'] . ERROR_EXCEED_MAX_SIZE . ' (' . $sMaxSize . LABEL_BYTES_PHPUTIL . ').';
+                    if ($aFileValues['error'] > $sMaxSize)
+                    $sErrorMsg .= FILE_LABEL_PHPUTIL . $aFileValues['name'] . ERROR_EXCEED_MAX_SIZE_PHP . ' (' . $sMaxSize . LABEL_BYTES_PHPUTIL . ').';
+                }
+
+                // si c'est une image avec les infos de taille final on resample
+                if($sFileType === "image" && (isset($aFileValues["width"]) && isset($aFileValues["height"]))){
+                    $sTmpFile = pictureResampler($sTmpFile, $aFileValues["width"], $aFileValues["height"], 0, 0, 0, 0, $sFileExtension);
+                    if(!$sTmpFile){
+                        $bAllowUpload = false;
+                        writeToErrorLog(ERROR_COPYING_FILE . $aFileValues['name'] . ON_SERVER_PHPUTIL . ', while resampling picture, ' . $sServerPath);
+                        $sErrorMsg = ERROR_COPYING_FILE . $aFileValues['name'] . ON_SERVER_PHPUTIL . '.';
+                    }
+                }
+
+                //Lance l'upload.
+                if ($bAllowUpload) {
+                    $sFileContent =  file_get_contents($sTmpFile);
+                    $this->oFileInterface->file_put_contents($sServerPath, $sFileContent);
+                    unlink($sTmpFile);
+                    $sErrorMsg = $sServerPath;
+                }
+            } else {
+                writeToErrorLog(ERROR_FILE . $aFileValues['name'] . ERROR_NOT_FILE . $sFileType);
+                $sErrorMsg = FILE_LABEL_PHPUTIL . $aFileValues['name'] . ERROR_NOT_FILE . $sFileType . ERROR_VALID_FILE . $sFormat . '.';
+            }
+        } else {
+            writeToErrorLog(ERROR_FILE . "File" . ERROR_DOWNLOAD_SERVER);
+            $sErrorMsg = FILE_LABEL_PHPUTIL . "File" . ERROR_DOWNLOAD_SERVER . '.';
+        }
+
+        return $sErrorMsg;
+    }
 
     /**
     *This method convert $_FILE struct or the aValues File to a File Struct usable by uploadFile.
@@ -179,6 +178,20 @@ class Files_manager{
                 "error" => $_FILES[$sField]['error'],
                 "size" => $_FILES[$sField]['size']
             );
+
+            // Fichiers multiples
+            if (!empty($_FILES[$sField][0])) {
+                $aFileStruc = [];
+                for ($i=0; $i < count($_FILES[$sField]); $i++) {
+                    $aFileStruc[] = array(
+                        "name" => $_FILES[$sField][$i]['name'],
+                        "tmp_name" => $_FILES[$sField][$i]['tmp_name'],
+                        "error" => $_FILES[$sField][$i]['error'],
+                        "size" => $_FILES[$sField][$i]['size']
+                    );
+                }
+            }
+
         } else {
             // Extraction de $aValues, on le met dans tmp pour préparer la copie dans upload file
             $sTmpFile = $this->oProperties['extract_dir'] . "/" . getUniqRandomId();
@@ -205,18 +218,22 @@ class Files_manager{
 
         return $aFileStruc;
     }
+
     /**
      *This method upload a file in ws_data.
      *@param $sModule Name of the module.
      *@param $sObject Name of the object.
      *@param $mId Id of the current object.
      *@param $sField field name (generally DB column name).
+     *@param $sContainer folder between $sObject and $mId
      *@param $aValues Vitis $aValues.
      *@param $iMaxSize Maximum size to upload on server. (set to -1 to disable this control)
      *@param $sFileTypeCtrl Type of the document. (set to all to disable this control)
+     *@param $aFileStruct File structure to upload
      *@return $sErrorMsg The error message.
      */
-    public function uploadInWsDataDir ($sModule, $sObject, $mId, $sField, $aValues, $iMaxSize = -1, $sFileTypeCtrl = "all"){
+    public function uploadInWsDataDir($sModule, $sObject, $mId, $sField, $sContainer = "", $iMaxSize = -1, $sFileTypeCtrl = "all", $aFileStruct = null){
+
         // on controle les attributs pour éviter les mauvais placements
         if (strpos($sModule, '/') > -1){
             writeToErrorLog("Module can't contain path : " . $sModule);
@@ -237,12 +254,45 @@ class Files_manager{
             writeToErrorLog("Field can't contain path : " . $sField);
             return "Field can't contain path : "  . $sField;
         }
-        // on génére la Structure fichier
-        $aFileStruct = $this->extractFileStruct ($sField, $aValues);
-        // on génére la destination
-        $sDestDir = $this->oProperties['ws_data_dir'] . "/" . $sModule . "/" . $sObject . "/" . $mId;
+
+        if (strpos($sContainer, "/") > -1){
+            writeToErrorLog("Container can't contain path : " . $sContainer);
+            return "Container can't contain path : "  . $sContainer;
+        }
+
+        // Génère la Structure fichier
+        if ($aFileStruct == null) {
+            $aFileStruct = $this->extractFileStruct($sField);
+        }
+
+        error_log('$sField: '. print_r($sField, true));
+        error_log('$aFileStruct: '. print_r($aFileStruct, true));
+
+        // Fichiers multiples
+        if (!empty($aFileStruct[0]['name'])) {
+            $aReturn = array();
+            for ($i=0; $i < count($aFileStruct); $i++) {
+                // Appel récursif
+                $aResult = $this->uploadInWsDataDir($sModule, $sObject, $mId, $sField, $sContainer, $iMaxSize, $sFileTypeCtrl, $aFileStruct[$i]);
+                $aReturn['message'][] = $aResult['message'];
+                $aReturn['file_name'][] = $aResult['file_name'];
+                $aReturn['file_path'][] = $aResult['file_path'];
+            }
+            $aReturn['field_value'] = implode('|', $aReturn['file_name']);
+            return $aReturn;
+        }
+
+        // Génère la destination
+        $sDestDir = $this->oProperties['ws_data_dir'] . "/" . $sModule . "/" . $sObject;
+
+        if(!empty($sContainer)){
+            $sDestDir .= "/" . $sContainer;
+        }
+        if(!empty($mId)){
+            $sDestDir .= "/" . $mId;
+        }
         if(!empty($sField)){
-          $sDestDir .= "/" . $sField;
+            $sDestDir .= "/" . $sField;
         }
         $sDestPath =  $sDestDir . "/" . $aFileStruct["name"];
 
@@ -263,7 +313,14 @@ class Files_manager{
             }
         }
         // Upload du fichier
-        return $this->uploadFile($sField, $sFileTypeCtrl, $sDestPath, $iMaxSize, $aFileStruct);
+        $sMessage = $this->uploadFile($sField, $sFileTypeCtrl, $sDestPath, $iMaxSize, $aFileStruct);
+
+        return array(
+            'message' => $sMessage,
+            'field_value' => $aFileStruct["name"],
+            'file_name' => $aFileStruct["name"],
+            'file_path' => $sDestPath
+        );
     }
     /**
      *This method upload a file in Public.