diff --git a/__init__.py b/__init__.py
index 0650744f6bc69b9f0b865e8c7174c813a5f5995e..f7209b17100218a42c80c8e984c08597d630b188 100644
--- a/__init__.py
+++ b/__init__.py
@@ -1 +1,2 @@
 from . import models
+from . import controllers
diff --git a/controllers/__init__.py b/controllers/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e425c18c14ba72b12d8086c870cdcd5f615f23f4
--- /dev/null
+++ b/controllers/__init__.py
@@ -0,0 +1,4 @@
+# -*- encoding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import main
diff --git a/controllers/main.py b/controllers/main.py
new file mode 100644
index 0000000000000000000000000000000000000000..07a7b85d55f5ce73e0bbaeb1ff343a0a6f633b80
--- /dev/null
+++ b/controllers/main.py
@@ -0,0 +1,66 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+import logging
+
+from odoo.addons.survey.controllers.main import Survey
+from odoo import http
+from odoo.exceptions import UserError
+from odoo.http import request
+
+
+_logger = logging.getLogger(__name__)
+
+
+class TrainingSurvey(Survey):
+
+    #
+    # ------------------------------------------------------------
+    # TAKING SURVEY ROUTES
+    # ------------------------------------------------------------
+
+    @http.route('/survey/start/<string:survey_token>', type='http', auth='public', website=True)
+    def survey_start(self, survey_token, answer_token=None, email=False, **post):
+        """ Start a survey by providing
+         * a token linked to a survey;
+         * a token linked to an answer or generate a new token if access is allowed;
+        """
+        # Get the current answer token from cookie
+        answer_from_cookie = False
+        if not answer_token:
+            answer_token = request.httprequest.cookies.get('survey_%s' % survey_token)
+            answer_from_cookie = bool(answer_token)
+
+        access_data = self._get_access_data(survey_token, answer_token, ensure_token=False)
+
+        if answer_from_cookie and access_data['validity_code'] in ('answer_wrong_user', 'token_wrong'):
+            # If the cookie had been generated for another user or does not correspond to any existing answer object
+            # (probably because it has been deleted), ignore it and redo the check.
+            # The cookie will be replaced by a legit value when resolving the URL, so we don't clean it further here.
+            access_data = self._get_access_data(survey_token, None, ensure_token=False)
+
+        if access_data['validity_code'] is not True:
+            return self._redirect_with_error(access_data, access_data['validity_code'])
+
+        survey_sudo, answer_sudo = access_data['survey_sudo'], access_data['answer_sudo']
+        if not answer_sudo:
+            try:
+                answer_sudo = survey_sudo._create_answer(user=request.env.user, email=email)
+            except UserError:
+                answer_sudo = False
+
+        if not answer_sudo:
+            try:
+                survey_sudo.with_user(request.env.user).check_access_rights('read')
+                survey_sudo.with_user(request.env.user).check_access_rule('read')
+            except:
+                return request.redirect("/")
+            else:
+                return request.render("survey.survey_403_page", {'survey': survey_sudo})
+
+        training_id = post.get("training_id")
+        if training_id:
+            training = request.env["training.training"].browse(int(training_id))
+            answer_sudo.training_id = training
+
+        return request.redirect('/survey/%s/%s' % (survey_sudo.access_token, answer_sudo.access_token))
diff --git a/models/survey_user_input.py b/models/survey_user_input.py
index 9e10838c7bc152ff39a09e4c177db9c10ee46aa8..bbf109ea971d0ad4336cbf7707390929765f7eff 100644
--- a/models/survey_user_input.py
+++ b/models/survey_user_input.py
@@ -16,7 +16,6 @@ class SurveyUserInput(models.Model):
         comodel_name="training.training",
         string="Formation",
         ondelete="cascade",
-        compute="_compute_training_id"
     )
 
     training_survey_type = fields.Selection(
@@ -43,12 +42,12 @@ class SurveyUserInput(models.Model):
         student_id = student_model.create(
             {
                 "partner_id": self.partner_id.id,
-                "training_id": self.training_id,
+                "training_id": self.training_id.id,
                 "student_company": self.company,
             }
         )
-        # Création de la réponse au sondage
-        answer_id = self.create(
+        # Création de la réponse au sondage et inscription
+        self.create(
             {
                 "partner_id": self.partner_id.id,
                 "email": self.partner_id.email,
@@ -65,16 +64,6 @@ class SurveyUserInput(models.Model):
     # ------------------------------------------------------
     # Compute
     # ------------------------------------------------------
-    @api.depends("survey_id")
-    def _compute_training_id(self):
-
-        for user_input in self:
-            user_input.training_id = self.env['training.training'].search(
-                [
-                    ('registration_survey_id', '=', user_input.survey_id.id),
-                    ('partner_id', '=', user_input.partner_id.id)
-                ]
-            )
 
     # ------------------------------------------------------
     # Buttons
diff --git a/models/training.py b/models/training.py
index 6f348dc223df4210811fe330a365f70c314432e4..dc501df57c9ba34c73f6b7bfb3ce88e30bcd162e 100644
--- a/models/training.py
+++ b/models/training.py
@@ -131,3 +131,8 @@ class Training(models.Model):
     # ------------------------------------------------------
     def _get_survey_xlsx(self, survey_id):
         return self.env.ref("survey_xlsx.report_survey_xlsx").report_action(survey_id)
+
+    def get_registration_survey_start_url(self):
+
+        url = self.registration_survey_id.get_start_url()
+        return f"{url}?training_id={self.id}"