diff --git a/core/xml/actions_pages.xml b/core/xml/actions_pages.xml
index 2412c120e67dff9e86460c67ed5478e94cb90096..9b75658ed2e82105f5661a9d1e02dd3cb7a3d8a8 100755
--- a/core/xml/actions_pages.xml
+++ b/core/xml/actions_pages.xml
@@ -296,7 +296,7 @@ An action page is described in a ACTIONPAGE tag :
         <LABEL>_SEND_DOCS_TO_RECOMMENDATION</LABEL>
         <NAME>send_docs_to_recommendation</NAME>
         <DESC>_SEND_DOCS_TO_RECOMMENDATION_DESC</DESC>
-        <component>v1Action</component>
+        <component>sendToParallelOpinion</component>
         <ORIGIN>module</ORIGIN>
         <MODULE>avis</MODULE>
         <FLAG_CREATE>false</FLAG_CREATE>
diff --git a/migration/20.03/2003.sql b/migration/20.03/2003.sql
index 2fd777c0f56f86a208142117ab8ac1d7d2c23812..7ad82c81f35e9cf7318607ff59df1deb1711e4fc 100644
--- a/migration/20.03/2003.sql
+++ b/migration/20.03/2003.sql
@@ -98,6 +98,7 @@ UPDATE actions SET component = 'closeMailWithAttachmentsOrNotesAction' WHERE act
 UPDATE actions SET component = 'sendToOpinionCircuitAction' WHERE action_page = 'send_to_avis';
 UPDATE actions SET component = 'continueOpinionCircuitAction' WHERE action_page = 'avis_workflow';
 UPDATE actions SET component = 'giveOpinionParallelAction' WHERE action_page = 'avis_workflow_simple';
+UPDATE actions SET component = 'sendToParallelOpinion' WHERE action_page = 'send_docs_to_recommendation';
 
 DELETE FROM actions_groupbaskets WHERE id_action IN (SELECT id FROM actions WHERE action_page = 'put_in_copy');
 DELETE FROM actions_categories WHERE action_id IN (SELECT id FROM actions WHERE action_page = 'put_in_copy');
diff --git a/rest/index.php b/rest/index.php
index 1c4869f35a5f156c515ad99fa3d2550839d7f916..ead633a08ea5e055ce050d58a4d607ce34dc961c 100755
--- a/rest/index.php
+++ b/rest/index.php
@@ -352,6 +352,7 @@ $app->get('/resources/{resId}/templates', \Template\controllers\TemplateControll
 $app->get('/resources/{resId}/listInstance', \Entity\controllers\ListInstanceController::class . ':getByResId');
 $app->get('/resources/{resId}/visaCircuit', \Entity\controllers\ListInstanceController::class . ':getVisaCircuitByResId');
 $app->get('/resources/{resId}/opinionCircuit', \Entity\controllers\ListInstanceController::class . ':getOpinionCircuitByResId');
+$app->get('/resources/{resId}/parallelOpinion', \Entity\controllers\ListInstanceController::class . ':getParallelOpinionByResId');
 $app->get('/resources/{resId}/defaultCircuit', \Entity\controllers\ListTemplateController::class . ':getDefaultCircuitByResId');
 $app->delete('/resources/{resId}/circuits/{type}', \Entity\controllers\ListInstanceController::class . ':deleteCircuit');
 $app->get('/resources/{resId}/linkedResources', \Resource\controllers\LinkController::class . ':getLinkedResources');
diff --git a/sql/data_fr.sql b/sql/data_fr.sql
index 5dd63a1af3842556a9e494f248bd399d5832d74f..32a89d5c980e8172afd759e4b6139d801cedd80c 100755
--- a/sql/data_fr.sql
+++ b/sql/data_fr.sql
@@ -984,7 +984,7 @@ INSERT INTO actions (id, label_action, id_status, is_system, history, component)
 INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (22, '', 'Attribuer au service', 'NEW', 'N', 'confirm_status', 'Y', 'confirmAction');
 INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (23, 'indexing', 'Attribuer au(x) service(s)', 'NEW', 'N', 'confirm_status', 'Y', 'confirmAction');
 INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (24, 'indexing', 'Remettre en validation', 'VAL', 'N', 'confirm_status', 'Y', 'confirmAction');
-INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (36, '', 'Envoyer pour avis', 'EAVIS', 'N', 'send_docs_to_recommendation', 'Y', 'v1Action');
+INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (36, '', 'Envoyer pour avis', 'EAVIS', 'N', 'send_docs_to_recommendation', 'Y', 'sendToParallelOpinion');
 INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (37, '', 'Donner un avis', '_NOSTATUS_', 'N', 'avis_workflow_simple', 'Y', 'giveOpinionParallelAction');
 -- INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (100, '', 'Voir le document', '', 'N', 'view', 'N', 'viewDoc');
 --INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (101, '', 'Envoyer pour visa', 'VIS', 'N', 'confirm_status', 'Y', 'confirmAction');
@@ -997,8 +997,8 @@ INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_pag
 INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (407, '', 'Renvoyer pour traitement', 'COU', 'N', 'confirm_status', 'Y', 'confirmAction');
 INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (408, '', 'Refuser le visa et remonter le circuit', '_NOSTATUS_', 'N',  'rejection_visa_previous', 'N', 'rejectVisaBackToPreviousAction');
 INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (410, '', 'Transmettre la réponse signée', 'EENV', 'N', 'interrupt_visa', 'Y', 'interruptVisaAction');
-INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (414, '', 'Envoyer au parapheur', '_NOSTATUS_', 'N', 'send_to_visa', 'Y', 'v1Action');
-INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (416, '', 'Valider et poursuivre le circuit', '_NOSTATUS_', 'N', 'visa_workflow', 'Y', 'v1Action');
+INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (414, '', 'Envoyer au parapheur', '_NOSTATUS_', 'N', 'send_to_visa', 'Y', 'sendSignatureBookAction');
+INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (416, '', 'Valider et poursuivre le circuit', '_NOSTATUS_', 'N', 'visa_workflow', 'Y', 'continueVisaCircuitAction');
 --INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (417, '', 'Envoyer l''AR', 'SVX', 'N', 'send_to_contact_with_mandatory_attachment', 'Y', 'v1Action');
 INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (420, '', 'Classer sans suite', 'SSUITE', 'N', 'confirm_status', 'Y', 'confirmAction');
 INSERT INTO actions (id, keyword, label_action, id_status, is_system, action_page, history, component) VALUES (421, '', 'Retourner au Service Courrier', 'RET', 'N', 'confirm_status', 'Y', 'confirmAction');
diff --git a/src/app/action/controllers/ActionMethodController.php b/src/app/action/controllers/ActionMethodController.php
index cedace191a68938a3a16e90614b820ffcb219fba..ce3260aa942e44c6021429f9967e4ae127bab47b 100644
--- a/src/app/action/controllers/ActionMethodController.php
+++ b/src/app/action/controllers/ActionMethodController.php
@@ -25,9 +25,11 @@ use ExternalSignatoryBook\controllers\MaarchParapheurController;
 use History\controllers\HistoryController;
 use MessageExchange\controllers\MessageExchangeReviewController;
 use Note\models\NoteModel;
+use Resource\controllers\ResController;
 use Resource\models\ResModel;
 use SrcCore\models\CoreConfigModel;
 use SrcCore\models\CurlModel;
+use SrcCore\models\DatabaseModel;
 use SrcCore\models\ValidatorModel;
 use User\models\UserModel;
 
@@ -59,6 +61,7 @@ class ActionMethodController
         'rejectVisaBackToPreviousAction'        => 'rejectVisaBackToPrevious',
         'resetVisaAction'                       => 'resetVisa',
         'interruptVisaAction'                   => 'interruptVisa',
+        'sendToParallelOpinion'                 => 'sendToParallelOpinion',
         'sendToOpinionCircuitAction'            => 'sendToOpinionCircuit',
         'continueOpinionCircuitAction'          => 'continueOpinionCircuit',
         'giveOpinionParallelAction'             => 'giveOpinionParallel',
@@ -555,10 +558,116 @@ class ActionMethodController
             return ["errors" => ["Opinion limit date is missing"]];
         }
 
+        $opinionLimitDate = new \DateTime($args['data']['opinionLimitDate']);
+        $today = new \DateTime('today');
+        if ($opinionLimitDate < $today) {
+            return ['errors' => "Opinion limit date is not a valid date"];
+        }
+
         ResModel::update([
             'set'   => ['opinion_limit_date' => $args['data']['opinionLimitDate']],
-            'where' => ['res_id = ?', 'difflist_type = ?'],
-            'data'  => [$args['resId'], 'AVIS_CIRCUIT']
+            'where' => ['res_id = ?'],
+            'data'  => [$args['resId']]
+        ]);
+
+        return true;
+    }
+
+    public static function sendToParallelOpinion(array $args)
+    {
+
+        $currentUser = UserModel::getById(['select' => ['user_id'], 'id' => $args['userId']]);
+
+        DatabaseModel::beginTransaction();
+
+        foreach ($args['data'] as $ListInstanceByRes) {
+            if (empty($ListInstanceByRes['resId'])) {
+                DatabaseModel::rollbackTransaction();
+                return ['errors' => ['resId is empty']];
+            }
+
+            if (!Validator::intVal()->validate($ListInstanceByRes['resId']) || !ResController::hasRightByResId(['resId' => [$ListInstanceByRes['resId']], 'userId' => $GLOBALS['id']])) {
+                DatabaseModel::rollbackTransaction();
+                return ['errors' => ['Document out of perimeter']];
+            }
+
+            if (empty($ListInstanceByRes['listInstances'])) {
+                return ['errors' => ['listInstances is empty']];
+            }
+
+            $listInstances = ListInstanceModel::get([
+                'select'    => ['*'],
+                'where'     => ['res_id = ?', 'difflist_type = ?', 'item_mode in (?)'],
+                'data'      => [$ListInstanceByRes['resId'], 'entity_id', ['avis', 'avis_copy', 'avis_info']]
+            ]);
+            ListInstanceModel::delete([
+                'where' => ['res_id = ?', 'difflist_type = ?', 'item_mode in (?)'],
+                'data'  => [$ListInstanceByRes['resId'], 'entity_id', ['avis', 'avis_copy', 'avis_info']]
+            ]);
+
+            foreach ($ListInstanceByRes['listInstances'] as $instance) {
+                if (!in_array($instance['item_mode'], ['avis', 'avis_copy', 'avis_info']) {
+                    return ['errors' => ['item_mode is different from avis, avis_copy or avis_info']];
+                }
+            }
+
+            foreach ($ListInstanceByRes['listInstances'] as $key => $instance) {
+                $listControl = ['item_id', 'item_type', 'item_mode'];
+                foreach ($listControl as $itemControl) {
+                    if (empty($instance[$itemControl])) {
+                        return ['errors' => ["ListInstance {$itemControl} is not set or empty"]];
+                    }
+                }
+
+                if (in_array($instance['item_type'], ['user_id', 'user'])) {
+                    if ($instance['item_type'] == 'user_id') {
+                        $user = UserModel::getByLogin(['login' => $instance['item_id'], 'select' => ['id']]);
+                    } else {
+                        $user = UserModel::getById(['id' => $instance['item_id'], 'select' => ['id', 'user_id']]);
+                        $instance['item_id'] = $user['user_id'] ?? null;
+                        $instance['item_type'] = 'user_id';
+                    }
+                    if (empty($user)) {
+                        DatabaseModel::rollbackTransaction();
+                        return ['errors' => ['User not found']];
+                    }
+                } else {
+                    DatabaseModel::rollbackTransaction();
+                    return ['errors' => ['item_type does not exist']];
+                }
+
+                ListInstanceModel::create([
+                    'res_id'                => $ListInstanceByRes['resId'],
+                    'sequence'              => $key,
+                    'item_id'               => $instance['item_id'],
+                    'item_type'             => $instance['item_type'],
+                    'item_mode'             => $instance['item_mode'],
+                    'added_by_user'         => $currentUser['user_id'],
+                    'difflist_type'         => 'entity_id',
+                    'process_date'          => null,
+                    'process_comment'       => null,
+                    'requested_signature'   => false,
+                    'viewed'                => empty($instance['viewed']) ? 0 : $instance['viewed']
+                ]);
+            }
+        }
+
+        DatabaseModel::commitTransaction();
+
+        if (empty($args['data']['opinionLimitDate'])) {
+            return ["errors" => ["Opinion limit date is missing"]];
+        }
+
+        $opinionLimitDate = new \DateTime($args['data']['opinionLimitDate']);
+        $today = new \DateTime('today');
+        if ($opinionLimitDate < $today) {
+            return ['errors' => "Opinion limit date is not a valid date"];
+        }
+
+        ResModel::update([
+            'set'   => ['opinion_limit_date' => $args['data']['opinionLimitDate']],
+            'where' => ['res_id = ?'],
+            'data'  => [$args['resId']]
         ]);
 
         return true;
diff --git a/src/app/entity/controllers/ListInstanceController.php b/src/app/entity/controllers/ListInstanceController.php
index 35616ce0fae722c8f65ad9e63719cd38ef2f050e..c9a2918220f6d6cde921b7c8683884dc218e049d 100755
--- a/src/app/entity/controllers/ListInstanceController.php
+++ b/src/app/entity/controllers/ListInstanceController.php
@@ -95,6 +95,22 @@ class ListInstanceController
         return $response->withJson($listInstances);
     }
 
+    public function getParallelOpinionByResId(Request $request, Response $response, array $aArgs)
+    {
+        if (!Validator::intVal()->validate($aArgs['resId']) || !ResController::hasRightByResId(['resId' => [$aArgs['resId']], 'userId' => $GLOBALS['id']])) {
+            return $response->withStatus(403)->withJson(['errors' => 'Document out of perimeter']);
+        }
+
+        $listInstances = ListInstanceModel::getParallelOpinionByResId(['select' => ['listinstance_id', 'sequence', 'item_id', 'item_type', 'users.id', 'firstname as item_firstname', 'lastname as item_lastname', 'entity_label as item_entity', 'viewed', 'process_date', 'process_comment'], 'id' => $aArgs['resId']]);
+        foreach ($listInstances as $key => $value) {
+            $listInstances[$key]['item_id'] = $listInstances[$key]['id'];
+            $listInstances[$key]['item_type'] = 'user';
+            $listInstances[$key]['labelToDisplay'] = $listInstances[$key]['item_firstname'].' '.$listInstances[$key]['item_lastname'];
+        }
+
+        return $response->withJson($listInstances);
+    }
+
     public function update(Request $request, Response $response)
     {
         $body = $request->getParsedBody();
diff --git a/src/app/entity/models/ListInstanceModelAbstract.php b/src/app/entity/models/ListInstanceModelAbstract.php
index 83c205b50e70dc14f6d6619fce21e28417d54e15..3cb3d5ea4cba868050992e76a042bb7a78d5248f 100755
--- a/src/app/entity/models/ListInstanceModelAbstract.php
+++ b/src/app/entity/models/ListInstanceModelAbstract.php
@@ -150,6 +150,24 @@ abstract class ListInstanceModelAbstract
         return $aListinstance;
     }
 
+    public static function getParallelOpinionByResId(array $aArgs)
+    {
+        ValidatorModel::notEmpty($aArgs, ['id']);
+        ValidatorModel::intVal($aArgs, ['id']);
+        ValidatorModel::arrayType($aArgs, ['select']);
+
+        $aListinstance = DatabaseModel::select([
+            'select'    => empty($aArgs['select']) ? ['*'] : $aArgs['select'],
+            'table'     => ['listinstance', 'users', 'users_entities', 'entities'],
+            'left_join' => ['listinstance.item_id = users.user_id', 'users_entities.user_id = users.user_id', 'entities.entity_id = users_entities.entity_id'],
+            'where'     => ['res_id = ?', 'item_type = ?', 'difflist_type = ?', 'primary_entity = ?', 'item_mode in (?)'],
+            'data'      => [$aArgs['id'], 'user_id', 'entity_id', 'Y', ['avis', 'avis_copy', 'avis_info']],
+            'order_by'  => ['listinstance_id ASC'],
+        ]);
+
+        return $aListinstance;
+    }
+
     public static function getCurrentStepByResId(array $aArgs)
     {
         ValidatorModel::notEmpty($aArgs, ['resId']);