diff --git a/apps/maarch_entreprise/xml/config.xml.default b/apps/maarch_entreprise/xml/config.xml.default
index c4f16a5eafa753b1854d31b4feb233ae930464fe..8791e5e930fc9699df7dc87d3b7fb67fcaf7db05 100755
--- a/apps/maarch_entreprise/xml/config.xml.default
+++ b/apps/maarch_entreprise/xml/config.xml.default
@@ -49,7 +49,7 @@
         <table>res_letterbox</table>
         <version_table>res_version_letterbox</version_table>
         <view>res_view_letterbox</view>
-        <adr>adr_x</adr>
+        <adr>adr_letterbox</adr>
         <index_file>index_letterbox.xml</index_file>
         <script_add>index_letterbox.php</script_add>
         <script_search>search_letterbox.php</script_search>
diff --git a/core/Controllers/HistoryController.php b/core/Controllers/HistoryController.php
index 63d01d80b7a69642a2498b7ced32b7717256f57d..a6c4cb7785c47649bb44642ae725c265d64b979a 100755
--- a/core/Controllers/HistoryController.php
+++ b/core/Controllers/HistoryController.php
@@ -8,7 +8,7 @@
 */
 
 /**
-* @brief Status Controller
+* @brief History Controller
 * @author dev@maarch.org
 * @ingroup core
 */
@@ -22,6 +22,7 @@ use Psr\Http\Message\ResponseInterface;
 use Core\Models\HistoryModel;
 use Core\Models\ServiceModel;
 use Core\Models\ValidatorModel;
+use Core\Controllers\UtilsController;
 use Notifications\Controllers\NotificationsEventsController;
 
 class HistoryController
@@ -46,6 +47,11 @@ class HistoryController
         if(empty($aArgs['level'])){
             $aArgs['level'] = 'DEBUG';
         }
+        if (empty($_SESSION['user']['UserId'])) {
+            $user = 'BOT';
+        } else {
+            $user = $_SESSION['user']['UserId'];
+        }
 
         $traceInformations = [
             'WHERE'         => $aArgs['tableName'],
@@ -152,7 +158,7 @@ class HistoryController
         );
 
         $logLine = TextFormatModel::htmlWasher($logLine);
-        $logLine = HistoryController::wd_remove_accents(['string' => $logLine]);
+        $logLine = UtilsController::wd_remove_accents(['string' => $logLine]);
 
         HistoryModel::writeLog([
             'logger'  => $logger,
@@ -161,34 +167,6 @@ class HistoryController
         ]);
     }
 
-
-    public static function wd_remove_accents(array $aArgs = [])
-    {
-        if(empty($aArgs['charset'])){
-            $aArgs['charset'] = 'utf-8';
-        }
-
-        $str = htmlentities($aArgs['string'], ENT_NOQUOTES, $aArgs['charset']);
-
-        $str = preg_replace(
-            '#\&([A-za-z])(?:uml|circ|tilde|acute|grave|cedil|ring)\;#',
-            '\1',
-            $str
-        );
-        $str = preg_replace(
-            '#\&([A-za-z]{2})(?:lig)\;#',
-            '\1',
-            $str
-        );
-        $str = preg_replace(
-            '#\&[^;]+\;#',
-            '',
-            $str
-        );
-
-        return $str;
-    }
-
     public function getForAdministration(RequestInterface $request, ResponseInterface $response, $aArgs)
     {
         if (!ServiceModel::hasService(['id' => 'history', 'userId' => $_SESSION['user']['UserId'], 'location' => 'apps', 'type' => 'admin'])) {
@@ -219,20 +197,4 @@ class HistoryController
 
         return $response->withJson($return);
     }
-
-    /*
-    timestart : timestamp Debut
-    timeend : timestamp Fin
-    level : level log4php
-    message : message dans les logs
-    */
-    public function executionTimeLog($timestart, $timeend, $level, $message){
-        if (empty($timeend)){
-            $timeend = microtime(true);
-        }
-        $time = $timeend - $timestart;
-
-        self::$level(['message' => $message.'. Done in ' . number_format($time, 3) . ' secondes.']);
-
-    }
 }
diff --git a/core/Controllers/LogsController.php b/core/Controllers/LogsController.php
new file mode 100644
index 0000000000000000000000000000000000000000..3018b047332439bf4c61687140bcb00bf4f435a2
--- /dev/null
+++ b/core/Controllers/LogsController.php
@@ -0,0 +1,352 @@
+<?php
+
+/**
+* Copyright Maarch since 2008 under licence GPLv3.
+* See LICENCE.txt file at the root folder for more details.
+* This file is part of Maarch software.
+*
+*/
+
+/**
+* @brief Logs Controller
+* @author dev@maarch.org
+* @ingroup core
+*/
+
+namespace Core\Controllers;
+
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+use Core\Models\ValidatorModel;
+use Core\Controllers\HistoryController;
+use Core\Controllers\UtilsController;
+
+if (!defined('_LOG4PHP'))
+    define(
+        '_LOG4PHP',
+        'log4php'
+    );
+if (!defined('_LOGGER_NAME_TECH_DEFAULT'))
+    define(
+        '_LOGGER_NAME_TECH_DEFAULT',
+        'loggerTechnique'
+    );
+if (!defined('_LOGGER_NAME_FUNC_DEFAULT'))
+    define(
+        '_LOGGER_NAME_FUNC_DEFAULT',
+        'loggerFonctionnel'
+    );
+
+require_once 'apps/maarch_entreprise/tools/log4php/Logger.php';
+
+class LogsController
+{
+    protected static function getLoggingMethodConfFile()
+    {
+        $xmlFileName = 'logging_method.xml';
+        if (file_exists($sLoggingMethodConfFile = 'custom'
+            .DIRECTORY_SEPARATOR.$_SESSION['custom_override_id']
+            .DIRECTORY_SEPARATOR . 'apps'
+            .DIRECTORY_SEPARATOR.$_SESSION['config']['app_id']
+            .DIRECTORY_SEPARATOR.'xml'
+            .DIRECTORY_SEPARATOR.$xmlFileName
+        )) {
+            return $sLoggingMethodConfFile;
+        }
+        if (file_exists($sLoggingMethodConfFile =
+            'apps'
+            .DIRECTORY_SEPARATOR.$_SESSION['config']['app_id']
+            .DIRECTORY_SEPARATOR.'xml'
+            .DIRECTORY_SEPARATOR.$xmlFileName
+        )) {
+            return $sLoggingMethodConfFile;
+        }
+
+        return null;
+    }
+
+    public static function getLoggingFormat(array $aArgs = []) 
+    {
+        ValidatorModel::notEmpty($aArgs,['key']);
+        ValidatorModel::intVal($aArgs,['key']);
+        $logging_methods = self::getLoggingMethod($aArgs);
+        return empty($logging_methods[$aArgs['key']]['LOG_FORMAT']) ? '[%RESULT%]' 
+            . '[%CODE_METIER%][%WHERE%][%ID%][%HOW%][%USER%]' 
+            . '[%WHAT%][%ID_MODULE%][%REMOTE_IP%]' : $logging_methods[$aArgs['key']]['LOG_FORMAT'];
+    }
+
+    public static function getLoggingCodeMetier(array $aArgs = [])
+    {
+        ValidatorModel::notEmpty($aArgs,['key']);
+        ValidatorModel::intVal($aArgs,['key']);
+        $logging_methods = self::getLoggingFormat($aArgs);
+        return empty($logging_methods[$aArgs['key']]['CODE_METIER']) ? '[%RESULT%]' 
+            . '[%CODE_METIER%][%WHERE%][%ID%][%HOW%][%USER%]' 
+            . '[%WHAT%][%ID_MODULE%][%REMOTE_IP%]' : $logging_methods[$aArgs['key']]['CODE_METIER'];
+    }
+
+    /**
+    * Get the logging method in the configuration file
+    */
+    protected static function getLoggingMethod(array $aArgs = [])
+    {
+        $sLoggingMethodConfFile = self::getLoggingMethodConfFile();
+        $logging_methods = [];
+        if ( ! $sLoggingMethodConfFile = self::getLoggingMethodConfFile() ) {
+            $logging_methods[0]['ID'] = 'database';
+            $logging_methods[0]['ACTIVATED'] = true;
+            $logging_methods[1]['ID'] = 'log4php';
+            $logging_methods[1]['ACTIVATED'] = true;
+            $logging_methods[1]['LOGGER_NAME_TECH'] = 'loggerTechnique';
+            $logging_methods[1]['LOGGER_NAME_FUNC'] = 'loggerFonctionnel';
+            $logging_methods[1]['LOG_FORMAT'] = '[%RESULT%][%CODE_METIER%][%WHERE%][%ID%][%HOW%][%USER%][%WHAT%][%ID_MODULE%][%REMOTE_IP%]';
+            $logging_methods[1]['CODE_METIER'] = 'MAARCH';
+            return $logging_methods;
+        }
+
+        if (! file_exists($sLoggingMethodConfFile) ) {
+            throw new \Exception('not file_exists : '.$sLoggingMethodConfFile);
+        }
+        $xmlConfig = @simplexml_load_file($sLoggingMethodConfFile);
+        if (! $xmlConfig) {
+            throw new \Exception('simplexml_load_file failed : '.$sLoggingMethodConfFile);
+        }
+        if (! $xmlConfig->METHOD) {
+            throw new \Exception('no data METHOD found : '.$sLoggingMethodConfFile);
+        }
+
+        foreach ($xmlConfig->METHOD as $METHOD) {
+            $id = ((string)$METHOD->ID);
+            $activated = ((boolean)$METHOD->ENABLED);
+            $loggerNameTech = ((string)$METHOD->LOGGER_NAME_TECH);
+            $loggerNameFunc = ((string)$METHOD->LOGGER_NAME_FUNC);
+            $logFormat = ((string)$METHOD->APPLI_LOG_FORMAT);
+            $codeMetier = ((string)$METHOD->CODE_METIER);
+
+            array_push(
+                $logging_methods,
+                array(
+                    'ID'         => $id,
+                    'ACTIVATED'  => $activated,
+                    'LOGGER_NAME_TECH' => $loggerNameTech,
+                    'LOGGER_NAME_FUNC' => $loggerNameFunc,
+                    'LOG_FORMAT'    => $logFormat,
+                    'CODE_METIER'   => $codeMetier
+                )
+            );
+        }
+        $oCache->set($sCache, $logging_methods);
+        return $logging_methods;
+    }
+
+    protected static function getConfFile(array $aArgs = [])
+    {
+        if ( empty($_SESSION['config']['app_id']) ) {
+            $_SESSION['config']['app_id'] = 'maarch_entreprise';
+        }
+        if (
+            !empty($_SESSION['config']['corepath']) && !empty($_SESSION['custom_override_id'])
+            && file_exists($configFileLog4PHP =
+            $_SESSION['config']['corepath']. DIRECTORY_SEPARATOR . 'custom'
+            . DIRECTORY_SEPARATOR . $_SESSION['custom_override_id']
+            . DIRECTORY_SEPARATOR . 'apps'
+            . DIRECTORY_SEPARATOR . $_SESSION['config']['app_id']
+            . DIRECTORY_SEPARATOR . 'xml'
+            . DIRECTORY_SEPARATOR . 'log4php.xml'
+        )) {
+            return $configFileLog4PHP;
+        }
+        if (file_exists($configFileLog4PHP =
+            'apps'
+            . DIRECTORY_SEPARATOR . $_SESSION['config']['app_id']
+            . DIRECTORY_SEPARATOR . 'xml'
+            . DIRECTORY_SEPARATOR . 'log4php.xml'
+        )) {
+            return $configFileLog4PHP;
+        }
+        return 'apps'
+            . DIRECTORY_SEPARATOR . $_SESSION['config']['app_id']
+            . DIRECTORY_SEPARATOR . 'xml'
+            . DIRECTORY_SEPARATOR . 'log4php.default.xml';
+    }
+
+    protected static function format_message(array $aArgs)
+    {
+        $aArgs['message'] = @$aArgs['message'];
+        switch (true) {
+            case is_object($aArgs['message']):
+                if ( $aArgs['message'] instanceof \Exception ) {
+                    $e = $aArgs['message'];
+                    $aArgs['code'] = $e->getCode();
+                    $aArgs['message'] = 'Exception: '.$e->getMessage();
+                    $aArgs['debug'] = $e->getTraceAsString();
+                    break;
+                }
+                $aArgs['message'] = '--object--';
+                break;
+            case is_array($aArgs['message']):
+                $aArgs['message'] = '--array--';
+                break;
+            default:
+                $aArgs['message'] = (string) $aArgs['message'];
+                break;
+        }
+        $aArgs['message'] = str_replace("\n", '\n', $aArgs['message']);
+
+        // Old method :
+        $aArgs['message'] = UtilsController::wash_html(
+            $aArgs['message'],
+            ''
+        );
+        $aArgs['message'] = UtilsController::wd_remove_accents(['string' => $aArgs['message']]);
+
+        if(!empty($_SESSION['user']['UserId'])){
+            $aArgs['message'] = '[' . $_SESSION['user']['UserId'] . '] ' . $aArgs['message'];
+        }
+
+        return $aArgs;
+    }
+
+    protected static function logs(array $aArgs = [])
+    {
+        // Initialisation du Logger :
+        \Logger::configure(
+            self::getConfFile()
+        );
+        if ( @$aArgs['class'] ) {
+            \Logger::getLogger($aArgs['class']);
+        }
+        $aLoggingMethods = self::getLoggingMethod();
+
+        $aArgs = self::format_message($aArgs);
+            if ( @$aArgs['class'] ) {
+                $sLog .= "[class:{$aArgs['class']}]";
+                \Logger::getLogger($aArgs['class']);
+            }
+
+        foreach ($aLoggingMethods as $logging_method) {
+            if ( ! $logging_method['ACTIVATED'] ) {
+                continue;
+            }
+
+            if (isset($aArgs['isTech']) && $aArgs['isTech']) {
+                $logger = \Logger::getLogger(
+                    $logging_method['LOGGER_NAME_TECH']
+                );
+            } else {
+                if(!isset($logging_method['LOGGER_NAME_FUNC'])){
+                    $logging_method['LOGGER_NAME_FUNC'] = 'loggerFonctionnel';
+                }
+                $logger = \Logger::getLogger(
+                    $logging_method['LOGGER_NAME_FUNC']
+                );
+            }
+            if ( empty($logger) ) {
+                throw new \Exception('logger not-loading', 1);
+            }
+            // Format :
+            $sLog = '';
+            if ( @$aArgs['file'] ) {
+                $sLog .= "[file:{$aArgs['file']}]";
+            }
+            if ( @$aArgs['class'] ) {
+                $sLog .= "[class:{$aArgs['class']}]";
+            }
+            if ( @$aArgs['function'] ) {
+                $sLog .= "[function:{$aArgs['function']}]";
+            }
+            if ( @$aArgs['code'] ) {
+                $aArgs['code'] = (int)$aArgs['code'];
+                $sLog .= "[code:{$aArgs['code']}]";
+            }
+
+            if(!isset($logging_method['CODE_METIER'])){
+                $logging_method['CODE_METIER'] = 'SIPol';
+            }
+            $sLog = str_replace(
+                '%CODE_METIER%', 
+                $logging_method['CODE_METIER'], 
+                "{$sLog}{$aArgs['message']}"
+            );
+
+            // Log :
+            switch ($aArgs['type']) {
+                case 'debug':
+                case _LEVEL_DEBUG:
+                    $logger->debug($sLog);
+                    break;
+
+                case 'info':
+                case _LEVEL_INFO:
+                    $logger->info($sLog);
+                    break;
+
+                case 'warning':
+                case _LEVEL_WARN:
+                    $logger->warn($sLog);
+                    break;
+
+                case 'error':
+                case _LEVEL_ERROR:
+                    $logger->error($sLog);
+                    break;
+
+                case _LEVEL_FATAL:
+                    $logger->fatal($sLog);
+                    break;
+
+                default:
+                    $logger->error($sLog);
+            }
+        }
+        return true;
+    }
+
+    public static function debug(array $aArgs = [])
+    {
+        $aArgs['type'] = 'debug';
+        return self::logs($aArgs);
+    }
+
+    public static function info(array $aArgs = [])
+    {
+        $aArgs['type'] = 'info';
+        return self::logs($aArgs);
+    }
+
+    public static function warning(array $aArgs = [])
+    {
+        $aArgs['type'] = 'warning';
+        return self::logs($aArgs);
+    }
+
+    public static function error(array $aArgs = [])
+    {
+        $aArgs['type'] = 'error';
+        return self::logs($aArgs);
+    }
+
+    public static function fatal(array $aArgs = [])
+    {
+        $aArgs['type'] = _LEVEL_FATAL;
+        return self::logs($aArgs);
+    }
+
+    /*
+    timestart : timestamp Debut
+    timeend : timestamp Fin
+    level : level log4php
+    message : message dans les logs
+    */
+    public function executionTimeLog($timestart, $timeend, $level, $message)
+    {
+        if (empty($timeend)){
+            $timeend = microtime(true);
+        }
+        $time = $timeend - $timestart;
+
+        self::$level(
+            ['message' => $message.'. Done in ' . number_format($time, 3) . ' secondes.']
+        );
+    }
+}
diff --git a/core/Controllers/StoreController.php b/core/Controllers/StoreController.php
index 751feb02f46e76ed509fd6ee8701a82d1b747e9a..bface426cb16ff2accb3424a7db5413f888cfbe6 100644
--- a/core/Controllers/StoreController.php
+++ b/core/Controllers/StoreController.php
@@ -95,6 +95,10 @@ class StoreController
         ValidatorModel::stringType($aArgs['fileInfos'], ['tmpDir', 'format', 'tmpFileName']);
         ValidatorModel::intVal($aArgs['fileInfos'], ['size']);
 
+        if (empty($aArgs['docserverTypeId'])) {
+            $aArgs['docserverTypeId'] = 'DOC';
+        }
+
         if (!is_dir($aArgs['fileInfos']['tmpDir'])) {
             return ['errors' => '[storeRessourceOnDocserver] FileInfos.tmpDir does not exist'];
         }
@@ -102,7 +106,9 @@ class StoreController
             return ['errors' => '[storeRessourceOnDocserver] FileInfos.tmpFileName does not exist'];
         }
 
-        $docserver = DocserverModel::getDocserverToInsert(['collId' => $aArgs['collId']])[0];
+        $docserver = DocserverModel::getDocserverToInsert(
+            ['collId' => $aArgs['collId'], 'typeId' => $aArgs['docserverTypeId']]
+        )[0];
         if (empty($docserver)) {
             return ['errors' => '[storeRessourceOnDocserver] No available Docserver'];
         }
diff --git a/core/Controllers/UtilsController.php b/core/Controllers/UtilsController.php
new file mode 100644
index 0000000000000000000000000000000000000000..a1e136301e8141d0d48cd99d2fd7ec6983d3761f
--- /dev/null
+++ b/core/Controllers/UtilsController.php
@@ -0,0 +1,118 @@
+<?php
+
+/**
+ * Copyright Maarch since 2008 under licence GPLv3.
+ * See LICENCE.txt file at the root folder for more details.
+ * This file is part of Maarch software.
+ *
+ */
+
+/**
+ * @brief Utils Controller
+ * @author dev@maarch.org
+ * @ingroup core
+ */
+
+namespace Core\Controllers;
+
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+
+
+class UtilsController
+{
+    public static function wd_remove_accents(array $aArgs = [])
+    {
+        if(empty($aArgs['charset'])){
+            $aArgs['charset'] = 'utf-8';
+        }
+
+        $str = htmlentities($aArgs['string'], ENT_NOQUOTES, $aArgs['charset']);
+
+        $str = preg_replace(
+            '#\&([A-za-z])(?:uml|circ|tilde|acute|grave|cedil|ring)\;#',
+            '\1',
+            $str
+        );
+        $str = preg_replace(
+            '#\&([A-za-z]{2})(?:lig)\;#',
+            '\1',
+            $str
+        );
+        $str = preg_replace(
+            '#\&[^;]+\;#',
+            '',
+            $str
+        );
+
+        return $str;
+    }
+
+    /**
+    * Cleans html string, replacing entities by utf-8 code
+    *
+    * @param  $var string  String to clean
+    * @return Cleaned string
+    */
+    public function wash_html($var, $mode="UNICODE")
+    {
+        if($mode == "UNICODE")
+        {
+            $var = str_replace("<br/>","\\n",$var);
+            $var = str_replace("<br />","\\n",$var);
+            $var = str_replace("<br/>","\\n",$var);
+            $var = str_replace("&nbsp;"," ",$var);
+            $var = str_replace("&eacute;", "\u00e9",$var);
+            $var = str_replace("&egrave;","\u00e8",$var);
+            $var = str_replace("&ecirc;","\00ea",$var);
+            $var = str_replace("&agrave;","\u00e0",$var);
+            $var = str_replace("&acirc;","\u00e2",$var);
+            $var = str_replace("&icirc;","\u00ee",$var);
+            $var = str_replace("&ocirc;","\u00f4",$var);
+            $var = str_replace("&ucirc;","\u00fb",$var);
+            $var = str_replace("&acute;","\u0027",$var);
+            $var = str_replace("&deg;","\u00b0",$var);
+            $var = str_replace("&rsquo;", "\u2019",$var);
+        }
+        else if($mode == 'NO_ACCENT')
+        {
+            $var = str_replace("<br/>","\\n",$var);
+            $var = str_replace("<br />","\\n",$var);
+            $var = str_replace("<br/>","\\n",$var);
+            $var = str_replace("&nbsp;"," ",$var);
+            $var = str_replace("&eacute;", "e",$var);
+            $var = str_replace("&egrave;","e",$var);
+            $var = str_replace("&ecirc;","e",$var);
+            $var = str_replace("&agrave;","a",$var);
+            $var = str_replace("&acirc;","a",$var);
+            $var = str_replace("&icirc;","i",$var);
+            $var = str_replace("&ocirc;","o",$var);
+            $var = str_replace("&ucirc;","u",$var);
+            $var = str_replace("&acute;","",$var);
+            $var = str_replace("&deg;","o",$var);
+            $var = str_replace("&rsquo;", "'",$var);
+
+            // AT LAST
+            $var = str_replace("&", " et ",$var);
+        }
+        else
+        {
+            $var = str_replace("<br/>","\\n",$var);
+            $var = str_replace("<br />","\\n",$var);
+            $var = str_replace("<br/>","\\n",$var);
+            $var = str_replace("&nbsp;"," ",$var);
+            $var = str_replace("&eacute;", "é",$var);
+            $var = str_replace("&egrave;","è",$var);
+            $var = str_replace("&ecirc;","ê",$var);
+            $var = str_replace("&agrave;","à",$var);
+            $var = str_replace("&acirc;","â",$var);
+            $var = str_replace("&icirc;","î",$var);
+            $var = str_replace("&ocirc;","ô",$var);
+            $var = str_replace("&ucirc;","û",$var);
+            $var = str_replace("&acute;","",$var);
+            $var = str_replace("&deg;","°",$var);
+            $var = str_replace("&rsquo;", "'",$var);
+        }
+        return $var;
+    }
+}
diff --git a/core/Models/DocserverModelAbstract.php b/core/Models/DocserverModelAbstract.php
index 847ea6d495423d5649f47005426ae3a9226b35f4..d57ae343c4ec09ddf0f3c3eefa3aec4f61245747 100755
--- a/core/Models/DocserverModelAbstract.php
+++ b/core/Models/DocserverModelAbstract.php
@@ -123,37 +123,21 @@ class DocserverModelAbstract
         return true;
     }
 
-    public static function getDocserverToInsert(array $aArgs = [])
-    {
-        ValidatorModel::notEmpty($aArgs, ['collId']);
-        ValidatorModel::stringType($aArgs, ['collId']);
-
-        $aReturn = DatabaseModel::select([
-            'select'    => ['*'],
-            'table'     => ['docservers'],
-            'where'     => ["is_readonly = 'N' and enabled = 'Y' and coll_id = ?"],
-            'data'      => [$aArgs['collId']],
-            'order_by'  => ['priority_number'],
-            'limit'     => 1,
-        ]);
-
-        return $aReturn;
-    }
 
     /**
-     * Get docservers to insert a new doc converted.
+     * Get docservers to insert a new doc.
      * Can return null if no corresponding object.
      * @param  $collId  string Collection identifier
      * @param  string $typeId [description]
      * @return docservers 
      */
-    public function findTargetDs(array $aArgs = [])
+    public static function getDocserverToInsert(array $aArgs = [])
     {
         ValidatorModel::notEmpty($aArgs, ['collId']);
         ValidatorModel::stringType($aArgs, ['collId']);
 
         if (empty($aArgs['typeId'])) {
-            $aArgs['typeId'] = 'CONVERT';
+            $aArgs['typeId'] = 'DOC';
         }
 
         $aReturn = DatabaseModel::select([
diff --git a/core/Models/ResModelAbstract.php b/core/Models/ResModelAbstract.php
index 33441780dc0e49b65e126bfe0788735b972c0fa1..85104fc98725990ad9ffa05b1a13ceea7b8a5afe 100755
--- a/core/Models/ResModelAbstract.php
+++ b/core/Models/ResModelAbstract.php
@@ -21,10 +21,14 @@ class ResModelAbstract
     {
         ValidatorModel::notEmpty($aArgs, ['resId']);
         ValidatorModel::intVal($aArgs, ['resId']);
+        
+        if (empty($aArgs['resTable'])) {
+            $aArgs['resTable'] = 'res_letterbox';
+        }
 
         $aReturn = DatabaseModel::select([
             'select'    => empty($aArgs['select']) ? ['*'] : $aArgs['select'],
-            'table'     => ['res_letterbox'],
+            'table'     => [$aArgs['resTable']],
             'where'     => ['res_id = ?'],
             'data'      => [$aArgs['resId']]
         ]);
diff --git a/modules/convert/Controllers/ProcessConvertController.php b/modules/convert/Controllers/ProcessConvertController.php
index f616fea024bc0f45e621020fa5fee301301489e3..844a0020cee11e1ecc7c043cb1281ce7bef3b0b0 100644
--- a/modules/convert/Controllers/ProcessConvertController.php
+++ b/modules/convert/Controllers/ProcessConvertController.php
@@ -25,18 +25,13 @@ namespace Convert\Controllers;
 
 use Psr\Http\Message\RequestInterface;
 use Psr\Http\Message\ResponseInterface;
-use Convert\Models\ProcessFulltextModel;
+use Convert\Models\ProcessConvertModel;
+use Core\Models\CoreConfigModel;
 use Core\Models\DocserverModel;
 use Core\Models\ResDocserverModel;
-
-require_once 'core/class/class_functions.php';
-require_once 'core/class/class_db_pdo.php';
-// require_once 'core/class/class_db.php';
-// require_once 'core/docservers_tools.php';
-// require_once 'core/class/docservers_controler.php';
-// require_once 'core/services/ManageDocservers.php';
-
-//include_once('html2text/html2text.php');
+use Core\Models\ResModel;
+use Core\Controllers\LogsController;
+use Core\Controllers\StoreController;
 
 class ProcessConvertController
 {
@@ -63,7 +58,7 @@ class ProcessConvertController
     public function convert(array $args=[])
     {
         $timestart = microtime(true);
-        // HistoryController::info(['message'=>'debut convert', 'code'=>111, ]);
+        // LogsController::info(['message'=>'debut convert', 'code'=>111, ]);
         $returnArray = array();
         if (empty($args['collId'])) {
             $returnArray = array(
@@ -112,20 +107,14 @@ class ProcessConvertController
             $tmpDir = $args['tmpDir'];
         }
 
-        $dbConv = new \Database($GLOBALS['configFile']);
-        
-        //retrieve path of the resource
-        $stmtConv = $dbConv->query("select * from " . $resTable 
-            . " where res_id = ?", array($resId)
-        );
-        $line = $stmtConv->fetchObject();
+        $res = ResModel::getById(['resId' => $resId, 'resTable' => $args['resTable']]);
         
-        if ($line->res_id <> '') {
+        if ($res['res_id'] <> '') {
             $resourcePath = ResDocserverModel::getSourceResourcePath(
                 [
                     'resTable' => $resTable, 
                     'adrTable' => $adrTable, 
-                    'resId' => $line->res_id,
+                    'resId' => $res['res_id'],
                     'adrType' => 'DOC'
                 ]
             );
@@ -136,7 +125,7 @@ class ProcessConvertController
                 'value' => '',
                 'error' => 'file not exists : ' . $resourcePath,
             );
-            $this->manageErrorOnDb($resTable, $resId, '-1');
+            ProcessConvertModel::manageErrorOnDb($resTable, $resId, '-1');
             return $returnArray;
         }
         //copy the resource on tmp directory
@@ -147,11 +136,11 @@ class ProcessConvertController
                 'value' => '',
                 'error' => 'copy on tmp failed',
             );
-            $this->manageErrorOnDb($resTable, $resId, '-1');
+            ProcessConvertModel::manageErrorOnDb($resTable, $resId, '-1');
             return $returnArray;
         }
         //now do the conversion !
-        if (strtoupper($line->format) <> 'PDF') {
+        if (strtoupper($res['format']) <> 'PDF') {
             $resultOfConversion = $this->launchConvert(
                 $fileNameOnTmp, 
                 'pdf', 
@@ -159,7 +148,6 @@ class ProcessConvertController
                 pathinfo($resourcePath, PATHINFO_EXTENSION)
             );
         } else {
-            //echo $fileNameOnTmp;
             copy($fileNameOnTmp, $fileNameOnTmp . '.pdf');
             $resultOfConversion = array(
                 'status' => '0',
@@ -169,50 +157,59 @@ class ProcessConvertController
         }
         
         if ($resultOfConversion['status'] <> '0') {
-            $this->manageErrorOnDb($resTable, $resId, '-1');
+            ProcessConvertModel::manageErrorOnDb($resTable, $resId, '-1');
             return $resultOfConversion;
         }
-        //find the target docserver
-        $targetDs = DocserverModel::findTargetDs(['collId' => $collId]);
-        if (empty($targetDs)) {
+        //copy the result on docserver
+        // LogsController::info(['message'=>'avant cp ds', 'code'=>1112, ]);
+        $storeResult = StoreController::storeResourceOnDocServer([
+            'collId'    => $collId,
+            'fileInfos' => [
+                'tmpDir'        => CoreConfigModel::getTmpPath(),
+                'size'          => filesize($fileNameOnTmp),
+                'format'        => 'PDF',
+                'tmpFileName'   => pathinfo($fileNameOnTmp, PATHINFO_FILENAME) . '.pdf',
+            ],
+            'docserverTypeId'   => 'CONVERT'
+        ]);
+
+        if (empty($storeResult)) {
             $returnArray = array(
                 'status' => '1',
                 'value' => '',
-                'error' => 'Ds of collection not found:' . $collId,
+                'error' => 'Ds of collection and ds type not found for convert:' 
+                    . $collId . ' CONVERT',
             );
-            $this->manageErrorOnDb($resTable, $resId, '-1');
+            ProcessConvertModel::manageErrorOnDb($resTable, $resId, '-1');
             return $returnArray;
         }
-        
-        //copy the result on docserver
-        // HistoryController::info(['message'=>'avant cp ds', 'code'=>1112, ]);
-        $resultCopyDs = $ManageDocservers->copyResOnDS($fileNameOnTmp . '.pdf', $targetDs);
-        if ($resultCopyDs['status'] <> '0') {
-            $this->manageErrorOnDb($resTable, $resId, '-1');
-            return $resultCopyDs;
-        }
-        // HistoryController::info(['message'=>'avant update', 'code'=>19, ]);
+
+        $targetDs = DocserverModel::getById(['docserver_id' => $storeResult['docserver_id']]);
+
+        // LogsController::info(['message'=>'avant update', 'code'=>19, ]);
         //update the \Database
-        $resultOfUpDb = $this->updateDatabase(
-            $collId,
-            $resTable, 
-            $adrTable, 
-            $resId,
-            $targetDs,
-            $resultCopyDs['value']['destinationDir'],
-            $resultCopyDs['value']['fileDestinationName']
+        $resultOfUpDb = ProcessConvertModel::updateDatabase(
+            [
+                'collId'     => $collId,
+                'resTable'   => $resTable, 
+                'adrTable'   => $adrTable, 
+                'resId'      => $resId,
+                'docserver'  => $targetDs[0],
+                'path'       => $storeResult['destination_dir'],
+                'fileName'   => $storeResult['file_destination_name']
+            ]
         );
-        // HistoryController::info(['message'=>var_export($resultOfUpDb, true), 'code'=>111111, ]);
-        // HistoryController::info(['message'=>$collId, 'code'=>2, ]);
-        // HistoryController::info(['message'=>$resTable, 'code'=>3, ]);
-        // HistoryController::info(['message'=>$adrTable, 'code'=>4, ]);
-        // HistoryController::info(['message'=>$resId, 'code'=>5, ]);
-        // HistoryController::info(['message'=>'apres res_id', 'code'=>6, ]);
-        // HistoryController::info(['message'=>$targetDs, 'code'=>6, ]);
-        // HistoryController::info(['message'=>var_export($resultCopyDs, true), 'code'=>7, ]);
+        // LogsController::info(['message'=>var_export($resultOfUpDb, true), 'code'=>111111, ]);
+        // LogsController::info(['message'=>$collId, 'code'=>2, ]);
+        // LogsController::info(['message'=>$resTable, 'code'=>3, ]);
+        // LogsController::info(['message'=>$adrTable, 'code'=>4, ]);
+        // LogsController::info(['message'=>$resId, 'code'=>5, ]);
+        // LogsController::info(['message'=>'apres res_id', 'code'=>6, ]);
+        // LogsController::info(['message'=>$targetDs, 'code'=>6, ]);
+        // LogsController::info(['message'=>var_export($resultCopyDs, true), 'code'=>7, ]);
 
         if ($resultOfUpDb['status'] <> '0') {
-            $this->manageErrorOnDb($resTable, $resId, '-1');
+            ProcessConvertModel::manageErrorOnDb($resTable, $resId, '-1');
             return $resultOfUpDb;
         }
 
@@ -224,7 +221,12 @@ class ProcessConvertController
             'value' => '',
             'error' => '',
         );
-        HistoryController::executionTimeLog($timestart, '', 'debug', '[TIMER] Convert_ProcessConvertAbstract_Service::convert');
+        LogsController::executionTimeLog(
+            $timestart, 
+            '', 
+            'debug', 
+            '[TIMER] Convert_ProcessConvertAbstract_Service::convert'
+        );
         return $returnArray;
     }
 
@@ -248,10 +250,10 @@ class ProcessConvertController
         $processHtml = false;
         $executable='';
         
-        HistoryController::info(['message'=>'[TIMER] Debut Convert_ProcessConvertAbstract_Service::launchConvert']);
+        LogsController::info(['message'=>'[TIMER] Debut Convert_ProcessConvertAbstract_Service::launchConvert']);
         if (strtoupper($srcfmt) == 'MAARCH' || strtoupper($srcfmt) == 'HTML') {
             $processHtml = true;
-            HistoryController::info(['message'=>'[TIMER] srcfmt ' . $srcfmt]);
+            LogsController::info(['message'=>'[TIMER] srcfmt ' . $srcfmt]);
             copy($srcfile, str_ireplace('.maarch', '.', $srcfile) . '.html');
             if (file_exists('/usr/bin/mywkhtmltopdf')) {
                 $command = "mywkhtmltopdf " 
@@ -266,7 +268,7 @@ class ProcessConvertController
             $executable='wkhtmltopdf';
         } else {
             $executable='soffice';
-            HistoryController::info(['message'=>'[TIMER] let LO do it ' . $this->libreOfficeExecutable]);
+            LogsController::info(['message'=>'[TIMER] let LO do it ' . $this->libreOfficeExecutable]);
             if ($this->libreOfficeExecutable == "cloudooo") {
                 $serverAddress = "http://192.168.21.40:8011";
                 $tokens = array();
@@ -311,11 +313,11 @@ class ProcessConvertController
         }
         //echo $command . '<br />';exit;
         if ($this->libreOfficeExecutable == "cloudooo" && !$processHtml) {
-            HistoryController::info(['message'=>'[TIMER] commande : cloudooo url ' . $serverAddress]);
-            HistoryController::info(['message'=>'[TIMER] Debut Convert_ProcessConvertAbstract_Service::launchConvert__exec']);
+            LogsController::info(['message'=>'[TIMER] commande : cloudooo url ' . $serverAddress]);
+            LogsController::info(['message'=>'[TIMER] Debut Convert_ProcessConvertAbstract_Service::launchConvert__exec']);
             $req = new PhpXmlRpc\Request('convertFile', $v);
-            //HistoryController::info(['message'=>'[TIMER] commande : cloudooo url ' . $serverAddress]);
-            HistoryController::info(['message'=>'[TIMER] Fin Convert_ProcessConvertAbstract_Service::launchConvert__exec']);
+            //LogsController::info(['message'=>'[TIMER] commande : cloudooo url ' . $serverAddress]);
+            LogsController::info(['message'=>'[TIMER] Fin Convert_ProcessConvertAbstract_Service::launchConvert__exec']);
             $client = new PhpXmlRpc\Client($serverAddress);
             $resp = $client->send($req);
             if (!$resp->faultCode()) {
@@ -343,8 +345,8 @@ class ProcessConvertController
         } else {
             $timestart_command = microtime(true);
             exec("timeout -k 5m 3m " . $command, $output, $return);
-            HistoryController::debug(['message'=>'[TIMER] commande : ' . $command]);
-            HistoryController::executionTimeLog($timestart_command, '', 'info', '[TIMER] ' . $executable . ' - Convert_ProcessConvertAbstract_Service::launchConvert__exec');
+            LogsController::debug(['message'=>'[TIMER] commande : ' . $command]);
+            LogsController::executionTimeLog($timestart_command, '', 'info', '[TIMER] ' . $executable . ' - Convert_ProcessConvertAbstract_Service::launchConvert__exec');
             if ($return === 0) {
                 $returnArray = array(
                     'status' => '0',
@@ -368,224 +370,12 @@ class ProcessConvertController
                 'error' => '',
             );
         }
-        HistoryController::executionTimeLog($timestart, '', 'info', '[TIMER] Fin Convert_ProcessConvertAbstract_Service::launchConvert');
-        return $returnArray;
-    }
-
-    /**
-     * Updating the database with the location information of the document on the
-     * new docserver
-     * @param string $collId collection
-     * @param string $resTable res table
-     * @param string $adrTable adr table
-     * @param bigint $resId Id of the resource to process
-     * @param docserver $docserver docserver object
-     * @param string $path location of the resource on the docserver
-     * @param string $fileName file name of the resource on the docserver
-     * @return array $returnArray the result
-     */
-    private function updateDatabase(
-        $collId, 
-        $resTable, 
-        $adrTable, 
-        $resId,
-        $docserver,
-        $path, 
-        $fileName
-    ) {
-        try {
-            $docserver->path_template = str_replace(
-                DIRECTORY_SEPARATOR, 
-                '#', 
-                $docserver->path_template
-            );
-            $path = str_replace($docserver->path_template, '', $path);
-            $dbConv = new \Database($GLOBALS['configFile']);
-            $query = "update convert_stack set status = 'P' where "
-               . " coll_id = ? and res_id = ?";
-            $stmt = $dbConv->query(
-                $query,
-                array(
-                    $collId,
-                    $resId
-                )
-            );
-
-            $query = "select * from " . $adrTable 
-                . " where res_id = ? order by adr_priority";
-            $stmt = $dbConv->query($query, array($resId));
-            if ($stmt->rowCount() == 0) {
-                $query = "select docserver_id, path, filename, offset_doc, fingerprint"
-                       . " from " . $resTable . " where res_id = ?";
-                $stmt = $dbConv->query($query, array($resId));
-                $recordset = $stmt->fetchObject();
-                // HistoryController::info(['message'=>$recordset, 'code'=>8, ]);
-                $resDocserverId = $recordset->docserver_id;
-                $resPath = $recordset->path;
-                $resFilename = $recordset->filename;
-                $resOffsetDoc = $recordset->offset_doc;
-                $fingerprintInit = $recordset->fingerprint;
-                $query = "select adr_priority_number from docservers "
-                       . " where docserver_id = ?";
-                $stmt = $dbConv->query($query, array($resDocserverId));
-                $recordset = $stmt->fetchObject();
-                $query = "insert into " . $adrTable . " (res_id, "
-                       . "docserver_id, path, filename, offset_doc, fingerprint, "
-                       . "adr_priority) values (?, ?, ?, ?, ?, ?, ?)";
-                $stmt = $dbConv->query(
-                    $query, 
-                    array(
-                        $resId,
-                        $resDocserverId,
-                        $resPath,
-                        $resFilename,
-                        $resOffsetDoc,
-                        $fingerprintInit,
-                        $recordset->adr_priority_number
-                    )
-                );
-            }
-
-            $query = "select * from " . $adrTable 
-                . " where res_id = ? and adr_type = 'CONV'";
-            $stmt = $dbConv->query($query, array($resId));
-            if ($stmt->rowCount() == 0) {
-                $query = "insert into " . $adrTable . " (res_id, docserver_id, "
-                   . "path, filename, offset_doc, fingerprint, adr_priority, adr_type) values (" 
-                   . "?, ?, ?, ?, ?, ?, ?, ?)";
-                $stmt = $dbConv->query(
-                    $query, 
-                    array(
-                        $resId,
-                        $docserver->docserver_id,
-                        $path,
-                        $fileName,
-                        $offsetDoc,
-                        $fingerprint,
-                        $docserver->adr_priority_number,
-                        'CONV'
-                    )
-                );
-            } else {
-                $query = "update " . $adrTable . " set docserver_id = ?, "
-                   . " path = ?, filename = ?, offset_doc = ?, fingerprint = ?, adr_priority = ?"
-                   . " where res_id = ? and adr_type = ? ";
-                $stmt = $dbConv->query(
-                    $query, 
-                    array(
-                        $docserver->docserver_id,
-                        $path,
-                        $fileName,
-                        $offsetDoc,
-                        $fingerprint,
-                        $docserver->adr_priority_number,
-                        $resId,
-                        'CONV'
-                    )
-                );
-            }
-            if ($_SESSION['user']['UserId'] <> '') {
-                $user = $_SESSION['user']['UserId'];
-            } else {
-                $user = 'CONVERT_BOT';
-            }
-            $query = "insert into history (table_name, record_id, "
-                   . "event_type, user_id, event_date, info, id_module) values (" 
-                   . "?, ?, 'ADD', '" . $user . "', " 
-                   . $dbConv->current_datetime() 
-                   . ", ?, 'convert')";
-            $stmt = $dbConv->query( 
-                $query, 
-                array(
-                    $resTable,
-                    $resId,
-                    "process convert done"
-                )
-            );
-
-            $queryCpt = "select coalesce(custom_t9, '0') as custom_t9 from " . $resTable 
-                . " where res_id = ?";
-            $stmtCpt = $dbConv->query($queryCpt, array($resId));
-            $rsCpt = $stmtCpt->fetchObject();
-            $cptConvert = $rsCpt->custom_t9 + 1;
-
-            $query = "update " . $resTable 
-                . " set convert_result = '1', is_multi_docservers = 'Y', custom_t9 = '" . $cptConvert . "' where "
-                . " res_id = ?";
-            $stmt = $dbConv->query(
-                $query,
-                array(
-                    $resId
-                )
-            );
-            $returnArray = array(
-                'status' => '0',
-                'value' => '',
-                'error' => '',
-            );
-            return $returnArray;
-        } catch (Exception $e) {
-            $returnArray = array(
-                'status' => '1',
-                'value' => '',
-                'error' => $e->getMessage(),
-            );
-            return $returnArray;
-        }
-    }
-
-    /**
-     * Updating the database with the error code
-     * @param string $resTable res table
-     * @param bigint $resId Id of the resource to process
-     * @param string $result error code
-     * @return nothing
-     */
-    private function manageErrorOnDb(
-        $resTable, 
-        $resId,
-        $result
-    ) {
-        $dbConv = new \Database($GLOBALS['configFile']);
-        $query = "update " . $resTable 
-            . " set convert_result = ? where "
-            . " res_id = ?";
-        $stmt = $dbConv->query(
-            $query,
-            array(
-                $result,
-                $resId
-            )
+        LogsController::executionTimeLog(
+            $timestart, 
+            '', 
+            'info', 
+            '[TIMER] Fin Convert_ProcessConvertAbstract_Service::launchConvert'
         );
-    }
-
-    /**
-     * Test if the record is already processed by convert module
-     * @param string $resTable res table
-     * @param bigint $resId Id of the resource to process
-     * @return boolean
-     */
-    public function isAlreadyProcessedByConvert(
-        $resTable, 
-        $resId
-    ) {
-        $dbConv = new \Database($GLOBALS['configFile']);
-        $query = "select convert_result from " . $resTable 
-            . "  where res_id = ?";
-        $stmt = $dbConv->query(
-            $query,
-            array(
-                $resId
-            )
-        );
-        $rs = $stmt->fetchObject();
-        if (
-            empty($rs->convert_result) || 
-            $rs->convert_result == '0'
-        ) {
-            return false;
-        } else {
-            return true;
-        }
+        return $returnArray;
     }
 }
\ No newline at end of file
diff --git a/modules/convert/Controllers/ProcessFulltextController.php b/modules/convert/Controllers/ProcessFulltextController.php
index 58f331853f2c13c6b69408d09ee062cec163c9df..3e195129d1daef79a1238fc4f972433bbcb21725 100644
--- a/modules/convert/Controllers/ProcessFulltextController.php
+++ b/modules/convert/Controllers/ProcessFulltextController.php
@@ -27,6 +27,7 @@ use Psr\Http\Message\RequestInterface;
 use Psr\Http\Message\ResponseInterface;
 use Convert\Models\ProcessFulltextModel;
 use Core\Models\ResDocserverModel;
+use Core\Controllers\LogsController;
 
 require_once 'core/class/class_functions.php';
 require_once 'core/class/class_db_pdo.php';
@@ -192,7 +193,7 @@ class ProcessFulltextController
         
         if ($resultOfConversion['status'] <> '0') {
             $this->manageErrorOnDb($resTable, $resId, '-1');
-            HistoryController::executionTimeLog(
+            LogsController::executionTimeLog(
                 $timestart, 
                 '', 
                 'debug', 
@@ -242,7 +243,7 @@ class ProcessFulltextController
             'value' => '',
             'error' => '',
         );
-        HistoryController::executionTimeLog(
+        LogsController::executionTimeLog(
             $timestart, 
             '', 
             'debug', 
@@ -325,7 +326,7 @@ class ProcessFulltextController
             $resultExtraction = exec("pdftotext " . escapeshellarg($pathToFile)
                     . " " . escapeshellarg($tmpFile) 
                 );
-            HistoryController::executionTimeLog($timestart_fulltext, '', 'debug', '[TIMER] Convert_ProcessFulltextAbstract_Service::prepareIndexFullTextPdf__exec');
+            LogsController::executionTimeLog($timestart_fulltext, '', 'debug', '[TIMER] Convert_ProcessFulltextAbstract_Service::prepareIndexFullTextPdf__exec');
             
             $fileContent = trim($this->readFileF($tmpFile));
             
@@ -345,7 +346,7 @@ class ProcessFulltextController
         } else {
             $result = 'file not found ' . $pathToFile;
         }
-        HistoryController::executionTimeLog(
+        LogsController::executionTimeLog(
             $timestart, 
             '', 
             'debug', 
@@ -726,7 +727,7 @@ class ProcessFulltextController
                 $_SESSION['config']['corepath'] . ' > /dev/null 2>&1 &'
             );
         }
-        HistoryController::executionTimeLog(
+        LogsController::executionTimeLog(
             $timestart, 
             '', 
             'debug', 
diff --git a/modules/convert/Models/ProcessConvertModelAbstract.php b/modules/convert/Models/ProcessConvertModelAbstract.php
index d7612a59fe6b6d2afd32bf3a5c98331ad998e986..98a5d1ee3ad706530f76b88167d31ab1d49a5ddd 100644
--- a/modules/convert/Models/ProcessConvertModelAbstract.php
+++ b/modules/convert/Models/ProcessConvertModelAbstract.php
@@ -15,24 +15,200 @@
 
 namespace Convert\Models;
 
-class ProcessConverttextModelAbstract
+use Core\Models\DatabaseModel;
+use Core\Models\ValidatorModel;
+use Core\Controllers\HistoryController;
+
+class ProcessConvertModelAbstract
 {
-    public static function getById(array $aArgs = [])
+    /**
+     * Updating the database with the location information of the document on the
+     * new docserver
+     * @param string $collId collection
+     * @param string $resTable res table
+     * @param string $adrTable adr table
+     * @param bigint $resId Id of the resource to process
+     * @param docserver $docserver docserver object
+     * @param string $path location of the resource on the docserver
+     * @param string $fileName file name of the resource on the docserver
+     * @return array $returnArray the result
+     */
+    public static function updateDatabase(array $aArgs = [])
     {
-        ValidatorModel::notEmpty($aArgs, ['resId']);
-        ValidatorModel::intVal($aArgs, ['resId']);
+        try {
+            ValidatorModel::notEmpty($aArgs, ['collId']);
+            ValidatorModel::notEmpty($aArgs, ['resTable']);
+            ValidatorModel::notEmpty($aArgs, ['adrTable']);
+            ValidatorModel::intVal($aArgs, ['resId']);
+            ValidatorModel::notEmpty($aArgs, ['docserver']);
+            ValidatorModel::notEmpty($aArgs, ['path']);
+            ValidatorModel::notEmpty($aArgs, ['fileName']);
 
-        $aReturn = DatabaseModel::select([
-            'select'    => empty($aArgs['select']) ? ['*'] : $aArgs['select'],
-            'table'     => ['res_letterbox'],
-            'where'     => ['res_id = ?'],
-            'data'      => [$aArgs['resId']]
-        ]);
+            $aArgs['docserver']['path_template'] = str_replace(
+                DIRECTORY_SEPARATOR, 
+                '#', 
+                $aArgs['docserver']['path_template']
+            );
+            $aArgs['path'] = str_replace(
+                $aArgs['docserver']['path_template'], 
+                '', 
+                $aArgs['path']
+            );
+
+            DatabaseModel::update([
+                'table'     => 'convert_stack',
+                'set'       => [
+                    'status'    => 'P'
+                ],
+                'where'     => ['coll_id = ?', 'res_id = ?'],
+                'data'      => [$aArgs['collId'], $aArgs['resId']]
+            ]);
+
+            $returnAdr = DatabaseModel::select([
+                'select'    => ['*'],
+                'table'     => [$aArgs['adrTable']],
+                'where'     => ['res_id = ?'],
+                'data'      => [$aArgs['resId']],
+                'order'      => ['adr_priority'],
+            ]);
+
+            if (empty($returnAdr)) {
+                $returnRes = DatabaseModel::select([
+                    'select'    => ['docserver_id, path, filename, offset_doc, fingerprint'],
+                    'table'     => [$aArgs['resTable']],
+                    'where'     => ['res_id = ?'],
+                    'data'      => [$aArgs['resId']]
+                ]);
+                $returnRes = $returnRes[0];
+                // LogsController::info(['message'=>$returnRes, 'code'=>8, ]);
+                $resDocserverId = $returnRes['docserver_id'];
+                $resPath = $returnRes['path'];
+                $resFilename = $returnRes['filename'];
+                $resOffsetDoc = $returnRes['offset_doc'];
+                $fingerprintInit = $returnRes['fingerprint'];
+
+                $returnDs = DatabaseModel::select([
+                    'select'    => ['adr_priority_number'],
+                    'table'     => ['docservers'],
+                    'where'     => ['docserver_id = ?'],
+                    'data'      => [$resDocserverId]
+                ]);
+
+                DatabaseModel::insert([
+                    'table'         => $aArgs['adrTable'],
+                    'columnsValues' => [
+                        'res_id'        => $aArgs['resId'],
+                        'docserver_id'  => $resDocserverId,
+                        'path'          => $resPath,
+                        'filename'      => $resFilename,
+                        'offset_doc'    => $resOffsetDoc,
+                        'fingerprint'   => $fingerprintInit,
+                        'adr_priority'  => $returnDs[0]['adr_priority_number'],
+                    ]
+                ]);
+            }
 
-        if (empty($aReturn[0])) {
-            return [];
+            $returnAdr = DatabaseModel::select([
+                'select'    => ['*'],
+                'table'     => [$aArgs['adrTable']],
+                'where'     => ['res_id = ?', 'adr_type= ?'],
+                'data'      => [$aArgs['resId'], 'CONV'],
+            ]);
+            
+            if (empty($returnAdr)) {
+                DatabaseModel::insert([
+                    'table'         => $aArgs['adrTable'],
+                    'columnsValues' => [
+                        'res_id'        => $aArgs['resId'],
+                        'docserver_id'  => $aArgs['docserver']['docserver_id'],
+                        'path'          => $aArgs['path'],
+                        'filename'      => $aArgs['fileName'],
+                        'offset_doc'    => $offsetDoc,
+                        'fingerprint'   => $fingerprint,
+                        'adr_priority'  => $aArgs['docserver']['adr_priority_number'],
+                        'adr_type'      => 'CONV',
+                    ]
+                ]);
+            } else {
+                DatabaseModel::update([
+                    'table'     => $aArgs['adrTable'],
+                    'set'       => [
+                        'docserver_id'  => $aArgs['docserver']['docserver_id'],
+                        'path'          => $aArgs['path'],
+                        'filename'      => $aArgs['fileName'],
+                        'offset_doc'    => $offsetDoc,
+                        'fingerprint'   => $fingerprint,
+                        'adr_priority'  => $aArgs['docserver']['adr_priority_number'],
+                    ],
+                    'where'     => ['res_id = ?', "adr_type = ?"],
+                    'data'      => [$aArgs['resId'], 'CONV']
+                ]);
+            }
+
+            HistoryController::add([
+                'tableName' => $aArgs['resTable'],
+                'recordId'  => (string) $aArgs['resId'],
+                'eventType' => 'ADD',
+                'info'      => 'process convert done',
+                'moduleId'  => 'convert',
+                'eventId'   => 'convert',
+            ]);
+
+            $queryCpt = DatabaseModel::select([
+                'select'    => ["coalesce(custom_t9, '0') as custom_t9"],
+                'table'     => [$aArgs['resTable']],
+                'where'     => ['res_id = ?'],
+                'data'      => [$aArgs['resId']],
+            ]);
+
+            $cptConvert = $queryCpt[0]['custom_t9'] + 1;
+
+            DatabaseModel::update([
+                'table'     => $aArgs['resTable'],
+                'set'       => [
+                    'convert_result'      => '1',
+                    'is_multi_docservers' => 'Y',
+                    'custom_t9'           => $cptConvert,
+                ],
+                'where'     => ['res_id = ?'],
+                'data'      => [$aArgs['resId']]
+            ]);
+
+            $returnArray = array(
+                'status' => '0',
+                'value' => '',
+                'error' => '',
+            );
+            return $returnArray;
+        } catch (Exception $e) {
+            $returnArray = array(
+                'status' => '1',
+                'value' => '',
+                'error' => $e->getMessage(),
+            );
+            return $returnArray;
         }
+    }
 
-        return $aReturn[0];
+    /**
+     * Updating the database with the error code
+     * @param string $resTable res table
+     * @param bigint $resId Id of the resource to process
+     * @param string $result error code
+     * @return nothing
+     */
+    public static function manageErrorOnDb(
+        $resTable, 
+        $resId,
+        $result
+    ) {
+        DatabaseModel::update([
+            'table'     => $aArgs['resTable'],
+            'set'       => [
+                'convert_result' => $result,
+            ],
+            'where'     => ['res_id = ?'],
+            'data'      => [$aArgs['resId']]
+        ]);
     }
 }
diff --git a/modules/convert/Test/ProcessConvertTest.php b/modules/convert/Test/ProcessConvertTest.php
index ac409db3a46dbe2b14b01091496362d4f6dd0a3d..c1f69f11bae4522e0c81b83e18e468201fd43d1e 100644
--- a/modules/convert/Test/ProcessConvertTest.php
+++ b/modules/convert/Test/ProcessConvertTest.php
@@ -20,14 +20,13 @@ class ProcessConvertTest extends TestCase
         $aArgs = [
             'collId' => 'letterbox_coll', 
             'resTable' => 'res_letterbox', 
-            'adrTable' => 'adr_x', 
-            'resId' => 100, 
+            'adrTable' => 'adr_letterbox', 
+            'resId' => 137, 
             'tmpDir' => $_SESSION['config']['tmppath']
         ];
 
         $response = $action->convert($aArgs);
-        var_dump($response);
-
+        
         $this->assertArrayHasKey('status', $response);
     }
 }
diff --git a/modules/convert/Test/ProcessFulltextTest.php b/modules/convert/Test/ProcessFulltextTest.php
index 74dd04e2e407fbfb8a8251f347d7c881281e8f1f..c21f8022abf89d8806bc813a5c806a8e65d5b7d2 100644
--- a/modules/convert/Test/ProcessFulltextTest.php
+++ b/modules/convert/Test/ProcessFulltextTest.php
@@ -21,7 +21,7 @@ class ProcessFulltextTest extends TestCase
         $aArgs = [
             'collId' => 'letterbox_coll', 
             'resTable' => 'res_letterbox', 
-            'adrTable' => 'adr_x', 
+            'adrTable' => 'adr_letterbox', 
             'resId' => 100,
             'tmpDir' => $_SESSION['config']['tmppath']
         ];
diff --git a/modules/convert/convert.sql b/modules/convert/convert.sql
index 62438dd3d9f06853f95df3eb5c5e27e01121eaf5..6a6663fa4c2aa2ce6d8d4d38798f841fc728f6f8 100644
--- a/modules/convert/convert.sql
+++ b/modules/convert/convert.sql
@@ -27,12 +27,77 @@ ALTER TABLE res_x ADD COLUMN tnl_result character varying(10) DEFAULT NULL::char
 ALTER TABLE res_version_attachments DROP COLUMN IF EXISTS tnl_result;
 ALTER TABLE res_version_attachments ADD COLUMN tnl_result character varying(10) DEFAULT NULL::character varying;
 
+-- adr_letterbox
+DROP TABLE IF EXISTS adr_letterbox;
+CREATE TABLE adr_letterbox
+(
+  res_id bigint NOT NULL,
+  docserver_id character varying(32) NOT NULL,
+  path character varying(255) DEFAULT NULL::character varying,
+  filename character varying(255) DEFAULT NULL::character varying,
+  offset_doc character varying(255) DEFAULT NULL::character varying,
+  fingerprint character varying(255) DEFAULT NULL::character varying,
+  adr_priority integer NOT NULL,
+  adr_type character varying(32) NOT NULL DEFAULT 'DOC'::character varying,
+  CONSTRAINT adr_letterbox_pkey PRIMARY KEY (res_id, docserver_id)
+)
+WITH (OIDS=FALSE);
+
+-- adr_attachments
+DROP TABLE IF EXISTS adr_attachments;
+CREATE TABLE adr_attachments
+(
+  res_id bigint NOT NULL,
+  docserver_id character varying(32) NOT NULL,
+  path character varying(255) DEFAULT NULL::character varying,
+  filename character varying(255) DEFAULT NULL::character varying,
+  offset_doc character varying(255) DEFAULT NULL::character varying,
+  fingerprint character varying(255) DEFAULT NULL::character varying,
+  adr_priority integer NOT NULL,
+  adr_type character varying(32) NOT NULL DEFAULT 'DOC'::character varying,
+  CONSTRAINT adr_attachments_pkey PRIMARY KEY (res_id, docserver_id)
+)
+WITH (OIDS=FALSE);
+
+-- adr_attachments_version
+DROP TABLE IF EXISTS adr_attachments_version;
+CREATE TABLE adr_attachments_version
+(
+  res_id bigint NOT NULL,
+  docserver_id character varying(32) NOT NULL,
+  path character varying(255) DEFAULT NULL::character varying,
+  filename character varying(255) DEFAULT NULL::character varying,
+  offset_doc character varying(255) DEFAULT NULL::character varying,
+  fingerprint character varying(255) DEFAULT NULL::character varying,
+  adr_priority integer NOT NULL,
+  adr_type character varying(32) NOT NULL DEFAULT 'DOC'::character varying,
+  CONSTRAINT adr_attachments_version_pkey PRIMARY KEY (res_id, docserver_id)
+)
+WITH (OIDS=FALSE);
+
+-- convert working table
+DROP TABLE IF EXISTS convert_stack;
+CREATE TABLE convert_stack
+(
+  coll_id character varying(32) NOT NULL,
+  res_id bigint NOT NULL,
+  convert_format character varying(32) NOT NULL DEFAULT 'pdf'::character varying,
+  cnt_retry integer,
+  status character(1) NOT NULL,
+  work_batch bigint,
+  regex character varying(32),
+  CONSTRAINT convert_stack_pkey PRIMARY KEY (coll_id, res_id, convert_format)
+)
+WITH (OIDS=FALSE);
+
 
 -- ************************************************************************* --
 --                               DATAS                             --
 -- ************************************************************************* --
 
 -- docservers
+UPDATE docservers set docserver_type_id = 'DOC';
+
 
 DELETE FROM docserver_types where docserver_type_id = 'CONVERT';
 INSERT INTO docserver_types (docserver_type_id, docserver_type_label, enabled, is_container, container_max_number, is_compressed, compression_mode, is_meta, meta_template, is_logged, log_template, is_signed, fingerprint_mode) 
diff --git a/phpunit.xml b/phpunit.xml
index 2ae7c3d3054df3b74c4a449a1f3abdf6a2bbf621..a85067c11e64da78c882cc744a9c580bea72a417 100755
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -9,7 +9,8 @@
             <file>core/Test/ResExtControllerTest.php</file-->
             <file>core/Test/StatusControllerTest.php</file>
             <file>core/Test/UserControllerTest.php</file>
-            <file>modules/convert/Test/ProcessFulltextTest.php</file>
+            <file>modules/convert/Test/ProcessConvertTest.php</file>
+            <!--file>modules/convert/Test/ProcessFulltextTest.php</file-->
         </testsuite>
     </testsuites>
     <filter>