From 012f07054b3d83b3078744056f32c23c41c10839 Mon Sep 17 00:00:00 2001
From: "florian.azizian" <florian.azizian@maarch.org>
Date: Tue, 12 Dec 2017 23:31:49 +0100
Subject: [PATCH] FIX merged 17.06_project_develop into develop after prod MTES

---
 .../Views/profile.component.html              | 58 ++++++------
 apps/maarch_entreprise/actions/process.php    |  2 +-
 .../actions/validate_mail.php                 |  4 +-
 .../class/class_list_show_Abstract.php        |  4 +-
 .../class/class_lists_Abstract.php            | 26 +++++-
 .../indexing_searching/search_adv.php         |  2 +-
 .../indexing_searching/search_adv_result.php  |  9 +-
 .../js/angular/app/profile.component.js       | 78 +++++++++++-----
 .../js/angular/app/profile.component.ts       | 81 ++++++++++++-----
 .../angular/app/signature-book.component.js   | 12 +++
 .../angular/app/signature-book.component.ts   | 14 +++
 .../js/angular/lang/lang-fr.js                |  2 +-
 .../js/angular/lang/lang-fr.ts                |  2 +-
 apps/maarch_entreprise/js/functions.js        | 39 +++++++-
 apps/maarch_entreprise/lang/fr.php            |  5 +-
 apps/maarch_entreprise/log.php                |  3 +
 apps/maarch_entreprise/sso_connect.php        | 12 +--
 .../template/documents_list_attachments.html  |  3 +-
 .../documents_list_attachments_simple.html    |  4 +-
 .../tools/phpids/lib/IDS/maarch_filter.xml    |  4 +-
 core/Controllers/UserController.php           | 49 +++++++++-
 core/Models/UserModelAbstract.php             | 19 ++++
 core/manage_action.php                        |  5 ++
 modules/attachments/attachments_content.php   | 20 ++++-
 modules/attachments/css/module.css            |  2 +-
 .../attachments/frame_list_attachments.php    |  3 +-
 modules/attachments/js/functions.js           |  8 ++
 modules/attachments/view_attachment.php       |  2 +-
 .../basket/Models/BasketsModelAbstract.php    | 24 ++++-
 .../class/class_admin_basket_Abstract.php     | 12 +++
 modules/basket/display_basket_list.php        | 89 ++++++++++++-------
 modules/basket/view_baskets.php               | 21 +++--
 .../content_management/dist/src/MaarchCM.java | 16 ++++
 modules/entities/lang/fr.php                  |  2 +-
 .../batch/load_process_email_stack.php        | 22 +++--
 .../batch/process_email_stack.php             |  2 +-
 .../class_schedule_notifications_Abstract.php |  4 +-
 .../manage_notifications_controler.php        | 11 +--
 .../sendmail/batch/load_process_emails.php    |  1 -
 modules/sendmail/batch/process_emails.php     | 25 ++++--
 .../class/templates_controler_Abstract.php    | 17 ++--
 modules/templates/js/functions.js             |  1 +
 modules/templates/templates_management.php    | 13 ++-
 modules/visa/Controllers/VisaController.php   |  2 +-
 .../class/class_modules_tools_Abstract.php    | 22 ++---
 modules/visa/css/module.css                   |  4 +
 modules/visa/js/functions.js                  | 51 +++++++++--
 modules/visa/lang/fr.php                      |  4 +-
 modules/visa/visa_workflow.php                | 24 ++---
 sql/17_xx.sql                                 |  1 +
 sql/structure.sql                             |  2 +-
 51 files changed, 630 insertions(+), 212 deletions(-)

diff --git a/apps/maarch_entreprise/Views/profile.component.html b/apps/maarch_entreprise/Views/profile.component.html
index f301f4f3878..9590bdd5e30 100755
--- a/apps/maarch_entreprise/Views/profile.component.html
+++ b/apps/maarch_entreprise/Views/profile.component.html
@@ -16,10 +16,13 @@
                         <a data-toggle="modal" data-target="#managePreferences"><i class="fa fa-cog"></i> Préférences </a>
                     </li>
                     <li style="cursor: pointer">
-                        <a data-toggle="modal" data-target="#manageAbs"><i class="fa fa-user-times" title=""></i> {{lang.manageAbsences}} </a>
+                        <a data-toggle="modal" data-target="#manageSign"><i class="fa fa-vcard-o"></i> {{lang.manageSignatures}} </a>
+                    </li>
+                    <li style="cursor: pointer" (click)="displayAbsenceButton=false">
+                        <a data-toggle="modal" data-target="#manageAbs" id="redirectBasketCard"><i class="fa fa-share"></i> {{lang.manageAbsences}} </a>
                     </li>
                     <li style="cursor: pointer">
-                        <a data-toggle="modal" data-target="#manageSign"><i class="fa fa-vcard-o"></i> {{lang.manageSignatures}} </a>
+                        <a (click)="askRedirectBasket()" ><i class="fa fa-user-times"></i> Activer mon absence </a>
                     </li>
                 </ul>
             </div>
@@ -154,7 +157,7 @@
                                 <i class="fa fa-tasks" title="{{basket.basket_id}}"></i> {{basket.basket_name}}
                                 <span class="pull-right">
                                     <input name="color" type="color" style="background: none;border: none;height: 20px;width:20px;padding: 0;margin-right: 15px" [(ngModel)]="user.regroupedBaskets[i].baskets[y].color" (change)="updateBasketColor(i, y)"/>
-                                    <a (click)="user.regroupedBaskets[i].baskets[y].color = '#666666'; updateBasketColor(i, y)" title="Réinitialiser la couleur" style="cursor: pointer;color: #666666"><i class="fa fa-magic"></i></a>
+                                    <a (click)="user.regroupedBaskets[i].baskets[y].color = ''; updateBasketColor(i, y)" title="Réinitialiser la couleur" style="cursor: pointer;color: #666666"><i class="fa fa-magic"></i></a>
                                 </span>
                             </li>
                         </ul>
@@ -166,51 +169,54 @@
 </div>
 
 <div id="manageAbs" class="modal fade bs-example-modal-lg" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel">
-    <div class="modal-dialog modal-lg" role="document">
+    <div class="modal-dialog modal-lg" role="document" style="width: 55%">
         <div class="modal-content">
             <div class="modal-header">
                 <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
-                <h4 class="modal-title" id="myModalLabel">{{lang.manageAbsences}}</h4>
+                <h4 class="modal-title" id="myModalLabel">Rediriger mes bannettes</h4>
             </div>
-            <div class="modal-body">
-                <div class="alert alert-danger" role="alert">{{lang.autoLogoutAbsence}}</div>
+            <div class="modal-body" style="max-height: calc(100vh - 170px);overflow-y: auto;">
                 <nav class="navbar navbar-default">
                     <div class="container-fluid">
                         <form class="navbar-form navbar-left" style="width: 100%">
-                            <div style="margin-left: 16%;padding-top: 15px">Ctrl + Clic pour sélectionner plusieurs corbeilles</div>
-                            <div class="form-group" style="margin-left: 16%;max-width: 51%;">
-                                <select style="height: 150px;max-width: 87%;" id="selectBasketAbsenceUser" class="form-control">
-                                    <option *ngFor="let basket of user.baskets" [disabled]="basket.disabled" title="{{basket.basket_name}}">
+                            <div style="margin-left: 3%;padding-top: 15px">Ctrl + Clic pour sélectionner plusieurs bannettes</div>
+                            <div class="form-group" style="margin-left: 3%;width: 66%;">
+                                <select style="height: 150px;width: 84%;" id="selectBasketAbsenceUser" class="form-control" multiple name="basketsToRedirect" [(ngModel)]="basketsToRedirect">
+                                    <option *ngFor="let basket of user.baskets; let i = index" [disabled]="basket.disabled" [value]="i" title="{{basket.basket_name}} {{basket.userToDisplay ? '('+basket.userToDisplay+')' : ''}}">
                                         {{basket.basket_name}}
-                                        <span *ngIf="basket.group_id">({{basket.group_id}})</span>
                                         <span *ngIf="basket.userToDisplay">({{basket.userToDisplay}})</span>
                                     </option>
                                 </select>
-                                <span>&nbsp;{{lang.to}}&nbsp;</span>
+                                <span style="margin-left: 25px; margin-right: 12px">vers</span>
                             </div>
-                            <div class="form-group typeahead__container">
-                                <div class="typeahead__field">
-                                    <input id="absenceUser" type="text" class="form-control" placeholder="{{lang.user}}" autocomplete="off">
+                            <div class="form-group typeahead__container" style="width: 28%">
+                                <div class="typeahead__field" style="width: 100%">
+                                    <input id="absenceUser" type="text" class="form-control" placeholder="{{lang.user}}" autocomplete="off" style="width: 100%">
                                 </div>
                             </div>
                         </form>
-                        <ul class="nav navbar-nav navbar-right" (click)="addBasketRedirection()" style="cursor: pointer">
-                            <li><a title="{{lang.save}}"><i class="fa fa-plus"></i></a></li>
-                        </ul>
+                    </div>
+                    <div style="padding: 15px;text-align: center">
+                        En validant, les modifications de redirection des bannettes sont automatiquement enregistrées<br><br>
+                        <button type="button" (click)="addBasketRedirection()" class="btn btn-success">Valider</button>
                     </div>
                 </nav>
                 <ul class="list-group">
-                    <li class="list-group-item" *ngFor="let uam of userAbsenceModel; let i = index">
-                        <i class="fa fa-tasks" title="{{uam.basketId}}"></i> {{uam.basketName}}
+                    <li class="list-group-item" *ngFor="let basket of user.redirectedBaskets">
+                        <i class="fa fa-tasks" title="{{basket.basket_id}}"></i> {{basket.basket_name}}
                         <span class="pull-right">
-                            <span class="label label-primary">{{uam.newUser}}</span>
-                        <a (click)="delBasketRedirection(i)" style="cursor: pointer" title="{{lang.delete}}"><i class="fa fa-trash" style="color:red;"></i></a>
+                            <span class="label label-primary" title="{{basket.userIdRedirection}}">{{basket.userToDisplay}}</span>
+                            <a (click)="delBasketRedirection(basket)" style="cursor: pointer" title="Supprimer la redirection"><i class="fa fa-trash fa-lg" style="color:red;"></i></a>
                         </span>
                     </li>
                 </ul>
-            </div>
-            <div class="modal-footer">
-                <button type="button" (click)="activateAbsence()" class="btn btn-default">{{lang.activateAbsence}}</button>
+                <span *ngIf="displayAbsenceButton">
+                    <hr>
+                    <div style="padding-bottom: 10px;text-align: center">
+                        <button type="button" (click)="activateAbsence()" class="btn btn-warning"><i class="fa fa-user-times"></i> Activer mon absence</button>
+                    </div>
+                </span>
+
             </div>
         </div>
     </div>
diff --git a/apps/maarch_entreprise/actions/process.php b/apps/maarch_entreprise/actions/process.php
index 414478df87f..7165b9d5a6e 100755
--- a/apps/maarch_entreprise/actions/process.php
+++ b/apps/maarch_entreprise/actions/process.php
@@ -241,7 +241,7 @@ function get_form_txt($values, $path_manage_action,  $id_action, $table, $module
             .'onclick="$j.ajax({url :\'index.php?display=true&dir=actions&page=docLocker\', type : \'POST\',data : {\'AJAX_CALL\': true, \'unlock\': true, \'res_id\': ' . $res_id . '}, success: function (answer) { ' ;
 //        .'onclick="new Ajax.Request(\'' . $_SESSION['config']['businessappurl'] 
   //      . 'index.php?display=true&dir=actions&page=docLocker\',{ method:\'post\', parameters: {\'AJAX_CALL\': true, \'unlock\': true, \'res_id\': ' 
-    $frm_str .= 'window.location.href=window.location.href;} });var tmp_bask=$(\'baskets\');';
+    $frm_str .= 'window.location.href=window.location.href.replace(\'&directLinkToAction\', \'\');} });var tmp_bask=$(\'baskets\');';
     $frm_str .= 'if (tmp_bask){tmp_bask.style.visibility=\'visible\';}var tmp_ent =$(\'entity\');';
     $frm_str .= 'if (tmp_ent){tmp_ent.style.visibility=\'visible\';} var tmp_cat =$(\'category\');';
     $frm_str .= 'if (tmp_cat){tmp_cat.style.visibility=\'visible\';}destroyModal(\'modal_'
diff --git a/apps/maarch_entreprise/actions/validate_mail.php b/apps/maarch_entreprise/actions/validate_mail.php
index 6fd641639e1..6fd658cc3c0 100755
--- a/apps/maarch_entreprise/actions/validate_mail.php
+++ b/apps/maarch_entreprise/actions/validate_mail.php
@@ -1821,7 +1821,7 @@ function manage_form($arr_id, $history, $id_action, $label_action, $status,  $co
                     $arrayPDOext = array_merge($arrayPDOext, array($contact_id));
                 }
                     $db->query("DELETE FROM contacts_res where res_id = ?", array($res_id));
-                    $query_ext .= ", is_multicontacts = ''";
+                    $query_ext .= ", is_multicontacts = null";
                     
             }elseif($contact_type == 'external'){
                 if($cat_id == 'incoming' || $cat_id == 'ged_doc')
@@ -1839,7 +1839,7 @@ function manage_form($arr_id, $history, $id_action, $label_action, $status,  $co
                 $arrayPDOext = array_merge($arrayPDOext, array($addressId));
 
                 $db->query("DELETE FROM contacts_res where res_id = ?", array($res_id));
-                $query_ext .= ", is_multicontacts = ''";
+                $query_ext .= ", is_multicontacts = null";
             }
         }
     }
diff --git a/apps/maarch_entreprise/class/class_list_show_Abstract.php b/apps/maarch_entreprise/class/class_list_show_Abstract.php
index 44ce9548d77..01f1a4fcf5d 100755
--- a/apps/maarch_entreprise/class/class_list_show_Abstract.php
+++ b/apps/maarch_entreprise/class/class_list_show_Abstract.php
@@ -1264,7 +1264,7 @@ class list_show_Abstract extends functions
                                     }
                                     else
                                     {
-                                        echo functions::show_str(self::thisword($result[$theline][$count_column]['value'],$expr, TRUE));
+                                        echo functions::show_str($result[$theline][$count_column]['value']);
                                     }
 
                                 }
@@ -1393,7 +1393,7 @@ class list_show_Abstract extends functions
                                         while($res = $stmt->fetchObject()){
                                             $item_mode = null;
                                             $item_mode = $res->item_mode;
-                                            $entity_label[] = $res->entity_label;
+                                            $entity_label[] = addslashes($res->entity_label);
                                         }
                                         if($item_mode == 'dest'){
                                            ?>
diff --git a/apps/maarch_entreprise/class/class_lists_Abstract.php b/apps/maarch_entreprise/class/class_lists_Abstract.php
index 78dbff0555f..3d1db4c02b8 100755
--- a/apps/maarch_entreprise/class/class_lists_Abstract.php
+++ b/apps/maarch_entreprise/class/class_lists_Abstract.php
@@ -1209,7 +1209,25 @@ abstract class lists_Abstract extends Database
            
         return $return;
     }
-    
+
+    protected function _tmplt_visualizeIconDocument($resultTheLine, $listKey) {
+        
+        $href = $this->_buildMyLink($this->params['visualizeDocumentLink'], $resultTheLine, $listKey);
+
+        $return .= '<div align="right" class="iconDoc" style="" ><a href="'.$href.'" target="_blank"><i class="tooltip fa fa-eye fa-2x" title="' . _VISUALIZE . '"></i></a></div>';
+           
+        return $return;
+    }
+
+    protected function _tmplt_downloadIconDocument($resultTheLine, $listKey) {
+        
+        $href = $this->_buildMyLink($this->params['downloadDocumentLink'], $resultTheLine, $listKey);
+
+        $return .= '<div align="right" class="iconDoc" style="" ><a href="'.$href.'" target="_blank"><i class="tooltip fa fa-download fa-2x" title="' . _DOWNLOAD . '"></i></a></div>';
+           
+        return $return;
+    }
+
     protected function _tmplt_showIconDetails($resultTheLine, $listKey) {
         
         $return = '';
@@ -1728,6 +1746,12 @@ abstract class lists_Abstract extends Database
 		##showIconDocument## : show document icon and link
         } elseif (preg_match("/^showIconDocument$/", $parameter)) {
             $var = $this->_tmplt_showIconDocument($resultTheLine, $listKey);
+        ##visualizeIconDocument## : show document icon and link
+        } elseif (preg_match("/^visualizeIconDocument$/", $parameter)) {
+            $var = $this->_tmplt_visualizeIconDocument($resultTheLine, $listKey);
+        ##downloadIconDocument## : show download document icon and link
+        } elseif (preg_match("/^downloadIconDocument$/", $parameter)) {
+            $var = $this->_tmplt_downloadIconDocument($resultTheLine, $listKey);
         ##showIconDetails## : show details icon and link
         } elseif (preg_match("/^showIconDetails$/", $parameter)) {
             $var = $this->_tmplt_showIconDetails($resultTheLine, $listKey);
diff --git a/apps/maarch_entreprise/indexing_searching/search_adv.php b/apps/maarch_entreprise/indexing_searching/search_adv.php
index c31fa7196f2..e2bd7dc95ab 100755
--- a/apps/maarch_entreprise/indexing_searching/search_adv.php
+++ b/apps/maarch_entreprise/indexing_searching/search_adv.php
@@ -455,7 +455,7 @@ $arr_tmp2 = array('label' => _SIGNATORY_NAME, 'type' => 'input_text', 'param' =>
 $param['signatory_name'] = $arr_tmp2;
 
 //Visa user
-$arr_tmp2 = array('label' => _VISA_USER_SEARCH, 'type' => 'input_text', 'param' => array('field_label' => _VISA_USER_SEARCH, 'other' => $size, 'autocompletion' => true));
+$arr_tmp2 = array('label' => _VISA_USER_SEARCH_MIN, 'type' => 'input_text', 'param' => array('field_label' => _VISA_USER_SEARCH_MIN, 'other' => $size, 'autocompletion' => true));
 $param['visa_user'] = $arr_tmp2;
 
  //Addresses contact externe
diff --git a/apps/maarch_entreprise/indexing_searching/search_adv_result.php b/apps/maarch_entreprise/indexing_searching/search_adv_result.php
index 2c0df5c4c2b..756c34d5781 100755
--- a/apps/maarch_entreprise/indexing_searching/search_adv_result.php
+++ b/apps/maarch_entreprise/indexing_searching/search_adv_result.php
@@ -111,7 +111,6 @@ if (count($_REQUEST['meta']) > 0) {
         //$func->show_array($tab_id_fields);
         for ($j=0; $j<count($tab_id_fields);$j++) {
             // ENTITIES
-            
             if ($tab_id_fields[$j] == 'services_chosen' && isset($_REQUEST['services_chosen'])) {
                 $json_txt .= " 'services_chosen' : [";
 
@@ -142,7 +141,7 @@ if (count($_REQUEST['meta']) > 0) {
                 $multifield = trim($_REQUEST['multifield']);
                 $json_txt .= "'multifield' : ['".addslashes(trim($multifield))."'],";
 
-                $where_request .= "(lower(translate(subject,'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûýýþÿŔŕ','aaaaaaaceeeeiiiidnoooooouuuuybsaaaaaaaceeeeiiiidnoooooouuuyybyRr')) like lower(:multifield) "
+                $where_request .= "(REGEXP_REPLACE(lower(translate(subject,'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûýýþÿŔŕ','aaaaaaaceeeeiiiidnoooooouuuuybsaaaaaaaceeeeiiiidnoooooouuuyybyRr')),'( ){2,}', ' ') like lower(:multifield) "
                     ."or (lower(translate(alt_identifier,'/','')) like lower(:multifield) OR lower(alt_identifier) like lower(:multifield)) "
                     ."or lower(title) LIKE lower(:multifield) "
                     ."or lower(doc_custom_t1) LIKE lower(:multifield) "
@@ -328,7 +327,7 @@ if (count($_REQUEST['meta']) > 0) {
                 $subject = $func->normalize($subject);
                 $json_txt .= " 'subject' : ['".addslashes(trim($subject))."'],";
 
-                $where_request .= " (lower(translate(subject,'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûýýþÿŔŕ','aaaaaaaceeeeiiiidnoooooouuuuybsaaaaaaaceeeeiiiidnoooooouuuyybyRr')) like lower(:subject) "
+                $where_request .= " (REGEXP_REPLACE(lower(translate(subject,'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûýýþÿŔŕ','aaaaaaaceeeeiiiidnoooooouuuuybsaaaaaaaceeeeiiiidnoooooouuuyybyRr')),'( ){2,}', ' ') like lower(:subject) "
                     ."or (res_id in (SELECT res_id_master FROM res_view_attachments WHERE coll_id = 'letterbox_coll' AND lower(translate(title,'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûýýþÿŔŕ','aaaaaaaceeeeiiiidnoooooouuuuybsaaaaaaaceeeeiiiidnoooooouuuyybyRr'))  like lower(:subject) ))) and ";
                 $arrayPDO = array_merge($arrayPDO, array(":subject" => "%".$subject."%"));
             } elseif ($tab_id_fields[$j] == 'fulltext' && !empty($_REQUEST['fulltext'])
@@ -474,7 +473,7 @@ if (count($_REQUEST['meta']) > 0) {
                     $where_request_welcome .= "(res_id = :resIdWelcome) or ";
                     $arrayPDO = array_merge($arrayPDO, array(":resIdWelcome" => $welcome));
                 }
-                $where_request_welcome .= "( lower(translate(subject,'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûýýþÿŔŕ','aaaaaaaceeeeiiiidnoooooouuuuybsaaaaaaaceeeeiiiidnoooooouuuyybyRr')) like lower(:multifieldWelcome) "
+                $where_request_welcome .= "( REGEXP_REPLACE(lower(translate(subject,'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûýýþÿŔŕ','aaaaaaaceeeeiiiidnoooooouuuuybsaaaaaaaceeeeiiiidnoooooouuuyybyRr')),'( ){2,}', ' ') like lower(:multifieldWelcome) "
                     ."or lower(identifier) LIKE lower(:multifieldWelcome) "
                     ."or (lower(translate(alt_identifier,'/','')) like lower(:multifieldWelcome) OR lower(alt_identifier) like lower(:multifieldWelcome)) "
                     ."or lower(title) LIKE lower(:multifieldWelcome) "
@@ -783,7 +782,7 @@ if (count($_REQUEST['meta']) > 0) {
             {
                 $json_txt .= " 'contactid_external' : ['".addslashes(trim($_REQUEST['contactid_external']))."'], 'contactid' : ['".addslashes(trim($_REQUEST['contactid']))."'],";
                     $contact_id = $_REQUEST['contactid_external'];
-					$where_request .= " (res_id in (select res_id from contacts_res where contact_id = :contactIdExternal and coll_id = '" . $coll_id . "') or ";
+                    $where_request .= " (res_id in (select res_id from contacts_res where contact_id = :contactIdExternal and coll_id = '" . $coll_id . "') or ";
                     $where_request .= " (exp_contact_id = '".$contact_id."' or dest_contact_id = '".$contact_id."') or (res_id in (SELECT res_id_master FROM res_view_attachments WHERE dest_contact_id = ".$contact_id.") )) and ";
                     $arrayPDO = array_merge($arrayPDO, array(":contactIdExternal" => $contact_id));
             }
diff --git a/apps/maarch_entreprise/js/angular/app/profile.component.js b/apps/maarch_entreprise/js/angular/app/profile.component.js
index e73d6b9421d..2ac37aeb5fe 100755
--- a/apps/maarch_entreprise/js/angular/app/profile.component.js
+++ b/apps/maarch_entreprise/js/angular/app/profile.component.js
@@ -45,6 +45,7 @@ var ProfileComponent = (function () {
         this.selectedSignature = -1;
         this.selectedSignatureLabel = "";
         this.loading = false;
+        this.displayAbsenceButton = false;
         window['angularProfileComponent'] = {
             componentAfterUpload: function (base64Content) { return _this.processAfterUpload(base64Content); },
         };
@@ -174,19 +175,42 @@ var ProfileComponent = (function () {
         }
     };
     ProfileComponent.prototype.addBasketRedirection = function () {
-        var index = $j("#selectBasketAbsenceUser option:selected").index();
-        if (index > 0) {
-            this.userAbsenceModel.push({
-                "basketId": this.user.baskets[index - 1].basket_id,
-                "basketName": this.user.baskets[index - 1].basket_name,
-                "virtual": this.user.baskets[index - 1].is_virtual,
-                "basketOwner": this.user.baskets[index - 1].basket_owner,
-                "newUser": $j("#absenceUser")[0].value,
-                "index": index - 1
+        var _this = this;
+        if (typeof this.basketsToRedirect[0] != 'undefined' && $j("#absenceUser")[0].value) {
+            var redirectModel = [];
+            console.log(this.basketsToRedirect);
+            this.basketsToRedirect.forEach(function (value) {
+                redirectModel.push({
+                    "basketId": _this.user.baskets[value].basket_id,
+                    "basketName": _this.user.baskets[value].basket_name,
+                    "virtual": _this.user.baskets[value].is_virtual,
+                    "basketOwner": _this.user.baskets[value].basket_owner,
+                    "newUser": $j("#absenceUser")[0].value,
+                });
             });
-            this.user.baskets[index - 1].disabled = true;
-            $j('#selectBasketAbsenceUser option:eq(0)').prop('selected', true);
-            $j("#absenceUser")[0].value = "";
+            this.http.post(this.coreUrl + 'rest/currentUser/baskets/absence', redirectModel)
+                .subscribe(function (data) {
+                $j('#selectBasketAbsenceUser option').prop('selected', false);
+                $j("#absenceUser")[0].value = "";
+                _this.basketsToRedirect = [];
+                _this.http.get(_this.coreUrl + 'rest/user/profile')
+                    .subscribe(function (data) {
+                    _this.user = data;
+                    _this.user.baskets.forEach(function (value, index) {
+                        _this.user.baskets[index]['disabled'] = false;
+                        _this.user.redirectedBaskets.forEach(function (value2) {
+                            if (value.basket_id == value2.basket_id && value.basket_owner == value2.basket_owner) {
+                                _this.user.baskets[index]['disabled'] = true;
+                            }
+                        });
+                    });
+                });
+            }, function (err) {
+                errorNotification(err.error.errors);
+            });
+        }
+        else {
+            errorNotification("Veuillez sélectionner au moins une bannette et un utilisateur");
         }
     };
     ProfileComponent.prototype.delBasketRedirection = function (index) {
@@ -194,21 +218,35 @@ var ProfileComponent = (function () {
         this.userAbsenceModel.splice(index, 1);
     };
     ProfileComponent.prototype.updateBasketColor = function (i, y) {
+        var _this = this;
         this.http.put(this.coreUrl + "rest/currentUser/groups/" + this.user.regroupedBaskets[i].groupId + "/baskets/" + this.user.regroupedBaskets[i].baskets[y].basket_id, { "color": this.user.regroupedBaskets[i].baskets[y].color })
             .subscribe(function (data) {
+            _this.user.regroupedBaskets = data.userBaskets;
         }, function (err) {
             errorNotification(err.error.errors);
         });
     };
     ProfileComponent.prototype.activateAbsence = function () {
-        var _this = this;
-        this.http.post(this.coreUrl + "rest/users/" + this.user.user_id + "/baskets/absence", this.userAbsenceModel)
-            .subscribe(function () {
-            _this.userAbsenceModel = [];
-            location.search = "?display=true&page=logout&abs_mode";
-        }, function (err) {
-            errorNotification(err.error.errors);
-        });
+        var r = confirm('Voulez-vous vraiment activer votre absence ? Vous serez automatiquement déconnecté.');
+        if (r) {
+            this.http.put(this.coreUrl + 'rest/currentUser/absence', {})
+                .subscribe(function () {
+                location.hash = "";
+                location.search = "?display=true&page=logout&abs_mode";
+            }, function (err) {
+                errorNotification(err.error.errors);
+            });
+        }
+    };
+    ProfileComponent.prototype.askRedirectBasket = function () {
+        var r = confirm('Voulez-vous rediriger vos corbeilles avant de vous mettre en absence ?');
+        if (r) {
+            this.displayAbsenceButton = true;
+            $j('#redirectBasketCard').click();
+        }
+        else {
+            this.activateAbsence();
+        }
     };
     ProfileComponent.prototype.updatePassword = function () {
         var _this = this;
diff --git a/apps/maarch_entreprise/js/angular/app/profile.component.ts b/apps/maarch_entreprise/js/angular/app/profile.component.ts
index 6be90333f07..02eeb737db2 100755
--- a/apps/maarch_entreprise/js/angular/app/profile.component.ts
+++ b/apps/maarch_entreprise/js/angular/app/profile.component.ts
@@ -47,6 +47,8 @@ export class ProfileComponent implements OnInit {
     selectedSignature           : number    = -1;
     selectedSignatureLabel      : string    = "";
     loading                     : boolean   = false;
+    displayAbsenceButton        : boolean   = false;
+
 
 
     constructor(public http: HttpClient, private zone: NgZone) {
@@ -199,20 +201,41 @@ export class ProfileComponent implements OnInit {
     }
 
     addBasketRedirection() {
-        var index = $j("#selectBasketAbsenceUser option:selected").index();
-
-        if (index > 0) {
-            this.userAbsenceModel.push({
-                "basketId"      : this.user.baskets[index - 1].basket_id,
-                "basketName"    : this.user.baskets[index - 1].basket_name,
-                "virtual"       : this.user.baskets[index - 1].is_virtual,
-                "basketOwner"   : this.user.baskets[index - 1].basket_owner,
-                "newUser"       : $j("#absenceUser")[0].value,
-                "index"         : index - 1
+        if (typeof this.basketsToRedirect[0] != 'undefined' && $j("#absenceUser")[0].value) {
+            var redirectModel :any[] = [];
+                console.log(this.basketsToRedirect);
+            this.basketsToRedirect.forEach((value: any) => {
+                redirectModel.push({
+                    "basketId"      : this.user.baskets[value].basket_id,
+                    "basketName"    : this.user.baskets[value].basket_name,
+                    "virtual"       : this.user.baskets[value].is_virtual,
+                    "basketOwner"   : this.user.baskets[value].basket_owner,
+                    "newUser"       : $j("#absenceUser")[0].value,
+                });
             });
-            this.user.baskets[index - 1].disabled = true;
-            $j('#selectBasketAbsenceUser option:eq(0)').prop('selected', true);
-            $j("#absenceUser")[0].value = "";
+
+            this.http.post(this.coreUrl + 'rest/currentUser/baskets/absence', redirectModel)
+                .subscribe((data: any) => {
+                    $j('#selectBasketAbsenceUser option').prop('selected', false);
+                    $j("#absenceUser")[0].value = "";
+                    this.basketsToRedirect = [];
+                    this.http.get(this.coreUrl + 'rest/user/profile')
+                        .subscribe((data) => {
+                            this.user = data;
+                            this.user.baskets.forEach((value: any, index: number) => {
+                                this.user.baskets[index]['disabled'] = false;
+                                this.user.redirectedBaskets.forEach((value2: any) => {
+                                    if (value.basket_id == value2.basket_id && value.basket_owner == value2.basket_owner) {
+                                        this.user.baskets[index]['disabled'] = true;
+                                    }
+                                });
+                            });
+                         });
+                }, (err) => {
+                    errorNotification(err.error.errors);
+                });
+        } else {
+            errorNotification("Veuillez sélectionner au moins une bannette et un utilisateur");
         }
     }
 
@@ -220,23 +243,39 @@ export class ProfileComponent implements OnInit {
         this.user.baskets[this.userAbsenceModel[index].index].disabled = false;
         this.userAbsenceModel.splice(index, 1);
     }
-
+ 
     updateBasketColor(i: number, y: number) {
         this.http.put(this.coreUrl + "rest/currentUser/groups/" + this.user.regroupedBaskets[i].groupId + "/baskets/" + this.user.regroupedBaskets[i].baskets[y].basket_id, {"color" : this.user.regroupedBaskets[i].baskets[y].color})
             .subscribe((data: any) => {
+                this.user.regroupedBaskets = data.userBaskets;
             }, (err) => {
                 errorNotification(err.error.errors);
             });
     }
 
     activateAbsence() {
-        this.http.post(this.coreUrl + "rest/users/" + this.user.user_id + "/baskets/absence", this.userAbsenceModel)
-            .subscribe(() => {
-                this.userAbsenceModel  = [];
-                location.search = "?display=true&page=logout&abs_mode";
-            }, (err) => {
-                errorNotification(err.error.errors);
-            });
+        let r = confirm('Voulez-vous vraiment activer votre absence ? Vous serez automatiquement déconnecté.');
+
+        if (r) {
+            this.http.put(this.coreUrl + 'rest/currentUser/absence', {})
+                .subscribe(() => {
+                        location.hash = "";
+                        location.search = "?display=true&page=logout&abs_mode";
+                }, (err) => {
+                    errorNotification(err.error.errors);
+                });
+        }
+    }
+
+    askRedirectBasket() {
+        let r = confirm('Voulez-vous rediriger vos corbeilles avant de vous mettre en absence ?');
+
+        if (r) {
+            this.displayAbsenceButton=true;
+            $j('#redirectBasketCard').click();
+        } else {
+            this.activateAbsence();
+        }
     }
 
     updatePassword() {
diff --git a/apps/maarch_entreprise/js/angular/app/signature-book.component.js b/apps/maarch_entreprise/js/angular/app/signature-book.component.js
index e93fa6aa588..d1935e010be 100755
--- a/apps/maarch_entreprise/js/angular/app/signature-book.component.js
+++ b/apps/maarch_entreprise/js/angular/app/signature-book.component.js
@@ -389,6 +389,12 @@ var SignatureBookComponent = (function () {
                     if (_this.signatureBook.resList.length > 0) {
                         _this.signatureBook.resList[_this.signatureBook.resListIndex].allSigned = allSigned;
                     }
+                    if (_this.headerTab == 3) {
+                        _this.changeSignatureBookLeftContent(0);
+                        setTimeout(function () {
+                            _this.changeSignatureBookLeftContent(3);
+                        }, 0);
+                    }
                 }
                 else {
                     alert(data.error);
@@ -422,6 +428,12 @@ var SignatureBookComponent = (function () {
             if (_this.signatureBook.resList.length > 0) {
                 _this.signatureBook.resList[_this.signatureBook.resListIndex].allSigned = false;
             }
+            if (_this.headerTab == 3) {
+                _this.changeSignatureBookLeftContent(0);
+                setTimeout(function () {
+                    _this.changeSignatureBookLeftContent(3);
+                }, 0);
+            }
         });
     };
     SignatureBookComponent.prototype.backToBasket = function () {
diff --git a/apps/maarch_entreprise/js/angular/app/signature-book.component.ts b/apps/maarch_entreprise/js/angular/app/signature-book.component.ts
index af20548b3ab..915cda79d8d 100755
--- a/apps/maarch_entreprise/js/angular/app/signature-book.component.ts
+++ b/apps/maarch_entreprise/js/angular/app/signature-book.component.ts
@@ -400,6 +400,13 @@ export class SignatureBookComponent implements OnInit {
                         if (this.signatureBook.resList.length > 0) {
                             this.signatureBook.resList[this.signatureBook.resListIndex].allSigned = allSigned;
                         }
+
+                        if(this.headerTab==3){
+                            this.changeSignatureBookLeftContent(0);
+                            setTimeout(() => {
+                                this.changeSignatureBookLeftContent(3);
+                            }, 0);
+                        }
                     } else {
                         alert(data.error);
                     }
@@ -434,6 +441,13 @@ export class SignatureBookComponent implements OnInit {
                 if (this.signatureBook.resList.length > 0) {
                     this.signatureBook.resList[this.signatureBook.resListIndex].allSigned = false;
                 }
+                if(this.headerTab==3){
+                    this.changeSignatureBookLeftContent(0);
+                    setTimeout(() => {
+                        this.changeSignatureBookLeftContent(3);
+                    }, 0);
+                }
+
             });
 
     }
diff --git a/apps/maarch_entreprise/js/angular/lang/lang-fr.js b/apps/maarch_entreprise/js/angular/lang/lang-fr.js
index c5873939125..6cc4a2fe2c4 100755
--- a/apps/maarch_entreprise/js/angular/lang/lang-fr.js
+++ b/apps/maarch_entreprise/js/angular/lang/lang-fr.js
@@ -66,7 +66,7 @@ exports.LANG_FR = {
     "renewPsw": "Retaper le mot de passe",
     "manageSignatures": "Gérer les signatures",
     "newSignature": "Nouvelle signature",
-    "manageAbsences": "Gérer les absences",
+    "manageAbsences": "Rediriger mes bannettes",
     "activateAbsence": "Activer l'absence",
     "desactivateAbsence": "Désactiver l'absence",
     "autoLogoutAbsence": "Vous allez être automatiquement déconnecté après avoir défini vos redirections de bannettes",
diff --git a/apps/maarch_entreprise/js/angular/lang/lang-fr.ts b/apps/maarch_entreprise/js/angular/lang/lang-fr.ts
index 44205e169b4..a24f1652afe 100755
--- a/apps/maarch_entreprise/js/angular/lang/lang-fr.ts
+++ b/apps/maarch_entreprise/js/angular/lang/lang-fr.ts
@@ -67,7 +67,7 @@ export const LANG_FR = {
     "renewPsw"                  : "Retaper le mot de passe",
     "manageSignatures"          : "Gérer les signatures",
     "newSignature"              : "Nouvelle signature",
-    "manageAbsences"            : "Gérer les absences",
+    "manageAbsences"            : "Rediriger mes bannettes",
     "activateAbsence"           : "Activer l'absence",
     "desactivateAbsence"        : "Désactiver l'absence",
     "autoLogoutAbsence"         : "Vous allez être automatiquement déconnecté après avoir défini vos redirections de bannettes",
diff --git a/apps/maarch_entreprise/js/functions.js b/apps/maarch_entreprise/js/functions.js
index fd2174f8660..e8b7c06d8bf 100755
--- a/apps/maarch_entreprise/js/functions.js
+++ b/apps/maarch_entreprise/js/functions.js
@@ -1058,6 +1058,15 @@ function destroyModal(id_mod){
     document.getElementsByTagName('body')[0].removeChild($j("#" + id_mod)[0]);
     document.getElementsByTagName('body')[0].removeChild($j("#" + id_layer)[0]);
     $j("input[type='button']").prop("disabled", false).css("opacity", "1");
+
+    // FIX IE 11
+    if($j('#leftPanelShowDocumentIframe')){
+       $j('#leftPanelShowDocumentIframe').show(); 
+    }
+    if($j('#rightPanelShowDocumentIframe')){
+       $j('#rightPanelShowDocumentIframe').show(); 
+    }
+
 }
 
 /**
@@ -1554,7 +1563,7 @@ function action_send_form_confirm_result(path_manage_script, mode_req, id_action
                     eval('response='+answer.responseText);
                     if(response.status == 0 ) //Form or confirm processed ok
                     {
-                        res_ids = response.result_id;
+                        /*res_ids = response.result_id;
                         if(res_id_values == 'none' && res_ids != '')
                         {
                             res_id_values = res_ids;
@@ -1567,7 +1576,29 @@ function action_send_form_confirm_result(path_manage_script, mode_req, id_action
                         }
                         var page_result = response.page_result;
                         page_result_final = response.page_result;
-                        close_action(id_action, page_result, path_manage_script, mode_req, res_id_values, table_name, id_coll);
+                        close_action(id_action, page_result, path_manage_script, mode_req, res_id_values, table_name, id_coll);*/
+                        var modal = $('modal_'+id_action);
+                        if(modal) {
+                            destroyModal('modal_'+id_action);
+                        }
+                        if(pile_actions.values.length > 0) {
+                            end_actions();
+                        } else {
+                            res_ids = response.result_id;
+                            if(res_id_values == 'none' && res_ids != '')
+                            {
+                                res_id_values = res_ids;
+                            }
+                            var table_name = tablename;
+                            if(response.table && response.table != '')
+                            {
+                                table_name = response.table;
+                            }
+                            var page_result = response.page_result;
+                            page_result_final = response.page_result;
+                            close_action(id_action, page_result, path_manage_script, mode_req, res_id_values, table_name, id_coll);                            
+                        }
+
                     }
                     else //  Form Params errors
                     {
@@ -1601,7 +1632,7 @@ function action_change_status(path_manage_script, mode_req, res_id_values, table
             },
             success: function(answer) {
 
-                setTimeout(function(){
+                // setTimeout(function(){
                     if(answer.status == 0 ) {
                         actions_status.values = [];
                         // Status changed
@@ -1640,7 +1671,7 @@ function action_change_status(path_manage_script, mode_req, res_id_values, table
                     }
                     
                     do_nothing = false;
-                }, 200);
+                // }, 200);
             }
         });
     }
diff --git a/apps/maarch_entreprise/lang/fr.php b/apps/maarch_entreprise/lang/fr.php
index aad8f3e39e0..6172fa365bf 100755
--- a/apps/maarch_entreprise/lang/fr.php
+++ b/apps/maarch_entreprise/lang/fr.php
@@ -819,7 +819,8 @@ if (!defined("_ADD_COPIES")) define("_ADD_COPIES","Ajouter des personnes en copi
 //Circuits de visa
 if (!defined("_TO_SIGN")) define("_TO_SIGN","Pour signature");
 if (!defined("_VISA_USER"))    define("_VISA_USER", "Pour visa");
-if (!defined("_VISA_USER_SEARCH"))    define("_VISA_USER_SEARCH", "Viseur");
+if (!defined("_VISA_USER_SEARCH"))    define("_VISA_USER_SEARCH", "VISEUR");
+if (!defined("_VISA_USER_SEARCH_MIN"))    define("_VISA_USER_SEARCH_MIN", "Viseur");
 //Circuits d'avis
 if (!defined("_TO_VIEW")) define("_TO_VIEW","Pour avis");
 if (!defined("_TO_SHARED_VIEW")) define("_TO_SHARED_VIEW","Pour avis partagé");
@@ -831,7 +832,7 @@ if (!defined("_NO_ANSWER")) define("_NO_ANSWER","Pas de réponse");
 if (!defined("_ANSWER")) define("_ANSWER","Réponse");
 if (!defined("_DETAILS")) define("_DETAILS", "Fiche détaillée");
 if (!defined("_VISIBLEBY")) define("_VISIBLEBY", "Visible par");
-if (!defined("_DOWNLOAD")) define("_DOWNLOAD", "Télécharger le courrier");
+if (!defined("_DOWNLOAD")) define("_DOWNLOAD", "Télécharger");
 if (!defined("_SEARCH_RESULTS")) define("_SEARCH_RESULTS", "Résultat de la recherche");
 
 if (!defined("_THE_SEARCH")) define("_THE_SEARCH", "La recherche");
diff --git a/apps/maarch_entreprise/log.php b/apps/maarch_entreprise/log.php
index 274cee2d719..25a5723bc8e 100755
--- a/apps/maarch_entreprise/log.php
+++ b/apps/maarch_entreprise/log.php
@@ -59,6 +59,9 @@ if(isset($_SESSION['web_cas_url'])){
 } else if (!empty($_SESSION['ozwillo']['userId'])) {
     $login = $_SESSION['ozwillo']['userId'];
     $_REQUEST['pass'] = 'maarch';
+} else if (!empty($_SESSION['sso']['userId'])) {
+    $login = $_SESSION['sso']['userId'];
+    $_REQUEST['pass'] = 'maarch';
 } else if (isset($_REQUEST['login'])) {
     $login = $func->wash($_REQUEST['login'], 'no', _THE_ID, 'yes');
 } else {
diff --git a/apps/maarch_entreprise/sso_connect.php b/apps/maarch_entreprise/sso_connect.php
index 5992ca9c78a..43da5e1748f 100755
--- a/apps/maarch_entreprise/sso_connect.php
+++ b/apps/maarch_entreprise/sso_connect.php
@@ -59,7 +59,7 @@ if (file_exists($_SESSION['config']['corepath'] . 'custom' .
     . DIRECTORY_SEPARATOR . 'xml' . DIRECTORY_SEPARATOR . 
     'mapping_sso.xml')
 ){
-    $xmlPath = $_SESSION['config']['corepath'] . DIRECTORY_SEPARATOR . 'apps'
+    $xmlPath = $_SESSION['config']['corepath'] .  'apps'
     . DIRECTORY_SEPARATOR . $_SESSION['config']['app_id']
     . DIRECTORY_SEPARATOR . 'xml' . DIRECTORY_SEPARATOR . 'mapping_sso.xml';
 } else {
@@ -400,9 +400,10 @@ if(!empty($control['error']) && $control['error'] <> 1) {
                     "ADMIN",
                     false);
     } else {
+        $_SESSION['sso']['userId'] = $loginArray['UserId'];
         header("location: " . $_SESSION['config']['businessappurl'] 
-            . "log.php?login=" . $loginArray['UserId'] 
-            . "&pass=" . $loginArray['password']);
+            . "log.php");
+
         //Traces fonctionnelles
         $trace->add("users",
                     $loginArray['UserId'],
@@ -502,8 +503,9 @@ function getHeaders()
 {
     foreach ($_SERVER as $h => $v ) 
     {
-      if( ereg( 'HTTP_(.+)', $h, $hp ) )
-      $headers[$hp[1]] = $v ;
+        if( strpos($h, 'HTTP_') === 0)
+        $headers[substr($h, 5)] = $v ;
+        // $headers[$h] = $v;
     }
     return $headers;
 }
diff --git a/apps/maarch_entreprise/template/documents_list_attachments.html b/apps/maarch_entreprise/template/documents_list_attachments.html
index 88e63a38390..dc7cd171db3 100755
--- a/apps/maarch_entreprise/template/documents_list_attachments.html
+++ b/apps/maarch_entreprise/template/documents_list_attachments.html
@@ -223,7 +223,8 @@ Mods
                                     <tbody>
                                         <tr>
                                             <td style="text-align:right;">##func_modify## ##func_delete##&nbsp;&nbsp;##func_final_version##&nbsp;&nbsp;</td>
-                                            <td style="width:1%;text-align:right;" class="attachmentIcon">##showIconDocument##</td>
+                                            <td style="width:30px" class="attachmentIcon">##visualizeIconDocument##</td>
+                                            <td style="width:30px" class="attachmentIcon">##downloadIconDocument##</td>
                                         </tr>
                                     </tbody></table>  </td>
                                 <!--<td style="text-align:left" width="17%">##loadValue|updated_by##</td>-->
diff --git a/apps/maarch_entreprise/template/documents_list_attachments_simple.html b/apps/maarch_entreprise/template/documents_list_attachments_simple.html
index e9375f179c7..25c3ac6075a 100755
--- a/apps/maarch_entreprise/template/documents_list_attachments_simple.html
+++ b/apps/maarch_entreprise/template/documents_list_attachments_simple.html
@@ -170,7 +170,6 @@ Mods
                     <td width="15%" style="text-align:center">
                         <table width="100%" border="0" cellspacing="0" cellpadding="0" >
                             <tr>
-                                <td>##showIconDocument##</td>
                                 <td><i style="font-size:10px;color:#16ADEB;" title="##defineLang|_VERSION##">##loadValue|relation##</i></td>
                                 <td style="text-align:center;font-size:13px;width:100px" title="##defineLang|_STATUS##"><i>##loadValue|status##</i></td>
                             </tr>
@@ -194,7 +193,8 @@ Mods
                                 <td style="text-align:left;width:100px;" title="##defineLang|_BACK_DATE##"><i class="fa fa-calendar-check-o"></i>
  ##loadValue|validation_date##</td>
                                 <td style="text-align:right">##func_modify## ##func_delete## ##func_final_version##</td>
-
+                                <td style="width:30px" class="attachmentIcon">##visualizeIconDocument##</td>
+                                <td style="width:30px" class="attachmentIcon">##downloadIconDocument##</td>
                                 <!--<td style="text-align:left" width="17%">##loadValue|updated_by##</td>-->
                             </tr>
                         </table>
diff --git a/apps/maarch_entreprise/tools/phpids/lib/IDS/maarch_filter.xml b/apps/maarch_entreprise/tools/phpids/lib/IDS/maarch_filter.xml
index 942f7cb158c..d13fbe5a605 100755
--- a/apps/maarch_entreprise/tools/phpids/lib/IDS/maarch_filter.xml
+++ b/apps/maarch_entreprise/tools/phpids/lib/IDS/maarch_filter.xml
@@ -240,7 +240,7 @@
         </tags>
         <impact>5</impact>
     </filter>	 -->
-    <filter>
+<!--     <filter>
         <id>23</id>
         <rule><![CDATA[(?:\.\s*\w+\W*=)|(?:\W\s*(?:location)\s*\W[^({[;]+[({[;])|(?:\(\w+\?[:\w]+\))]]></rule>
         <description>Detects JavaScript location/document property access and window access obfuscation</description>
@@ -249,7 +249,7 @@
             <tag>csrf</tag>
         </tags>
         <impact>5</impact>
-    </filter>    
+    </filter>   -->  
     <filter>
         <id>24</id>
         <rule><![CDATA[(?:[".]script\s*\()|(?:\$\$?\s*\(\s*[\w"])|(?:\/[\w\s]+\/\.)|(?:=\s*\/\w+\/\s*\.)|(?:(?:this|window|top|parent|frames|self|content)\[\s*[(,"]*\s*[\w\$])|(?:,\s*new\s+\w+\s*[,;)])]]></rule>
diff --git a/core/Controllers/UserController.php b/core/Controllers/UserController.php
index 9cdec912944..fe0cc41b1c5 100755
--- a/core/Controllers/UserController.php
+++ b/core/Controllers/UserController.php
@@ -214,6 +214,46 @@ class UserController
         return $response->withJson(['success' => _UPDATED_PASSWORD]);
     }
 
+    public function setCurrentUserBasketsRedirectionForAbsence(RequestInterface $request, ResponseInterface $response) {
+        if (empty($_SESSION['user']['UserId'])) {
+            return $response->withStatus(401)->withJson(['errors' => 'User Not Connected']);
+        }
+
+        $data = $request->getParams();
+
+        foreach ($data as $key => $value) {
+            if (empty($value['newUser']) || empty($value['basketId']) || empty($value['basketOwner']) || empty($value['virtual'])) {
+                return $response->withStatus(400)->withJson(['errors' => _FORM_ERROR]);
+            }
+            $newUser = strrchr($value['newUser'], '(');
+            $newUser = str_replace(['(', ')'], '', $newUser);
+            if (!empty($newUser)) {
+                $check = UserModel::getById(['userId' => $newUser, 'select' => ['1']]);
+            }
+            if (empty($newUser) || empty($check)) {
+                return $response->withStatus(400)->withJson(['errors' => _UNDEFINED_USER]);
+            }
+            $data[$key]['newUser'] = $newUser;
+
+            if($value['basketOwner'] != $_SESSION['user']['UserId']){
+                BasketsModel::updateBasketsRedirection([
+                    'userId'      => $_SESSION['user']['UserId'],
+                    'basketOwner' => $value['basketOwner'],
+                    'basketId'    => $value['basketId'],
+                    'userAbs'     => $value['basketOwner'],
+                    'newUser'     => $newUser
+                ]);
+                unset($data[$key]);
+            }
+        }
+
+        if (!empty($data)) {
+            BasketsModel::setBasketsRedirection(['userId' => $_SESSION['user']['UserId'], 'data' => $data]);
+        }
+
+        return $response->withJson(['redirectedBaskets' => BasketsModel::getRedirectedBasketsByUserId(['userId' => $_SESSION['user']['UserId']])]);
+    }
+
     public function setRedirectedBaskets(RequestInterface $request, ResponseInterface $response, $aArgs) {
         $error = $this->hasUsersRights(['id' => $aArgs['id'], 'himself' => true]);
         if (!empty($error['error'])) {
@@ -735,11 +775,16 @@ class UserController
 
         $user = UserModel::getByUserId(['userId' => $_SESSION['user']['UserId'], 'select' => ['id']]);
 
-        if (!empty($data['color'])) {
+        if(isset($data['color']) && $data['color'] == ''){
+            UserModel::eraseBasketColor(['id' => $user['id'], 'groupId' => $aArgs['groupId'], 'basketId' => $aArgs['basketId']]);
+        } else if (!empty($data['color'])) {
             UserModel::updateBasketColor(['id' => $user['id'], 'groupId' => $aArgs['groupId'], 'basketId' => $aArgs['basketId'], 'color' => $data['color']]);
         }
 
-        return $response->withJson(['success' => 'success']);
+        return $response->withJson([
+            'userBaskets' => BasketsModel::getRegroupedBasketsByUserId(['userId' => $_SESSION['user']['UserId']])
+        ]);
+
     }
 
     private function hasUsersRights(array $aArgs = [])
diff --git a/core/Models/UserModelAbstract.php b/core/Models/UserModelAbstract.php
index 3cabd475451..f97a12c1bcf 100755
--- a/core/Models/UserModelAbstract.php
+++ b/core/Models/UserModelAbstract.php
@@ -841,4 +841,23 @@ class UserModelAbstract
 
         return true;
     }
+
+    public static function eraseBasketColor(array $aArgs)
+    {
+        ValidatorModel::notEmpty($aArgs, ['id', 'groupId', 'basketId']);
+        ValidatorModel::intVal($aArgs, ['id']);
+        ValidatorModel::stringType($aArgs, ['groupId', 'basketId']);
+
+        DatabaseModel::delete(
+            [
+                'table' => 'users_baskets',
+                'where' => ['user_serial_id = ?', 'group_id = ?', 'basket_id = ?'],
+                'data'  => [$aArgs['id'], $aArgs['groupId'], $aArgs['basketId']]
+            ]
+        );
+
+        return true;
+    }
+
+
 }
diff --git a/core/manage_action.php b/core/manage_action.php
index 5f91726a383..230c9a0914f 100755
--- a/core/manage_action.php
+++ b/core/manage_action.php
@@ -291,6 +291,11 @@ else if(empty($_POST['values']) || !isset($_POST['action_id']) || empty($_POST['
             echo "{status : 3, form_content : '<div class=\"h2_title\">" . addslashes(_ADD_ATTACHMENT_TO_SEND_TO_CONTACT) .
                 "</div><p class=\"buttons\"><input type=\"button\" class=\"button\" value=\""._CANCEL."\" onclick=\"destroyModal(\'modal_" .$id_action . "\')\" id=\"submit\" name=\"submit\"></p>', height : '250px', width : '300px', 'mode_frm' : '', validate : 'OK', 'action_status' : '".functions::xssafe($status)."'}";
             exit();
+        }
+        elseif( $_POST['req'] == 'first_request' && $error_visa_workflow_signature_book == true)
+        {
+            echo "{status : 4, error : '".addslashes(_NO_RESPONSE_PROJECT_VISA)."', validate : 'OK', 'action_status' : '".functions::xssafe($status)."'}";
+            exit();
         }
 		elseif( $_POST['req'] == 'first_request' && $error_visa == true)
         {
diff --git a/modules/attachments/attachments_content.php b/modules/attachments/attachments_content.php
index e303d0d5f81..f4dcd524929 100755
--- a/modules/attachments/attachments_content.php
+++ b/modules/attachments/attachments_content.php
@@ -360,6 +360,10 @@ if (isset($_POST['add']) && $_POST['add']) {
                         $_SESSION['collection_id_choice'], $fileInfos
                     );
 
+                    if($attachment_types == 'outgoing_mail' && strpos($fileInfos['format'], 'xl') === false && strpos($fileInfos['format'], 'ppt') === false){
+                        $_SESSION['upfile']['outgoingMail'] = true;
+                    }
+
                     if (isset($storeResult['error']) && $storeResult['error'] <> '') {
                         $_SESSION['error'] = $storeResult['error'];
                     } else {
@@ -1445,6 +1449,16 @@ if (isset($_POST['add']) && $_POST['add']) {
 							'type' => "int",
 						)
 					);
+
+                    array_push(
+                        $_SESSION['data_pdf'],
+                        array(
+                            'column' => "in_signature_book",
+                            'value' => 1,
+                            'type' => "bool",
+                        )
+                    );
+
 					$resAttach = new resource();
 					$id_up = $resAttach->load_into_db(
 						RES_ATTACHMENTS_TABLE,
@@ -2051,16 +2065,16 @@ $content .= '</div>';
 $content .= '<div style="float: right; width: 65%">';
 
 $content .= '<div id="menuOnglet">
-                <ul id="ongletAttachement">
+                <ul id="ongletAttachement" style="cursor:pointer">
                     <li id="liAttachement" ';
 
                 if(empty($_REQUEST['id'])){
                     $content .= ' style="display:none" ';
                 }
 
-                    $content .= 'onclick="activeOngletAttachement()"><a href="#"> Pièce jointe </a></li>';
+                    $content .= 'onclick="activeOngletAttachement()"><span> Pièce jointe </span></li>';
                     if($_GET['cat'] != 'outgoing' && $data_attachment->attachment_type != 'outgoing_mail'){
-                        $content .='<li id="liMainDocument" onclick="activeOngletMainDocument()"><a href="#"> Document principal </a></li>';
+                        $content .='<li id="liMainDocument" onclick="activeOngletMainDocument()"><span> Document principal </span></li>';
                     }
                 $content .='</ul>
             </div>';
diff --git a/modules/attachments/css/module.css b/modules/attachments/css/module.css
index 51b26e34e25..593c6efb6c8 100755
--- a/modules/attachments/css/module.css
+++ b/modules/attachments/css/module.css
@@ -19,7 +19,7 @@
     font-family: Verdana,Geneva,Arial,Helvetica,sans-serif;
 }
 
-#ongletAttachement a
+#ongletAttachement span
 {
     display : block;
     color : #666;
diff --git a/modules/attachments/frame_list_attachments.php b/modules/attachments/frame_list_attachments.php
index bcd3e51e685..13da4cc477e 100755
--- a/modules/attachments/frame_list_attachments.php
+++ b/modules/attachments/frame_list_attachments.php
@@ -381,7 +381,8 @@ if (isset($_REQUEST['load'])) {
         $paramsTab['templates'] = $template_list;
     }
     $paramsTab['bool_showTemplateDefaultList'] = true;                                  //Default list (no template)
-    $paramsTab['viewDocumentLink'] = $_SESSION['config']['businessappurl'].'index.php?display=true&module=attachments&page=view_attachment&res_id_master='.$_SESSION['doc_id'];
+    $paramsTab['downloadDocumentLink'] = $_SESSION['config']['businessappurl'].'index.php?display=true&module=attachments&page=view_attachment&res_id_master='.$_SESSION['doc_id'];
+    $paramsTab['visualizeDocumentLink'] = $_SESSION['config']['businessappurl'].'index.php?display=true&module=attachments&page=view_attachment&res_id_master='.$_SESSION['doc_id'].'&viewpdf=true';
 
 	$content = $list->showList($attachArr, $paramsTab, $listKey);
 	$status = 0;
diff --git a/modules/attachments/js/functions.js b/modules/attachments/js/functions.js
index 82b274c1603..069e830ed5e 100755
--- a/modules/attachments/js/functions.js
+++ b/modules/attachments/js/functions.js
@@ -435,6 +435,14 @@ function loadSelectedContact() {
 }
 
 function createModalinAttachmentList(txt, id_mod, height, width, mode_frm){
+    // FIX IE 11
+    if($j('#leftPanelShowDocumentIframe')){
+       $j('#leftPanelShowDocumentIframe').hide(); 
+    }
+    if($j('#rightPanelShowDocumentIframe')){
+       $j('#rightPanelShowDocumentIframe').hide(); 
+    }
+
     if(height == undefined || height=='') {
         height = '100px';
     }
diff --git a/modules/attachments/view_attachment.php b/modules/attachments/view_attachment.php
index c3810f26498..43721ae3c05 100755
--- a/modules/attachments/view_attachment.php
+++ b/modules/attachments/view_attachment.php
@@ -126,7 +126,7 @@ if (! empty($_SESSION['error'])) {
         } else {
             $line = $stmt->fetchObject();
 
-            if(!empty($_GET['editingMode']) && strpos($line->format, 'xl') === false && strpos($line->format, 'ppt') === false){
+            if((!empty($_GET['editingMode']) || !empty($_GET['viewpdf'])) && strpos($line->format, 'xl') === false && strpos($line->format, 'ppt') === false){
                 $stmtPdf = $db->query(
                     "SELECT docserver_id, path, filename, format, title
                      FROM res_view_attachments
diff --git a/modules/basket/Models/BasketsModelAbstract.php b/modules/basket/Models/BasketsModelAbstract.php
index 2a271d53122..ee880036077 100755
--- a/modules/basket/Models/BasketsModelAbstract.php
+++ b/modules/basket/Models/BasketsModelAbstract.php
@@ -169,6 +169,23 @@ class BasketsModelAbstract
         return true;
     }
 
+    public static function updateBasketsRedirection(array $aArgs = [])
+    {
+        static::checkRequired($aArgs, ['userId', 'basketOwner', 'basketId', 'userAbs', 'newUser']);
+        static::checkString($aArgs, ['userId']);
+
+        $isUpdated = parent::update([
+            'table'     => 'user_abs',
+            'set'       => [
+                'new_user' => $aArgs['newUser']
+            ],
+            'where'     => ['basket_id = ?', 'basket_owner = ?', 'user_abs = ?', 'new_user = ?'],
+            'data'      => [$aArgs['basketId'], $aArgs['basketOwner'], $aArgs['userAbs'], $aArgs['userId']]
+        ]);
+
+        return true;
+    }
+
     public static function deleteBasketRedirection(array $aArgs)
     {
         ValidatorModel::notEmpty($aArgs, ['userId', 'basketId']);
@@ -196,9 +213,10 @@ class BasketsModelAbstract
         ]);
 
         foreach ($aBaskets as $key => $value) {
-            $user = UserModel::getById(['userId' => $value['new_user'], 'select' => ['firstname', 'lastname']]);
-            $aBaskets[$key]['userToDisplay'] = "{$user['firstname']} {$user['lastname']} ({$value['new_user']})";
-            $aBaskets[$key]['user'] = "{$user['firstname']} {$user['lastname']}";
+            $user = UserModel::getByUserId(['userId' => $value['new_user'], 'select' => ['firstname', 'lastname']]);
+            $aBaskets[$key]['userToDisplay']     = "{$user['firstname']} {$user['lastname']}";
+            $aBaskets[$key]['userIdRedirection'] = $value['new_user'];
+            $aBaskets[$key]['user']              = "{$user['firstname']} {$user['lastname']}" ;
         }
 
         return $aBaskets;
diff --git a/modules/basket/class/class_admin_basket_Abstract.php b/modules/basket/class/class_admin_basket_Abstract.php
index ab3446a7466..3ca4c29dce1 100755
--- a/modules/basket/class/class_admin_basket_Abstract.php
+++ b/modules/basket/class/class_admin_basket_Abstract.php
@@ -574,6 +574,12 @@ abstract class admin_basket_Abstract extends Database
                     // Empties the basket administration session var and redirect to baskets list
                     $this->clearbasketinfos();
                     $_SESSION['info'] = _BASKET_ADDED;
+
+                    // Refresh personnal basket info
+                    require_once 'modules/basket/class/class_modules_tools.php';
+                    $basketModule = new basket();
+                    $basketModule->load_module_var_session($_SESSION['user']);
+
                     header("location: ".$_SESSION['config']['businessappurl']."index.php?page=basket&module=basket&order=".$order."&order_field=".$order_field."&start=".$start."&what=".$what);
                     exit();
                 }
@@ -623,6 +629,12 @@ abstract class admin_basket_Abstract extends Database
                 // Empties the basket administration session var and redirect to baskets list
                 $this->clearbasketinfos();
                 $_SESSION['info'] = _BASKET_UPDATED;
+                
+                // Refresh personnal basket info
+                require_once 'modules/basket/class/class_modules_tools.php';
+                $basketModule = new basket();
+                $basketModule->load_module_var_session($_SESSION['user']);
+
                 header("location: ".$_SESSION['config']['businessappurl']."index.php?page=basket&module=basket&order=".$order."&order_field=".$order_field."&start=".$start."&what=".$what);
                 exit();
             }
diff --git a/modules/basket/display_basket_list.php b/modules/basket/display_basket_list.php
index 972782b8523..09f9362d976 100755
--- a/modules/basket/display_basket_list.php
+++ b/modules/basket/display_basket_list.php
@@ -52,6 +52,10 @@ $db = new Database();
 <br />
 <?php
 if ($core_tools->test_service('display_basket_list','basket', false)) {
+
+        // Refresh personnal basket info
+        $bask->load_module_var_session($_SESSION['user']);
+
         if (
             isset($_SESSION['user']['baskets'])
             && count($_SESSION['user']['baskets']) > 0
@@ -69,15 +73,15 @@ if ($core_tools->test_service('display_basket_list','basket', false)) {
                     );
                 }
             }
-            //$core_tools->show_array($collWithUserBaskets);
+
             ?>
             <div class="block">
                 <h2><?php echo _MY_BASKETS;?> : </h2>
             
             <?php
             $redirectedBaskets = \Baskets\Models\BasketsModel::getRedirectedBasketsByUserId(['userId' => $_SESSION['user']['UserId']]);
-            $coloredBaskets = \Baskets\Models\BasketsModel::getColoredBasketsByUserId(['userId' => $_SESSION['user']['UserId']]);
-            $countColl = count($collWithUserBaskets);
+            $coloredBaskets    = \Baskets\Models\BasketsModel::getColoredBasketsByUserId(['userId' => $_SESSION['user']['UserId']]);
+            $countColl         = count($collWithUserBaskets);
             $currentGroup = '';
             for ($cpt=0;$cpt<$countColl;$cpt++) {
                 echo '<h4><i class="fa fa-inbox fa-2x"></i>&nbsp;'
@@ -97,14 +101,6 @@ if ($core_tools->test_service('display_basket_list','basket', false)) {
                             echo '<li style="padding-top: 5px;padding-bottom: 5px;"><i class="fa-li fa fa-users" style="padding-top: 5px;padding-bottom: 5px;"></i>'
                                 . '<small>' . functions::xssafe($currentGroup) . '</small></li>';
                         }
-                        if (
-                            $_SESSION['user']['baskets'][$i]['abs_basket'] == true
-                            && !$abs_basket
-                        ) {
-                            echo '</ul><br /><h3>' . _OTHER_BASKETS
-                                . ' :</h3><ul class="fa-ul">';
-                            $abs_basket = true;
-                        }
                         $nb = '';
                         if (
                             preg_match('/^CopyMailBasket/', $_SESSION['user']['baskets'][$i]['id'])
@@ -122,6 +118,17 @@ if ($core_tools->test_service('display_basket_list','basket', false)) {
                             $nb = '';
                         }
                         if ($_SESSION['user']['baskets'][$i]['id_page'] <> 'redirect_to_action') {
+                            $redirectedTo = '';
+                            foreach ($redirectedBaskets as $redirectBasketValue) {
+                                if ($redirectBasketValue['basket_owner'] == $_SESSION['user']['UserId']) {
+                                    if ($redirectBasketValue['basket_id'] == $_SESSION['user']['baskets'][$i]['id']) {
+                                        $redirectedTo = $redirectBasketValue['user'];
+                                    }
+                                } elseif ($_SESSION['user']['baskets'][$i]['id'] == $redirectBasketValue['basket_id'] . '_' . $redirectBasketValue['basket_owner']) {
+                                    $redirectedTo = $redirectBasketValue['user'];
+                                }
+                            }
+
                             $color = $_SESSION['user']['baskets'][$i]['color'];
                             foreach ($coloredBaskets as $coloredBasket) {
                                 if ($coloredBasket['basket_id'] == $_SESSION['user']['baskets'][$i]['id'] && $coloredBasket['group_id'] == $_SESSION['user']['baskets'][$i]['group_id']) {
@@ -129,28 +136,48 @@ if ($core_tools->test_service('display_basket_list','basket', false)) {
                                 }
                             }
 
-                            if ($core_tools->is_module_loaded('folder') && $_SESSION['user']['baskets'][$i]['is_folder_basket'] == 'Y') {
-                                echo '<li style="padding-top: 5px;padding-bottom: 5px;"><a title="'.$_SESSION['user']['baskets'][$i]['desc'].'" href="'
-                                    . $_SESSION['config']['businessappurl']
-                                    . 'index.php?page=view_baskets&amp;module=basket&amp;baskets='
-                                    . $_SESSION['user']['baskets'][$i]['id']
-                                    . '"><b><span id="nb_' . $_SESSION['user']['baskets'][$i]['id'] 
+                            $fontweight = 'bold';
+                            if($color == '#666666' || $color == '#666' || empty($color)){
+                                $fontweight = 'normal';
+                            }
+
+                            if (empty($redirectedTo)) {
+
+                                if ($_SESSION['user']['baskets'][$i]['abs_basket'] == true && !$abs_basket) {
+                                    echo '</ul><br /><h3>' . _OTHER_BASKETS
+                                        . ' :</h3><ul class="fa-ul">';
+                                    $abs_basket = true;
+                                }
+                                
+                                if ($core_tools->is_module_loaded('folder') && $_SESSION['user']['baskets'][$i]['is_folder_basket'] == 'Y') {
+                                    echo '<li style="padding-top: 5px;padding-bottom: 5px;"><a title="'.$_SESSION['user']['baskets'][$i]['desc'].'" href="'
+                                        . $_SESSION['config']['businessappurl']
+                                        . 'index.php?page=view_baskets&amp;module=basket&amp;baskets='
+                                        . $_SESSION['user']['baskets'][$i]['id']
+                                        . '"><b><span id="nb_' . $_SESSION['user']['baskets'][$i]['id']
+                                        . '" name="nb_' . $_SESSION['user']['baskets'][$i]['id']
+                                        . '"><i class="fa-li fa fa-spinner fa-spin" style="margin-left: -10px;position: inherit;margin-right: -7px;"></i>'
+                                        . '</span></b> <i class="fa-li fa fa-folder" style="padding-top: 5px;padding-bottom: 5px;"></i>'
+                                        . '<span style="color: ' .$color . ';font-weight: '.$fontweight.'">' . functions::xssafe($_SESSION['user']['baskets'][$i]['name']) . '</span>'
+                                        . ' </a></li>';
+                                } else {
+                                    echo '<li style="padding-top: 5px;padding-bottom: 5px;"><a title="'.$_SESSION['user']['baskets'][$i]['desc'].'" href="'
+                                        . $_SESSION['config']['businessappurl']
+                                        . 'index.php?page=view_baskets&amp;module=basket&amp;baskets='
+                                        . $_SESSION['user']['baskets'][$i]['id']
+                                        . '"><b><span id="nb_' . $_SESSION['user']['baskets'][$i]['id']
+                                        . '" name="nb_' . $_SESSION['user']['baskets'][$i]['id']
+                                        . '"><i class="fa-li fa fa-spinner fa-spin" style=";margin-left: -10px;position: inherit;margin-right: -7px;"></i>'
+                                        . '</span></b> <i class="fa-li fa fa-tasks" style="padding-top: 5px;padding-bottom: 5px;"></i> '
+                                        . '<span style="color: ' .$color . ';font-weight: '.$fontweight.'">' . functions::xssafe($_SESSION['user']['baskets'][$i]['name']) . '</span>'
+                                        . ' </a></li>';
+                                }
+                            } else if(!$_SESSION['user']['baskets'][$i]['abs_basket']){
+                                echo '<li style="padding-top: 5px;padding-bottom: 5px;"><a title="'.$_SESSION['user']['baskets'][$i]['desc'].'"><b><span id="nb_' . $_SESSION['user']['baskets'][$i]['id']
                                     . '" name="nb_' . $_SESSION['user']['baskets'][$i]['id']
                                     . '"><i class="fa-li fa fa-spinner fa-spin" style="margin-left: -10px;position: inherit;margin-right: -7px;"></i>'
-                                    . '</span></b> <i class="fa-li fa fa-folder" style="padding-top: 5px;padding-bottom: 5px;"></i>'
-                                    . '<span style="color: ' .$color . '">' . functions::xssafe($_SESSION['user']['baskets'][$i]['name']) . '</span>'
-                                    . ' </a></li>';
-                            } else {
-                                echo '<li style="padding-top: 5px;padding-bottom: 5px;"><a title="'.$_SESSION['user']['baskets'][$i]['desc'].'" href="'
-                                    . $_SESSION['config']['businessappurl']
-                                    . 'index.php?page=view_baskets&amp;module=basket&amp;baskets='
-                                    . $_SESSION['user']['baskets'][$i]['id']
-                                    . '"><b><span id="nb_' . $_SESSION['user']['baskets'][$i]['id'] 
-                                    . '" name="nb_' . $_SESSION['user']['baskets'][$i]['id']
-                                    . '"><i class="fa-li fa fa-spinner fa-spin" style=";margin-left: -10px;position: inherit;margin-right: -7px;"></i>'
-                                    . '</span></b> <i class="fa-li fa fa-tasks" style="padding-top: 5px;padding-bottom: 5px;"></i> '
-                                    . '<span style="color: ' .$color . '">' . functions::xssafe($_SESSION['user']['baskets'][$i]['name']) . '</span>'
-                                    . ' </a></li>';
+                                    . '</span></b> <i class="fa-li fa fa-share" style="padding-top: 5px;padding-bottom: 5px;color: #c62b62"></i><span style="color: ' .$color . ';font-weight: '.$fontweight.'">' . functions::xssafe($_SESSION['user']['baskets'][$i]['name']) . ' (redirigé vers ' . $redirectedTo . ')'
+                                    . ' </span></a></li>';
                             }
                         }
                     }
diff --git a/modules/basket/view_baskets.php b/modules/basket/view_baskets.php
index 9bf67fd1837..ce83c69c09f 100755
--- a/modules/basket/view_baskets.php
+++ b/modules/basket/view_baskets.php
@@ -50,10 +50,6 @@ $_SESSION['location_bar']['level2']['path'] = $_SESSION['config']['businessappur
         $urlParameters .= '&lines='.$_SESSION['save_list']['lines'];
         $urlParameters .= '&order='.$_SESSION['save_list']['order'];
         $urlParameters .= '&order_field='.$_SESSION['save_list']['order_field'];
-
-
-        
-
         if ($_SESSION['save_list']['template'] <> "") {
             $urlParameters .= '&template='.BasketsModel::getTemplateById(['basketId'=>$_SESSION['current_basket']['id']]);
         }
@@ -160,7 +156,7 @@ if (isset($_REQUEST['baskets']) && ! empty($_REQUEST['baskets'])) {
 }
 
 if ((isset($_REQUEST['id']) && !empty($_REQUEST['id'])) && !isset($_REQUEST['resid'])) {
-	$_REQUEST['resid'] = $_REQUEST['id'];
+    $_REQUEST['resid'] = $_REQUEST['id'];
 }
 
 if (
@@ -228,8 +224,21 @@ if (count($_SESSION['user']['baskets']) > 0) {
             <select name="baskets"id="baskets" onchange="cleanSessionBasket('<?php echo $_SESSION['config']['businessappurl'];?>index.php?display=true&module=basket&page=cleanSessionBasket','ok'); this.form.submit();" class="listext_big" >
                 <option value=""><?php echo _CHOOSE_BASKET;?></option>
                 <?php
+                $redirectedBaskets = BasketsModel::getRedirectedBasketsByUserId(['userId' => $_SESSION['user']['UserId']]);
     for ($i = 0; $i < count($_SESSION['user']['baskets']); $i ++) {
-        if($_SESSION['user']['baskets'][$i]['is_visible'] === 'Y') {
+
+        foreach ($redirectedBaskets as $redirectBasketValue) {
+            if ($redirectBasketValue['basket_owner'] == $_SESSION['user']['UserId']) {
+                if ($redirectBasketValue['basket_id'] == $_SESSION['user']['baskets'][$i]['id']) {
+                    $redirectedTo = $redirectBasketValue['user'];
+                }
+            } elseif ($_SESSION['user']['baskets'][$i]['id'] == $redirectBasketValue['basket_id'] . '_' . $redirectBasketValue['basket_owner']) {
+                $redirectedTo = $redirectBasketValue['user'];
+            }
+        }
+
+        if(($_SESSION['user']['baskets'][$i]['is_visible'] === 'Y' &&  $_SESSION['user']['baskets'][$i]['abs_basket'] == false) 
+            || $_SESSION['user']['baskets'][$i]['abs_basket'] == true && empty($redirectedTo)) {
         ?>
         <option value="<?php
         if (isset($_SESSION['user']['baskets'][$i]['id'])) {
diff --git a/modules/content_management/dist/src/MaarchCM.java b/modules/content_management/dist/src/MaarchCM.java
index 2ccb0bb013b..45f60b68b61 100644
--- a/modules/content_management/dist/src/MaarchCM.java
+++ b/modules/content_management/dist/src/MaarchCM.java
@@ -338,6 +338,22 @@ public class MaarchCM {
                 if ("linux".equals(os) || "mac".equals(os)) {
                     editMode = "libreoffice";
                 } else {
+                    programName = fM.findGoodProgramWithExt(fileExtension);
+                    String pathProgram;
+                    pathProgram = fM.findPathProgramInRegistry(programName);
+                    System.out.println("check prog name : "+programName);
+                    System.out.println("check path : "+pathProgram);
+                    if("soffice.exe".equals(programName)){   
+                        if("\"null\"".equals(pathProgram)){
+                            System.out.println(programName+" not found! switch to microsoft office...");
+                            programName = "office.exe";
+                        }
+                    }else{
+                        if("\"null\"".equals(pathProgram)){
+                            System.out.println(programName+" not found! switch to libreoffice...");
+                            programName = "soffice.exe";
+                        }
+                    }
                     if("soffice.exe".equals(programName)){
                         editMode = "libreoffice";
                     }else{
diff --git a/modules/entities/lang/fr.php b/modules/entities/lang/fr.php
index 100191e6845..35d8468d493 100755
--- a/modules/entities/lang/fr.php
+++ b/modules/entities/lang/fr.php
@@ -119,7 +119,7 @@ if (!defined("_ENTITY_LABEL"))
 if (!defined("_SHORT_LABEL"))
     define("_SHORT_LABEL", "Nom court");
 if (!defined("_ENTITY_FULL_NAME"))
-    define("_ENTITY_FULL_NAME", "Nom complet");
+    define("_ENTITY_FULL_NAME", "Bloc arborescence");
 if (!defined("_ENTITY_ADR_1"))
     define("_ENTITY_ADR_1", "Adresse 1");
 if (!defined("_ENTITY_ADR_2"))
diff --git a/modules/notifications/batch/load_process_email_stack.php b/modules/notifications/batch/load_process_email_stack.php
index afc02eebbfd..1272c74a434 100755
--- a/modules/notifications/batch/load_process_email_stack.php
+++ b/modules/notifications/batch/load_process_email_stack.php
@@ -213,15 +213,25 @@ if (file_exists($GLOBALS['errorLckFile'])) {
     exit(13);
 }
 
-/*if (file_exists($GLOBALS['lckFile'])) {
+$semaphore = @fopen($GLOBALS['lckFile'], 'x');
+// If file exists, wait for 60 secondes to try again
+if(!$semaphore){
     $GLOBALS['logger']->write(
-        'An instance of the batch is already in progress',
-        'ERROR', 109
+        'An instance of the batch is already in progress. Waiting for the second try..',
+        'INFO'
     );
-    exit(109);
+    sleep(60);
+    $semaphore = @fopen($GLOBALS['lckFile'], 'x');
+    if(!$semaphore){
+        $GLOBALS['logger']->write(
+            'An instance of the batch is already in progress',
+            'INFO', 109
+        );
+        exit(109);
+    }
 }
-$semaphore = fopen($GLOBALS['lckFile'], 'a');
+
 fwrite($semaphore, '1');
-fclose($semaphore);*/
+fclose($semaphore);
 
 Bt_getWorkBatch();
diff --git a/modules/notifications/batch/process_email_stack.php b/modules/notifications/batch/process_email_stack.php
index 9ef9e4609c4..8506057bb51 100755
--- a/modules/notifications/batch/process_email_stack.php
+++ b/modules/notifications/batch/process_email_stack.php
@@ -124,6 +124,6 @@ Bt_logInDataBase(
 );
 Bt_updateWorkBatch();
 
-//unlink($GLOBALS['lckFile']);
+unlink($GLOBALS['lckFile']);
 exit($GLOBALS['exitCode']);
 ?>
diff --git a/modules/notifications/class/class_schedule_notifications_Abstract.php b/modules/notifications/class/class_schedule_notifications_Abstract.php
index 383a65443b0..d1d288fc680 100755
--- a/modules/notifications/class/class_schedule_notifications_Abstract.php
+++ b/modules/notifications/class/class_schedule_notifications_Abstract.php
@@ -157,9 +157,9 @@ abstract class ScheduleNotifications_Abstract
             fwrite($file_open, 'php \'basket_event_stack.php\' -c '.$ConfigNotif.' -n '.$notification_id);
         } 
         else if ($notification_id == 'RELANCE1' || $notification_id == 'RELANCE2' || $notification_id == 'RET1' || $notification_id == 'RET2'){
-            fwrite($file_open, 'php \'process_event_stack.php\' -c '.$ConfigNotif.' -n '.$notification_id);
-            fwrite($file_open, "\n");
             fwrite($file_open, 'php \'stack_letterbox_alerts.php\' -c '.$ConfigNotif);
+            fwrite($file_open, "\n");
+            fwrite($file_open, 'php \'process_event_stack.php\' -c '.$ConfigNotif.' -n '.$notification_id);
         }
         else {
             fwrite($file_open, 'php \'process_event_stack.php\' -c '.$ConfigNotif.' -n '.$notification_id);
diff --git a/modules/notifications/manage_notifications_controler.php b/modules/notifications/manage_notifications_controler.php
index a3273b10aa9..cdddbdc11d2 100755
--- a/modules/notifications/manage_notifications_controler.php
+++ b/modules/notifications/manage_notifications_controler.php
@@ -444,14 +444,15 @@ function validate_notif_submit() {
     } else {
         if ($mode == 'add') {
             $_SESSION['info'] = _NOTIF_ADDED;
-
-            if (PHP_OS == "Linux") {
-                $ScheduleNotifications = new ScheduleNotifications();
-                $ScheduleNotifications->createScriptNotification($control['value'], $notifObj->notification_id);
-            }
         } else {
             $_SESSION['info'] = _NOTIF_MODIFIED;
         }
+        
+        if (PHP_OS == "Linux") {
+            $ScheduleNotifications = new ScheduleNotifications();
+            $ScheduleNotifications->createScriptNotification($control['value'], $notifObj->notification_id);
+        }
+
         unset($_SESSION['m_admin']);
         header(
             'location: ' . $_SESSION['config']['businessappurl']
diff --git a/modules/sendmail/batch/load_process_emails.php b/modules/sendmail/batch/load_process_emails.php
index 1be64b76310..c821bea6b12 100755
--- a/modules/sendmail/batch/load_process_emails.php
+++ b/modules/sendmail/batch/load_process_emails.php
@@ -151,7 +151,6 @@ $GLOBALS['batchDirectory'] = $GLOBALS['maarchDirectory'] . 'modules'
 $notificationErrors = $xmlconfig->NOTIFICATION_ERROR;
 $GLOBALS['adminmail'] = (string)$notificationErrors->adminmail;
 $GLOBALS['subjectmail'] = (string)$notificationErrors->subjectmail;
-$GLOBALS['bodymail'] = (string)$notificationErrors->body;
 
 set_include_path(get_include_path() . PATH_SEPARATOR . $GLOBALS['maarchDirectory']);
 
diff --git a/modules/sendmail/batch/process_emails.php b/modules/sendmail/batch/process_emails.php
index b89373468a7..77e6ab77d50 100755
--- a/modules/sendmail/batch/process_emails.php
+++ b/modules/sendmail/batch/process_emails.php
@@ -262,14 +262,16 @@ while ($state <> 'END') {
                 $query = "INSERT INTO notif_email_stack (sender, recipient, subject, html_body, charset, module) VALUES (?, ?, ?, ?, ?, 'notifications')";  
 
                 $html = "Message automatique : <br><br>
-                		L'email avec l'identifiant ".$email->email_id." dans la table 'sendmail' n'a pas été envoyé. <br>
+                		Le courriel avec l'identifiant ".$email->email_id." dans la table 'sendmail' n'a pas été envoyé. <br>
                 		Pour plus d'informations, regardez les logs dans le fichier ".$GLOBALS['maarchDirectory']."/modules/sendmail/batch/".$logFile."<br><br>
                 		Répertoire d'installation de l'application : ".$GLOBALS['maarchDirectory']."<br>
-                		Fichier de configuration de sendmail : " . $GLOBALS['configFile'] . "<br>
-                		IP de la base de données : " . $_SESSION['config']['databaseserver'] . "<br>
-                		Port de la base de données : " . $_SESSION['config']['databaseserverport'] . "<br>
-                		Type de base de données : " . $_SESSION['config']['databasetype'] . "<br>
-                		Nom de la base de données : " . $_SESSION['config']['databasename'] . "<br>";
+                		Fichier de configuration de sendmail : " . $GLOBALS['configFile'];
+
+        		$queryMlb = "SELECT alt_identifier FROM mlb_coll_ext WHERE res_id = ? ";
+				$stmt = Bt_doQuery($GLOBALS['db'], $queryMlb, array($email->res_id));
+				$mlbRecordSet = $stmt->fetchObject();
+
+				$html .= '<br><br>Le courriel a été envoyé depuis le courrier dont le numéro chrono est : ' . $mlbRecordSet->alt_identifier;
 
                 $adminMails = explode(',', $GLOBALS['adminmail']);
                 if(!empty($adminMails)){
@@ -281,7 +283,16 @@ while ($state <> 'END') {
                 }
 
             	if(!empty($userInfo['mail'])){
-            		Bt_doQuery($GLOBALS['db'], $query, array($emailFrom, $userInfo['mail'], $GLOBALS['subjectmail'], $GLOBALS['bodymail'].'<br><br>'.$return[0], $GLOBALS['charset']));
+					if(strlen($email->email_object) >= 100) {
+						$objectToSend = mb_substr($email->email_object, 0, 100);
+						$objectToSend = substr($objectToSend, 0, strrpos($objectToSend, ' ')).'...';
+					} else {
+						$objectToSend = $email->email_object;
+					}					
+
+            		$bodyMailError = "Message automatique : <br><br>
+            						 Votre envoi de courriel dont l'objet est \"". $objectToSend . "\" avec le numéro chrono \"" . $mlbRecordSet->alt_identifier . "\" n'a pas été envoyé. Veuillez réessayer ou contacter votre administreur.";
+            		Bt_doQuery($GLOBALS['db'], $query, array($emailFrom, $userInfo['mail'], $GLOBALS['subjectmail'], $bodyMailError, $GLOBALS['charset']));
                 }
 
 			}
diff --git a/modules/templates/class/templates_controler_Abstract.php b/modules/templates/class/templates_controler_Abstract.php
index f7d8cbed449..5b85af383e6 100755
--- a/modules/templates/class/templates_controler_Abstract.php
+++ b/modules/templates/class/templates_controler_Abstract.php
@@ -188,17 +188,11 @@ abstract class templates_controler_Abstract extends ObjectControler implements O
             );
         } else {            
             if ($template->template_type == 'OFFICE') {
-                /*if ($mode == 'add' && !$_SESSION['m_admin']['templates']['applet']) {
-                    $return = array(
-                        'status' => 'ko', 
-                        'value' => $template, 
-                        'error' => _EDIT_YOUR_TEMPLATE,
-                    );
-                    return $return;
-                }*/
-                if ((($mode == 'up' && $_SESSION['m_admin']['templates']['applet']) || $mode == 'add') 
-                  /*  && $_SESSION['m_admin']['templates']['applet'] */
-                ) {
+                if (($mode == 'up' && $_SESSION['m_admin']['templates']['applet']) 
+                    || ($mode == 'up' && !empty($_SESSION['m_admin']['templates']['current_style'])) 
+                    || $mode == 'add') 
+                {
+
                     $storeInfos = array();
                     $storeInfos = $this->storeTemplateFile();
                     if (!$storeInfos) {
@@ -208,7 +202,6 @@ abstract class templates_controler_Abstract extends ObjectControler implements O
                             'error' => $_SESSION['error'],
                         );
                     } else {
-                        //print_r($storeInfos);exit;
                         $template->template_path = $storeInfos['destination_dir'];
                         $template->template_file_name = $storeInfos['file_destination_name'];
                         $template->template_style = $storeInfos['template_style'];
diff --git a/modules/templates/js/functions.js b/modules/templates/js/functions.js
index 48bb9918236..3b9b86870e5 100755
--- a/modules/templates/js/functions.js
+++ b/modules/templates/js/functions.js
@@ -127,6 +127,7 @@ function addTemplateBase(file)
                 $j('#template_style').hide();
                 $j('#addTemplate').val(file.files[0].name);
                 $j('#addTemplate').show();
+                $j('#templateEditTr').hide();
             } else {
                 alert(response.error_txt);
             }
diff --git a/modules/templates/templates_management.php b/modules/templates/templates_management.php
index e6fef2f1f19..74ffbc569f3 100755
--- a/modules/templates/templates_management.php
+++ b/modules/templates/templates_management.php
@@ -288,7 +288,8 @@ if ($mode == 'list') {
                     }
                     $objectTable = _TEMPLATES_TABLE_NAME;
                     ?>
-                    <p id="templateEditTr">
+                    <p>
+                        <span id="templateEditTr">
                         <label><?php echo _EDIT_TEMPLATE;?> :</label>
                   
                                 <?php
@@ -307,6 +308,16 @@ if ($mode == 'list') {
                                     <i class="fa fa-pencil fa-2x"></i>
                                 <?php echo _EDIT_TEMPLATE;?>
                             </a>   
+                        </span>
+                        <?php if ($mode == 'up') {?>
+                        <a href="#" onclick="$j('#addTemplateFile').click();$('template_style_icon').setStyle({color: '#009DC5'})" style="margin-left:15px">
+
+                            <i id="template_style_icon" class="fa fa-paperclip fa-2x"></i> Importer un fichier
+                        </a>
+                        <input class="button" name="addTemplate" id="addTemplate" onclick="$j('#addTemplateFile').click();" style="display:none;margin-left:15px" value="+" type="button"/>
+                        <input id="addTemplateFile" type="file" onchange="addTemplateBase(this);" style="display:none;" accept="application/msword,application/vnd.openxmlformats-officedocument.wordprocessing‌​ml.document,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel,application/vnd.ms-powerpoint,application/vnd.openxmlformats-officedocument.presentationml‌​.slideshow,application/vnd.oasis.opendocument.text,application/vnd.oasis.opendocument.presentation,application/vnd.oasis.opendocument.spreadsheet"/>
+                        <?php } ?>  
+
                     </p>
                 </div>
                 <div id="txt_div" name="txt_div">
diff --git a/modules/visa/Controllers/VisaController.php b/modules/visa/Controllers/VisaController.php
index 5d4c72e6583..427379d87bd 100755
--- a/modules/visa/Controllers/VisaController.php
+++ b/modules/visa/Controllers/VisaController.php
@@ -126,7 +126,7 @@ class VisaController
         $incomingMail = ResModel::getById([
             'resId'     => $resId,
             'select'    => ['res_id', 'subject', 'alt_identifier', 'category_id'],
-            'table'     => 'res_view_letterbox'
+            'resTable'  => 'res_view_letterbox'
         ]);
 
         if (empty($incomingMail)) {
diff --git a/modules/visa/class/class_modules_tools_Abstract.php b/modules/visa/class/class_modules_tools_Abstract.php
index ade4df12604..a3df5c92a21 100755
--- a/modules/visa/class/class_modules_tools_Abstract.php
+++ b/modules/visa/class/class_modules_tools_Abstract.php
@@ -501,13 +501,13 @@ abstract class visa_Abstract extends Database
 		$db = new Database();
 		$where = "res_id= ? and coll_id = ? and difflist_type = ? and process_date IS NULL";
         $order = "ORDER BY listinstance_id ASC";
-        $query = $db->limit_select(0, 1, 'sequence, item_mode', 'listinstance', $where, '', '', $order);
+        $query = $db->limit_select(0, 1, 'requested_signature', 'listinstance', $where, '', '', $order);
 
 		$stmt = $db->query($query, array($res_id, $coll_id, 'VISA_CIRCUIT'));
 		$resListDiffVisa = $stmt->fetchObject();
 
 		// If there is only one step in the visa workflow, we set status to ESIG
-		if ((count($curr_visa_wf['visa']) == 0 && count($curr_visa_wf['sign']) == 1) || $resListDiffVisa->item_mode == "sign"){
+		if ($resListDiffVisa->requested_signature){
 	        $mailStatus = 'ESIG';
 	    } else {
 	        $mailStatus = 'EVIS';
@@ -519,14 +519,15 @@ abstract class visa_Abstract extends Database
 	public function getList($res_id, $coll_id, $bool_modif=false, $typeList, $isVisaStep = false, $fromDetail = ""){
 			$core = new core_tools();      
 			$circuit = $this->getWorkflow($res_id, $coll_id, $typeList);
-			if ($this->isAllAttachementSigned($res_id) == 'noAttachment') {
+			$sAllAttachmentSigned = $this->isAllAttachementSigned($res_id);
+			if ($sAllAttachmentSigned == 'noAttachment') {
 				$str = '<input type="hidden" id="isAllAttachementSigned" value="true"/>';
 				$isAllAttachementSigned = " disabled='disabled'";
 				$isAllAttachementSignedInfo = _IS_ALL_ATTACHMENT_SIGNED_INFO;
 
-			} else if ($this->isAllAttachementSigned($res_id) == 'yes') {
-				$str = '<input type="hidden" id="isAllAttachementSigned" value="true"/>';
-				$isAllAttachementSigned = " disabled='disabled'";
+			} else if ($sAllAttachmentSigned == 'yes') {
+				$str = '<input type="hidden" id="isAllAttachementSigned" value="allsigned"/>';
+				$isAllAttachementSigned = "";
 				$isAllAttachementSignedInfo = _IS_ALL_ATTACHMENT_SIGNED_INFO2;				
 			}else{
 				$str = '<input type="hidden" id="isAllAttachementSigned" value="false"/>';
@@ -581,7 +582,7 @@ abstract class visa_Abstract extends Database
                 $str .= '</script>';
                 $str .= '<br/><br/>';
             }
-            if (!empty($isAllAttachementSigned)) {
+            if (!empty($isAllAttachementSignedInfo)) {
 				$str .= '<b style="color:red;">'.$isAllAttachementSignedInfo.'</b>';
 			}
             $str .= '<div id="visa_content">';
@@ -1219,11 +1220,9 @@ abstract class visa_Abstract extends Database
 	public function isAllAttachementSigned($res_id){
 		
 		$db = new Database();
-		$stmt = $db->query("SELECT count(res_id) as nb from res_attachments WHERE in_signature_book = false AND signatory_user_serial_id IS NULL AND status NOT IN ('DEL','OBS','TMP') AND attachment_type NOT IN ('converted_pdf','print_folder') AND res_id_master = ?", array($res_id));
-		$res = $stmt->fetchObject();
-		$stmt2 = $db->query("SELECT count(res_id) as nb from res_attachments WHERE in_signature_book = true AND signatory_user_serial_id IS NULL AND status NOT IN ('DEL','OBS','TMP') AND attachment_type NOT IN ('converted_pdf','print_folder') AND res_id_master = ?", array($res_id));
+		$stmt2 = $db->query("SELECT count(res_id) as nb from res_attachments WHERE in_signature_book = true AND signatory_user_serial_id IS NULL AND status NOT IN ('DEL','OBS','TMP') AND attachment_type NOT IN ('converted_pdf','print_folder','signed_response') AND res_id_master = ?", array($res_id));
 		$res2 = $stmt2->fetchObject();
-		$stmt3 = $db->query("SELECT count(res_id) as nb from res_attachments WHERE in_signature_book = true AND status NOT IN ('DEL','OBS','TMP') AND attachment_type NOT IN ('converted_pdf','print_folder') AND res_id_master = ?", array($res_id));
+		$stmt3 = $db->query("SELECT count(res_id) as nb from res_view_attachments WHERE in_signature_book = true AND status NOT IN ('DEL','OBS','TMP') AND attachment_type NOT IN ('converted_pdf','print_folder','signed_response') AND res_id_master = ?", array($res_id));
 		$res3 = $stmt3->fetchObject();
 		if ($res3->nb == 0) {
 			return 'noAttachment';
@@ -1233,6 +1232,7 @@ abstract class visa_Abstract extends Database
 			return false;
 		}
 	}
+
 	public function currentUserSignRequired($res_id){
 		$user_id = $this->getCurrentUserStep($res_id);
 		$db = new Database();
diff --git a/modules/visa/css/module.css b/modules/visa/css/module.css
index 0efee59f33a..69362567d06 100755
--- a/modules/visa/css/module.css
+++ b/modules/visa/css/module.css
@@ -991,3 +991,7 @@ img.panelSelectedThumbnail,img:hover.panelSelectedThumbnail{
 .chosen-container-single .chosen-default {
     color: black !important;
 }
+
+#visa_content select{
+    font-size: 11px;
+}
diff --git a/modules/visa/js/functions.js b/modules/visa/js/functions.js
index 2f1f32e79ca..266d60a8e6d 100755
--- a/modules/visa/js/functions.js
+++ b/modules/visa/js/functions.js
@@ -5,7 +5,8 @@ function addVisaUser(users) {
         if(nb_visa == 0){
             $j("#emptyVisa").hide();      
         }
-        if ($j("select[id^=signRequest_] option:selected[value=true]").length >= 1 && $j("select[id^=signRequest_] option:last:selected[value=true]").length == 0) {
+        if ($j("select[id^=signRequest_] option:selected[value=true]").length >= 2 || 
+            ($j("select[id^=signRequest_] option:selected[value=true]").length == 1 && $j("select[id^=signRequest_] option:last:selected[value=true]").length == 0)) {
             selected = '';
         } else {
             if (!$j('#signRequest_'+nb_visa).is(':disabled')) {
@@ -16,9 +17,11 @@ function addVisaUser(users) {
         
 
         if ($j("#isAllAttachementSigned").val() == 'false') {
-            signRequest = '<br/><sub><select id="signRequest_'+next_visa+'"><option value="false">Viseur</option><option value="true" '+selected+'>Signataire</option></select></sub>';
+            signRequest = '<br/><sub><select id="signRequest_'+next_visa+'"><option value="false">VISEUR</option><option value="true" '+selected+'>SIGNATAIRE</option></select></sub>';
+        } else if($j("#isAllAttachementSigned").val() == 'allsigned'){
+            signRequest = '<br/><sub><select id="signRequest_'+next_visa+'"><option value="false" '+selected+'>VISEUR</option><option value="true">SIGNATAIRE</option></select></sub>';
         } else {
-            signRequest = '<br/><sub><select id="signRequest_'+next_visa+'" disabled="disabled"><option value="false">Viseur</option><option value="true" '+selected+'>Signataire</option></select></sub>';
+            signRequest = '<br/><sub><select id="signRequest_'+next_visa+'" disabled="disabled"><option value="false" '+selected+'>VISEUR</option><option value="true">SIGNATAIRE</option></select></sub>';
         }
 
         $j("#visa_content").append('<div class="droptarget" id="visa_' + next_visa + '" draggable="true">'
@@ -62,9 +65,11 @@ function addVisaUser(users) {
         }
 
         if ($j("#isAllAttachementSigned").val() == 'false') {
-            signRequest = '<br/><sub><select id="signRequest_'+next_visa+'"><option value="false">Viseur</option><option value="true" '+selected+'>Signataire</option></select></sub>';
+            signRequest = '<br/><sub><select id="signRequest_'+next_visa+'"><option value="false">VISEUR</option><option value="true" '+selected+'>SIGNATAIRE</option></select></sub>';
+        } else if($j("#isAllAttachementSigned").val() == 'allsigned'){
+            signRequest = '<br/><sub><select id="signRequest_'+next_visa+'"><option value="false" '+selected+'>VISEUR</option><option value="true">SIGNATAIRE</option></select></sub>';
         } else {
-            signRequest = '<br/><sub><select id="signRequest_'+next_visa+'" disabled="disabled"><option value="false">Viseur</option><option value="true" '+selected+'>Signataire</option></select></sub>';            
+            signRequest = '<br/><sub><select id="signRequest_'+next_visa+'" disabled="disabled"><option value="false" '+selected+'>VISEUR</option><option value="true">SIGNATAIRE</option></select></sub>';            
         }
         $j("#visa_content").append('<div class="droptarget" id="visa_' + next_visa + '" draggable="true">'
             +'<span class="visaUserStatus">'
@@ -107,17 +112,43 @@ function resetPosVisa () {
     i = 1;
     $j(".droptarget").each(function() {
         this.id = 'visa_' + i;
+        $j("#" + this.id).find("select[id^=signRequest_]")[0].id='signRequest_'+i;
+        $j("#" + this.id).find("[id^=signedUser_]")[0].id='signedUser_'+i;
         $j("#" + this.id).find(".visaUserPos").text(i);
         i++;
     });
+
+    i = 1;
+    var hasSignatory = false;
+    $j(".droptarget").each(function() {
+        if ($j("#signRequest_"+(i)+" option:selected[value=true]").length) {
+            userRequestSign=true;
+        } else {
+            userRequestSign=false;
+        }
+        if ($j("#signedUser_"+(i)).css('visibility') == 'visible') {
+            userSignatory=true;
+        } else {
+            userSignatory=false;
+        }
+
+        if(userRequestSign || userSignatory){
+            hasSignatory = true;
+        }
+        if ($j("#signRequest_"+(i+1)).length == 0 && !hasSignatory) {
+            $j('#signRequest_'+(i)).val("true");
+        }
+        i++;
+
+    });
     i--;
 
-    //$j("#visa_" + i).find(".visaUserSign").css("visibility","visible");
 
 }
 function updateVisaWorkflow(resId) {
     var i = 0;
     var userList = [];
+    var hasSignatory = false;
     if (($j("select[id^=signRequest_] option:selected[value=true]").length == 0) && $j(".droptarget").length != 0) {
         $j('#signRequest_'+i).val("true");
     }
@@ -138,6 +169,14 @@ function updateVisaWorkflow(resId) {
             userConsigne = $j("#" + this.id).find(".consigne").val();
             userVisaDate = $j("#" + this.id).find(".visaDate").val();
             userPos = i;
+            // last one is signatory if no one selected
+            if(userRequestSign || userSignatory){
+                hasSignatory = true;
+            }
+            if ($j("#signRequest_"+(i+2)).length == 0 && !hasSignatory) {
+                userRequestSign=true;
+                $j('#signRequest_'+(i+1)).val("true");
+            }
             userList.push({userId: userId, userPos: userPos, userConsigne: userConsigne, userVisaDate: userVisaDate, userRequestSign: userRequestSign, userSignatory: userSignatory});
             i++;
         });
diff --git a/modules/visa/lang/fr.php b/modules/visa/lang/fr.php
index ca56a68bb8b..a86a14642e1 100755
--- a/modules/visa/lang/fr.php
+++ b/modules/visa/lang/fr.php
@@ -164,7 +164,7 @@ if (!defined("_NO_SIGNATORY"))
     define("_NO_SIGNATORY", "Aucun signataire");
 
 if (!defined("_SIGNATORY"))
-    define("_SIGNATORY", "Signataire");
+    define("_SIGNATORY", "SIGNATAIRE");
 
 if (!defined("_SIGNED_TO"))
     define("_SIGNED_TO", "Signé le");
@@ -301,4 +301,4 @@ if (!defined('_IS_ALL_ATTACHMENT_SIGNED_INFO'))
     define('_IS_ALL_ATTACHMENT_SIGNED_INFO', "Vous ne pourrez pas demander de signature aux utilisateurs, aucune pièce jointe présente dans le parapheur");
 
 if (!defined('_IS_ALL_ATTACHMENT_SIGNED_INFO2'))
-    define('_IS_ALL_ATTACHMENT_SIGNED_INFO2', "Vous ne pourrez pas demander de signature aux utilsateurs, toutes les pièces jointes présentes dans le parapheur ont été signées.");
+    define('_IS_ALL_ATTACHMENT_SIGNED_INFO2', "Toutes les pièces jointes présentes dans le parapheur ont été signées.");
diff --git a/modules/visa/visa_workflow.php b/modules/visa/visa_workflow.php
index 787134bdd3d..c25680d5663 100755
--- a/modules/visa/visa_workflow.php
+++ b/modules/visa/visa_workflow.php
@@ -10,13 +10,15 @@
 */
 require_once 'modules/visa/class/class_modules_tools.php';
 $visa = new visa();
+$confirm = true;
 
-if ($visa->currentUserSignRequired($_SESSION['doc_id']) == 'true') {
-    $confirm = true;
+$error_visa_workflow_signature_book = false;
+if($visa->isAllAttachementSigned($_SESSION['doc_id']) == 'noAttachment'){
+    $error_visa_workflow_signature_book = true;
+} else if ($visa->currentUserSignRequired($_SESSION['doc_id']) == 'true') {
     $label_action .=" ("._NO_USER_SIGNED_DOC.")";
-} else {
-    $confirm = false;
-}
+} 
+
 $etapes = ['empty_error'];
 
 function manage_empty_error($arr_id, $history, $id_action, $label_action, $status)
@@ -45,7 +47,7 @@ function manage_empty_error($arr_id, $history, $id_action, $label_action, $statu
 
         //enables to process the visa if i am not the item_id
         if ($stepDetails['item_id'] <> $_SESSION['user']['UserId']) {
-            $stmt = $db->query(
+            $db->query(
                 "UPDATE listinstance SET process_date = CURRENT_TIMESTAMP "
                 . " WHERE listinstance_id = ? AND item_mode = ? AND res_id = ? AND item_id = ? AND difflist_type = ?",
                 array($stepDetails['listinstance_id'], $stepDetails['item_mode'], $res_id, $stepDetails['item_id'], 'VISA_CIRCUIT')
@@ -62,7 +64,7 @@ function manage_empty_error($arr_id, $history, $id_action, $label_action, $statu
 
             $message[] = " " ._VISA_BY . " " . $user1 . " " . _INSTEAD_OF . " " . $user2;
         } else {
-            $stmt = $db->query(
+            $db->query(
                 "UPDATE listinstance SET process_date = CURRENT_TIMESTAMP "
                 . " WHERE listinstance_id = ? AND item_mode = ? AND res_id = ? AND item_id = ? AND difflist_type = ?",
                 array($stepDetails['listinstance_id'], $stepDetails['item_mode'], $res_id, $_SESSION['user']['UserId'], 'VISA_CIRCUIT')
@@ -70,9 +72,11 @@ function manage_empty_error($arr_id, $history, $id_action, $label_action, $statu
             $message[] = "";
         }
 
-        if ($circuit_visa->getCurrentStep($res_id, $coll_id, 'VISA_CIRCUIT') == $circuit_visa->nbVisa($res_id, $coll_id)) {
-            $mailStatus = 'ESIG';
-            $db->query("UPDATE res_letterbox SET status = ? WHERE res_id = ? ", [$mailStatus, $res_id]);
+        $stmt = $db->query("SELECT status FROM res_letterbox WHERE res_id = ?", array($res_id));
+        $resource  = $stmt->fetchObject();
+
+        if ($resource->status == 'EVIS' || $resource->status == 'ESIG') {
+            $circuit_visa->setStatusVisa($res_id, 'letterbox_coll');
         }
         $result .= $arr_id[$i] . '#';
     }
diff --git a/sql/17_xx.sql b/sql/17_xx.sql
index 06dbdcb6d4b..2f2eaae59d8 100755
--- a/sql/17_xx.sql
+++ b/sql/17_xx.sql
@@ -354,3 +354,4 @@ UPDATE res_attachments SET in_signature_book = TRUE;
 UPDATE res_version_attachments SET in_signature_book = TRUE;
 UPDATE listinstance SET signatory = TRUE WHERE item_mode = 'sign';
 
+ALTER TABLE notif_event_stack ALTER COLUMN record_id TYPE character varying(128);
diff --git a/sql/structure.sql b/sql/structure.sql
index bd780729fb4..2d4b10421d4 100755
--- a/sql/structure.sql
+++ b/sql/structure.sql
@@ -1062,7 +1062,7 @@ CREATE TABLE notif_event_stack
   event_stack_sid bigint NOT NULL DEFAULT nextval('notif_event_stack_seq'::regclass),
   notification_sid bigint NOT NULL,
   table_name character varying(50) NOT NULL,
-  record_id character varying(50) NOT NULL,
+  record_id character varying(128) NOT NULL,
   user_id character varying(128) NOT NULL,
   event_info character varying(255) NOT NULL,
   event_date timestamp without time zone NOT NULL,
-- 
GitLab