noalyss-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Noalyss-commit] [noalyss] 20/21: Task #1151 - Amélioration configurati


From: Dany De Bontridder
Subject: [Noalyss-commit] [noalyss] 20/21: Task #1151 - Amélioration configuration des menus Ergonomy change easily the menu and configuration + SQL for upgrade
Date: Wed, 19 Aug 2015 22:59:33 +0000

sparkyx pushed a commit to branch master
in repository noalyss.

commit 60207bf50e6679ad233bcc258a63140c7a5d87e4
Author: Dany De Bontridder <address@hidden>
Date:   Thu Aug 20 00:38:05 2015 +0200

    Task #1151 - Amélioration configuration des menus
    Ergonomy change easily the menu and configuration + SQL for upgrade
---
 html/ajax_misc.php                                 |    6 +
 html/direct.php                                    |    2 +-
 html/do.php                                        |   41 ++-
 html/js/scripts.js                                 |  105 ++++-
 include/ac_common.php                              |   59 ++-
 include/ajax_add_menu.php                          |  256 ++++++----
 include/ajax_display_submenu.php                   |   97 ++++
 include/ajax_get_menu_detail.php                   |   41 +--
 include/ajax_get_profile.php                       |   18 +-
 html/direct.php => include/ajax_remove_submenu.php |   33 +-
 include/class_profile_menu.php                     |  185 +++----
 include/class_user.php                             |    2 +-
 include/profile.inc.php                            |  560 +++++++++++---------
 include/template/menu.php                          |   21 +-
 include/template/module.php                        |    2 +-
 include/template/profile_menu_display_module.php   |  103 ++++
 include/template/profile_menu_display_submenu.php  |   79 +++
 include/template/profile_sec_repository.php        |    3 +-
 include/template/user_sec_profile.php              |    2 +-
 sql/upgrade.sql                                    |  393 ++++++---------
 20 files changed, 1200 insertions(+), 808 deletions(-)

diff --git a/html/ajax_misc.php b/html/ajax_misc.php
index 815427e..ecee035 100644
--- a/html/ajax_misc.php
+++ b/html/ajax_misc.php
@@ -539,6 +539,12 @@ EOF;
        case 'add_menu':
                require_once NOALYSS_INCLUDE.'/ajax_add_menu.php';
                break;
+        case 'display_submenu':
+                require_once NOALYSS_INCLUDE.'/ajax_display_submenu.php';
+                break;
+        case 'remove_submenu':
+                require_once NOALYSS_INCLUDE.'/ajax_remove_submenu.php';
+                break;
        case 'cardsearch':
                require_once NOALYSS_INCLUDE.'/ajax_boxcard_search.php';
                break;
diff --git a/html/direct.php b/html/direct.php
index 1b97f79..242e3d9 100644
--- a/html/direct.php
+++ b/html/direct.php
@@ -27,7 +27,7 @@ global $g_user;
 $g_user=new User($cn);
 $g_user->Check();
 $g_user->check_dossier($_GET['gDossier']);
-$res=$cn->exec_sql("select code,description from get_profile_menu($1) where 
code ~* $2 or description ~* $3 limit 
8",array($g_user->login,$_POST['acs'],$_POST['acs']));
+$res=$cn->exec_sql("select distinct code,description from get_profile_menu($1) 
where code ~* $2 or description ~* $3 limit 
8",array($g_user->login,$_POST['acs'],$_POST['acs']));
 $nb=Database::num_row($res);
        echo "<ul>";
 for ($i = 0;$i< $nb;$i++)
diff --git a/html/do.php b/html/do.php
index e41b798..e5ebead 100644
--- a/html/do.php
+++ b/html/do.php
@@ -175,23 +175,46 @@ if (isset($_REQUEST['ac']))
     }
 
     $_REQUEST['ac']=  trim(strtoupper($_REQUEST['ac']));
-    $all = explode('/', $_REQUEST['ac']);
-    $module_selected = $all[0];
-    $g_user->audit();
-// Show module and highligt selected one
-    show_module($module_selected);
-    for ($i = 0; $i != count($all); $i++)
-    {   // show the menu
-               show_menu($all, $i);
+    $AC=$_REQUEST['ac'];
+    $user_profile=$g_user->get_profile();
+    
+    
+    $amenu_id=$cn->get_array('select 
+      pm_id_v3,pm_id_v2,pm_id_v1
+    from v_menu_profile where code= upper($1)  and p_id=$2',
+            array($AC,$user_profile));
+            
+    if ( count($amenu_id) != 1 ) {
+        throw new Exception(_('Erreur menu'));
     }
+    $module_id=$cn->get_value('select case when pm_id_v3 = 0 then (case when 
pm_id_v2 = 0 then pm_id_v1 else pm_id_v2 end) else pm_id_v3 end 
+        from v_menu_profile where p_id=$1 and upper(code)=upper($2)',
+            array($user_profile,$AC));
+    $g_user->audit();
+    // Show module and highligt selected one
+    show_module($module_id);
+    show_menu( $amenu_id[0]['pm_id_v3']);
+    show_menu( $amenu_id[0]['pm_id_v2']);
+    show_menu($amenu_id[0]['pm_id_v1']);
 }
 else
 {
     $default = find_default_module();
+    $user_profile=$cn->get_value('select p_id from profile_user where 
lower(user_name)=lower($1)',
+                array($g_user->login));
+    if ( $user_profile == "" ) 
+        throw new Exception (_('Aucun profil utilisateur'));
+    
+    $menu_id=$cn->get_value('select 
+        case when pm_id_v3 = 0 then 
+            (case when pm_id_v2 = 0 then pm_id_v1 else pm_id_v2 end) 
+       else pm_id_v3 end 
+    from v_menu_profile where code= upper($1)  and p_id=$2',
+            array($default,$user_profile));
     $_GET['ac']=$default;
     $_POST['ac']=$default;
     $_REQUEST['ac']=$default;
-    show_module($default);
+    show_module($menu_id);
     $all[0] = $default;
     show_menu($all, 0);
 }
diff --git a/html/js/scripts.js b/html/js/scripts.js
index 57ee0bf..b5faf7a 100644
--- a/html/js/scripts.js
+++ b/html/js/scripts.js
@@ -1371,6 +1371,13 @@ function remove_waiting_box()
     removeDiv('wait_box');
     remove_waiting_node();
 }
+/**
+ * Show all the detail of a profile : Menu, Management, Repository and
+ * let the user to modify it
+ * @param {type} gDossier
+ * @param {type} profile_id
+ * @returns {undefined}
+ */
 function get_profile_detail(gDossier, profile_id)
 {
     waiting_box();
@@ -1382,6 +1389,7 @@ function get_profile_detail(gDossier, profile_id)
                 onFailure: null,
                 onSuccess: function (req) {
                     remove_waiting_box();
+                    $('list_profile').hide();
                     $('detail_profile').innerHTML = req.responseText;
                     req.responseText.evalScripts();
                     $('detail_profile').show();
@@ -1427,6 +1435,12 @@ function calcy(p_sy)
     return sy;
 
 }
+/**
+ * @brief display a box with the menu option
+ * @param {type} gdossier
+ * @param {type} pm_id
+ * @returns {undefined}
+ */
 function mod_menu(gdossier, pm_id)
 {
     waiting_box();
@@ -1451,23 +1465,100 @@ function mod_menu(gdossier, pm_id)
     );
 }
 /**
+ * Display the submenu of a menu or a module, used in setting the menu
+ * 
+ * @param {type} p_dossier
+ * @param {type} p_profile
+ * @param {type} p_dep
+ * @returns {undefined}
+ */
+function display_sub_menu(p_dossier,p_profile,p_dep,p_level)
+{
+    waiting_box();
+    new Ajax.Request('ajax_misc.php',
+    {
+        method:'get',
+        parameters : { op:'display_submenu',
+                gDossier:p_dossier,
+                dep:p_dep,
+                p_profile:p_profile ,
+                p_level : p_level
+            },
+        onSuccess : function (req) {
+            try {
+                remove_waiting_box();
+                if ( $('menu_table').rows.length > p_level ) {
+                    $('menu_table').rows[1].remove();
+                }
+                var new_row = document.createElement('TR');
+                new_row.innerHTML = req.responseText;
+                $('menu_table').appendChild(new_row);
+            } catch (e) {
+                alert(e.message);
+            }
+        }
+    })
+}
+/**
+ * in CFGPRO, ask to confirm before removing a submenu and its children
+ * @param {type} p_dossier
+ * @param {type} profile_menu_id
+ * @returns {undefined}
+ */
+function remove_sub_menu(p_dossier,profile_menu_id)
+{
+    if ( ! confirm ('Confirm ?')) return;
+    waiting_box();
+    new Ajax.Request('ajax_misc.php',
+                    {                   
+                        method:'get',
+                        parameters: { op:'remove_submenu',gDossier:p_dossier,
+                        p_profile_menu_id:profile_menu_id},
+                        onSuccess:function (req) {
+                            try {
+                                remove_waiting_box();
+                                 if ( $('menu_table').rows.length > 1 ) {
+                                      $('menu_table').rows[1].remove();
+                                 }
+                                $('sub'+profile_menu_id).remove();
+                            } catch(e)
+                            {
+                                alert(e.message);
+                            }
+                        }
+                    }
+                            
+            );
+}
+/**
  * @brief add a menu to a profile, propose only the available menu
- * @param obj json object {dossier  : , p_id : profile id , type : type of 
menu}
- * Type of menu are "pr" for Printing "me" for plain menu
+ * @param obj json object 
+ *   - dossier  : , 
+ *   - p_id : profile id , 
+ *   - type : Type of menu are "pr" for Printing "me" for plain menu 
+ *   - p_level : level of menu (0 -> module,1-> top menu, 2->submenu)
+ *   - dep : the parent menu id  (pm_id)
+ * 
  */
 function add_menu(obj)
 {
     var pdossier = obj.dossier;
     var p_id = obj.p_id;
     var p_type = obj.type;
+    
     waiting_box();
     removeDiv('divdm' + p_id);
-    var qs = "op=add_menu&gDossier=" + pdossier + "&p_id=" + p_id + 
"&ctl=divdm" + p_id + "&type=" + p_type;
     var pos = fixed_position(250, 150)+";width:50%;";
     var action = new Ajax.Request('ajax_misc.php',
             {
                 method: 'get',
-                parameters: qs,
+                parameters:  { op:'add_menu',
+                            'gDossier':pdossier , 
+                            'p_id' :p_id ,
+                            'ctl' : 'divdm' + p_id ,
+                            'type' : p_type,
+                            'dep':obj.dep,
+                            'p_level':obj.p_level},
                 onFailure: null,
                 onSuccess: function (req) {
                     try {
@@ -1511,6 +1602,12 @@ function add_plugin(p_dossier)
             }
     );
 }
+/**
+ * Modify a menu
+ * @param {type} p_dossier
+ * @param {type} me_code
+ * @returns {undefined}
+ */
 function mod_plugin(p_dossier, me_code)
 {
     waiting_box();
diff --git a/include/ac_common.php b/include/ac_common.php
index cb0ee72..57f686e 100644
--- a/include/ac_common.php
+++ b/include/ac_common.php
@@ -806,8 +806,8 @@ EOF;
 }
 
 /**
- *
- * @param int $selected module selected
+ *Show the modules
+ * @param int $selected module selected profile_menu.pm_id
  */
 function show_module($selected)
 {
@@ -823,9 +823,11 @@ function show_module($selected)
 
     if ($selected != -1)
     {
-       require_once('template/module.php');
+        $selected_module=$cn->get_value('select me_code from profile_menu 
where'
+                . ' pm_id = $1 ', array($selected));
+       require_once NOALYSS_INCLUDE.'/template/module.php';
        $file = $cn->get_array("select 
me_file,me_parameter,me_javascript,me_type,me_description from v_all_menu
-           where me_code=$1 and user_name=$2", 
array($selected,$g_user->login));
+           where pm_id=$1 and user_name=$2", array($selected,$g_user->login));
        if ( count($file ) == 0 )
        {
                echo '</div>';
@@ -946,34 +948,52 @@ function find_default_module()
  * @param $module the $_REQUEST['ac'] exploded into an array
  * @param  $idx the index of the array : the AD code is splitted into an array 
thanks the slash
  */
-function show_menu($module, $idx)
+function show_menu($module)
 {
+    if ($module == 0)return;
+    static $level=0;
     global $g_user;
+    
     $cn = Dossier::connect();
-    $amenu = $cn->get_array("select
-       me_menu,me_code,me_url,me_javascript,me_type,me_description
-       from v_all_menu
-       where
-       me_code_dep=$1 and user_name=$2 order by p_order", array($module[$idx], 
$g_user->login));
-
+    /**
+     * Show the submenus
+     */
+    $amenu = $cn->get_array("
+        select 
+            pm_id,
+            me_code,
+            pm_id_dep,
+            me_file,
+            me_javascript,
+            me_url,
+            me_menu,
+            me_description,
+            me_description_etendue
+            from profile_menu 
+            join menu_ref using (me_code) 
+            where pm_id_dep=$1 and p_id=$2
+        order by p_order", array($module, $g_user->get_profile()));
+    
+    // There are submenuS, so show them
     if (!empty($amenu) && count($amenu) > 1)
     {
         $a_style_menu=array('topmenu','menu2','menu3');
-        if ( $idx > count($a_style_menu))
+        if ( $level > count($a_style_menu))
             $style_menu='menu3';
         else {
-            $style_menu=$a_style_menu[$idx];
+            $style_menu=$a_style_menu[$level];
         }
                require 'template/menu.php';
-    }
+    } // there is only one submenu so we include the code or javascript
     elseif (count($amenu) == 1)
     {
                echo '<div class="topmenu">';
                echo h2info(_($amenu[0]['me_menu']));
                echo '</div>';
-               $module[$idx] = $amenu[0]['me_code'];
+               $module = $amenu[0]['pm_id'];
     }
-
+    
+    // There is no submenu or only one
     if (empty($amenu) || count($amenu) == 1)
     {
                $file = $cn->get_array("select 
me_file,me_parameter,me_javascript,me_type
@@ -981,14 +1001,14 @@ function show_menu($module, $idx)
                join profile_menu using (me_code)
                join profile_user using (p_id)
                where
-               me_code=$1 and
+               pm_id=$1 and
                user_name=$2 and
                (me_file is not null or trim(me_file) <>'' or
-               me_javascript is not null or trim (me_javascript) <> '')", 
array($module[$idx],$g_user->login));
+               me_javascript is not null or trim (me_javascript) <> '')", 
array($module,$g_user->login));
 
                if (count($file)==0)
                {
-                       echo "Configuration incorrecte pour ce module 
".$module[$idx];
+                       echo "Configuration incorrecte pour ce module ".$module;
                        exit;
                }
 
@@ -1025,6 +1045,7 @@ function show_menu($module, $idx)
                     echo create_script($js);
                }
     }
+    $level++;
 }
 /**
  * Put in superglobal (get,post,request) the value contained in
diff --git a/include/ajax_add_menu.php b/include/ajax_add_menu.php
index 333810a..72086a9 100644
--- a/include/ajax_add_menu.php
+++ b/include/ajax_add_menu.php
@@ -1,5 +1,4 @@
 <?php
-
 /*
  *   This file is part of NOALYSS.
  *
@@ -22,30 +21,63 @@
 
 /**
  * @file
- * @brief show the form to add a menu
+ * @brief show the form for adding a menu. 
+ * $type : 
+ *     # me , it is a menu to add , so it could have dependencies
+ *     # pr , menu for Printing : no dependency 
+ * $p_level:
+ *     # 0 it is a module : no dependency p_type = M , refresh the detail of 
menu
+ *     # 1 it is a menu with possible submenu p_type = E, refresh the table 
with menu
+ *     # 2 it is a menu with no submenu , p_type = E 
+ * $dep  : is the profile_menu.pm_id of the parent menu
+ *     
+ * 
  */
-if ( ! defined ('ALLOWED') ) die('Appel direct ne sont pas permis');
-$type=HtmlInput::default_value_get('type','XX');
-if ($type == 'XX') {
-     throw new Exception('invalid call');
+if (!defined('ALLOWED'))
+    die('Appel direct ne sont pas permis');
+
+// Security 
+if ($g_user->check_module('CFGPRO')==0)
+    die();
+
+$type=HtmlInput::default_value_get('type', 'XX');
+$p_level=HtmlInput::default_value_get('p_level', 0);
+$dep=HtmlInput::default_value_get('dep', 0);
+if ($type=='XX')
+{
+    throw new Exception('invalid call');
     return;
 }
 // if type == menu the 
-if ( $type=='me')
+if ($type=='me')
 {
-$ame_code_dep=$cn->make_array("
-       select me_code,me_code||' '||me_menu||' '||coalesce(me_description,'') 
from
+    if ( isNumber($p_level)==0 ) throw new Exception('invalid call');
+    
+    if ($p_level==0)
+    {
+        // There is no dependency
+        // Menu which can be added
+        $ame_code=$cn->make_array("
+select me_code,me_code||' '||coalesce(me_menu,'')||' 
'||coalesce(me_description,'')
+       ||'('|| case when me_type='SP' then 'Special'
+               when me_type='PL' then 'Plugin'
+               when me_type='ME' and me_file is null and me_javascript is null 
and me_url is null then 'Module - Menu principal'
+               when me_type='ME' then 'Menu'
+               else
+               me_type
+               end||')'
+       from
        menu_ref
-       where
-       me_file is null and me_javascript is null and me_url is null and 
me_type<>'PR' and me_type <> 'SP'
-       and me_code in (select me_code from profile_menu where p_id=$1)".
-       "       UNION ALL
-               select me_code,me_code||' '||me_menu||' 
'||coalesce(me_description,'') from menu_ref
-       where
-               me_code='EXT'
+        where
+        me_type<>'PR'
        order by 1
-       ",1,array($p_id));
-$ame_code=$cn->make_array("
+       ");
+    }
+    elseif ($p_level==1)
+    {
+        // dependency is in dep
+        // Menu which can be added
+        $ame_code=$cn->make_array("
 select me_code,me_code||' '||coalesce(me_menu,'')||' 
'||coalesce(me_description,'')
        ||'('|| case when me_type='SP' then 'Special'
                when me_type='PL' then 'Plugin'
@@ -60,97 +92,119 @@ select me_code,me_code||' '||coalesce(me_menu,'')||' 
'||coalesce(me_description,
         me_type<>'PR'
        order by 1
        ");
+    }
+    elseif ($p_level==2)
+    {
+        // menu can *NOT* have submenu
+        // Menu which can be added
+        $ame_code=$cn->make_array("
+select me_code,me_code||' '||coalesce(me_menu,'')||' 
'||coalesce(me_description,'')
+       ||'('|| case when me_type='SP' then 'Special'
+               when me_type='PL' then 'Plugin'
+               when me_type='ME' and me_file is null and me_javascript is null 
and me_url is null then 'Module - Menu principal'
+               when me_type='ME' then 'Menu'
+               else
+               me_type
+               end||')'
+       from
+       menu_ref
+        where
+        me_type<>'PR' and
+       (
+          coalesce(me_file,'') <> '' or
+          coalesce(me_url,'') <> '' or
+          coalesce(me_javascript,'') <> ''
+        )
+       order by 1
+       ");
+    }
+    else
+    {
+        throw new Exception('LEVEL ERROR');
+    }
 
-$p_order=new INum("p_order","10");
-$atype=$cn->make_array("select pm_type,pm_desc from profile_menu_type order by 
1");
-
-$me_code=new ISelect('me_code');
-$me_code->value=$ame_code;
-
-$me_code_dep=new ISelect('me_code_dep');
-$me_code_dep->value=$ame_code_dep;
-
-$p_type=new ISelect('p_type');
-$p_type->value=$atype;
-$pm_default=new ICheckBox('pm_default');
-echo HtmlInput::title_box(_("Nouveau menu"), $ctl);
-?>
-<form method="POST" onsubmit="return confirm('<?php echo _('Vous 
confirmez');?> ?')">
-       <?php 
-       echo HtmlInput::hidden('tab','profile_menu_div');
-       ?>
-       <?php echo HtmlInput::hidden('p_id',$p_id)?>
-<table>
-<tr>
-       <td><?php echo _("Code")?></td>
-       <td><?php echo $me_code->input()?></td>
-</tr>
-<tr>
-       <td><?php echo _("Dépendant de ")?><?php echo 
HtmlInput::infobulle(20)?></td>
-       <td><?php echo $me_code_dep->input()?></td>
-</tr>
-
-<tr>
-       <td><?php echo _("Ordre d'apparition")?></td>
-       <td><?php echo $p_order->input()?></td>
-</tr>
-<tr>
-       <td><?php echo _("Menu par défaut")?></td>
-       <td><?php echo $pm_default->input()?></td>
-</tr>
-<tr>
-       <td><?php echo _("Type de menu")?></td>
-       <td><?php echo $p_type->input()?></td>
-</tr>
-</table>
-<?php 
-echo HtmlInput::submit('add_menu',_("Valider"));
-echo '</form>';
-return;
-}
+
+    $p_order=new INum("p_order", "10");
+
+    $me_code=new ISelect('me_code');
+    $me_code->value=$ame_code;
+
+
+    $pm_default=new ICheckBox('pm_default');
+    echo HtmlInput::title_box(_("Nouveau"), $ctl);
+    ?>
+    <form method="POST" onsubmit="return confirm('<?php echo _('Vous 
confirmez'); ?> ?')">
+        <?php
+        echo HtmlInput::hidden('tab', 'profile_menu_div');
+        ?>
+        <?php echo HtmlInput::hidden('p_id', $p_id) ?>
+        <?php echo HtmlInput::hidden('p_level', $p_level) ?>
+        <?php echo HtmlInput::hidden('type', $type) ?>
+        <?php echo HtmlInput::hidden('dep', $dep) ?>
+        <table>
+            <tr>
+                <td><?php echo _("Code") ?></td>
+                <td><?php echo $me_code->input() ?></td>
+            </tr>
+
+            <tr>
+                <td><?php echo _("Ordre d'apparition") ?></td>
+                <td><?php echo $p_order->input() ?></td>
+            </tr>
+            <tr>
+                <td><?php echo _("Menu par défaut") ?></td>
+                <td><?php echo $pm_default->input() ?></td>
+            </tr>
+
+        </table>
+        <?php
+        echo HtmlInput::submit('add_menu', _("Valider"));
+        echo '</form>';
+        return;
+    }
 
 // for printing menu (export CSV or PDF)
-if ($type=='pr')
-{
+    if ($type=='pr')
+    {
 
-$ame_code=$cn->make_array("
+        $ame_code=$cn->make_array("
 select me_code,me_code||' '||coalesce(me_menu,'')||' 
'||coalesce(me_description,'')
        from
        menu_ref
        where me_type='PR'
        and me_code not in (select me_code from profile_menu where p_id=$1)
        order by 1
-       ",0,array($p_id));
-
-$me_code=new ISelect('me_code');
-$me_code->value=$ame_code;
-
-       echo HtmlInput::title_box(_("Nouveau menu"), $ctl);
-       if (count($ame_code)==0)
-       {
-               echo h2(_("Aucune impression disponible à 
ajouter"),'class="notice"');
-               return;
-       }
-?>
-<form method="POST" onsubmit="return confirm('<?php echo _('Vous confirmez 
?')?>">
-       <?php 
-       echo HtmlInput::hidden('tab','profile_print_div');
-       ?>
-       <?php echo HtmlInput::hidden('p_id',$p_id)?>
-       <?php echo HtmlInput::hidden('p_order',10)?>
-       <?php echo HtmlInput::hidden('me_code_dep','')?>
-       <?php echo HtmlInput::hidden('p_type','PR')?>
-<table>
-<tr>
-       <td><?php echo _("Code")?></td>
-       <td><?php echo $me_code->input()?></td>
-</tr>
-
-</table>
-<?php 
-    echo HtmlInput::submit('add_impress',_("Valider"));
-    echo '</form>';
-    return;
-}
+       ", 0, array($p_id));
+
+        $me_code=new ISelect('me_code');
+        $me_code->value=$ame_code;
+
+        echo HtmlInput::title_box(_("Nouveau menu"), $ctl);
+        if (count($ame_code)==0)
+        {
+            echo h2(_("Aucune impression disponible à ajouter"),
+                    'class="notice"');
+            return;
+        }
+        ?>
+        <form method="POST" onsubmit="return confirm('<?php echo _('Vous 
confirmez ?') ?>">
+            <?php
+            echo HtmlInput::hidden('tab', 'profile_print_div');
+            ?>
+            <?php echo HtmlInput::hidden('p_id', $p_id) ?>
+            <?php echo HtmlInput::hidden('p_order', 10) ?>
+            <?php echo HtmlInput::hidden('me_code_dep', '') ?>
+            <?php echo HtmlInput::hidden('p_type', 'PR') ?>
+            <table>
+                <tr>
+                    <td><?php echo _("Code") ?></td>
+                    <td><?php echo $me_code->input() ?></td>
+                </tr>
 
-?>
+            </table>
+            <?php
+            echo HtmlInput::submit('add_impress', _("Valider"));
+            echo '</form>';
+            return;
+        }
+        ?>
diff --git a/include/ajax_display_submenu.php b/include/ajax_display_submenu.php
new file mode 100644
index 0000000..c1b665e
--- /dev/null
+++ b/include/ajax_display_submenu.php
@@ -0,0 +1,97 @@
+<?php
+/*
+ *   This file is part of NOALYSS.
+ *
+ *   NOALYSS is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   NOALYSS is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with NOALYSS; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+// Copyright 2015 Author Dany De Bontridder address@hidden
+/** 
+ * @brief call from ajax : display submenu
+ * Security : only user with the menu CFGPRO
+ * display the submenu of a menu or a module
+ * It expects 2 parameters  = p_profile (profile.p_id) and the dep 
(menu_ref.me_code)
+ */
+// require_once '.php';
+if ( ! defined ('ALLOWED') ) die('Appel direct ne sont pas permis');
+
+// Security 
+if ( $g_user->check_module('CFGPRO') == 0 ) die();
+
+// Check parameter
+$module=HtmlInput::default_value_get("dep", "");
+$p_level=HtmlInput::default_value_get("p_level", 0);
+$p_id=HtmlInput::default_value_get('p_profile',-1);
+
+if ($module == ""
+        || $p_id == -1 
+        || isNumber($p_id) == 0
+        || isNumber($p_level) == 0
+        )
+{
+    echo _('Paramètre invalide');
+    return;
+}
+
+require_once NOALYSS_INCLUDE.'/class_profile_menu.php';
+$p_level++;
+$profile=new Profile_Menu($cn,$p_id);
+$profile->display_module_menu($module,$p_level);
+
+////////////////////////////////////////////////////////////////////////////////
+// EXAMPLE
+////////////////////////////////////////////////////////////////////////////////
+/*
+if ($ac == 'save') // operation
+{
+    
+    $cn=new Database(dossier::id());
+    $todo=new Todo_List($cn);
+     $id=HtmlInput::default_value_get("id", 0); // get variable
+    $todo->set_parameter("id",$id);
+    if ($id <> 0 ) { $todo->load(); }
+    else
+    {
+        $todo->set_parameter("owner", $_SESSION['g_user']);
+    }
+    
+    $todo->set_parameter("date", HtmlInput::default_value_get("p_date_todo", 
""));
+    $todo->set_parameter("title", HtmlInput::default_value_get("p_title", ""));
+    $todo->set_parameter("desc", HtmlInput::default_value_get("p_desc", ""));
+    $todo->set_is_public(HtmlInput::default_value_get("p_public", "N"));
+    
+    if ( $todo->get_parameter('owner') == $_SESSION['g_user'] ) $todo->save();
+    $todo->load();
+ //----------------------------------------------------------------
+ // Answer in XML
+     header('Content-type: text/xml; charset=UTF-8');
+    $dom=new DOMDocument('1.0','UTF-8');
+    $tl_id=$dom->createElement('tl_id',$todo->get_parameter('id'));
+    
$tl_content=$dom->createElement('row',$todo->display_row('class="odd"','N'));
+     $root=$dom->createElement("root");
+     $todo_class=$todo->get_class();
+     $todo_class=($todo_class=="")?' odd ':$todo_class;
+     $class=$dom->createElement("style",$todo_class);
+    
+    $root->appendChild($tl_id);
+    $root->appendChild($tl_content);
+    $root->appendChild($class);
+    $dom->appendChild($root);
+   
+    echo $dom->saveXML();
+    exit();
+}
+  */
+?>        
\ No newline at end of file
diff --git a/include/ajax_get_menu_detail.php b/include/ajax_get_menu_detail.php
index b8f2562..1af6e30 100644
--- a/include/ajax_get_menu_detail.php
+++ b/include/ajax_get_menu_detail.php
@@ -29,19 +29,6 @@
 if ( ! defined ('ALLOWED') ) die('Appel direct ne sont pas permis');
 $profile=$cn->get_value("select p_id from profile_menu where 
pm_id=$1",array($pm_id));
 $a_value=$cn->make_array("select me_code,me_code||' '||me_menu||' 
'||coalesce(me_description,'') from menu_ref",0);
-$ame_code_dep=$cn->make_array("
-       select me_code,me_code||' '||me_menu||' '||coalesce(me_description,'') 
from
-       menu_ref
-       where
-       me_file is null and me_javascript is null and me_url is null and 
me_type<>'PR' and me_type <> 'SP'
-       and me_code in (select me_code from profile_menu where p_id=$1)".
-       "       UNION ALL
-               select me_code,me_code||' '||me_menu||' 
'||coalesce(me_description,'') from menu_ref
-       where
-               me_code='EXT'
-       order by 1
-       ",1,array($profile));
-$a_type=$cn->make_array("select pm_type,pm_desc from profile_menu_type",1);
 
 $array=$cn->get_array("select 
p_id,pm_id,me_code,me_code_dep,p_order,p_type_display,pm_default
        from profile_menu
@@ -58,10 +45,6 @@ $me_code=new ISelect('me_code');
 $me_code->value=$a_value;
 $me_code->selected=$array[0]['me_code'];
 
-$me_code_dep=new ISelect('me_code_dep');
-$me_code_dep->value=$ame_code_dep;
-$me_code_dep->selected=$array[0]['me_code_dep'];
-
 $p_order=new Inum('p_order',$array[0]['p_order']);
 $pm_default=new ICheckBox('pm_default','1');
 $pm_default->set_check($array[0]['pm_default']);
@@ -70,6 +53,7 @@ $pm_default->set_check($array[0]['pm_default']);
 <form method="POST" onsubmit="return confirm('<?php echo _("Vous confirmez")?> 
?')">
        <?php echo HtmlInput::hidden('pm_id',$array[0]['pm_id'])?>
        <?php echo HtmlInput::hidden('p_id',$array[0]['p_id'])?>
+       <?php echo HtmlInput::hidden('tab',"profile_menu_div")?>
 <table>
 <tr>
        <td><?php echo _("Code");?></td>
@@ -79,11 +63,6 @@ $pm_default->set_check($array[0]['pm_default']);
 if ($array[0]['p_type_display']!='P'):
 ?>
 <tr>
-       <td><?php echo _('Dépendant de');?> </td>
-       <td><?php echo $me_code_dep->input()?></td>
-</tr>
-
-<tr>
        <td><?php echo _("Ordre d'apparition");?></td>
        <td><?php echo $p_order->input()?></td>
 </tr>
@@ -93,24 +72,6 @@ if ($array[0]['p_type_display']!='P'):
 </tr>
 <?php endif;?>
 </table>
-       <p>
-<?php echo _("Cochez cette case si vous souhaitez effacer ce menu");?>
-<?php 
-$delete=new ICheckBox('delete',"1");
-echo $delete->input();
-?>
-</p>
-<?php 
-if ($array[0]['p_type_display']!='P'):
-?>
-       <p>
-<?php echo _("Cochez cette case si vous souhaitez effacer ce menu ainsi que 
ceux qui en dépendent");?>
-<?php 
-$delete=new ICheckBox('del_dep',"1");
-echo $delete->input();
-?>
-</p>
-<?php endif;?>
 <?php 
 echo HtmlInput::submit('mod',_("Valider"));
 echo '</form>';
diff --git a/include/ajax_get_profile.php b/include/ajax_get_profile.php
index 29bfb7b..d4c461b 100644
--- a/include/ajax_get_profile.php
+++ b/include/ajax_get_profile.php
@@ -27,17 +27,21 @@
  *
  */
 if ( ! defined ('ALLOWED') ) die('Appel direct ne sont pas permis');
+
+// Security 
+if ( $g_user->check_module('CFGPRO') == 0 ) die();
+
 require_once NOALYSS_INCLUDE.'/class_profile_sql.php';
 require_once NOALYSS_INCLUDE.'/class_profile_menu.php';
+require_once NOALYSS_INCLUDE.'/class_html_input.php';
+
 $profile=new Profile_sql($cn,$p_id);
 $gDossier=Dossier::id();
-$add_menu=HtmlInput::button("add", _("Ajout 
Menu"),"onclick=\"add_menu({dossier:$gDossier,p_id:$p_id,type:'me'})\"");
 $add_impression=HtmlInput::button("add", _("Ajout 
Menu"),"onclick=\"add_menu({dossier:$gDossier,p_id:$p_id,type:'pr'})\"");
 $call_tab=HtmlInput::default_value_post('tab', 'none');
 
$a_tab=array('profile_gen_div'=>'tabs','profile_menu_div'=>'tabs','profile_print_div'=>'tabs','profile_gestion_div'=>'tabs','profile_repo_div'=>'tabs');
 $a_tab[$call_tab]='tabs_selected';
 ?>
-<hr>
 <h1>Profil <?php echo $profile->p_name?></h1>
 <?php
     echo HtmlInput::anchor(_('Retour'), "", " onclick = \" 
$('detail_profile').hide();$('list_profile').show(); \" ", 'class="line"');
@@ -99,22 +103,22 @@ if ($profile->p_id > 0)
         echo '<div class="myfieldset"  style="display:none" 
id="profile_menu_div">';
        //Menu / Module /plugin in this profile
        echo "<h1 class=\"legend\">"._("Menu")."</h2>";
-       echo $add_menu;
        $profile_menu = new Profile_Menu($cn);
-       $profile_menu->listing_profile($p_id);
+        $profile_menu->p_id=$p_id;
+       $profile_menu->display_profile_menu_detail();
         echo '</div>';
         echo '<div class="myfieldset"  style="display:none" 
id="profile_print_div">';
        echo "<h1 class=\"legend\">"._("Impression")."</h1>";
-       $profile_menu->printing($p_id);
+       $profile_menu->printing();
        echo $add_impression;
         echo '</div>';
         echo '<div class="myfieldset"  style="display:none" 
id="profile_gestion_div">';
        echo "<h1 class=\"legend\">".('Groupe gestion')."</h1>";
-       $profile_menu->available_profile($p_id);
+       $profile_menu->available_profile();
         echo '</div>';
         echo '<div class="myfieldset"  style="display:none" 
id="profile_repo_div">';
        echo "<h1 class=\"legend\">"._("Dépôt de stock accessible")."</h1>";
-       $profile_menu->available_repository($p_id);
+       $profile_menu->available_repository();
         echo '</div>';
         if ( isset ($_POST['tab']))
         {
diff --git a/html/direct.php b/include/ajax_remove_submenu.php
similarity index 53%
copy from html/direct.php
copy to include/ajax_remove_submenu.php
index 1b97f79..913f997 100644
--- a/html/direct.php
+++ b/include/ajax_remove_submenu.php
@@ -1,5 +1,4 @@
 <?php
-
 /*
  *   This file is part of NOALYSS.
  *
@@ -16,26 +15,16 @@
  *   You should have received a copy of the GNU General Public License
  *   along with NOALYSS; if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
+*/
+
+// Copyright 2015 Author Dany De Bontridder address@hidden
 
-require_once '../include/constant.php';
-require_once NOALYSS_INCLUDE.'/class_database.php';
-require_once NOALYSS_INCLUDE.'/class_user.php';
+// require_once '.php';
+if ( ! defined ('ALLOWED') ) die('Appel direct ne sont pas permis');
 
-$cn=new Database($_GET['gDossier']);
-global $g_user;
-$g_user=new User($cn);
-$g_user->Check();
-$g_user->check_dossier($_GET['gDossier']);
-$res=$cn->exec_sql("select code,description from get_profile_menu($1) where 
code ~* $2 or description ~* $3 limit 
8",array($g_user->login,$_POST['acs'],$_POST['acs']));
-$nb=Database::num_row($res);
-       echo "<ul>";
-for ($i = 0;$i< $nb;$i++)
-{
-       $row=Database::fetch_array($res,$i);
-       echo "<li>";
-       echo $row['code'];
-       echo '<span class="informal"> '.$row['description'].'</span></li>';
-}
-       echo "</ul>";
-?>
+// Security 
+if ($g_user->check_module('CFGPRO')==0)
+    die();
+$p_profile_menu_id=HtmlInput::default_value_get('p_profile_menu_id', 0);
+$cn->exec_sql('delete from profile_menu where pm_id = $1 or 
pm_id_dep=$1',array($p_profile_menu_id))
+?>        
\ No newline at end of file
diff --git a/include/class_profile_menu.php b/include/class_profile_menu.php
index 9c48d5a..58de6dd 100644
--- a/include/class_profile_menu.php
+++ b/include/class_profile_menu.php
@@ -35,7 +35,7 @@ class Profile_Menu extends Profile_Menu_sql
     }
 
     /**
-     * Display the content of a profile
+     * Display the content of a profile menu for printing
      * @param type $resource
      * @param type $p_id
      */
@@ -43,8 +43,10 @@ class Profile_Menu extends Profile_Menu_sql
     {
         if (Database::num_row($resource)!=0)
         {
+            ////
+            // If there are submenus
             $gDossier=dossier::id();
-            echo '<ul style="list-style-type:none">';
+            echo '<td>';
             for ($e=0; $e<Database::num_row($resource); $e++)
             {
                 $menu=Database::fetch_array($resource, $e);
@@ -57,16 +59,12 @@ class Profile_Menu extends Profile_Menu_sql
                 $me_menu=$menu['me_menu'];
                 $me_desc=$menu['me_description'];
                 $me_def=($menu['pm_default']=='1')?'<span class="notice" 
style="display:inline">Défaut</span>':'';
-                $js=sprintf(
-                        '<a class="line" href="javascript:void(0)" 
onclick="mod_menu(\'%s\',\'%s\')">%s</A>', $gDossier, $menu['pm_id'], $me_code);
                 ?>
-                <li>
+                <li id="sub<?php echo $menu['pm_id'] ?>">
 
                     <?php echo $me_menu ?>
-                    ( <?php echo $js ?> )
                     <?php echo $me_desc ?>  <?php echo $me_def ?>
-                    <?php
-                $ret2=$this->cn->exec_sql("
+                    <?php $ret2=$this->cn->exec_sql("
                                     SELECT pm_id,
                                             pm.me_code,
                                             me_code_dep,
@@ -83,8 +81,16 @@ class Profile_Menu extends Profile_Menu_sql
                                             where
                                             p_id=$1 and me_code_dep=$2
                                             order by p_order asc
-                        ", array($p_id, $me_code));
-                    $this->sub_menu($ret2, $p_id);
+                        ", array($p_id, $me_code)); ?>
+                    <span>
+                        <?php
+                        echo HtmlInput::anchor(SMALLX, "",
+                                sprintf(" onclick = 
\"remove_sub_menu(%d,%d)\"",
+                                        Dossier::id(), $menu['pm_id']),
+                                'class="tinybutton"')
+                        ?>
+                    </span>
+                    <?php
                     echo "</li>";
                 } //end loop e
                 echo '</ul>';
@@ -95,9 +101,9 @@ class Profile_Menu extends Profile_Menu_sql
          * Show a table with all the menu and the type
          * @param type $p_id profile.p_id
          */
-        function listing_profile($p_id)
+        function display_profile_menu_detail()
         {
-            $array=$this->cn->get_array("
+            $a_module=$this->cn->get_array("
                        SELECT pm_id,
                                        pm.me_code,
                                        me_code_dep,
@@ -107,82 +113,26 @@ class Profile_Menu extends Profile_Menu_sql
                                        pm_default,
                                        pm_desc,
                                        me_menu,
-                                       me_description
-                       FROM profile_menu as pm join profile_menu_type on 
(p_type_display=pm_type)
+                                       me_description,
+                                        me_url,
+                                        me_file,
+                                        me_javascript
+                       FROM profile_menu as pm 
+                        join profile_menu_type on (p_type_display=pm_type)
                        join menu_ref as mr on (mr.me_code=pm.me_code)
                        where
                        p_id=$1 and p_type_display='M'
                        order by p_order asc
-                       ", array($p_id));
-            if (count($array)==0)
-            {
-                // if not module show only menu
-                $ret=$this->cn->exec_sql("
-                                    SELECT pm_id,
-                                    pm.me_code,
-                                    me_code_dep,
-                                    p_id,
-                                    p_order,
-                                    p_type_display,
-                                    pm_default,
-                                    pm_desc,
-                                    me_menu,
-                                    me_description
-                                    FROM profile_menu as pm
-                                            join profile_menu_type on 
(p_type_display=pm_type)
-                                            join menu_ref as mr on 
(mr.me_code=pm.me_code)
-                                    where
-                                    p_id=$1 and p_type_display='E'
-                                    order by p_order asc
-                                                       ", array($p_id));
-                echo '<ul style="list-style-type:none">';
-
-                $this->sub_menu($ret, $p_id);
-                // $this->listing_profile($p_id,$ret, $array[$i]['me_code']);
+                       ", array($this->p_id));
+            ////////////////////////////////////////////////////////////
+            // With a module
+            ////////////////////////////////////////////////////////////
+            $this->display_module($a_module);
 
-                echo "</li>";
-                echo '</ul>';
-            }
-            else
-            {
-                $this->cn->prepare("menu", "
-                               SELECT pm_id,
-                                    pm.me_code,
-                                    me_code_dep,
-                                    p_id,
-                                    p_order,
-                                    p_type_display,
-                                    pm_default,
-                                    pm_desc,
-                                    me_menu,
-                                    me_description
-                                    FROM profile_menu as pm
-                                            join profile_menu_type on 
(p_type_display=pm_type)
-                                            join menu_ref as mr on 
(mr.me_code=pm.me_code)
-                                    where
-                                    p_id=$1 and me_code_dep=$2 and 
p_type_display in ('E','S')
-                                    order by p_order asc
-                                                       ");
-                echo '<ul style="list-style-type:none">';
-                // Menu by module
-                $gDossier=Dossier::id();
-                for ($i=0; $i<count($array); $i++)
-                {
-                    $me_def=($array[$i]['pm_default']=='1')?'<span 
class="notice" style="display:inline">Défaut</span>':'';
-                    $js=sprintf('<a class="line" 
style="display:inline;text-decoration:underline"
-                                               href="javascript:void(0)" 
onclick="mod_menu(\'%s\',\'%s\')">%s</A>', $gDossier, $array[$i]['pm_id'], 
$array[$i]['me_code']);
-                    echo "<li>".$array[$i]['me_menu']." 
(".$js.")".$array[$i]['me_description']." ".$me_def;
-
-                    $ret=$this->cn->execute("menu", array($p_id, 
$array[$i]['me_code']));
-                    $this->sub_menu($ret, $p_id);
-
-                    echo "</li>";
-                }// end loop i
-                echo '</ul>';
-                //*******************************************
-                // show also menu without a module
-                //*******************************************
-                $ret=$this->cn->exec_sql("
+            //*******************************************
+            // show also menu without a module
+            //*******************************************
+            $ret=$this->cn->exec_sql("
                                         SELECT pm_id,
                                         pm.me_code,
                                         me_code_dep,
@@ -199,16 +149,57 @@ class Profile_Menu extends Profile_Menu_sql
                                        where
                                        p_id=$1 and  p_type_display not in 
('M','P') and me_code_dep is null
                                        order by p_order asc
-                                                       ", array($p_id));
-                if (Database::num_row($ret))
-                {
-                    echo "<h2>Menu sans module</h2>";
-                    $this->sub_menu($ret, $p_id);
-                }
-            }
+                                                       ", array($this->p_id));
         }
 
-        function printing($p_id)
+        /**
+         * @brief Display the module, with a javascript inside to show the 
menu 
+         * contained in the module
+         * Used for setting the configuration
+         * @param $ap_module $array of module received from 
display_profile_menu_detail  
+         * @see Profile_menu::display_profile_menu_detail
+         */
+        function display_module($ap_module)
+        {
+            include 
NOALYSS_INCLUDE.'/template/profile_menu_display_module.php';
+        }
+
+        /**
+         * @brief  Display all menu and submenu of a module.
+         * @see display_profile_module 
+         * 
+         */
+        function display_module_menu($p_module_id, $p_level)
+        {
+            // Get the submenu
+            $a_module=$this->cn->get_array('
+                SELECT pm_id, 
+                    me_code, 
+                    me_code_dep, 
+                    p_id, 
+                    p_order, 
+                    p_type_display, 
+                    pm_default,
+                    me_menu,
+                    me_file,
+                    me_url,
+                    me_javascript,
+                    me_parameter,
+                    me_description
+                FROM profile_menu
+                join menu_ref using (me_code)
+                where
+                p_id = $1 and
+                pm_id_dep = $2 order by p_order',
+                    array($this->p_id, $p_module_id));
+            require 
NOALYSS_INCLUDE.'/template/profile_menu_display_submenu.php';
+        }
+
+        /**
+         * display all the accessible export of a profile $p_id
+         * @param type $p_id profile.p_id
+         */
+        function printing()
         {
             $ret=$this->cn->exec_sql("
                             SELECT pm_id,
@@ -227,17 +218,17 @@ class Profile_Menu extends Profile_Menu_sql
                                 where
                                 p_id=$1 and me_type='PR'
                                 order by p_order asc
-                                                       ", array($p_id));
+                                                       ", array($this->p_id));
             // Menu by module
             $gDossier=Dossier::id();
-            $this->sub_menu($ret, $p_id);
+            $this->sub_menu($ret, $this->p_id);
         }
 
         /**
          * Show the available profile for the profile $p_id, it concerns only 
the action of management (action-gestion)
          * @param $p_id is the profile p_id
          */
-        function available_profile($p_id)
+        function available_profile()
         {
             $array=$this->cn->get_array("
                                        select 
p.p_id,p.p_name,s.p_granted,s.ua_id,s.ua_right
@@ -249,7 +240,7 @@ class Profile_Menu extends Profile_Menu_sql
                                                from profile as p2
                                                where
                                                p2.p_id not in (select 
p_granted from user_sec_action_profile where p_id = $1) order by p_name;
-                               ", array($p_id));
+                               ", array($this->p_id));
             $aright_value=array(
                 array('value'=>'R', 'label'=>_('Lecture')),
                 array('value'=>'W', 'label'=>_('Ecriture')),
@@ -262,7 +253,7 @@ class Profile_Menu extends Profile_Menu_sql
          * Show the available repository for the profile $p_id
          * @param $p_id is the profile p_id
          */
-        function available_repository($p_id)
+        function available_repository()
         {
             $array=$this->cn->get_array("
                                        select 
p.r_id,p.r_name,s.ur_id,s.ur_right
@@ -274,7 +265,7 @@ class Profile_Menu extends Profile_Menu_sql
                                                from stock_repository as p2
                                                where
                                                p2.r_id not in (select r_id 
from profile_sec_repository where p_id = $1) order by r_name;
-                               ", array($p_id));
+                               ", array($this->p_id));
             $aright_value=array(
                 array('value'=>'R', 'label'=>_('Lecture')),
                 array('value'=>'W', 'label'=>_('Ecriture')),
diff --git a/include/class_user.php b/include/class_user.php
index 8852440..a856114 100644
--- a/include/class_user.php
+++ b/include/class_user.php
@@ -1110,7 +1110,7 @@ class User
        function get_profile()
        {
                $profile = $this->db->get_value("select p_id from profile_user 
where
-                               user_name=$1", array($this->login));
+                               lower(user_name)=lower($1)", 
array($this->login));
                return $profile;
        }
         /**
diff --git a/include/profile.inc.php b/include/profile.inc.php
index 4c2b4e4..3ab96df 100644
--- a/include/profile.inc.php
+++ b/include/profile.inc.php
@@ -18,7 +18,8 @@
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 // Copyright Author Dany De Bontridder address@hidden
-if ( ! defined ('ALLOWED') ) die('Appel direct ne sont pas permis');
+if (!defined('ALLOWED'))
+    die('Appel direct ne sont pas permis');
 require_once NOALYSS_INCLUDE.'/class_profile_sql.php';
 global $cn;
 
@@ -27,70 +28,76 @@ global $cn;
 //**********************************************
 if (isset($_POST['change_profile']))
 {
-       extract($_POST);
-       try
-       {
-               for ($e = 0; $e < count($right); $e++)
-               {
-                       if ($right[$e] == 'X' && $ua_id[$e]=='')
-                               continue;
-                       if ($right[$e] == 'X' && $ua_id[$e]!='')
-                       {
-                               $cn->exec_sql("delete from 
user_sec_action_profile where p_id=$1 and p_granted=$2", array($p_id, 
$ap_id[$e]));
-                               continue;
-                       }
-                       if ($ua_id[$e] == "")
-                       {
-                               $cn->exec_sql("insert into 
user_sec_action_profile (p_id,p_granted,ua_right) values($1,$2,$3)", 
array($p_id, $ap_id[$e], $right[$e]));
-                               continue;
-                       }
-                       if ($ua_id[$e] != '')
-                       {
-                               $cn->exec_sql("update user_sec_action_profile 
set ua_right=$3 where  p_id=$1 and p_granted=$2 ", array($p_id, $ap_id[$e], 
$right[$e]));
-                               continue;
-                       }
-               }
-       }
-       catch (Exception $exc)
-       {
-               echo $exc->getTraceAsString();
-               throw $exc;
-       }
+    extract($_POST);
+    try
+    {
+        for ($e=0; $e<count($right); $e++)
+        {
+            if ($right[$e]=='X'&&$ua_id[$e]=='')
+                continue;
+            if ($right[$e]=='X'&&$ua_id[$e]!='')
+            {
+                $cn->exec_sql("delete from user_sec_action_profile where 
p_id=$1 and p_granted=$2",
+                        array($p_id, $ap_id[$e]));
+                continue;
+            }
+            if ($ua_id[$e]=="")
+            {
+                $cn->exec_sql("insert into user_sec_action_profile 
(p_id,p_granted,ua_right) values($1,$2,$3)",
+                        array($p_id, $ap_id[$e], $right[$e]));
+                continue;
+            }
+            if ($ua_id[$e]!='')
+            {
+                $cn->exec_sql("update user_sec_action_profile set ua_right=$3 
where  p_id=$1 and p_granted=$2 ",
+                        array($p_id, $ap_id[$e], $right[$e]));
+                continue;
+            }
+        }
+    }
+    catch (Exception $exc)
+    {
+        echo $exc->getTraceAsString();
+        throw $exc;
+    }
 }
 //**********************************************
 // Save avail. profiles
 //**********************************************
 if (isset($_POST['change_stock']))
 {
-       extract($_POST);
-       try
-       {
-               for ($e = 0; $e < count($right); $e++)
-               {
-                       if ($right[$e] == 'X' && $ur_id[$e]=='')
-                               continue;
-                       if ($right[$e] == 'X' && $ur_id[$e]!='')
-                       {
-                               $cn->exec_sql("delete from 
profile_sec_repository where p_id=$1 and r_id=$2", array($p_id, $ar_id[$e]));
-                               continue;
-                       }
-                       if ($ur_id[$e] == "")
-                       {
-                               $cn->exec_sql("insert into 
profile_sec_repository (p_id,r_id,ur_right) values($1,$2,$3)", array($p_id, 
$ar_id[$e], $right[$e]));
-                               continue;
-                       }
-                       if ($ur_id[$e] != '')
-                       {
-                               $cn->exec_sql("update profile_sec_repository 
set ur_right=$3 where  p_id=$1 and r_id=$2 ", array($p_id, $ar_id[$e], 
$right[$e]));
-                               continue;
-                       }
-               }
-       }
-       catch (Exception $exc)
-       {
-               echo $exc->getTraceAsString();
-               throw $exc;
-       }
+    extract($_POST);
+    try
+    {
+        for ($e=0; $e<count($right); $e++)
+        {
+            if ($right[$e]=='X'&&$ur_id[$e]=='')
+                continue;
+            if ($right[$e]=='X'&&$ur_id[$e]!='')
+            {
+                $cn->exec_sql("delete from profile_sec_repository where 
p_id=$1 and r_id=$2",
+                        array($p_id, $ar_id[$e]));
+                continue;
+            }
+            if ($ur_id[$e]=="")
+            {
+                $cn->exec_sql("insert into profile_sec_repository 
(p_id,r_id,ur_right) values($1,$2,$3)",
+                        array($p_id, $ar_id[$e], $right[$e]));
+                continue;
+            }
+            if ($ur_id[$e]!='')
+            {
+                $cn->exec_sql("update profile_sec_repository set ur_right=$3 
where  p_id=$1 and r_id=$2 ",
+                        array($p_id, $ar_id[$e], $right[$e]));
+                continue;
+            }
+        }
+    }
+    catch (Exception $exc)
+    {
+        echo $exc->getTraceAsString();
+        throw $exc;
+    }
 }
 //**********************************************
 // Save_name
@@ -99,250 +106,289 @@ if (isset($_POST['change_stock']))
 if (isset($_POST['save_name']))
 {
 
-       extract($_POST);
-       try
-       {
-               if (strlen(trim($p_name)) == 0)
-                       throw new Exception("Nom ne peut être vide");
-               if (isNumber($p_id) == 0)
-                       throw new Exception("profile Invalide");
-               $wc = (isset($with_calc)) ? 1 : 0;
-               $wd = (isset($with_direct_form)) ? 1 : 0;
-               $p_desc = (strlen(trim($p_desc)) == 0) ? null : trim($p_desc);
-               if ($p_id != -1)
-               {
-                       $cn->exec_sql("update profile set p_name=$1,p_desc=$2,
-                                       with_calc=$3, with_direct_form=$4 where 
p_id=$5", array($p_name,
-                               $p_desc, $wc, $wd, $p_id));
-               }
-               else
-               {
-                       $p_id = $cn->get_value("insert into profile (p_name,
+    extract($_POST);
+    try
+    {
+        if (strlen(trim($p_name))==0)
+            throw new Exception("Nom ne peut être vide");
+        if (isNumber($p_id)==0)
+            throw new Exception("profile Invalide");
+        $wc=(isset($with_calc))?1:0;
+        $wd=(isset($with_direct_form))?1:0;
+        $p_desc=(strlen(trim($p_desc))==0)?null:trim($p_desc);
+        if ($p_id!=-1)
+        {
+            $cn->exec_sql("update profile set p_name=$1,p_desc=$2,
+                                       with_calc=$3, with_direct_form=$4 where 
p_id=$5",
+                    array($p_name,
+                $p_desc, $wc, $wd, $p_id));
+        }
+        else
+        {
+            $p_id=$cn->get_value("insert into profile (p_name,
                                p_desc,with_calc,with_direct_form) values
-                               ($1,$2,$3,$4) returning p_id", array(
-                               $p_name, $p_desc, $wc, $wd
-                                       ));
-               }
-       }
-       catch (Exception $e)
-       {
-               alert($e->getMessage());
-       }
+                               ($1,$2,$3,$4) returning p_id",
+                    array(
+                $p_name, $p_desc, $wc, $wd
+            ));
+        }
+    }
+    catch (Exception $e)
+    {
+        alert($e->getMessage());
+    }
 }
 //************************************
 // Clone
 //************************************
 if (isset($_POST['clone']))
 {
-       extract($_POST);
-       try
-       {
-               $cn->start();
-               $new_id = $cn->get_value("insert into 
profile(p_name,p_desc,with_calc,
+    extract($_POST);
+    try
+    {
+        $cn->start();
+        $new_id=$cn->get_value("insert into profile(p_name,p_desc,with_calc,
                        with_direct_form)
                        select 'copie de '||p_name,p_desc,with_calc,
                        with_direct_form from profile where p_id=$1 returning 
p_id", array($p_id));
-               $cn->exec_sql("
+        $cn->exec_sql("
                                insert into profile_menu 
(p_id,me_code,me_code_dep,p_order,p_type_display,pm_default)
                                select 
$1,me_code,me_code_dep,p_order,p_type_display,pm_default from profile_menu
                                where p_id=$2
                        ", array($new_id, $p_id));
-               $cn->commit();
-               $p_id = $new_id;
-       }
-       catch (Exception $exc)
-       {
-               echo alert($exc->getMessage());
-               $cn->rollback();
-       }
+        $cn->commit();
+        $p_id=$new_id;
+    }
+    catch (Exception $exc)
+    {
+        echo alert($exc->getMessage());
+        $cn->rollback();
+    }
 }
 //************************************
 // Delete
 //************************************
 if (isset($_POST['delete_profil']))
 {
-       extract($_POST);
-       try
-       {
-               $cn->start();
-               if ($p_id == 1)
-               {
-                       throw new Exception('On ne peut pas effacer le profil 
par défaut');
-               }
-               $new_id = $cn->get_value("delete from profile
+    extract($_POST);
+    try
+    {
+        $cn->start();
+        if ($p_id==1)
+        {
+            throw new Exception('On ne peut pas effacer le profil par défaut');
+        }
+        $new_id=$cn->get_value("delete from profile
                        where p_id=$1 ", array($p_id));
-               $cn->commit();
-
-       }
-       catch (Exception $exc)
-       {
-               echo alert($exc->getMessage());
-               $cn->rollback();
-       }
+        $cn->commit();
+    }
+    catch (Exception $exc)
+    {
+        echo alert($exc->getMessage());
+        $cn->rollback();
+    }
 }
 //************************************
 // Modify the menu or delete it
 //************************************
 if (isset($_POST['mod']))
 {
-       extract($_POST);
-       if (isset($delete) || isset($del_dep))
-       {
-               try
-               {
-                       $cn->start();
-                       if (isset($del_dep))
-                       {
-                               $cn->exec_sql("delete from profile_menu where 
pm_id in (select * from get_menu_dependency($1))", array($pm_id));
-                       }
-                       $cn->exec_sql("delete from profile_menu where 
pm_id=$1", array($pm_id));
-                       $cn->commit();
-               }
-               catch (Exception $exc)
-               {
-                       echo $exc->getMessage();
-                       $cn->rollback();
-               }
-       }
-       else
-               try
-               {
-                       /**
-                        * Printing cannot be a menu and do not depend of 
anything
-                        */
-                       $menu_type = $cn->get_value("select me_type from 
menu_ref
+    // pm_id of the menu to modify
+    $pm_id=HtmlInput::default_value_post("pm_id", 0);
+    // profile id
+    $p_id=HtmlInput::default_value_post("p_id", "");
+    // display order 
+    $p_order=HtmlInput::default_value_post("p_order", 0);
+    // code to add
+    $me_code=HtmlInput::default_value_post("me_code", "");
+    // tab
+    $tab=HtmlInput::default_value_post("tab", "");
+    // set Default
+    $pm_default=HtmlInput::default_value_post('pm_default', 0);
+    try
+    {
+        if ($pm_id==""||
+                $p_id==""||
+                $p_order==""||
+                $me_code==""
+        )
+            throw new Exception('Argument');
+        /**
+         * Printing cannot be a menu and do not depend of anything
+         */
+        $menu_type=$cn->get_value("select me_type from menu_ref
                        where me_code=$1", array($me_code));
 
-                       if ($menu_type == 'PR')
-                       {
-                               $p_type = 'P';
-                               $me_code_dep = -1;
-                       }
-                       /**
-                        * Check if we don't add a menu depending on itself
-                        */
-                       if ( $me_code == $me_code_dep )
-                                throw new Exception("Un menu ne peut pas 
dépendre de lui-même");
-                       $cn->start();
-                       $me_code_dep = ($me_code_dep == -1) ? null : 
$me_code_dep;
-                       $pm_default = (isset($pm_default)) ? 1 : 0;
-                       $p_order = (strlen(trim($p_order)) == 0) ? "0" : 
$p_order;
-                       if ($pm_default == 1)
-                       {
-                               $cn->exec_sql("update profile_menu set 
pm_default=0
-                               where p_id=(select p_id from profile_menu
+        if ($menu_type=='PR')
+        {
+            $p_type='P';
+            $me_code_dep=-1;
+        }
+        $cn->start();
+        $p_order=(strlen(trim($p_order))==0)?"0":$p_order;
+        if ($pm_default==1)
+        {
+            // reset all default
+            $cn->exec_sql("update profile_menu set pm_default=0
+                               where pm_id_dep=(select pm_id_dep from 
profile_menu
                                                                where
                                                                pm_id=$1)", 
array($pm_id));
-                       }
-                       $cn->exec_sql("update profile_menu set 
me_code=$1,me_code_dep=$2,p_order=$3,pm_default=$4
-                       where pm_id=$5", array($me_code, $me_code_dep, 
$p_order, $pm_default, $pm_id));
-                       $cn->commit();
-               }
-               catch (Exception $e)
-               {
-                       $cn->rollback();
-                       alert($e->getMessage());
-               }
+        }
+        $cn->exec_sql("update profile_menu set 
me_code=$1,p_order=$2,pm_default=$3
+                       where pm_id=$4", array($me_code, $p_order, $pm_default, 
$pm_id));
+        $cn->commit();
+    }
+    catch (Exception $e)
+    {
+        $cn->rollback();
+        alert($e->getMessage());
+    }
 }
 
 //****************************************************
 // Add a menu, module, submenu,plugin...
 //****************************************************
-if (isset($_POST['add_menu']) || isset($_POST['add_impress']))
+if (isset($_POST['add_menu'])||isset($_POST['add_impress']))
 {
-       extract($_POST);
-       try
-       {
-               $cn->start();
+    // type of menu me or pr
+    $p_type=HtmlInput::default_value_post("type", "");
+    // level
+    $p_level=HtmlInput::default_value_post("p_level", "");
+    // pm_id of menu parent
+    $p_dep=HtmlInput::default_value_post("dep", "");
+    // profile id
+    $p_id=HtmlInput::default_value_post("p_id", "");
+    // display order 
+    $p_order=HtmlInput::default_value_post("p_order", 0);
+    // code to add
+    $me_code=HtmlInput::default_value_post("me_code", "");
+    // tab
+    $tab=HtmlInput::default_value_post("tab", "");
+    try
+    {
+        $cn->start();
 
-               /**
-                * Printing cannot be a menu and do not depend of anything
-                */
-               $menu_type = $cn->get_value("select me_type from menu_ref
-                       where me_code=$1", array($me_code));
 
-               if ($menu_type == 'PR')
-               {
-                       $p_type = 'P';
-                       $me_code_dep = -1;
-               }
+        /**
+         * Printing cannot be a menu and do not depend of anything
+         */
+        $menu_type=$cn->get_value("select me_type from menu_ref
+                where me_code=$1", array($me_code));
+
+        if ($menu_type=='PR')
+        {
+            $p_type='P';
+            $me_code_dep=null;
+            $pm_id_dep=null;
+        }
 
-               // Module never depends of anything
-               if ($p_type == 'M')
-               {
-                       $me_code_dep = -1;
-               }
-               /**
-                * Check for infinite loop
-                */
-               $inf = $cn->get_value("select count(*) from profile_menu
-                       where p_id=$1 and me_code_dep=$2 and me_code=$3", 
array($p_id, $me_code, $me_code_dep));
-               if ($inf > 0)
-                       throw new Exception("Boucle infinie");
-               /**
-                * Check if we don't add a menu depending on itself
-                */
-               if ( $me_code == $me_code_dep )
-                        throw new Exception("Un menu ne peut pas dépendre de 
lui-même");
+        // Module never depends of anything
+        if ($p_type=='me')
+        {
+            /*
+             * Check variable
+             */
+            if ($p_type==""||
+                    $p_level==""||
+                    $p_dep==""||
+                    $p_id==""||
+                    $me_code==""
+            )
+                throw new Exception('Argument');
+            if ($p_level==0)
+            {
+                $me_code_dep=null;
+                $pm_id_dep=null;
+                $p_type='M';
+            }
+            else
+            {
+                $me_code_dep=$cn->get_value('select me_code from profile_menu'
+                        .' where pm_id = $1 and p_id=$2', array($p_dep, 
$p_id));
+                $pm_id_dep=$p_dep;
+                $p_type='E';
+            }
+        }
+        /**
+         * Check for infinite loop
+         */
+        $inf=$cn->get_value("select count(*) from profile_menu
+                where p_id=$1 and me_code_dep=$2 and me_code=$3",
+                array($p_id, $me_code, $me_code_dep));
+        if ($inf>0)
+            throw new Exception("Boucle infinie");
+        /**
+         * Check if we don't add a menu depending on itself
+         */
+        if ($me_code==$me_code_dep)
+            throw new Exception("Un menu ne peut pas dépendre de lui-même");
 
 
-               /**
-                * if me_code_dep == -1, it means it is null
-                */
-               $me_code_dep = ($me_code_dep == -1) ? null : $me_code_dep;
+        /**
+         * if me_code_dep == -1, it means it is null
+         */
+        $me_code_dep=($me_code_dep==-1)?null:$me_code_dep;
 
-               $pm_default = (isset($pm_default)) ? 1 : 0;
-               $cn->exec_sql("
-                               insert into profile_menu 
(me_code,me_code_dep,p_id,p_order,pm_default,p_type_display)
-                               values ($1,$2,$3,$4,$5,$6)
-                               ", array($me_code, $me_code_dep, $p_id, 
$p_order, $pm_default, $p_type));
+        $pm_default=(isset($pm_default))?1:0;
+        $cn->exec_sql("
+                        insert into profile_menu 
(me_code,me_code_dep,p_id,p_order,pm_default,p_type_display,pm_id_dep)
+                        values ($1,$2,$3,$4,$5,$6,$7)
+                        ",
+                array($me_code, $me_code_dep, $p_id, $p_order, $pm_default, 
$p_type,
+            $pm_id_dep));
 
-               $cn->commit();
-       }
-       catch (Exception $exc)
-       {
-               alert($exc->getMessage());
-       }
+        $cn->commit();
+    }
+    catch (Exception $exc)
+    {
+        alert($exc->getMessage());
+    }
 }
 
 echo '<div id="list_profile" class="content">';
-$table = new Sort_Table();
-$url = $_SERVER['REQUEST_URI'];
+$table=new Sort_Table();
+$url=$_SERVER['REQUEST_URI'];
 
-$table->add(_('Nom'), $url, "order by p_name asc", "order by p_name desc", 
"na", "nd");
-$table->add(_('Description'), $url, "order by p_desc asc", "order by p_desc 
desc", "da", "dd");
-$table->add(_('Calculatrice visible'), $url, "order by with_calc asc", "order 
by with_calc desc", "ca", "cd");
-$table->add(_('Accès Direct visible'), $url, "order by with_direct_form asc", 
"order by with_direct_form desc", "fa", "fd");
+$table->add(_('Nom'), $url, "order by p_name asc", "order by p_name desc", 
"na",
+        "nd");
+$table->add(_('Description'), $url, "order by p_desc asc",
+        "order by p_desc desc", "da", "dd");
+$table->add(_('Calculatrice visible'), $url, "order by with_calc asc",
+        "order by with_calc desc", "ca", "cd");
+$table->add(_('Accès Direct visible'), $url, "order by with_direct_form asc",
+        "order by with_direct_form desc", "fa", "fd");
 
-$ord = (isset($_REQUEST['ord'])) ? $_REQUEST['ord'] : 'na';
+$ord=(isset($_REQUEST['ord']))?$_REQUEST['ord']:'na';
 
-$order = $table->get_sql_order($ord);
+$order=$table->get_sql_order($ord);
 
-$menu = new Profile_sql($cn);
-$ret = $menu->seek("where p_id > 0 ".$order);
+$menu=new Profile_sql($cn);
+$ret=$menu->seek("where p_id > 0 ".$order);
 echo '<table class="result">';
 echo '<tr>';
-echo '<th>' . $table->get_header(0) . '</th>';
-echo '<th>' . $table->get_header(1) . '</th>';
-echo '<th>' . $table->get_header(2) . '</th>';
-echo '<th>' . $table->get_header(3) . '</th>';
+echo '<th>'.$table->get_header(0).'</th>';
+echo '<th>'.$table->get_header(1).'</th>';
+echo '<th>'.$table->get_header(2).'</th>';
+echo '<th>'.$table->get_header(3).'</th>';
 echo '</tr>';
-$gDossier = Dossier::id();
-for ($i = 0; $i < Database::num_row($ret); $i++)
+$gDossier=Dossier::id();
+for ($i=0; $i<Database::num_row($ret); $i++)
 {
-       $row = $menu->get_object($ret, $i);
+    $row=$menu->get_object($ret, $i);
 
-       $js = sprintf('<a href="javascript:void(0)" 
style="text-decoration:underline" 
onclick="get_profile_detail(\'%s\',\'%s\')">', $gDossier, $row->p_id);
-       echo '<tr>';
-       echo "<td>" . $js . $row->p_name . '</a>' . '</td>';
-       echo td($row->p_desc);
-       echo td($row->with_calc);
-       echo td($row->with_direct_form);
-       echo '</tr>';
+    $js=sprintf('<a href="javascript:void(0)" 
style="text-decoration:underline" onclick="get_profile_detail(\'%s\',\'%s\')">',
+            $gDossier, $row->p_id);
+    echo '<tr>';
+    echo "<td>".$js.$row->p_name.'</a>'.'</td>';
+    echo td($row->p_desc);
+    echo td($row->with_calc);
+    echo td($row->with_direct_form);
+    echo '</tr>';
 }
-$js = sprintf('<a href="javascript:void(0)"  class="button" 
onclick="get_profile_detail(\'%s\',\'%s\')">', $gDossier, -1);
+$js=sprintf('<a href="javascript:void(0)"  class="button" 
onclick="get_profile_detail(\'%s\',\'%s\')">',
+        $gDossier, -1);
 echo '<tr>';
-echo "<td>" . $js . "Ajouter un profil </td>";
+echo "<td>".$js."Ajouter un profil </td>";
 echo '</tr>';
 echo '</table>';
 echo '</div>';
@@ -354,21 +400,23 @@ echo '</div>';
 echo '<div id="detail_profile" class="content">';
 if (isset($_POST['p_id']))
 {
-       require_once NOALYSS_INCLUDE.'/ajax_get_profile.php';
-        ?>
-<script>
+    require_once NOALYSS_INCLUDE.'/ajax_get_profile.php';
+    ?>
+    <script>
         $('list_profile').hide()
-</script>
-<?php
+    </script>
+    <?php
+
 }
 echo '</div>';
-if ( isset($_POST['delete_profil'] ))
+if (isset($_POST['delete_profil']))
 {
-       echo create_script(" $('detail_profile').hide()");
-?>
-<script>
+    echo create_script(" $('detail_profile').hide()");
+    ?>
+    <script>
         $('list_profile').show()
-</script>
-<?php
+    </script>
+    <?php
+
 }
 ?>
diff --git a/include/template/menu.php b/include/template/menu.php
index 99e3536..07e8dd3 100644
--- a/include/template/menu.php
+++ b/include/template/menu.php
@@ -2,9 +2,9 @@
 //This file is part of NOALYSS and is under GPL 
 //see licence.txt
 ?><div class="<?php echo $style_menu; ?>">
-    <?php if ( count($amenu) > 4 && $idx == 0) :
+    <?php if ( count($amenu) > 4 && $level == 0) :
        $style ='style= "width:100%"';
-     elseif ($idx==0):
+     elseif ($level==0):
 switch (count($amenu))
 {
 case 4:
@@ -28,7 +28,7 @@ $style="";
        global $g_user;
        // Display the menu
        for($i=0;$i < count($amenu);$i++):
-           if ( (count($amenu)==1)|| (isset($module[$idx+1]) && 
$module[$idx+1]==$amenu[$i]['me_code'])):
+           if ( (count($amenu)==1)):
                $class="selectedcell";
 ?>
        <td class="<?php echo $class?>">
@@ -39,12 +39,8 @@ $style="";
 <?php 
            else:
                $class="mtitle";
-           $url="";$pt="";
                $js="";
-           for ($e=0;$e <= $idx;$e++):
-                       $url.=$pt.$module[$e];
-                       $pt="/";
-           endfor;
+                
                if ( $amenu[$i]['me_url']!='')
                {
                        $url=$row['me_url'];
@@ -56,7 +52,14 @@ $style="";
                }
                else
                {
-                       $url.=$pt.$amenu[$i]['me_code'];
+                    $a_request=explode('/', $_REQUEST['ac']);
+                    if ( $level == 0) {
+                        $url=$a_request[0];
+                    } elseif ($level == 1)
+                    {
+                        $url=$a_request[0].'/'.$a_request[1];
+                    }
+                    $url.='/'.$amenu[$i]['me_code'];
                }
 
 ?>     <td class="<?php echo $class?>">
diff --git a/include/template/module.php b/include/template/module.php
index e15fbd2..7754671 100644
--- a/include/template/module.php
+++ b/include/template/module.php
@@ -66,7 +66,7 @@ endif;?>
                        continue;
                    }
                     $style="tool";
-                   if ($row['me_code']==$selected)
+                   if ($row['me_code']==$selected_module)
                    {
                        $style='toolselected';
                    }
diff --git a/include/template/profile_menu_display_module.php 
b/include/template/profile_menu_display_module.php
new file mode 100644
index 0000000..e32f419
--- /dev/null
+++ b/include/template/profile_menu_display_module.php
@@ -0,0 +1,103 @@
+<?php
+/*
+ * * Copyright (C) 2015 Dany De Bontridder <address@hidden>
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+ * 
+ */
+/**
+ * @file
+ * @brief display the module, used to setup the module and menu, included from
+ * Profile_Menu
+ */
+?>
+ <div id="module_setting">
+       <table class="result">
+           <tr>
+               <?php
+               foreach ($ap_module as $row):
+                       $js="";
+                   $style="";
+                   if ( $row['me_code']=='new_line')
+                   {
+                       echo "</tr><tr>";
+                       continue;
+                   }
+                    $style=" tool ";
+                    $url="XX";
+                   if ( $row['me_url']!='')
+                   {
+                       $url=$row['me_url'];
+                   }
+                   elseif ($row['me_javascript'] != '')
+                    {
+                        $url=$row['me_javascript'];
+                    }
+                    elseif ( $row['me_file'] != "")
+                    {
+                        $url=$row['me_file'];
+                    }
+                    else
+                   {
+                       $url=HtmlInput::anchor(_('Menu'),'',
+                                sprintf(" onclick = \" 
\$('menu_table').innerHTML='';display_sub_menu(%d,%d,%d,%d)\" ",
+                                        Dossier::id(),
+                                        $this->p_id,
+                                        $row['pm_id'],0));
+                   }
+                   ?>
+               <td class="<?php echo $style?>" id="sub<?php echo 
$row['pm_id']?>">
+                        <?php echo 
HtmlInput::anchor(gettext($row['me_menu']),'',sprintf(" onclick =\"mod_menu 
(%d,%d) \" ",Dossier::id(),$row['pm_id']),' class="line" ')?>
+                        <span>
+                            <?php echo HtmlInput::anchor(SMALLX, "", 
+                                    sprintf (" onclick = 
\"remove_sub_menu(%d,%d)\"", Dossier::id(),$row['pm_id']),
+                                    'class="tinybutton"' ) ?>
+                        </span>
+                        <p>
+                        <?php echo _($row['me_description'])?>
+                        </p>
+                        <p>
+                        <?php echo $url?>
+                        </p>
+                        <p>
+                        <?php echo _('ordre apparition') , " 
",$row['p_order'];?>
+                        <p>
+                        <?php echo _('Default')," : ",
+                                ($row['pm_default']==1)?_('Oui'):_('Non')
+                            ?>
+                        </p>
+                        
+                 </td>
+               <?php 
+                   endforeach;
+               ?>
+                 <td>
+                     <?php
+                     echo HtmlInput::button_action("+", 
+                             
sprintf("add_menu({dossier:%d,p_id:%d,type:'%s',p_level:%d,dep:0})",
+                                     Dossier::id(),$this->p_id,'me',0)
+                             ,"xx",'smallbutton')
+                     ?>
+                 </td>
+           </tr>
+       </table>
+    </div>
+
+<div id='sub_menu_div'>
+    <table id="menu_table" class="result">
+
+    </table>
+</div>
\ No newline at end of file
diff --git a/include/template/profile_menu_display_submenu.php 
b/include/template/profile_menu_display_submenu.php
new file mode 100644
index 0000000..c5ac5ff
--- /dev/null
+++ b/include/template/profile_menu_display_submenu.php
@@ -0,0 +1,79 @@
+<?php
+/*
+ * * Copyright (C) 2015 Dany De Bontridder <address@hidden>
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+ * 
+ */
+
+
+/**
+ * @file
+ * @brief  display a submenu contained in a array
+ * @parameter $a_module contains rows from profile_menu
+ * @parameter $p_module_id is the module / menu id main menu
+ * @see Profile_Menu::display_module_menu
+ */
+?>
+    <?php
+    $nb_module=count($a_module);
+    for ($i=0;$i < $nb_module ; $i ++ ):
+    ?>
+    <td id="sub<?php echo $a_module[$i]['pm_id']?>" class="tool">
+        <?php
+            if ( $a_module[$i]['me_file'] != "") {
+                $url=$a_module[$i]['me_file'];
+            } else if ( $a_module[$i]['me_url'] != "") {
+                $url=h($a_module[$i]['me_url'] );
+            } else if ($a_module[$i]['me_javascript'] != "") {
+                $url="-> javascript";
+            } else {
+                $url = HtmlInput::anchor("sous-menu", "x", 
+                        sprintf(" onclick = \" 
display_sub_menu(%d,%d,%d,%d)\"",Dossier::id(),$this->p_id,$a_module[$i]['pm_id'],$p_level),
 
+                        ' class="line" ');
+            }
+        ?>
+        <?php 
+            echo HtmlInput::anchor(gettext($a_module[$i]['me_menu']),'',
+                   sprintf(" onclick =\"mod_menu (%d,%d) \" 
",Dossier::id(),$a_module[$i]['pm_id']),
+                   ' class="line" ')?>
+        <span>
+                            <?php echo HtmlInput::anchor(SMALLX, "", 
+                                    sprintf (" onclick = 
\"remove_sub_menu(%d,%d)\"", Dossier::id(),$a_module[$i]['pm_id']),
+                                    'class="tinybutton"' ) ?>
+        </span>
+        <br/>
+        <?php echo $url;?>
+        <p>
+            <?php echo _('ordre apparition') , " ",$a_module[$i]['p_order'];?>
+        <p>
+            <?php echo _('Default')," : ",
+                    ($a_module[$i]['pm_default']==1)?_('Oui'):_('Non')
+                ?>
+        </p>
+    </td>
+    <?php
+    endfor;
+    ?>
+<td>
+                     <?php
+                     echo HtmlInput::button_action("+", 
+                             
sprintf("add_menu({dossier:%d,p_id:%d,type:'%s',p_level:%d,dep:'%s'})",
+                                     
Dossier::id(),$this->p_id,'me',$p_level,$p_module_id)
+                             ,"xx",'smallbutton')
+                     ?>
+                 
+</td>
diff --git a/include/template/profile_sec_repository.php 
b/include/template/profile_sec_repository.php
index 4ad10ba..a2c359d 100644
--- a/include/template/profile_sec_repository.php
+++ b/include/template/profile_sec_repository.php
@@ -29,7 +29,7 @@
 <form method="POST" class="print">
 <?php echo HtmlInput::hidden('tab','profile_repo_div')?>
 
-       <?php echo HtmlInput::hidden("p_id", $p_id);?>
+       <?php echo HtmlInput::hidden("p_id", $this->p_id);?>
        <table>
                <tr>
                        <th><?php echo _("Dépot")?></th>
@@ -56,4 +56,5 @@
                </tr>
                <?php endfor;?>
        </table>
+</form>
 <?php echo HtmlInput::submit("change_stock", _("Sauver"))?>
diff --git a/include/template/user_sec_profile.php 
b/include/template/user_sec_profile.php
index 18b6355..6f0d001 100644
--- a/include/template/user_sec_profile.php
+++ b/include/template/user_sec_profile.php
@@ -29,7 +29,7 @@
 ?>
 <form method="POST" class="print">
     <?php echo HtmlInput::hidden('tab','profile_gestion_div')?>
-       <?php echo HtmlInput::hidden("p_id", $p_id);?>
+       <?php echo HtmlInput::hidden("p_id", $this->p_id);?>
        <table>
                <tr>
                        <th><?php echo _("Profil")?></th>
diff --git a/sql/upgrade.sql b/sql/upgrade.sql
index 8c11283..67da775 100644
--- a/sql/upgrade.sql
+++ b/sql/upgrade.sql
@@ -1,245 +1,160 @@
-ALTER TABLE action    ALTER COLUMN ac_code TYPE character varying(30);
 
-INSERT INTO action(ac_id, ac_description, ac_module, ac_code)
-    VALUES (1110, 'Enlever une pièce justificative', 'compta', 'RMRECEIPT');
-INSERT INTO action(ac_id, ac_description, ac_module, ac_code)
-    VALUES (1120, 'Effacer une opération ', 'compta', 'RMOPER');
-INSERT INTO action(ac_id, ac_description, ac_module, ac_code)
-    VALUES (1210, 'Partager une note', 'note', 'SHARENOTE');
-INSERT INTO action(ac_id, ac_description, ac_module, ac_code)
-    VALUES (1220, 'Créer une note publique', 'note', 'SHARENOTEPUBLIC');
-INSERT INTO action(ac_id, ac_description, ac_module, ac_code)
-    VALUES (1230, 'Effacer une note publique', 'note', 'SHARENOTEREMOVE');
-
-
-CREATE TABLE todo_list_shared (id  serial primary key, todo_list_id int4 NOT 
NULL, use_login text NOT NULL, CONSTRAINT unique_todo_list_id_login 
-    UNIQUE (todo_list_id, use_login));
-
-ALTER TABLE todo_list_shared ADD CONSTRAINT fk_todo_list_shared_todo_list 
FOREIGN KEY (todo_list_id) REFERENCES todo_list (tl_id);
-
-comment on table todo_list_shared is 'Note of todo list shared with other 
users';
-comment on column todo_list_shared.todo_list_id is 'fk to todo_list';
-comment on column todo_list_shared.use_login is 'user login';
-
-alter table todo_list add is_public char(1) default 'N';
-comment on column todo_list.is_public is 'Flag for the public parameter';
-ALTER TABLE todo_list    ALTER COLUMN is_public SET NOT NULL;
-
-ALTER TABLE todo_list ADD CONSTRAINT ck_is_public CHECK (is_public in 
('Y','N'));
-
-/**
-Arbre dépendance
- with recursive t (ag_id,ag_ref_ag_id,ag_title,depth) as (
-  select 
-    ag_id , ag_ref_ag_id, ag_title , 1
-  from 
-    action_gestion
-  where ag_id=55
-  union all
-  select 
-    p2.ag_id,p2.ag_ref_ag_id,p2.ag_title,depth + 1
-  from 
-    t as p1, action_gestion as p2
-  where
-    p1.ag_ref_ag_id is not null and
-    p1.ag_id = p2.ag_ref_ag_id
-) select * from t;
-
-*/
--- update menu_ref set me_menu = me_menu||' <span 
id="menu_'||lower(me_code)||'"><img src="image/empty.gif"></span>' where 
me_type='ME';
-update menu_ref set me_menu = 'Favori &#9733; ' where me_code='BOOKMARK';
-update menu_ref set me_menu = 'Sortie &#9094;' where me_code='LOGOUT'; 
-
-insert into menu_ref(me_code,me_menu,me_file, 
me_url,me_description,me_parameter,me_javascript,me_type,me_description_etendue)
-values
-('BALAGE','Balance agée','balance_age.inc.php',null,'Balance 
agée',null,null,'ME','Balance agée pour les clients et fournisseurs') ,
-('CSV:balance_age','Export Balance 
agée','export_balance_age_csv.php',null,'Balance agée',null,null,'PR','Balance 
agée pour les clients et fournisseurs') 
-
-;
-
-insert into profile_menu (me_code,me_code_dep,p_id,p_order, 
p_type_display,pm_default) 
-values
-('BALAGE','PRINT',1,550,'E',0),('BALAGE','PRINT',2,550,'E',0),
-('CSV:balance_age',null,1,null,'P',0),('CSV:balance_age',null,2,null,'P',0)
-;
-
-
-/*
-with m as (
-    select jr_id,jr_grpt_id,
-            coalesce(jr_ech,jr_date) as op_date ,
-            jr_date_paid from jrn 
-    where jr_date_paid is not null
-),n as (
-    select jr_id ,jr_date_paid - op_date    as 
delta,jr_grpt_id,jr_date_paid,op_date
-    from m 
-    where 
-    jr_date_paid  - op_date < 30 
-    ),solde as (
-select sum(qp_price+qp_vat+qp_nd_amount+qp_nd_tva+qp_nd_tva_recup - 
qp_vat_sided), 
-    qp_supplier 
-from quant_purchase 
-    join jrnx using (j_id) 
-    join n on (j_grpt=n.jr_grpt_id) 
-group by qp_supplier)
-select * , 
-    (select vw_name from vw_fiche_attr where f_id=qp_supplier) ,
-    (select vw_first_name from vw_fiche_attr where f_id=qp_supplier) ,
-(select quick_code from vw_fiche_attr where f_id=qp_supplier) 
-from solde
-;
-*/
-/*
-CREATE TABLE tmp_bal_aged (
-  id         SERIAL NOT NULL, 
-  create_on timestamp default now(), 
-  PRIMARY KEY (id));
-COMMENT ON TABLE tmp_bal_aged IS 'Table temporaire pour le calcul des balances 
agées';
-
-CREATE TABLE tmp_bal_aged_child (
-  tmp_bal_agedid bigint NOT NULL, 
-  id              SERIAL NOT NULL, 
-  f_id           bigint NOT NULL, 
-  amount         numeric(20,4) NOT NULL, 
-  amount30       numeric(20,4)  NOT NULL, 
-  amount60       numeric(20,4) NOT NULL, 
-  amount90       numeric(20,4) NOT NULL, 
-  PRIMARY KEY (id));
-COMMENT ON TABLE tmp_bal_aged_child IS 'Table temporaire pour le calcul des 
balances agées';
-*/
-
-
-CREATE OR REPLACE FUNCTION comptaproc.account_compute(p_f_id integer)
-  RETURNS account_type AS
+alter table profile_menu add pm_id_dep bigint ;
+comment on column profile_menu.pm_id_dep is 'parent of this menu item';
+
+
+CREATE OR REPLACE VIEW v_menu_dependency AS 
+ WITH t_menu AS (
+         SELECT pm.pm_id, mr.me_menu, pm.me_code, pm.me_code_dep, 
pm.p_type_display, mr.me_file, mr.me_javascript, mr.me_description, 
mr.me_description_etendue, p.p_id
+           FROM profile_menu pm
+      JOIN profile p ON p.p_id = pm.p_id
+   JOIN menu_ref mr USING (me_code)
+        )
+ SELECT DISTINCT (COALESCE(v3.me_code || '/'::text, ''::text) || 
COALESCE(v2.me_code, ''::text)) || 
+        CASE
+            WHEN v2.me_code IS NULL THEN COALESCE(v1.me_code, ''::text)
+            WHEN v2.me_code IS NOT NULL THEN COALESCE('/'::text || v1.me_code, 
''::text)
+            ELSE NULL::text
+        END AS code, v1.pm_id, v1.me_code, v1.me_description, 
v1.me_description_etendue, v1.me_file, '> '::text || v1.me_menu AS v1menu, 
+        CASE
+            WHEN v2.pm_id IS NOT NULL THEN v2.pm_id
+            WHEN v3.pm_id IS NOT NULL THEN v3.pm_id
+            ELSE NULL::integer
+        END AS higher_dep, 
+        CASE
+            WHEN COALESCE(v3.me_menu, ''::text) <> ''::text THEN ' > '::text 
|| v2.me_menu
+            ELSE v2.me_menu
+        END AS v2menu, v3.me_menu AS v3menu, v3.p_type_display, 
COALESCE(v1.me_javascript, COALESCE(v2.me_javascript, v3.me_javascript)) AS 
javascript, v1.p_id, v2.p_id AS v2pid, v3.p_id AS v3pid
+   FROM t_menu v1
+   LEFT JOIN t_menu v2 ON v1.me_code_dep = v2.me_code
+   LEFT JOIN t_menu v3 ON v2.me_code_dep = v3.me_code
+  WHERE COALESCE(v2.p_id, v1.p_id) = v1.p_id AND COALESCE(v3.p_id, v1.p_id) = 
v1.p_id AND v1.p_type_display <> 'P'::text
+  ORDER BY v1.pm_id;
+
+CREATE OR REPLACE FUNCTION modify_menu_system(n_profile numeric)
+  RETURNS void AS
 $BODY$
-declare
-       class_base fiche_def.fd_class_base%type;
-       maxcode numeric;
-       sResult text;
-       bAlphanum bool;
-       sName text;
-begin
-       select fd_class_base into class_base
-       from
-               fiche_def join fiche using (fd_id)
-       where
-               f_id=p_f_id;
-       raise notice 'account_compute class base %',class_base;
-       bAlphanum := account_alphanum();
-       if bAlphanum = false  then
-       raise info 'account_compute : Alphanum is false';
-               select count (pcm_val) into maxcode from tmp_pcmn where 
pcm_val_parent = class_base;
-               if maxcode = 0  then
-                       maxcode:=class_base::numeric;
-               else
-                       select max (pcm_val) into maxcode from tmp_pcmn where 
pcm_val_parent = class_base;
-                       maxcode:=maxcode::numeric;
-               end if;
-               if maxcode::text = class_base then
-                       maxcode:=class_base::numeric*1000;
-               end if;
-               maxcode:=maxcode+1;
-               raise notice 'account_compute Max code %',maxcode;
-               sResult:=maxcode::account_type;
-       else
-       raise info 'account_compute : Alphanum is true';
-               -- if alphanum, use name
-               select ad_value into sName from fiche_detail where f_id=p_f_id 
and ad_id=1;
-               raise info 'name is %',sName;
-               if sName is null then
-                       raise exception 'Cannot compute an accounting without 
the name of the card for %',p_f_id;
-               end if;
-               sResult := class_base||sName;
-               sResult := substr(sResult,1,40);
-               raise info 'Result is %',sResult;
-       end if;
-       return sResult::account_type;
-end;
-$BODY$ 
-LANGUAGE plpgsql ;
+declare 
+r_duplicate profile_menu%ROWTYPE;
+str_duplicate text;
+n_lowest_id numeric; -- lowest pm_id : update the dependency in profile_menu
+n_highest_id numeric; -- highest pm_id insert into profile_menu
 
-CREATE OR REPLACE FUNCTION comptaproc.account_insert(p_f_id integer, p_account 
text)
-  RETURNS text AS
-$BODY$
-declare
-       nParent tmp_pcmn.pcm_val_parent%type;
-       sName varchar;
-       sNew tmp_pcmn.pcm_val%type;
-       bAuto bool;
-       nFd_id integer;
-       sClass_Base fiche_def.fd_class_base%TYPE;
-       nCount integer;
-       first text;
-       second text;
-       s_account text;
 begin
 
-       if p_account is not null and length(trim(p_account)) != 0 then
-       -- if there is coma in p_account, treat normally
-               if position (',' in p_account) = 0 then
-                       raise info 'p_account is not empty';
-                               s_account := substr( p_account,1 , 40);
-                               select count(*)  into nCount from tmp_pcmn 
where pcm_val=s_account::account_type;
-                               raise notice 'found in tmp_pcm %',nCount;
-                               if nCount !=0  then
-                                       raise info 'this account exists in 
tmp_pcmn ';
-                                       perform 
attribut_insert(p_f_id,5,s_account);
-                                  else
-                                      -- account doesn't exist, create it
-                                       select ad_value into sName from
-                                               fiche_detail
-                                       where
-                                       ad_id=1 and f_id=p_f_id;
-
-                                       
nParent:=account_parent(s_account::account_type);
-                                       insert into 
tmp_pcmn(pcm_val,pcm_lib,pcm_val_parent) values 
(s_account::account_type,sName,nParent);
-                                       perform 
attribut_insert(p_f_id,5,s_account);
-
-                               end if;
-               else
-               raise info 'presence of a comma';
-               -- there is 2 accounts separated by a comma
-               first := split_part(p_account,',',1);
-               second := split_part(p_account,',',2);
-               -- check there is no other coma
-               raise info 'first value % second value %', first, second;
-
-               if  position (',' in first) != 0 or position (',' in second) != 
0 then
-                       raise exception 'Too many comas, invalid account';
-               end if;
-               perform attribut_insert(p_f_id,5,p_account);
-               end if;
-       else
-       raise info 'A000 : p_account is  empty';
-               select fd_id into nFd_id from fiche where f_id=p_f_id;
-               bAuto:= account_auto(nFd_id);
-
-               select fd_class_base into sClass_base from fiche_def where 
fd_id=nFd_id;
-raise info 'sClass_Base : %',sClass_base;
-               if bAuto = true and sClass_base similar to '[[:digit:]]*'  then
-                       raise info 'account generated automatically';
-                       sNew:=account_compute(p_f_id);
-                       raise info 'sNew %', sNew;
-                       select ad_value into sName from
-                               fiche_detail
-                       where
-                               ad_id=1 and f_id=p_f_id;
-                       nParent:=account_parent(sNew);
-                       sNew := account_add  (sNew,sName);
-                       perform attribut_insert(p_f_id,5,sNew);
-
-               else
-               -- if there is an account_base then it is the default
-                     select fd_class_base::account_type into sNew from 
fiche_def join fiche using (fd_id) where f_id=p_f_id;
-                       if sNew is null or length(trim(sNew)) = 0 then
-                               raise notice 'count is null';
-                                perform attribut_insert(p_f_id,5,null);
-                       else
-                                perform attribut_insert(p_f_id,5,sNew);
-                       end if;
-               end if;
-       end if;
-
-return 0;
+for str_duplicate in   
+       select me_code 
+       from profile_menu 
+       where 
+       p_id=n_profile and 
+       p_type_display <> 'P' and
+       pm_id_dep is null
+       group by me_code 
+       having count(*) > 1 
+loop
+       raise info 'str_duplicate %',str_duplicate;
+       for r_duplicate in select * 
+               from profile_menu 
+               where 
+               p_id=n_profile and
+               me_code_dep=str_duplicate
+       loop
+               raise info 'r_duplicate %',r_duplicate;
+               -- get the lowest 
+               select a.pm_id into n_lowest_id from profile_menu a join 
profile_menu b on (a.me_code=b.me_code and a.p_id = b.p_id)
+               where
+               a.me_code=str_duplicate
+               and a.p_id=n_profile
+               and a.pm_id < b.pm_id;
+               raise info 'lowest is %',n_lowest_id;
+               -- get the highest
+               select a.pm_id into n_highest_id from profile_menu a join 
profile_menu b on (a.me_code=b.me_code and a.p_id = b.p_id)
+               where
+               a.me_code=str_duplicate
+               and a.p_id=n_profile
+               and a.pm_id > b.pm_id;
+               raise info 'highest is %',n_highest_id;
+
+               -- update the first one
+               update profile_menu set pm_id_dep = n_lowest_id where 
pm_id=r_duplicate.pm_id;
+               -- insert a new one
+               insert into profile_menu (me_code,
+                       me_code_dep,
+                       p_id,
+                       p_order,
+                       p_type_display,
+                       pm_default,
+                       pm_id_dep)
+               values (r_duplicate.me_code,
+                       r_duplicate.me_code_dep,
+                       r_duplicate.p_id,
+                       r_duplicate.p_order,
+                       r_duplicate.p_type_display,
+                       r_duplicate.pm_default,
+                       n_highest_id);
+               
+       end loop;       
+
+end loop;      
 end;
-$BODY$  LANGUAGE plpgsql ;
+$BODY$
+language plpgsql;
+
+select modify_menu_system(1);
+select modify_menu_system(2);
+
+update profile_menu set pm_id_dep=(select higher_dep from v_menu_dependency as 
a where
+ a.pm_id= profile_menu.pm_id) where pm_id_dep is null and p_id=1;
+
+update profile_menu set pm_id_dep=(select higher_dep from v_menu_dependency as 
a where
+ a.pm_id= profile_menu.pm_id) where pm_id_dep is null and p_id=2;
+CREATE OR REPLACE VIEW v_menu_profile AS 
+ WITH t_menu AS (
+         SELECT pm.pm_id,pm.pm_id_dep, pm.me_code, pm.me_code_dep, 
pm.p_type_display,pm.p_id
+           FROM profile_menu pm
+   JOIN profile p ON p.p_id = pm.p_id
+   )
+ SELECT DISTINCT 
+       (COALESCE(v3.me_code || '/'::text, ''::text) || COALESCE(v2.me_code, 
''::text)) || 
+        CASE
+            WHEN v2.me_code IS NULL THEN COALESCE(v1.me_code, ''::text)
+            WHEN v2.me_code IS NOT NULL THEN COALESCE('/'::text || v1.me_code, 
''::text)
+            ELSE NULL::text
+        END AS code, 
+        v3.p_type_display,
+        coalesce(v3.pm_id,0) as pm_id_v3,
+       coalesce(v2.pm_id,0) as pm_id_v2,
+        v1.pm_id as pm_id_v1
+        ,v1.p_id
+   FROM t_menu v1
+   LEFT JOIN t_menu v2 ON v1.pm_id_dep = v2.pm_id
+   LEFT JOIN t_menu v3 ON v2.pm_id_dep= v3.pm_id
+  WHERE v1.p_type_display <> 'P'::text 
+;
+COMMENT ON VIEW v_menu_profile  IS 'Give the profile and the menu + 
dependencies';
+
+CREATE OR REPLACE VIEW v_menu_description AS 
+ WITH t_menu AS (
+         SELECT pm.pm_id,pm.pm_id_dep,pm.p_id,mr.me_menu, pm.me_code, 
pm.me_code_dep, pm.p_type_display, pu.user_name, mr.me_file, mr.me_javascript, 
mr.me_description, mr.me_description_etendue
+           FROM profile_menu pm
+      JOIN profile_user pu ON pu.p_id = pm.p_id
+   JOIN profile p ON p.p_id = pm.p_id
+   JOIN menu_ref mr USING (me_code)
+        )
+ SELECT DISTINCT (COALESCE(v3.me_code || '/'::text, ''::text) || 
COALESCE(v2.me_code, ''::text)) || 
+        CASE
+            WHEN v2.me_code IS NULL THEN COALESCE(v1.me_code, ''::text)
+            WHEN v2.me_code IS NOT NULL THEN COALESCE('/'::text || v1.me_code, 
''::text)
+            ELSE NULL::text
+        END AS code, v1.me_code, v1.me_description, v1.me_description_etendue, 
v1.me_file, v1.user_name, '> '::text || v1.me_menu AS v1menu, 
+        CASE
+            WHEN COALESCE(v3.me_menu, ''::text) <> ''::text THEN ' > '::text 
|| v2.me_menu
+            ELSE v2.me_menu
+        END AS v2menu, v3.me_menu AS v3menu, v3.p_type_display, 
COALESCE(v1.me_javascript, COALESCE(v2.me_javascript, v3.me_javascript)) AS 
javascript,
+        v1.pm_id,v1.pm_id_dep,v1.p_id
+   FROM t_menu v1
+   LEFT JOIN t_menu v2 ON v1.me_code_dep = v2.me_code
+   LEFT JOIN t_menu v3 ON v2.me_code_dep = v3.me_code
+  WHERE v1.p_type_display <> 'P'::text AND (COALESCE(v1.me_file, ''::text) <> 
''::text OR COALESCE(v1.me_javascript, ''::text) <> ''::text);
+
+COMMENT ON VIEW v_menu_description  IS 'Description des menus';



reply via email to

[Prev in Thread] Current Thread [Next in Thread]