Merge remote branch 'origin/xorg/maint' into xorg/master
[platal.git] / modules / fusionax.php
index 848bc27..b30fcb4 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /***************************************************************************
- *  Copyright (C) 2003-2010 Polytechnique.org                              *
+ *  Copyright (C) 2003-2011 Polytechnique.org                              *
  *  http://opensource.polytechnique.org/                                   *
  *                                                                         *
  *  This program is free software; you can redistribute it and/or modify   *
@@ -35,26 +35,28 @@ class FusionAxModule extends PLModule
     {
         if (Platal::globals()->merge->state == 'pending') {
             return array(
-                'fusionax'                  => $this->make_hook('index',    AUTH_MDP, 'admin'),
-                'fusionax/import'           => $this->make_hook('import',   AUTH_MDP, 'admin'),
-                'fusionax/view'             => $this->make_hook('view',     AUTH_MDP, 'admin'),
-                'fusionax/ids'              => $this->make_hook('ids',      AUTH_MDP, 'admin'),
-                'fusionax/deceased'         => $this->make_hook('deceased', AUTH_MDP, 'admin'),
-                'fusionax/promo'            => $this->make_hook('promo',    AUTH_MDP, 'admin'),
-                'fusionax/names'            => $this->make_hook('names',    AUTH_MDP, 'admin')
+                'fusionax'                  => $this->make_hook('index',    AUTH_PASSWD, 'admin'),
+                'fusionax/import'           => $this->make_hook('import',   AUTH_PASSWD, 'admin'),
+                'fusionax/view'             => $this->make_hook('view',     AUTH_PASSWD, 'admin'),
+                'fusionax/ids'              => $this->make_hook('ids',      AUTH_PASSWD, 'admin'),
+                'fusionax/deceased'         => $this->make_hook('deceased', AUTH_PASSWD, 'admin'),
+                'fusionax/promo'            => $this->make_hook('promo',    AUTH_PASSWD, 'admin'),
+                'fusionax/names'            => $this->make_hook('names',    AUTH_PASSWD, 'admin'),
+                'fusionax/edu'              => $this->make_hook('edu',      AUTH_PASSWD, 'admin'),
+                'fusionax/corps'            => $this->make_hook('corps',    AUTH_PASSWD, 'admin')
             );
         } elseif (Platal::globals()->merge->state == 'done') {
             return array(
-                'fusionax'                  => $this->make_hook('index',            AUTH_MDP, 'admin,edit_directory'),
-                'fusionax/issues'           => $this->make_hook('issues',           AUTH_MDP, 'admin,edit_directory'),
-                'fusionax/issues/deathdate' => $this->make_hook('issues_deathdate', AUTH_MDP, 'admin,edit_directory'),
-                'fusionax/issues/promo'     => $this->make_hook('issues_promo',     AUTH_MDP, 'admin,edit_directory'),
+                'fusionax'                  => $this->make_hook('index',            AUTH_PASSWD, 'admin,edit_directory'),
+                'fusionax/issues'           => $this->make_hook('issues',           AUTH_PASSWD, 'admin,edit_directory'),
+                'fusionax/issues/deathdate' => $this->make_hook('issues_deathdate', AUTH_PASSWD, 'admin,edit_directory'),
+                'fusionax/issues/promo'     => $this->make_hook('issues_promo',     AUTH_PASSWD, 'admin,edit_directory'),
             );
         }
     }
 
 
-    function handler_index(&$page)
+    function handler_index($page)
     {
         if (Platal::globals()->merge->state == 'pending') {
             $page->changeTpl('fusionax/index.tpl');
@@ -85,7 +87,7 @@ class FusionAxModule extends PLModule
     }
 
     /** Import de l'annuaire de l'AX depuis l'export situé dans le home de jacou */
-    function handler_import(&$page, $action = 'index', $file = '')
+    function handler_import($page, $action = 'index', $file = '')
     {
         if ($action == 'index') {
             $page->changeTpl('fusionax/import.tpl');
@@ -109,17 +111,17 @@ class FusionAxModule extends PLModule
             } else {
                 // séparation de l'archive en fichiers par tables
                 $file = $spoolpath . $file;
-                // Removes master and doctorate students
-                exec('grep -v "^[A-Z]\{2\}.[0-9]\{4\}[MD][0-9]\{3\}" ' . $file . ' > ' . $file . '.tmp');
-                exec('mv -f ' . $file . '.tmp ' . $file);
                 // Split export into specialised files
                 exec('grep "^AD" ' . $file . ' > ' . $spoolpath . 'Adresses.txt');
                 exec('grep "^AN" ' . $file . ' > ' . $spoolpath . 'Anciens.txt');
+                exec('grep "^FO.[0-9]\{4\}[MD][0-9]\{3\}.Etudiant" ' . $file . ' > ' . $spoolpath . 'Formations_MD.txt');
+                exec('grep "^FO.[0-9]\{4\}[MD][0-9]\{3\}.Doct. de" ' . $file . ' >> ' . $spoolpath . 'Formations_MD.txt');
                 exec('grep "^FO" ' . $file . ' > ' . $spoolpath . 'Formations.txt');
                 exec('grep "^AC" ' . $file . ' > ' . $spoolpath . 'Activites.txt');
                 exec('grep "^EN" ' . $file . ' > ' . $spoolpath . 'Entreprises.txt');
                 exec($modulepath . 'formation.pl');
                 exec('mv -f ' . $spoolpath . 'Formations_out.txt ' . $spoolpath . 'Formations.txt');
+                exec('mv -f ' . $spoolpath . 'Formations_MD_out.txt ' . $spoolpath . 'Formations_MD.txt');
                 $report[] = 'Fichier parsé.';
                 $report[] = 'Import dans la base en cours...';
                 $next = 'integrateSQL';
@@ -132,7 +134,8 @@ class FusionAxModule extends PLModule
                 1 => 'Adresses.sql',
                 2 => 'Anciens.sql',
                 3 => 'Formations.sql',
-                4 => 'Entreprises.sql'
+                4 => 'Entreprises.sql',
+                5 => 'Formations_MD.sql'
             );
             if ($file != '') {
                 // récupère le contenu du fichier sql
@@ -155,7 +158,7 @@ class FusionAxModule extends PLModule
             } else {
                 $nextfile = 0;
             }
-            if ($nextfile > 4) {
+            if ($nextfile > 5) {
                 // tous les fichiers ont été exécutés, on passe à l'étape suivante
                 $next = 'adds1920';
             } else {
@@ -169,8 +172,6 @@ class FusionAxModule extends PLModule
                                     FROM  fusionax_anciens
                                    WHERE  promotion_etude = 1920;');
 
-            $nameTypes = DirEnum::getOptions(DirEnum::NAMETYPES);
-            $nameTypes = array_flip($nameTypes);
             $eduSchools = DirEnum::getOptions(DirEnum::EDUSCHOOLS);
             $eduSchools = array_flip($eduSchools);
             $eduDegrees = DirEnum::getOptions(DirEnum::EDUDEGREES);
@@ -198,29 +199,26 @@ class FusionAxModule extends PLModule
                 $directoryName = $lastname . ' ' . $firstname;
                 ++$xorgId;
 
-                XDB::execute('REPLACE INTO  profiles (hrpid, xorg_id, ax_id, sex)
-                                    VALUES  ({?}, {?}, {?}, {?})',
+                XDB::execute('INSERT INTO  profiles (hrpid, xorg_id, ax_id, sex)
+                                   VALUES  ({?}, {?}, {?}, {?})',
                              $hrid, $xorgId, $ax_id, $sex);
                 $pid = XDB::insertId();
-                XDB::execute('REPLACE INTO  profile_name (pid, name, typeid)
-                                    VALUES  ({?}, {?}, {?})',
-                             $pid, $lastname, $nameTypes['name_ini']);
-                XDB::execute('REPLACE INTO  profile_name (pid, name, typeid)
-                                    VALUES  ({?}, {?}, {?})',
-                             $pid, $firstname, $nameTypes['firstname_ini']);
-                XDB::execute('REPLACE INTO  profile_display (pid, yourself, public_name, private_name,
-                                                             directory_name, short_name, sort_name, promo)
-                                    VALUES  ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})',
+                XDB::execute('INSERT INTO  profile_public_names (pid, lastname_initial, firstname_initial)
+                                   VALUES  ({?}, {?}, {?})',
+                             $pid, $lastname, $firstname);
+                XDB::execute('INSERT INTO  profile_display (pid, yourself, public_name, private_name,
+                                                            directory_name, short_name, sort_name, promo)
+                                   VALUES  ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})',
                              $pid, $firstname, $fullName, $fullName, $directoryName, $fullName, $directoryName, $promo);
-                XDB::execute('REPLACE INTO  profile_education (pid, eduid, degreeid, entry_year, grad_year, flags)
-                                    VALUES  ({?}, {?}, {?}, {?}, {?}, {?})',
+                XDB::execute('INSERT INTO  profile_education (pid, eduid, degreeid, entry_year, grad_year, flags)
+                                   VALUES  ({?}, {?}, {?}, {?}, {?}, {?})',
                              $pid, $eduSchools[Profile::EDU_X], $degreeid, $entry_year, $grad_year, 'primary');
-                XDB::execute('REPLACE INTO  accounts (hruid, type, is_admin, state, full_name, directory_name, display_name, sex)
-                                    VALUES  ({?}, {?}, {?}, {?}, {?}, {?}, {?})',
-                             $hrid, $type, 0, 'active', $fullName, $directoryName, $lastname, $sex);
+                XDB::execute('INSERT INTO  accounts (hruid, type, is_admin, state, full_name, directory_name, display_name, lastname, firstname, sex)
+                                   VALUES  ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})',
+                             $hrid, $type, 0, 'active', $fullName, $directoryName, $firstname, $lastname, $firstname, $sex);
                 $uid = XDB::insertId();
-                XDB::execute('REPLACE INTO  account_profiles (uid, pid, perms)
-                                    VALUES  ({?}, {?}, {?})',
+                XDB::execute('INSERT INTO  account_profiles (uid, pid, perms)
+                                   VALUES  ({?}, {?}, {?})',
                              $uid, $pid, 'owner');
             }
             $report[] = 'Promo 1920 ajoutée.';
@@ -230,11 +228,11 @@ class FusionAxModule extends PLModule
                                                           SELECT  p.pid, p.ax_id, pd.promo, pd.private_name, pd.public_name,
                                                                   pd.sort_name, pd.short_name, pd.directory_name
                                                             FROM  profiles        AS p
-                                                      INNER JOIN  profile_display AS pd USING(pid)');
+                                                      INNER JOIN  profile_display AS pd ON (pd.pid = p.pid)');
             $next = 'clean';
         } elseif ($action == 'clean') {
             // nettoyage du fichier temporaire
-            exec('rm -Rf ' . $spoolpath);
+            //exec('rm -Rf ' . $spoolpath);
             $report[] = 'Import finit.';
         }
         foreach($report as $t) {
@@ -249,17 +247,17 @@ class FusionAxModule extends PLModule
         exit;
     }
 
-    function handler_view(&$page, $action = '')
+    function handler_view($page, $action = '')
     {
         $page->changeTpl('fusionax/view.tpl');
         if ($action == 'create') {
             XDB::execute('DROP VIEW IF EXISTS fusionax_deceased');
-            XDB::execute('CREATE VIEW  fusionax_deceased AS
+            XDB::execute("CREATE VIEW  fusionax_deceased AS
                                SELECT  p.pid, a.ax_id, pd.private_name, pd.promo, p.deathdate AS deces_xorg, a.Date_deces AS deces_ax
                                  FROM  profiles         AS p
                            INNER JOIN  profile_display  AS pd ON (p.pid = pd.pid)
                            INNER JOIN  fusionax_anciens AS a ON (a.ax_id = p.ax_id)
-                                WHERE  p.deathdate != a.Date_deces');
+                                WHERE  p.deathdate != a.Date_deces OR (p.deathdate IS NULL AND a.Date_deces != '0000-00-00')");
             XDB::execute('DROP VIEW IF EXISTS fusionax_promo');
             XDB::execute('CREATE VIEW  fusionax_promo AS
                                SELECT  p.pid, p.ax_id, pd.private_name, pd.promo, pe.entry_year AS promo_etude_xorg,
@@ -287,7 +285,7 @@ class FusionAxModule extends PLModule
     }
 
     /* Cherche les les anciens présents dans Xorg avec un matricule_ax ne correspondant à rien dans la base de l'AX
-     * (mises à part les promo 1921 et 1923 qui ne figurent pas dans les données de l'AX)*/
+     * (mises à part les promo 1921, 1923, 1924, 1925 qui ne figurent pas dans les données de l'AX)*/
     private static function find_wrong_in_xorg($limit = 10)
     {
         return XDB::iterator('SELECT  u.promo, u.pid, u.private_name
@@ -295,7 +293,7 @@ class FusionAxModule extends PLModule
                                WHERE  NOT EXISTS (SELECT  *
                                                     FROM  fusionax_anciens AS f
                                                    WHERE  f.ax_id = u.ax_id)
-                                      AND u.ax_id IS NOT NULL AND promo != \'X1921\' AND promo != \'X1923\'');
+                                      AND u.ax_id IS NOT NULL AND promo NOT IN (\'X1921\', \'X1923\', \'X1924\', \'X1925\')');
     }
 
     /** Lier les identifiants d'un ancien dans les deux annuaires
@@ -330,12 +328,12 @@ class FusionAxModule extends PLModule
     {
         $easy_to_link = XDB::iterator("
         SELECT  u.private_name, u.promo, u.pid, ax.ax_id,
-                CONCAT(ax.prenom, ' ', ax.nom_complet, ' (X', ax.promotion_etude, ')') AS display_name_ax,
+                CONCAT(ax.prenom, ' ', ax.nom_complet, ' (', ax.groupe_promo, ax.promotion_etude, ')') AS display_name_ax,
                 COUNT(*) AS nbMatches
           FROM  fusionax_anciens      AS ax
     INNER JOIN  fusionax_import       AS i ON (i.ax_id = ax.ax_id AND i.pid IS NULL)
      LEFT JOIN  fusionax_xorg_anciens AS u ON (u.ax_id IS NULL
-                                               AND u.promo = CONCAT('X', ax.promotion_etude)
+                                               AND u.promo = CONCAT(ax.groupe_promo, ax.promotion_etude)
                                                AND (CONCAT(ax.prenom, ' ', ax.nom_complet) = u.private_name
                                                     OR CONCAT(ax.prenom, ' ', ax.nom_complet) = u.public_name
                                                     OR CONCAT(ax.prenom, ' ', ax.nom_complet) = u.short_name))
@@ -346,7 +344,7 @@ class FusionAxModule extends PLModule
         }
         return XDB::iterator("
         SELECT  u.private_name, u.promo, u.pid, ax.ax_id,
-                CONCAT(ax.prenom, ' ', ax.nom_complet, ' (X', ax.promotion_etude, ')') AS display_name_ax,
+                CONCAT(ax.prenom, ' ', ax.nom_complet, ' (', ax.groupe_promo, ax.promotion_etude, ')') AS display_name_ax,
                 COUNT(*) AS nbMatches
           FROM  fusionax_anciens      AS ax
     INNER JOIN  fusionax_import       AS i ON (i.ax_id = ax.ax_id AND i.pid IS NULL)
@@ -354,14 +352,14 @@ class FusionAxModule extends PLModule
                                                AND (CONCAT(ax.prenom, ' ', ax.nom_complet) = u.private_name
                                                     OR CONCAT(ax.prenom, ' ', ax.nom_complet) = u.public_name
                                                     OR CONCAT(ax.prenom, ' ', ax.nom_complet) = u.short_name)
-                                               AND u.promo < CONCAT('X', ax.promotion_etude + 2)
-                                               AND u.promo > CONCAT('X', ax.promotion_etude - 2))
+                                               AND u.promo < CONCAT(ax.groupe_promo, ax.promotion_etude + 2)
+                                               AND u.promo > CONCAT(ax.groupe_promo, ax.promotion_etude - 2))
       GROUP BY  u.pid
         HAVING  u.pid IS NOT NULL AND nbMatches = 1" . ($limit ? (' LIMIT ' . $limit) : ''));
     }
 
     /** Module de mise en correspondance les ids */
-    function handler_ids(&$page, $part = 'main', $pid = null, $ax_id = null)
+    function handler_ids($page, $part = 'main', $pid = null, $ax_id = null)
     {
         $nbToLink = 100;
         $page->assign('xorg_title', 'Polytechnique.org - Fusion - Mise en correspondance simple');
@@ -371,7 +369,8 @@ class FusionAxModule extends PLModule
             $page->changeTpl('fusionax/idsMissingInAx.tpl');
             $missingInAX = XDB::iterator('SELECT  promo, pid, private_name
                                             FROM  fusionax_xorg_anciens
-                                           WHERE  ax_id IS NULL');
+                                           WHERE  ax_id IS NULL
+                                        ORDER BY  promo');
             $page->assign('missingInAX', $missingInAX);
             return;
         }
@@ -379,10 +378,11 @@ class FusionAxModule extends PLModule
             // locate all persons from AX's database that are not here
             $page->changeTpl('fusionax/idsMissingInXorg.tpl');
             $missingInXorg = XDB::iterator("SELECT  CONCAT(a.prenom, ' ', a.Nom_usuel) AS private_name,
-                                                    a.promotion_etude AS promo, a.ax_id
+                                                    CONCAT(a.groupe_promo, a.promotion_etude) AS promo, a.ax_id
                                               FROM  fusionax_import
                                         INNER JOIN  fusionax_anciens AS a USING (ax_id)
-                                             WHERE  fusionax_import.pid IS NULL");
+                                             WHERE  fusionax_import.pid IS NULL
+                                          ORDER BY  promo");
             $page->assign('missingInXorg', $missingInXorg);
             return;
         }
@@ -448,12 +448,12 @@ class FusionAxModule extends PLModule
         }
     }
 
-    function handler_deceased(&$page, $action = '')
+    function handler_deceased($page, $action = '')
     {
         if ($action == 'updateXorg') {
             XDB::execute('UPDATE  fusionax_deceased
                              SET  deces_xorg = deces_ax
-                           WHERE  deces_xorg = "0000-00-00"');
+                           WHERE  deces_xorg IS NULL');
         }
         if ($action == 'updateAX') {
             XDB::execute('UPDATE  fusionax_deceased
@@ -474,7 +474,7 @@ class FusionAxModule extends PLModule
         $page->assign('deceasedErrors', $deceasedErrorsSql->fetchOneCell());
         $res = XDB::iterator('SELECT  pid, ax_id, promo, private_name, deces_ax
                                 FROM  fusionax_deceased
-                               WHERE  deces_xorg = "0000-00-00"
+                               WHERE  deces_xorg IS NULL
                                LIMIT  10');
         $page->assign('nbDeceasedMissingInXorg', $res->total());
         $page->assign('deceasedMissingInXorg', $res);
@@ -491,7 +491,7 @@ class FusionAxModule extends PLModule
         $page->assign('deceasedDifferent', $res);
     }
 
-    function handler_promo(&$page, $action = '')
+    function handler_promo($page, $action = '')
     {
         $page->changeTpl('fusionax/promo.tpl');
         $res = XDB::iterator('SELECT  pid, private_name, promo_etude_xorg, promo_sortie_xorg, promo_etude_ax, promo
@@ -531,7 +531,7 @@ class FusionAxModule extends PLModule
         $page->assign('nbMissmatchingPromosTotal', $nbMissmatchingPromos);
     }
 
-    function handler_names(&$page, $action = '')
+    function handler_names($page, $action = '')
     {
         $page->changeTpl('fusionax/names.tpl');
 
@@ -540,42 +540,75 @@ class FusionAxModule extends PLModule
                        INNER JOIN  profiles         AS p    ON (f.ax_id = p.ax_id)');
         $page->assign('total', $res->fetchOneCell());
 
-        // To be checked:
-        // | lastname           |  1 |
-        // | lastname_marital   |  2 |
-        // | lastname_ordinary  |  3 |
-        // | firstname          |  4 |
-        // | firstname_ordinary |  7 |
-        // | firstname_other    |  8 |
-        // | name_other         |  9 |
-        // | name_ini           | 10 |
-        // | firstname_ini      | 11 |
-        $res = XDB::query("SELECT  COUNT(*)
-                             FROM  fusionax_anciens AS f
-                       INNER JOIN  profiles         AS p   ON (f.ax_id = p.ax_id)
-                        LEFT JOIN  profile_name     AS pnp ON (p.pid = pnp.pid AND pnp.typeid = 1)
-                        LEFT JOIN  profile_name     AS pnm ON (p.pid = pnm.pid AND pnm.typeid = 2)
-                        LEFT JOIN  profile_name     AS pno ON (p.pid = pno.pid AND pno.typeid = 3)
-                        LEFT JOIN  profile_name     AS pne ON (p.pid = pne.pid AND pne.typeid = 9)
-                        LEFT JOIN  profile_name     AS pni ON (p.pid = pni.pid AND pni.typeid = 10)
-                            WHERE  IF(f.partic_patro, CONCAT(f.partic_patro, CONCAT(' ', f.Nom_patronymique)), f.Nom_patronymique) NOT IN (pnp.name, pno.name, pnm.name, pne.name, pni.name)
-                                   OR IF(f.partic_nom, CONCAT(f.partic_nom, CONCAT(' ', f.Nom_usuel)), f.Nom_usuel) NOT IN (pnp.name, pno.name, pnm.name, pne.name, pni.name)
-                                   OR f.Nom_complet NOT IN (pnp.name, pno.name, pnm.name, pne.name, pni.name)");
+        $res = XDB::rawFetchOneCell("SELECT  COUNT(*)
+                                       FROM  fusionax_anciens AS f
+                                 INNER JOIN  profiles         AS p   ON (f.ax_id = p.ax_id)
+                                      WHERE  IF(f.partic_patro, CONCAT(f.partic_patro, CONCAT(' ', f.Nom_patronymique)), f.Nom_patronymique) NOT IN (p.lastname_initial, p.lastname_main, p.lastname_marital, p.lastname_ordinary)
+                                             OR IF(f.partic_nom, CONCAT(f.partic_nom, CONCAT(' ', f.Nom_usuel)), f.Nom_usuel) NOT IN (p.lastname_initial, p.lastname_main, p.lastname_marital, p.lastname_ordinary)
+                                             OR f.Nom_complet NOT IN (p.lastname_initial, p.lastname_main, p.lastname_marital, p.lastname_ordinary)");
         $page->assign('lastnameIssues', $res->fetchOneCell());
 
-        $res = XDB::query('SELECT  COUNT(*)
-                             FROM  fusionax_anciens AS f
-                       INNER JOIN  profiles         AS p   ON (f.ax_id = p.ax_id)
-                        LEFT JOIN  profile_name     AS pnf ON (p.pid = pnf.pid AND pnf.typeid = 4)
-                        LEFT JOIN  profile_name     AS pno ON (p.pid = pno.pid AND pno.typeid = 7)
-                        LEFT JOIN  profile_name     AS pne ON (p.pid = pne.pid AND pne.typeid = 8)
-                        LEFT JOIN  profile_name     AS pni ON (p.pid = pni.pid AND pni.typeid = 11)
-                            WHERE  f.prenom NOT IN (pnf.name, pno.name, pne.name, pni.name)');
+        $res = XDB::rawFetchOneCell('SELECT  COUNT(*)
+                                       FROM  fusionax_anciens AS f
+                                 INNER JOIN  profiles         AS p   ON (f.ax_id = p.ax_id)
+                                      WHERE  f.prenom NOT IN (p.firstname_initial, p.firstname_main, p.firstname_ordinary)');
         $page->assign('firstnameIssues', $res->fetchOneCell());
 
     }
 
-    function handler_issues_deathdate(&$page, $action = '')
+    function handler_edu($page, $action = '')
+    {
+        $page->changeTpl('fusionax/education.tpl');
+
+        $missingEducation = XDB::rawIterator("SELECT  DISTINCT(f.Intitule_formation)
+                                                FROM  fusionax_formations AS f
+                                               WHERE  f.Intitule_formation != '' AND NOT EXISTS (SELECT  *
+                                                                                                   FROM  profile_education_enum AS e
+                                                                                                  WHERE  f.Intitule_formation = e.name)");
+        $missingDegree = XDB::rawIterator("SELECT  DISTINCT(f.Intitule_diplome)
+                                             FROM  fusionax_formations AS f
+                                            WHERE  f.Intitule_diplome != '' AND NOT EXISTS (SELECT  *
+                                                                                              FROM  profile_education_degree_enum AS e
+                                                                                             WHERE  f.Intitule_diplome = e.abbreviation)");
+        $missingCouple = XDB::rawIterator("SELECT  DISTINCT(f.Intitule_formation) AS edu, f.Intitule_diplome AS degree, ee.id AS eduid, de.id AS degreeid
+                                             FROM  fusionax_formations           AS f
+                                       INNER JOIN  profile_education_enum        AS ee ON (f.Intitule_formation = ee.name)
+                                       INNER JOIN  profile_education_degree_enum AS de ON (f.Intitule_diplome = de.abbreviation)
+                                            WHERE  f.Intitule_diplome != '' AND f.Intitule_formation != ''
+                                                   AND NOT EXISTS (SELECT  *
+                                                                     FROM  profile_education_degree AS d
+                                                                    WHERE  ee.id = d.eduid AND de.id = d.degreeid)");
+
+        $page->assign('missingEducation', $missingEducation);
+        $page->assign('missingDegree', $missingDegree);
+        $page->assign('missingCouple', $missingCouple);
+        $page->assign('missingEducationCount', $missingEducation->total());
+        $page->assign('missingDegreeCount', $missingDegree->total());
+        $page->assign('missingCoupleCount', $missingCouple->total());
+    }
+
+    function handler_corps($page)
+    {
+        $page->changeTpl('fusionax/corps.tpl');
+
+        $missingCorps = XDB::rawIterator('SELECT  DISTINCT(f.corps_sortie) AS name
+                                            FROM  fusionax_anciens AS f
+                                           WHERE  NOT EXISTS (SELECT  *
+                                                                FROM  profile_corps_enum AS c
+                                                               WHERE  f.corps_sortie = c.abbreviation)');
+        $missingGrade = XDB::rawIterator('SELECT  DISTINCT(f.grade) AS name
+                                            FROM  fusionax_anciens AS f
+                                           WHERE  NOT EXISTS (SELECT  *
+                                                                FROM  profile_corps_rank_enum AS c
+                                                               WHERE  f.grade = c.name)');
+
+        $page->assign('missingCorps', $missingCorps);
+        $page->assign('missingGrade', $missingGrade);
+        $page->assign('missingCorpsCount', $missingCorps->total());
+        $page->assign('missingGradeCount', $missingGrade->total());
+    }
+
+    function handler_issues_deathdate($page, $action = '')
     {
         $page->changeTpl('fusionax/deathdate_issues.tpl');
         if ($action == 'edit') {
@@ -617,7 +650,7 @@ class FusionAxModule extends PLModule
         $page->assign('total', count($issues));
     }
 
-    function handler_issues_promo(&$page, $action = '')
+    function handler_issues_promo($page, $action = '')
     {
         $page->changeTpl('fusionax/promo_issues.tpl');
         if ($action == 'edit') {
@@ -664,7 +697,7 @@ class FusionAxModule extends PLModule
         $page->assign('total', count($issues));
     }
 
-    function handler_issues(&$page, $action = '')
+    function handler_issues($page, $action = '')
     {
         static $issueList = array(
             'name'      => 'noms',
@@ -673,6 +706,13 @@ class FusionAxModule extends PLModule
             'address'   => 'adresses',
             'job'       => 'emplois'
         );
+        static $typeList = array(
+            'name'      => 'general',
+            'phone'     => 'general',
+            'education' => 'general',
+            'address'   => 'adresses',
+            'job'       => 'emploi'
+        );
 
         if (!array_key_exists($action, $issueList)) {
             pl_redirect('fusionax');
@@ -695,6 +735,7 @@ class FusionAxModule extends PLModule
             $page->changeTpl('fusionax/other_issues.tpl');
             $page->assign('issues', $issues);
             $page->assign('issue', $issueList[$action]);
+            $page->assign('type', $typeList[$action]);
             $page->assign('total', $total);
         }
     }