Skip to content

Commit 433d4bc

Browse files
[ADD] survey_question_type_model_selection: new module
1 parent d79082b commit 433d4bc

21 files changed

+974
-0
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
====================================
2+
Survey model selection question type
3+
====================================
4+
5+
..
6+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
7+
!! This file is generated by oca-gen-addon-readme !!
8+
!! changes will be overwritten. !!
9+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
10+
!! source digest: sha256:fe3c2db9a4d30bf585e09ebda06f06903385422b6582e9cd6eec923ed3a86f06
11+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
12+
13+
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
14+
:target: https://odoo-community.org/page/development-status
15+
:alt: Beta
16+
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
17+
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
18+
:alt: License: AGPL-3
19+
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsurvey-lightgray.png?logo=github
20+
:target: https://github.com/OCA/survey/tree/17.0/survey_question_type_model_selection
21+
:alt: OCA/survey
22+
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
23+
:target: https://translation.odoo-community.org/projects/survey-17-0/survey-17-0-survey_question_type_model_selection
24+
:alt: Translate me on Weblate
25+
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
26+
:target: https://runboat.odoo-community.org/builds?repo=OCA/survey&target_branch=17.0
27+
:alt: Try me on Runboat
28+
29+
|badge1| |badge2| |badge3| |badge4| |badge5|
30+
31+
This module add Model selection field question type for attach on survey
32+
page.
33+
34+
**Table of contents**
35+
36+
.. contents::
37+
:local:
38+
39+
Configuration
40+
=============
41+
42+
Once installed from the configuration of the questions, in the options,
43+
you can select the model to apply and also you can add filters.
44+
45+
Bug Tracker
46+
===========
47+
48+
Bugs are tracked on `GitHub Issues <https://github.com/OCA/survey/issues>`_.
49+
In case of trouble, please check there if your issue has already been reported.
50+
If you spotted it first, help us to smash it by providing a detailed and welcomed
51+
`feedback <https://github.com/OCA/survey/issues/new?body=module:%20survey_question_type_model_selection%0Aversion:%2017.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
52+
53+
Do not contact contributors directly about support or help with technical issues.
54+
55+
Credits
56+
=======
57+
58+
Authors
59+
-------
60+
61+
* Tecnativa
62+
63+
Contributors
64+
------------
65+
66+
- `Tecnativa <https://www.tecnativa.com>`__
67+
68+
- Eduardo Ezerouali
69+
70+
Maintainers
71+
-----------
72+
73+
This module is maintained by the OCA.
74+
75+
.. image:: https://odoo-community.org/logo.png
76+
:alt: Odoo Community Association
77+
:target: https://odoo-community.org
78+
79+
OCA, or the Odoo Community Association, is a nonprofit organization whose
80+
mission is to support the collaborative development of Odoo features and
81+
promote its widespread use.
82+
83+
This module is part of the `OCA/survey <https://github.com/OCA/survey/tree/17.0/survey_question_type_model_selection>`_ project on GitHub.
84+
85+
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import models
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Copyright 2025 Tecnativa - Eduardo Ezerouali
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
{
4+
"name": "Survey model selection question type",
5+
"version": "17.0.1.0.0",
6+
"summary": "This module add model selection field as question type for survey page",
7+
"author": "Tecnativa, Odoo Community Association (OCA)",
8+
"website": "https://github.com/OCA/survey",
9+
"license": "AGPL-3",
10+
"category": "Marketing/Survey",
11+
"depends": ["survey"],
12+
"data": [
13+
"views/survey_question_views.xml",
14+
"views/survey_user_input_line_views.xml",
15+
"views/survey_template.xml",
16+
],
17+
"assets": {
18+
"web.assets_frontend": [
19+
"survey_question_type_model_selection/static/src/js/survey_form_patch.esm.js",
20+
"survey_question_type_model_selection/static/src/js/survey_form_model.esm.js",
21+
"survey_question_type_model_selection/static/src/css/survey_model.scss",
22+
],
23+
"web.assets_tests": [
24+
"survey_question_type_model_selection/static/tests/test_tour_survey_question_model.esm.js",
25+
],
26+
},
27+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from . import survey_question
2+
from . import survey_user_input
3+
from . import survey_user_input_line
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Copyright 2025 Tecnativa - Eduardo Ezerouali
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
import ast
4+
5+
from odoo import fields, models
6+
7+
8+
class SurveyQuestion(models.Model):
9+
_inherit = "survey.question"
10+
11+
question_type = fields.Selection(selection_add=[("model", "Model selection")])
12+
question_model_id = fields.Many2one(
13+
string="Applies to",
14+
comodel_name="ir.model",
15+
default=lambda self: self.env["ir.model"]._get_id("res.partner"),
16+
ondelete="cascade",
17+
)
18+
question_model_name = fields.Char(related="question_model_id.model")
19+
question_domain = fields.Char(string="Filter Domain")
20+
21+
def _get_parsed_domain(self):
22+
"""Parse domain string safely into a Python list."""
23+
if not self.question_domain:
24+
return []
25+
try:
26+
domain = ast.literal_eval(self.question_domain)
27+
return domain if isinstance(domain, list) else []
28+
except Exception:
29+
return []
30+
31+
def get_model_options(self):
32+
"""Return Model options filtered by the domain."""
33+
self.ensure_one()
34+
domain = self._get_parsed_domain()
35+
records = self.env[self.question_model_name].sudo().search(domain)
36+
return [(rec.id, rec.display_name, rec._name) for rec in records]
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Copyright 2025 Tecnativa - Eduardo Ezerouali
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
from odoo import models
4+
5+
6+
class SurveyUserInput(models.Model):
7+
_inherit = "survey.user_input"
8+
9+
def _save_lines(self, question, answer, comment=None, overwrite_existing=True):
10+
old_answers = self.env["survey.user_input.line"].search(
11+
[
12+
("user_input_id", "=", self.id),
13+
("question_id", "=", question.id),
14+
]
15+
)
16+
if question.question_type == "model":
17+
if not isinstance(answer, (list | tuple)):
18+
answer = [answer]
19+
if not answer:
20+
answer = [False]
21+
for answer_drop in answer:
22+
old_answers = self._save_line_simple_answer(
23+
question, old_answers, answer_drop
24+
)
25+
else:
26+
super()._save_lines(
27+
question, answer, comment=comment, overwrite_existing=overwrite_existing
28+
)
29+
return True
30+
31+
def _get_line_answer_values(self, question, answer, answer_type):
32+
res = super()._get_line_answer_values(question, answer, answer_type)
33+
if answer_type == "model":
34+
res["value_model"] = answer
35+
return res
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Copyright 2025 Tecnativa - Eduardo Ezerouali
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
from odoo import api, fields, models
4+
5+
6+
class SurveyUserInputLine(models.Model):
7+
_inherit = "survey.user_input.line"
8+
9+
answer_type = fields.Selection(
10+
selection_add=[
11+
("model", "Model selection"),
12+
]
13+
)
14+
value_model = fields.Reference(
15+
string="Selection answer", selection="_selection_target_model"
16+
)
17+
18+
def _compute_display_name(self):
19+
for line in self:
20+
if line.answer_type == "model":
21+
line.display_name = line.value_model.display_name
22+
return super()._compute_display_name()
23+
24+
@api.model
25+
def _selection_target_model(self):
26+
return [
27+
(model.model, model.name)
28+
for model in self.env["ir.model"].sudo().search([])
29+
]
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[build-system]
2+
requires = ["whool"]
3+
build-backend = "whool.buildapi"
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Once installed from the configuration of the questions, in the options,
2+
you can select the model to apply and also you can add filters.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- [Tecnativa](https://www.tecnativa.com)
2+
- Eduardo Ezerouali

0 commit comments

Comments
 (0)