Surveys

survey
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/19.0/survey
VERSION
VERSION 3.7
CATEGORY
CATEGORYMarketing/Surveys
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo S.A.
MAINTAINERS
MAINTAINERSOdoo S.A.
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Thibault Delavallée, Denis Ledoux, Xavier Morel, Goffin Simon, Géry Debongnie, Aaron Bohy, Christophe Monniez, Jorge Pinna Puissant, Julien Castiaux, Aurélien Warnon, Julien Mougenot, Tiffany Chang (tic), Gorash, Mathieu Duckerts-Antoine, William Braeckman, yhu-odoo, Florian Charlier, Abdelouahab (abla), Mathieu Walravens, Renaud Thiry, Louis Wicket (wil), Victor Piryns (pivi), amdi-odoo, Pierre-Yves Dufays, Maruan Aguerdouh (magm), Dylan Kiss (dyki), Mayurrajsinh Rathod, Walid (wasa), Astik Singh, bary, vava-odoo, Julien Carion (juca), adsh-odoo, Lopes Marc (loma), nihp-odoo, Shubham Thanki, aath-odoo, Xavier Luyckx (xlu), Pierre Lamotte (pila), Pierre Pulinckx, Bastien PIERRE, Anton Romanova (roan), Hoste Patrick, pish-odoo, João Horta Alves, lse-odoo, Krzysztof Magusiak (krma), utma-odoo, Alessandro Lupo, Augustin (duau), Serhii Rubanskyi, Jérôme Belpaire, josv-odoo, lecr, saurabh, Séna Nshimiyimana, Kadam Darji, ELCO, chpa-odoo, Romain ROSANO (rros), Dhrumit Parmar, samueljlieber, João Alves
WEBSITE
WEBSITEhttps://www.odoo.com/app/surveys
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 01:51:45
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - auth_signup
    - base_setup
    - base
    - web
    - mail
    - bus
    - web_tour
    - html_editor
    - http_routing
    - gamification
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
Create beautiful surveys and visualize answers
==============================================

It depends on the answers or reviews of some questions by different users. A
survey may have multiple pages. Each page may contain multiple questions and
each question may have multiple answers. Different users may give different
answers of question and according to that survey is done. Partners are also
sent mails with personal token for the invitation of the survey.
    

Code Analysis

Views touched (73)
XML IDNameModelTypeStatus
certification_preview certification_preview ir.ui.view qweb New
certification_report_view certification_report_view ir.ui.view qweb New
certification_report_view_general certification_report_view_general ir.ui.view qweb New
gamification_badge_form_view_simplified gamification.badge.form.view.simplified gamification.badge form New
question_char_box Question: text box ir.ui.view qweb New
question_container Survey: question container ir.ui.view qweb New
question_date Question: date box ir.ui.view qweb New
question_datetime Question: datetime box ir.ui.view qweb New
question_matrix Question: matrix ir.ui.view qweb New
question_multiple_choice Question: multiple choice ir.ui.view qweb New
question_numerical_box Question: numerical box ir.ui.view qweb New
question_result_choice Question: choice result (simple_choice, multiple_choice, scale) ir.ui.view qweb New
question_result_comments Question: comments ir.ui.view qweb New
question_result_matrix Question: matrix result (matrix) ir.ui.view qweb New
question_result_number_or_date_or_datetime Question: number or date (and time) result (numerical_box or date or datetime) ir.ui.view qweb New
question_result_text Question: text result (text_box, char_box) ir.ui.view qweb New
question_scale Question: scale ir.ui.view qweb New
question_simple_choice Question: simple choice ir.ui.view qweb New
question_suggested_value_image Image from the question suggested answer ir.ui.view qweb New
question_table_pagination Survey: statistics table pagination ir.ui.view qweb New
question_text_box Question: free text box ir.ui.view qweb New
res_partner_view_form res.partner.view.form.inherit.survey res.partner xpath Inherits base.view_partner_form
survey.layout Survey Layout ir.ui.view qweb Inherits web.frontend_layout
survey_403_page Survey: custom 403 page ir.ui.view qweb New
survey_access_error Survey: access error ir.ui.view qweb New
survey_auth_required Survey: login required ir.ui.view qweb New
survey_button_form_view Survey: back to form view ir.ui.view qweb New
survey_button_retake Survey: retake button ir.ui.view qweb New
survey_closed_expired Survey: expired ir.ui.view qweb New
survey_fill_form Survey: main page content ir.ui.view qweb New
survey_fill_form_done Survey: finished ir.ui.view qweb New
survey_fill_form_in_progress Survey: form with questions ir.ui.view qweb New
survey_fill_form_start Survey: start form content ir.ui.view qweb New
survey_fill_header Survey: main page header ir.ui.view qweb New
survey_invite_view_form survey.invite.view.form survey.invite form New
survey_navigation Survey: Navigation ir.ui.view qweb New
survey_page_fill Survey: main page (take survey) ir.ui.view qweb New
survey_page_print Survey: print page ir.ui.view qweb New
survey_page_statistics Survey: result statistics page ir.ui.view qweb New
survey_page_statistics_header Survey: result statistics header ir.ui.view qweb New
survey_page_statistics_inner Survey: result statistics content ir.ui.view qweb New
survey_page_statistics_question Question: result statistics ir.ui.view qweb New
survey_progression Survey: Progression ir.ui.view qweb New
survey_question_answer_view_form survey.question.answer.view.form survey.question.answer form New
survey_question_answer_view_search survey.question.answer.view.search survey.question.answer search New
survey_question_answer_view_tree survey.question.answer.view.list survey.question.answer list New
survey_question_form Form view for survey question survey.question form New
survey_question_search Search view for survey question survey.question search New
survey_question_tree List view for survey question survey.question list New
survey_remove_unnecessary_decimals Survey: remove .0 ir.ui.view qweb New
survey_response_line_view_tree survey.user_input.line.view.list survey.user_input.line list New
survey_results_filters Survey: Filter results ir.ui.view qweb New
survey_selection_key survey_selection_key ir.ui.view qweb New
survey_session_code Survey: Access Code page ir.ui.view qweb New
survey_survey_view_activity survey.survey.view.activity survey.survey activity New
survey_survey_view_form survey.survey.view.form survey.survey form New
survey_survey_view_graph survey.survey.view.graph survey.survey graph New
survey_survey_view_kanban survey.survey.view.kanban survey.survey kanban New
survey_survey_view_pivot survey.survey.view.pivot survey.survey pivot New
survey_survey_view_search survey.survey.search survey.survey search New
survey_survey_view_tree survey.survey.view.list survey.survey list New
survey_user_input_line_view_form survey.user_input.line.view.form survey.user_input.line form New
survey_user_input_line_view_search survey.user_input.line.view.search survey.user_input.line search New
survey_user_input_view_form survey.user_input.view.form survey.user_input form New
survey_user_input_view_search survey.user_input.view.search survey.user_input search New
survey_user_input_view_tree survey.user_input.view.list survey.user_input list New
survey_user_input_viuew_kanban survey.user_input.view.kanban survey.user_input kanban New
survey_void_content Survey: void content ir.ui.view qweb New
user_input_session Survey User Input Session ir.ui.view qweb Inherits web.frontend_layout
user_input_session_leaderboard Survey User Input Leaderboard ir.ui.view qweb New
user_input_session_manage Survey: Manage Session ir.ui.view qweb New
user_input_session_manage_content Survey User Input Session Manage ir.ui.view qweb New
user_input_session_open Survey: Open Session ir.ui.view qweb New
Models touched (12)

New fields (2)
  • survey_id Many2one → survey.survey
    compute='_compute_survey_id' store=True args: 'survey.survey', 'Survey'
  • survey_ids One2many → survey.survey
    args: 'survey.survey', 'certification_badge_id', 'Survey Ids'
Public methods (0)

No public methods.

New fields (1)
  • challenge_category Selection
    ondelete={'certification': 'set default'} selection_add=[('certification', 'Certifications')]
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • get_nearest_lang(self, lang_code)
    @api.model

New fields (0)

No new fields.

Public methods (1)
  • write(self, vals)
    When languages are disabled, clear corresponding survey languages.

New fields (2)
  • certifications_company_count Integer
    compute='_compute_certifications_company_count' args: 'Company Certifications Count'
  • certifications_count Integer
    compute='_compute_certifications_count' args: 'Certifications Count'
Public methods (1)
  • action_view_certifications(self)

New fields (16)
  • attachment_ids Many2many → ir.attachment
    bypass_search_access=True compute='_compute_attachment_ids' readonly=False store=True string='Attachments' args: 'ir.attachment', 'survey_mail_compose_message_ir_attachments_rel', 'wizard_id', 'attachment_id'
  • author_id Many2one → res.partner
    default=_get_default_author index=True ondelete='set null' args: 'res.partner', 'Author'
  • deadline Datetime
    string='Answer deadline'
  • emails Text
    string='Additional emails'
  • existing_emails Text
    compute='_compute_existing_emails' readonly=True store=False args: 'Existing emails'
  • existing_mode Selection
    default='resend' required=True string='Handle existing' args: [('new', 'New invite'), ('resend', 'Resend invite')]
  • existing_partner_ids Many2many → res.partner
    compute='_compute_existing_partner_ids' readonly=True store=False args: 'res.partner'
  • existing_text Text
    compute='_compute_existing_text' args: 'Resend Comment'
  • mail_server_id Many2one → ir.mail_server
    args: 'ir.mail_server', 'Outgoing mail server'
  • partner_ids Many2many → res.partner
    domain="[ '|', (survey_users_can_signup, '=', 1), '|', (not survey_users_login_required, '=', 1), ('user_ids', '!=', False), ]" string='Recipients' args: 'res.partner', 'survey_invite_partner_ids', 'invite_id', 'partner_id'
  • send_email Boolean
    compute='_compute_send_email' inverse='_inverse_send_email'
  • survey_access_mode Selection
    readonly=True related='survey_id.access_mode'
  • survey_id Many2one → survey.survey
    required=True string='Survey' args: 'survey.survey'
  • survey_start_url Char
    compute='_compute_survey_start_url' args: 'Survey URL'
  • survey_users_can_signup Boolean
    related='survey_id.users_can_signup'
  • survey_users_login_required Boolean
    readonly=True related='survey_id.users_login_required'
Public methods (2)
  • action_invite(self)
    Process the wizard content and proceed with sending the related email(s), rendering any template patterns on the fly if needed
  • create(self, vals_list)
    @api.model_create_multi

New fields (57)
  • allowed_triggering_question_ids Many2many → survey.question
    compute='_compute_allowed_triggering_question_ids' copy=False string='Allowed Triggering Questions' args: 'survey.question'
  • answer_date Date
    help='Correct date answer for this question.' args: 'Correct date answer'
  • answer_datetime Datetime
    help='Correct date and time answer for this question.' args: 'Correct datetime answer'
  • answer_numerical_box Float
    help='Correct number answer for this question.' args: 'Correct numerical answer'
  • answer_score Float
    help='Score value for a correct answer to this question.' args: 'Score'
  • background_image Image
    compute='_compute_background_image' readonly=False store=True args: 'Background Image'
  • background_image_url Char
    compute='_compute_background_image_url' args: 'Background Url'
  • comment_count_as_answer Boolean
    args: 'Comment is an answer'
  • comments_allowed Boolean
    args: 'Show Comments Field'
  • comments_message Char
    translate=True args: 'Comment Message'
  • constr_error_msg Char
    translate=True args: 'Error message'
  • constr_mandatory Boolean
    args: 'Mandatory Answer'
  • description Html
    help='Use this field to add additional explanations about your question or to illustrate it with pictures or a video' sanitize=True sanitize_overridable=True translate=True args: 'Description'
  • has_image_only_suggested_answer Boolean
    compute='_compute_has_image_only_suggested_answer' args: 'Has image only suggested answer'
  • is_page Boolean
    args: 'Is a page?'
  • is_placed_before_trigger Boolean
    compute='_compute_allowed_triggering_question_ids' help='Is this question placed before any of its trigger questions?' string='Is misplaced?'
  • is_scored_question Boolean
    compute='_compute_is_scored_question' copy=True help='Include this question as part of quiz scoring. Requires an answer and answer score to be taken into account.' readonly=False store=True args: 'Scored'
  • is_time_customized Boolean
    args: 'Customized speed rewards'
  • is_time_limited Boolean
    help='Currently only supported for live sessions.' args: 'The question is limited in time'
  • matrix_row_ids One2many → survey.question.answer
    copy=True help='Labels used for proposed choices: rows of matrix' string='Matrix Rows' args: 'survey.question.answer', 'matrix_question_id'
  • matrix_subtype Selection
    default='simple' string='Matrix Type' args: [('simple', 'One choice per row'), ('multiple', 'Multiple choices per row')]
  • page_id Many2one → survey.question
    compute='_compute_page_id' store=True string='Page' args: 'survey.question'
  • question_ids One2many → survey.question
    compute='_compute_question_ids' string='Questions' args: 'survey.question'
  • question_placeholder Char
    compute='_compute_question_placeholder' readonly=False store=True translate=True args: 'Placeholder'
  • question_type Selection
    compute='_compute_question_type' readonly=False store=True string='Question Type' args: [('simple_choice', 'Multiple choice: only one answer'), ('multiple_choice', 'Multiple choice: multiple answers allowed'), ('text_box', 'Multiple Lines Text Box'), ('char_box', 'Single Line Text Box'), ('numerical_box', 'Numerical Value'), ('scale', 'Scale'), ('date', 'Date'), ('datetime', 'Datetime'), ('matrix', 'Matrix')]
  • questions_selection Selection
    help='If randomized is selected, add the number of random questions next to the section.' readonly=True related='survey_id.questions_selection'
  • random_questions_count Integer
    default=1 help='Used on randomized sections to take X random questions from all the questions of that section.' args: '# Questions Randomly Picked'
  • save_as_email Boolean
    compute='_compute_save_as_email' copy=True help="If checked, this option will save the user's answer as its email address." readonly=False store=True args: 'Save as user email'
  • save_as_nickname Boolean
    compute='_compute_save_as_nickname' copy=True help="If checked, this option will save the user's answer as its nickname." readonly=False store=True args: 'Save as user nickname'
  • scale_max Integer
    default=10 args: 'Scale Maximum Value'
  • scale_max_label Char
    translate=True args: 'Scale Maximum Label'
  • scale_mid_label Char
    translate=True args: 'Scale Middle Label'
  • scale_min Integer
    default=0 args: 'Scale Minimum Value'
  • scale_min_label Char
    translate=True args: 'Scale Minimum Label'
  • scoring_type Selection
    readonly=True related='survey_id.scoring_type' string='Scoring Type'
  • sequence Integer
    default=10 args: 'Sequence'
  • session_available Boolean
    readonly=True related='survey_id.session_available' string='Live Session available'
  • suggested_answer_ids One2many → survey.question.answer
    copy=True help='Labels used for proposed choices: simple choice, multiple choice and columns of matrix' string='Types of answers' args: 'survey.question.answer', 'question_id'
  • survey_id Many2one → survey.survey
    index='btree_not_null' ondelete='cascade' string='Survey' args: 'survey.survey'
  • survey_session_speed_rating Boolean
    related='survey_id.session_speed_rating'
  • survey_session_speed_rating_time_limit Integer
    related='survey_id.session_speed_rating_time_limit' string='General Time limit (seconds)'
  • time_limit Integer
    args: 'Time limit (seconds)'
  • title Char
    required=True translate=True args: 'Title'
  • triggering_answer_ids Many2many → survey.question.answer
    copy=False domain="[\n ('question_id.survey_id', '=', survey_id),\n '&', ('question_id.question_type', 'in', ['simple_choice', 'multiple_choice']),\n '|',\n ('question_id.sequence', '<', sequence),\n '&', ('question_id.sequence', '=', sequence), ('question_id.id', '<', id)\n ]" help='Picking any of these answers will trigger this question.\nLeave the field empty if the question should always be displayed.' readonly=False store=True string='Triggering Answers' args: 'survey.question.answer'
  • triggering_question_ids Many2many → survey.question
    compute='_compute_triggering_question_ids' help='Questions containing the triggering answer(s) to display the current question.' store=False string='Triggering Questions' args: 'survey.question'
  • user_input_line_ids One2many → survey.user_input.line
    domain=[('skipped', '=', False)] groups='survey.group_survey_user' string='Answers' args: 'survey.user_input.line', 'question_id'
  • validation_email Boolean
    args: 'Input must be an email'
  • validation_error_msg Char
    translate=True args: 'Validation Error'
  • validation_length_max Integer
    default=0 args: 'Maximum Text Length'
  • validation_length_min Integer
    default=0 args: 'Minimum Text Length'
  • validation_max_date Date
    args: 'Maximum Date'
  • validation_max_datetime Datetime
    args: 'Maximum Datetime'
  • validation_max_float_value Float
    default=0.0 args: 'Maximum value'
  • validation_min_date Date
    args: 'Minimum Date'
  • validation_min_datetime Datetime
    args: 'Minimum Datetime'
  • validation_min_float_value Float
    default=0.0 args: 'Minimum value'
  • validation_required Boolean
    compute='_compute_validation_required' readonly=False store=True args: 'Validate entry'
Public methods (4)
  • copy(self, default=None)
  • create(self, vals_list)
    @api.model_create_multi
  • default_get(self, fields)
    @api.model
  • validate_question(self, answer, comment=None)
    Validate question, depending on question type and parameters for simple choice, text, date and number, answer is simply the answer of the question. For other multiple choices questions, answer is a list of answers (the selected choices or a list of selected answers per question -for matrix type-): - Simple answer : ``answer = 'example'`` or ``2`` or ``question_answer_id`` or ``2019/10/10`` - Multiple choice : ``answer = [question_answer_id1, question_answer_id2, question_answer_id3]`` - Matrix: ``answer = { 'rowId1' : [colId1, colId2,...], 'rowId2' : [colId1, colId3, ...] }`` :returns: A dict ``{question.id: error}``, or an empty dict if no validation error. :rtype: dict[int, str]

New fields (11)
  • answer_score Float
    help='A positive score indicates a correct choice; a negative or null score indicates a wrong answer' args: 'Score'
  • is_correct Boolean
    args: 'Correct'
  • matrix_question_id Many2one → survey.question
    index='btree_not_null' ondelete='cascade' string='Question (as matrix row)' args: 'survey.question'
  • question_id Many2one → survey.question
    index='btree_not_null' ondelete='cascade' string='Question' args: 'survey.question'
  • question_type Selection
    related='question_id.question_type'
  • scoring_type Selection
    related='question_id.scoring_type'
  • sequence Integer
    default=10 args: 'Label Sequence order'
  • value Char
    translate=True args: 'Suggested value'
  • value_image Image
    max_height=1024 max_width=1024 args: 'Image'
  • value_image_filename Char
    args: 'Image Filename'
  • value_label Char
    compute='_compute_value_label' help='Answer label as either the value itself if not empty or a letter representing the index of the answer otherwise.' args: 'Value Label'
Public methods (0)

No public methods.

New fields (57)
  • access_mode Selection
    default='public' required=True string='Access Mode' args: [('public', 'Anyone with the link'), ('token', 'Invited people only')]
  • access_token Char
    copy=False default=<expr> args: 'Access Token'
  • active Boolean
    default=True args: 'Active'
  • allowed_survey_types Json
    compute='_compute_allowed_survey_types' string='Allowed survey types'
  • answer_count Integer
    compute='_compute_survey_statistic' args: 'Registered'
  • answer_done_count Integer
    compute='_compute_survey_statistic' args: 'Attempts'
  • answer_duration_avg Float
    compute='_compute_answer_duration_avg' help='Average duration of the survey (in hours)' args: 'Average Duration'
  • answer_score_avg Float
    compute='_compute_survey_statistic' args: 'Avg Score (%)'
  • attempts_limit Integer
    default=1 args: 'Number of attempts'
  • background_image Image
    args: 'Background Image'
  • background_image_url Char
    compute='_compute_background_image_url' args: 'Background Url'
  • certification Boolean
    compute='_compute_certification' precompute=True readonly=False store=True args: 'Is a Certification'
  • certification_badge_id Many2one → gamification.badge
    copy=False index='btree_not_null' args: 'gamification.badge', 'Certification Badge'
  • certification_badge_id_dummy Many2one
    related='certification_badge_id' string='Certification Badge '
  • certification_give_badge Boolean
    compute='_compute_certification_give_badge' copy=False readonly=False store=True args: 'Give Badge'
  • certification_mail_template_id Many2one → mail.template
    domain="[('model', '=', 'survey.user_input')]" help='Automated email sent to the user when they succeed the certification, containing their certification document.' args: 'mail.template', 'Certified Email Template'
  • certification_report_layout Selection
    default='modern_purple' string='Certification template' args: [('modern_purple', 'Modern Purple'), ('modern_blue', 'Modern Blue'), ('modern_gold', 'Modern Gold'), ('classic_purple', 'Classic Purple'), ('classic_blue', 'Classic Blue'), ('classic_gold', 'Classic Gold')]
  • color Integer
    default=0 args: 'Color Index'
  • description Html
    help='The description will be displayed on the home page of the survey. You can use this to give the purpose and guidelines to your candidates before they start it.' sanitize=True sanitize_overridable=True translate=True args: 'Description'
  • description_done Html
    help='This message will be displayed when survey is completed' translate=True args: 'End Message'
  • has_conditional_questions Boolean
    compute='_compute_has_conditional_questions' args: 'Contains conditional questions'
  • is_attempts_limited Boolean
    compute='_compute_is_attempts_limited' help='Check this option if you want to limit the number of attempts per user' readonly=False store=True args: 'Limited number of attempts'
  • is_time_limited Boolean
    args: 'The survey is limited in time'
  • lang_ids Many2many → res.lang
    default=<expr> domain=<expr> help='Leave the field empty to support all installed languages.' string='Languages' args: 'res.lang'
  • page_ids One2many → survey.question
    compute='_compute_page_and_question_ids' string='Pages' args: 'survey.question'
  • progression_mode Selection
    default='percent' help='If Number is selected, it will display the number of questions answered on the total number of question to answer.' string='Display Progress as' args: [('percent', 'Percentage left'), ('number', 'Number')]
  • question_and_page_ids One2many → survey.question
    copy=True string='Sections and Questions' args: 'survey.question', 'survey_id'
  • question_count Integer
    compute='_compute_page_and_question_ids' args: '# Questions'
  • question_ids One2many → survey.question
    compute='_compute_page_and_question_ids' string='Questions' args: 'survey.question'
  • questions_layout Selection
    default='page_per_question' required=True string='Pagination' args: [('page_per_question', 'One page per question'), ('page_per_section', 'One page per section'), ('one_page', 'One page with all the questions')]
  • questions_selection Selection
    default='all' help='If randomized is selected, you can configure the number of random questions by section. This mode is ignored in live session.' required=True string='Question Selection' args: [('all', 'All questions'), ('random', 'Randomized per Section')]
  • restrict_user_ids Many2many → res.users
    domain=[('share', '=', False)] string='Restricted to' tracking=2 args: 'res.users'
  • scoring_max_obtainable Float
    compute='_compute_scoring_max_obtainable' args: 'Maximum obtainable score'
  • scoring_success_min Float
    default=80.0 args: 'Required Score (%)'
  • scoring_type Selection
    compute='_compute_scoring_type' precompute=True readonly=False required=True store=True string='Scoring' args: [('no_scoring', 'No scoring'), ('scoring_with_answers_after_page', 'Scoring with answers after each page'), ('scoring_with_answers', 'Scoring with answers at the end'), ('scoring_without_answers', 'Scoring without answers')]
  • session_answer_count Integer
    compute='_compute_session_answer_count' args: 'Answers Count'
  • session_available Boolean
    compute='_compute_session_available' args: 'Live session available'
  • session_code Char
    compute='_compute_session_code' copy=False help='This code will be used by your attendees to reach your session. Feel free to customize it however you like!' precompute=True readonly=False store=True args: 'Session Code'
  • session_link Char
    compute='_compute_session_link' args: 'Session Link'
  • session_question_answer_count Integer
    compute='_compute_session_question_answer_count' args: 'Question Answers Count'
  • session_question_id Many2one → survey.question
    copy=False help='The current question of the survey session.' string='Current Question' args: 'survey.question'
  • session_question_start_time Datetime
    copy=False help='The time at which the current question has started, used to handle the timer for attendees.' args: 'Current Question Start Time'
  • session_show_leaderboard Boolean
    compute='_compute_session_show_leaderboard' help='Whether or not we want to show the attendees leaderboard for this survey.' args: 'Show Session Leaderboard'
  • session_speed_rating Boolean
    help='Attendees get more points if they answer quickly' args: 'Reward quick answers'
  • session_speed_rating_time_limit Integer
    help='Default time given to receive additional points for right answers' args: 'Time limit (seconds)'
  • session_start_time Datetime
    copy=False args: 'Current Session Start Time'
  • session_state Selection
    copy=False string='Session State' args: [('ready', 'Ready'), ('in_progress', 'In Progress')]
  • success_count Integer
    compute='_compute_survey_statistic' args: 'Success'
  • success_ratio Integer
    compute='_compute_survey_statistic' args: 'Success Ratio (%)'
  • survey_type Selection
    default='custom' required=True string='Survey Type' args: [('survey', 'Survey'), ('live_session', 'Live session'), ('assessment', 'Assessment'), ('custom', 'Custom')]
  • time_limit Float
    default=10 args: 'Time limit (minutes)'
  • title Char
    required=True translate=True args: 'Survey Title'
  • user_id Many2one → res.users
    default=<expr> domain=[('share', '=', False)] string='Responsible' tracking=1 args: 'res.users'
  • user_input_ids One2many → survey.user_input
    readonly=True string='User responses' args: 'survey.user_input', 'survey_id'
  • users_can_go_back Boolean
    help='If checked, users can go back to previous pages.' args: 'Users can go back'
  • users_can_signup Boolean
    compute='_compute_users_can_signup' args: 'Users can signup'
  • users_login_required Boolean
    help='If checked, users have to login before answering even with a valid token.' args: 'Require Login'
Public methods (23)
  • action_archive(self)
  • action_end_session(self)
    The write is sudo'ed because a survey user can end a session even if it's not their own survey.
  • action_open_session_manager(self)
  • action_print_survey(self, answer=None)
    Open the website page with the survey printable view
  • action_result_survey(self)
    Open the website page with the survey results view
  • action_send_survey(self)
    Open a window to compose an email, pre-filled with the survey message
  • action_start_session(self)
    Sets the necessary fields for the session to take place and starts it. The write is sudo'ed because a survey user can start a session even if it's not their own survey.
  • action_start_survey(self, answer=None)
    Open the website page with the survey form
  • action_survey_preview_certification_template(self)
  • action_survey_user_input(self)
  • action_survey_user_input_certified(self)
  • action_survey_user_input_completed(self)
  • action_test_survey(self)
    Open the website page with the survey form into test mode
  • action_unarchive(self)
  • check_validity(self)
  • copy(self, default=None)
    Correctly copy the 'triggering_answer_ids' field from the original to the clone. This needs to be done in post-processing to make sure we get references to the newly created answers from the copy instead of references to the answers of the original. This implementation assumes that the order of created answers will be kept between the original and the clone, using 'zip()' to match the records between the two. Note that when `question_ids` is provided in the default parameter, it falls back to the standard copy, meaning that triggering logic will not be maintained.
  • copy_data(self, default=None)
  • create(self, vals_list)
    @api.model_create_multi
  • default_get(self, fields)
    @api.model
  • get_print_url(self)
  • get_start_short_url(self)
    See controller method docstring for more details.
  • get_start_url(self)
  • write(self, vals)

New fields (0)

No new fields.

Public methods (4)
  • action_load_sample_custom(self)
    @api.model
  • action_load_survey_template_sample(self, template_key)
    @api.model
  • action_show_sample(self)
  • get_survey_templates_data(self)
    @api.model

New fields (27)
  • access_token Char
    copy=False default=<expr> readonly=True required=True args: 'Identification token'
  • attempts_count Integer
    compute='_compute_attempts_info' args: 'Attempts Count'
  • attempts_limit Integer
    related='survey_id.attempts_limit' args: 'Number of attempts'
  • attempts_number Integer
    compute='_compute_attempts_info' args: 'Attempt n°'
  • deadline Datetime
    help='Datetime until customer can open the survey and submit answers' args: 'Deadline'
  • email Char
    readonly=True args: 'Email'
  • end_datetime Datetime
    readonly=True args: 'End date and time'
  • invite_token Char
    copy=False readonly=True args: 'Invite token'
  • is_attempts_limited Boolean
    related='survey_id.is_attempts_limited' args: 'Limited number of attempts'
  • is_session_answer Boolean
    help='Is that user input part of a survey session or not.' args: 'Is in a Session'
  • lang_id Many2one → res.lang
    string='Language' args: 'res.lang'
  • last_displayed_page_id Many2one → survey.question
    string='Last displayed question/page' args: 'survey.question'
  • nickname Char
    help='Attendee nickname, mainly used to identify them in the survey session leaderboard.' args: 'Nickname'
  • partner_id Many2one → res.partner
    index='btree_not_null' readonly=True string='Contact' args: 'res.partner'
  • predefined_question_ids Many2many → survey.question
    readonly=True string='Predefined Questions' args: 'survey.question'
  • question_time_limit_reached Boolean
    compute='_compute_question_time_limit_reached' args: 'Question Time Limit Reached'
  • scoring_percentage Float
    compute='_compute_scoring_values' compute_sudo=True store=True args: 'Score (%)'
  • scoring_success Boolean
    compute='_compute_scoring_success' compute_sudo=True store=True args: 'Quiz Passed'
  • scoring_total Float
    compute='_compute_scoring_values' compute_sudo=True digits=(10, 2) store=True args: 'Total Score'
  • scoring_type Selection
    related='survey_id.scoring_type' string='Scoring'
  • start_datetime Datetime
    readonly=True args: 'Start date and time'
  • state Selection
    default='new' readonly=True string='Status' args: [('new', 'New'), ('in_progress', 'In Progress'), ('done', 'Completed')]
  • survey_first_submitted Boolean
    string='Survey First Submitted'
  • survey_id Many2one → survey.survey
    index=True ondelete='cascade' readonly=True required=True string='Survey' args: 'survey.survey'
  • survey_time_limit_reached Boolean
    compute='_compute_survey_time_limit_reached' args: 'Survey Time Limit Reached'
  • test_entry Boolean
    readonly=True
  • user_input_line_ids One2many → survey.user_input.line
    copy=True string='Answers' args: 'survey.user_input.line', 'user_input_id'
Public methods (6)
  • action_print_answers(self)
    Open the website page with the survey form
  • action_redirect_to_attempts(self)
  • action_resend(self)
  • create(self, vals_list)
    @api.model_create_multi
  • get_print_url(self)
  • get_start_url(self)

New fields (18)
  • answer_is_correct Boolean
    compute='_compute_answer_score' precompute=True store=True args: 'Correct'
  • answer_score Float
    compute='_compute_answer_score' precompute=True store=True args: 'Score'
  • answer_type Selection
    string='Answer Type' args: [('text_box', 'Free Text'), ('char_box', 'Text'), ('numerical_box', 'Number'), ('scale', 'Number'), ('date', 'Date'), ('datetime', 'Datetime'), ('suggestion', 'Suggestion')]
  • lang_id Many2one → res.lang
    related='user_input_id.lang_id' args: 'res.lang'
  • matrix_row_id Many2one → survey.question.answer
    string='Row answer' args: 'survey.question.answer'
  • page_id Many2one
    readonly=False related='question_id.page_id' string='Section'
  • question_id Many2one → survey.question
    index=True ondelete='cascade' required=True string='Question' args: 'survey.question'
  • question_sequence Integer
    related='question_id.sequence' store=True args: 'Sequence'
  • skipped Boolean
    args: 'Skipped'
  • suggested_answer_id Many2one → survey.question.answer
    string='Suggested answer' args: 'survey.question.answer'
  • survey_id Many2one
    readonly=False related='user_input_id.survey_id' store=True string='Survey'
  • user_input_id Many2one → survey.user_input
    index=True ondelete='cascade' required=True string='User Input' args: 'survey.user_input'
  • value_char_box Char
    args: 'Text answer'
  • value_date Date
    args: 'Date answer'
  • value_datetime Datetime
    args: 'Datetime answer'
  • value_numerical_box Float
    args: 'Numerical answer'
  • value_scale Integer
    args: 'Scale value'
  • value_text_box Text
    args: 'Free Text answer'
Public methods (0)

No public methods.

REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/18.0/survey
VERSION
VERSION 3.7
CATEGORY
CATEGORYMarketing/Surveys
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Martin Trigaux, Thibault Delavallée, Xavier ALT, Xavier Morel, Goffin Simon, Géry Debongnie, Aaron Bohy, Jeremy Kersten, qsm-odoo, Odoo Online, Romain Derie, Christophe Monniez, Jorge Pinna Puissant, Julien Castiaux, Aurélien Warnon, Julien Mougenot, Nasreddin Boulif (bon), Prakash Prajapati, Tiffany Chang (tic), Gorash, Pierre Paridans, abd-msyukyu-odoo, Florian Charlier, Abdelouahab (abla), Mathieu Walravens, jorv, damr, Louis Wicket (wil), tsm-odoo, Victor Piryns (pivi), amdi-odoo, Simon Genin (ges), Pierre-Yves Dufays, Naman Shah, Maruan Aguerdouh (magm), Dylan Kiss (dyki), Antoine (ande), Mayurrajsinh Rathod, omra-odoo, Walid (wasa), sesn-odoo, visp-odoo, Jay Savaliya, Astik Singh, Mélanie, Ethan Vincent, bary, Maryam Kia, vava-odoo, adsh-odoo, Lopes Marc (loma), Martin Trigaux (mat), Shubham Thanki, aath-odoo, Louis (wil), mano-odoo, Pratik Raval (PRRA), yagp-odoo, Ryan Cen, Pierre Pulinckx (PIPU), Pierre Lamotte (pila), Pierre Pulinckx (pipu), Pierre Pulinckx, Bastien PIERRE, Hoste Patrick, João Horta Alves, lse-odoo, Krzysztof Magusiak (krma), utma-odoo, Earth Patel, Jérôme Belpaire, josv-odoo, lecr, Soumya M, saurabh
WEBSITE
WEBSITEhttps://www.odoo.com/app/surveys
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 01:25:58
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - auth_signup
    - base_setup
    - base
    - web
    - mail
    - bus
    - web_tour
    - html_editor
    - http_routing
    - gamification
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
Create beautiful surveys and visualize answers
==============================================

It depends on the answers or reviews of some questions by different users. A
survey may have multiple pages. Each page may contain multiple questions and
each question may have multiple answers. Different users may give different
answers of question and according to that survey is done. Partners are also
sent mails with personal token for the invitation of the survey.
    

Code Analysis

Views touched (73)
XML IDNameModelTypeStatus
certification_preview certification_preview ir.ui.view qweb New
certification_report_view certification_report_view ir.ui.view qweb New
certification_report_view_general certification_report_view_general ir.ui.view qweb New
gamification_badge_form_view_simplified gamification.badge.form.view.simplified gamification.badge form New
question_char_box Question: text box ir.ui.view qweb New
question_container Survey: question container ir.ui.view qweb New
question_date Question: date box ir.ui.view qweb New
question_datetime Question: datetime box ir.ui.view qweb New
question_matrix Question: matrix ir.ui.view qweb New
question_multiple_choice Question: multiple choice ir.ui.view qweb New
question_numerical_box Question: numerical box ir.ui.view qweb New
question_result_choice Question: choice result (simple_choice, multiple_choice, scale) ir.ui.view qweb New
question_result_comments Question: comments ir.ui.view qweb New
question_result_matrix Question: matrix result (matrix) ir.ui.view qweb New
question_result_number_or_date_or_datetime Question: number or date (and time) result (numerical_box or date or datetime) ir.ui.view qweb New
question_result_text Question: text result (text_box, char_box) ir.ui.view qweb New
question_scale Question: scale ir.ui.view qweb New
question_simple_choice Question: simple choice ir.ui.view qweb New
question_suggested_value_image Image from the question suggested answer ir.ui.view qweb New
question_table_pagination Survey: statistics table pagination ir.ui.view qweb New
question_text_box Question: free text box ir.ui.view qweb New
res_partner_view_form res.partner.view.form.inherit.survey res.partner xpath Inherits base.view_partner_form
survey.layout Survey Layout ir.ui.view qweb Inherits web.frontend_layout
survey_403_page Survey: custom 403 page ir.ui.view qweb New
survey_access_error Survey: access error ir.ui.view qweb New
survey_auth_required Survey: login required ir.ui.view qweb New
survey_button_form_view Survey: back to form view ir.ui.view qweb New
survey_button_retake Survey: retake button ir.ui.view qweb New
survey_closed_expired Survey: expired ir.ui.view qweb New
survey_fill_form Survey: main page content ir.ui.view qweb New
survey_fill_form_done Survey: finished ir.ui.view qweb New
survey_fill_form_in_progress Survey: form with questions ir.ui.view qweb New
survey_fill_form_start Survey: start form content ir.ui.view qweb New
survey_fill_header Survey: main page header ir.ui.view qweb New
survey_invite_view_form survey.invite.view.form survey.invite form New
survey_navigation Survey: Navigation ir.ui.view qweb New
survey_page_fill Survey: main page (take survey) ir.ui.view qweb New
survey_page_print Survey: print page ir.ui.view qweb New
survey_page_statistics Survey: result statistics page ir.ui.view qweb New
survey_page_statistics_header Survey: result statistics header ir.ui.view qweb New
survey_page_statistics_inner Survey: result statistics content ir.ui.view qweb New
survey_page_statistics_question Question: result statistics ir.ui.view qweb New
survey_progression Survey: Progression ir.ui.view qweb New
survey_question_answer_view_form survey.question.answer.view.form survey.question.answer form New
survey_question_answer_view_search survey.question.answer.view.search survey.question.answer search New
survey_question_answer_view_tree survey.question.answer.view.list survey.question.answer list New
survey_question_form Form view for survey question survey.question form New
survey_question_search Search view for survey question survey.question search New
survey_question_tree List view for survey question survey.question list New
survey_remove_unnecessary_decimals Survey: remove .0 ir.ui.view qweb New
survey_response_line_view_tree survey.user_input.line.view.list survey.user_input.line list New
survey_results_filters Survey: Filter results ir.ui.view qweb New
survey_selection_key survey_selection_key ir.ui.view qweb New
survey_session_code Survey: Access Code page ir.ui.view qweb New
survey_survey_view_activity survey.survey.view.activity survey.survey activity New
survey_survey_view_form survey.survey.view.form survey.survey form New
survey_survey_view_graph survey.survey.view.graph survey.survey graph New
survey_survey_view_kanban survey.survey.view.kanban survey.survey kanban New
survey_survey_view_pivot survey.survey.view.pivot survey.survey pivot New
survey_survey_view_search survey.survey.search survey.survey search New
survey_survey_view_tree survey.survey.view.list survey.survey list New
survey_user_input_line_view_form survey.user_input.line.view.form survey.user_input.line form New
survey_user_input_line_view_search survey.user_input.line.view.search survey.user_input.line search New
survey_user_input_view_form survey.user_input.view.form survey.user_input form New
survey_user_input_view_search survey.user_input.view.search survey.user_input search New
survey_user_input_view_tree survey.user_input.view.list survey.user_input list New
survey_user_input_viuew_kanban survey.user_input.view.kanban survey.user_input kanban New
survey_void_content Survey: void content ir.ui.view qweb New
user_input_session Survey User Input Session ir.ui.view qweb Inherits web.frontend_layout
user_input_session_leaderboard Survey User Input Leaderboard ir.ui.view qweb New
user_input_session_manage Survey: Manage Session ir.ui.view qweb New
user_input_session_manage_content Survey User Input Session Manage ir.ui.view qweb New
user_input_session_open Survey: Open Session ir.ui.view qweb New
Models touched (11)

New fields (2)
  • survey_id Many2one → survey.survey
    compute='_compute_survey_id' store=True args: 'survey.survey', 'Survey'
  • survey_ids One2many → survey.survey
    args: 'survey.survey', 'certification_badge_id', 'Survey Ids'
Public methods (0)

No public methods.

New fields (1)
  • challenge_category Selection
    ondelete={'certification': 'set default'} selection_add=[('certification', 'Certifications')]
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (2)
  • certifications_company_count Integer
    compute='_compute_certifications_company_count' args: 'Company Certifications Count'
  • certifications_count Integer
    compute='_compute_certifications_count' args: 'Certifications Count'
Public methods (1)
  • action_view_certifications(self)

New fields (16)
  • attachment_ids Many2many → ir.attachment
    compute='_compute_attachment_ids' readonly=False store=True string='Attachments' args: 'ir.attachment', 'survey_mail_compose_message_ir_attachments_rel', 'wizard_id', 'attachment_id'
  • author_id Many2one → res.partner
    default=_get_default_author index=True ondelete='set null' args: 'res.partner', 'Author'
  • deadline Datetime
    string='Answer deadline'
  • emails Text
    string='Additional emails'
  • existing_emails Text
    compute='_compute_existing_emails' readonly=True store=False args: 'Existing emails'
  • existing_mode Selection
    default='resend' required=True string='Handle existing' args: [('new', 'New invite'), ('resend', 'Resend invite')]
  • existing_partner_ids Many2many → res.partner
    compute='_compute_existing_partner_ids' readonly=True store=False args: 'res.partner'
  • existing_text Text
    compute='_compute_existing_text' args: 'Resend Comment'
  • mail_server_id Many2one → ir.mail_server
    args: 'ir.mail_server', 'Outgoing mail server'
  • partner_ids Many2many → res.partner
    domain="[ '|', (survey_users_can_signup, '=', 1), '|', (not survey_users_login_required, '=', 1), ('user_ids', '!=', False), ]" string='Recipients' args: 'res.partner', 'survey_invite_partner_ids', 'invite_id', 'partner_id'
  • send_email Boolean
    compute='_compute_send_email' inverse='_inverse_send_email'
  • survey_access_mode Selection
    readonly=True related='survey_id.access_mode'
  • survey_id Many2one → survey.survey
    required=True string='Survey' args: 'survey.survey'
  • survey_start_url Char
    compute='_compute_survey_start_url' args: 'Survey URL'
  • survey_users_can_signup Boolean
    related='survey_id.users_can_signup'
  • survey_users_login_required Boolean
    readonly=True related='survey_id.users_login_required'
Public methods (2)
  • action_invite(self)
    Process the wizard content and proceed with sending the related email(s), rendering any template patterns on the fly if needed
  • create(self, vals_list)
    @api.model_create_multi

New fields (57)
  • allowed_triggering_question_ids Many2many → survey.question
    compute='_compute_allowed_triggering_question_ids' copy=False string='Allowed Triggering Questions' args: 'survey.question'
  • answer_date Date
    help='Correct date answer for this question.' args: 'Correct date answer'
  • answer_datetime Datetime
    help='Correct date and time answer for this question.' args: 'Correct datetime answer'
  • answer_numerical_box Float
    help='Correct number answer for this question.' args: 'Correct numerical answer'
  • answer_score Float
    help='Score value for a correct answer to this question.' args: 'Score'
  • background_image Image
    compute='_compute_background_image' readonly=False store=True args: 'Background Image'
  • background_image_url Char
    compute='_compute_background_image_url' args: 'Background Url'
  • comment_count_as_answer Boolean
    args: 'Comment is an answer'
  • comments_allowed Boolean
    args: 'Show Comments Field'
  • comments_message Char
    translate=True args: 'Comment Message'
  • constr_error_msg Char
    translate=True args: 'Error message'
  • constr_mandatory Boolean
    args: 'Mandatory Answer'
  • description Html
    help='Use this field to add additional explanations about your question or to illustrate it with pictures or a video' sanitize=True sanitize_overridable=True translate=True args: 'Description'
  • has_image_only_suggested_answer Boolean
    compute='_compute_has_image_only_suggested_answer' args: 'Has image only suggested answer'
  • is_page Boolean
    args: 'Is a page?'
  • is_placed_before_trigger Boolean
    compute='_compute_allowed_triggering_question_ids' help='Is this question placed before any of its trigger questions?' string='Is misplaced?'
  • is_scored_question Boolean
    compute='_compute_is_scored_question' copy=True help='Include this question as part of quiz scoring. Requires an answer and answer score to be taken into account.' readonly=False store=True args: 'Scored'
  • is_time_customized Boolean
    args: 'Customized speed rewards'
  • is_time_limited Boolean
    help='Currently only supported for live sessions.' args: 'The question is limited in time'
  • matrix_row_ids One2many → survey.question.answer
    copy=True help='Labels used for proposed choices: rows of matrix' string='Matrix Rows' args: 'survey.question.answer', 'matrix_question_id'
  • matrix_subtype Selection
    default='simple' string='Matrix Type' args: [('simple', 'One choice per row'), ('multiple', 'Multiple choices per row')]
  • page_id Many2one → survey.question
    compute='_compute_page_id' store=True string='Page' args: 'survey.question'
  • question_ids One2many → survey.question
    compute='_compute_question_ids' string='Questions' args: 'survey.question'
  • question_placeholder Char
    compute='_compute_question_placeholder' readonly=False store=True translate=True args: 'Placeholder'
  • question_type Selection
    compute='_compute_question_type' readonly=False store=True string='Question Type' args: [('simple_choice', 'Multiple choice: only one answer'), ('multiple_choice', 'Multiple choice: multiple answers allowed'), ('text_box', 'Multiple Lines Text Box'), ('char_box', 'Single Line Text Box'), ('numerical_box', 'Numerical Value'), ('scale', 'Scale'), ('date', 'Date'), ('datetime', 'Datetime'), ('matrix', 'Matrix')]
  • questions_selection Selection
    help='If randomized is selected, add the number of random questions next to the section.' readonly=True related='survey_id.questions_selection'
  • random_questions_count Integer
    default=1 help='Used on randomized sections to take X random questions from all the questions of that section.' args: '# Questions Randomly Picked'
  • save_as_email Boolean
    compute='_compute_save_as_email' copy=True help="If checked, this option will save the user's answer as its email address." readonly=False store=True args: 'Save as user email'
  • save_as_nickname Boolean
    compute='_compute_save_as_nickname' copy=True help="If checked, this option will save the user's answer as its nickname." readonly=False store=True args: 'Save as user nickname'
  • scale_max Integer
    default=10 args: 'Scale Maximum Value'
  • scale_max_label Char
    translate=True args: 'Scale Maximum Label'
  • scale_mid_label Char
    translate=True args: 'Scale Middle Label'
  • scale_min Integer
    default=0 args: 'Scale Minimum Value'
  • scale_min_label Char
    translate=True args: 'Scale Minimum Label'
  • scoring_type Selection
    readonly=True related='survey_id.scoring_type' string='Scoring Type'
  • sequence Integer
    default=10 args: 'Sequence'
  • session_available Boolean
    readonly=True related='survey_id.session_available' string='Live Session available'
  • suggested_answer_ids One2many → survey.question.answer
    copy=True help='Labels used for proposed choices: simple choice, multiple choice and columns of matrix' string='Types of answers' args: 'survey.question.answer', 'question_id'
  • survey_id Many2one → survey.survey
    ondelete='cascade' string='Survey' args: 'survey.survey'
  • survey_session_speed_rating Boolean
    related='survey_id.session_speed_rating'
  • survey_session_speed_rating_time_limit Integer
    related='survey_id.session_speed_rating_time_limit' string='General Time limit (seconds)'
  • time_limit Integer
    args: 'Time limit (seconds)'
  • title Char
    required=True translate=True args: 'Title'
  • triggering_answer_ids Many2many → survey.question.answer
    copy=False domain="[\n ('question_id.survey_id', '=', survey_id),\n '&', ('question_id.question_type', 'in', ['simple_choice', 'multiple_choice']),\n '|',\n ('question_id.sequence', '<', sequence),\n '&', ('question_id.sequence', '=', sequence), ('question_id.id', '<', id)\n ]" help='Picking any of these answers will trigger this question.\nLeave the field empty if the question should always be displayed.' readonly=False store=True string='Triggering Answers' args: 'survey.question.answer'
  • triggering_question_ids Many2many → survey.question
    compute='_compute_triggering_question_ids' help='Questions containing the triggering answer(s) to display the current question.' store=False string='Triggering Questions' args: 'survey.question'
  • user_input_line_ids One2many → survey.user_input.line
    domain=[('skipped', '=', False)] groups='survey.group_survey_user' string='Answers' args: 'survey.user_input.line', 'question_id'
  • validation_email Boolean
    args: 'Input must be an email'
  • validation_error_msg Char
    translate=True args: 'Validation Error'
  • validation_length_max Integer
    default=0 args: 'Maximum Text Length'
  • validation_length_min Integer
    default=0 args: 'Minimum Text Length'
  • validation_max_date Date
    args: 'Maximum Date'
  • validation_max_datetime Datetime
    args: 'Maximum Datetime'
  • validation_max_float_value Float
    default=0.0 args: 'Maximum value'
  • validation_min_date Date
    args: 'Minimum Date'
  • validation_min_datetime Datetime
    args: 'Minimum Datetime'
  • validation_min_float_value Float
    default=0.0 args: 'Minimum value'
  • validation_required Boolean
    compute='_compute_validation_required' readonly=False store=True args: 'Validate entry'
Public methods (4)
  • copy(self, default=None)
  • create(self, vals_list)
  • default_get(self, fields_list)
    @api.model
  • validate_question(self, answer, comment=None)
    Validate question, depending on question type and parameters for simple choice, text, date and number, answer is simply the answer of the question. For other multiple choices questions, answer is a list of answers (the selected choices or a list of selected answers per question -for matrix type-): - Simple answer : answer = 'example' or 2 or question_answer_id or 2019/10/10 - Multiple choice : answer = [question_answer_id1, question_answer_id2, question_answer_id3] - Matrix: answer = { 'rowId1' : [colId1, colId2,...], 'rowId2' : [colId1, colId3, ...] } return dict {question.id (int): error (str)} -> empty dict if no validation error.

New fields (11)
  • answer_score Float
    help='A positive score indicates a correct choice; a negative or null score indicates a wrong answer' args: 'Score'
  • is_correct Boolean
    args: 'Correct'
  • matrix_question_id Many2one → survey.question
    index='btree_not_null' ondelete='cascade' string='Question (as matrix row)' args: 'survey.question'
  • question_id Many2one → survey.question
    index='btree_not_null' ondelete='cascade' string='Question' args: 'survey.question'
  • question_type Selection
    related='question_id.question_type'
  • scoring_type Selection
    related='question_id.scoring_type'
  • sequence Integer
    default=10 args: 'Label Sequence order'
  • value Char
    translate=True args: 'Suggested value'
  • value_image Image
    max_height=1024 max_width=1024 args: 'Image'
  • value_image_filename Char
    args: 'Image Filename'
  • value_label Char
    compute='_compute_value_label' help='Answer label as either the value itself if not empty or a letter representing the index of the answer otherwise.' args: 'Value Label'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (5)
  • action_load_sample_assessment(self)
    @api.model
  • action_load_sample_custom(self)
    @api.model
  • action_load_sample_live_session(self)
    @api.model
  • action_load_sample_survey(self)
    @api.model
  • action_show_sample(self)

New fields (56)
  • access_mode Selection
    default='public' required=True string='Access Mode' args: [('public', 'Anyone with the link'), ('token', 'Invited people only')]
  • access_token Char
    copy=False default=<expr> args: 'Access Token'
  • active Boolean
    default=True args: 'Active'
  • allowed_survey_types Json
    compute='_compute_allowed_survey_types' string='Allowed survey types'
  • answer_count Integer
    compute='_compute_survey_statistic' args: 'Registered'
  • answer_done_count Integer
    compute='_compute_survey_statistic' args: 'Attempts'
  • answer_duration_avg Float
    compute='_compute_answer_duration_avg' help='Average duration of the survey (in hours)' args: 'Average Duration'
  • answer_score_avg Float
    compute='_compute_survey_statistic' args: 'Avg Score (%)'
  • attempts_limit Integer
    default=1 args: 'Number of attempts'
  • background_image Image
    args: 'Background Image'
  • background_image_url Char
    compute='_compute_background_image_url' args: 'Background Url'
  • certification Boolean
    compute='_compute_certification' precompute=True readonly=False store=True args: 'Is a Certification'
  • certification_badge_id Many2one → gamification.badge
    copy=False args: 'gamification.badge', 'Certification Badge'
  • certification_badge_id_dummy Many2one
    related='certification_badge_id' string='Certification Badge '
  • certification_give_badge Boolean
    compute='_compute_certification_give_badge' copy=False readonly=False store=True args: 'Give Badge'
  • certification_mail_template_id Many2one → mail.template
    domain="[('model', '=', 'survey.user_input')]" help='Automated email sent to the user when they succeed the certification, containing their certification document.' args: 'mail.template', 'Certified Email Template'
  • certification_report_layout Selection
    default='modern_purple' string='Certification template' args: [('modern_purple', 'Modern Purple'), ('modern_blue', 'Modern Blue'), ('modern_gold', 'Modern Gold'), ('classic_purple', 'Classic Purple'), ('classic_blue', 'Classic Blue'), ('classic_gold', 'Classic Gold')]
  • color Integer
    default=0 args: 'Color Index'
  • description Html
    help='The description will be displayed on the home page of the survey. You can use this to give the purpose and guidelines to your candidates before they start it.' sanitize=True sanitize_overridable=True translate=True args: 'Description'
  • description_done Html
    help='This message will be displayed when survey is completed' translate=True args: 'End Message'
  • has_conditional_questions Boolean
    compute='_compute_has_conditional_questions' args: 'Contains conditional questions'
  • is_attempts_limited Boolean
    compute='_compute_is_attempts_limited' help='Check this option if you want to limit the number of attempts per user' readonly=False store=True args: 'Limited number of attempts'
  • is_time_limited Boolean
    args: 'The survey is limited in time'
  • page_ids One2many → survey.question
    compute='_compute_page_and_question_ids' string='Pages' args: 'survey.question'
  • progression_mode Selection
    default='percent' help='If Number is selected, it will display the number of questions answered on the total number of question to answer.' string='Display Progress as' args: [('percent', 'Percentage left'), ('number', 'Number')]
  • question_and_page_ids One2many → survey.question
    copy=True string='Sections and Questions' args: 'survey.question', 'survey_id'
  • question_count Integer
    compute='_compute_page_and_question_ids' args: '# Questions'
  • question_ids One2many → survey.question
    compute='_compute_page_and_question_ids' string='Questions' args: 'survey.question'
  • questions_layout Selection
    default='page_per_question' required=True string='Pagination' args: [('page_per_question', 'One page per question'), ('page_per_section', 'One page per section'), ('one_page', 'One page with all the questions')]
  • questions_selection Selection
    default='all' help='If randomized is selected, you can configure the number of random questions by section. This mode is ignored in live session.' required=True string='Question Selection' args: [('all', 'All questions'), ('random', 'Randomized per Section')]
  • restrict_user_ids Many2many → res.users
    domain=[('share', '=', False)] string='Restricted to' tracking=2 args: 'res.users'
  • scoring_max_obtainable Float
    compute='_compute_scoring_max_obtainable' args: 'Maximum obtainable score'
  • scoring_success_min Float
    default=80.0 args: 'Required Score (%)'
  • scoring_type Selection
    compute='_compute_scoring_type' precompute=True readonly=False required=True store=True string='Scoring' args: [('no_scoring', 'No scoring'), ('scoring_with_answers_after_page', 'Scoring with answers after each page'), ('scoring_with_answers', 'Scoring with answers at the end'), ('scoring_without_answers', 'Scoring without answers')]
  • session_answer_count Integer
    compute='_compute_session_answer_count' args: 'Answers Count'
  • session_available Boolean
    compute='_compute_session_available' args: 'Live session available'
  • session_code Char
    compute='_compute_session_code' copy=False help='This code will be used by your attendees to reach your session. Feel free to customize it however you like!' precompute=True readonly=False store=True args: 'Session Code'
  • session_link Char
    compute='_compute_session_link' args: 'Session Link'
  • session_question_answer_count Integer
    compute='_compute_session_question_answer_count' args: 'Question Answers Count'
  • session_question_id Many2one → survey.question
    copy=False help='The current question of the survey session.' string='Current Question' args: 'survey.question'
  • session_question_start_time Datetime
    copy=False help='The time at which the current question has started, used to handle the timer for attendees.' args: 'Current Question Start Time'
  • session_show_leaderboard Boolean
    compute='_compute_session_show_leaderboard' help='Whether or not we want to show the attendees leaderboard for this survey.' args: 'Show Session Leaderboard'
  • session_speed_rating Boolean
    help='Attendees get more points if they answer quickly' args: 'Reward quick answers'
  • session_speed_rating_time_limit Integer
    help='Default time given to receive additional points for right answers' args: 'Time limit (seconds)'
  • session_start_time Datetime
    copy=False args: 'Current Session Start Time'
  • session_state Selection
    copy=False string='Session State' args: [('ready', 'Ready'), ('in_progress', 'In Progress')]
  • success_count Integer
    compute='_compute_survey_statistic' args: 'Success'
  • success_ratio Integer
    compute='_compute_survey_statistic' args: 'Success Ratio (%)'
  • survey_type Selection
    default='custom' required=True string='Survey Type' args: [('survey', 'Survey'), ('live_session', 'Live session'), ('assessment', 'Assessment'), ('custom', 'Custom')]
  • time_limit Float
    default=10 args: 'Time limit (minutes)'
  • title Char
    required=True translate=True args: 'Survey Title'
  • user_id Many2one → res.users
    default=<expr> domain=[('share', '=', False)] string='Responsible' tracking=1 args: 'res.users'
  • user_input_ids One2many → survey.user_input
    readonly=True string='User responses' args: 'survey.user_input', 'survey_id'
  • users_can_go_back Boolean
    help='If checked, users can go back to previous pages.' args: 'Users can go back'
  • users_can_signup Boolean
    compute='_compute_users_can_signup' args: 'Users can signup'
  • users_login_required Boolean
    help='If checked, users have to login before answering even with a valid token.' args: 'Require Login'
Public methods (22)
  • action_end_session(self)
    The write is sudo'ed because a survey user can end a session even if it's not their own survey.
  • action_open_session_manager(self)
  • action_print_survey(self, answer=None)
    Open the website page with the survey printable view
  • action_result_survey(self)
    Open the website page with the survey results view
  • action_send_survey(self)
    Open a window to compose an email, pre-filled with the survey message
  • action_start_session(self)
    Sets the necessary fields for the session to take place and starts it. The write is sudo'ed because a survey user can start a session even if it's not their own survey.
  • action_start_survey(self, answer=None)
    Open the website page with the survey form
  • action_survey_preview_certification_template(self)
  • action_survey_user_input(self)
  • action_survey_user_input_certified(self)
  • action_survey_user_input_completed(self)
  • action_test_survey(self)
    Open the website page with the survey form into test mode
  • check_validity(self)
  • copy(self, default=None)
    Correctly copy the 'triggering_answer_ids' field from the original to the clone. This needs to be done in post-processing to make sure we get references to the newly created answers from the copy instead of references to the answers of the original. This implementation assumes that the order of created answers will be kept between the original and the clone, using 'zip()' to match the records between the two. Note that when `question_ids` is provided in the default parameter, it falls back to the standard copy, meaning that triggering logic will not be maintained.
  • copy_data(self, default=None)
  • create(self, vals_list)
    @api.model_create_multi
  • default_get(self, fields_list)
    @api.model
  • get_print_url(self)
  • get_start_short_url(self)
    See controller method docstring for more details.
  • get_start_url(self)
  • toggle_active(self)
  • write(self, vals)

New fields (26)
  • access_token Char
    copy=False default=<expr> readonly=True required=True args: 'Identification token'
  • attempts_count Integer
    compute='_compute_attempts_info' args: 'Attempts Count'
  • attempts_limit Integer
    related='survey_id.attempts_limit' args: 'Number of attempts'
  • attempts_number Integer
    compute='_compute_attempts_info' args: 'Attempt n°'
  • deadline Datetime
    help='Datetime until customer can open the survey and submit answers' args: 'Deadline'
  • email Char
    readonly=True args: 'Email'
  • end_datetime Datetime
    readonly=True args: 'End date and time'
  • invite_token Char
    copy=False readonly=True args: 'Invite token'
  • is_attempts_limited Boolean
    related='survey_id.is_attempts_limited' args: 'Limited number of attempts'
  • is_session_answer Boolean
    help='Is that user input part of a survey session or not.' args: 'Is in a Session'
  • last_displayed_page_id Many2one → survey.question
    string='Last displayed question/page' args: 'survey.question'
  • nickname Char
    help='Attendee nickname, mainly used to identify them in the survey session leaderboard.' args: 'Nickname'
  • partner_id Many2one → res.partner
    index='btree_not_null' readonly=True string='Contact' args: 'res.partner'
  • predefined_question_ids Many2many → survey.question
    readonly=True string='Predefined Questions' args: 'survey.question'
  • question_time_limit_reached Boolean
    compute='_compute_question_time_limit_reached' args: 'Question Time Limit Reached'
  • scoring_percentage Float
    compute='_compute_scoring_values' compute_sudo=True store=True args: 'Score (%)'
  • scoring_success Boolean
    compute='_compute_scoring_success' compute_sudo=True store=True args: 'Quizz Passed'
  • scoring_total Float
    compute='_compute_scoring_values' compute_sudo=True digits=(10, 2) store=True args: 'Total Score'
  • scoring_type Selection
    related='survey_id.scoring_type' string='Scoring'
  • start_datetime Datetime
    readonly=True args: 'Start date and time'
  • state Selection
    default='new' readonly=True string='Status' args: [('new', 'New'), ('in_progress', 'In Progress'), ('done', 'Completed')]
  • survey_first_submitted Boolean
    string='Survey First Submitted'
  • survey_id Many2one → survey.survey
    index=True ondelete='cascade' readonly=True required=True string='Survey' args: 'survey.survey'
  • survey_time_limit_reached Boolean
    compute='_compute_survey_time_limit_reached' args: 'Survey Time Limit Reached'
  • test_entry Boolean
    readonly=True
  • user_input_line_ids One2many → survey.user_input.line
    copy=True string='Answers' args: 'survey.user_input.line', 'user_input_id'
Public methods (6)
  • action_print_answers(self)
    Open the website page with the survey form
  • action_redirect_to_attempts(self)
  • action_resend(self)
  • create(self, vals_list)
    @api.model_create_multi
  • get_print_url(self)
  • get_start_url(self)

New fields (17)
  • answer_is_correct Boolean
    args: 'Correct'
  • answer_score Float
    args: 'Score'
  • answer_type Selection
    string='Answer Type' args: [('text_box', 'Free Text'), ('char_box', 'Text'), ('numerical_box', 'Number'), ('scale', 'Number'), ('date', 'Date'), ('datetime', 'Datetime'), ('suggestion', 'Suggestion')]
  • matrix_row_id Many2one → survey.question.answer
    string='Row answer' args: 'survey.question.answer'
  • page_id Many2one
    readonly=False related='question_id.page_id' string='Section'
  • question_id Many2one → survey.question
    index=True ondelete='cascade' required=True string='Question' args: 'survey.question'
  • question_sequence Integer
    related='question_id.sequence' store=True args: 'Sequence'
  • skipped Boolean
    args: 'Skipped'
  • suggested_answer_id Many2one → survey.question.answer
    string='Suggested answer' args: 'survey.question.answer'
  • survey_id Many2one
    readonly=False related='user_input_id.survey_id' store=True string='Survey'
  • user_input_id Many2one → survey.user_input
    index=True ondelete='cascade' required=True string='User Input' args: 'survey.user_input'
  • value_char_box Char
    args: 'Text answer'
  • value_date Date
    args: 'Date answer'
  • value_datetime Datetime
    args: 'Datetime answer'
  • value_numerical_box Float
    args: 'Numerical answer'
  • value_scale Integer
    args: 'Scale value'
  • value_text_box Text
    args: 'Free Text answer'
Public methods (2)
  • create(self, vals_list)
    @api.model_create_multi
  • write(self, vals)
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/17.0/survey
VERSION
VERSION 3.6
CATEGORY
CATEGORYMarketing/Surveys
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSOdoo Translation Bot, Martin Trigaux, Olivier Dony, Thibault Delavallée, Xavier ALT, Xavier Morel, Géry Debongnie, Aaron Bohy, Damien Bouvy, Yannick Tivisse, qsm-odoo, Odoo Online, Romain Derie, Adrien Dieudonne, Christophe Monniez, Jorge Pinna Puissant, Julien Castiaux, Aurélien Warnon, Xavier-Do, Romeo Fragomeli, Adrien Dieudonné, Joseph Caburnay, Samuel Degueldre, Ivan Yelizariev, Nasreddin Boulif (bon), Prakash Prajapati, Tiffany Chang (tic), Rémy Voet (ryv), Gorash, Pierre Paridans, abd-msyukyu-odoo, Romain Estievenart, Benoit Socias, Csaba Tóth, Florian Charlier, Patrick Hoste, Abdelouahab (abla), Mathieu Walravens, Dossogne Bertrand, Renaud Thiry, Ipsita Borisagar, niyasraphy, jorv, Andro Gvivradze, Louis Wicket (wil), Victor Piryns (pivi), amdi-odoo, Pierre-Yves Dufays, Saurabh Mishra, Naman Shah, Maruan Aguerdouh (magm), Dylan Kiss (dyki), Bruno Boi, Antoine (ande), FrancoisGe, Michael (mcm), Mayurrajsinh Rathod, Vivek Pathak, Adrien Schoffeniels, Thomas Josse (thjo), Xavier Bol (xbo), Brieuc-brd, Andrzej(pian), visp-odoo, Astik Singh, Pratik Raval, dasz, Ethan Vincent, bary, Julien Carion (juca), adsh-odoo, Lopes Marc (loma), Martin Trigaux (mat), smna-odoo, aath-odoo, Louis (wil), mano-odoo, Elisabeth Dickinson, Pratik Raval (PRRA), Ryan Cen, Pierre Lamotte (pila), Pierre Pulinckx (pipu), fdardenne, Bastien PIERRE, Sahil Patel, Aditya Sharma, Hoste Patrick, Antoine Boonen (aboo), João Horta Alves, Pulinckx Pierre (PIPU), utma-odoo, Earth Patel, Nishit Prajapati, Jérôme Belpaire, lecr
WEBSITE
WEBSITEhttps://www.odoo.com/app/surveys
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 01:02:09
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - auth_signup
    - base_setup
    - base
    - web
    - mail
    - bus
    - web_tour
    - http_routing
    - gamification
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
Create beautiful surveys and visualize answers
==============================================

It depends on the answers or reviews of some questions by different users. A
survey may have multiple pages. Each page may contain multiple questions and
each question may have multiple answers. Different users may give different
answers of question and according to that survey is done. Partners are also
sent mails with personal token for the invitation of the survey.
    

Code Analysis

Views touched (72)
XML IDNameModelTypeStatus
certification_preview certification_preview ir.ui.view qweb New
certification_report_view certification_report_view ir.ui.view qweb New
certification_report_view_general certification_report_view_general ir.ui.view qweb New
gamification_badge_form_view_simplified gamification.badge.form.view.simplified gamification.badge form New
question_char_box Question: text box ir.ui.view qweb New
question_container Survey: question container ir.ui.view qweb New
question_date Question: date box ir.ui.view qweb New
question_datetime Question: datetime box ir.ui.view qweb New
question_matrix Question: matrix ir.ui.view qweb New
question_multiple_choice Question: multiple choice ir.ui.view qweb New
question_numerical_box Question: numerical box ir.ui.view qweb New
question_result_choice Question: choice result (simple_choice, multiple_choice) ir.ui.view qweb New
question_result_comments Question: comments ir.ui.view qweb New
question_result_matrix Question: matrix result (matrix) ir.ui.view qweb New
question_result_number_or_date_or_datetime Question: number or date (and time) result (numerical_box or date or datetime) ir.ui.view qweb New
question_result_text Question: text result (text_box, char_box) ir.ui.view qweb New
question_simple_choice Question: simple choice ir.ui.view qweb New
question_suggested_value_image Image from the question suggested answer ir.ui.view qweb New
question_table_pagination Survey: statistics table pagination ir.ui.view qweb New
question_text_box Question: free text box ir.ui.view qweb New
res_partner_view_form res.partner.view.form.inherit.survey res.partner xpath Inherits base.view_partner_form
survey.layout Survey Layout ir.ui.view qweb Inherits web.frontend_layout
survey_403_page Survey: custom 403 page ir.ui.view qweb New
survey_access_error Survey: access error ir.ui.view qweb New
survey_auth_required Survey: login required ir.ui.view qweb New
survey_button_form_view Survey: back to form view ir.ui.view qweb New
survey_button_retake Survey: retake button ir.ui.view qweb New
survey_closed_expired Survey: expired ir.ui.view qweb New
survey_fill_form Survey: main page content ir.ui.view qweb New
survey_fill_form_done Survey: finished ir.ui.view qweb New
survey_fill_form_in_progress Survey: form with questions ir.ui.view qweb New
survey_fill_form_start Survey: start form content ir.ui.view qweb New
survey_fill_header Survey: main page header ir.ui.view qweb New
survey_invite_view_form survey.invite.view.form survey.invite form New
survey_navigation Survey: Navigation ir.ui.view qweb New
survey_page_fill Survey: main page (take survey) ir.ui.view qweb New
survey_page_print Survey: print page ir.ui.view qweb New
survey_page_statistics Survey: result statistics page ir.ui.view qweb New
survey_page_statistics_header Survey: result statistics header ir.ui.view qweb New
survey_page_statistics_inner Survey: result statistics content ir.ui.view qweb New
survey_page_statistics_question Question: result statistics ir.ui.view qweb New
survey_progression Survey: Progression ir.ui.view qweb New
survey_question_answer_view_form survey.question.answer.view.form survey.question.answer form New
survey_question_answer_view_search survey.question.answer.view.search survey.question.answer search New
survey_question_answer_view_tree survey.question.answer.view.tree survey.question.answer tree New
survey_question_form Form view for survey question survey.question form New
survey_question_search Search view for survey question survey.question search New
survey_question_tree Tree view for survey question survey.question tree New
survey_remove_unnecessary_decimals Survey: remove .0 ir.ui.view qweb New
survey_response_line_view_tree survey.user_input.line.view.tree survey.user_input.line tree New
survey_results_filters Survey: Filter results ir.ui.view qweb New
survey_selection_key survey_selection_key ir.ui.view qweb New
survey_session_code Survey: Access Code page ir.ui.view qweb New
survey_survey_view_activity survey.survey.view.activity survey.survey activity New
survey_survey_view_form survey.survey.view.form survey.survey form New
survey_survey_view_graph survey.survey.view.graph survey.survey graph New
survey_survey_view_kanban survey.survey.view.kanban survey.survey kanban New
survey_survey_view_pivot survey.survey.view.pivot survey.survey pivot New
survey_survey_view_search survey.survey.search survey.survey search New
survey_survey_view_tree survey.survey.view.tree survey.survey tree New
survey_user_input_line_view_form survey.user_input.line.view.form survey.user_input.line form New
survey_user_input_line_view_search survey.user_input.line.view.search survey.user_input.line search New
survey_user_input_view_form survey.user_input.view.form survey.user_input form New
survey_user_input_view_search survey.user_input.view.search survey.user_input search New
survey_user_input_view_tree survey.user_input.view.tree survey.user_input tree New
survey_user_input_viuew_kanban survey.user_input.view.kanban survey.user_input kanban New
survey_void_content Survey: void content ir.ui.view qweb New
user_input_session Survey User Input Session ir.ui.view qweb Inherits web.frontend_layout
user_input_session_leaderboard Survey User Input Leaderboard ir.ui.view qweb New
user_input_session_manage Survey: Manage Session ir.ui.view qweb New
user_input_session_manage_content Survey User Input Session Manage ir.ui.view qweb New
user_input_session_open Survey: Open Session ir.ui.view qweb New
Models touched (11)

New fields (2)
  • survey_id Many2one → survey.survey
    compute='_compute_survey_id' store=True args: 'survey.survey', 'Survey'
  • survey_ids One2many → survey.survey
    args: 'survey.survey', 'certification_badge_id', 'Survey Ids'
Public methods (0)

No public methods.

New fields (1)
  • challenge_category Selection
    ondelete={'certification': 'set default'} selection_add=[('certification', 'Certifications')]
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (2)
  • certifications_company_count Integer
    compute='_compute_certifications_company_count' args: 'Company Certifications Count'
  • certifications_count Integer
    compute='_compute_certifications_count' args: 'Certifications Count'
Public methods (1)
  • action_view_certifications(self)

New fields (16)
  • attachment_ids Many2many → ir.attachment
    compute='_compute_attachment_ids' readonly=False store=True string='Attachments' args: 'ir.attachment', 'survey_mail_compose_message_ir_attachments_rel', 'wizard_id', 'attachment_id'
  • author_id Many2one → res.partner
    default=_get_default_author index=True ondelete='set null' args: 'res.partner', 'Author'
  • deadline Datetime
    string='Answer deadline'
  • emails Text
    string='Additional emails'
  • existing_emails Text
    compute='_compute_existing_emails' readonly=True store=False args: 'Existing emails'
  • existing_mode Selection
    default='resend' required=True string='Handle existing' args: [('new', 'New invite'), ('resend', 'Resend invite')]
  • existing_partner_ids Many2many → res.partner
    compute='_compute_existing_partner_ids' readonly=True store=False args: 'res.partner'
  • existing_text Text
    compute='_compute_existing_text' args: 'Resend Comment'
  • mail_server_id Many2one → ir.mail_server
    args: 'ir.mail_server', 'Outgoing mail server'
  • partner_ids Many2many → res.partner
    domain="[ '|', (survey_users_can_signup, '=', 1), '|', (not survey_users_login_required, '=', 1), ('user_ids', '!=', False), ]" string='Recipients' args: 'res.partner', 'survey_invite_partner_ids', 'invite_id', 'partner_id'
  • send_email Boolean
    compute='_compute_send_email' inverse='_inverse_send_email'
  • survey_access_mode Selection
    readonly=True related='survey_id.access_mode'
  • survey_id Many2one → survey.survey
    required=True string='Survey' args: 'survey.survey'
  • survey_start_url Char
    compute='_compute_survey_start_url' args: 'Survey URL'
  • survey_users_can_signup Boolean
    related='survey_id.users_can_signup'
  • survey_users_login_required Boolean
    readonly=True related='survey_id.users_login_required'
Public methods (2)
  • action_invite(self)
    Process the wizard content and proceed with sending the related email(s), rendering any template patterns on the fly if needed
  • create(self, vals_list)
    @api.model_create_multi

New fields (47)
  • allowed_triggering_question_ids Many2many → survey.question
    compute='_compute_allowed_triggering_question_ids' copy=False string='Allowed Triggering Questions' args: 'survey.question'
  • answer_date Date
    help='Correct date answer for this question.' args: 'Correct date answer'
  • answer_datetime Datetime
    help='Correct date and time answer for this question.' args: 'Correct datetime answer'
  • answer_numerical_box Float
    help='Correct number answer for this question.' args: 'Correct numerical answer'
  • answer_score Float
    help='Score value for a correct answer to this question.' args: 'Score'
  • background_image Image
    compute='_compute_background_image' readonly=False store=True args: 'Background Image'
  • background_image_url Char
    compute='_compute_background_image_url' args: 'Background Url'
  • comment_count_as_answer Boolean
    args: 'Comment is an answer'
  • comments_allowed Boolean
    args: 'Show Comments Field'
  • comments_message Char
    translate=True args: 'Comment Message'
  • constr_error_msg Char
    translate=True args: 'Error message'
  • constr_mandatory Boolean
    args: 'Mandatory Answer'
  • description Html
    help='Use this field to add additional explanations about your question or to illustrate it with pictures or a video' sanitize=True sanitize_overridable=True translate=True args: 'Description'
  • is_page Boolean
    args: 'Is a page?'
  • is_placed_before_trigger Boolean
    compute='_compute_allowed_triggering_question_ids' help='Is this question placed before any of its trigger questions?' string='Is misplaced?'
  • is_scored_question Boolean
    compute='_compute_is_scored_question' copy=True help='Include this question as part of quiz scoring. Requires an answer and answer score to be taken into account.' readonly=False store=True args: 'Scored'
  • is_time_limited Boolean
    help='Currently only supported for live sessions.' args: 'The question is limited in time'
  • matrix_row_ids One2many → survey.question.answer
    copy=True help='Labels used for proposed choices: rows of matrix' string='Matrix Rows' args: 'survey.question.answer', 'matrix_question_id'
  • matrix_subtype Selection
    default='simple' string='Matrix Type' args: [('simple', 'One choice per row'), ('multiple', 'Multiple choices per row')]
  • page_id Many2one → survey.question
    compute='_compute_page_id' store=True string='Page' args: 'survey.question'
  • question_ids One2many → survey.question
    compute='_compute_question_ids' string='Questions' args: 'survey.question'
  • question_placeholder Char
    compute='_compute_question_placeholder' readonly=False store=True translate=True args: 'Placeholder'
  • question_type Selection
    compute='_compute_question_type' readonly=False store=True string='Question Type' args: [('simple_choice', 'Multiple choice: only one answer'), ('multiple_choice', 'Multiple choice: multiple answers allowed'), ('text_box', 'Multiple Lines Text Box'), ('char_box', 'Single Line Text Box'), ('numerical_box', 'Numerical Value'), ('date', 'Date'), ('datetime', 'Datetime'), ('matrix', 'Matrix')]
  • questions_selection Selection
    help='If randomized is selected, add the number of random questions next to the section.' readonly=True related='survey_id.questions_selection'
  • random_questions_count Integer
    default=1 help='Used on randomized sections to take X random questions from all the questions of that section.' args: '# Questions Randomly Picked'
  • save_as_email Boolean
    compute='_compute_save_as_email' copy=True help="If checked, this option will save the user's answer as its email address." readonly=False store=True args: 'Save as user email'
  • save_as_nickname Boolean
    compute='_compute_save_as_nickname' copy=True help="If checked, this option will save the user's answer as its nickname." readonly=False store=True args: 'Save as user nickname'
  • scoring_type Selection
    readonly=True related='survey_id.scoring_type' string='Scoring Type'
  • sequence Integer
    default=10 args: 'Sequence'
  • suggested_answer_ids One2many → survey.question.answer
    copy=True help='Labels used for proposed choices: simple choice, multiple choice and columns of matrix' string='Types of answers' args: 'survey.question.answer', 'question_id'
  • survey_id Many2one → survey.survey
    ondelete='cascade' string='Survey' args: 'survey.survey'
  • time_limit Integer
    args: 'Time limit (seconds)'
  • title Char
    required=True translate=True args: 'Title'
  • triggering_answer_ids Many2many → survey.question.answer
    copy=False domain="[\n ('question_id.survey_id', '=', survey_id),\n '&', ('question_id.question_type', 'in', ['simple_choice', 'multiple_choice']),\n '|',\n ('question_id.sequence', '<', sequence),\n '&', ('question_id.sequence', '=', sequence), ('question_id.id', '<', id)\n ]" help='Picking any of these answers will trigger this question.\nLeave the field empty if the question should always be displayed.' readonly=False store=True string='Triggering Answers' args: 'survey.question.answer'
  • triggering_question_ids Many2many → survey.question
    compute='_compute_triggering_question_ids' help='Questions containing the triggering answer(s) to display the current question.' store=False string='Triggering Questions' args: 'survey.question'
  • user_input_line_ids One2many → survey.user_input.line
    domain=[('skipped', '=', False)] groups='survey.group_survey_user' string='Answers' args: 'survey.user_input.line', 'question_id'
  • validation_email Boolean
    args: 'Input must be an email'
  • validation_error_msg Char
    translate=True args: 'Validation Error'
  • validation_length_max Integer
    default=0 args: 'Maximum Text Length'
  • validation_length_min Integer
    default=0 args: 'Minimum Text Length'
  • validation_max_date Date
    args: 'Maximum Date'
  • validation_max_datetime Datetime
    args: 'Maximum Datetime'
  • validation_max_float_value Float
    default=0.0 args: 'Maximum value'
  • validation_min_date Date
    args: 'Minimum Date'
  • validation_min_datetime Datetime
    args: 'Minimum Datetime'
  • validation_min_float_value Float
    default=0.0 args: 'Minimum value'
  • validation_required Boolean
    compute='_compute_validation_required' readonly=False store=True args: 'Validate entry'
Public methods (2)
  • copy(self, default=None)
    @api.returns('self', <expr>)
  • validate_question(self, answer, comment=None)
    Validate question, depending on question type and parameters for simple choice, text, date and number, answer is simply the answer of the question. For other multiple choices questions, answer is a list of answers (the selected choices or a list of selected answers per question -for matrix type-): - Simple answer : answer = 'example' or 2 or question_answer_id or 2019/10/10 - Multiple choice : answer = [question_answer_id1, question_answer_id2, question_answer_id3] - Matrix: answer = { 'rowId1' : [colId1, colId2,...], 'rowId2' : [colId1, colId3, ...] } return dict {question.id (int): error (str)} -> empty dict if no validation error.

New fields (10)
  • answer_score Float
    help='A positive score indicates a correct choice; a negative or null score indicates a wrong answer' args: 'Score'
  • is_correct Boolean
    args: 'Correct'
  • matrix_question_id Many2one → survey.question
    index='btree_not_null' ondelete='cascade' string='Question (as matrix row)' args: 'survey.question'
  • question_id Many2one → survey.question
    index='btree_not_null' ondelete='cascade' string='Question' args: 'survey.question'
  • question_type Selection
    related='question_id.question_type'
  • scoring_type Selection
    related='question_id.scoring_type'
  • sequence Integer
    default=10 args: 'Label Sequence order'
  • value Char
    required=True translate=True args: 'Suggested value'
  • value_image Image
    max_height=1024 max_width=1024 args: 'Image'
  • value_image_filename Char
    args: 'Image Filename'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (5)
  • action_load_sample_assessment(self)
    @api.model
  • action_load_sample_custom(self)
    @api.model
  • action_load_sample_live_session(self)
    @api.model
  • action_load_sample_survey(self)
    @api.model
  • action_show_sample(self)

New fields (52)
  • access_mode Selection
    default='public' required=True string='Access Mode' args: [('public', 'Anyone with the link'), ('token', 'Invited people only')]
  • access_token Char
    copy=False default=<expr> args: 'Access Token'
  • active Boolean
    default=True args: 'Active'
  • answer_count Integer
    compute='_compute_survey_statistic' args: 'Registered'
  • answer_done_count Integer
    compute='_compute_survey_statistic' args: 'Attempts'
  • answer_duration_avg Float
    compute='_compute_answer_duration_avg' help='Average duration of the survey (in hours)' args: 'Average Duration'
  • answer_score_avg Float
    compute='_compute_survey_statistic' args: 'Avg Score (%)'
  • attempts_limit Integer
    default=1 args: 'Number of attempts'
  • background_image Image
    args: 'Background Image'
  • background_image_url Char
    compute='_compute_background_image_url' args: 'Background Url'
  • certification Boolean
    compute='_compute_certification' precompute=True readonly=False store=True args: 'Is a Certification'
  • certification_badge_id Many2one → gamification.badge
    copy=False args: 'gamification.badge', 'Certification Badge'
  • certification_badge_id_dummy Many2one
    related='certification_badge_id' string='Certification Badge '
  • certification_give_badge Boolean
    compute='_compute_certification_give_badge' copy=False readonly=False store=True args: 'Give Badge'
  • certification_mail_template_id Many2one → mail.template
    domain="[('model', '=', 'survey.user_input')]" help='Automated email sent to the user when they succeed the certification, containing their certification document.' args: 'mail.template', 'Certified Email Template'
  • certification_report_layout Selection
    default='modern_purple' string='Certification template' args: [('modern_purple', 'Modern Purple'), ('modern_blue', 'Modern Blue'), ('modern_gold', 'Modern Gold'), ('classic_purple', 'Classic Purple'), ('classic_blue', 'Classic Blue'), ('classic_gold', 'Classic Gold')]
  • color Integer
    default=0 args: 'Color Index'
  • description Html
    help='The description will be displayed on the home page of the survey. You can use this to give the purpose and guidelines to your candidates before they start it.' sanitize=True sanitize_overridable=True translate=True args: 'Description'
  • description_done Html
    help='This message will be displayed when survey is completed' translate=True args: 'End Message'
  • has_conditional_questions Boolean
    compute='_compute_has_conditional_questions' args: 'Contains conditional questions'
  • is_attempts_limited Boolean
    compute='_compute_is_attempts_limited' help='Check this option if you want to limit the number of attempts per user' readonly=False store=True args: 'Limited number of attempts'
  • is_time_limited Boolean
    args: 'The survey is limited in time'
  • page_ids One2many → survey.question
    compute='_compute_page_and_question_ids' string='Pages' args: 'survey.question'
  • progression_mode Selection
    default='percent' help='If Number is selected, it will display the number of questions answered on the total number of question to answer.' string='Display Progress as' args: [('percent', 'Percentage left'), ('number', 'Number')]
  • question_and_page_ids One2many → survey.question
    copy=True string='Sections and Questions' args: 'survey.question', 'survey_id'
  • question_count Integer
    compute='_compute_page_and_question_ids' args: '# Questions'
  • question_ids One2many → survey.question
    compute='_compute_page_and_question_ids' string='Questions' args: 'survey.question'
  • questions_layout Selection
    default='page_per_question' required=True string='Pagination' args: [('page_per_question', 'One page per question'), ('page_per_section', 'One page per section'), ('one_page', 'One page with all the questions')]
  • questions_selection Selection
    default='all' help='If randomized is selected, you can configure the number of random questions by section. This mode is ignored in live session.' required=True string='Question Selection' args: [('all', 'All questions'), ('random', 'Randomized per Section')]
  • scoring_max_obtainable Float
    compute='_compute_scoring_max_obtainable' args: 'Maximum obtainable score'
  • scoring_success_min Float
    default=80.0 args: 'Required Score (%)'
  • scoring_type Selection
    compute='_compute_scoring_type' precompute=True readonly=False required=True store=True string='Scoring' args: [('no_scoring', 'No scoring'), ('scoring_with_answers_after_page', 'Scoring with answers after each page'), ('scoring_with_answers', 'Scoring with answers at the end'), ('scoring_without_answers', 'Scoring without answers')]
  • session_answer_count Integer
    compute='_compute_session_answer_count' args: 'Answers Count'
  • session_code Char
    copy=False default=<expr> help='This code will be used by your attendees to reach your session. Feel free to customize it however you like!' args: 'Session Code'
  • session_link Char
    compute='_compute_session_link' args: 'Session Link'
  • session_question_answer_count Integer
    compute='_compute_session_question_answer_count' args: 'Question Answers Count'
  • session_question_id Many2one → survey.question
    copy=False help='The current question of the survey session.' string='Current Question' args: 'survey.question'
  • session_question_start_time Datetime
    copy=False help='The time at which the current question has started, used to handle the timer for attendees.' args: 'Current Question Start Time'
  • session_show_leaderboard Boolean
    compute='_compute_session_show_leaderboard' help='Whether or not we want to show the attendees leaderboard for this survey.' args: 'Show Session Leaderboard'
  • session_speed_rating Boolean
    help='Attendees get more points if they answer quickly' args: 'Reward quick answers'
  • session_start_time Datetime
    copy=False args: 'Current Session Start Time'
  • session_state Selection
    copy=False string='Session State' args: [('ready', 'Ready'), ('in_progress', 'In Progress')]
  • success_count Integer
    compute='_compute_survey_statistic' args: 'Success'
  • success_ratio Integer
    compute='_compute_survey_statistic' args: 'Success Ratio (%)'
  • survey_type Selection
    default='custom' required=True string='Survey Type' args: [('survey', 'Survey'), ('live_session', 'Live session'), ('assessment', 'Assessment'), ('custom', 'Custom')]
  • time_limit Float
    default=10 args: 'Time limit (minutes)'
  • title Char
    required=True translate=True args: 'Survey Title'
  • user_id Many2one → res.users
    default=<expr> domain=[('share', '=', False)] string='Responsible' tracking=True args: 'res.users'
  • user_input_ids One2many → survey.user_input
    groups='survey.group_survey_user' readonly=True string='User responses' args: 'survey.user_input', 'survey_id'
  • users_can_go_back Boolean
    help='If checked, users can go back to previous pages.' args: 'Users can go back'
  • users_can_signup Boolean
    compute='_compute_users_can_signup' args: 'Users can signup'
  • users_login_required Boolean
    help='If checked, users have to login before answering even with a valid token.' args: 'Require Login'
Public methods (22)
  • action_end_session(self)
    The write is sudo'ed because a survey user can end a session even if it's not their own survey.
  • action_open_session_manager(self)
  • action_print_survey(self, answer=None)
    Open the website page with the survey printable view
  • action_result_survey(self)
    Open the website page with the survey results view
  • action_send_survey(self)
    Open a window to compose an email, pre-filled with the survey message
  • action_start_session(self)
    Sets the necessary fields for the session to take place and starts it. The write is sudo'ed because a survey user can start a session even if it's not their own survey.
  • action_start_survey(self, answer=None)
    Open the website page with the survey form
  • action_survey_preview_certification_template(self)
  • action_survey_user_input(self)
  • action_survey_user_input_certified(self)
  • action_survey_user_input_completed(self)
  • action_test_survey(self)
    Open the website page with the survey form into test mode
  • check_validity(self)
  • copy(self, default=None)
    @api.returns('self', <expr>)
    Correctly copy the 'triggering_answer_ids' field from the original to the clone. This needs to be done in post-processing to make sure we get references to the newly created answers from the copy instead of references to the answers of the original. This implementation assumes that the order of created answers will be kept between the original and the clone, using 'zip()' to match the records between the two. Note that when `question_ids` is provided in the default parameter, it falls back to the standard copy, meaning that triggering logic will not be maintained.
  • copy_data(self, default=None)
  • create(self, vals_list)
    @api.model_create_multi
  • default_get(self, fields_list)
    @api.model
  • get_print_url(self)
  • get_start_short_url(self)
    See controller method docstring for more details.
  • get_start_url(self)
  • toggle_active(self)
  • write(self, vals)

New fields (26)
  • access_token Char
    copy=False default=<expr> readonly=True required=True args: 'Identification token'
  • attempts_count Integer
    compute='_compute_attempts_info' args: 'Attempts Count'
  • attempts_limit Integer
    related='survey_id.attempts_limit' args: 'Number of attempts'
  • attempts_number Integer
    compute='_compute_attempts_info' args: 'Attempt n°'
  • deadline Datetime
    help='Datetime until customer can open the survey and submit answers' args: 'Deadline'
  • email Char
    readonly=True args: 'Email'
  • end_datetime Datetime
    readonly=True args: 'End date and time'
  • invite_token Char
    copy=False readonly=True args: 'Invite token'
  • is_attempts_limited Boolean
    related='survey_id.is_attempts_limited' args: 'Limited number of attempts'
  • is_session_answer Boolean
    help='Is that user input part of a survey session or not.' args: 'Is in a Session'
  • last_displayed_page_id Many2one → survey.question
    string='Last displayed question/page' args: 'survey.question'
  • nickname Char
    help='Attendee nickname, mainly used to identify them in the survey session leaderboard.' args: 'Nickname'
  • partner_id Many2one → res.partner
    index='btree_not_null' readonly=True string='Contact' args: 'res.partner'
  • predefined_question_ids Many2many → survey.question
    readonly=True string='Predefined Questions' args: 'survey.question'
  • question_time_limit_reached Boolean
    compute='_compute_question_time_limit_reached' args: 'Question Time Limit Reached'
  • scoring_percentage Float
    compute='_compute_scoring_values' compute_sudo=True store=True args: 'Score (%)'
  • scoring_success Boolean
    compute='_compute_scoring_success' compute_sudo=True store=True args: 'Quizz Passed'
  • scoring_total Float
    compute='_compute_scoring_values' compute_sudo=True store=True args: 'Total Score'
  • scoring_type Selection
    related='survey_id.scoring_type' string='Scoring'
  • start_datetime Datetime
    readonly=True args: 'Start date and time'
  • state Selection
    default='new' readonly=True string='Status' args: [('new', 'Not started yet'), ('in_progress', 'In Progress'), ('done', 'Completed')]
  • survey_first_submitted Boolean
    string='Survey First Submitted'
  • survey_id Many2one → survey.survey
    index=True ondelete='cascade' readonly=True required=True string='Survey' args: 'survey.survey'
  • survey_time_limit_reached Boolean
    compute='_compute_survey_time_limit_reached' args: 'Survey Time Limit Reached'
  • test_entry Boolean
    readonly=True
  • user_input_line_ids One2many → survey.user_input.line
    copy=True string='Answers' args: 'survey.user_input.line', 'user_input_id'
Public methods (6)
  • action_print_answers(self)
    Open the website page with the survey form
  • action_redirect_to_attempts(self)
  • action_resend(self)
  • create(self, vals_list)
    @api.model_create_multi
  • get_print_url(self)
  • get_start_url(self)

New fields (16)
  • answer_is_correct Boolean
    args: 'Correct'
  • answer_score Float
    args: 'Score'
  • answer_type Selection
    string='Answer Type' args: [('text_box', 'Free Text'), ('char_box', 'Text'), ('numerical_box', 'Number'), ('date', 'Date'), ('datetime', 'Datetime'), ('suggestion', 'Suggestion')]
  • matrix_row_id Many2one → survey.question.answer
    string='Row answer' args: 'survey.question.answer'
  • page_id Many2one
    readonly=False related='question_id.page_id' string='Section'
  • question_id Many2one → survey.question
    index=True ondelete='cascade' required=True string='Question' args: 'survey.question'
  • question_sequence Integer
    related='question_id.sequence' store=True args: 'Sequence'
  • skipped Boolean
    args: 'Skipped'
  • suggested_answer_id Many2one → survey.question.answer
    string='Suggested answer' args: 'survey.question.answer'
  • survey_id Many2one
    readonly=False related='user_input_id.survey_id' store=True string='Survey'
  • user_input_id Many2one → survey.user_input
    index=True ondelete='cascade' required=True string='User Input' args: 'survey.user_input'
  • value_char_box Char
    args: 'Text answer'
  • value_date Date
    args: 'Date answer'
  • value_datetime Datetime
    args: 'Datetime answer'
  • value_numerical_box Float
    args: 'Numerical answer'
  • value_text_box Text
    args: 'Free Text answer'
Public methods (2)
  • create(self, vals_list)
    @api.model_create_multi
  • write(self, vals)
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/16.0/survey
VERSION
VERSION 3.5
CATEGORY
CATEGORYMarketing/Surveys
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Martin Trigaux, Fabien Pinckaers, Olivier Dony, Thibault Delavallée, Denis Ledoux, Xavier Morel, Thibault Francois, Aaron Bohy, Damien Bouvy, Yannick Tivisse, qsm-odoo, Dharmraj Jhala, Romain Derie, Adrien Dieudonne, Christophe Monniez, Alexandre Kühn, Julien Castiaux, Aurélien Warnon, Xavier-Do, Romeo Fragomeli, Victor Feyens, Adrien Dieudonné, Sébastien Theys, oco-odoo, Samuel Degueldre, Achraf (abz), David Beguin, Ivan Yelizariev, Nasreddin Boulif (bon), Gorash, Mathieu Duckerts-Antoine, Pierre Paridans, abd-msyukyu-odoo, Romain Estievenart, Kevin Baptiste, Arnaud Baes, Hubert Van de Walle (huvw), Guillaume (gdi), Merlin (megu), Florian Charlier, Patrick Hoste, Abdelouahab (abla), Jinjiu Liu, Mathieu Walravens, Dossogne Bertrand, luvi, dht-odoo, Fabio Barbero, Julien Banken, niyasraphy, jorv, Thomas Lefebvre (thle), Andro Gvivradze, Louis Wicket (wil), tsm-odoo, Mahamadasif Ansari, amdi-odoo, Pierre-Yves Dufays, Saurabh Mishra, Naman Shah, Maruan Aguerdouh (magm), Dylan Kiss (dyki), Sébastien Geelen (sge), Bruno Boi, Antoine (ande), Mitul Shah, Michael (mcm), Mayurrajsinh Rathod, Adrien Schoffeniels, Thomas Josse (thjo), Noe Antoine, Astik Singh, Pratik Raval, Ethan Vincent, Lopes Marc (loma), Martin Trigaux (mat), smna-odoo, Thomas Josse, Pratik Raval (PRRA), umgu-odoo, Aditya Sharma, Hoste Patrick, pish-odoo, Antoine Boonen (aboo), João Horta Alves
WEBSITE
WEBSITEhttps://www.odoo.com/app/surveys
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:40:52
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - auth_signup
    - base_setup
    - base
    - web
    - mail
    - bus
    - web_tour
    - http_routing
    - gamification
    - web_kanban_gauge
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
Create beautiful surveys and visualize answers
==============================================

It depends on the answers or reviews of some questions by different users. A
survey may have multiple pages. Each page may contain multiple questions and
each question may have multiple answers. Different users may give different
answers of question and according to that survey is done. Partners are also
sent mails with personal token for the invitation of the survey.
    

Code Analysis

Views touched (71)
XML IDNameModelTypeStatus
certification_preview certification_preview ir.ui.view qweb New
certification_report_view certification_report_view ir.ui.view qweb New
certification_report_view_classic certification_report_view_classic ir.ui.view qweb New
certification_report_view_modern certification_report_view_modern ir.ui.view qweb New
gamification_badge_form_view_simplified gamification.badge.form.view.simplified gamification.badge form New
question_char_box Question: text box ir.ui.view qweb New
question_container Survey: question container ir.ui.view qweb New
question_date Question: date box ir.ui.view qweb New
question_datetime Question: datetime box ir.ui.view qweb New
question_matrix Question: matrix ir.ui.view qweb New
question_multiple_choice Question: multiple choice ir.ui.view qweb New
question_numerical_box Question: numerical box ir.ui.view qweb New
question_result_choice Question: choice result (simple_choice, multiple_choice) ir.ui.view qweb New
question_result_comments Question: comments ir.ui.view qweb New
question_result_matrix Question: matrix result (matrix) ir.ui.view qweb New
question_result_number_or_date_or_datetime Question: number or date (and time) result (numerical_box or date or datetime) ir.ui.view qweb New
question_result_text Question: text result (text_box, char_box) ir.ui.view qweb New
question_simple_choice Question: simple choice ir.ui.view qweb New
question_suggested_value_image Image from the question suggested answer ir.ui.view qweb New
question_table_pagination Survey: statistics table pagination ir.ui.view qweb New
question_text_box Question: free text box ir.ui.view qweb New
res_partner_view_form res.partner.view.form.inherit.survey res.partner xpath Inherits base.view_partner_form
survey.layout Survey Layout ir.ui.view qweb Inherits web.frontend_layout
survey_403_page Survey: custom 403 page ir.ui.view qweb New
survey_auth_required Survey: login required ir.ui.view qweb New
survey_button_form_view Survey: back to form view ir.ui.view qweb New
survey_button_retake Survey: retake button ir.ui.view qweb New
survey_closed_expired Survey: expired ir.ui.view qweb New
survey_fill_form Survey: main page content ir.ui.view qweb New
survey_fill_form_done Survey: finished ir.ui.view qweb New
survey_fill_form_in_progress Survey: form with questions ir.ui.view qweb New
survey_fill_form_start Survey: start form content ir.ui.view qweb New
survey_fill_header Survey: main page header ir.ui.view qweb New
survey_invite_view_form survey.invite.view.form survey.invite form New
survey_navigation Survey: Navigation ir.ui.view qweb New
survey_page_fill Survey: main page (take survey) ir.ui.view qweb New
survey_page_print Survey: print page ir.ui.view qweb New
survey_page_statistics Survey: result statistics page ir.ui.view qweb New
survey_page_statistics_header Survey: result statistics header ir.ui.view qweb New
survey_page_statistics_inner Survey: result statistics content ir.ui.view qweb New
survey_page_statistics_question Question: result statistics ir.ui.view qweb New
survey_progression Survey: Progression ir.ui.view qweb New
survey_question_answer_view_form survey.question.answer.view.form survey.question.answer form New
survey_question_answer_view_search survey.question.answer.view.search survey.question.answer search New
survey_question_answer_view_tree survey.question.answer.view.tree survey.question.answer tree New
survey_question_form Form view for survey question survey.question form New
survey_question_search Search view for survey question survey.question search New
survey_question_tree Tree view for survey question survey.question tree New
survey_remove_unnecessary_decimals Survey: remove .0 ir.ui.view qweb New
survey_response_line_view_tree survey.user_input.line.view.tree survey.user_input.line tree New
survey_results_filters Survey: Filter results ir.ui.view qweb New
survey_selection_key survey_selection_key ir.ui.view qweb New
survey_session_code Survey: Access Code page ir.ui.view qweb New
survey_survey_view_form survey.survey.view.form survey.survey form New
survey_survey_view_graph survey.survey.view.graph survey.survey graph New
survey_survey_view_kanban survey.survey.view.kanban survey.survey kanban New
survey_survey_view_pivot survey.survey.view.pivot survey.survey pivot New
survey_survey_view_search survey.survey.search survey.survey search New
survey_survey_view_tree survey.survey.view.tree survey.survey tree New
survey_user_input_line_view_form survey.user_input.line.view.form survey.user_input.line form New
survey_user_input_line_view_search survey.user_input.line.view.search survey.user_input.line search New
survey_user_input_view_form survey.user_input.view.form survey.user_input form New
survey_user_input_view_search survey.user_input.view.search survey.user_input search New
survey_user_input_view_tree survey.user_input.view.tree survey.user_input tree New
survey_user_input_viuew_kanban survey.user_input.view.kanban survey.user_input kanban New
survey_void_content Survey: void content ir.ui.view qweb New
user_input_session Survey User Input Session ir.ui.view qweb Inherits web.frontend_layout
user_input_session_leaderboard Survey User Input Leaderboard ir.ui.view qweb New
user_input_session_manage Survey: Manage Session ir.ui.view qweb New
user_input_session_manage_content Survey User Input Session Manage ir.ui.view qweb New
user_input_session_open Survey: Open Session ir.ui.view qweb New
Models touched (11)

New fields (2)
  • survey_id Many2one → survey.survey
    compute='_compute_survey_id' store=True args: 'survey.survey', 'Survey'
  • survey_ids One2many → survey.survey
    args: 'survey.survey', 'certification_badge_id', 'Survey Ids'
Public methods (0)

No public methods.

New fields (1)
  • challenge_category Selection
    ondelete={'certification': 'set default'} selection_add=[('certification', 'Certifications')]
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (2)
  • certifications_company_count Integer
    compute='_compute_certifications_company_count' args: 'Company Certifications Count'
  • certifications_count Integer
    compute='_compute_certifications_count' args: 'Certifications Count'
Public methods (1)
  • action_view_certifications(self)

New fields (16)
  • attachment_ids Many2many → ir.attachment
    compute='_compute_attachment_ids' readonly=False store=True string='Attachments' args: 'ir.attachment', 'survey_mail_compose_message_ir_attachments_rel', 'wizard_id', 'attachment_id'
  • author_id Many2one → res.partner
    default=_get_default_author index=True ondelete='set null' args: 'res.partner', 'Author'
  • deadline Datetime
    string='Answer deadline'
  • email_from Char
    compute='_compute_email_from' readonly=False store=True args: 'From'
  • emails Text
    help='This list of emails of recipients will not be converted in contacts. Emails must be separated by commas, semicolons or newline.' string='Additional emails'
  • existing_emails Text
    compute='_compute_existing_emails' readonly=True store=False args: 'Existing emails'
  • existing_mode Selection
    default='resend' required=True string='Handle existing' args: [('new', 'New invite'), ('resend', 'Resend invite')]
  • existing_partner_ids Many2many → res.partner
    compute='_compute_existing_partner_ids' readonly=True store=False args: 'res.partner'
  • existing_text Text
    compute='_compute_existing_text' readonly=True store=False args: 'Resend Comment'
  • mail_server_id Many2one → ir.mail_server
    args: 'ir.mail_server', 'Outgoing mail server'
  • partner_ids Many2many → res.partner
    domain="[ '|', (survey_users_can_signup, '=', 1), '|', (not survey_users_login_required, '=', 1), ('user_ids', '!=', False), ]" string='Recipients' args: 'res.partner', 'survey_invite_partner_ids', 'invite_id', 'partner_id'
  • survey_access_mode Selection
    readonly=True related='survey_id.access_mode'
  • survey_id Many2one → survey.survey
    required=True string='Survey' args: 'survey.survey'
  • survey_start_url Char
    compute='_compute_survey_start_url' args: 'Survey URL'
  • survey_users_can_signup Boolean
    related='survey_id.users_can_signup'
  • survey_users_login_required Boolean
    readonly=True related='survey_id.users_login_required'
Public methods (2)
  • action_invite(self)
    Process the wizard content and proceed with sending the related email(s), rendering any template patterns on the fly if needed
  • create(self, vals_list)
    @api.model_create_multi

New fields (46)
  • answer_date Date
    help='Correct date answer for this question.' args: 'Correct date answer'
  • answer_datetime Datetime
    help='Correct date and time answer for this question.' args: 'Correct datetime answer'
  • answer_numerical_box Float
    help='Correct number answer for this question.' args: 'Correct numerical answer'
  • answer_score Float
    help='Score value for a correct answer to this question.' args: 'Score'
  • background_image Image
    compute='_compute_background_image' readonly=False store=True args: 'Background Image'
  • background_image_url Char
    compute='_compute_background_image_url' args: 'Background Url'
  • comment_count_as_answer Boolean
    args: 'Comment is an answer'
  • comments_allowed Boolean
    args: 'Show Comments Field'
  • comments_message Char
    translate=True args: 'Comment Message'
  • constr_error_msg Char
    translate=True args: 'Error message'
  • constr_mandatory Boolean
    args: 'Mandatory Answer'
  • description Html
    help='Use this field to add additional explanations about your question or to illustrate it with pictures or a video' sanitize=True sanitize_overridable=True translate=True args: 'Description'
  • is_conditional Boolean
    copy=True help='If checked, this question will be displayed only\n if the specified conditional answer have been selected in a previous question' string='Conditional Display'
  • is_page Boolean
    args: 'Is a page?'
  • is_scored_question Boolean
    compute='_compute_is_scored_question' copy=True help='Include this question as part of quiz scoring. Requires an answer and answer score to be taken into account.' readonly=False store=True args: 'Scored'
  • is_time_limited Boolean
    help='Currently only supported for live sessions.' args: 'The question is limited in time'
  • matrix_row_ids One2many → survey.question.answer
    copy=True help='Labels used for proposed choices: rows of matrix' string='Matrix Rows' args: 'survey.question.answer', 'matrix_question_id'
  • matrix_subtype Selection
    default='simple' string='Matrix Type' args: [('simple', 'One choice per row'), ('multiple', 'Multiple choices per row')]
  • page_id Many2one → survey.question
    compute='_compute_page_id' store=True string='Page' args: 'survey.question'
  • question_ids One2many → survey.question
    compute='_compute_question_ids' string='Questions' args: 'survey.question'
  • question_placeholder Char
    compute='_compute_question_placeholder' readonly=False store=True translate=True args: 'Placeholder'
  • question_type Selection
    compute='_compute_question_type' readonly=False store=True string='Question Type' args: [('simple_choice', 'Multiple choice: only one answer'), ('multiple_choice', 'Multiple choice: multiple answers allowed'), ('text_box', 'Multiple Lines Text Box'), ('char_box', 'Single Line Text Box'), ('numerical_box', 'Numerical Value'), ('date', 'Date'), ('datetime', 'Datetime'), ('matrix', 'Matrix')]
  • questions_selection Selection
    help='If randomized is selected, add the number of random questions next to the section.' readonly=True related='survey_id.questions_selection'
  • random_questions_count Integer
    default=1 help='Used on randomized sections to take X random questions from all the questions of that section.' args: '# Questions Randomly Picked'
  • save_as_email Boolean
    compute='_compute_save_as_email' copy=True help="If checked, this option will save the user's answer as its email address." readonly=False store=True args: 'Save as user email'
  • save_as_nickname Boolean
    compute='_compute_save_as_nickname' copy=True help="If checked, this option will save the user's answer as its nickname." readonly=False store=True args: 'Save as user nickname'
  • scoring_type Selection
    readonly=True related='survey_id.scoring_type' string='Scoring Type'
  • sequence Integer
    default=10 args: 'Sequence'
  • suggested_answer_ids One2many → survey.question.answer
    copy=True help='Labels used for proposed choices: simple choice, multiple choice and columns of matrix' string='Types of answers' args: 'survey.question.answer', 'question_id'
  • survey_id Many2one → survey.survey
    ondelete='cascade' string='Survey' args: 'survey.survey'
  • time_limit Integer
    args: 'Time limit (seconds)'
  • title Char
    required=True translate=True args: 'Title'
  • triggering_answer_id Many2one → survey.question.answer
    compute='_compute_triggering_answer_id' copy=False domain="[('question_id', '=', triggering_question_id)]" help='Answer that will trigger the display of the current question.' readonly=False store=True string='Triggering Answer' args: 'survey.question.answer'
  • triggering_question_id Many2one → survey.question
    compute='_compute_triggering_question_id' copy=False domain="[('survey_id', '=', survey_id), '&', ('question_type', 'in', ['simple_choice', 'multiple_choice']), '|', ('sequence', '<', sequence), '&', ('sequence', '=', sequence), ('id', '<', id)]" help='Question containing the triggering answer to display the current question.' readonly=False store=True string='Triggering Question' args: 'survey.question'
  • user_input_line_ids One2many → survey.user_input.line
    domain=[('skipped', '=', False)] groups='survey.group_survey_user' string='Answers' args: 'survey.user_input.line', 'question_id'
  • validation_email Boolean
    args: 'Input must be an email'
  • validation_error_msg Char
    translate=True args: 'Validation Error message'
  • validation_length_max Integer
    default=0 args: 'Maximum Text Length'
  • validation_length_min Integer
    default=0 args: 'Minimum Text Length'
  • validation_max_date Date
    args: 'Maximum Date'
  • validation_max_datetime Datetime
    args: 'Maximum Datetime'
  • validation_max_float_value Float
    default=0.0 args: 'Maximum value'
  • validation_min_date Date
    args: 'Minimum Date'
  • validation_min_datetime Datetime
    args: 'Minimum Datetime'
  • validation_min_float_value Float
    default=0.0 args: 'Minimum value'
  • validation_required Boolean
    compute='_compute_validation_required' readonly=False store=True args: 'Validate entry'
Public methods (1)
  • validate_question(self, answer, comment=None)
    Validate question, depending on question type and parameters for simple choice, text, date and number, answer is simply the answer of the question. For other multiple choices questions, answer is a list of answers (the selected choices or a list of selected answers per question -for matrix type-): - Simple answer : answer = 'example' or 2 or question_answer_id or 2019/10/10 - Multiple choice : answer = [question_answer_id1, question_answer_id2, question_answer_id3] - Matrix: answer = { 'rowId1' : [colId1, colId2,...], 'rowId2' : [colId1, colId3, ...] } return dict {question.id (int): error (str)} -> empty dict if no validation error.

New fields (10)
  • answer_score Float
    help='A positive score indicates a correct choice; a negative or null score indicates a wrong answer' args: 'Score'
  • is_correct Boolean
    args: 'Correct'
  • matrix_question_id Many2one → survey.question
    ondelete='cascade' string='Question (as matrix row)' args: 'survey.question'
  • question_id Many2one → survey.question
    ondelete='cascade' string='Question' args: 'survey.question'
  • question_type Selection
    related='question_id.question_type'
  • scoring_type Selection
    related='question_id.scoring_type'
  • sequence Integer
    default=10 args: 'Label Sequence order'
  • value Char
    required=True translate=True args: 'Suggested value'
  • value_image Image
    max_height=1024 max_width=1024 args: 'Image'
  • value_image_filename Char
    args: 'Image Filename'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (4)
  • action_load_sample_certification(self)
    @api.model
  • action_load_sample_feedback_form(self)
    @api.model
  • action_load_sample_live_presentation(self)
    @api.model
  • action_show_sample(self)

New fields (50)
  • access_mode Selection
    default='public' required=True string='Access Mode' args: [('public', 'Anyone with the link'), ('token', 'Invited people only')]
  • access_token Char
    copy=False default=<expr> args: 'Access Token'
  • active Boolean
    default=True args: 'Active'
  • answer_count Integer
    compute='_compute_survey_statistic' args: 'Registered'
  • answer_done_count Integer
    compute='_compute_survey_statistic' args: 'Attempts'
  • answer_duration_avg Float
    compute='_compute_answer_duration_avg' help='Average duration of the survey (in hours)' args: 'Average Duration'
  • answer_score_avg Float
    compute='_compute_survey_statistic' args: 'Avg Score (%)'
  • attempts_limit Integer
    default=1 args: 'Number of attempts'
  • background_image Image
    args: 'Background Image'
  • background_image_url Char
    compute='_compute_background_image_url' args: 'Background Url'
  • certification Boolean
    compute='_compute_certification' precompute=True readonly=False store=True args: 'Is a Certification'
  • certification_badge_id Many2one → gamification.badge
    copy=False args: 'gamification.badge', 'Certification Badge'
  • certification_badge_id_dummy Many2one
    related='certification_badge_id' string='Certification Badge '
  • certification_give_badge Boolean
    compute='_compute_certification_give_badge' copy=False readonly=False store=True args: 'Give Badge'
  • certification_mail_template_id Many2one → mail.template
    domain="[('model', '=', 'survey.user_input')]" help='Automated email sent to the user when they succeed the certification, containing their certification document.' args: 'mail.template', 'Certified Email Template'
  • certification_report_layout Selection
    default='modern_purple' string='Certification template' args: [('modern_purple', 'Modern Purple'), ('modern_blue', 'Modern Blue'), ('modern_gold', 'Modern Gold'), ('classic_purple', 'Classic Purple'), ('classic_blue', 'Classic Blue'), ('classic_gold', 'Classic Gold')]
  • color Integer
    default=0 args: 'Color Index'
  • description Html
    help='The description will be displayed on the home page of the survey. You can use this to give the purpose and guidelines to your candidates before they start it.' sanitize=True sanitize_overridable=True translate=True args: 'Description'
  • description_done Html
    help='This message will be displayed when survey is completed' translate=True args: 'End Message'
  • has_conditional_questions Boolean
    compute='_compute_has_conditional_questions' args: 'Contains conditional questions'
  • is_attempts_limited Boolean
    compute='_compute_is_attempts_limited' help='Check this option if you want to limit the number of attempts per user' readonly=False store=True args: 'Limited number of attempts'
  • is_time_limited Boolean
    args: 'The survey is limited in time'
  • page_ids One2many → survey.question
    compute='_compute_page_and_question_ids' string='Pages' args: 'survey.question'
  • progression_mode Selection
    default='percent' help='If Number is selected, it will display the number of questions answered on the total number of question to answer.' string='Display Progress as' args: [('percent', 'Percentage left'), ('number', 'Number')]
  • question_and_page_ids One2many → survey.question
    copy=True string='Sections and Questions' args: 'survey.question', 'survey_id'
  • question_count Integer
    compute='_compute_page_and_question_ids' args: '# Questions'
  • question_ids One2many → survey.question
    compute='_compute_page_and_question_ids' string='Questions' args: 'survey.question'
  • questions_layout Selection
    default='page_per_question' required=True string='Pagination' args: [('page_per_question', 'One page per question'), ('page_per_section', 'One page per section'), ('one_page', 'One page with all the questions')]
  • questions_selection Selection
    default='all' help='If randomized is selected, you can configure the number of random questions by section. This mode is ignored in live session.' required=True string='Question Selection' args: [('all', 'All questions'), ('random', 'Randomized per Section')]
  • scoring_success_min Float
    default=80.0 args: 'Required Score (%)'
  • scoring_type Selection
    compute='_compute_scoring_type' precompute=True readonly=False required=True store=True string='Scoring' args: [('no_scoring', 'No scoring'), ('scoring_with_answers', 'Scoring with answers at the end'), ('scoring_without_answers', 'Scoring without answers at the end')]
  • session_answer_count Integer
    compute='_compute_session_answer_count' args: 'Answers Count'
  • session_code Char
    copy=False default=<expr> help='This code will be used by your attendees to reach your session. Feel free to customize it however you like!' args: 'Session Code'
  • session_link Char
    compute='_compute_session_link' args: 'Session Link'
  • session_question_answer_count Integer
    compute='_compute_session_question_answer_count' args: 'Question Answers Count'
  • session_question_id Many2one → survey.question
    copy=False help='The current question of the survey session.' string='Current Question' args: 'survey.question'
  • session_question_start_time Datetime
    copy=False help='The time at which the current question has started, used to handle the timer for attendees.' args: 'Current Question Start Time'
  • session_show_leaderboard Boolean
    compute='_compute_session_show_leaderboard' help='Whether or not we want to show the attendees leaderboard for this survey.' args: 'Show Session Leaderboard'
  • session_speed_rating Boolean
    help='Attendees get more points if they answer quickly' args: 'Reward quick answers'
  • session_start_time Datetime
    copy=False args: 'Current Session Start Time'
  • session_state Selection
    copy=False string='Session State' args: [('ready', 'Ready'), ('in_progress', 'In Progress')]
  • success_count Integer
    compute='_compute_survey_statistic' args: 'Success'
  • success_ratio Integer
    compute='_compute_survey_statistic' args: 'Success Ratio (%)'
  • time_limit Float
    default=10 args: 'Time limit (minutes)'
  • title Char
    required=True translate=True args: 'Survey Title'
  • user_id Many2one → res.users
    default=<expr> domain=[('share', '=', False)] string='Responsible' tracking=True args: 'res.users'
  • user_input_ids One2many → survey.user_input
    groups='survey.group_survey_user' readonly=True string='User responses' args: 'survey.user_input', 'survey_id'
  • users_can_go_back Boolean
    help='If checked, users can go back to previous pages.' args: 'Users can go back'
  • users_can_signup Boolean
    compute='_compute_users_can_signup' args: 'Users can signup'
  • users_login_required Boolean
    help='If checked, users have to login before answering even with a valid token.' args: 'Require Login'
Public methods (21)
  • action_end_session(self)
    The write is sudo'ed because a survey user can end a session even if it's not their own survey.
  • action_open_session_manager(self)
  • action_print_survey(self, answer=None)
    Open the website page with the survey printable view
  • action_result_survey(self)
    Open the website page with the survey results view
  • action_send_survey(self)
    Open a window to compose an email, pre-filled with the survey message
  • action_start_session(self)
    Sets the necessary fields for the session to take place and starts it. The write is sudo'ed because a survey user can start a session even if it's not their own survey.
  • action_start_survey(self, answer=None)
    Open the website page with the survey form
  • action_survey_preview_certification_template(self)
  • action_survey_user_input(self)
  • action_survey_user_input_certified(self)
  • action_survey_user_input_completed(self)
  • action_test_survey(self)
    Open the website page with the survey form into test mode
  • copy(self, default=None)
    @api.returns('self', <expr>)
    Correctly copy the 'triggering_question_id' and 'triggering_answer_id' fields from the original to the clone. This needs to be done in post-processing to make sure we get references to the newly created answers/questions from the copy instead of references to the answers/questions of the original. This implementation assumes that the order of created questions/answers will be kept between the original and the clone, using 'zip()' to match the records between the two. Note that when question_ids is provided in the default parameter, it falls back to the standard copy.
  • copy_data(self, default=None)
  • create(self, vals_list)
    @api.model_create_multi
  • default_get(self, fields_list)
    @api.model
  • get_print_url(self)
  • get_start_short_url(self)
    See controller method docstring for more details.
  • get_start_url(self)
  • toggle_active(self)
  • write(self, vals)

New fields (25)
  • access_token Char
    copy=False default=<expr> readonly=True required=True args: 'Identification token'
  • attempts_count Integer
    compute='_compute_attempts_info' args: 'Attempts Count'
  • attempts_limit Integer
    related='survey_id.attempts_limit' args: 'Number of attempts'
  • attempts_number Integer
    compute='_compute_attempts_info' args: 'Attempt n°'
  • deadline Datetime
    help='Datetime until customer can open the survey and submit answers' args: 'Deadline'
  • email Char
    readonly=True args: 'Email'
  • end_datetime Datetime
    readonly=True args: 'End date and time'
  • invite_token Char
    copy=False readonly=True args: 'Invite token'
  • is_attempts_limited Boolean
    related='survey_id.is_attempts_limited' args: 'Limited number of attempts'
  • is_session_answer Boolean
    help='Is that user input part of a survey session or not.' args: 'Is in a Session'
  • last_displayed_page_id Many2one → survey.question
    string='Last displayed question/page' args: 'survey.question'
  • nickname Char
    help='Attendee nickname, mainly used to identify them in the survey session leaderboard.' args: 'Nickname'
  • partner_id Many2one → res.partner
    readonly=True string='Contact' args: 'res.partner'
  • predefined_question_ids Many2many → survey.question
    readonly=True string='Predefined Questions' args: 'survey.question'
  • question_time_limit_reached Boolean
    compute='_compute_question_time_limit_reached' args: 'Question Time Limit Reached'
  • scoring_percentage Float
    compute='_compute_scoring_values' compute_sudo=True store=True args: 'Score (%)'
  • scoring_success Boolean
    compute='_compute_scoring_success' compute_sudo=True store=True args: 'Quizz Passed'
  • scoring_total Float
    compute='_compute_scoring_values' compute_sudo=True store=True args: 'Total Score'
  • scoring_type Selection
    related='survey_id.scoring_type' string='Scoring'
  • start_datetime Datetime
    readonly=True args: 'Start date and time'
  • state Selection
    default='new' readonly=True string='Status' args: [('new', 'Not started yet'), ('in_progress', 'In Progress'), ('done', 'Completed')]
  • survey_id Many2one → survey.survey
    ondelete='cascade' readonly=True required=True string='Survey' args: 'survey.survey'
  • survey_time_limit_reached Boolean
    compute='_compute_survey_time_limit_reached' args: 'Survey Time Limit Reached'
  • test_entry Boolean
    readonly=True
  • user_input_line_ids One2many → survey.user_input.line
    copy=True string='Answers' args: 'survey.user_input.line', 'user_input_id'
Public methods (7)
  • action_print_answers(self)
    Open the website page with the survey form
  • action_redirect_to_attempts(self)
  • action_resend(self)
  • create(self, vals_list)
    @api.model_create_multi
  • get_print_url(self)
  • get_start_url(self)
  • save_lines(self, question, answer, comment=None)
    Save answers to questions, depending on question type If an answer already exists for question and user_input_id, it will be overwritten (or deleted for 'choice' questions) (in order to maintain data consistency).

New fields (16)
  • answer_is_correct Boolean
    args: 'Correct'
  • answer_score Float
    args: 'Score'
  • answer_type Selection
    string='Answer Type' args: [('text_box', 'Free Text'), ('char_box', 'Text'), ('numerical_box', 'Number'), ('date', 'Date'), ('datetime', 'Datetime'), ('suggestion', 'Suggestion')]
  • matrix_row_id Many2one → survey.question.answer
    string='Row answer' args: 'survey.question.answer'
  • page_id Many2one
    readonly=False related='question_id.page_id' string='Section'
  • question_id Many2one → survey.question
    ondelete='cascade' required=True string='Question' args: 'survey.question'
  • question_sequence Integer
    related='question_id.sequence' store=True args: 'Sequence'
  • skipped Boolean
    args: 'Skipped'
  • suggested_answer_id Many2one → survey.question.answer
    string='Suggested answer' args: 'survey.question.answer'
  • survey_id Many2one
    readonly=False related='user_input_id.survey_id' store=True string='Survey'
  • user_input_id Many2one → survey.user_input
    index=True ondelete='cascade' required=True string='User Input' args: 'survey.user_input'
  • value_char_box Char
    args: 'Text answer'
  • value_date Date
    args: 'Date answer'
  • value_datetime Datetime
    args: 'Datetime answer'
  • value_numerical_box Float
    args: 'Numerical answer'
  • value_text_box Text
    args: 'Free Text answer'
Public methods (2)
  • create(self, vals_list)
    @api.model_create_multi
  • write(self, vals)
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/15.0/survey
VERSION
VERSION 3.4
CATEGORY
CATEGORYMarketing/Surveys
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Martin Trigaux, Thibault Delavallée, Nicolas Lempereur, Aaron Bohy, Jeremy Kersten, Dharmraj Jhala, Romain Derie, Adrien Dieudonne, Christophe Monniez, Julien Castiaux, Aurélien Warnon, Xavier-Do, Victor Feyens, Sébastien Theys, alt-odoo, oco-odoo, Julien Mougenot, Debauche Stéphane, std-odoo, Achraf (abz), David Beguin, Adrien Widart, Ivan Yelizariev, Jérémy Hennecart, Nasreddin Boulif (bon), nie, Tiffany Chang (tic), Djamel (otd), abd-msyukyu-odoo, Kevin Baptiste, Arnaud Baes, Hubert Van de Walle (huvw), sofiagvaladze, Merlin (megu), Florian Charlier, Abdelouahab (abla), Nicolas Bayet, Jinjiu Liu, Michael Mattiello (mcm), dht-odoo, Fabio Barbero, jorv, Thomas Lefebvre (thle), Andro Gvivradze, Louis Wicket (wil), Mahamadasif Ansari, miad-odoo, amdi-odoo, Simon Genin (ges), Pierre-Yves Dufays, Saurabh Mishra, Maruan Aguerdouh (magm), Sébastien Geelen (sge), Mitul Shah, Vivek Pathak, Adrien Schoffeniels, Thomas Josse (thjo), Lopes Marc (loma), Martin Trigaux (mat), smna-odoo
WEBSITE
WEBSITEhttps://www.odoo.com/app/surveys
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:25:29
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - auth_signup
    - base_setup
    - base
    - web
    - mail
    - bus
    - web_tour
    - http_routing
    - gamification
    - web_kanban_gauge
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
Create beautiful surveys and visualize answers
==============================================

It depends on the answers or reviews of some questions by different users. A
survey may have multiple pages. Each page may contain multiple questions and
each question may have multiple answers. Different users may give different
answers of question and according to that survey is done. Partners are also
sent mails with personal token for the invitation of the survey.
    

Code Analysis

Views touched (66)
XML IDNameModelTypeStatus
certification_preview certification_preview ir.ui.view qweb New
certification_report_view certification_report_view ir.ui.view qweb New
certification_report_view_classic certification_report_view_classic ir.ui.view qweb New
certification_report_view_modern certification_report_view_modern ir.ui.view qweb New
gamification_badge_form_view_simplified gamification.badge.form.view.simplified gamification.badge form New
question_char_box Question: text box ir.ui.view qweb New
question_container Survey: question container ir.ui.view qweb New
question_date Question: date box ir.ui.view qweb New
question_datetime Question: datetime box ir.ui.view qweb New
question_matrix Question: matrix ir.ui.view qweb New
question_multiple_choice Question: multiple choice ir.ui.view qweb New
question_numerical_box Question: numerical box ir.ui.view qweb New
question_result_choice Question: choice result (simple_choice, multiple_choice) ir.ui.view qweb New
question_result_comments Question: comments ir.ui.view qweb New
question_result_matrix Question: matrix result (matrix) ir.ui.view qweb New
question_result_number_or_date Question: number or date result (numerical_box or date) ir.ui.view qweb New
question_result_text Question: text result (text_box, char_box, datetime) ir.ui.view qweb New
question_simple_choice Question: simple choice ir.ui.view qweb New
question_suggested_value_image Image from the question suggested answer ir.ui.view qweb New
question_table_pagination Survey: statistics table pagination ir.ui.view qweb New
question_text_box Question: free text box ir.ui.view qweb New
res_partner_view_form res.partner.view.form.inherit.survey res.partner xpath Inherits base.view_partner_form
survey.layout Survey Layout ir.ui.view qweb Inherits web.frontend_layout
survey_403_page Survey: custom 403 page ir.ui.view qweb New
survey_auth_required Survey: login required ir.ui.view qweb New
survey_button_form_view Survey: back to form view ir.ui.view qweb New
survey_button_retake Survey: retake button ir.ui.view qweb New
survey_closed_expired Survey: expired ir.ui.view qweb New
survey_fill_form Survey: main page content ir.ui.view qweb New
survey_fill_form_done Survey: finished ir.ui.view qweb New
survey_fill_form_in_progress Survey: form with questions ir.ui.view qweb New
survey_fill_form_start Survey: start form content ir.ui.view qweb New
survey_fill_header Survey: main page header ir.ui.view qweb New
survey_form survey.survey.view.form survey.survey form New
survey_invite_view_form survey.invite.view.form survey.invite form New
survey_kanban survey.survey.view.kanban survey.survey kanban New
survey_navigation Survey: Navigation ir.ui.view qweb New
survey_page_fill Survey: main page (take survey) ir.ui.view qweb New
survey_page_print Survey: print page ir.ui.view qweb New
survey_page_statistics Survey: result statistics page ir.ui.view qweb New
survey_page_statistics_header Survey: result statistics header ir.ui.view qweb New
survey_page_statistics_inner Survey: result statistics content ir.ui.view qweb New
survey_page_statistics_question Question: result statistics ir.ui.view qweb New
survey_progression Survey: Progression ir.ui.view qweb New
survey_question_answer_view_search survey.question.answer.view.search survey.question.answer search New
survey_question_answer_view_tree survey.question.answer.view.tree survey.question.answer tree New
survey_question_form Form view for survey question survey.question form New
survey_question_search Search view for survey question survey.question search New
survey_question_tree Tree view for survey question survey.question tree New
survey_response_line_view_tree survey.user_input.line.view.tree survey.user_input.line tree New
survey_selection_key survey_selection_key ir.ui.view qweb New
survey_session_code Survey: Access Code page ir.ui.view qweb New
survey_survey_view_search survey.survey.search survey.survey search New
survey_tree survey.survey.view.tree survey.survey tree New
survey_user_input_line_view_form survey.user_input.line.view.form survey.user_input.line form New
survey_user_input_line_view_search survey.user_input.line.view.search survey.user_input.line search New
survey_user_input_view_form survey.user_input.view.form survey.user_input form New
survey_user_input_view_search survey.user_input.view.search survey.user_input search New
survey_user_input_view_tree survey.user_input.view.tree survey.user_input tree New
survey_user_input_viuew_kanban survey.user_input.view.kanban survey.user_input kanban New
survey_void_content Survey: void content ir.ui.view qweb New
user_input_session Survey User Input Session ir.ui.view qweb Inherits web.frontend_layout
user_input_session_leaderboard Survey User Input Leaderboard ir.ui.view qweb New
user_input_session_manage Survey: Manage Session ir.ui.view qweb New
user_input_session_manage_content Survey User Input Session Manage ir.ui.view qweb New
user_input_session_open Survey: Open Session ir.ui.view qweb New
Models touched (9)

New fields (2)
  • survey_id Many2one → survey.survey
    compute='_compute_survey_id' store=True args: 'survey.survey', 'Survey'
  • survey_ids One2many → survey.survey
    args: 'survey.survey', 'certification_badge_id', 'Survey Ids'
Public methods (0)

No public methods.

New fields (1)
  • challenge_category Selection
    ondelete={'certification': 'set default'} selection_add=[('certification', 'Certifications')]
Public methods (0)

No public methods.

New fields (2)
  • certifications_company_count Integer
    compute='_compute_certifications_company_count' args: 'Company Certifications Count'
  • certifications_count Integer
    compute='_compute_certifications_count' args: 'Certifications Count'
Public methods (1)
  • action_view_certifications(self)

New fields (16)
  • attachment_ids Many2many → ir.attachment
    string='Attachments' args: 'ir.attachment', 'survey_mail_compose_message_ir_attachments_rel', 'wizard_id', 'attachment_id'
  • author_id Many2one → res.partner
    default=_get_default_author help='Author of the message.' index=True ondelete='set null' args: 'res.partner', 'Author'
  • deadline Datetime
    string='Answer deadline'
  • email_from Char
    compute='_compute_email_from' help='Email address of the sender.' readonly=False store=True args: 'From'
  • emails Text
    help='This list of emails of recipients will not be converted in contacts. Emails must be separated by commas, semicolons or newline.' string='Additional emails'
  • existing_emails Text
    compute='_compute_existing_emails' readonly=True store=False args: 'Existing emails'
  • existing_mode Selection
    default='resend' required=True string='Handle existing' args: [('new', 'New invite'), ('resend', 'Resend invite')]
  • existing_partner_ids Many2many → res.partner
    compute='_compute_existing_partner_ids' readonly=True store=False args: 'res.partner'
  • existing_text Text
    compute='_compute_existing_text' readonly=True store=False args: 'Resend Comment'
  • mail_server_id Many2one → ir.mail_server
    args: 'ir.mail_server', 'Outgoing mail server'
  • partner_ids Many2many → res.partner
    domain="[\n '|', (survey_users_can_signup, '=', 1),\n '|', (not survey_users_login_required, '=', 1),\n ('user_ids', '!=', False),\n ]" string='Recipients' args: 'res.partner', 'survey_invite_partner_ids', 'invite_id', 'partner_id'
  • survey_access_mode Selection
    readonly=True related='survey_id.access_mode'
  • survey_id Many2one → survey.survey
    required=True string='Survey' args: 'survey.survey'
  • survey_start_url Char
    compute='_compute_survey_start_url' args: 'Survey URL'
  • survey_users_can_signup Boolean
    related='survey_id.users_can_signup'
  • survey_users_login_required Boolean
    readonly=True related='survey_id.users_login_required'
Public methods (2)
  • action_invite(self)
    Process the wizard content and proceed with sending the related email(s), rendering any template patterns on the fly if needed
  • create(self, vals_list)
    @api.model_create_multi

New fields (45)
  • allow_value_image Boolean
    help='Display images in addition to answer label. Valid only for simple / multiple choice questions.' args: 'Images on answers'
  • answer_date Date
    help='Correct date answer for this question.' args: 'Correct date answer'
  • answer_datetime Datetime
    help='Correct date and time answer for this question.' args: 'Correct datetime answer'
  • answer_numerical_box Float
    help='Correct number answer for this question.' args: 'Correct numerical answer'
  • answer_score Float
    help='Score value for a correct answer to this question.' args: 'Score'
  • column_nb Selection
    default='12' help='These options refer to col-xx-[12|6|4|3|2] classes in Bootstrap for dropdown-based simple and multiple choice questions.' string='Number of columns' args: [('12', '1'), ('6', '2'), ('4', '3'), ('3', '4'), ('2', '6')]
  • comment_count_as_answer Boolean
    args: 'Comment Field is an Answer Choice'
  • comments_allowed Boolean
    args: 'Show Comments Field'
  • comments_message Char
    default=<expr> translate=True args: 'Comment Message'
  • constr_error_msg Char
    default=<expr> translate=True args: 'Error message'
  • constr_mandatory Boolean
    args: 'Mandatory Answer'
  • description Html
    help='Use this field to add additional explanations about your question or to illustrate it with pictures or a video' sanitize=False translate=True args: 'Description'
  • is_conditional Boolean
    copy=False help='If checked, this question will be displayed only \n if the specified conditional answer have been selected in a previous question' string='Conditional Display'
  • is_page Boolean
    args: 'Is a page?'
  • is_scored_question Boolean
    compute='_compute_is_scored_question' copy=True help='Include this question as part of quiz scoring. Requires an answer and answer score to be taken into account.' readonly=False store=True args: 'Scored'
  • is_time_limited Boolean
    help='Currently only supported for live sessions.' args: 'The question is limited in time'
  • matrix_row_ids One2many → survey.question.answer
    copy=True help='Labels used for proposed choices: rows of matrix' string='Matrix Rows' args: 'survey.question.answer', 'matrix_question_id'
  • matrix_subtype Selection
    default='simple' string='Matrix Type' args: [('simple', 'One choice per row'), ('multiple', 'Multiple choices per row')]
  • page_id Many2one → survey.question
    compute='_compute_page_id' store=True string='Page' args: 'survey.question'
  • question_ids One2many → survey.question
    compute='_compute_question_ids' string='Questions' args: 'survey.question'
  • question_type Selection
    compute='_compute_question_type' readonly=False store=True string='Question Type' args: [('text_box', 'Multiple Lines Text Box'), ('char_box', 'Single Line Text Box'), ('numerical_box', 'Numerical Value'), ('date', 'Date'), ('datetime', 'Datetime'), ('simple_choice', 'Multiple choice: only one answer'), ('multiple_choice', 'Multiple choice: multiple answers allowed'), ('matrix', 'Matrix')]
  • questions_selection Selection
    help='If randomized is selected, add the number of random questions next to the section.' readonly=True related='survey_id.questions_selection'
  • random_questions_count Integer
    default=1 help='Used on randomized sections to take X random questions from all the questions of that section.' args: 'Random questions count'
  • save_as_email Boolean
    compute='_compute_save_as_email' copy=True help="If checked, this option will save the user's answer as its email address." readonly=False store=True args: 'Save as user email'
  • save_as_nickname Boolean
    compute='_compute_save_as_nickname' copy=True help="If checked, this option will save the user's answer as its nickname." readonly=False store=True args: 'Save as user nickname'
  • scoring_type Selection
    readonly=True related='survey_id.scoring_type' string='Scoring Type'
  • sequence Integer
    default=10 args: 'Sequence'
  • suggested_answer_ids One2many → survey.question.answer
    copy=True help='Labels used for proposed choices: simple choice, multiple choice and columns of matrix' string='Types of answers' args: 'survey.question.answer', 'question_id'
  • survey_id Many2one → survey.survey
    ondelete='cascade' string='Survey' args: 'survey.survey'
  • time_limit Integer
    args: 'Time limit (seconds)'
  • title Char
    required=True translate=True args: 'Title'
  • triggering_answer_id Many2one → survey.question.answer
    compute='_compute_triggering_answer_id' copy=False domain="[('question_id', '=', triggering_question_id)]" help='Answer that will trigger the display of the current question.' readonly=False store=True string='Triggering Answer' args: 'survey.question.answer'
  • triggering_question_id Many2one → survey.question
    compute='_compute_triggering_question_id' copy=False domain="[('survey_id', '=', survey_id),\n '&', ('question_type', 'in', ['simple_choice', 'multiple_choice']),\n '|',\n ('sequence', '<', sequence),\n '&', ('sequence', '=', sequence), ('id', '<', id)]" help='Question containing the triggering answer to display the current question.' readonly=False store=True string='Triggering Question' args: 'survey.question'
  • user_input_line_ids One2many → survey.user_input.line
    domain=[('skipped', '=', False)] groups='survey.group_survey_user' string='Answers' args: 'survey.user_input.line', 'question_id'
  • validation_email Boolean
    args: 'Input must be an email'
  • validation_error_msg Char
    default=<expr> translate=True args: 'Validation Error message'
  • validation_length_max Integer
    default=0 args: 'Maximum Text Length'
  • validation_length_min Integer
    default=0 args: 'Minimum Text Length'
  • validation_max_date Date
    args: 'Maximum Date'
  • validation_max_datetime Datetime
    args: 'Maximum Datetime'
  • validation_max_float_value Float
    default=0.0 args: 'Maximum value'
  • validation_min_date Date
    args: 'Minimum Date'
  • validation_min_datetime Datetime
    args: 'Minimum Datetime'
  • validation_min_float_value Float
    default=0.0 args: 'Minimum value'
  • validation_required Boolean
    args: 'Validate entry'
Public methods (2)
  • default_get(self, fields)
    @api.model
  • validate_question(self, answer, comment=None)
    Validate question, depending on question type and parameters for simple choice, text, date and number, answer is simply the answer of the question. For other multiple choices questions, answer is a list of answers (the selected choices or a list of selected answers per question -for matrix type-): - Simple answer : answer = 'example' or 2 or question_answer_id or 2019/10/10 - Multiple choice : answer = [question_answer_id1, question_answer_id2, question_answer_id3] - Matrix: answer = { 'rowId1' : [colId1, colId2,...], 'rowId2' : [colId1, colId3, ...] } return dict {question.id (int): error (str)} -> empty dict if no validation error.

New fields (7)
  • answer_score Float
    help='A positive score indicates a correct choice; a negative or null score indicates a wrong answer' args: 'Score for this choice'
  • is_correct Boolean
    args: 'Is a correct answer'
  • matrix_question_id Many2one → survey.question
    ondelete='cascade' string='Question (as matrix row)' args: 'survey.question'
  • question_id Many2one → survey.question
    ondelete='cascade' string='Question' args: 'survey.question'
  • sequence Integer
    default=10 args: 'Label Sequence order'
  • value Char
    required=True translate=True args: 'Suggested value'
  • value_image Image
    max_height=256 max_width=256 args: 'Image'
Public methods (0)

No public methods.

New fields (48)
  • access_mode Selection
    default='public' required=True string='Access Mode' args: [('public', 'Anyone with the link'), ('token', 'Invited people only')]
  • access_token Char
    copy=False default=<expr> args: 'Access Token'
  • active Boolean
    default=True args: 'Active'
  • answer_count Integer
    compute='_compute_survey_statistic' args: 'Registered'
  • answer_done_count Integer
    compute='_compute_survey_statistic' args: 'Attempts'
  • answer_duration_avg Float
    compute='_compute_answer_duration_avg' help='Average duration of the survey (in hours)' args: 'Average Duration'
  • answer_score_avg Float
    compute='_compute_survey_statistic' args: 'Avg Score %'
  • attempts_limit Integer
    default=1 args: 'Number of attempts'
  • background_image Binary
    args: 'Background Image'
  • certification Boolean
    compute='_compute_certification' readonly=False store=True args: 'Is a Certification'
  • certification_badge_id Many2one → gamification.badge
    copy=False args: 'gamification.badge', 'Certification Badge'
  • certification_badge_id_dummy Many2one
    related='certification_badge_id' string='Certification Badge '
  • certification_give_badge Boolean
    compute='_compute_certification_give_badge' copy=False readonly=False store=True args: 'Give Badge'
  • certification_mail_template_id Many2one → mail.template
    domain="[('model', '=', 'survey.user_input')]" help='Automated email sent to the user when he succeeds the certification, containing his certification document.' args: 'mail.template', 'Email Template'
  • certification_report_layout Selection
    default='modern_purple' string='Certification template' args: [('modern_purple', 'Modern Purple'), ('modern_blue', 'Modern Blue'), ('modern_gold', 'Modern Gold'), ('classic_purple', 'Classic Purple'), ('classic_blue', 'Classic Blue'), ('classic_gold', 'Classic Gold')]
  • color Integer
    default=0 args: 'Color Index'
  • description Html
    help='The description will be displayed on the home page of the survey. You can use this to give the purpose and guidelines to your candidates before they start it.' sanitize=False translate=True args: 'Description'
  • description_done Html
    help='This message will be displayed when survey is completed' translate=True args: 'End Message'
  • has_conditional_questions Boolean
    compute='_compute_has_conditional_questions' args: 'Contains conditional questions'
  • is_attempts_limited Boolean
    compute='_compute_is_attempts_limited' help='Check this option if you want to limit the number of attempts per user' readonly=False store=True args: 'Limited number of attempts'
  • is_time_limited Boolean
    args: 'The survey is limited in time'
  • page_ids One2many → survey.question
    compute='_compute_page_and_question_ids' string='Pages' args: 'survey.question'
  • progression_mode Selection
    default='percent' help='If Number is selected, it will display the number of questions answered on the total number of question to answer.' string='Progression Mode' args: [('percent', 'Percentage'), ('number', 'Number')]
  • question_and_page_ids One2many → survey.question
    copy=True string='Sections and Questions' args: 'survey.question', 'survey_id'
  • question_ids One2many → survey.question
    compute='_compute_page_and_question_ids' string='Questions' args: 'survey.question'
  • questions_layout Selection
    default='one_page' required=True string='Layout' args: [('one_page', 'One page with all the questions'), ('page_per_section', 'One page per section'), ('page_per_question', 'One page per question')]
  • questions_selection Selection
    default='all' help='If randomized is selected, you can configure the number of random questions by section. This mode is ignored in live session.' required=True string='Selection' args: [('all', 'All questions'), ('random', 'Randomized per section')]
  • scoring_success_min Float
    default=80.0 args: 'Success %'
  • scoring_type Selection
    default='no_scoring' required=True string='Scoring' args: [('no_scoring', 'No scoring'), ('scoring_with_answers', 'Scoring with answers at the end'), ('scoring_without_answers', 'Scoring without answers at the end')]
  • session_answer_count Integer
    compute='_compute_session_answer_count' args: 'Answers Count'
  • session_code Char
    copy=False default=<expr> help='This code will be used by your attendees to reach your session. Feel free to customize it however you like!' args: 'Session Code'
  • session_link Char
    compute='_compute_session_link' args: 'Session Link'
  • session_question_answer_count Integer
    compute='_compute_session_question_answer_count' args: 'Question Answers Count'
  • session_question_id Many2one → survey.question
    copy=False help='The current question of the survey session.' string='Current Question' args: 'survey.question'
  • session_question_start_time Datetime
    copy=False help='The time at which the current question has started, used to handle the timer for attendees.' args: 'Current Question Start Time'
  • session_show_leaderboard Boolean
    compute='_compute_session_show_leaderboard' help='Whether or not we want to show the attendees leaderboard for this survey.' args: 'Show Session Leaderboard'
  • session_speed_rating Boolean
    help='Attendees get more points if they answer quickly' args: 'Reward quick answers'
  • session_start_time Datetime
    copy=False args: 'Current Session Start Time'
  • session_state Selection
    copy=False string='Session State' args: [('ready', 'Ready'), ('in_progress', 'In Progress')]
  • success_count Integer
    compute='_compute_survey_statistic' args: 'Success'
  • success_ratio Integer
    compute='_compute_survey_statistic' args: 'Success Ratio'
  • time_limit Float
    default=10 args: 'Time limit (minutes)'
  • title Char
    required=True translate=True args: 'Survey Title'
  • user_id Many2one → res.users
    default=<expr> string='Responsible' tracking=True args: 'res.users'
  • user_input_ids One2many → survey.user_input
    groups='survey.group_survey_user' readonly=True string='User responses' args: 'survey.user_input', 'survey_id'
  • users_can_go_back Boolean
    help='If checked, users can go back to previous pages.' args: 'Users can go back'
  • users_can_signup Boolean
    compute='_compute_users_can_signup' args: 'Users can signup'
  • users_login_required Boolean
    help='If checked, users have to login before answering even with a valid token.' args: 'Login Required'
Public methods (19)
  • action_end_session(self)
    The write is sudo'ed because a survey user can end a session even if it's not his own survey.
  • action_open_session_manager(self)
  • action_print_survey(self, answer=None)
    Open the website page with the survey printable view
  • action_result_survey(self)
    Open the website page with the survey results view
  • action_send_survey(self)
    Open a window to compose an email, pre-filled with the survey message
  • action_start_session(self)
    Sets the necessary fields for the session to take place and starts it. The write is sudo'ed because a survey user can start a session even if it's not his own survey.
  • action_start_survey(self, answer=None)
    Open the website page with the survey form
  • action_survey_preview_certification_template(self)
  • action_survey_user_input(self)
  • action_survey_user_input_certified(self)
  • action_survey_user_input_completed(self)
  • action_test_survey(self)
    Open the website page with the survey form into test mode
  • copy_data(self, default=None)
  • create(self, vals)
    @api.model
  • get_print_url(self)
  • get_start_short_url(self)
    See controller method docstring for more details.
  • get_start_url(self)
  • toggle_active(self)
  • write(self, vals)

New fields (24)
  • access_token Char
    copy=False default=<expr> readonly=True required=True args: 'Identification token'
  • attempts_limit Integer
    related='survey_id.attempts_limit' args: 'Number of attempts'
  • attempts_number Integer
    compute='_compute_attempts_number' args: 'Attempt n°'
  • deadline Datetime
    help='Datetime until customer can open the survey and submit answers' args: 'Deadline'
  • email Char
    readonly=True args: 'Email'
  • end_datetime Datetime
    readonly=True args: 'End date and time'
  • invite_token Char
    copy=False readonly=True args: 'Invite token'
  • is_attempts_limited Boolean
    related='survey_id.is_attempts_limited' args: 'Limited number of attempts'
  • is_session_answer Boolean
    help='Is that user input part of a survey session or not.' args: 'Is in a Session'
  • last_displayed_page_id Many2one → survey.question
    string='Last displayed question/page' args: 'survey.question'
  • nickname Char
    help='Attendee nickname, mainly used to identify him in the survey session leaderboard.' args: 'Nickname'
  • partner_id Many2one → res.partner
    readonly=True string='Partner' args: 'res.partner'
  • predefined_question_ids Many2many → survey.question
    readonly=True string='Predefined Questions' args: 'survey.question'
  • question_time_limit_reached Boolean
    compute='_compute_question_time_limit_reached' args: 'Question Time Limit Reached'
  • scoring_percentage Float
    compute='_compute_scoring_values' compute_sudo=True store=True args: 'Score (%)'
  • scoring_success Boolean
    compute='_compute_scoring_success' compute_sudo=True store=True args: 'Quizz Passed'
  • scoring_total Float
    compute='_compute_scoring_values' compute_sudo=True store=True args: 'Total Score'
  • scoring_type Selection
    related='survey_id.scoring_type' string='Scoring'
  • start_datetime Datetime
    readonly=True args: 'Start date and time'
  • state Selection
    default='new' readonly=True string='Status' args: [('new', 'Not started yet'), ('in_progress', 'In Progress'), ('done', 'Completed')]
  • survey_id Many2one → survey.survey
    ondelete='cascade' readonly=True required=True string='Survey' args: 'survey.survey'
  • survey_time_limit_reached Boolean
    compute='_compute_survey_time_limit_reached' args: 'Survey Time Limit Reached'
  • test_entry Boolean
    readonly=True
  • user_input_line_ids One2many → survey.user_input.line
    copy=True string='Answers' args: 'survey.user_input.line', 'user_input_id'
Public methods (6)
  • action_print_answers(self)
    Open the website page with the survey form
  • action_resend(self)
  • create(self, vals_list)
    @api.model_create_multi
  • get_print_url(self)
  • get_start_url(self)
  • save_lines(self, question, answer, comment=None)
    Save answers to questions, depending on question type If an answer already exists for question and user_input_id, it will be overwritten (or deleted for 'choice' questions) (in order to maintain data consistency).

New fields (16)
  • answer_is_correct Boolean
    args: 'Correct'
  • answer_score Float
    args: 'Score'
  • answer_type Selection
    string='Answer Type' args: [('text_box', 'Free Text'), ('char_box', 'Text'), ('numerical_box', 'Number'), ('date', 'Date'), ('datetime', 'Datetime'), ('suggestion', 'Suggestion')]
  • matrix_row_id Many2one → survey.question.answer
    string='Row answer' args: 'survey.question.answer'
  • page_id Many2one
    readonly=False related='question_id.page_id' string='Section'
  • question_id Many2one → survey.question
    ondelete='cascade' required=True string='Question' args: 'survey.question'
  • question_sequence Integer
    related='question_id.sequence' store=True args: 'Sequence'
  • skipped Boolean
    args: 'Skipped'
  • suggested_answer_id Many2one → survey.question.answer
    string='Suggested answer' args: 'survey.question.answer'
  • survey_id Many2one
    readonly=False related='user_input_id.survey_id' store=True string='Survey'
  • user_input_id Many2one → survey.user_input
    ondelete='cascade' required=True string='User Input' args: 'survey.user_input'
  • value_char_box Char
    args: 'Text answer'
  • value_date Date
    args: 'Date answer'
  • value_datetime Datetime
    args: 'Datetime answer'
  • value_numerical_box Float
    args: 'Numerical answer'
  • value_text_box Text
    args: 'Free Text answer'
Public methods (2)
  • create(self, vals_list)
    @api.model_create_multi
  • write(self, vals)
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/14.0/survey
VERSION
VERSION 3.2
CATEGORY
CATEGORYMarketing/Surveys
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Martin Trigaux, Olivier Dony, Thibault Delavallée, Christophe Simonis, Xavier Morel, Goffin Simon, Nicolas Martinelli, Nicolas Lempereur, Thibault Francois, Aaron Bohy, Jeremy Kersten, GitHub, Barad Mahendra, Yannick Tivisse, Christophe Monniez, Jorge Pinna Puissant, Julien Castiaux, Aurélien Warnon, Xavier-Do, jvm-odoo, Victor Feyens, Sébastien Theys, alt-odoo, oco-odoo, Jason Van Malder, fw-bot, Debauche Stéphane, std-odoo, Achraf (abz), David Beguin, Adrien Widart, Jérémy Hennecart, Nasreddin Boulif (bon), nie, Djamel (otd), Kevin Baptiste, Arnaud Baes, Benoit Socias, Hubert Van de Walle (huvw), Merlin (megu), thcl-odoo, Florian Charlier, Abdelouahab (abla), Jinjiu Liu, dht-odoo, Fabio Barbero, jorv, Louis Wicket (wil), Mahamadasif Ansari, miad-odoo, amdi-odoo, Pierre-Yves Dufays, Mitul Shah, Vivek Pathak, Adrien Schoffeniels, Thomas Josse (thjo)
WEBSITE
WEBSITEhttps://www.odoo.com/page/survey
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:14:30
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - auth_signup
    - base_setup
    - base
    - web
    - mail
    - bus
    - web_tour
    - http_routing
    - gamification
    - web_kanban_gauge
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
Create beautiful surveys and visualize answers
==============================================

It depends on the answers or reviews of some questions by different users. A
survey may have multiple pages. Each page may contain multiple questions and
each question may have multiple answers. Different users may give different
answers of question and according to that survey is done. Partners are also
sent mails with personal token for the invitation of the survey.
    

Code Analysis

Views touched (71)
XML IDNameModelTypeStatus
assets_backend survey assets ir.ui.view qweb Inherits web.assets_backend
assets_backend_inherit_survey Survey backend assets ir.ui.view qweb Inherits web.assets_backend
assets_tests Survey Assets Tests ir.ui.view qweb Inherits web.assets_tests
certification_report_view certification_report_view ir.ui.view qweb New
certification_report_view_classic certification_report_view_classic ir.ui.view qweb New
certification_report_view_modern certification_report_view_modern ir.ui.view qweb New
gamification_badge_form_view_simplified gamification.badge.form.view.simplified gamification.badge form New
question_char_box Question: text box ir.ui.view qweb New
question_container Survey: question container ir.ui.view qweb New
question_date Question: date box ir.ui.view qweb New
question_datetime Question: datetime box ir.ui.view qweb New
question_matrix Question: matrix ir.ui.view qweb New
question_multiple_choice Question: multiple choice ir.ui.view qweb New
question_numerical_box Question: numerical box ir.ui.view qweb New
question_result_choice Question: choice result (simple_choice, multiple_choice) ir.ui.view qweb New
question_result_comments Question: comments ir.ui.view qweb New
question_result_matrix Question: matrix result (matrix) ir.ui.view qweb New
question_result_number_or_date Question: number or date result (numerical_box or date) ir.ui.view qweb New
question_result_text Question: text result (text_box, char_box, datetime) ir.ui.view qweb New
question_simple_choice Question: simple choice ir.ui.view qweb New
question_suggested_value_image Image from the question suggested answer ir.ui.view qweb New
question_table_pagination Survey: statistics table pagination ir.ui.view qweb New
question_text_box Question: free text box ir.ui.view qweb New
res_partner_view_form res.partner.view.form.inherit.survey res.partner xpath Inherits base.view_partner_form
survey.layout Survey Layout ir.ui.view qweb Inherits web.frontend_layout
survey_403_page Survey: custom 403 page ir.ui.view qweb New
survey_assets Survey Results assets ir.ui.view qweb New
survey_auth_required Survey: login required ir.ui.view qweb New
survey_button_form_view Survey: back to form view ir.ui.view qweb New
survey_button_retake Survey: retake button ir.ui.view qweb New
survey_closed_expired Survey: expired ir.ui.view qweb New
survey_fill_form Survey: main page content ir.ui.view qweb New
survey_fill_form_done Survey: finished ir.ui.view qweb New
survey_fill_form_in_progress Survey: form with questions ir.ui.view qweb New
survey_fill_form_start Survey: start form content ir.ui.view qweb New
survey_fill_header Survey: main page header ir.ui.view qweb New
survey_form Form view for survey survey.survey form New
survey_invite_view_form survey.invite.view.form survey.invite form New
survey_kanban Kanban view for survey survey.survey kanban New
survey_navigation Survey: Navigation ir.ui.view qweb New
survey_page_fill Survey: main page (take survey) ir.ui.view qweb New
survey_page_print Survey: print page ir.ui.view qweb New
survey_page_statistics Survey: result statistics page ir.ui.view qweb New
survey_page_statistics_header Survey: result statistics header ir.ui.view qweb New
survey_page_statistics_inner Survey: result statistics content ir.ui.view qweb New
survey_page_statistics_question Question: result statistics ir.ui.view qweb New
survey_progression Survey: Progression ir.ui.view qweb New
survey_question_answer_view_search survey.question.answer.view.search survey.question.answer search New
survey_question_answer_view_tree survey.question.answer.view.tree survey.question.answer tree New
survey_question_form Form view for survey question survey.question form New
survey_question_search Search view for survey question survey.question search New
survey_question_tree Tree view for survey question survey.question tree New
survey_report_assets_pdf survey_report_assets_pdf ir.ui.view qweb Inherits web.report_assets_pdf
survey_response_line_view_tree survey.user_input.line.view.tree survey.user_input.line tree New
survey_selection_key survey_selection_key ir.ui.view qweb New
survey_session_code Survey: Access Code page ir.ui.view qweb New
survey_survey_view_search survey.survey.search survey.survey search New
survey_tree Tree view for survey survey.survey tree New
survey_user_input_line_view_form survey.user_input.line.view.form survey.user_input.line form New
survey_user_input_line_view_search survey.user_input.line.view.search survey.user_input.line search New
survey_user_input_session_assets Survey User Input Session Assets ir.ui.view qweb New
survey_user_input_view_form survey.user_input.view.form survey.user_input form New
survey_user_input_view_search survey.user_input.view.search survey.user_input search New
survey_user_input_view_tree survey.user_input.view.tree survey.user_input tree New
survey_user_input_viuew_kanban survey.user_input.view.kanban survey.user_input kanban New
survey_void_content Survey: void content ir.ui.view qweb New
user_input_session Survey User Input Session ir.ui.view qweb Inherits web.frontend_layout
user_input_session_leaderboard Survey User Input Leaderboard ir.ui.view qweb New
user_input_session_manage Survey: Manage Session ir.ui.view qweb New
user_input_session_manage_content Survey User Input Session Manage ir.ui.view qweb New
user_input_session_open Survey: Open Session ir.ui.view qweb New
Models touched (9)

New fields (2)
  • survey_id Many2one → survey.survey
    compute='_compute_survey_id' store=True args: 'survey.survey', 'Survey'
  • survey_ids One2many → survey.survey
    args: 'survey.survey', 'certification_badge_id', 'Survey Ids'
Public methods (0)

No public methods.

New fields (1)
  • challenge_category Selection
    ondelete={'certification': 'set default'} selection_add=[('certification', 'Certifications')]
Public methods (0)

No public methods.

New fields (2)
  • certifications_company_count Integer
    compute='_compute_certifications_company_count' args: 'Company Certifications Count'
  • certifications_count Integer
    compute='_compute_certifications_count' args: 'Certifications Count'
Public methods (1)
  • action_view_certifications(self)

New fields (19)
  • attachment_ids Many2many → ir.attachment
    string='Attachments' args: 'ir.attachment', 'survey_mail_compose_message_ir_attachments_rel', 'wizard_id', 'attachment_id'
  • author_id Many2one → res.partner
    default=_get_default_author help='Author of the message.' index=True ondelete='set null' args: 'res.partner', 'Author'
  • body Html
    compute='_compute_body' readonly=False sanitize_style=True store=True args: 'Contents'
  • deadline Datetime
    string='Answer deadline'
  • email_from Char
    default=_get_default_from help='Email address of the sender.' args: 'From'
  • emails Text
    help='This list of emails of recipients will not be converted in contacts. Emails must be separated by commas, semicolons or newline.' string='Additional emails'
  • existing_emails Text
    compute='_compute_existing_emails' readonly=True store=False args: 'Existing emails'
  • existing_mode Selection
    default='resend' required=True string='Handle existing' args: [('new', 'New invite'), ('resend', 'Resend invite')]
  • existing_partner_ids Many2many → res.partner
    compute='_compute_existing_partner_ids' readonly=True store=False args: 'res.partner'
  • existing_text Text
    compute='_compute_existing_text' readonly=True store=False args: 'Resend Comment'
  • mail_server_id Many2one → ir.mail_server
    args: 'ir.mail_server', 'Outgoing mail server'
  • partner_ids Many2many → res.partner
    domain="[\n '|', (survey_users_can_signup, '=', 1),\n '|', (not survey_users_login_required, '=', 1),\n ('user_ids', '!=', False),\n ]" string='Recipients' args: 'res.partner', 'survey_invite_partner_ids', 'invite_id', 'partner_id'
  • subject Char
    compute='_compute_subject' readonly=False store=True args: 'Subject'
  • survey_access_mode Selection
    readonly=True related='survey_id.access_mode'
  • survey_id Many2one → survey.survey
    required=True string='Survey' args: 'survey.survey'
  • survey_start_url Char
    compute='_compute_survey_start_url' args: 'Survey URL'
  • survey_users_can_signup Boolean
    related='survey_id.users_can_signup'
  • survey_users_login_required Boolean
    readonly=True related='survey_id.users_login_required'
  • template_id Many2one → mail.template
    domain="[('model', '=', 'survey.user_input')]" index=True args: 'mail.template', 'Use template'
Public methods (2)
  • action_invite(self)
    Process the wizard content and proceed with sending the related email(s), rendering any template patterns on the fly if needed
  • create(self, values)
    @api.model

New fields (45)
  • allow_value_image Boolean
    help='Display images in addition to answer label. Valid only for simple / multiple choice questions.' args: 'Images on answers'
  • answer_date Date
    help='Correct date answer for this question.' args: 'Correct date answer'
  • answer_datetime Datetime
    help='Correct date and time answer for this question.' args: 'Correct datetime answer'
  • answer_numerical_box Float
    help='Correct number answer for this question.' args: 'Correct numerical answer'
  • answer_score Float
    help='Score value for a correct answer to this question.' args: 'Score'
  • column_nb Selection
    default='12' help='These options refer to col-xx-[12|6|4|3|2] classes in Bootstrap for dropdown-based simple and multiple choice questions.' string='Number of columns' args: [('12', '1'), ('6', '2'), ('4', '3'), ('3', '4'), ('2', '6')]
  • comment_count_as_answer Boolean
    args: 'Comment Field is an Answer Choice'
  • comments_allowed Boolean
    args: 'Show Comments Field'
  • comments_message Char
    default=<expr> translate=True args: 'Comment Message'
  • constr_error_msg Char
    default=<expr> translate=True args: 'Error message'
  • constr_mandatory Boolean
    args: 'Mandatory Answer'
  • description Html
    help='Use this field to add additional explanations about your question or to illustrate it with pictures or a video' sanitize=False translate=True args: 'Description'
  • is_conditional Boolean
    copy=False help='If checked, this question will be displayed only \n if the specified conditional answer have been selected in a previous question' string='Conditional Display'
  • is_page Boolean
    args: 'Is a page?'
  • is_scored_question Boolean
    compute='_compute_is_scored_question' copy=True help='Include this question as part of quiz scoring. Requires an answer and answer score to be taken into account.' readonly=False store=True args: 'Scored'
  • is_time_limited Boolean
    help='Currently only supported for live sessions.' args: 'The question is limited in time'
  • matrix_row_ids One2many → survey.question.answer
    copy=True help='Labels used for proposed choices: rows of matrix' string='Matrix Rows' args: 'survey.question.answer', 'matrix_question_id'
  • matrix_subtype Selection
    default='simple' string='Matrix Type' args: [('simple', 'One choice per row'), ('multiple', 'Multiple choices per row')]
  • page_id Many2one → survey.question
    compute='_compute_page_id' store=True string='Page' args: 'survey.question'
  • question_ids One2many → survey.question
    compute='_compute_question_ids' string='Questions' args: 'survey.question'
  • question_type Selection
    compute='_compute_question_type' readonly=False store=True string='Question Type' args: [('text_box', 'Multiple Lines Text Box'), ('char_box', 'Single Line Text Box'), ('numerical_box', 'Numerical Value'), ('date', 'Date'), ('datetime', 'Datetime'), ('simple_choice', 'Multiple choice: only one answer'), ('multiple_choice', 'Multiple choice: multiple answers allowed'), ('matrix', 'Matrix')]
  • questions_selection Selection
    help='If randomized is selected, add the number of random questions next to the section.' readonly=True related='survey_id.questions_selection'
  • random_questions_count Integer
    default=1 help='Used on randomized sections to take X random questions from all the questions of that section.' args: 'Random questions count'
  • save_as_email Boolean
    compute='_compute_save_as_email' copy=True help="If checked, this option will save the user's answer as its email address." readonly=False store=True args: 'Save as user email'
  • save_as_nickname Boolean
    compute='_compute_save_as_nickname' copy=True help="If checked, this option will save the user's answer as its nickname." readonly=False store=True args: 'Save as user nickname'
  • scoring_type Selection
    readonly=True related='survey_id.scoring_type' string='Scoring Type'
  • sequence Integer
    default=10 args: 'Sequence'
  • suggested_answer_ids One2many → survey.question.answer
    copy=True help='Labels used for proposed choices: simple choice, multiple choice and columns of matrix' string='Types of answers' args: 'survey.question.answer', 'question_id'
  • survey_id Many2one → survey.survey
    ondelete='cascade' string='Survey' args: 'survey.survey'
  • time_limit Integer
    args: 'Time limit (seconds)'
  • title Char
    required=True translate=True args: 'Title'
  • triggering_answer_id Many2one → survey.question.answer
    compute='_compute_triggering_answer_id' copy=False domain="[('question_id', '=', triggering_question_id)]" help='Answer that will trigger the display of the current question.' readonly=False store=True string='Triggering Answer' args: 'survey.question.answer'
  • triggering_question_id Many2one → survey.question
    compute='_compute_triggering_question_id' copy=False domain="[('survey_id', '=', survey_id),\n '&', ('question_type', 'in', ['simple_choice', 'multiple_choice']),\n '|',\n ('sequence', '<', sequence),\n '&', ('sequence', '=', sequence), ('id', '<', id)]" help='Question containing the triggering answer to display the current question.' readonly=False store=True string='Triggering Question' args: 'survey.question'
  • user_input_line_ids One2many → survey.user_input.line
    domain=[('skipped', '=', False)] groups='survey.group_survey_user' string='Answers' args: 'survey.user_input.line', 'question_id'
  • validation_email Boolean
    args: 'Input must be an email'
  • validation_error_msg Char
    default=<expr> translate=True args: 'Validation Error message'
  • validation_length_max Integer
    default=0 args: 'Maximum Text Length'
  • validation_length_min Integer
    default=0 args: 'Minimum Text Length'
  • validation_max_date Date
    args: 'Maximum Date'
  • validation_max_datetime Datetime
    args: 'Maximum Datetime'
  • validation_max_float_value Float
    default=0.0 args: 'Maximum value'
  • validation_min_date Date
    args: 'Minimum Date'
  • validation_min_datetime Datetime
    args: 'Minimum Datetime'
  • validation_min_float_value Float
    default=0.0 args: 'Minimum value'
  • validation_required Boolean
    args: 'Validate entry'
Public methods (2)
  • default_get(self, fields)
    @api.model
  • validate_question(self, answer, comment=None)
    Validate question, depending on question type and parameters for simple choice, text, date and number, answer is simply the answer of the question. For other multiple choices questions, answer is a list of answers (the selected choices or a list of selected answers per question -for matrix type-): - Simple answer : answer = 'example' or 2 or question_answer_id or 2019/10/10 - Multiple choice : answer = [question_answer_id1, question_answer_id2, question_answer_id3] - Matrix: answer = { 'rowId1' : [colId1, colId2,...], 'rowId2' : [colId1, colId3, ...] } return dict {question.id (int): error (str)} -> empty dict if no validation error.

New fields (7)
  • answer_score Float
    help='A positive score indicates a correct choice; a negative or null score indicates a wrong answer' args: 'Score for this choice'
  • is_correct Boolean
    args: 'Is a correct answer'
  • matrix_question_id Many2one → survey.question
    ondelete='cascade' string='Question (as matrix row)' args: 'survey.question'
  • question_id Many2one → survey.question
    ondelete='cascade' string='Question' args: 'survey.question'
  • sequence Integer
    default=10 args: 'Label Sequence order'
  • value Char
    required=True translate=True args: 'Suggested value'
  • value_image Image
    max_height=256 max_width=256 args: 'Image'
Public methods (0)

No public methods.

New fields (47)
  • access_mode Selection
    default='public' required=True string='Access Mode' args: [('public', 'Anyone with the link'), ('token', 'Invited people only')]
  • access_token Char
    copy=False default=<expr> args: 'Access Token'
  • active Boolean
    default=True args: 'Active'
  • answer_count Integer
    compute='_compute_survey_statistic' args: 'Registered'
  • answer_done_count Integer
    compute='_compute_survey_statistic' args: 'Attempts'
  • answer_score_avg Float
    compute='_compute_survey_statistic' args: 'Avg Score %'
  • attempts_limit Integer
    default=1 args: 'Number of attempts'
  • background_image Binary
    args: 'Background Image'
  • certification Boolean
    compute='_compute_certification' readonly=False store=True args: 'Is a Certification'
  • certification_badge_id Many2one → gamification.badge
    args: 'gamification.badge', 'Certification Badge'
  • certification_badge_id_dummy Many2one
    related='certification_badge_id' string='Certification Badge '
  • certification_give_badge Boolean
    compute='_compute_certification_give_badge' readonly=False store=True args: 'Give Badge'
  • certification_mail_template_id Many2one → mail.template
    domain="[('model', '=', 'survey.user_input')]" help='Automated email sent to the user when he succeeds the certification, containing his certification document.' args: 'mail.template', 'Email Template'
  • certification_report_layout Selection
    default='modern_purple' string='Certification template' args: [('modern_purple', 'Modern Purple'), ('modern_blue', 'Modern Blue'), ('modern_gold', 'Modern Gold'), ('classic_purple', 'Classic Purple'), ('classic_blue', 'Classic Blue'), ('classic_gold', 'Classic Gold')]
  • color Integer
    default=0 args: 'Color Index'
  • description Html
    help='The description will be displayed on the home page of the survey. You can use this to give the purpose and guidelines to your candidates before they start it.' sanitize=False translate=True args: 'Description'
  • description_done Html
    help='This message will be displayed when survey is completed' translate=True args: 'End Message'
  • has_conditional_questions Boolean
    compute='_compute_has_conditional_questions' args: 'Contains conditional questions'
  • is_attempts_limited Boolean
    compute='_compute_is_attempts_limited' help='Check this option if you want to limit the number of attempts per user' readonly=False store=True args: 'Limited number of attempts'
  • is_time_limited Boolean
    args: 'The survey is limited in time'
  • page_ids One2many → survey.question
    compute='_compute_page_and_question_ids' string='Pages' args: 'survey.question'
  • progression_mode Selection
    default='percent' help='If Number is selected, it will display the number of questions answered on the total number of question to answer.' string='Progression Mode' args: [('percent', 'Percentage'), ('number', 'Number')]
  • question_and_page_ids One2many → survey.question
    copy=True string='Sections and Questions' args: 'survey.question', 'survey_id'
  • question_ids One2many → survey.question
    compute='_compute_page_and_question_ids' string='Questions' args: 'survey.question'
  • questions_layout Selection
    default='one_page' required=True string='Layout' args: [('one_page', 'One page with all the questions'), ('page_per_section', 'One page per section'), ('page_per_question', 'One page per question')]
  • questions_selection Selection
    default='all' help='If randomized is selected, you can configure the number of random questions by section. This mode is ignored in live session.' required=True string='Selection' args: [('all', 'All questions'), ('random', 'Randomized per section')]
  • scoring_success_min Float
    default=80.0 args: 'Success %'
  • scoring_type Selection
    default='no_scoring' required=True string='Scoring' args: [('no_scoring', 'No scoring'), ('scoring_with_answers', 'Scoring with answers at the end'), ('scoring_without_answers', 'Scoring without answers at the end')]
  • session_answer_count Integer
    compute='_compute_session_answer_count' args: 'Answers Count'
  • session_code Char
    copy=False default=<expr> help='This code will be used by your attendees to reach your session. Feel free to customize it however you like!' args: 'Session Code'
  • session_link Char
    compute='_compute_session_link' args: 'Session Link'
  • session_question_answer_count Integer
    compute='_compute_session_question_answer_count' args: 'Question Answers Count'
  • session_question_id Many2one → survey.question
    copy=False help='The current question of the survey session.' string='Current Question' args: 'survey.question'
  • session_question_start_time Datetime
    copy=False help='The time at which the current question has started, used to handle the timer for attendees.' args: 'Current Question Start Time'
  • session_show_leaderboard Boolean
    compute='_compute_session_show_leaderboard' help='Whether or not we want to show the attendees leaderboard for this survey.' args: 'Show Session Leaderboard'
  • session_speed_rating Boolean
    help='Attendees get more points if they answer quickly' args: 'Reward quick answers'
  • session_start_time Datetime
    copy=False args: 'Current Session Start Time'
  • session_state Selection
    copy=False string='Session State' args: [('ready', 'Ready'), ('in_progress', 'In Progress')]
  • state Selection
    default='draft' group_expand='_read_group_states' required=True selection=[('draft', 'Draft'), ('open', 'In Progress'), ('closed', 'Closed')] string='Survey Stage'
  • success_count Integer
    compute='_compute_survey_statistic' args: 'Success'
  • success_ratio Integer
    compute='_compute_survey_statistic' args: 'Success Ratio'
  • time_limit Float
    default=10 args: 'Time limit (minutes)'
  • title Char
    required=True translate=True args: 'Survey Title'
  • user_input_ids One2many → survey.user_input
    groups='survey.group_survey_user' readonly=True string='User responses' args: 'survey.user_input', 'survey_id'
  • users_can_go_back Boolean
    help='If checked, users can go back to previous pages.' args: 'Users can go back'
  • users_can_signup Boolean
    compute='_compute_users_can_signup' args: 'Users can signup'
  • users_login_required Boolean
    help='If checked, users have to login before answering even with a valid token.' args: 'Login Required'
Public methods (22)
  • action_close(self)
  • action_draft(self)
  • action_end_session(self)
    The write is sudo'ed because a survey user can end a session even if it's not his own survey.
  • action_open(self)
  • action_open_session_manager(self)
  • action_print_survey(self, answer=None)
    Open the website page with the survey printable view
  • action_result_survey(self)
    Open the website page with the survey results view
  • action_send_survey(self)
    Open a window to compose an email, pre-filled with the survey message
  • action_start_session(self)
    Sets the necessary fields for the session to take place and starts it. The write is sudo'ed because a survey user can start a session even if it's not his own survey.
  • action_start_survey(self, answer=None)
    Open the website page with the survey form
  • action_survey_preview_certification_template(self)
  • action_survey_user_input(self)
  • action_survey_user_input_certified(self)
  • action_survey_user_input_completed(self)
  • action_test_survey(self)
    Open the website page with the survey form into test mode
  • copy_data(self, default=None)
  • create(self, vals)
    @api.model
  • get_print_url(self)
  • get_start_short_url(self)
    See controller method docstring for more details.
  • get_start_url(self)
  • toggle_active(self)
  • write(self, vals)

New fields (23)
  • access_token Char
    copy=False default=<expr> readonly=True required=True args: 'Identification token'
  • attempts_limit Integer
    related='survey_id.attempts_limit' args: 'Number of attempts'
  • attempts_number Integer
    compute='_compute_attempts_number' args: 'Attempt n°'
  • deadline Datetime
    help='Datetime until customer can open the survey and submit answers' args: 'Deadline'
  • email Char
    readonly=True args: 'Email'
  • invite_token Char
    copy=False readonly=True args: 'Invite token'
  • is_attempts_limited Boolean
    related='survey_id.is_attempts_limited' args: 'Limited number of attempts'
  • is_session_answer Boolean
    help='Is that user input part of a survey session or not.' args: 'Is in a Session'
  • last_displayed_page_id Many2one → survey.question
    string='Last displayed question/page' args: 'survey.question'
  • nickname Char
    help='Attendee nickname, mainly used to identify him in the survey session leaderboard.' args: 'Nickname'
  • partner_id Many2one → res.partner
    readonly=True string='Partner' args: 'res.partner'
  • predefined_question_ids Many2many → survey.question
    readonly=True string='Predefined Questions' args: 'survey.question'
  • question_time_limit_reached Boolean
    compute='_compute_question_time_limit_reached' args: 'Question Time Limit Reached'
  • scoring_percentage Float
    compute='_compute_scoring_values' compute_sudo=True store=True args: 'Score (%)'
  • scoring_success Boolean
    compute='_compute_scoring_success' compute_sudo=True store=True args: 'Quizz Passed'
  • scoring_total Float
    compute='_compute_scoring_values' compute_sudo=True store=True args: 'Total Score'
  • scoring_type Selection
    related='survey_id.scoring_type' string='Scoring'
  • start_datetime Datetime
    readonly=True args: 'Start date and time'
  • state Selection
    default='new' readonly=True string='Status' args: [('new', 'Not started yet'), ('in_progress', 'In Progress'), ('done', 'Completed')]
  • survey_id Many2one → survey.survey
    ondelete='cascade' readonly=True required=True string='Survey' args: 'survey.survey'
  • survey_time_limit_reached Boolean
    compute='_compute_survey_time_limit_reached' args: 'Survey Time Limit Reached'
  • test_entry Boolean
    readonly=True
  • user_input_line_ids One2many → survey.user_input.line
    copy=True string='Answers' args: 'survey.user_input.line', 'user_input_id'
Public methods (6)
  • action_print_answers(self)
    Open the website page with the survey form
  • action_resend(self)
  • create(self, vals_list)
    @api.model_create_multi
  • get_print_url(self)
  • get_start_url(self)
  • save_lines(self, question, answer, comment=None)
    Save answers to questions, depending on question type If an answer already exists for question and user_input_id, it will be overwritten (or deleted for 'choice' questions) (in order to maintain data consistency).

New fields (16)
  • answer_is_correct Boolean
    args: 'Correct'
  • answer_score Float
    args: 'Score'
  • answer_type Selection
    string='Answer Type' args: [('text_box', 'Free Text'), ('char_box', 'Text'), ('numerical_box', 'Number'), ('date', 'Date'), ('datetime', 'Datetime'), ('suggestion', 'Suggestion')]
  • matrix_row_id Many2one → survey.question.answer
    string='Row answer' args: 'survey.question.answer'
  • page_id Many2one
    readonly=False related='question_id.page_id' string='Section'
  • question_id Many2one → survey.question
    ondelete='cascade' required=True string='Question' args: 'survey.question'
  • question_sequence Integer
    related='question_id.sequence' store=True args: 'Sequence'
  • skipped Boolean
    args: 'Skipped'
  • suggested_answer_id Many2one → survey.question.answer
    string='Suggested answer' args: 'survey.question.answer'
  • survey_id Many2one
    readonly=False related='user_input_id.survey_id' store=True string='Survey'
  • user_input_id Many2one → survey.user_input
    ondelete='cascade' required=True string='User Input' args: 'survey.user_input'
  • value_char_box Char
    args: 'Text answer'
  • value_date Date
    args: 'Date answer'
  • value_datetime Datetime
    args: 'Datetime answer'
  • value_numerical_box Float
    args: 'Numerical answer'
  • value_text_box Text
    args: 'Free Text answer'
Public methods (2)
  • create(self, vals_list)
    @api.model_create_multi
  • write(self, vals)
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/13.0/survey
VERSION
VERSION 3.0
CATEGORY
CATEGORYMarketing/Survey
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Christophe Matthieu, Martin Trigaux, Thibault Delavallée, Denis Ledoux, Christophe Simonis, Xavier Morel, Goffin Simon, Nicolas Martinelli, Aaron Bohy, Jeremy Kersten, Yannick Tivisse, qsm-odoo, Martin Geubelle, Dharmraj Jhala, Odoo Online, jem-odoo, Adrien Dieudonne, Christophe Monniez, Jorge Pinna Puissant, Alexandre Kühn, Toufik Ben Jaa, Adrian Torres, Julien Castiaux, Aurélien Warnon, Priyanka Kakadiya, Xavier-Do, jvm-odoo, mgh-odoo, jerome hanke (jhk), Victor Feyens, Florimond Husquinet (fhu), Andrea Grazioso (agr-odoo), Paul Morelle, Sébastien Theys, Nasreddin (bon), alt-odoo, Florent de Labarre, Jason Van Malder, fw-bot, Rémy Baranx (bar), David Beguin, Lucas Lefèvre, Adrien Widart, Jérémy Hennecart, Mathieu Duckerts-Antoine, Kevin Baptiste, Arnaud Baes, qmo-odoo, laa, ryv-odoo, Hetal Dhanak, Patrick Hoste, Julien Banken
WEBSITE
WEBSITEhttps://www.odoo.com/page/survey
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:06:43
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - auth_signup
    - base_setup
    - base
    - web
    - mail
    - bus
    - web_tour
    - http_routing
    - gamification
    - web_kanban_gauge
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
Create beautiful surveys and visualize answers
==============================================

It depends on the answers or reviews of some questions by different users. A
survey may have multiple pages. Each page may contain multiple questions and
each question may have multiple answers. Different users may give different
answers of question and according to that survey is done. Partners are also
sent mails with personal token for the invitation of the survey.
    

Code Analysis

Views touched (54)
XML IDNameModelTypeStatus
403 403 ir.ui.view qweb New
assets_backend survey assets ir.ui.view qweb Inherits web.assets_backend
assets_backend_inherit_survey Survey backend assets ir.ui.view qweb Inherits web.assets_backend
assets_tests Survey Assets Tests ir.ui.view qweb Inherits web.assets_tests
auth_required Login required for this survey ir.ui.view qweb New
back Back ir.ui.view qweb New
certification_report_view certification_report_view ir.ui.view qweb New
date Date box ir.ui.view qweb New
datetime DateTime box ir.ui.view qweb New
free_text Free text box ir.ui.view qweb New
gamification_badge_form_view_simplified gamification.badge.form.view.simplified gamification.badge form New
matrix Matrix ir.ui.view qweb New
multiple_choice Multiple choice ir.ui.view qweb New
numerical_box Numerical box ir.ui.view qweb New
page Page ir.ui.view qweb New
pagination Survey Result ir.ui.view qweb New
question Question ir.ui.view qweb New
res_partner_view_form res.partner.view.form.inherit.survey res.partner xpath Inherits base.view_partner_form
result Survey Result ir.ui.view qweb New
result_choice Choice Result ir.ui.view qweb New
result_comments Text Result ir.ui.view qweb New
result_matrix Matrix Result ir.ui.view qweb New
result_number Number Result ir.ui.view qweb New
result_text Text Result ir.ui.view qweb New
retake_survey_button Retake Survey Button ir.ui.view qweb New
sfinished Survey Finished ir.ui.view qweb New
simple_choice Simple choice ir.ui.view qweb New
survey Survey ir.ui.view qweb New
survey.layout Survey Layout ir.ui.view qweb Inherits web.frontend_layout
survey_assets Survey Results assets ir.ui.view qweb New
survey_expired Survey Expired ir.ui.view qweb New
survey_form Form view for survey survey.survey form New
survey_header Header ir.ui.view qweb New
survey_init Survey ir.ui.view qweb New
survey_invite_view_form survey.invite.view.form survey.invite form New
survey_kanban Kanban view for survey survey.survey kanban New
survey_label_search survey_label_search survey.label search New
survey_label_tree survey_label_tree survey.label tree New
survey_print Survey ir.ui.view qweb New
survey_question_form Form view for survey question survey.question form New
survey_question_search Search view for survey question survey.question search New
survey_question_tree Tree view for survey question survey.question tree New
survey_report_assets_pdf survey_report_assets_pdf ir.ui.view qweb Inherits web.report_assets_pdf
survey_response_line_search survey_response_line_search survey.user_input_line search New
survey_response_line_tree survey_response_line_tree survey.user_input_line tree New
survey_survey_view_search survey.survey.search survey.survey search New
survey_tree Tree view for survey survey.survey tree New
survey_user_input_line_form survey_user_input_line_form survey.user_input_line form New
survey_user_input_view_form survey.user_input.view.form survey.user_input form New
survey_user_input_view_search survey.user_input.view.search survey.user_input search New
survey_user_input_view_tree survey.user_input.view.tree survey.user_input tree New
survey_user_input_viuew_kanban survey.user_input.view.kanban survey.user_input kanban New
survey_void Survey has no pages ir.ui.view qweb New
textbox Text box ir.ui.view qweb New
Models touched (10)

New fields (2)
  • survey_id Many2one → survey.survey
    compute='_compute_survey_id' store=True args: 'survey.survey', 'Survey'
  • survey_ids One2many → survey.survey
    args: 'survey.survey', 'certification_badge_id', 'Survey Ids'
Public methods (0)

No public methods.

New fields (1)
  • category Selection
    selection_add=[('certification', 'Certifications')]
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • power_on(self, *args, **kwargs)
    @api.model

New fields (2)
  • certifications_company_count Integer
    compute='_compute_certifications_company_count' args: 'Company Certifications Count'
  • certifications_count Integer
    compute='_compute_certifications_count' args: 'Certifications Count'
Public methods (1)
  • action_view_certifications(self)

New fields (18)
  • attachment_ids Many2many → ir.attachment
    string='Attachments' args: 'ir.attachment', 'survey_mail_compose_message_ir_attachments_rel', 'wizard_id', 'attachment_id'
  • author_id Many2one → res.partner
    default=_get_default_author help='Author of the message.' index=True ondelete='set null' args: 'res.partner', 'Author'
  • body Html
    default='' sanitize_style=True args: 'Contents'
  • deadline Datetime
    string='Answer deadline'
  • email_from Char
    default=_get_default_from help='Email address of the sender.' args: 'From'
  • emails Text
    help='This list of emails of recipients will not be converted in contacts. Emails must be separated by commas, semicolons or newline.' string='Additional emails'
  • existing_emails Text
    compute='_compute_existing_emails' readonly=True store=False args: 'Existing emails'
  • existing_mode Selection
    default='resend' required=True string='Handle existing' args: [('new', 'New invite'), ('resend', 'Resend invite')]
  • existing_partner_ids Many2many → res.partner
    compute='_compute_existing_partner_ids' readonly=True store=False args: 'res.partner'
  • existing_text Text
    compute='_compute_existing_text' readonly=True store=False args: 'Resend Comment'
  • mail_server_id Many2one → ir.mail_server
    args: 'ir.mail_server', 'Outgoing mail server'
  • partner_ids Many2many → res.partner
    string='Recipients' args: 'res.partner', 'survey_invite_partner_ids', 'invite_id', 'partner_id'
  • subject Char
    args: 'Subject'
  • survey_access_mode Selection
    readonly=True related='survey_id.access_mode'
  • survey_id Many2one → survey.survey
    required=True string='Survey' args: 'survey.survey'
  • survey_url Char
    readonly=True related='survey_id.public_url'
  • survey_users_login_required Boolean
    readonly=True related='survey_id.users_login_required'
  • template_id Many2one → mail.template
    domain="[('model', '=', 'survey.user_input')]" index=True args: 'mail.template', 'Use template'
Public methods (2)
  • action_invite(self)
    Process the wizard content and proceed with sending the related email(s), rendering any template patterns on the fly if needed
  • create(self, values)
    @api.model

New fields (6)
  • answer_score Float
    help='A positive score indicates a correct choice; a negative or null score indicates a wrong answer' args: 'Score for this choice'
  • is_correct Boolean
    args: 'Is a correct answer'
  • question_id Many2one → survey.question
    ondelete='cascade' string='Question' args: 'survey.question'
  • question_id_2 Many2one → survey.question
    ondelete='cascade' string='Question 2' args: 'survey.question'
  • sequence Integer
    default=10 args: 'Label Sequence order'
  • value Char
    required=True translate=True args: 'Suggested value'
Public methods (0)

No public methods.

New fields (34)
  • column_nb Selection
    default='12' help='These options refer to col-xx-[12|6|4|3|2] classes in Bootstrap for dropdown-based simple and multiple choice questions.' string='Number of columns' args: [('12', '1'), ('6', '2'), ('4', '3'), ('3', '4'), ('2', '6')]
  • comment_count_as_answer Boolean
    args: 'Comment Field is an Answer Choice'
  • comments_allowed Boolean
    args: 'Show Comments Field'
  • comments_message Char
    default=<expr> translate=True args: 'Comment Message'
  • constr_error_msg Char
    default=<expr> translate=True args: 'Error message'
  • constr_mandatory Boolean
    args: 'Mandatory Answer'
  • description Html
    help='Use this field to add additional explanations about your question' translate=True args: 'Description'
  • display_mode Selection
    default='columns' help='Display mode of simple choice questions.' string='Display Mode' args: [('columns', 'Radio Buttons'), ('dropdown', 'Selection Box')]
  • is_page Boolean
    args: 'Is a page?'
  • labels_ids One2many → survey.label
    copy=True help='Labels used for proposed choices: simple choice, multiple choice and columns of matrix' string='Types of answers' args: 'survey.label', 'question_id'
  • labels_ids_2 One2many → survey.label
    copy=True help='Labels used for proposed choices: rows of matrix' string='Rows of the Matrix' args: 'survey.label', 'question_id_2'
  • matrix_subtype Selection
    default='simple' string='Matrix Type' args: [('simple', 'One choice per row'), ('multiple', 'Multiple choices per row')]
  • page_id Many2one → survey.question
    compute='_compute_page_id' store=True string='Page' args: 'survey.question'
  • question Char
    related='title' args: 'Question'
  • question_ids One2many → survey.question
    compute='_compute_question_ids' string='Questions' args: 'survey.question'
  • question_type Selection
    string='Question Type' args: [('free_text', 'Multiple Lines Text Box'), ('textbox', 'Single Line Text Box'), ('numerical_box', 'Numerical Value'), ('date', 'Date'), ('datetime', 'Datetime'), ('simple_choice', 'Multiple choice: only one answer'), ('multiple_choice', 'Multiple choice: multiple answers allowed'), ('matrix', 'Matrix')]
  • questions_selection Selection
    help='If randomized is selected, add the number of random questions next to the section.' readonly=True related='survey_id.questions_selection'
  • random_questions_count Integer
    default=1 help='Used on randomized sections to take X random questions from all the questions of that section.' args: 'Random questions count'
  • scoring_type Selection
    readonly=True related='survey_id.scoring_type' string='Scoring Type'
  • sequence Integer
    default=10 args: 'Sequence'
  • survey_id Many2one → survey.survey
    ondelete='cascade' string='Survey' args: 'survey.survey'
  • title Char
    required=True translate=True args: 'Title'
  • user_input_line_ids One2many → survey.user_input_line
    domain=[('skipped', '=', False)] groups='survey.group_survey_user' string='Answers' args: 'survey.user_input_line', 'question_id'
  • validation_email Boolean
    args: 'Input must be an email'
  • validation_error_msg Char
    default=<expr> translate=True args: 'Validation Error message'
  • validation_length_max Integer
    args: 'Maximum Text Length'
  • validation_length_min Integer
    args: 'Minimum Text Length'
  • validation_max_date Date
    args: 'Maximum Date'
  • validation_max_datetime Datetime
    args: 'Maximum Datetime'
  • validation_max_float_value Float
    args: 'Maximum value'
  • validation_min_date Date
    args: 'Minimum Date'
  • validation_min_datetime Datetime
    args: 'Minimum Datetime'
  • validation_min_float_value Float
    args: 'Minimum value'
  • validation_required Boolean
    args: 'Validate entry'
Public methods (12)
  • date_validation(self, date_type, post, answer_tag, min_value, max_value)
  • default_get(self, fields)
    @api.model
  • get_correct_answer_ids(self)
  • validate_date(self, post, answer_tag)
  • validate_datetime(self, post, answer_tag)
  • validate_free_text(self, post, answer_tag)
  • validate_matrix(self, post, answer_tag)
  • validate_multiple_choice(self, post, answer_tag)
  • validate_numerical_box(self, post, answer_tag)
  • validate_question(self, post, answer_tag)
    Validate question, depending on question type and parameters
  • validate_simple_choice(self, post, answer_tag)
  • validate_textbox(self, post, answer_tag)

New fields (35)
  • access_mode Selection
    default='public' required=True string='Access Mode' args: [('public', 'Anyone with the link'), ('token', 'Invited people only')]
  • access_token Char
    copy=False default=<expr> args: 'Access Token'
  • active Boolean
    default=True args: 'Active'
  • answer_count Integer
    compute='_compute_survey_statistic' args: 'Registered'
  • answer_done_count Integer
    compute='_compute_survey_statistic' args: 'Attempts'
  • answer_score_avg Float
    compute='_compute_survey_statistic' args: 'Avg Score %'
  • attempts_limit Integer
    default=1 args: 'Number of attempts'
  • category Selection
    default='default' help='Category is used to know in which context the survey is used. Various apps may define their own categories when they use survey like jobs recruitment or employee appraisal surveys.' required=True string='Category' args: [('default', 'Generic Survey')]
  • certificate Boolean
    args: 'Certificate'
  • certification_badge_id Many2one → gamification.badge
    args: 'gamification.badge', 'Certification Badge'
  • certification_badge_id_dummy Many2one
    related='certification_badge_id' string='Certification Badge '
  • certification_give_badge Boolean
    args: 'Give Badge'
  • certification_mail_template_id Many2one → mail.template
    domain="[('model', '=', 'survey.user_input')]" help='Automated email sent to the user when he succeeds the certification, containing his certification document.' args: 'mail.template', 'Email Template'
  • color Integer
    default=0 args: 'Color Index'
  • description Html
    help='The description will be displayed on the home page of the survey. You can use this to give the purpose and guidelines to your candidates before they start it.' translate=True args: 'Description'
  • is_attempts_limited Boolean
    help='Check this option if you want to limit the number of attempts per user' args: 'Limited number of attempts'
  • is_time_limited Boolean
    args: 'The survey is limited in time'
  • page_ids One2many → survey.question
    compute='_compute_page_and_question_ids' string='Pages' args: 'survey.question'
  • passing_score Float
    default=80.0 required=True args: 'Passing score (%)'
  • public_url Char
    compute='_compute_survey_url' args: 'Public link'
  • question_and_page_ids One2many → survey.question
    copy=True string='Sections and Questions' args: 'survey.question', 'survey_id'
  • question_ids One2many → survey.question
    compute='_compute_page_and_question_ids' string='Questions' args: 'survey.question'
  • questions_layout Selection
    default='one_page' required=True string='Layout' args: [('one_page', 'One page with all the questions'), ('page_per_section', 'One page per section'), ('page_per_question', 'One page per question')]
  • questions_selection Selection
    default='all' help='If randomized is selected, add the number of random questions next to the section.' required=True string='Selection' args: [('all', 'All questions'), ('random', 'Randomized per section')]
  • scoring_type Selection
    default='no_scoring' required=True string='Scoring' args: [('no_scoring', 'No scoring'), ('scoring_with_answers', 'Scoring with answers at the end'), ('scoring_without_answers', 'Scoring without answers at the end')]
  • state Selection
    default='draft' group_expand='_read_group_states' required=True selection=[('draft', 'Draft'), ('open', 'In Progress'), ('closed', 'Closed')] string='Survey Stage'
  • success_count Integer
    compute='_compute_survey_statistic' args: 'Success'
  • success_ratio Integer
    compute='_compute_survey_statistic' args: 'Success Ratio'
  • thank_you_message Html
    help='This message will be displayed when survey is completed' translate=True args: 'Thanks Message'
  • time_limit Float
    args: 'Time limit (minutes)'
  • title Char
    required=True translate=True args: 'Survey Title'
  • user_input_ids One2many → survey.user_input
    groups='survey.group_survey_user' readonly=True string='User responses' args: 'survey.user_input', 'survey_id'
  • users_can_go_back Boolean
    help='If checked, users can go back to previous pages.' args: 'Users can go back'
  • users_can_signup Boolean
    compute='_compute_users_can_signup' args: 'Users can signup'
  • users_login_required Boolean
    help='If checked, users have to login before answering even with a valid token.' args: 'Login Required'
Public methods (19)
  • action_close(self)
  • action_draft(self)
  • action_open(self)
  • action_print_survey(self)
    Open the website page with the survey printable view
  • action_result_survey(self)
    Open the website page with the survey results view
  • action_send_survey(self)
    Open a window to compose an email, pre-filled with the survey message
  • action_start_survey(self)
    Open the website page with the survey form
  • action_survey_user_input(self)
  • action_survey_user_input_certified(self)
  • action_survey_user_input_completed(self)
  • action_test_survey(self)
    Open the website page with the survey form into test mode
  • copy_data(self, default=None)
  • create(self, vals)
    @api.model
  • filter_input_ids(self, filters, finished=False)
    If user applies any filters, then this function returns list of filtered user_input_id and label's strings for display data in web. :param filters: list of dictionary (having: row_id, ansewr_id) :param finished: True for completely filled survey,Falser otherwise. :returns list of filtered user_input_ids.
  • get_filter_display_data(self, filters)
    @api.model
    Returns data to display current filters :param filters: list of dictionary (having: row_id, answer_id) :returns list of dict having data to display filters.
  • get_input_summary(self, question, current_filters=None)
    @api.model
    Returns overall summary of question e.g. answered, skipped, total_inputs on basis of filter
  • next_page_or_question(self, user_input, page_or_question_id, go_back=False)
    @api.model
    The next page to display to the user, knowing that page_id is the id of the last displayed page. If page_id == 0, it will always return the first page of the survey. If all the pages have been displayed and go_back == False, it will return None If go_back == True, it will return the *previous* page instead of the next page. .. note:: It is assumed here that a careful user will not try to set go_back to True if she knows that the page to display is the first one! (doing this will probably cause a giant worm to eat her house)
  • prepare_result(self, question, current_filters=None)
    @api.model
    Compute statistical data for questions by counting number of vote per choice on basis of filter
  • write(self, vals)

New fields (20)
  • attempt_number Integer
    compute='_compute_attempt_number' args: 'Attempt n°'
  • attempts_limit Integer
    related='survey_id.attempts_limit' args: 'Number of attempts'
  • deadline Datetime
    help='Datetime until customer can open the survey and submit answers' args: 'Deadline'
  • email Char
    readonly=True args: 'E-mail'
  • input_type Selection
    default='manually' readonly=True required=True string='Answer Type' args: [('manually', 'Manual'), ('link', 'Invitation')]
  • invite_token Char
    copy=False readonly=True args: 'Invite token'
  • is_attempts_limited Boolean
    related='survey_id.is_attempts_limited' args: 'Limited number of attempts'
  • is_time_limit_reached Boolean
    compute='_compute_is_time_limit_reached' args: 'Is time limit reached?'
  • last_displayed_page_id Many2one → survey.question
    string='Last displayed question/page' args: 'survey.question'
  • partner_id Many2one → res.partner
    readonly=True string='Partner' args: 'res.partner'
  • question_ids Many2many → survey.question
    readonly=True string='Predefined Questions' args: 'survey.question'
  • quizz_passed Boolean
    compute='_compute_quizz_passed' compute_sudo=True store=True args: 'Quizz Passed'
  • quizz_score Float
    compute='_compute_quizz_score' compute_sudo=True store=True args: 'Score (%)'
  • scoring_type Selection
    related='survey_id.scoring_type' string='Scoring'
  • start_datetime Datetime
    readonly=True args: 'Start date and time'
  • state Selection
    default='new' readonly=True string='Status' args: [('new', 'Not started yet'), ('skip', 'Partially completed'), ('done', 'Completed')]
  • survey_id Many2one → survey.survey
    ondelete='cascade' readonly=True required=True string='Survey' args: 'survey.survey'
  • test_entry Boolean
    readonly=True
  • token Char
    copy=False default=<expr> readonly=True required=True args: 'Identification token'
  • user_input_line_ids One2many → survey.user_input_line
    copy=True string='Answers' args: 'survey.user_input_line', 'user_input_id'
Public methods (3)
  • action_print_answers(self)
    Open the website page with the survey form
  • action_resend(self)
  • do_clean_emptys(self)
    @api.model
    Remove empty user inputs that have been created manually (used as a cronjob declared in data/survey_cron.xml)

New fields (16)
  • answer_is_correct Boolean
    compute='_compute_answer_is_correct' args: 'Correct'
  • answer_score Float
    args: 'Score'
  • answer_type Selection
    string='Answer Type' args: [('text', 'Text'), ('number', 'Number'), ('date', 'Date'), ('datetime', 'Datetime'), ('free_text', 'Free Text'), ('suggestion', 'Suggestion')]
  • page_id Many2one
    readonly=False related='question_id.page_id' string='Section'
  • question_id Many2one → survey.question
    ondelete='cascade' required=True string='Question' args: 'survey.question'
  • question_sequence Integer
    related='question_id.sequence' store=True args: 'Sequence'
  • skipped Boolean
    args: 'Skipped'
  • survey_id Many2one
    readonly=False related='user_input_id.survey_id' store=True string='Survey'
  • user_input_id Many2one → survey.user_input
    ondelete='cascade' required=True string='User Input' args: 'survey.user_input'
  • value_date Date
    args: 'Date answer'
  • value_datetime Datetime
    args: 'Datetime answer'
  • value_free_text Text
    args: 'Free Text answer'
  • value_number Float
    args: 'Numerical answer'
  • value_suggested Many2one → survey.label
    string='Suggested answer' args: 'survey.label'
  • value_suggested_row Many2one → survey.label
    string='Row answer' args: 'survey.label'
  • value_text Char
    args: 'Text answer'
Public methods (11)
  • create(self, vals_list)
    @api.model_create_multi
  • save_line_date(self, user_input_id, question, post, answer_tag)
    @api.model
  • save_line_datetime(self, user_input_id, question, post, answer_tag)
    @api.model
  • save_line_free_text(self, user_input_id, question, post, answer_tag)
    @api.model
  • save_line_matrix(self, user_input_id, question, post, answer_tag)
    @api.model
  • save_line_multiple_choice(self, user_input_id, question, post, answer_tag)
    @api.model
  • save_line_numerical_box(self, user_input_id, question, post, answer_tag)
    @api.model
  • save_line_simple_choice(self, user_input_id, question, post, answer_tag)
    @api.model
  • save_line_textbox(self, user_input_id, question, post, answer_tag)
    @api.model
  • save_lines(self, user_input_id, question, post, answer_tag)
    @api.model
    Save answers to questions, depending on question type If an answer already exists for question and user_input_id, it will be overwritten (in order to maintain data consistency).
  • write(self, vals)
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/12.0/survey
VERSION
VERSION 3.0
CATEGORY
CATEGORYMarketing
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Martin Trigaux, Thibault Delavallée, Christophe Simonis, Nicolas Lempereur, qdp-odoo, Jeremy Kersten, GitHub, Lucas Perais (lpe), Yannick Tivisse, Alexandre Kühn, qsm-odoo, Martin Geubelle, Toufik Benjaa, Christophe Monniez, len-odoo, Nans Lefebvre, Johan Demaret Rivarola, Adrian Torres, Aurélien Warnon, Priyanka Kakadiya, Xavier-Do, David Beguin
WEBSITE
WEBSITEhttps://www.odoo.com/page/survey
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-05 23:57:02
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - http_routing
    - web
    - base
    - mail
    - base_setup
    - bus
    - web_tour
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
Create beautiful surveys and visualize answers
==============================================

It depends on the answers or reviews of some questions by different users. A
survey may have multiple pages. Each page may contain multiple questions and
each question may have multiple answers. Different users may give different
answers of question and according to that survey is done. Partners are also
sent mails with personal token for the invitation of the survey.
    

Code Analysis

Views touched (50)
XML IDNameModelTypeStatus
403 403 ir.ui.view qweb New
assets_backend survey assets ir.ui.view qweb Inherits web.assets_backend
assets_common tour ir.ui.view qweb Inherits web.assets_common
auth_required Login required for this survey ir.ui.view qweb New
back Back ir.ui.view qweb New
date Date box ir.ui.view qweb New
free_text Free text box ir.ui.view qweb New
matrix Matrix ir.ui.view qweb New
multiple_choice Multiple choice ir.ui.view qweb New
no_result Survey Result ir.ui.view qweb New
nopages Survey has no pages ir.ui.view qweb New
notopen Survey not open ir.ui.view qweb New
numerical_box Numerical box ir.ui.view qweb New
page Page ir.ui.view qweb New
pagination Survey Result ir.ui.view qweb New
result Survey Result ir.ui.view qweb New
result_choice Choice Result ir.ui.view qweb New
result_comments Text Result ir.ui.view qweb New
result_matrix Matrix Result ir.ui.view qweb New
result_number Number Result ir.ui.view qweb New
result_text Text Result ir.ui.view qweb New
sfinished Survey Finished ir.ui.view qweb New
simple_choice Simple choice ir.ui.view qweb New
survey Survey ir.ui.view qweb New
survey.layout Survey Layout ir.ui.view qweb New
survey_assets Survey Results assets ir.ui.view qweb New
survey_email_compose_message survey.mail.compose.message.form survey.mail.compose.message form New
survey_form Form view for survey survey.survey form New
survey_init Survey ir.ui.view qweb New
survey_kanban Kanban view for survey survey.survey kanban New
survey_label_search survey_label_search survey.label search New
survey_label_tree survey_label_tree survey.label tree New
survey_page_form Form view for survey page survey.page form New
survey_page_search Search view for survey page survey.page search New
survey_page_tree Tree view for survey page survey.page tree New
survey_print Survey ir.ui.view qweb New
survey_question_form Form view for survey question survey.question form New
survey_question_search Search view for survey question survey.question search New
survey_question_tree Tree view for survey question survey.question tree New
survey_response_line_search survey_response_line_search survey.user_input_line search New
survey_response_line_tree survey_response_line_tree survey.user_input_line tree New
survey_stage_form Form view for survey stage survey.stage form New
survey_survey_view_search survey.survey.search survey.survey search New
survey_tree Tree view for survey survey.survey tree New
survey_user_input_form survey_user_input_form survey.user_input form New
survey_user_input_line_form survey_user_input_line_form survey.user_input_line form New
survey_user_input_search survey_user_input_search survey.user_input search New
survey_user_input_tree survey_user_input_tree survey.user_input tree New
textbox Text box ir.ui.view qweb New
view_survey_user_input_kanban survey.user_input.kanban survey.user_input kanban New
Models touched (9)

New fields (0)

No new fields.

Public methods (1)
  • power_on(self, *args, **kwargs)
    @api.model

New fields (5)
  • question_id Many2one → survey.question
    ondelete='cascade' string='Question' args: 'survey.question'
  • question_id_2 Many2one → survey.question
    ondelete='cascade' string='Question 2' args: 'survey.question'
  • quizz_mark Float
    help='A positive score indicates a correct choice; a negative or null score indicates a wrong answer' args: 'Score for this choice'
  • sequence Integer
    default=10 args: 'Label Sequence order'
  • value Char
    required=True translate=True args: 'Suggested value'
Public methods (0)

No public methods.

New fields (8)
  • attachment_ids Many2many → ir.attachment
    string='Attachments' args: 'ir.attachment', 'survey_mail_compose_message_ir_attachments_rel', 'wizard_id', 'attachment_id'
  • date_deadline Date
    help='Deadline to which the invitation to respond for this survey is valid. If the field is empty, the invitation is still valid.' string='Deadline to which the invitation to respond is valid'
  • multi_email Text
    help='This list of emails of recipients will not be converted in contacts. Emails must be separated by commas, semicolons or newline.' string='List of emails'
  • partner_ids Many2many → res.partner
    string='Existing contacts' args: 'res.partner', 'survey_mail_compose_message_res_partner_rel', 'wizard_id', 'partner_id'
  • public Selection
    default='public_link' required=True string='Share options' args: [('public_link', 'Share the public web link to your audience.'), ('email_public_link', 'Send by email the public web link to your audience.'), ('email_private', 'Send private invitation to your audience (only one response per recipient and per invitation).')]
  • public_url Char
    compute='_compute_survey_url' string='Public url'
  • public_url_html Char
    compute='_compute_survey_url' string='Public HTML web link'
  • survey_id Many2one → survey.survey
    default=default_survey_id required=True string='Survey' args: 'survey.survey'
Public methods (5)
  • default_get(self, fields)
    @api.model
  • default_survey_id(self)
  • onchange_multi_email(self)
    @api.onchange('multi_email')
  • send_mail(self, auto_commit=False)
    @api.multi
    Process the wizard content and proceed with sending the related email(s), rendering any template patterns on the fly if needed
  • send_mail_action(self)
    @api.multi

New fields (5)
  • description Html
    help='An introductory text to your page' oldname='note' translate=True args: 'Description'
  • question_ids One2many → survey.question
    copy=True string='Questions' args: 'survey.question', 'page_id'
  • sequence Integer
    default=10 args: 'Page number'
  • survey_id Many2one → survey.survey
    ondelete='cascade' required=True string='Survey' args: 'survey.survey'
  • title Char
    required=True translate=True args: 'Page Title'
Public methods (0)

No public methods.

New fields (26)
  • column_nb Selection
    default='12' args: [('12', '1'), ('6', '2'), ('4', '3'), ('3', '4'), ('2', '6')], 'Number of columns'
  • comment_count_as_answer Boolean
    oldname='make_comment_field' args: 'Comment Field is an Answer Choice'
  • comments_allowed Boolean
    oldname='allow_comment' args: 'Show Comments Field'
  • comments_message Char
    default=<expr> translate=True args: 'Comment Message'
  • constr_error_msg Char
    default=<expr> oldname='req_error_msg' translate=True args: 'Error message'
  • constr_mandatory Boolean
    oldname='is_require_answer' args: 'Mandatory Answer'
  • description Html
    help='Use this field to add additional explanations about your question' oldname='descriptive_text' translate=True args: 'Description'
  • display_mode Selection
    default='columns' args: [('columns', 'Radio Buttons'), ('dropdown', 'Selection Box')]
  • labels_ids One2many → survey.label
    copy=True oldname='answer_choice_ids' string='Types of answers' args: 'survey.label', 'question_id'
  • labels_ids_2 One2many → survey.label
    copy=True string='Rows of the Matrix' args: 'survey.label', 'question_id_2'
  • matrix_subtype Selection
    default='simple' string='Matrix Type' args: [('simple', 'One choice per row'), ('multiple', 'Multiple choices per row')]
  • page_id Many2one → survey.page
    default=<expr> ondelete='cascade' required=True string='Survey page' args: 'survey.page'
  • question Char
    required=True translate=True args: 'Question Name'
  • sequence Integer
    default=10 args: 'Sequence'
  • survey_id Many2one → survey.survey
    readonly=False related='page_id.survey_id' string='Survey' args: 'survey.survey'
  • type Selection
    default='free_text' required=True string='Type of Question' args: [('free_text', 'Multiple Lines Text Box'), ('textbox', 'Single Line Text Box'), ('numerical_box', 'Numerical Value'), ('date', 'Date'), ('simple_choice', 'Multiple choice: only one answer'), ('multiple_choice', 'Multiple choice: multiple answers allowed'), ('matrix', 'Matrix')]
  • user_input_line_ids One2many → survey.user_input_line
    domain=[('skipped', '=', False)] string='Answers' args: 'survey.user_input_line', 'question_id'
  • validation_email Boolean
    args: 'Input must be an email'
  • validation_error_msg Char
    default=<expr> oldname='validation_valid_err_msg' translate=True args: 'Validation Error message'
  • validation_length_max Integer
    args: 'Maximum Text Length'
  • validation_length_min Integer
    args: 'Minimum Text Length'
  • validation_max_date Date
    args: 'Maximum Date'
  • validation_max_float_value Float
    args: 'Maximum value'
  • validation_min_date Date
    args: 'Minimum Date'
  • validation_min_float_value Float
    args: 'Minimum value'
  • validation_required Boolean
    oldname='is_validation_require' args: 'Validate entry'
Public methods (9)
  • onchange_validation_email(self)
    @api.onchange('validation_email')
  • validate_date(self, post, answer_tag)
    @api.multi
  • validate_free_text(self, post, answer_tag)
    @api.multi
  • validate_matrix(self, post, answer_tag)
    @api.multi
  • validate_multiple_choice(self, post, answer_tag)
    @api.multi
  • validate_numerical_box(self, post, answer_tag)
    @api.multi
  • validate_question(self, post, answer_tag)
    @api.multi
    Validate question, depending on question type and parameters
  • validate_simple_choice(self, post, answer_tag)
    @api.multi
  • validate_textbox(self, post, answer_tag)
    @api.multi

New fields (4)
  • closed Boolean
    help="If closed, people won't be able to answer to surveys in this column."
  • fold Boolean
    string='Folded in kanban view'
  • name Char
    required=True translate=True
  • sequence Integer
    default=1
Public methods (0)

No public methods.

New fields (21)
  • active Boolean
    default=True args: 'Active'
  • auth_required Boolean
    help='Users with a public link will be requested to login before taking part to the survey' oldname='authenticate' args: 'Login required'
  • color Integer
    default=0 args: 'Color Index'
  • description Html
    help='A long description of the purpose of the survey' translate=True args: 'Description'
  • designed Boolean
    compute='_is_designed' args: 'Is designed?'
  • email_template_id Many2one → mail.template
    ondelete='set null' string='Email Template' args: 'mail.template'
  • is_closed Boolean
    readonly=False related='stage_id.closed' args: 'Is closed'
  • page_ids One2many → survey.page
    copy=True string='Pages' args: 'survey.page', 'survey_id'
  • print_url Char
    compute='_compute_survey_url' args: 'Print link'
  • public_url Char
    compute='_compute_survey_url' args: 'Public link'
  • public_url_html Char
    compute='_compute_survey_url' args: 'Public link (html version)'
  • quizz_mode Boolean
    args: 'Quizz Mode'
  • result_url Char
    compute='_compute_survey_url' args: 'Results link'
  • stage_id Many2one → survey.stage
    copy=False default=_default_stage group_expand='_read_group_stage_ids' ondelete='restrict' string='Stage' args: 'survey.stage'
  • thank_you_message Html
    help='This message will be displayed when survey is completed' translate=True args: 'Thanks Message'
  • title Char
    required=True translate=True args: 'Title'
  • tot_comp_survey Integer
    compute='_compute_survey_statistic' args: 'Number of completed surveys'
  • tot_sent_survey Integer
    compute='_compute_survey_statistic' args: 'Number of sent surveys'
  • tot_start_survey Integer
    compute='_compute_survey_statistic' args: 'Number of started surveys'
  • user_input_ids One2many → survey.user_input
    readonly=True string='User responses' args: 'survey.user_input', 'survey_id'
  • users_can_go_back Boolean
    help='If checked, users can go back to previous pages.' args: 'Users can go back'
Public methods (12)
  • action_print_survey(self)
    @api.multi
    Open the website page with the survey printable view
  • action_result_survey(self)
    @api.multi
    Open the website page with the survey results view
  • action_send_survey(self)
    @api.multi
    Open a window to compose an email, pre-filled with the survey message
  • action_start_survey(self)
    @api.multi
    Open the website page with the survey form
  • action_survey_user_input(self)
    @api.multi
  • action_test_survey(self)
    @api.multi
    Open the website page with the survey form into test mode
  • copy_data(self, default=None)
  • filter_input_ids(self, filters, finished=False)
    @api.multi
    If user applies any filters, then this function returns list of filtered user_input_id and label's strings for display data in web. :param filters: list of dictionary (having: row_id, ansewr_id) :param finished: True for completely filled survey,Falser otherwise. :returns list of filtered user_input_ids.
  • get_filter_display_data(self, filters)
    @api.model
    Returns data to display current filters :param filters: list of dictionary (having: row_id, answer_id) :returns list of dict having data to display filters.
  • get_input_summary(self, question, current_filters=None)
    @api.model
    Returns overall summary of question e.g. answered, skipped, total_inputs on basis of filter
  • next_page(self, user_input, page_id, go_back=False)
    @api.model
    The next page to display to the user, knowing that page_id is the id of the last displayed page. If page_id == 0, it will always return the first page of the survey. If all the pages have been displayed and go_back == False, it will return None If go_back == True, it will return the *previous* page instead of the next page. .. note:: It is assumed here that a careful user will not try to set go_back to True if she knows that the page to display is the first one! (doing this will probably cause a giant worm to eat her house)
  • prepare_result(self, question, current_filters=None)
    @api.model
    Compute statistical data for questions by counting number of vote per choice on basis of filter

New fields (14)
  • date_create Datetime
    copy=False default=fields.Datetime.now readonly=True required=True args: 'Creation Date'
  • deadline Datetime
    help='Date by which the person can open the survey and submit answers' oldname='date_deadline' args: 'Deadline'
  • email Char
    readonly=True args: 'E-mail'
  • last_displayed_page_id Many2one → survey.page
    string='Last displayed page' args: 'survey.page'
  • partner_id Many2one → res.partner
    readonly=True string='Partner' args: 'res.partner'
  • print_url Char
    readonly=False related='survey_id.print_url' args: 'Public link to the empty survey'
  • quizz_score Float
    compute='_compute_quizz_score' default=0.0 args: 'Score for the quiz'
  • result_url Char
    readonly=False related='survey_id.result_url' args: 'Public link to the survey results'
  • state Selection
    default='new' readonly=True string='Status' args: [('new', 'Not started yet'), ('skip', 'Partially completed'), ('done', 'Completed')]
  • survey_id Many2one → survey.survey
    ondelete='restrict' readonly=True required=True string='Survey' args: 'survey.survey'
  • test_entry Boolean
    readonly=True
  • token Char
    copy=False default=<expr> readonly=True required=True args: 'Identification token'
  • type Selection
    default='manually' oldname='response_type' readonly=True required=True string='Answer Type' args: [('manually', 'Manually'), ('link', 'Link')]
  • user_input_line_ids One2many → survey.user_input_line
    copy=True string='Answers' args: 'survey.user_input_line', 'user_input_id'
Public methods (4)
  • action_survey_resend(self)
    @api.multi
    Send again the invitation
  • action_survey_results(self)
    @api.multi
    Open the website page with the survey results
  • action_view_answers(self)
    @api.multi
    Open the website page with the survey form
  • do_clean_emptys(self)
    @api.model
    Remove empty user inputs that have been created manually (used as a cronjob declared in data/survey_cron.xml)

New fields (14)
  • answer_type Selection
    string='Answer Type' args: [('text', 'Text'), ('number', 'Number'), ('date', 'Date'), ('free_text', 'Free Text'), ('suggestion', 'Suggestion')]
  • date_create Datetime
    default=fields.Datetime.now required=True args: 'Create Date'
  • page_id Many2one
    readonly=False related='question_id.page_id' string='Page'
  • question_id Many2one → survey.question
    ondelete='restrict' required=True string='Question' args: 'survey.question'
  • quizz_mark Float
    args: 'Score given for this choice'
  • skipped Boolean
    args: 'Skipped'
  • survey_id Many2one
    readonly=False related='user_input_id.survey_id' store=True string='Survey'
  • user_input_id Many2one → survey.user_input
    ondelete='cascade' required=True string='User Input' args: 'survey.user_input'
  • value_date Date
    args: 'Date answer'
  • value_free_text Text
    args: 'Free Text answer'
  • value_number Float
    args: 'Numerical answer'
  • value_suggested Many2one → survey.label
    string='Suggested answer' args: 'survey.label'
  • value_suggested_row Many2one → survey.label
    string='Row answer' args: 'survey.label'
  • value_text Char
    args: 'Text answer'
Public methods (10)
  • create(self, vals_list)
    @api.model_create_multi
  • save_line_date(self, user_input_id, question, post, answer_tag)
    @api.model
  • save_line_free_text(self, user_input_id, question, post, answer_tag)
    @api.model
  • save_line_matrix(self, user_input_id, question, post, answer_tag)
    @api.model
  • save_line_multiple_choice(self, user_input_id, question, post, answer_tag)
    @api.model
  • save_line_numerical_box(self, user_input_id, question, post, answer_tag)
    @api.model
  • save_line_simple_choice(self, user_input_id, question, post, answer_tag)
    @api.model
  • save_line_textbox(self, user_input_id, question, post, answer_tag)
    @api.model
  • save_lines(self, user_input_id, question, post, answer_tag)
    @api.model
    Save answers to questions, depending on question type If an answer already exists for question and user_input_id, it will be overwritten (in order to maintain data consistency).
  • write(self, vals)
    @api.multi
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/11.0/survey
VERSION
VERSION 2.0
CATEGORY
CATEGORYMarketing
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Martin Trigaux, Fabien Pinckaers, Olivier Dony, Thibault Delavallée, Denis Ledoux, Christophe Simonis, Xavier Morel, Nicolas Martinelli, Jérome Maes, Richard Mathot, Jeremy Kersten, GitHub, Yannick Tivisse, Alexandre Kühn, qsm-odoo, Martin Geubelle, Odoo Online
WEBSITE
WEBSITEhttps://www.odoo.com/page/survey
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-05 23:53:43
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - mail
    - base
    - base_setup
    - web
    - bus
    - web_tour
    - website
    - web_editor
    - web_planner
    - http_routing
    - portal
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
Create beautiful web surveys and visualize answers
==================================================

It depends on the answers or reviews of some questions by different users. A
survey may have multiple pages. Each page may contain multiple questions and
each question may have multiple answers. Different users may give different
answers of question and according to that survey is done. Partners are also
sent mails with personal token for the invitation of the survey.
    

Code Analysis

Views touched (49)
XML IDNameModelTypeStatus
assets_backend survey assets ir.ui.view qweb Inherits web.assets_backend
assets_frontend Survey assets ir.ui.view qweb Inherits website.assets_frontend
assets_frontend_result Survey Results assets ir.ui.view qweb Inherits website.assets_frontend
assets_frontend_survey Printing Survey assets ir.ui.view qweb Inherits website.assets_frontend
auth_required Login required for this survey ir.ui.view qweb New
back Back ir.ui.view qweb New
date Date box ir.ui.view qweb New
free_text Free text box ir.ui.view qweb New
matrix Matrix ir.ui.view qweb New
multiple_choice Multiple choice ir.ui.view qweb New
no_result Survey Result ir.ui.view qweb New
nopages Survey has no pages ir.ui.view qweb New
notopen Survey not open ir.ui.view qweb New
numerical_box Numerical box ir.ui.view qweb New
page Page ir.ui.view qweb New
pagination Survey Result ir.ui.view qweb New
result Survey Result ir.ui.view qweb New
result_choice Choice Result ir.ui.view qweb New
result_comments Text Result ir.ui.view qweb New
result_matrix Matrix Result ir.ui.view qweb New
result_number Number Result ir.ui.view qweb New
result_text Text Result ir.ui.view qweb New
sfinished Survey Finished ir.ui.view qweb New
simple_choice Simple choice ir.ui.view qweb New
survey Survey ir.ui.view qweb New
survey_email_compose_message survey.mail.compose.message.form survey.mail.compose.message form New
survey_form Form view for survey survey.survey form New
survey_init Survey ir.ui.view qweb New
survey_kanban Kanban view for survey survey.survey kanban New
survey_label_search survey_label_search survey.label search New
survey_label_tree survey_label_tree survey.label tree New
survey_page_form Form view for survey page survey.page form New
survey_page_search Search view for survey page survey.page search New
survey_page_tree Tree view for survey page survey.page tree New
survey_print Survey ir.ui.view qweb New
survey_question_form Form view for survey question survey.question form New
survey_question_search Search view for survey question survey.question search New
survey_question_tree Tree view for survey question survey.question tree New
survey_response_line_search survey_response_line_search survey.user_input_line search New
survey_response_line_tree survey_response_line_tree survey.user_input_line tree New
survey_stage_form Form view for survey stage survey.stage form New
survey_survey_view_search survey.survey.search survey.survey search New
survey_tree Tree view for survey survey.survey tree New
survey_user_input_form survey_user_input_form survey.user_input form New
survey_user_input_line_form survey_user_input_line_form survey.user_input_line form New
survey_user_input_search survey_user_input_search survey.user_input search New
survey_user_input_tree survey_user_input_tree survey.user_input tree New
textbox Text box ir.ui.view qweb New
view_survey_user_input_kanban survey.user_input.kanban survey.user_input kanban New
Models touched (9)

New fields (0)

No new fields.

Public methods (1)
  • power_on(self, *args, **kwargs)
    @api.model

New fields (5)
  • question_id Many2one → survey.question
    ondelete='cascade' string='Question' args: 'survey.question'
  • question_id_2 Many2one → survey.question
    ondelete='cascade' string='Question 2' args: 'survey.question'
  • quizz_mark Float
    help='A positive score indicates a correct choice; a negative or null score indicates a wrong answer' args: 'Score for this choice'
  • sequence Integer
    default=10 args: 'Label Sequence order'
  • value Char
    required=True translate=True args: 'Suggested value'
Public methods (0)

No public methods.

New fields (8)
  • attachment_ids Many2many → ir.attachment
    string='Attachments' args: 'ir.attachment', 'survey_mail_compose_message_ir_attachments_rel', 'wizard_id', 'attachment_id'
  • date_deadline Date
    help='Deadline to which the invitation to respond for this survey is valid. If the field is empty, the invitation is still valid.' string='Deadline to which the invitation to respond is valid'
  • multi_email Text
    help='This list of emails of recipients will not be converted in contacts. Emails must be separated by commas, semicolons or newline.' string='List of emails'
  • partner_ids Many2many → res.partner
    string='Existing contacts' args: 'res.partner', 'survey_mail_compose_message_res_partner_rel', 'wizard_id', 'partner_id'
  • public Selection
    default='public_link' required=True string='Share options' args: [('public_link', 'Share the public web link to your audience.'), ('email_public_link', 'Send by email the public web link to your audience.'), ('email_private', 'Send private invitation to your audience (only one response per recipient and per invitation).')]
  • public_url Char
    compute='_compute_survey_url' string='Public url'
  • public_url_html Char
    compute='_compute_survey_url' string='Public HTML web link'
  • survey_id Many2one → survey.survey
    default=default_survey_id required=True string='Survey' args: 'survey.survey'
Public methods (4)
  • default_get(self, fields)
    @api.model
  • default_survey_id(self)
  • onchange_multi_email(self)
    @api.onchange('multi_email')
  • send_mail(self, auto_commit=False)
    @api.multi
    Process the wizard content and proceed with sending the related email(s), rendering any template patterns on the fly if needed

New fields (5)
  • description Html
    help='An introductory text to your page' oldname='note' translate=True args: 'Description'
  • question_ids One2many → survey.question
    copy=True string='Questions' args: 'survey.question', 'page_id'
  • sequence Integer
    default=10 args: 'Page number'
  • survey_id Many2one → survey.survey
    ondelete='cascade' required=True string='Survey' args: 'survey.survey'
  • title Char
    required=True translate=True args: 'Page Title'
Public methods (0)

No public methods.

New fields (26)
  • column_nb Selection
    default='12' args: [('12', '1'), ('6', '2'), ('4', '3'), ('3', '4'), ('2', '6')], 'Number of columns'
  • comment_count_as_answer Boolean
    oldname='make_comment_field' args: 'Comment Field is an Answer Choice'
  • comments_allowed Boolean
    oldname='allow_comment' args: 'Show Comments Field'
  • comments_message Char
    default=<expr> translate=True args: 'Comment Message'
  • constr_error_msg Char
    default=<expr> oldname='req_error_msg' translate=True args: 'Error message'
  • constr_mandatory Boolean
    oldname='is_require_answer' args: 'Mandatory Answer'
  • description Html
    help='Use this field to add additional explanations about your question' oldname='descriptive_text' translate=True args: 'Description'
  • display_mode Selection
    default='columns' args: [('columns', 'Radio Buttons'), ('dropdown', 'Selection Box')]
  • labels_ids One2many → survey.label
    copy=True oldname='answer_choice_ids' string='Types of answers' args: 'survey.label', 'question_id'
  • labels_ids_2 One2many → survey.label
    copy=True string='Rows of the Matrix' args: 'survey.label', 'question_id_2'
  • matrix_subtype Selection
    default='simple' string='Matrix Type' args: [('simple', 'One choice per row'), ('multiple', 'Multiple choices per row')]
  • page_id Many2one → survey.page
    default=<expr> ondelete='cascade' required=True string='Survey page' args: 'survey.page'
  • question Char
    required=True translate=True args: 'Question Name'
  • sequence Integer
    default=10 args: 'Sequence'
  • survey_id Many2one → survey.survey
    related='page_id.survey_id' string='Survey' args: 'survey.survey'
  • type Selection
    default='free_text' required=True string='Type of Question' args: [('free_text', 'Multiple Lines Text Box'), ('textbox', 'Single Line Text Box'), ('numerical_box', 'Numerical Value'), ('date', 'Date'), ('simple_choice', 'Multiple choice: only one answer'), ('multiple_choice', 'Multiple choice: multiple answers allowed'), ('matrix', 'Matrix')]
  • user_input_line_ids One2many → survey.user_input_line
    domain=[('skipped', '=', False)] string='Answers' args: 'survey.user_input_line', 'question_id'
  • validation_email Boolean
    args: 'Input must be an email'
  • validation_error_msg Char
    default=<expr> oldname='validation_valid_err_msg' translate=True args: 'Validation Error message'
  • validation_length_max Integer
    args: 'Maximum Text Length'
  • validation_length_min Integer
    args: 'Minimum Text Length'
  • validation_max_date Date
    args: 'Maximum Date'
  • validation_max_float_value Float
    args: 'Maximum value'
  • validation_min_date Date
    args: 'Minimum Date'
  • validation_min_float_value Float
    args: 'Minimum value'
  • validation_required Boolean
    oldname='is_validation_require' args: 'Validate entry'
Public methods (9)
  • onchange_validation_email(self)
    @api.onchange('validation_email')
  • validate_date(self, post, answer_tag)
    @api.multi
  • validate_free_text(self, post, answer_tag)
    @api.multi
  • validate_matrix(self, post, answer_tag)
    @api.multi
  • validate_multiple_choice(self, post, answer_tag)
    @api.multi
  • validate_numerical_box(self, post, answer_tag)
    @api.multi
  • validate_question(self, post, answer_tag)
    @api.multi
    Validate question, depending on question type and parameters
  • validate_simple_choice(self, post, answer_tag)
    @api.multi
  • validate_textbox(self, post, answer_tag)
    @api.multi

New fields (4)
  • closed Boolean
    help="If closed, people won't be able to answer to surveys in this column."
  • fold Boolean
    string='Folded in kanban view'
  • name Char
    required=True translate=True
  • sequence Integer
    default=1
Public methods (0)

No public methods.

New fields (21)
  • active Boolean
    default=True args: 'Active'
  • auth_required Boolean
    help='Users with a public link will be requested to login before taking part to the survey' oldname='authenticate' args: 'Login required'
  • color Integer
    default=0 args: 'Color Index'
  • description Html
    help='A long description of the purpose of the survey' translate=True args: 'Description'
  • designed Boolean
    compute='_is_designed' args: 'Is designed?'
  • email_template_id Many2one → mail.template
    ondelete='set null' string='Email Template' args: 'mail.template'
  • is_closed Boolean
    related='stage_id.closed' args: 'Is closed'
  • page_ids One2many → survey.page
    copy=True string='Pages' args: 'survey.page', 'survey_id'
  • print_url Char
    compute='_compute_survey_url' args: 'Print link'
  • public_url Char
    compute='_compute_survey_url' args: 'Public link'
  • public_url_html Char
    compute='_compute_survey_url' args: 'Public link (html version)'
  • quizz_mode Boolean
    args: 'Quizz Mode'
  • result_url Char
    compute='_compute_survey_url' args: 'Results link'
  • stage_id Many2one → survey.stage
    copy=False default=_default_stage group_expand='_read_group_stage_ids' ondelete='set null' string='Stage' args: 'survey.stage'
  • thank_you_message Html
    help='This message will be displayed when survey is completed' translate=True args: 'Thanks Message'
  • title Char
    required=True translate=True args: 'Title'
  • tot_comp_survey Integer
    compute='_compute_survey_statistic' args: 'Number of completed surveys'
  • tot_sent_survey Integer
    compute='_compute_survey_statistic' args: 'Number of sent surveys'
  • tot_start_survey Integer
    compute='_compute_survey_statistic' args: 'Number of started surveys'
  • user_input_ids One2many → survey.user_input
    readonly=True string='User responses' args: 'survey.user_input', 'survey_id'
  • users_can_go_back Boolean
    help='If checked, users can go back to previous pages.' args: 'Users can go back'
Public methods (12)
  • action_print_survey(self)
    @api.multi
    Open the website page with the survey printable view
  • action_result_survey(self)
    @api.multi
    Open the website page with the survey results view
  • action_send_survey(self)
    @api.multi
    Open a window to compose an email, pre-filled with the survey message
  • action_start_survey(self)
    @api.multi
    Open the website page with the survey form
  • action_survey_user_input(self)
    @api.multi
  • action_test_survey(self)
    @api.multi
    Open the website page with the survey form into test mode
  • copy_data(self, default=None)
  • filter_input_ids(self, filters, finished=False)
    @api.multi
    If user applies any filters, then this function returns list of filtered user_input_id and label's strings for display data in web. :param filters: list of dictionary (having: row_id, ansewr_id) :param finished: True for completely filled survey,Falser otherwise. :returns list of filtered user_input_ids.
  • get_filter_display_data(self, filters)
    @api.model
    Returns data to display current filters :param filters: list of dictionary (having: row_id, answer_id) :returns list of dict having data to display filters.
  • get_input_summary(self, question, current_filters=None)
    @api.model
    Returns overall summary of question e.g. answered, skipped, total_inputs on basis of filter
  • next_page(self, user_input, page_id, go_back=False)
    @api.model
    The next page to display to the user, knowing that page_id is the id of the last displayed page. If page_id == 0, it will always return the first page of the survey. If all the pages have been displayed and go_back == False, it will return None If go_back == True, it will return the *previous* page instead of the next page. .. note:: It is assumed here that a careful user will not try to set go_back to True if she knows that the page to display is the first one! (doing this will probably cause a giant worm to eat her house)
  • prepare_result(self, question, current_filters=None)
    @api.model
    Compute statistical data for questions by counting number of vote per choice on basis of filter

New fields (14)
  • date_create Datetime
    copy=False default=fields.Datetime.now readonly=True required=True args: 'Creation Date'
  • deadline Datetime
    help='Date by which the person can open the survey and submit answers' oldname='date_deadline' args: 'Deadline'
  • email Char
    readonly=True args: 'E-mail'
  • last_displayed_page_id Many2one → survey.page
    string='Last displayed page' args: 'survey.page'
  • partner_id Many2one → res.partner
    readonly=True string='Partner' args: 'res.partner'
  • print_url Char
    related='survey_id.print_url' args: 'Public link to the empty survey'
  • quizz_score Float
    compute='_compute_quizz_score' default=0.0 args: 'Score for the quiz'
  • result_url Char
    related='survey_id.result_url' args: 'Public link to the survey results'
  • state Selection
    default='new' readonly=True string='Status' args: [('new', 'Not started yet'), ('skip', 'Partially completed'), ('done', 'Completed')]
  • survey_id Many2one → survey.survey
    ondelete='restrict' readonly=True required=True string='Survey' args: 'survey.survey'
  • test_entry Boolean
    readonly=True
  • token Char
    copy=False default=<expr> readonly=True required=True args: 'Identification token'
  • type Selection
    default='manually' oldname='response_type' readonly=True required=True string='Answer Type' args: [('manually', 'Manually'), ('link', 'Link')]
  • user_input_line_ids One2many → survey.user_input_line
    copy=True string='Answers' args: 'survey.user_input_line', 'user_input_id'
Public methods (4)
  • action_survey_resend(self)
    @api.multi
    Send again the invitation
  • action_survey_results(self)
    @api.multi
    Open the website page with the survey results
  • action_view_answers(self)
    @api.multi
    Open the website page with the survey form
  • do_clean_emptys(self)
    @api.model
    Remove empty user inputs that have been created manually (used as a cronjob declared in data/survey_cron.xml)

New fields (14)
  • answer_type Selection
    string='Answer Type' args: [('text', 'Text'), ('number', 'Number'), ('date', 'Date'), ('free_text', 'Free Text'), ('suggestion', 'Suggestion')]
  • date_create Datetime
    default=fields.Datetime.now required=True args: 'Create Date'
  • page_id Many2one
    related='question_id.page_id' string='Page'
  • question_id Many2one → survey.question
    ondelete='restrict' required=True string='Question' args: 'survey.question'
  • quizz_mark Float
    args: 'Score given for this choice'
  • skipped Boolean
    args: 'Skipped'
  • survey_id Many2one
    related='user_input_id.survey_id' store=True string='Survey'
  • user_input_id Many2one → survey.user_input
    ondelete='cascade' required=True string='User Input' args: 'survey.user_input'
  • value_date Date
    args: 'Date answer'
  • value_free_text Text
    args: 'Free Text answer'
  • value_number Float
    args: 'Numerical answer'
  • value_suggested Many2one → survey.label
    string='Suggested answer' args: 'survey.label'
  • value_suggested_row Many2one → survey.label
    string='Row answer' args: 'survey.label'
  • value_text Char
    args: 'Text answer'
Public methods (10)
  • create(self, vals)
    @api.model
  • save_line_date(self, user_input_id, question, post, answer_tag)
    @api.model
  • save_line_free_text(self, user_input_id, question, post, answer_tag)
    @api.model
  • save_line_matrix(self, user_input_id, question, post, answer_tag)
    @api.model
  • save_line_multiple_choice(self, user_input_id, question, post, answer_tag)
    @api.model
  • save_line_numerical_box(self, user_input_id, question, post, answer_tag)
    @api.model
  • save_line_simple_choice(self, user_input_id, question, post, answer_tag)
    @api.model
  • save_line_textbox(self, user_input_id, question, post, answer_tag)
    @api.model
  • save_lines(self, user_input_id, question, post, answer_tag)
    @api.model
    Save answers to questions, depending on question type If an answer already exists for question and user_input_id, it will be overwritten (in order to maintain data consistency).
  • write(self, vals)
    @api.multi
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/10.0/survey
VERSION
VERSION 2.0
CATEGORY
CATEGORYMarketing
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Christophe Matthieu, Martin Trigaux, Fabien Pinckaers, Olivier Dony, Thibault Delavallée, Denis Ledoux, Christophe Simonis, Goffin Simon, Nicolas Martinelli, Jérome Maes, Julien Legros, Richard Mathot, qdp-odoo, Jeremy Kersten, Yannick Tivisse, qsm-odoo
WEBSITE
WEBSITEhttps://www.odoo.com/page/survey
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-05 23:50:48
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - mail
    - base
    - base_setup
    - web_kanban
    - web
    - bus
    - web_tour
    - website
    - web_editor
    - web_planner
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
Create beautiful web surveys and visualize answers
==================================================

It depends on the answers or reviews of some questions by different users. A
survey may have multiple pages. Each page may contain multiple questions and
each question may have multiple answers. Different users may give different
answers of question and according to that survey is done. Partners are also
sent mails with personal token for the invitation of the survey.
    

Code Analysis

Views touched (48)
XML IDNameModelTypeStatus
assets_backend survey assets ir.ui.view qweb Inherits web.assets_backend
assets_frontend Survey assets ir.ui.view qweb Inherits website.assets_frontend
assets_frontend_result Survey Results assets ir.ui.view qweb Inherits website.assets_frontend
assets_frontend_survey Printing Survey assets ir.ui.view qweb Inherits website.assets_frontend
auth_required Login required for this survey ir.ui.view qweb New
back Back ir.ui.view qweb New
datetime Datetime box ir.ui.view qweb New
free_text Free text box ir.ui.view qweb New
matrix Matrix ir.ui.view qweb New
multiple_choice Multiple choice ir.ui.view qweb New
no_result Survey Result ir.ui.view qweb New
nopages Survey has no pages ir.ui.view qweb New
notopen Survey not open ir.ui.view qweb New
numerical_box Numerical box ir.ui.view qweb New
page Page ir.ui.view qweb New
pagination Survey Result ir.ui.view qweb New
result Survey Result ir.ui.view qweb New
result_choice Choice Result ir.ui.view qweb New
result_comments Text Result ir.ui.view qweb New
result_matrix Matrix Result ir.ui.view qweb New
result_number Number Result ir.ui.view qweb New
result_text Text Result ir.ui.view qweb New
sfinished Survey Finished ir.ui.view qweb New
simple_choice Simple choice ir.ui.view qweb New
survey Survey ir.ui.view qweb New
survey_email_compose_message survey.mail.compose.message.form survey.mail.compose.message form New
survey_form Form view for survey survey.survey form New
survey_init Survey ir.ui.view qweb New
survey_kanban Kanban view for survey survey.survey kanban New
survey_label_search survey_label_search survey.label search New
survey_label_tree survey_label_tree survey.label tree New
survey_page_form Form view for survey page survey.page form New
survey_page_search Search view for survey page survey.page search New
survey_page_tree Tree view for survey page survey.page tree New
survey_print Survey ir.ui.view qweb New
survey_question_form Form view for survey question survey.question form New
survey_question_search Search view for survey question survey.question search New
survey_question_tree Tree view for survey question survey.question tree New
survey_response_line_search survey_response_line_search survey.user_input_line search New
survey_response_line_tree survey_response_line_tree survey.user_input_line tree New
survey_stage_form Form view for survey stage survey.stage form New
survey_survey_view_search survey.survey.search survey.survey search New
survey_tree Tree view for survey survey.survey tree New
survey_user_input_form survey_user_input_form survey.user_input form New
survey_user_input_line_form survey_user_input_line_form survey.user_input_line form New
survey_user_input_search survey_user_input_search survey.user_input search New
survey_user_input_tree survey_user_input_tree survey.user_input tree New
textbox Text box ir.ui.view qweb New
Models touched (9)

New fields (0)

No new fields.

Public methods (1)
  • power_on(self, *args, **kwargs)
    @api.model

New fields (5)
  • question_id Many2one → survey.question
    ondelete='cascade' string='Question' args: 'survey.question'
  • question_id_2 Many2one → survey.question
    ondelete='cascade' string='Question 2' args: 'survey.question'
  • quizz_mark Float
    help='A positive score indicates a correct choice; a negative or null score indicates a wrong answer' args: 'Score for this choice'
  • sequence Integer
    default=10 args: 'Label Sequence order'
  • value Char
    required=True translate=True args: 'Suggested value'
Public methods (0)

No public methods.

New fields (8)
  • attachment_ids Many2many → ir.attachment
    string='Attachments' args: 'ir.attachment', 'survey_mail_compose_message_ir_attachments_rel', 'wizard_id', 'attachment_id'
  • date_deadline Date
    help='Deadline to which the invitation to respond for this survey is valid. If the field is empty, the invitation is still valid.' string='Deadline to which the invitation to respond is valid'
  • multi_email Text
    help='This list of emails of recipients will not be converted in contacts. Emails must be separated by commas, semicolons or newline.' string='List of emails'
  • partner_ids Many2many → res.partner
    string='Existing contacts' args: 'res.partner', 'survey_mail_compose_message_res_partner_rel', 'wizard_id', 'partner_id'
  • public Selection
    default='public_link' required=True string='Share options' args: [('public_link', 'Share the public web link to your audience.'), ('email_public_link', 'Send by email the public web link to your audience.'), ('email_private', 'Send private invitation to your audience (only one response per recipient and per invitation).')]
  • public_url Char
    compute='_compute_survey_url' string='Public url'
  • public_url_html Char
    compute='_compute_survey_url' string='Public HTML web link'
  • survey_id Many2one → survey.survey
    default=default_survey_id required=True string='Survey' args: 'survey.survey'
Public methods (4)
  • default_get(self, fields)
    @api.model
  • default_survey_id(self)
  • onchange_multi_email(self)
    @api.onchange('multi_email')
  • send_mail(self, auto_commit=False)
    @api.multi
    Process the wizard content and proceed with sending the related email(s), rendering any template patterns on the fly if needed

New fields (5)
  • description Html
    help='An introductory text to your page' oldname='note' translate=True args: 'Description'
  • question_ids One2many → survey.question
    copy=True string='Questions' args: 'survey.question', 'page_id'
  • sequence Integer
    default=10 args: 'Page number'
  • survey_id Many2one → survey.survey
    ondelete='cascade' required=True string='Survey' args: 'survey.survey'
  • title Char
    required=True translate=True args: 'Page Title'
Public methods (0)

No public methods.

New fields (26)
  • column_nb Selection
    default='12' args: [('12', '1'), ('6', '2'), ('4', '3'), ('3', '4'), ('2', '6')], 'Number of columns'
  • comment_count_as_answer Boolean
    oldname='make_comment_field' args: 'Comment Field is an Answer Choice'
  • comments_allowed Boolean
    oldname='allow_comment' args: 'Show Comments Field'
  • comments_message Char
    default=<expr> translate=True args: 'Comment Message'
  • constr_error_msg Char
    default=<expr> oldname='req_error_msg' translate=True args: 'Error message'
  • constr_mandatory Boolean
    oldname='is_require_answer' args: 'Mandatory Answer'
  • description Html
    help='Use this field to add additional explanations about your question' oldname='descriptive_text' translate=True args: 'Description'
  • display_mode Selection
    default='columns' args: [('columns', 'Radio Buttons'), ('dropdown', 'Selection Box')]
  • labels_ids One2many → survey.label
    copy=True oldname='answer_choice_ids' string='Types of answers' args: 'survey.label', 'question_id'
  • labels_ids_2 One2many → survey.label
    copy=True string='Rows of the Matrix' args: 'survey.label', 'question_id_2'
  • matrix_subtype Selection
    default='simple' string='Matrix Type' args: [('simple', 'One choice per row'), ('multiple', 'Multiple choices per row')]
  • page_id Many2one → survey.page
    default=<expr> ondelete='cascade' required=True string='Survey page' args: 'survey.page'
  • question Char
    required=True translate=True args: 'Question Name'
  • sequence Integer
    default=10 args: 'Sequence'
  • survey_id Many2one → survey.survey
    related='page_id.survey_id' string='Survey' args: 'survey.survey'
  • type Selection
    default='free_text' required=True string='Type of Question' args: [('free_text', 'Multiple Lines Text Box'), ('textbox', 'Single Line Text Box'), ('numerical_box', 'Numerical Value'), ('datetime', 'Date and Time'), ('simple_choice', 'Multiple choice: only one answer'), ('multiple_choice', 'Multiple choice: multiple answers allowed'), ('matrix', 'Matrix')]
  • user_input_line_ids One2many → survey.user_input_line
    domain=[('skipped', '=', False)] string='Answers' args: 'survey.user_input_line', 'question_id'
  • validation_email Boolean
    args: 'Input must be an email'
  • validation_error_msg Char
    default=<expr> oldname='validation_valid_err_msg' translate=True args: 'Validation Error message'
  • validation_length_max Integer
    args: 'Maximum Text Length'
  • validation_length_min Integer
    args: 'Minimum Text Length'
  • validation_max_date Datetime
    args: 'Maximum Date'
  • validation_max_float_value Float
    args: 'Maximum value'
  • validation_min_date Datetime
    args: 'Minimum Date'
  • validation_min_float_value Float
    args: 'Minimum value'
  • validation_required Boolean
    oldname='is_validation_require' args: 'Validate entry'
Public methods (9)
  • onchange_validation_email(self)
    @api.onchange('validation_email')
  • validate_datetime(self, post, answer_tag)
    @api.multi
  • validate_free_text(self, post, answer_tag)
    @api.multi
  • validate_matrix(self, post, answer_tag)
    @api.multi
  • validate_multiple_choice(self, post, answer_tag)
    @api.multi
  • validate_numerical_box(self, post, answer_tag)
    @api.multi
  • validate_question(self, post, answer_tag)
    @api.multi
    Validate question, depending on question type and parameters
  • validate_simple_choice(self, post, answer_tag)
    @api.multi
  • validate_textbox(self, post, answer_tag)
    @api.multi

New fields (4)
  • closed Boolean
    help="If closed, people won't be able to answer to surveys in this column."
  • fold Boolean
    string='Folded in kanban view'
  • name Char
    required=True translate=True
  • sequence Integer
    default=1
Public methods (0)

No public methods.

New fields (21)
  • active Boolean
    default=True args: 'Active'
  • auth_required Boolean
    help='Users with a public link will be requested to login before taking part to the survey' oldname='authenticate' args: 'Login required'
  • color Integer
    default=0 args: 'Color Index'
  • description Html
    help='A long description of the purpose of the survey' translate=True args: 'Description'
  • designed Boolean
    compute='_is_designed' args: 'Is designed?'
  • email_template_id Many2one → mail.template
    ondelete='set null' string='Email Template' args: 'mail.template'
  • is_closed Boolean
    related='stage_id.closed' args: 'Is closed'
  • page_ids One2many → survey.page
    copy=True string='Pages' args: 'survey.page', 'survey_id'
  • print_url Char
    compute='_compute_survey_url' args: 'Print link'
  • public_url Char
    compute='_compute_survey_url' args: 'Public link'
  • public_url_html Char
    compute='_compute_survey_url' args: 'Public link (html version)'
  • quizz_mode Boolean
    args: 'Quizz Mode'
  • result_url Char
    compute='_compute_survey_url' args: 'Results link'
  • stage_id Many2one → survey.stage
    copy=False default=_default_stage group_expand='_read_group_stage_ids' ondelete='set null' string='Stage' args: 'survey.stage'
  • thank_you_message Html
    help='This message will be displayed when survey is completed' translate=True args: 'Thanks Message'
  • title Char
    required=True translate=True args: 'Title'
  • tot_comp_survey Integer
    compute='_compute_survey_statistic' args: 'Number of completed surveys'
  • tot_sent_survey Integer
    compute='_compute_survey_statistic' args: 'Number of sent surveys'
  • tot_start_survey Integer
    compute='_compute_survey_statistic' args: 'Number of started surveys'
  • user_input_ids One2many → survey.user_input
    readonly=True string='User responses' args: 'survey.user_input', 'survey_id'
  • users_can_go_back Boolean
    help='If checked, users can go back to previous pages.' args: 'Users can go back'
Public methods (12)
  • action_print_survey(self)
    @api.multi
    Open the website page with the survey printable view
  • action_result_survey(self)
    @api.multi
    Open the website page with the survey results view
  • action_send_survey(self)
    @api.multi
    Open a window to compose an email, pre-filled with the survey message
  • action_start_survey(self)
    @api.multi
    Open the website page with the survey form
  • action_survey_user_input(self)
    @api.multi
  • action_test_survey(self)
    @api.multi
    Open the website page with the survey form into test mode
  • copy_data(self, default=None)
  • filter_input_ids(self, filters, finished=False)
    @api.multi
    If user applies any filters, then this function returns list of filtered user_input_id and label's strings for display data in web. :param filters: list of dictionary (having: row_id, ansewr_id) :param finished: True for completely filled survey,Falser otherwise. :returns list of filtered user_input_ids.
  • get_filter_display_data(self, filters)
    @api.model
    Returns data to display current filters :param filters: list of dictionary (having: row_id, answer_id) :returns list of dict having data to display filters.
  • get_input_summary(self, question, current_filters=None)
    @api.model
    Returns overall summary of question e.g. answered, skipped, total_inputs on basis of filter
  • next_page(self, user_input, page_id, go_back=False)
    @api.model
    The next page to display to the user, knowing that page_id is the id of the last displayed page. If page_id == 0, it will always return the first page of the survey. If all the pages have been displayed and go_back == False, it will return None If go_back == True, it will return the *previous* page instead of the next page. .. note:: It is assumed here that a careful user will not try to set go_back to True if she knows that the page to display is the first one! (doing this will probably cause a giant worm to eat her house)
  • prepare_result(self, question, current_filters=None)
    @api.model
    Compute statistical data for questions by counting number of vote per choice on basis of filter

New fields (14)
  • date_create Datetime
    copy=False default=fields.Datetime.now readonly=True required=True args: 'Creation Date'
  • deadline Datetime
    help='Date by which the person can open the survey and submit answers' oldname='date_deadline' args: 'Deadline'
  • email Char
    readonly=True args: 'E-mail'
  • last_displayed_page_id Many2one → survey.page
    string='Last displayed page' args: 'survey.page'
  • partner_id Many2one → res.partner
    readonly=True string='Partner' args: 'res.partner'
  • print_url Char
    related='survey_id.print_url' args: 'Public link to the empty survey'
  • quizz_score Float
    compute='_compute_quizz_score' default=0.0 args: 'Score for the quiz'
  • result_url Char
    related='survey_id.result_url' args: 'Public link to the survey results'
  • state Selection
    default='new' readonly=True string='Status' args: [('new', 'Not started yet'), ('skip', 'Partially completed'), ('done', 'Completed')]
  • survey_id Many2one → survey.survey
    ondelete='restrict' readonly=True required=True string='Survey' args: 'survey.survey'
  • test_entry Boolean
    readonly=True
  • token Char
    copy=False default=<expr> readonly=True required=True args: 'Identification token'
  • type Selection
    default='manually' oldname='response_type' readonly=True required=True string='Answer Type' args: [('manually', 'Manually'), ('link', 'Link')]
  • user_input_line_ids One2many → survey.user_input_line
    copy=True string='Answers' args: 'survey.user_input_line', 'user_input_id'
Public methods (4)
  • action_survey_resend(self)
    @api.multi
    Send again the invitation
  • action_survey_results(self)
    @api.multi
    Open the website page with the survey results
  • action_view_answers(self)
    @api.multi
    Open the website page with the survey form
  • do_clean_emptys(self)
    @api.model
    Remove empty user inputs that have been created manually (used as a cronjob declared in data/survey_cron.xml)

New fields (14)
  • answer_type Selection
    string='Answer Type' args: [('text', 'Text'), ('number', 'Number'), ('date', 'Date'), ('free_text', 'Free Text'), ('suggestion', 'Suggestion')]
  • date_create Datetime
    default=fields.Datetime.now required=True args: 'Create Date'
  • page_id Many2one
    related='question_id.page_id' string='Page'
  • question_id Many2one → survey.question
    ondelete='restrict' required=True string='Question' args: 'survey.question'
  • quizz_mark Float
    args: 'Score given for this choice'
  • skipped Boolean
    args: 'Skipped'
  • survey_id Many2one
    related='user_input_id.survey_id' store=True string='Survey'
  • user_input_id Many2one → survey.user_input
    ondelete='cascade' required=True string='User Input' args: 'survey.user_input'
  • value_date Datetime
    args: 'Date answer'
  • value_free_text Text
    args: 'Free Text answer'
  • value_number Float
    args: 'Numerical answer'
  • value_suggested Many2one → survey.label
    string='Suggested answer' args: 'survey.label'
  • value_suggested_row Many2one → survey.label
    string='Row answer' args: 'survey.label'
  • value_text Char
    args: 'Text answer'
Public methods (10)
  • create(self, vals)
    @api.model
  • save_line_datetime(self, user_input_id, question, post, answer_tag)
    @api.model
  • save_line_free_text(self, user_input_id, question, post, answer_tag)
    @api.model
  • save_line_matrix(self, user_input_id, question, post, answer_tag)
    @api.model
  • save_line_multiple_choice(self, user_input_id, question, post, answer_tag)
    @api.model
  • save_line_numerical_box(self, user_input_id, question, post, answer_tag)
    @api.model
  • save_line_simple_choice(self, user_input_id, question, post, answer_tag)
    @api.model
  • save_line_textbox(self, user_input_id, question, post, answer_tag)
    @api.model
  • save_lines(self, user_input_id, question, post, answer_tag)
    @api.model
    Save answers to questions, depending on question type If an answer already exists for question and user_input_id, it will be overwritten (in order to maintain data consistency).
  • write(self, vals)
    @api.multi
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/9.0/survey
VERSION
VERSION 2.0
CATEGORY
CATEGORYMarketing
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSOdoo Translation Bot, Christophe Matthieu, Martin Trigaux, Olivier Dony, Thibault Delavallée, Denis Ledoux, Fabien Meghazi, Christophe Simonis, Simon Lejeune, Nicolas Martinelli, Richard Mathot, Géry Debongnie, Aaron Bohy, Julien De Coster, Yannick Tivisse, qsm-odoo, Martin Geubelle, odoo-tac
WEBSITE
WEBSITEhttps://www.odoo.com/page/survey
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-05 23:48:31
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - mail
    - base
    - base_setup
    - web_kanban
    - web
    - bus
    - website
    - web_editor
    - web_planner
    - marketing
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
Create beautiful web surveys and visualize answers
==================================================

It depends on the answers or reviews of some questions by different users. A
survey may have multiple pages. Each page may contain multiple questions and
each question may have multiple answers. Different users may give different
answers of question and according to that survey is done. Partners are also
sent mails with personal token for the invitation of the survey.
    

Code Analysis

Views touched (47)
XML IDNameModelTypeStatus
assets_backend survey assets ir.ui.view qweb Inherits web.assets_backend
assets_frontend Survey assets ir.ui.view qweb Inherits website.assets_frontend
assets_frontend_result Survey Results assets ir.ui.view qweb Inherits website.assets_frontend
assets_frontend_survey Printing Survey assets ir.ui.view qweb Inherits website.assets_frontend
auth_required Login required for this survey ir.ui.view qweb New
back Back ir.ui.view qweb New
datetime Datetime box ir.ui.view qweb New
free_text Free text box ir.ui.view qweb New
matrix Matrix ir.ui.view qweb New
multiple_choice Multiple choice ir.ui.view qweb New
no_result Survey Result ir.ui.view qweb New
nopages Survey has no pages ir.ui.view qweb New
notopen Survey not open ir.ui.view qweb New
numerical_box Numerical box ir.ui.view qweb New
page Page ir.ui.view qweb New
pagination Survey Result ir.ui.view qweb New
result Survey Result ir.ui.view qweb New
result_choice Choice Result ir.ui.view qweb New
result_comments Text Result ir.ui.view qweb New
result_matrix Matrix Result ir.ui.view qweb New
result_number Number Result ir.ui.view qweb New
result_text Text Result ir.ui.view qweb New
sfinished Survey Finished ir.ui.view qweb New
simple_choice Simple choice ir.ui.view qweb New
survey Survey ir.ui.view qweb New
survey_email_compose_message survey.mail.compose.message.form survey.mail.compose.message form New
survey_form Form view for survey survey.survey form New
survey_init Survey ir.ui.view qweb New
survey_kanban Kanban view for survey survey.survey kanban New
survey_label_search survey_label_search survey.label search New
survey_label_tree survey_label_tree survey.label tree New
survey_page_form Form view for survey page survey.page form New
survey_page_search Search view for survey page survey.page search New
survey_page_tree Tree view for survey page survey.page tree New
survey_print Survey ir.ui.view qweb New
survey_question_form Form view for survey question survey.question form New
survey_question_search Search view for survey question survey.question search New
survey_question_tree Tree view for survey question survey.question tree New
survey_response_line_search survey_response_line_search survey.user_input_line search New
survey_response_line_tree survey_response_line_tree survey.user_input_line tree New
survey_stage_form Form view for survey stage survey.stage form New
survey_tree Tree view for survey survey.survey tree New
survey_user_input_form survey_user_input_form survey.user_input form New
survey_user_input_line_form survey_user_input_line_form survey.user_input_line form New
survey_user_input_search survey_user_input_search survey.user_input search New
survey_user_input_tree survey_user_input_tree survey.user_input tree New
textbox Text box ir.ui.view qweb New
Models touched (8)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (4)
  • default_get(self, cr, uid, fields, context=None)
  • onchange_multi_email(self, cr, uid, ids, multi_email, context=None)
  • onchange_survey_id(self, cr, uid, ids, survey_id, context=None)
    Compute if the message is unread by the current user.
  • send_mail(self, cr, uid, ids, auto_commit=False, context=None)
    Process the wizard content and proceed with sending the related email(s), rendering any template patterns on the fly if needed

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (9)
  • onchange_validation_email(self, cr, uid, ids, validation_email, context=None)
  • validate_datetime(self, cr, uid, question, post, answer_tag, context=None)
  • validate_free_text(self, cr, uid, question, post, answer_tag, context=None)
  • validate_matrix(self, cr, uid, question, post, answer_tag, context=None)
  • validate_multiple_choice(self, cr, uid, question, post, answer_tag, context=None)
  • validate_numerical_box(self, cr, uid, question, post, answer_tag, context=None)
  • validate_question(self, cr, uid, question, post, answer_tag, context=None)
    Validate question, depending on question type and parameters
  • validate_simple_choice(self, cr, uid, question, post, answer_tag, context=None)
  • validate_textbox(self, cr, uid, question, post, answer_tag, context=None)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (11)
  • action_print_survey(self, cr, uid, ids, context=None)
    Open the website page with the survey printable view
  • action_result_survey(self, cr, uid, ids, context=None)
    Open the website page with the survey results view
  • action_send_survey(self, cr, uid, ids, context=None)
    Open a window to compose an email, pre-filled with the survey message
  • action_start_survey(self, cr, uid, ids, context=None)
    Open the website page with the survey form
  • action_test_survey(self, cr, uid, ids, context=None)
    Open the website page with the survey form into test mode
  • copy_data(self, cr, uid, id, default=None, context=None)
  • filter_input_ids(self, cr, uid, survey, filters, finished=False, context=None)
    If user applies any filters, then this function returns list of filtered user_input_id and label's strings for display data in web. :param filters: list of dictionary (having: row_id, ansewr_id) :param finished: True for completely filled survey,Falser otherwise. :returns list of filtered user_input_ids.
  • get_filter_display_data(self, cr, uid, filters, context)
    Returns data to display current filters :param filters: list of dictionary (having: row_id, answer_id) :param finished: True for completely filled survey, False otherwise. :returns list of dict having data to display filters.
  • get_input_summary(self, cr, uid, question, current_filters=None, context=None)
    Returns overall summary of question e.g. answered, skipped, total_inputs on basis of filter
  • next_page(self, cr, uid, user_input, page_id, go_back=False, context=None)
    The next page to display to the user, knowing that page_id is the id of the last displayed page. If page_id == 0, it will always return the first page of the survey. If all the pages have been displayed and go_back == False, it will return None If go_back == True, it will return the *previous* page instead of the next page. .. note:: It is assumed here that a careful user will not try to set go_back to True if she knows that the page to display is the first one! (doing this will probably cause a giant worm to eat her house)
  • prepare_result(self, cr, uid, question, current_filters=None, context=None)
    Compute statistical data for questions by counting number of vote per choice on basis of filter

New fields (0)

No new fields.

Public methods (4)
  • action_survey_resent(self, cr, uid, ids, context=None)
    Sent again the invitation
  • action_survey_results(self, cr, uid, ids, context=None)
    Open the website page with the survey results
  • action_view_answers(self, cr, uid, ids, context=None)
    Open the website page with the survey form
  • do_clean_emptys(self, cr, uid, automatic=False, context=None)
    Remove empty user inputs that have been created manually (used as a cronjob declared in data/survey_cron.xml)

New fields (0)

No new fields.

Public methods (10)
  • create(self, cr, uid, vals, context=None)
  • save_line_datetime(self, cr, uid, user_input_id, question, post, answer_tag, context=None)
  • save_line_free_text(self, cr, uid, user_input_id, question, post, answer_tag, context=None)
  • save_line_matrix(self, cr, uid, user_input_id, question, post, answer_tag, context=None)
  • save_line_multiple_choice(self, cr, uid, user_input_id, question, post, answer_tag, context=None)
  • save_line_numerical_box(self, cr, uid, user_input_id, question, post, answer_tag, context=None)
  • save_line_simple_choice(self, cr, uid, user_input_id, question, post, answer_tag, context=None)
  • save_line_textbox(self, cr, uid, user_input_id, question, post, answer_tag, context=None)
  • save_lines(self, cr, uid, user_input_id, question, post, answer_tag, context=None)
    Save answers to questions, depending on question type If an answer already exists for question and user_input_id, it will be overwritten (in order to maintain data consistency).
  • write(self, cr, uid, ids, vals, context=None)
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/8.0/survey
VERSION
VERSION 2.0
CATEGORY
CATEGORYMarketing
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOpenERP SA
MAINTAINERS
MAINTAINERSOpenERP SA
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Christophe Matthieu, Martin Trigaux, Fabien Pinckaers, Antony Lesuisse, Olivier Dony, Thibault Delavallée, Vo Minh Thu, Launchpad Translations on behalf of openerp, Quentin (OpenERP), Denis Ledoux, Fabien Meghazi, Christophe Simonis, Xavier Morel, Nicolas Lempereur, Nimesh Contractor (OpenERP), Richard Mathot, Géry Debongnie, Aaron Bohy, Chandni Machchhar (OpenERP Trainee), Richard Mathot (OpenERP), ged-odoo, Jeremy Kersten, Kunal Chavda (Open ERP), ima-openerp, Parth Gajjar (Open ERP), Dharmraj Jhala (OpenERP), Dharmraj Zala (OpenERP Trainee)
WEBSITE
WEBSITEhttps://www.odoo.com/page/survey
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-05 23:45:40
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - email_template
    - mail
    - base
    - base_setup
    - web_kanban
    - web
    - website
    - share
    - marketing
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
Create beautiful web surveys and visualize answers
==================================================

It depends on the answers or reviews of some questions by different users. A
survey may have multiple pages. Each page may contain multiple questions and
each question may have multiple answers. Different users may give different
answers of question and according to that survey is done. Partners are also
sent mails with personal token for the invitation of the survey.
    

Code Analysis

Views touched (45)
XML IDNameModelTypeStatus
assets_frontend Survey assets ir.ui.view qweb Inherits website.assets_frontend
assets_frontend_result Survey Results assets ir.ui.view qweb Inherits website.assets_frontend
assets_frontend_survey Printing Survey assets ir.ui.view qweb Inherits website.assets_frontend
auth_required Login required for this survey ir.ui.view qweb New
datetime Datetime box ir.ui.view qweb New
free_text Free text box ir.ui.view qweb New
matrix Matrix ir.ui.view qweb New
multiple_choice Multiple choice ir.ui.view qweb New
no_result Survey Result ir.ui.view qweb New
nopages Survey has no pages ir.ui.view qweb New
notopen Survey not open ir.ui.view qweb New
numerical_box Numerical box ir.ui.view qweb New
page Page ir.ui.view qweb New
pagination Survey Result ir.ui.view qweb New
result Survey Result ir.ui.view qweb New
result_choice Choice Result ir.ui.view qweb New
result_comments Text Result ir.ui.view qweb New
result_matrix Matrix Result ir.ui.view qweb New
result_number Number Result ir.ui.view qweb New
result_text Text Result ir.ui.view qweb New
sfinished Survey Finished ir.ui.view qweb New
simple_choice Simple choice ir.ui.view qweb New
survey Survey ir.ui.view qweb New
survey_email_compose_message survey.mail.compose.message.form survey.mail.compose.message form New
survey_form Form view for survey survey.survey form New
survey_init Survey ir.ui.view qweb New
survey_kanban Kanban view for survey survey.survey kanban New
survey_label_search survey_label_search survey.label search New
survey_label_tree survey_label_tree survey.label tree New
survey_page_form Form view for survey page survey.page form New
survey_page_search Search view for survey page survey.page search New
survey_page_tree Tree view for survey page survey.page tree New
survey_print Survey ir.ui.view qweb New
survey_question_form Form view for survey question survey.question form New
survey_question_search Search view for survey question survey.question search New
survey_question_tree Tree view for survey question survey.question tree New
survey_response_line_search survey_response_line_search survey.user_input_line search New
survey_response_line_tree survey_response_line_tree survey.user_input_line tree New
survey_stage_form Form view for survey stage survey.stage form New
survey_tree Tree view for survey survey.survey tree New
survey_user_input_form survey_user_input_form survey.user_input form New
survey_user_input_line_form survey_user_input_line_form survey.user_input_line form New
survey_user_input_search survey_user_input_search survey.user_input search New
survey_user_input_tree survey_user_input_tree survey.user_input tree New
textbox Text box ir.ui.view qweb New
Models touched (8)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (4)
  • default_get(self, cr, uid, fields, context=None)
  • onchange_multi_email(self, cr, uid, ids, multi_email, context=None)
  • onchange_survey_id(self, cr, uid, ids, survey_id, context=None)
    Compute if the message is unread by the current user.
  • send_mail(self, cr, uid, ids, context=None)
    Process the wizard content and proceed with sending the related email(s), rendering any template patterns on the fly if needed

New fields (0)

No new fields.

Public methods (1)
  • copy_data(self, cr, uid, ids, default=None, context=None)

New fields (0)

No new fields.

Public methods (9)
  • copy_data(self, cr, uid, ids, default=None, context=None)
  • validate_datetime(self, cr, uid, question, post, answer_tag, context=None)
  • validate_free_text(self, cr, uid, question, post, answer_tag, context=None)
  • validate_matrix(self, cr, uid, question, post, answer_tag, context=None)
  • validate_multiple_choice(self, cr, uid, question, post, answer_tag, context=None)
  • validate_numerical_box(self, cr, uid, question, post, answer_tag, context=None)
  • validate_question(self, cr, uid, question, post, answer_tag, context=None)
    Validate question, depending on question type and parameters
  • validate_simple_choice(self, cr, uid, question, post, answer_tag, context=None)
  • validate_textbox(self, cr, uid, question, post, answer_tag, context=None)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (11)
  • action_print_survey(self, cr, uid, ids, context=None)
    Open the website page with the survey printable view
  • action_result_survey(self, cr, uid, ids, context=None)
    Open the website page with the survey results view
  • action_send_survey(self, cr, uid, ids, context=None)
    Open a window to compose an email, pre-filled with the survey message
  • action_start_survey(self, cr, uid, ids, context=None)
    Open the website page with the survey form
  • action_test_survey(self, cr, uid, ids, context=None)
    Open the website page with the survey form into test mode
  • copy_data(self, cr, uid, id, default=None, context=None)
  • filter_input_ids(self, cr, uid, survey, filters, finished=False, context=None)
    If user applies any filters, then this function returns list of filtered user_input_id and label's strings for display data in web. :param filters: list of dictionary (having: row_id, ansewr_id) :param finished: True for completely filled survey,Falser otherwise. :returns list of filtered user_input_ids.
  • get_filter_display_data(self, cr, uid, filters, context)
    Returns data to display current filters :param filters: list of dictionary (having: row_id, answer_id) :param finished: True for completely filled survey, False otherwise. :returns list of dict having data to display filters.
  • get_input_summary(self, cr, uid, question, current_filters=None, context=None)
    Returns overall summary of question e.g. answered, skipped, total_inputs on basis of filter
  • next_page(self, cr, uid, user_input, page_id, go_back=False, context=None)
    The next page to display to the user, knowing that page_id is the id of the last displayed page. If page_id == 0, it will always return the first page of the survey. If all the pages have been displayed and go_back == False, it will return None If go_back == True, it will return the *previous* page instead of the next page. .. note:: It is assumed here that a careful user will not try to set go_back to True if she knows that the page to display is the first one! (doing this will probably cause a giant worm to eat her house)
  • prepare_result(self, cr, uid, question, current_filters=None, context=None)
    Compute statistical data for questions by counting number of vote per choice on basis of filter

New fields (0)

No new fields.

Public methods (4)
  • action_survey_resent(self, cr, uid, ids, context=None)
    Sent again the invitation
  • action_survey_results(self, cr, uid, ids, context=None)
    Open the website page with the survey results
  • action_view_answers(self, cr, uid, ids, context=None)
    Open the website page with the survey form
  • do_clean_emptys(self, cr, uid, automatic=False, context=None)
    Remove empty user inputs that have been created manually (used as a cronjob declared in data/survey_cron.xml)

New fields (0)

No new fields.

Public methods (10)
  • create(self, cr, uid, vals, context=None)
  • save_line_datetime(self, cr, uid, user_input_id, question, post, answer_tag, context=None)
  • save_line_free_text(self, cr, uid, user_input_id, question, post, answer_tag, context=None)
  • save_line_matrix(self, cr, uid, user_input_id, question, post, answer_tag, context=None)
  • save_line_multiple_choice(self, cr, uid, user_input_id, question, post, answer_tag, context=None)
  • save_line_numerical_box(self, cr, uid, user_input_id, question, post, answer_tag, context=None)
  • save_line_simple_choice(self, cr, uid, user_input_id, question, post, answer_tag, context=None)
  • save_line_textbox(self, cr, uid, user_input_id, question, post, answer_tag, context=None)
  • save_lines(self, cr, uid, user_input_id, question, post, answer_tag, context=None)
    Save answers to questions, depending on question type If an answer already exists for question and user_input_id, it will be overwritten (in order to maintain data consistency).
  • write(self, cr, uid, ids, vals, context=None)
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/7.0/survey
VERSION
VERSION 1.0
CATEGORY
CATEGORYTools
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOpenERP SA
MAINTAINERS
MAINTAINERSOpenERP SA
COMMITTERS
COMMITTERSRaphael Collet, Twinkle Christian (OpenERP), Cecile Tonglet, Atul Patel (OpenERP), Randhir Mayatra (OpenERP), Stephane Wirtel, Odoo Translation Bot, Turkesh Patel (Open ERP), Numerigraphe - Lionel Sausin, Pinakin Nayi (OpenERP), DBR (OpenERP), Antonin Bourguignon, Martin Trigaux, Ajay Chauhan (OpenERP), Foram Katharotiya (OpenERP), Purnendu Singh (OpenERP), Saurang Suthar (OpenERP), Fabien Pinckaers, Antony Lesuisse, Bharat Devnani (OpenERP), Meera Trambadia (OpenERP), Olivier Dony, Rajesh Prajapati (OpenERP), Twinkle (OpenERP), Divyesh Makwana (Open ERP), Tejas Tank, Thibault Delavallée, Vo Minh Thu, Hardik, Arnaud Pineux, pso (OpenERP), Sbh (Openerp), Amit Patel (OpenERP), Launchpad Translations on behalf of openerp, vta vta@openerp.com, Quentin (OpenERP), Denis Ledoux, ara@tinyerp.com, Mayur Maheshwari (OpenERP), Jigar Amin - OpenERP, Sanjay Gohel (Open ERP), niv-openerp, Christophe Simonis, Amit Patel, Vijaykumar Baladaniya, Ashvin Rathod (OpenERP), Amit Dodiya, Hiral Patel (OpenERP), Chandni Machchhar (OpenERP Trainee)
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-05 23:43:10
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - mail
    - base
    - base_setup
    - web_kanban
    - web
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
This module is used for surveying.
==================================

It depends on the answers or reviews of some questions by different users. A
survey may have multiple pages. Each page may contain multiple questions and each
question may have multiple answers. Different users may give different answers of
question and according to that survey is done. Partners are also sent mails with
user name and password for the invitation of the survey.
    

Code Analysis

Views touched (36)
XML IDNameModelTypeStatus
survey_answer_form survey_answer_form survey.answer form New
survey_answer_tree survey_answer_tree survey.answer tree New
survey_form survey_form survey form New
survey_page_form survey_page_form survey.page form New
survey_page_tree survey_page_tree survey.page tree New
survey_page_wizard_test1 survey_page_wizard_test survey.page form New
survey_question_column_heading_form survey_question_column_heading_form survey.question.column.heading form New
survey_question_column_heading_tree survey_question_column_heading_tree survey.question.column.heading tree New
survey_question_form survey_question_form survey.question form New
survey_question_search survey_question_search survey.question search New
survey_question_tree survey_question_tree survey.question tree New
survey_question_wizard_test survey_question_wizard_test survey.question form New
survey_request_form survey_request_form survey.request form New
survey_request_search survey_request_search survey.request search New
survey_request_tree survey_request_tree survey.request tree New
survey_response_answer_form survey_response_answer_form survey.response.answer form New
survey_response_answer_tree survey_response_answer_tree survey.response.answer tree New
survey_response_form survey_response_form survey.response form New
survey_response_line_form survey_response_line_form survey.response.line form New
survey_response_line_tree survey_response_line_tree survey.response.line tree New
survey_response_tree survey_response_tree survey.response tree New
survey_search survey_search survey search New
survey_tree survey_tree survey tree New
survey_type_form survey_type_form survey.type form New
survey_type_tree survey_type_tree survey.type tree New
view_survey_answer Survey survey.browse.answer form New
view_survey_kanban event.survey.kanban survey kanban New
view_survey_name Survey survey.name.wiz form New
view_survey_page_filter survey.page.list.select survey.page search New
view_survey_print Survey Print survey.print form New
view_survey_print_answer Survey Print Answer survey.print.answer form New
view_survey_print_statistics Survey Print Statistics survey.print.statistics form New
view_survey_question_message Survey Answer survey.question.wiz form New
view_survey_question_message1 Survey Search survey.question.wiz search New
view_survey_send_invitation Send Invitation survey.send.invitation form New
view_survey_send_invitation_log survey send invitation log survey.send.invitation.log form New
Models touched (0)

No models found for this module.

REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/6.1/survey
VERSION
VERSION 1.0
CATEGORY
CATEGORYTools
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOpenERP SA
MAINTAINERS
MAINTAINERSOpenERP SA
COMMITTERS
COMMITTERSRaphael Collet, Rucha (Open ERP), Stephane Wirtel, DBR (OpenERP), Harry (OpenERP), Bhumika (OpenERP), Saurang Suthar (OpenERP), Fabien Pinckaers, Antony Lesuisse, Bharat Devnani (OpenERP), Olivier Dony, Tejas Tank, Thibault Delavallée, Vo Minh Thu, Launchpad Translations on behalf of openerp, Quentin (OpenERP), Kuldeep Joshi (OpenERP), Mayur Maheshwari (OpenERP), Jigar Amin - OpenERP, Sanjay Gohel (Open ERP), vro, niv-openerp, Christophe Simonis, Ujjvala Collins (OpenERP), Xavier Morel, Jigar Amin, Serpent Consulting Services, Amit Bhavsar (Open ERP), Thibault Francois, MVA, Carlos Vásquez, Israel Fermin Montilla, Rifakat Haradwala (Open ERP), Hardik Ansodariy (OpenERP), aag (OpenERP), Yogesh (OpenERP), tfr@openerp.com, Naresh (OpenERP), RavishchanraMurari (Open ERP), YSA (Openerp), Ashutosh Srivastava (Open ERP)
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-05 23:41:35
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base_tools
    - base
    - mail
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
This module is used for surveying.
==================================

It depends on the answers or reviews of some questions by different users.
A survey may have multiple pages. Each page may contain multiple questions and each question may have multiple answers.
Different users may give different answers of question and according to that survey is done.
Partners are also sent mails with user name and password for the invitation of the survey
    

Code Analysis

Views touched (35)
XML IDNameModelTypeStatus
survey_answer_form survey_answer_form survey.answer form New
survey_answer_tree survey_answer_tree survey.answer tree New
survey_form survey_form survey form New
survey_page_form survey_page_form survey.page form New
survey_page_tree survey_page_tree survey.page tree New
survey_page_wizard_test1 survey_page_wizard_test survey.page form New
survey_question_column_heading_form survey_question_column_heading_form survey.question.column.heading form New
survey_question_column_heading_tree survey_question_column_heading_tree survey.question.column.heading tree New
survey_question_form survey_question_form survey.question form New
survey_question_search survey_question_search survey.question search New
survey_question_tree survey_question_tree survey.question tree New
survey_question_wizard_test survey_question_wizard_test survey.question form New
survey_request_form survey_request_form survey.request form New
survey_request_search survey_request_search survey.request search New
survey_request_tree survey_request_tree survey.request tree New
survey_response_answer_form survey_response_answer_form survey.response.answer form New
survey_response_answer_tree survey_response_answer_tree survey.response.answer tree New
survey_response_form survey_response_form survey.response form New
survey_response_line_form survey_response_line_form survey.response.line form New
survey_response_line_tree survey_response_line_tree survey.response.line tree New
survey_response_tree survey_response_tree survey.response tree New
survey_search survey_search survey search New
survey_tree survey_tree survey tree New
survey_type_form survey_type_form survey.type form New
survey_type_tree survey_type_tree survey.type tree New
view_survey_answer Survey survey.browse.answer form New
view_survey_name Survey survey.name.wiz form New
view_survey_page_filter survey.page.list.select survey.page search New
view_survey_print Survey Print survey.print form New
view_survey_print_answer Survey Print Answer survey.print.answer form New
view_survey_print_statistics Survey Print Statistics survey.print.statistics form New
view_survey_question_message Survey Question survey.question.wiz form New
view_survey_question_message1 Survey Search survey.question.wiz search New
view_survey_send_invitation Send Invitation survey.send.invitation form New
view_survey_send_invitation_log survey send invitation log survey.send.invitation.log form New
Models touched (0)

No models found for this module.