diff --git a/__manifest__.py b/__manifest__.py
index 96ae5579eab216cc17ae9005fe833c6e196bbf3d..de6967d8708c097589df4e32a73943c1336eb586 100644
--- a/__manifest__.py
+++ b/__manifest__.py
@@ -15,9 +15,11 @@
         # datas
         # templates
         # views
+        "views/survey.xml",
         "views/training.xml",
         "views/training_program.xml",
         # menus
+        "views/menus.xml",
     ],
     "assets": {
         "web.report_assets_common": [],
diff --git a/models/__init__.py b/models/__init__.py
index a9d14033adf8cd645ffcab42dcef77fb9a3612b8..972ef021af9da20427819f3be9338325a87dee67 100644
--- a/models/__init__.py
+++ b/models/__init__.py
@@ -1,2 +1,3 @@
+from . import survey
 from . import training
 from . import training_program
diff --git a/models/survey.py b/models/survey.py
new file mode 100644
index 0000000000000000000000000000000000000000..be2104dc8b427feb5e11775e920c771df5e50a27
--- /dev/null
+++ b/models/survey.py
@@ -0,0 +1,66 @@
+# Copyright 2019-2022 Le Filament (<https://le-filament.com>)
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
+
+from odoo import fields, models
+
+
+class Survey(models.Model):
+    _inherit = "survey.survey"
+
+    survey_type = fields.Selection(
+        selection=[
+            ("training", "formation"),
+        ],
+        string="Type de questionnaire",
+    )
+    training_survey_type = fields.Selection(
+        selection=[
+            ("subscribe", "Inscription / Positionnement"),
+            ("aeci", "AECI"),
+            ("aect", "AECT"),
+            ("satisfaction", "Satisfaction"),
+        ],
+        string="Type de questionnaire",
+    )
+    training_ids = fields.One2many(
+        comodel_name="training.training",
+        compute="_compute_training_ids",
+    )
+    program_ids = fields.One2many(
+        comodel_name="training.program", compute="_compute_program_ids"
+    )
+
+    # ------------------------------------------------------
+    # Override ORM
+    # ------------------------------------------------------
+
+    # ------------------------------------------------------
+    # Compute
+    # ------------------------------------------------------
+    def _compute_training_ids(self):
+        for survey in self:
+            if survey.survey_type == "training":
+                survey.training_ids = self.env["training.training"].search(
+                    [("satisfaction_survey_id", "=", survey.id)]
+                )
+            else:
+                survey.training_ids = False
+
+    def _compute_program_ids(self):
+        for survey in self:
+            if survey.survey_type == "training":
+                survey.program_ids = self.env["training.program"].search(
+                    [
+                        "|",
+                        "|",
+                        ("registration_survey_id", "=", survey.id),
+                        ("aeci_survey_id", "=", survey.id),
+                        ("aect_survey_id", "=", survey.id),
+                    ]
+                )
+            else:
+                survey.program_ids = False
+
+    # ------------------------------------------------------
+    # Buttons
+    # ------------------------------------------------------
diff --git a/models/training.py b/models/training.py
index 4b0a2618e5f9b09322b8a0719deca11e889b62c6..8753ca80bf545c3bb71e2be05fc767d26e98ab08 100644
--- a/models/training.py
+++ b/models/training.py
@@ -1,14 +1,21 @@
-# Copyright 2019-2022 Le Filament (<https://le-filament.com>)
+# Copyright 2024 Le Filament (<https://le-filament.com>)
 # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
 
-from odoo import fields, models
+from odoo import _, fields, models
+from odoo.exceptions import UserError
 
 
 class Training(models.Model):
     _inherit = "training.training"
 
     satisfaction_survey_id = fields.Many2one(
-        comodel_name="survey.survey", string="Satisfaction", ondelete="restrict"
+        comodel_name="survey.survey",
+        string="Satisfaction",
+        domain=[
+            ("survey_type", "=", "survey_type"),
+            ("training_survey_type", "=", "satisfaction"),
+        ],
+        ondelete="restrict",
     )
 
     # ------------------------------------------------------
@@ -16,9 +23,17 @@ class Training(models.Model):
     # ------------------------------------------------------
 
     # ------------------------------------------------------
-    # compute
+    # Compute
     # ------------------------------------------------------
 
+    # ------------------------------------------------------
+    # Inherit parent
+    # ------------------------------------------------------
+    def action_valid(self):
+        if not self.satisfaction_survey_id:
+            raise UserError(_("Le questionnaire de satisfaction doit être renseigné."))
+        super().action_valid()
+
     # ------------------------------------------------------
     # Buttons
     # ------------------------------------------------------
diff --git a/models/training_program.py b/models/training_program.py
index c60cce81ecc023f85364b86dea60245f67d3b7e0..9fe49e4201eb9c11fc7c639f4fdf3f3920298c89 100644
--- a/models/training_program.py
+++ b/models/training_program.py
@@ -1,7 +1,8 @@
-# Copyright 2019-2022 Le Filament (<https://le-filament.com>)
+# Copyright 2024 Le Filament (<https://le-filament.com>)
 # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
 
-from odoo import fields, models
+from odoo import _, fields, models
+from odoo.exceptions import UserError
 
 
 class TrainingProgram(models.Model):
@@ -10,15 +11,44 @@ class TrainingProgram(models.Model):
     registration_survey_id = fields.Many2one(
         comodel_name="survey.survey",
         string="Inscription/Positionnement",
+        domain=[
+            ("survey_type", "=", "training"),
+            ("training_survey_type", "=", "subscribe"),
+        ],
         ondelete="restrict",
     )
     aeci_survey_id = fields.Many2one(
-        comodel_name="survey.survey", string="AECI", ondelete="restrict"
+        comodel_name="survey.survey",
+        string="AECI",
+        domain=[
+            ("survey_type", "=", "training"),
+            ("training_survey_type", "=", "aeci"),
+        ],
+        ondelete="restrict",
     )
     aect_survey_id = fields.Many2one(
-        comodel_name="survey.survey", string="AECT", ondelete="restrict"
+        comodel_name="survey.survey",
+        string="AECT",
+        domain=[
+            ("survey_type", "=", "training"),
+            ("training_survey_type", "=", "aect"),
+        ],
+        ondelete="restrict",
     )
 
     # ------------------------------------------------------
     # Compute
     # ------------------------------------------------------
+
+    # ------------------------------------------------------
+    # Inherit parent
+    # ------------------------------------------------------
+    def action_valid(self):
+        if not self.registration_survey_id or not self.aeci_survey_id:
+            raise UserError(
+                _(
+                    "Les questionnaires d'inscription/positionnement et AECI "
+                    "doivent être renseignés."
+                )
+            )
+        super(TrainingProgram, self).action_valid()
diff --git a/views/menus.xml b/views/menus.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9ec86be1307ec31d8c05270e426515fbd861d803
--- /dev/null
+++ b/views/menus.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<odoo>
+    <!-- MENU -->
+    <menuitem
+        id="menu_training_survey"
+        name="Questionnaires"
+        sequence="30"
+        parent="training.menu_training"
+        action="action_training_survey"
+    />
+
+</odoo>
diff --git a/views/survey.xml b/views/survey.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8689d4f87bf708929161b2f9e265c7ef4a2d5a5a
--- /dev/null
+++ b/views/survey.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!-- Copyright 2024 Le Filament (<https://le-filament.com>)
+     License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
+<odoo>
+    <!-- Form -->
+    <record id="training_survey_form" model="ir.ui.view">
+        <field name="name">training.survey.form</field>
+        <field name="model">survey.survey</field>
+        <field name="inherit_id" ref="survey.survey_survey_view_form" />
+        <field name="arch" type="xml">
+            <xpath expr="//field[@name='user_id']" position="before">
+                <field name="survey_type" invisible="1" />
+                <field
+                    name="training_survey_type"
+                    attrs="{'invisible': [('survey_type', '!=', 'training')], 'required': [('survey_type', '=', 'training')]}"
+                />
+            </xpath>
+            <xpath expr="//notebook" position="inside">
+                <page
+                    name="trainings"
+                    string="Formations"
+                    attrs="{'invisible': ['|', ('survey_type', '!=', 'training'), ('training_survey_type', '!=', 'satisfaction'), ]}"
+                >
+                    <field name="training_ids" />
+                </page>
+                <page
+                    name="programs"
+                    strong="Programmes"
+                    attrs="{'invisible': ['|', ('survey_type', '!=', 'training'), ('training_survey_type', 'not in', ['aeci', 'aect', 'subscribe']), ]}"
+                >
+                    <field name="program_ids" />
+                </page>
+            </xpath>
+        </field>
+    </record>
+
+    <!-- Tree -->
+    <record id="training_survey_tree" model="ir.ui.view">
+        <field name="name">training.survey.tree</field>
+        <field name="model">survey.survey</field>
+        <field name="inherit_id" ref="survey.survey_survey_view_tree" />
+        <field name="arch" type="xml">
+            <xpath expr="//field[@name='user_id']" position="after">
+                <field name="survey_type" invisible="1" />
+                <field
+                    name="training_survey_type"
+                    readonly="1"
+                    optional="show"
+                    attrs="{'column_invisible': [('survey_type', '!=', 'training')]}"
+                />
+            </xpath>
+        </field>
+    </record>
+
+    <!-- Kanban -->
+    <record id="training_survey_kanban" model="ir.ui.view">
+        <field name="name">training.survey.kanban</field>
+        <field name="model">survey.survey</field>
+        <field name="inherit_id" ref="survey.survey_survey_view_kanban" />
+        <field name="arch" type="xml">
+            <xpath expr="//field[@name='success_ratio']" position="after">
+                <field name="survey_type" />
+                <field name="training_survey_type" />
+            </xpath>
+            <xpath
+                expr="//div[hasclass('o_survey_kanban_card_ungrouped')]/div/div"
+                position="inside"
+            >
+                <div
+                    class="text-center mt-3"
+                    t-if="record.survey_type.raw_value == 'training'"
+                >
+                    <field name="training_survey_type" widget="badge" />
+                </div>
+            </xpath>
+        </field>
+    </record>
+
+    <!-- Search -->
+    <record id="training_survey_search" model="ir.ui.view">
+        <field name="name">training.survey.search</field>
+        <field name="model">survey.survey</field>
+        <field name="mode">primary</field>
+        <field name="inherit_id" ref="survey.survey_survey_view_search" />
+        <field name="arch" type="xml">
+            <xpath expr="//filter[@name='inactive']" position="before">
+                <field name="training_survey_type" />
+            </xpath>
+            <xpath expr="//filter[@name='inactive']" position="before">
+                <filter
+                    string="Inscription/Positionnement"
+                    name="subscribe"
+                    domain="[('training_survey_type', '=', 'subscribe')]"
+                />
+                <filter
+                    string="AECI"
+                    name="aeci"
+                    domain="[('training_survey_type', '=', 'aeci')]"
+                />
+                <filter
+                    string="AECT"
+                    name="aect"
+                    domain="[('training_survey_type', '=', 'aect')]"
+                />
+                <filter
+                    string="Satisfaction"
+                    name="satisfaction"
+                    domain="[('training_survey_type', '=', 'satisfaction')]"
+                />
+                <separator />
+            </xpath>
+            <xpath expr="//filter[@name='group_by_responsible']" position="before">
+                <filter
+                    string="Type de questionnaire"
+                    name="group_by_training_survey_type"
+                    context="{'group_by': 'training_survey_type'}"
+                />
+            </xpath>
+        </field>
+    </record>
+
+
+    <!-- Actions -->
+    <!-- Inherit parent action for domain -->
+    <record model="ir.actions.act_window" id="survey.action_survey_form">
+        <field name="domain">[("survey_type", "=", False)]</field>
+    </record>
+    <!-- New Actions -->
+    <record model="ir.actions.act_window" id="action_training_survey">
+        <field name="name">Questionnaires formation</field>
+        <field name="res_model">survey.survey</field>
+        <field name="domain">[("survey_type", "=", "training")]</field>
+        <field name="view_mode">kanban,tree,form,activity</field>
+        <field name="context">{"default_survey_type": "training"}</field>
+        <field name="search_view_id" ref="training_survey_search" />
+    </record>
+
+</odoo>
diff --git a/views/training.xml b/views/training.xml
index 5e8ed8c7e26a18f65efaa48ab460f6b92f3b68e6..0a4ca8509f763e61e04b42de08c52a203b9f65f5 100644
--- a/views/training.xml
+++ b/views/training.xml
@@ -13,7 +13,7 @@
                         <group>
                             <field
                                 name="satisfaction_survey_id"
-                                option="{'no_create': 1, 'no_edit': 1}"
+                                options="{'no_create': 1, 'no_edit': 1}"
                             />
                         </group>
                     </group>
diff --git a/views/training_program.xml b/views/training_program.xml
index 5d428b8a81417e7a03f3e5cf5185f02cb24f2035..b4d0bfd016b4aadba579d82d96a16a80118ee52c 100644
--- a/views/training_program.xml
+++ b/views/training_program.xml
@@ -11,20 +11,18 @@
             <xpath expr="//notebook" position="inside">
                 <page string="Questionnaires" name="survey">
                     <group>
-                        <group>
-                            <field
-                                name="registration_survey_id"
-                                option="{'no_create': 1, 'no_edit': 1}"
-                            />
-                            <field
-                                name="aect_survey_id"
-                                option="{'no_create': 1, 'no_edit': 1}"
-                            />
-                            <field
-                                name="aeci_survey_id"
-                                option="{'no_create': 1, 'no_edit': 1}"
-                            />
-                        </group>
+                        <field
+                            name="registration_survey_id"
+                            options="{'no_create': 1, 'no_edit': 1}"
+                        />
+                        <field
+                            name="aect_survey_id"
+                            options="{'no_create': 1, 'no_edit': 1}"
+                        />
+                        <field
+                            name="aeci_survey_id"
+                            options="{'no_create': 1, 'no_edit': 1}"
+                        />
                     </group>
                 </page>
             </xpath>