diff --git a/apps/maarch_entreprise/template/history_list_diff.html b/apps/maarch_entreprise/template/history_list_diff.html
index 1940855651bb387d2d59143fb477e306ff577910..8e7d3b1b326162b7ff09156140505328409115a5 100755
--- a/apps/maarch_entreprise/template/history_list_diff.html
+++ b/apps/maarch_entreprise/template/history_list_diff.html
@@ -71,7 +71,7 @@ Mods
 
            <tr  class="##cssLine|col|white ##" >
                 <td width ="25%">##loadValue|updated_date##</td>
-                <td width ="50%">##loadValue|updated_by_user##</td>
+                <td width ="25%">##loadValue|user_id##</td>
                 <td width="30px" style="font-size:10px;" >##showActionIcon|Voir le detail de la liste|#loadImage|cogs fa-2x#|loadDiffListHistory('#loadValue|listinstance_history_id#')##</td>
             </tr>
 
diff --git a/modules/avis/difflist_avis_history_display.php b/modules/avis/difflist_avis_history_display.php
index 282186028142f641cd609e3b9de3361b87b8e092..b33dda038c07889e08366bfde6d3a1b710104bd5 100755
--- a/modules/avis/difflist_avis_history_display.php
+++ b/modules/avis/difflist_avis_history_display.php
@@ -74,7 +74,7 @@ $urlParameters = '';
 
 //Fields
     //Documents
-    array_push($select[$view], "listinstance_history_id", "res_id", "updated_by_user", "updated_date");
+    array_push($select[$view], "listinstance_history_id", "res_id", "updated_date", 'user_id');
 
 //Where clause
     $where_tab = array();
@@ -142,20 +142,16 @@ $urlParameters = '';
                     $tab[$i][$j]["value_export"] = $tab[$i][$j]['value'];
                     $tab[$i][$j]["order"]="res_id";
                 }
-
-                if ($tab[$i][$j][$value]=="updated_by_user") {
-                    $tab[$i][$j]["label"]=_UPDATED_BY_USER;
-                    $db = new Database();
-                    $stmt = $db->query("SELECT firstname, lastname FROM users WHERE user_id = ?", array($tab[$i][$j]['value']));
-                    $user = $stmt->fetchObject();
-                    $tab[$i][$j]['value'] =  ucwords($user->lastname) . " " . functions::show_string(ucfirst($user->firstname));
+                if ($tab[$i][$j][$value]=="user_id") {
+                    $tab[$i][$j]["label"] = _UPDATED_BY_USER;
+                    $tab[$i][$j]['value'] =  \User\models\UserModel::getLabelledUserById(['id' => $tab[$i][$j]['value']]);
                     $tab[$i][$j]["size"]="15";
                     $tab[$i][$j]["label_align"]="left";
                     $tab[$i][$j]["align"]="left";
                     $tab[$i][$j]["valign"]="bottom";
                     $tab[$i][$j]["show"]=true;
                     $tab[$i][$j]["value_export"] = $tab[$i][$j]['value'];
-                    $tab[$i][$j]["order"]="updated_by_user";
+                    $tab[$i][$j]["order"]="user_id";
                 }
 
                 if ($tab[$i][$j][$value]=="updated_date") {
diff --git a/modules/entities/class/class_manage_listdiff_Abstract.php b/modules/entities/class/class_manage_listdiff_Abstract.php
index 4ca045f6fb32189e20b53228d4e48e44cb4782c6..ffb1c3dda18bd508fd637fecefbc1d4c0c5de57b 100755
--- a/modules/entities/class/class_manage_listdiff_Abstract.php
+++ b/modules/entities/class/class_manage_listdiff_Abstract.php
@@ -603,8 +603,10 @@ abstract class diffusion_list_Abstract extends functions
 
     public function save_listinstance_history($coll_id, $res_id, $difflistType)
     {
+        $user = \User\models\UserModel::getByLogin(['select' => ['id'], 'login' => $_SESSION['user']['UserId']]);
+
         $db = new Database();
-        $db->query('INSERT INTO listinstance_history (coll_id, res_id, updated_by_user, updated_date) VALUES (?, ?, ?, current_timestamp)', array($coll_id, $res_id, $_SESSION['user']['UserId']));
+        $db->query('INSERT INTO listinstance_history (coll_id, res_id, user_id, updated_date) VALUES (?, ?, ?, current_timestamp)', array($coll_id, $res_id, $user['id']));
         $listinstance_history_id = $db->lastInsertId('listinstance_history_id_seq');
 
         $stmt = $db->query('SELECT * FROM listinstance WHERE res_id = ? and coll_id = ? and difflist_type = ?', array($res_id, $coll_id, $difflistType));
diff --git a/modules/entities/difflist_history_display.php b/modules/entities/difflist_history_display.php
index 37d0fc7286c292b51b2004b46d0322e3efc25c02..0e2d0782356819703517b8f38dab040e8d7ad6b4 100755
--- a/modules/entities/difflist_history_display.php
+++ b/modules/entities/difflist_history_display.php
@@ -75,7 +75,7 @@ $urlParameters = '';
 
 //Fields
     //Documents
-    array_push($select[$view], "listinstance_history_id", "res_id", "updated_by_user", "updated_date");
+    array_push($select[$view], "listinstance_history_id", "res_id", "updated_date", 'user_id');
 
 //Where clause
     $where_tab = array();
@@ -143,20 +143,16 @@ $urlParameters = '';
                     $tab[$i][$j]["value_export"] = $tab[$i][$j]['value'];
                     $tab[$i][$j]["order"]="res_id";
                 }
-
-                if ($tab[$i][$j][$value]=="updated_by_user") {
-                    $tab[$i][$j]["label"]=_UPDATED_BY_USER;
-                    $db = new Database();
-                    $stmt = $db->query("SELECT firstname, lastname FROM users WHERE user_id = '".$tab[$i][$j]['value']."'");
-                    $user = $stmt->fetchObject();
-                    $tab[$i][$j]['value'] =  ucwords($user->lastname) . " " . functions::show_string(ucfirst($user->firstname));
+                if ($tab[$i][$j][$value]=="user_id") {
+                    $tab[$i][$j]["label"] = _UPDATED_BY_USER;
+                    $tab[$i][$j]['value'] =  \User\models\UserModel::getLabelledUserById(['id' => $tab[$i][$j]['value']]);
                     $tab[$i][$j]["size"]="15";
                     $tab[$i][$j]["label_align"]="left";
                     $tab[$i][$j]["align"]="left";
                     $tab[$i][$j]["valign"]="bottom";
                     $tab[$i][$j]["show"]=true;
                     $tab[$i][$j]["value_export"] = $tab[$i][$j]['value'];
-                    $tab[$i][$j]["order"]="updated_by_user";
+                    $tab[$i][$j]["order"]="user_id";
                 }
 
                 if ($tab[$i][$j][$value]=="updated_date") {
diff --git a/modules/entities/difflist_visa_history_display.php b/modules/entities/difflist_visa_history_display.php
index d5fcf9642ccc1677d89853b7d6912ff686e0f4a4..177486cb519750fe2a9333d5c5fd5dd554c4aa27 100755
--- a/modules/entities/difflist_visa_history_display.php
+++ b/modules/entities/difflist_visa_history_display.php
@@ -74,7 +74,7 @@ $urlParameters = '';
 
 //Fields
     //Documents
-    array_push($select[$view], "listinstance_history_id", "res_id", "updated_by_user", "updated_date");
+    array_push($select[$view], "listinstance_history_id", "res_id", 'user_id', "updated_date");
 
 //Where clause
     $where_tab = array();
@@ -142,20 +142,16 @@ $urlParameters = '';
                     $tab[$i][$j]["value_export"] = $tab[$i][$j]['value'];
                     $tab[$i][$j]["order"]="res_id";
                 }
-
-                if ($tab[$i][$j][$value]=="updated_by_user") {
-                    $tab[$i][$j]["label"]=_UPDATED_BY_USER;
-                    $db = new Database();
-                    $stmt = $db->query("SELECT firstname, lastname FROM users WHERE user_id = ?", array($tab[$i][$j]['value']));
-                    $user = $stmt->fetchObject();
-                    $tab[$i][$j]['value'] =  ucwords($user->lastname) . " " . functions::show_string(ucfirst($user->firstname));
+                if ($tab[$i][$j][$value]=="user_id") {
+                    $tab[$i][$j]["label"] = _UPDATED_BY_USER;
+                    $tab[$i][$j]['value'] =  \User\models\UserModel::getLabelledUserById(['id' => $tab[$i][$j]['value']]);
                     $tab[$i][$j]["size"]="15";
                     $tab[$i][$j]["label_align"]="left";
                     $tab[$i][$j]["align"]="left";
                     $tab[$i][$j]["valign"]="bottom";
                     $tab[$i][$j]["show"]=true;
                     $tab[$i][$j]["value_export"] = $tab[$i][$j]['value'];
-                    $tab[$i][$j]["order"]="updated_by_user";
+                    $tab[$i][$j]["order"]="user_id";
                 }
 
                 if ($tab[$i][$j][$value]=="updated_date") {
diff --git a/sql/develop.sql b/sql/develop.sql
index bedefa7f7ea580984ecc614a197490b76522d18c..f1beecb4d2b00b14c3616db0ff6012247c5f8c26 100755
--- a/sql/develop.sql
+++ b/sql/develop.sql
@@ -135,26 +135,6 @@ END$$;
 UPDATE baskets SET basket_clause = regexp_replace(basket_clause,'recommendation_limit_date','opinion_limit_date','g');
 UPDATE baskets SET basket_res_order = regexp_replace(basket_res_order,'recommendation_limit_date','opinion_limit_date','g');
 
-/* REFACTORING */
-ALTER TABLE mlb_coll_ext DROP COLUMN IF EXISTS flag_notif;
-DELETE FROM usergroups_services WHERE service_id = 'print_doc_details_from_list';
-UPDATE res_letterbox SET locker_user_id = NULL;
-ALTER TABLE res_letterbox ALTER COLUMN locker_user_id DROP DEFAULT;
-ALTER TABLE res_letterbox ALTER COLUMN locker_user_id TYPE INTEGER USING locker_user_id::integer;
-ALTER TABLE res_letterbox ALTER COLUMN locker_user_id SET DEFAULT NULL;
-ALTER TABLE notes DROP COLUMN IF EXISTS tablename;
-ALTER TABLE notes DROP COLUMN IF EXISTS coll_id;
-ALTER TABLE notes DROP COLUMN IF EXISTS type;
-ALTER TABLE notes ADD COLUMN type CHARACTER VARYING (32) DEFAULT 'resource' NOT NULL;
-DO $$ BEGIN
-  IF (SELECT count(attname) FROM pg_attribute WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'notes') AND attname = 'date_note') = 1 THEN
-	  ALTER TABLE notes RENAME COLUMN date_note TO creation_date;
-	  ALTER sequence notes_seq RENAME TO notes_id_seq;
-  END IF;
-END$$;
-ALTER TABLE res_mark_as_read DROP COLUMN IF EXISTS coll_id;
-
-
 /* PARAM LIST DISPLAY */
 UPDATE groupbasket SET list_display = '[{"value":"getPriority","cssClasses":[],"icon":"fa-traffic-light"},{"value":"getCategory","cssClasses":[],"icon":"fa-exchange-alt"},{"value":"getDoctype","cssClasses":[],"icon":"fa-suitcase"},{"value":"getAssignee","cssClasses":[],"icon":"fa-sitemap"},{"value":"getRecipients","cssClasses":[],"icon":"fa-user"},{"value":"getSenders","cssClasses":[],"icon":"fa-book"},{"value":"getCreationAndProcessLimitDates","cssClasses":["align_rightData"],"icon":"fa-calendar"}]' WHERE result_page = 'list_with_attachments' OR result_page = 'list_copies';
 UPDATE groupbasket SET list_display = '[{"value":"getPriority","cssClasses":[],"icon":"fa-traffic-light"},{"value":"getCategory","cssClasses":[],"icon":"fa-exchange-alt"},{"value":"getDoctype","cssClasses":[],"icon":"fa-suitcase"},{"value":"getParallelOpinionsNumber","cssClasses":["align_rightData"],"icon":"fa-comment-alt"},{"value":"getOpinionLimitDate","cssClasses":["align_rightData"],"icon":"fa-stopwatch"}]' WHERE result_page = 'list_with_avis';
@@ -199,6 +179,35 @@ DELETE FROM docservers WHERE docserver_id = 'ACKNOWLEDGEMENT_RECEIPTS';
 INSERT INTO docservers (docserver_id, docserver_type_id, device_label, is_readonly, size_limit_number, actual_size_number, path_template, creation_date, coll_id)
 VALUES ('ACKNOWLEDGEMENT_RECEIPTS', 'ACKNOWLEDGEMENT_RECEIPTS', 'Dépôt des AR', 'N', 50000000000, 0, '/opt/maarch/docservers/acknowledgment_receipts/', '2019-04-19 22:22:22.201904', 'letterbox_coll');
 
+/* REFACTORING */
+ALTER TABLE mlb_coll_ext DROP COLUMN IF EXISTS flag_notif;
+DELETE FROM usergroups_services WHERE service_id = 'print_doc_details_from_list';
+UPDATE res_letterbox SET locker_user_id = NULL;
+ALTER TABLE res_letterbox ALTER COLUMN locker_user_id DROP DEFAULT;
+ALTER TABLE res_letterbox ALTER COLUMN locker_user_id TYPE INTEGER USING locker_user_id::integer;
+ALTER TABLE res_letterbox ALTER COLUMN locker_user_id SET DEFAULT NULL;
+ALTER TABLE notes DROP COLUMN IF EXISTS tablename;
+ALTER TABLE notes DROP COLUMN IF EXISTS coll_id;
+ALTER TABLE notes DROP COLUMN IF EXISTS type;
+ALTER TABLE notes ADD COLUMN type CHARACTER VARYING (32) DEFAULT 'resource' NOT NULL;
+DO $$ BEGIN
+  IF (SELECT count(attname) FROM pg_attribute WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'notes') AND attname = 'date_note') = 1 THEN
+	  ALTER TABLE notes RENAME COLUMN date_note TO creation_date;
+	  ALTER sequence notes_seq RENAME TO notes_id_seq;
+  END IF;
+END$$;
+ALTER TABLE res_mark_as_read DROP COLUMN IF EXISTS coll_id;
+DO $$ BEGIN
+  IF (SELECT count(attname) FROM pg_attribute WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'listinstance_history') AND attname = 'updated_by_user') THEN
+    ALTER TABLE listinstance_history DROP COLUMN IF EXISTS user_id;
+    ALTER TABLE listinstance_history ADD COLUMN user_id integer;
+    UPDATE listinstance_history set user_id = (select id FROM users where users.user_id = listinstance_history.updated_by_user);
+    ALTER TABLE listinstance_history ALTER COLUMN user_id set not null;
+    ALTER TABLE listinstance_history DROP COLUMN IF EXISTS updated_by_user;
+  END IF;
+END$$;
+
+
 /* RE-CREATE VIEW*/
 CREATE OR REPLACE VIEW res_view_letterbox AS
  SELECT r.tablename,
diff --git a/sql/structure.sql b/sql/structure.sql
index eaee8dd354185a3ae7279267d6a7e30c0b415e66..fb3f69cabfbe51ed8ff7991e92ae186a562494f2 100755
--- a/sql/structure.sql
+++ b/sql/structure.sql
@@ -1557,7 +1557,7 @@ CREATE TABLE listinstance_history
 listinstance_history_id bigint NOT NULL DEFAULT nextval('listinstance_history_id_seq'::regclass),
 coll_id character varying(50) NOT NULL,
 res_id bigint NOT NULL,
-updated_by_user character varying(128) NOT NULL,
+user_id INTEGER NOT NULL,
 updated_date timestamp without time zone NOT NULL,
 CONSTRAINT listinstance_history_pkey PRIMARY KEY (listinstance_history_id)
 )
diff --git a/src/app/entity/controllers/ListInstanceController.php b/src/app/entity/controllers/ListInstanceController.php
index bdc13e9817dad1e1cc497824e4f52ebe04a1f8c9..d91e7fa6af188d4a344e1f3db0965f5ddb1d6c09 100755
--- a/src/app/entity/controllers/ListInstanceController.php
+++ b/src/app/entity/controllers/ListInstanceController.php
@@ -14,6 +14,8 @@
 
 namespace Entity\controllers;
 
+use Entity\models\ListInstanceHistoryDetailModel;
+use Entity\models\ListInstanceHistoryModel;
 use Entity\models\ListInstanceModel;
 use Slim\Http\Request;
 use Slim\Http\Response;
@@ -83,6 +85,8 @@ class ListInstanceController
 
         DatabaseModel::beginTransaction();
 
+        $currentUser = UserModel::getByLogin(['login' => $GLOBALS['userId']]);
+
         foreach ($body as $ListInstanceByRes) {
             if (empty($ListInstanceByRes['resId'])) {
                 DatabaseModel::rollbackTransaction();
@@ -94,73 +98,93 @@ class ListInstanceController
                 return $response->withStatus(403)->withJson(['errors' => 'Document out of perimeter']);
             }
 
+            if (empty($ListInstanceByRes['listInstances'])) {
+                continue;
+            }
+
+            $listInstances = ListInstanceModel::get([
+                'select'    => ['*'],
+                'where'     => ['res_id = ?', 'difflist_type = ?'],
+                'data'      => [$ListInstanceByRes['resId'], $ListInstanceByRes['listInstances'][0]['difflist_type']]
+            ]);
             ListInstanceModel::delete([
                 'where' => ['res_id = ?', 'difflist_type = ?'],
-                'data'  => [$ListInstanceByRes['resId'], 'entity_id']
+                'data'  => [$ListInstanceByRes['resId'], $ListInstanceByRes['listInstances'][0]['difflist_type']]
             ]);
 
-            if (empty($ListInstanceByRes['listInstances'])) {
-                DatabaseModel::rollbackTransaction();
-                return $response->withStatus(400)->withJson(['listInstances is missing or is empty']);
-            } else {
-                foreach ($ListInstanceByRes['listInstances'] as $instance) {
-                    
-                    $listControl = ['res_id', 'item_id', 'item_type', 'item_mode', 'difflist_type'];
-                    foreach($listControl as $itemControl){
-                        if (empty($instance[$itemControl])) {
-                            return $response->withStatus(400)->withJson(['errors' => $itemControl . ' are empty']);
-                        }
+            foreach ($ListInstanceByRes['listInstances'] as $instance) {
+                $listControl = ['res_id', 'item_id', 'item_type', 'item_mode', 'difflist_type'];
+                foreach($listControl as $itemControl){
+                    if (empty($instance[$itemControl])) {
+                        return $response->withStatus(400)->withJson(['errors' => $itemControl . ' are empty']);
                     }
-                    
-                    unset($instance['listinstance_id']);
-                    unset($instance['requested_signature']);
-                    unset($instance['signatory']);
-                    
-                    if ($instance['item_type'] == 'user_id') {
-                        $user = UserModel::getByLogin(['login' => $instance['item_id']]);
-                        if (empty($user) || $user['status'] != "OK") {
-                            DatabaseModel::rollbackTransaction();
-                            return $response->withStatus(400)->withJson(['errors' => 'User not found or not active']);
-                        }
-                    } elseif ($instance['item_type'] == 'entity_id') {
-                        $entity = EntityModel::getByEntityId(['entityId' => $instance['item_id']]);
-                        if (empty($entity) || $entity['enabled'] != "Y") {
-                            DatabaseModel::rollbackTransaction();
-                            return $response->withStatus(400)->withJson(['errors' => 'Entity not found or not active']);
-                        }
+                }
+
+                unset($instance['listinstance_id']);
+                unset($instance['requested_signature']);
+                unset($instance['signatory']);
+
+                if ($instance['item_type'] == 'user_id') {
+                    $user = UserModel::getByLogin(['login' => $instance['item_id']]);
+                    if (empty($user) || $user['status'] != "OK") {
+                        DatabaseModel::rollbackTransaction();
+                        return $response->withStatus(400)->withJson(['errors' => 'User not found or not active']);
                     }
+                } elseif ($instance['item_type'] == 'entity_id') {
+                    $entity = EntityModel::getByEntityId(['entityId' => $instance['item_id']]);
+                    if (empty($entity) || $entity['enabled'] != "Y") {
+                        DatabaseModel::rollbackTransaction();
+                        return $response->withStatus(400)->withJson(['errors' => 'Entity not found or not active']);
+                    }
+                }
+
+                ListInstanceModel::create($instance);
 
-                    ListInstanceModel::create($instance);
-
-                    if ($instance['item_mode'] == 'dest') {
-                        $set = ['dest_user' => $instance['item_id']];
-                        $changeDestination = true;
-                        $entities = UserEntityModel::get(['select' => ['entity_id', 'primary_entity'], 'where' => ['user_id = ?'], 'data' => [$instance['item_id']]]);
-                        $resource = ResModel::getById(['select' => ['destination'], 'resId' => [$instance['res_id']]]);
-                        foreach ($entities as $entity) {
-                            if ($entity['entity_id'] == $resource['destination']) {
-                                $changeDestination = false;
-                            }
-                            if ($entity['primary_entity'] == 'Y') {
-                                $primaryEntity = $entity['entity_id'];
-                            }
+                if ($instance['item_mode'] == 'dest') {
+                    $set = ['dest_user' => $instance['item_id']];
+                    $changeDestination = true;
+                    $entities = UserEntityModel::get(['select' => ['entity_id', 'primary_entity'], 'where' => ['user_id = ?'], 'data' => [$instance['item_id']]]);
+                    $resource = ResModel::getById(['select' => ['destination'], 'resId' => [$instance['res_id']]]);
+                    foreach ($entities as $entity) {
+                        if ($entity['entity_id'] == $resource['destination']) {
+                            $changeDestination = false;
                         }
-                        if ($changeDestination && !empty($primaryEntity)) {
-                            $set['destination'] = $primaryEntity;
+                        if ($entity['primary_entity'] == 'Y') {
+                            $primaryEntity = $entity['entity_id'];
                         }
-
-                        ResModel::update([
-                            'set'   => $set,
-                            'where' => ['res_id = ?'],
-                            'data'  => [$instance['res_id']]
-                        ]);
                     }
+                    if ($changeDestination && !empty($primaryEntity)) {
+                        $set['destination'] = $primaryEntity;
+                    }
+
+                    ResModel::update([
+                        'set'   => $set,
+                        'where' => ['res_id = ?'],
+                        'data'  => [$instance['res_id']]
+                    ]);
                 }
             }
+
+            $listInstanceHistoryId = ListInstanceHistoryModel::create(['resId' => $ListInstanceByRes['resId'], 'userId' => $currentUser['id']]);
+            foreach ($listInstances as $listInstance) {
+                ListInstanceHistoryDetailModel::create([
+                    'listinstance_history_id'   => $listInstanceHistoryId,
+                    'res_id'                    => $listInstance['res_id'],
+                    'sequence'                  => $listInstance['sequence'],
+                    'item_id'                   => $listInstance['item_id'],
+                    'item_type'                 => $listInstance['item_type'],
+                    'item_mode'                 => $listInstance['item_mode'],
+                    'added_by_user'             => $listInstance['added_by_user'],
+                    'added_by_entity'           => $listInstance['added_by_entity'],
+                    'difflist_type'             => $listInstance['difflist_type'],
+                    'process_date'              => $listInstance['process_date'],
+                    'process_comment'           => $listInstance['process_comment']
+                ]);
+            }
         }
 
         DatabaseModel::commitTransaction();
 
-        return $response->withJson(['success' => 'success']);
+        return $response->withStatus(204);
     }
 }
diff --git a/src/app/entity/models/ListInstanceHistoryDetailModel.php b/src/app/entity/models/ListInstanceHistoryDetailModel.php
new file mode 100644
index 0000000000000000000000000000000000000000..b8377972a415236ba38c107e7cbc617120e641f2
--- /dev/null
+++ b/src/app/entity/models/ListInstanceHistoryDetailModel.php
@@ -0,0 +1,51 @@
+<?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 List Instance History Detail Model Abstract
+ * @author dev@maarch.org
+ */
+
+namespace Entity\models;
+
+use SrcCore\models\ValidatorModel;
+use SrcCore\models\DatabaseModel;
+
+class ListInstanceHistoryDetailModel
+{
+    public static function create(array $args)
+    {
+        ValidatorModel::notEmpty($args, ['listinstance_history_id', 'resId', 'item_id', 'item_type', 'item_mode', 'added_by_user', 'added_by_entity', 'difflist_type']);
+        ValidatorModel::intVal($args, ['listinstance_history_id', 'resId', 'item_id']);
+        ValidatorModel::stringType($args, ['item_type', 'item_mode', 'added_by_user', 'added_by_entity', 'difflist_type', 'process_date', 'process_comment']);
+
+        DatabaseModel::insert([
+            'table'         => 'listinstance_history_details',
+            'columnsValues' => [
+                'listinstance_history_id'   => $args['listinstance_history_id'],
+                'coll_id'                   => 'letterbox_coll',
+                'res_id'                    => $args['res_id'],
+                'listinstance_type'         => 'DOC',
+                'sequence'                  => $args['sequence'],
+                'item_id'                   => $args['item_id'],
+                'item_type'                 => $args['item_type'],
+                'item_mode'                 => $args['item_mode'],
+                'added_by_user'             => $args['added_by_user'],
+                'added_by_entity'           => $args['added_by_entity'],
+                'visible'                   => 'Y',
+                'viewed'                    => 0,
+                'difflist_type'             => $args['difflist_type'],
+                'process_date'              => $args['process_date'],
+                'process_comment'           => $args['process_comment']
+            ]
+        ]);
+
+        return true;
+    }
+}
diff --git a/src/app/entity/models/ListInstanceHistoryModel.php b/src/app/entity/models/ListInstanceHistoryModel.php
new file mode 100644
index 0000000000000000000000000000000000000000..9cad393e1fb37645edd009fafac06c781b131797
--- /dev/null
+++ b/src/app/entity/models/ListInstanceHistoryModel.php
@@ -0,0 +1,42 @@
+<?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 List Instance History Model Abstract
+ * @author dev@maarch.org
+ */
+
+namespace Entity\models;
+
+use SrcCore\models\ValidatorModel;
+use SrcCore\models\DatabaseModel;
+
+class ListInstanceHistoryModel
+{
+    public static function create(array $args)
+    {
+        ValidatorModel::notEmpty($args, ['resId', 'userId']);
+        ValidatorModel::intVal($args, ['resId', 'userId']);
+
+        $nextSequenceId = DatabaseModel::getNextSequenceValue(['sequenceId' => 'listinstance_history_id_seq']);
+
+        DatabaseModel::insert([
+            'table'         => 'listinstance_history',
+            'columnsValues' => [
+                'listinstance_history_id'   => $nextSequenceId,
+                'coll_id'                   => 'letterbox_coll',
+                'res_id'                    => $args['resId'],
+                'user_id'                   => $args['userId'],
+                'updated_date'              => 'CURRENT_TIMESTAMP'
+            ]
+        ]);
+
+        return $nextSequenceId;
+    }
+}
diff --git a/src/app/entity/models/ListInstanceModelAbstract.php b/src/app/entity/models/ListInstanceModelAbstract.php
index 3b8842167a914987e410737292c9118d01967a13..9ec21153d4c36e2c823455d33874f377ca0dc3f3 100755
--- a/src/app/entity/models/ListInstanceModelAbstract.php
+++ b/src/app/entity/models/ListInstanceModelAbstract.php
@@ -22,17 +22,17 @@ abstract class ListInstanceModelAbstract
     public static function get(array $aArgs)
     {
         ValidatorModel::notEmpty($aArgs, ['select']);
-        ValidatorModel::arrayType($aArgs, ['select', 'where', 'data', 'orderBy']);
+        ValidatorModel::arrayType($aArgs, ['select', 'where', 'data', 'orderBy', 'groupBy']);
         ValidatorModel::intType($aArgs, ['limit']);
 
         $aListInstances = DatabaseModel::select([
             'select'    => $aArgs['select'],
             'table'     => ['listinstance'],
-            'where'     => $aArgs['where'],
-            'data'      => $aArgs['data'],
-            'order_by'  => $aArgs['orderBy'],
-            'groupBy'   => $aArgs['groupBy'],
-            'limit'     => $aArgs['limit']
+            'where'     => empty($aArgs['where']) ? [] : $aArgs['where'],
+            'data'      => empty($aArgs['data']) ? [] : $aArgs['data'],
+            'order_by'  => empty($aArgs['orderBy']) ? [] : $aArgs['orderBy'],
+            'groupBy'   => empty($aArgs['groupBy']) ? [] : $aArgs['groupBy'],
+            'limit'     => empty($aArgs['limit']) ? 0 : $aArgs['limit']
         ]);
 
         return $aListInstances;
diff --git a/src/app/user/models/UserModelAbstract.php b/src/app/user/models/UserModelAbstract.php
index 79eb53f9ed056b9ceaa6502906fd5a84f407fd99..de6edb8512e232ba74bf90bbddaaad49e16b6204 100755
--- a/src/app/user/models/UserModelAbstract.php
+++ b/src/app/user/models/UserModelAbstract.php
@@ -118,23 +118,30 @@ abstract class UserModelAbstract
         return true;
     }
 
-    public static function getByLogin(array $aArgs)
+    public static function getByLogin(array $args)
     {
-        ValidatorModel::notEmpty($aArgs, ['login']);
-        ValidatorModel::stringType($aArgs, ['login']);
+        ValidatorModel::notEmpty($args, ['login']);
+        ValidatorModel::stringType($args, ['login']);
 
-        $aUser = DatabaseModel::select([
-            'select'    => empty($aArgs['select']) ? ['*'] : $aArgs['select'],
+        static $users;
+
+        if (!empty($users[$args['login']])) {
+            return $users[$args['login']];
+        }
+
+        $user = DatabaseModel::select([
+            'select'    => ['*'],
             'table'     => ['users'],
             'where'     => ['user_id = ?'],
-            'data'      => [$aArgs['login']]
+            'data'      => [$args['login']]
         ]);
 
-        if (empty($aUser)) {
+        if (empty($user)) {
             return [];
         }
+        $users[$args['login']] = $user[0];
 
-        return $aUser[0];
+        return $users[$args['login']];
     }
     
     public static function getByLowerLogin(array $aArgs)